diff --git a/DB/Sources/DB/Content/ContentDatabase.swift b/DB/Sources/DB/Content/ContentDatabase.swift index a9cd173..c8280f2 100644 --- a/DB/Sources/DB/Content/ContentDatabase.swift +++ b/DB/Sources/DB/Content/ContentDatabase.swift @@ -16,7 +16,6 @@ public struct ContentDatabase { public init(id: Identity.Id, useHomeTimelineLastReadId: Bool, - useNotificationsLastReadId: Bool, inMemory: Bool, appGroup: String, keychain: Keychain.Type) throws { @@ -35,8 +34,7 @@ public struct ContentDatabase { try Self.clean( databaseWriter, - useHomeTimelineLastReadId: useHomeTimelineLastReadId, - useNotificationsLastReadId: useNotificationsLastReadId) + useHomeTimelineLastReadId: useHomeTimelineLastReadId) activeFiltersPublisher = ValueObservation.tracking { try Filter.filter(Filter.Columns.expiresAt == nil || Filter.Columns.expiresAt > Date()).fetchAll($0) @@ -708,48 +706,14 @@ private extension ContentDatabase { // swiftlint:disable:next function_body_length static func clean(_ databaseWriter: DatabaseWriter, - useHomeTimelineLastReadId: Bool, - useNotificationsLastReadId: Bool) throws { + useHomeTimelineLastReadId: Bool) throws { try databaseWriter.write { - let notificationAccountIds: [Account.Id] - let notificationStatusIds: [Status.Id] - + try NotificationRecord.deleteAll($0) try ConversationRecord.deleteAll($0) try StatusAncestorJoin.deleteAll($0) try StatusDescendantJoin.deleteAll($0) try AccountList.deleteAll($0) - if useNotificationsLastReadId { - var notificationIds = try MastodonNotification.Id.fetchAll( - $0, - NotificationRecord.select(NotificationRecord.Columns.id) - .order(NotificationRecord.Columns.id.desc)) - - if let lastReadId = try MastodonNotification.Id.fetchOne( - $0, - LastReadIdRecord.filter( - LastReadIdRecord.Columns.markerTimeline == Marker.Timeline.notifications.rawValue) - .select(LastReadIdRecord.Columns.id)) - ?? notificationIds.first, - let index = notificationIds.firstIndex(of: lastReadId) { - notificationIds = Array(notificationIds.prefix(index + Self.cleanAfterLastReadIdCount)) - } - - try NotificationRecord.filter(!notificationIds.contains(NotificationRecord.Columns.id)).deleteAll($0) - notificationAccountIds = try Account.Id.fetchAll( - $0, - NotificationRecord.select(NotificationRecord.Columns.accountId)) - notificationStatusIds = try Status.Id.fetchAll( - $0, - NotificationRecord.filter( - NotificationRecord.Columns.statusId != nil) - .select(NotificationRecord.Columns.statusId)) - } else { - try NotificationRecord.deleteAll($0) - notificationAccountIds = [] - notificationStatusIds = [] - } - if useHomeTimelineLastReadId { try TimelineRecord.filter(TimelineRecord.Columns.id != Timeline.home.id).deleteAll($0) var statusIds = try Status.Id.fetchAll( @@ -766,7 +730,6 @@ private extension ContentDatabase { statusIds = Array(statusIds.prefix(index + Self.cleanAfterLastReadIdCount)) } - statusIds += notificationStatusIds statusIds += try Status.Id.fetchAll( $0, StatusRecord.filter(statusIds.contains(StatusRecord.Columns.id) @@ -774,7 +737,6 @@ private extension ContentDatabase { .select(StatusRecord.Columns.reblogId)) try StatusRecord.filter(!statusIds.contains(StatusRecord.Columns.id)).deleteAll($0) var accountIds = try Account.Id.fetchAll($0, StatusRecord.select(StatusRecord.Columns.accountId)) - accountIds += notificationAccountIds accountIds += try Account.Id.fetchAll( $0, AccountRecord.filter(accountIds.contains(AccountRecord.Columns.id) @@ -783,8 +745,8 @@ private extension ContentDatabase { try AccountRecord.filter(!accountIds.contains(AccountRecord.Columns.id)).deleteAll($0) } else { try TimelineRecord.deleteAll($0) - try StatusRecord.filter(!notificationStatusIds.contains(StatusRecord.Columns.id)).deleteAll($0) - try AccountRecord.filter(!notificationAccountIds.contains(AccountRecord.Columns.id)).deleteAll($0) + try StatusRecord.deleteAll($0) + try AccountRecord.deleteAll($0) } } } diff --git a/Localizations/Localizable.strings b/Localizations/Localizable.strings index 3422727..1857692 100644 --- a/Localizations/Localizable.strings +++ b/Localizations/Localizable.strings @@ -198,7 +198,6 @@ "preferences.home-timeline-position-on-startup" = "Home timeline position on startup"; "preferences.notifications-position-on-startup" = "Notifications position on startup"; "preferences.position.remember-position" = "Remember position"; -"preferences.position.sync-position" = "Sync position with web and other devices"; "preferences.position.newest" = "Load newest"; "preferences.require-double-tap-to-reblog" = "Require double tap to reblog"; "preferences.require-double-tap-to-favorite" = "Require double tap to favorite"; diff --git a/ServiceLayer/Sources/ServiceLayer/Services/IdentityService.swift b/ServiceLayer/Sources/ServiceLayer/Services/IdentityService.swift index 2733ecc..cb398f6 100644 --- a/ServiceLayer/Sources/ServiceLayer/Services/IdentityService.swift +++ b/ServiceLayer/Sources/ServiceLayer/Services/IdentityService.swift @@ -34,7 +34,6 @@ public struct IdentityService { contentDatabase = try ContentDatabase( id: id, useHomeTimelineLastReadId: appPreferences.homeTimelineBehavior == .rememberPosition, - useNotificationsLastReadId: appPreferences.notificationsTabBehavior == .rememberPosition, inMemory: environment.inMemoryContent, appGroup: AppEnvironment.appGroup, keychain: environment.keychain) @@ -134,10 +133,6 @@ public extension IdentityService { switch AppPreferences(environment: environment).positionBehavior(markerTimeline: markerTimeline) { case .rememberPosition: return contentDatabase.setLastReadId(id, markerTimeline: markerTimeline) - case .syncPosition: - return mastodonAPIClient.request(MarkersEndpoint.post([markerTimeline: id])) - .ignoreOutput() - .eraseToAnyPublisher() case .newest: return Empty().eraseToAnyPublisher() } diff --git a/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift b/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift index ccb9de2..ce59cd1 100644 --- a/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift +++ b/ServiceLayer/Sources/ServiceLayer/Utilities/AppPreferences.swift @@ -40,7 +40,6 @@ public extension AppPreferences { enum PositionBehavior: String, CaseIterable, Identifiable { case rememberPosition - case syncPosition case newest public var id: String { rawValue } @@ -116,18 +115,6 @@ public extension AppPreferences { set { self[.homeTimelineBehavior] = newValue.rawValue } } - var notificationsTabBehavior: PositionBehavior { - get { - if let rawValue = self[.notificationsTabBehavior] as String?, - let value = PositionBehavior(rawValue: rawValue) { - return value - } - - return .newest - } - set { self[.notificationsTabBehavior] = newValue.rawValue } - } - var defaultEmojiSkinTone: SystemEmoji.SkinTone? { get { if let rawValue = self[.defaultEmojiSkinTone] as Int?, @@ -158,7 +145,7 @@ public extension AppPreferences { case .home: return homeTimelineBehavior case .notifications: - return notificationsTabBehavior + return .newest } } diff --git a/ViewModels/Sources/PreviewViewModels/PreviewViewModels.swift b/ViewModels/Sources/PreviewViewModels/PreviewViewModels.swift index 0ae45fb..2d24863 100644 --- a/ViewModels/Sources/PreviewViewModels/PreviewViewModels.swift +++ b/ViewModels/Sources/PreviewViewModels/PreviewViewModels.swift @@ -51,7 +51,6 @@ extension ContentDatabase { static let preview = try! ContentDatabase( id: identityId, useHomeTimelineLastReadId: false, - useNotificationsLastReadId: false, inMemory: true, appGroup: "group.metabolist.metatext", keychain: MockKeychain.self) diff --git a/ViewModels/Sources/ViewModels/View Models/CollectionItemsViewModel.swift b/ViewModels/Sources/ViewModels/View Models/CollectionItemsViewModel.swift index 283d2e1..b840bd5 100644 --- a/ViewModels/Sources/ViewModels/View Models/CollectionItemsViewModel.swift +++ b/ViewModels/Sources/ViewModels/View Models/CollectionItemsViewModel.swift @@ -21,7 +21,7 @@ public class CollectionItemsViewModel: ObservableObject { private let lastReadId = CurrentValueSubject(nil) private var lastSelectedLoadMore: LoadMore? private var hasRequestedUsingMarker = false - private var shouldRestorePositionOfLocalLastReadId = false + private var markerScrollPositionItemId: CollectionItem.Id? private var cancellables = Set() public init(collectionService: CollectionService, identityContext: IdentityContext) { @@ -50,8 +50,10 @@ public class CollectionItemsViewModel: ObservableObject { .store(in: &cancellables) if let markerTimeline = collectionService.markerTimeline { - shouldRestorePositionOfLocalLastReadId = - identityContext.appPreferences.positionBehavior(markerTimeline: markerTimeline) == .rememberPosition + if identityContext.appPreferences.positionBehavior(markerTimeline: markerTimeline) == .rememberPosition { + markerScrollPositionItemId = identityContext.service.getLocalLastReadId(markerTimeline) + } + lastReadId.compactMap { $0 } .removeDuplicates() .debounce(for: .seconds(Self.lastReadIdDebounceInterval), scheduler: DispatchQueue.global()) @@ -102,32 +104,7 @@ extension CollectionItemsViewModel: CollectionViewModel { public var canRefresh: Bool { collectionService.canRefresh } public func request(maxId: String? = nil, minId: String? = nil, search: Search?) { - let publisher: AnyPublisher - - if let markerTimeline = collectionService.markerTimeline, - identityContext.appPreferences.positionBehavior(markerTimeline: markerTimeline) == .syncPosition, - !hasRequestedUsingMarker { - publisher = identityContext.service.getMarker(markerTimeline) - .flatMap { [weak self] in - self?.collectionService.request(maxId: $0.lastReadId, minId: nil, search: nil) - ?? Empty().eraseToAnyPublisher() - } - .catch { [weak self] _ in - self?.collectionService.request(maxId: nil, minId: nil, search: nil) - ?? Empty().eraseToAnyPublisher() - } - .collect() - .flatMap { [weak self] _ in - self?.collectionService.request(maxId: nil, minId: nil, search: nil) - ?? Empty().eraseToAnyPublisher() - } - .eraseToAnyPublisher() - self.hasRequestedUsingMarker = true - } else { - publisher = collectionService.request(maxId: realMaxId(maxId: maxId), minId: minId, search: search) - } - - publisher + collectionService.request(maxId: realMaxId(maxId: maxId), minId: minId, search: search) .receive(on: DispatchQueue.main) .assignErrorsToAlertItem(to: \.alertItem, on: self) .handleEvents( @@ -180,8 +157,7 @@ extension CollectionItemsViewModel: CollectionViewModel { public func viewedAtTop(indexPath: IndexPath) { topVisibleIndexPath = indexPath - if !shouldRestorePositionOfLocalLastReadId, - lastUpdate.sections.count > indexPath.section, + if lastUpdate.sections.count > indexPath.section, lastUpdate.sections[indexPath.section].items.count > indexPath.item { lastReadId.send(lastUpdate.sections[indexPath.section].items[indexPath.item].itemId) } @@ -387,13 +363,11 @@ private extension CollectionItemsViewModel { let items = lastUpdate.sections.map(\.items).reduce([], +) let newItems = newSections.map(\.items).reduce([], +) - if shouldRestorePositionOfLocalLastReadId, - let markerTimeline = collectionService.markerTimeline, - let localLastReadId = identityContext.service.getLocalLastReadId(markerTimeline), - newItems.contains(where: { $0.itemId == localLastReadId }) { - shouldRestorePositionOfLocalLastReadId = false + if let itemId = markerScrollPositionItemId, + newItems.contains(where: { $0.itemId == itemId }) { + markerScrollPositionItemId = nil - return localLastReadId + return itemId } if collectionService is ContextService, diff --git a/Views/SwiftUI/PreferencesView.swift b/Views/SwiftUI/PreferencesView.swift index abc4cd4..19814e5 100644 --- a/Views/SwiftUI/PreferencesView.swift +++ b/Views/SwiftUI/PreferencesView.swift @@ -121,12 +121,6 @@ struct PreferencesView: View { Text(option.localizedStringKey).tag(option) } } - Picker("preferences.notifications-position-on-startup", - selection: $identityContext.appPreferences.notificationsTabBehavior) { - ForEach(AppPreferences.PositionBehavior.allCases) { option in - Text(option.localizedStringKey).tag(option) - } - } } } } @@ -183,8 +177,6 @@ extension AppPreferences.PositionBehavior { switch self { case .rememberPosition: return "preferences.position.remember-position" - case .syncPosition: - return "preferences.position.sync-position" case .newest: return "preferences.position.newest" }