diff --git a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift index 27b42b75b..815e85a54 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Home/HomeFeedViewModel.swift @@ -250,8 +250,7 @@ enum LoadingBarStyle { } func setLinkArchived(dataService: DataService, objectID: NSManagedObjectID, archived: Bool) { - dataService.archiveLink(objectID: objectID, archived: archived) - snackbar(archived ? "Link archived" : "Link unarchived") + archiveLibraryItemAction(dataService: dataService, objectID: objectID, archived: archived) } func removeLibraryItem(dataService: DataService, objectID: NSManagedObjectID) { diff --git a/apple/OmnivoreKit/Sources/App/Views/Profile/PushNotificationSettingsView.swift b/apple/OmnivoreKit/Sources/App/Views/Profile/PushNotificationSettingsView.swift index aaf50a9cd..9e3bd7678 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Profile/PushNotificationSettingsView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Profile/PushNotificationSettingsView.swift @@ -25,7 +25,8 @@ func checkPushNotificationsStatus() { UNUserNotificationCenter.current().getNotificationSettings { settings in DispatchQueue.main.async { - self.desiredNotificationsEnabled = settings.alertSetting == UNNotificationSetting.enabled + let desired = UserDefaults.standard.bool(forKey: UserDefaultKey.notificationsEnabled.rawValue) + self.desiredNotificationsEnabled = desired && settings.alertSetting == UNNotificationSetting.enabled } } } diff --git a/apple/OmnivoreKit/Sources/App/Views/RemoveLibraryItemAction.swift b/apple/OmnivoreKit/Sources/App/Views/RemoveLibraryItemAction.swift index c728509ee..ceaa39cd0 100644 --- a/apple/OmnivoreKit/Sources/App/Views/RemoveLibraryItemAction.swift +++ b/apple/OmnivoreKit/Sources/App/Views/RemoveLibraryItemAction.swift @@ -7,18 +7,20 @@ import Utils import Views func removeLibraryItemAction(dataService: DataService, objectID: NSManagedObjectID) { + var localPdf: String? = nil + dataService.viewContext.performAndWait { if let item = dataService.viewContext.object(with: objectID) as? Models.LibraryItem { item.state = "DELETED" try? dataService.viewContext.save() - - // Delete local PDF file if it exists - if let localPdf = item.localPDF, let localPdfURL = PDFUtils.localPdfURL(filename: localPdf) { - try? FileManager.default.removeItem(at: localPdfURL) - } + localPdf = item.localPDF } } + if let localPdf = localPdf, let localPdfURL = PDFUtils.localPdfURL(filename: localPdf) { + try? FileManager.default.removeItem(at: localPdfURL) + } + let syncTask = Task.detached(priority: .background) { do { try await Task.sleep(nanoseconds: 4_000_000_000) @@ -44,3 +46,43 @@ func removeLibraryItemAction(dataService: DataService, objectID: NSManagedObject } }, dismissAfter: 2000) } + +func archiveLibraryItemAction(dataService: DataService, objectID: NSManagedObjectID, archived: Bool) { + var localPdf: String? = nil + dataService.viewContext.performAndWait { + if let item = dataService.viewContext.object(with: objectID) as? Models.LibraryItem { + item.isArchived = archived + try? dataService.viewContext.save() + localPdf = item.localPDF + } + } + + // Delete local PDF file if it exists + if let localPdf = localPdf, let localPdfURL = PDFUtils.localPdfURL(filename: localPdf) { + try? FileManager.default.removeItem(at: localPdfURL) + } + + let syncTask = Task.detached(priority: .background) { + do { + try await Task.sleep(nanoseconds: 4_000_000_000) + let canceled = Task.isCancelled + if !canceled { + dataService.archiveLink(objectID: objectID, archived: archived) + } + } catch { + print("error running task: ", error) + } + print("checking if task is canceled: ", Task.isCancelled) + } + + Snackbar.show(message: "Item archived", undoAction: { + print("canceling task", syncTask) + syncTask.cancel() + dataService.viewContext.performAndWait { + if let item = dataService.viewContext.object(with: objectID) as? Models.LibraryItem { + item.state = "SUCCEEDED" + try? dataService.viewContext.save() + } + } + }, dismissAfter: 2000) +} diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift index b816f8987..1cb4aab3d 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderContainer.swift @@ -405,10 +405,14 @@ struct WebReaderContainerView: View { anchorIndex: Int(item.readingProgressAnchor), force: false ) - Task { - await audioController.preload(itemIDs: [item.unwrappedID]) - } viewModel.trackReadEvent(item: item) + + // Wait 1.5s while loading the reader before attempting to preload the speech file + DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(1500)) { + Task { + await audioController.preload(itemIDs: [item.unwrappedID]) + } + } } .confirmationDialog(linkToOpen?.absoluteString ?? "", isPresented: $displayLinkSheet, titleVisibility: .visible) { diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderLoadingContainer.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderLoadingContainer.swift index bdc018795..b8f068c71 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderLoadingContainer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderLoadingContainer.swift @@ -18,6 +18,7 @@ import Views guard let objectID = try? await dataService.loadItemContentUsingRequestID(username: username, requestID: requestID) else { + errorMessage = "Item is no longer available" return } item = dataService.viewContext.object(with: objectID) as? Models.LibraryItem @@ -71,7 +72,19 @@ public struct WebReaderLoadingContainer: View { .onAppear { viewModel.trackReadEvent() } } } else if let errorMessage = viewModel.errorMessage { - Text(errorMessage) + NavigationView { + VStack(spacing: 15) { + Text(errorMessage) + Button(action: { + dismiss() + }, label: { + Text("Dismiss") + }) + } + } +#if os(iOS) + .navigationViewStyle(.stack) +#endif } else { ProgressView() .task {