Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added more logs for basic UI actions #728

Merged
merged 1 commit into from
Jul 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 85 additions & 23 deletions Zotero/Scenes/Detail/DetailCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ protocol DetailItemsCoordinatorDelegate: AnyObject {
func showCollectionsPicker(in library: Library, completed: @escaping (Set<String>) -> Void)
func showItemDetail(for type: ItemDetailState.DetailType, library: Library, scrolledToKey childKey: String?, animated: Bool)
func showAttachmentError(_ error: Error)
func showNote(with text: String, tags: [Tag], title: NoteEditorState.TitleData?, libraryId: LibraryIdentifier, readOnly: Bool, save: @escaping (String, [Tag]) -> Void)
func showNote(with text: String, tags: [Tag], title: NoteEditorState.TitleData?, key: String?, libraryId: LibraryIdentifier, readOnly: Bool, save: @escaping (String, [Tag]) -> Void)
func showAddActions(viewModel: ViewModel<ItemsActionHandler>, button: UIBarButtonItem)
func showSortActions(viewModel: ViewModel<ItemsActionHandler>, button: UIBarButtonItem)
func show(url: URL)
Expand All @@ -41,7 +41,7 @@ protocol DetailItemsCoordinatorDelegate: AnyObject {
}

protocol DetailItemDetailCoordinatorDelegate: AnyObject {
func showNote(with text: String, tags: [Tag], title: NoteEditorState.TitleData?, libraryId: LibraryIdentifier, readOnly: Bool, save: @escaping (String, [Tag]) -> Void)
func showNote(with text: String, tags: [Tag], title: NoteEditorState.TitleData?, key: String?, libraryId: LibraryIdentifier, readOnly: Bool, save: @escaping (String, [Tag]) -> Void)
func showAttachmentPicker(save: @escaping ([URL]) -> Void)
func showTagPicker(libraryId: LibraryIdentifier, selected: Set<String>, picked: @escaping ([Tag]) -> Void)
func showTypePicker(selected: String, picked: @escaping (String) -> Void)
Expand Down Expand Up @@ -115,6 +115,7 @@ final class DetailCoordinator: Coordinator {

func start(animated: Bool) {
guard let userControllers = self.controllers.userControllers else { return }
DDLogInfo("DetailCoordinator: show items for \(self.collection.id); \(self.library.id)")
let controller = self.createItemsViewController(
collection: self.collection,
library: self.library,
Expand Down Expand Up @@ -180,29 +181,39 @@ final class DetailCoordinator: Coordinator {

switch contentType {
case "application/pdf":
DDLogInfo("DetailCoordinator: show PDF \(attachment.key)")
self.showPdf(at: url, key: attachment.key, library: library)

case "text/html":
DDLogInfo("DetailCoordinator: show HTML \(attachment.key)")
self.showWebView(for: url)

case "text/plain":
let text = try? String(contentsOf: url, encoding: .utf8)
if let text = text {
DDLogInfo("DetailCoordinator: show plain text \(attachment.key)")
self.show(text: text, title: filename)
} else {
DDLogInfo("DetailCoordinator: share plain text \(attachment.key)")
self.share(item: url, sourceView: .view(sourceView, rect))
}

case _ where contentType.contains("image"):
let image = (contentType == "image/gif") ? (try? Data(contentsOf: url)).flatMap({ try? UIImage(gifData: $0) }) :
UIImage(contentsOfFile: url.path)
let image = (contentType == "image/gif") ? (try? Data(contentsOf: url)).flatMap({ try? UIImage(gifData: $0) }) : UIImage(contentsOfFile: url.path)
if let image = image {
DDLogInfo("DetailCoordinator: show image \(attachment.key)")
self.show(image: image, title: filename)
} else {
self.share(item: url, sourceView: .view(sourceView, rect))
DDLogInfo("DetailCoordinator: share image \(attachment.key)")
self.share(item: url, sourceView: .view(sourceView, rect))
}

default:
if AVURLAsset(url: url).isPlayable {
DDLogInfo("DetailCoordinator: show video \(attachment.key)")
self.showVideo(for: url)
} else {
DDLogInfo("DetailCoordinator: share attachment \(attachment.key)")
self.share(item: file.createUrl(), sourceView: .view(sourceView, rect))
}
}
Expand Down Expand Up @@ -239,6 +250,8 @@ final class DetailCoordinator: Coordinator {
func showTagPicker(libraryId: LibraryIdentifier, selected: Set<String>, userInterfaceStyle: UIUserInterfaceStyle?, navigationController: UINavigationController?, picked: @escaping ([Tag]) -> Void) {
guard let navigationController, let dbStorage = self.controllers.userControllers?.dbStorage else { return }

DDLogInfo("DetailCoordinator: show tag picker for \(libraryId)")

let state = TagPickerState(libraryId: libraryId, selectedTags: selected)
let handler = TagPickerActionHandler(dbStorage: dbStorage)
let viewModel = ViewModel(initialState: state, handler: handler)
Expand Down Expand Up @@ -275,10 +288,13 @@ final class DetailCoordinator: Coordinator {

func show(doi: String) {
guard let url = URL(string: "https://doi.org/\(doi)") else { return }
DDLogInfo("DetailCoordinator: show DOI \(doi)")
self.showWeb(url: url)
}

func show(url: URL) {
DDLogInfo("DetailCoordinator: show url \(url.absoluteString)")

if let scheme = url.scheme, scheme != "http" && scheme != "https" {
UIApplication.shared.open(url)
} else {
Expand Down Expand Up @@ -343,6 +359,8 @@ extension DetailCoordinator: DetailItemsCoordinatorDelegate {
}

func showSortActions(viewModel: ViewModel<ItemsActionHandler>, button: UIBarButtonItem) {
DDLogInfo("DetailCoordinator: show item sort popup")

let navigationController = UINavigationController()
navigationController.modalPresentationStyle = UIDevice.current.userInterfaceIdiom == .pad ? .popover : .formSheet
navigationController.popoverPresentationController?.barButtonItem = button
Expand Down Expand Up @@ -394,16 +412,30 @@ extension DetailCoordinator: DetailItemsCoordinatorDelegate {

private func sortButtonTitles(for sortType: ItemsSortType) -> (field: String, order: String) {
let sortOrderTitle = sortType.ascending ? L10n.Items.ascending : L10n.Items.descending
return ("\(L10n.Items.sortBy): \(sortType.field.title)",
"\(L10n.Items.sortOrder): \(sortOrderTitle)")
return ("\(L10n.Items.sortBy): \(sortType.field.title)", "\(L10n.Items.sortOrder): \(sortOrderTitle)")
}

func showNote(with text: String, tags: [Tag], title: NoteEditorState.TitleData?, libraryId: LibraryIdentifier, readOnly: Bool, save: @escaping (String, [Tag]) -> Void) {
func showNote(with text: String, tags: [Tag], title: NoteEditorState.TitleData?, key: String?, libraryId: LibraryIdentifier, readOnly: Bool, save: @escaping (String, [Tag]) -> Void) {
if let key = key {
DDLogInfo("DetailCoordinator: show note \(key)")
} else {
DDLogInfo("DetailCoordinator: show note creation")
}

let navigationController = NavigationViewController()
navigationController.modalPresentationStyle = .fullScreen
navigationController.isModalInPresentation = true

let coordinator = NoteEditorCoordinator(text: text, tags: tags, title: title, libraryId: libraryId, readOnly: readOnly, save: save, navigationController: navigationController, controllers: self.controllers)
let coordinator = NoteEditorCoordinator(
text: text,
tags: tags,
title: title,
libraryId: libraryId,
readOnly: readOnly,
save: save,
navigationController: navigationController,
controllers: self.controllers
)
coordinator.parentCoordinator = self
self.childCoordinators.append(coordinator)
coordinator.start(animated: false)
Expand All @@ -414,17 +446,31 @@ extension DetailCoordinator: DetailItemsCoordinatorDelegate {
func showItemDetail(for type: ItemDetailState.DetailType, library: Library, scrolledToKey childKey: String?, animated: Bool) {
guard let dbStorage = self.controllers.userControllers?.dbStorage,
let fileDownloader = self.controllers.userControllers?.fileDownloader,
let fileCleanupController = self.controllers.userControllers?.fileCleanupController else { return }
let fileCleanupController = self.controllers.userControllers?.fileCleanupController
else { return }

switch type {
case .preview(let key):
DDLogInfo("DetailCoordinator: show item detail \(key)")

case .duplication(let itemKey, let collectionKey):
DDLogInfo("DetailCoordinator: show item duplication for \(itemKey); \(String(describing: collectionKey))")

case .creation:
DDLogInfo("DetailCoordinator: show item creation")
}

let state = ItemDetailState(type: type, library: library, preScrolledChildKey: childKey, userId: Defaults.shared.userId)
let handler = ItemDetailActionHandler(apiClient: self.controllers.apiClient,
fileStorage: self.controllers.fileStorage,
dbStorage: dbStorage,
schemaController: self.controllers.schemaController,
dateParser: self.controllers.dateParser,
urlDetector: self.controllers.urlDetector,
fileDownloader: fileDownloader,
fileCleanupController: fileCleanupController)
let handler = ItemDetailActionHandler(
apiClient: self.controllers.apiClient,
fileStorage: self.controllers.fileStorage,
dbStorage: dbStorage,
schemaController: self.controllers.schemaController,
dateParser: self.controllers.dateParser,
urlDetector: self.controllers.urlDetector,
fileDownloader: fileDownloader,
fileCleanupController: fileCleanupController
)
let viewModel = ViewModel(initialState: state, handler: handler)

let controller = ItemDetailViewController(viewModel: viewModel, controllers: self.controllers)
Expand All @@ -435,6 +481,8 @@ extension DetailCoordinator: DetailItemsCoordinatorDelegate {
func showCollectionsPicker(in library: Library, completed: @escaping (Set<String>) -> Void) {
guard let dbStorage = self.controllers.userControllers?.dbStorage else { return }

DDLogInfo("DetailCoordinator: show collection picker")

let state = CollectionsPickerState(library: library, excludedKeys: [], selected: [])
let handler = CollectionsPickerActionHandler(dbStorage: dbStorage)
let viewModel = ViewModel(initialState: state, handler: handler)
Expand All @@ -447,6 +495,8 @@ extension DetailCoordinator: DetailItemsCoordinatorDelegate {
}

func showFilters(viewModel: ViewModel<ItemsActionHandler>, itemsController: ItemsViewController, button: UIBarButtonItem) {
DDLogInfo("DetailCoordinator: show item filters")

let navigationController = NavigationViewController()
navigationController.modalPresentationStyle = UIDevice.current.userInterfaceIdiom == .pad ? .popover : .formSheet
navigationController.popoverPresentationController?.barButtonItem = button
Expand Down Expand Up @@ -483,8 +533,15 @@ extension DetailCoordinator: DetailItemsCoordinatorDelegate {
func showCitation(for itemIds: Set<String>, libraryId: LibraryIdentifier) {
guard let citationController = self.controllers.userControllers?.citationController else { return }

let state = SingleCitationState(itemIds: itemIds, libraryId: libraryId, styleId: Defaults.shared.quickCopyStyleId,
localeId: Defaults.shared.quickCopyLocaleId, exportAsHtml: Defaults.shared.quickCopyAsHtml)
DDLogInfo("DetailCoordinator: show citation popup for \(itemIds)")

let state = SingleCitationState(
itemIds: itemIds,
libraryId: libraryId,
styleId: Defaults.shared.quickCopyStyleId,
localeId: Defaults.shared.quickCopyLocaleId,
exportAsHtml: Defaults.shared.quickCopyAsHtml
)
let handler = SingleCitationActionHandler(citationController: citationController)
let viewModel = ViewModel(initialState: state, handler: handler)

Expand Down Expand Up @@ -519,18 +576,18 @@ extension DetailCoordinator: DetailItemsCoordinatorDelegate {
coordinator.parentCoordinator = self
self.childCoordinators.append(coordinator)
coordinator.start(animated: false)

self.navigationController?.present(containerController, animated: true, completion: nil)
}

func showCiteExport(for itemIds: Set<String>, libraryId: LibraryIdentifier) {
DDLogInfo("DetailCoordinator: show citation/bibliography export for \(itemIds)")

let navigationController = NavigationViewController()
let containerController = ContainerViewController(rootViewController: navigationController)
let coordinator = CitationBibliographyExportCoordinator(itemIds: itemIds, libraryId: libraryId, navigationController: navigationController, controllers: self.controllers)
coordinator.parentCoordinator = self
self.childCoordinators.append(coordinator)
coordinator.start(animated: false)

self.navigationController?.present(containerController, animated: true, completion: nil)
}

Expand Down Expand Up @@ -589,7 +646,7 @@ extension DetailCoordinator: DetailItemsCoordinatorDelegate {

extension DetailCoordinator: DetailItemActionSheetCoordinatorDelegate {
func showNoteCreation(title: NoteEditorState.TitleData?, libraryId: LibraryIdentifier, save: @escaping (String, [Tag]) -> Void) {
self.showNote(with: "", tags: [], title: title, libraryId: libraryId, readOnly: false, save: save)
self.showNote(with: "", tags: [], title: title, key: nil, libraryId: libraryId, readOnly: false, save: save)
}

func showAttachmentPicker(save: @escaping ([URL]) -> Void) {
Expand Down Expand Up @@ -679,6 +736,8 @@ extension DetailCoordinator: DetailItemDetailCoordinatorDelegate {
}

private func _showCreatorEditor(for creator: ItemDetailState.Creator, itemType: String, saved: @escaping CreatorEditSaveAction, deleted: CreatorEditDeleteAction?) {
DDLogInfo("DetailCoordinator: show item detail creator editor for \(creator.type)")

let navigationController = NavigationViewController()
navigationController.isModalInPresentation = true
navigationController.modalPresentationStyle = .formSheet
Expand All @@ -692,6 +751,7 @@ extension DetailCoordinator: DetailItemDetailCoordinatorDelegate {
}

func showTypePicker(selected: String, picked: @escaping (String) -> Void) {
DDLogInfo("DetailCoordinator: show item type picker")
let viewModel = ItemTypePickerViewModelCreator.create(selected: selected, schemaController: self.controllers.schemaController)
self.presentPicker(viewModel: viewModel, requiresSaveButton: false, saveAction: picked)
}
Expand Down Expand Up @@ -818,6 +878,8 @@ extension DetailCoordinator: DetailNoteEditorCoordinatorDelegate {
func pushTagPicker(libraryId: LibraryIdentifier, selected: Set<String>, picked: @escaping ([Tag]) -> Void) {
guard let dbStorage = self.controllers.userControllers?.dbStorage else { return }

DDLogInfo("DetailCoordinator: push tag picker for \(libraryId)")

let state = TagPickerState(libraryId: libraryId, selectedTags: selected)
let handler = TagPickerActionHandler(dbStorage: dbStorage)
let viewModel = ViewModel(initialState: state, handler: handler)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,17 @@ final class ItemDetailViewController: UIViewController {
let library = self.viewModel.state.library
let key = note?.key ?? KeyGenerator.newKey
let title = NoteEditorState.TitleData(type: self.viewModel.state.data.type, title: self.viewModel.state.data.title)
self.coordinatorDelegate?.showNote(with: (note?.text ?? ""), tags: (note?.tags ?? []), title: title,
libraryId: library.identifier, readOnly: !library.metadataEditable, save: { [weak self] text, tags in
self?.viewModel.process(action: .saveNote(key: key, text: text, tags: tags))
})
self.coordinatorDelegate?.showNote(
with: (note?.text ?? ""),
tags: (note?.tags ?? []),
title: title,
key: note?.key,
libraryId: library.identifier,
readOnly: !library.metadataEditable,
save: { [weak self] text, tags in
self?.viewModel.process(action: .saveNote(key: key, text: text, tags: tags))
}
)

case .openTagPicker:
self.coordinatorDelegate?.showTagPicker(libraryId: self.viewModel.state.library.identifier,
Expand Down Expand Up @@ -195,6 +202,7 @@ final class ItemDetailViewController: UIViewController {

if state.changes.contains(.editing) || state.changes.contains(.type) {
if state.changes.contains(.editing) {
DDLogInfo("ItemDetailViewController: editing changed to \(state.isEditing)")
self.setNavigationBarButtons(to: state)
}
if state.changes.contains(.type) {
Expand Down
14 changes: 11 additions & 3 deletions Zotero/Scenes/Detail/Items/Views/ItemsViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,17 @@ final class ItemsViewController: UIViewController {
guard let note = Note(item: item) else { return }
let tags = Array(item.tags.map({ Tag(tag: $0) }))
let library = self.viewModel.state.library
self.coordinatorDelegate?.showNote(with: note.text, tags: tags, title: nil, libraryId: library.identifier, readOnly: !library.metadataEditable, save: { [weak self] newText, newTags in
self?.viewModel.process(action: .saveNote(note.key, newText, newTags))
})
self.coordinatorDelegate?.showNote(
with: note.text,
tags: tags,
title: nil,
key: note.key,
libraryId: library.identifier,
readOnly: !library.metadataEditable,
save: { [weak self] newText, newTags in
self?.viewModel.process(action: .saveNote(note.key, newText, newTags))
}
)

default:
self.coordinatorDelegate?.showItemDetail(for: .preview(key: item.key), library: self.viewModel.state.library, scrolledToKey: nil, animated: true)
Expand Down
Loading