From 1d2e666c0079224c6928a285a200c1da4b18aaa9 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Sat, 15 Jan 2022 14:22:13 -0500 Subject: [PATCH] Mark items read on the server immediately instead of waiting for sync --- Reader/FervorController.swift | 21 +++++++++++++++++++ Reader/Screens/AppSplitViewController.swift | 6 ++++-- .../Items/ItemCollectionViewCell.swift | 19 ++++++++++------- .../Screens/Items/ItemsViewController.swift | 12 +++++++---- Reader/Screens/Read/ReadViewController.swift | 4 +++- 5 files changed, 48 insertions(+), 14 deletions(-) diff --git a/Reader/FervorController.swift b/Reader/FervorController.swift index 94689bc..ae7bff5 100644 --- a/Reader/FervorController.swift +++ b/Reader/FervorController.swift @@ -110,4 +110,25 @@ class FervorController { } } + @MainActor + func markItem(_ item: Item, read: Bool) async { + item.read = read + do { + let f = item.read ? client.read(item:) : client.unread(item:) + _ = try await f(item.id!) + item.needsReadStateSync = false + } catch { + logger.error("Failed to mark item (un)read: \(error.localizedDescription, privacy: .public)") + item.needsReadStateSync = true + } + + if persistentContainer.viewContext.hasChanges { + do { + try persistentContainer.viewContext.save() + } catch { + logger.error("Failed to save view context: \(error.localizedDescription, privacy: .public)") + } + } + } + } diff --git a/Reader/Screens/AppSplitViewController.swift b/Reader/Screens/AppSplitViewController.swift index bbc05b2..8472de4 100644 --- a/Reader/Screens/AppSplitViewController.swift +++ b/Reader/Screens/AppSplitViewController.swift @@ -58,8 +58,10 @@ class AppSplitViewController: UISplitViewController { let read = nav.topViewController as? ReadViewController else { return } - read.item.read = !read.item.read - updateImage(toolbarItem: item) + Task { + await fervorController.markItem(read.item, read: !read.item.read) + updateImage(toolbarItem: item) + } } private func updateImage(toolbarItem: NSToolbarItem) { diff --git a/Reader/Screens/Items/ItemCollectionViewCell.swift b/Reader/Screens/Items/ItemCollectionViewCell.swift index c74d560..2e6fc6d 100644 --- a/Reader/Screens/Items/ItemCollectionViewCell.swift +++ b/Reader/Screens/Items/ItemCollectionViewCell.swift @@ -8,6 +8,8 @@ import UIKit protocol ItemCollectionViewCellDelegate: AnyObject { + var fervorController: FervorController { get } + func itemCellSelected(cell: ItemCollectionViewCell, item: Item) } @@ -86,14 +88,17 @@ class ItemCollectionViewCell: UICollectionViewListCell { func setRead(_ read: Bool, animated: Bool) { guard self.item.read != read else { return } - self.item.read = read - if animated { - // i don't know why .transition works but .animate doesn't - UIView.transition(with: self, duration: 0.2, options: .transitionCrossDissolve) { - self.updateColors() + Task { + await self.delegate?.fervorController.markItem(self.item, read: read) + + if animated { + // i don't know why .transition works but .animate doesn't + UIView.transition(with: self, duration: 0.2, options: .transitionCrossDissolve) { + self.updateColors() + } + } else { + updateColors() } - } else { - updateColors() } } diff --git a/Reader/Screens/Items/ItemsViewController.swift b/Reader/Screens/Items/ItemsViewController.swift index 4261faa..0906bbd 100644 --- a/Reader/Screens/Items/ItemsViewController.swift +++ b/Reader/Screens/Items/ItemsViewController.swift @@ -139,12 +139,16 @@ extension ItemsViewController: UICollectionViewDelegate { })) } if item.read { - children.append(UIAction(title: "Mark as Unread", image: UIImage(systemName: "checkmark.circle"), handler: { _ in - item.read = false + children.append(UIAction(title: "Mark as Unread", image: UIImage(systemName: "checkmark.circle"), handler: { [unowned self] _ in + Task { + await self.fervorController.markItem(item, read: false) + } })) } else { - children.append(UIAction(title: "Mark as Read", image: UIImage(systemName: "checkmark.circle.fill"), handler: { _ in - item.read = true + children.append(UIAction(title: "Mark as Read", image: UIImage(systemName: "checkmark.circle.fill"), handler: { [unowned self] _ in + Task { + await self.fervorController.markItem(item, read: true) + } })) } return UIMenu(children: children) diff --git a/Reader/Screens/Read/ReadViewController.swift b/Reader/Screens/Read/ReadViewController.swift index f1da8f1..fe5b8a6 100644 --- a/Reader/Screens/Read/ReadViewController.swift +++ b/Reader/Screens/Read/ReadViewController.swift @@ -189,7 +189,9 @@ extension ReadViewController: StretchyMenuInteractionDelegate { self.present(UIActivityViewController(activityItems: [url], applicationActivities: nil), animated: true) }), StretchyMenuItem(title: item.read ? "Mark as Unread" : "Mark as Read", subtitle: nil, action: { [unowned self] in - item.read = !item.read + Task { + await self.fervorController.markItem(item, read: !item.read) + } }), ] }