2
2
mirror of https://github.com/mastodon/mastodon-ios synced 2025-04-11 22:58:02 +02:00

Remove Boutique

Not appropriate for this use case.
This commit is contained in:
shannon 2025-03-05 16:00:51 -05:00
parent 5e6978248f
commit 332543aa3d
4 changed files with 74 additions and 157 deletions

View File

@ -509,7 +509,6 @@
DBFEEC99279BDCDE004F81DD /* ProfileAboutViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEEC98279BDCDE004F81DD /* ProfileAboutViewModel.swift */; };
DBFEEC9B279BDDD9004F81DD /* ProfileAboutViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEEC9A279BDDD9004F81DD /* ProfileAboutViewModel+Diffable.swift */; };
DBFEEC9D279C12C1004F81DD /* ProfileFieldEditCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEEC9C279C12C1004F81DD /* ProfileFieldEditCollectionViewCell.swift */; };
FB24973A2D6771D500A508B2 /* Boutique in Frameworks */ = {isa = PBXBuildFile; productRef = FB2497392D6771D500A508B2 /* Boutique */; };
FB7C4CC62CD2CAB000F6129A /* DonationCompletionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB7C4CC52CD2CAA800F6129A /* DonationCompletionViewController.swift */; };
FB7C4CCC2CD55DEB00F6129A /* NavigationFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB7C4CCB2CD55DEB00F6129A /* NavigationFlow.swift */; };
FB7C4CCE2CD55DFF00F6129A /* NewDonationNavigationFlow.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB7C4CCD2CD55DFE00F6129A /* NewDonationNavigationFlow.swift */; };
@ -1276,9 +1275,9 @@
FBBEA04F2D3819080000A900 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
membershipExceptions = (
BoutiqueStores.swift,
GroupedNotificationFeedLoader.swift,
InlinePostPreview.swift,
LastReadMarkers.swift,
NotificationInfo.swift,
NotificationListViewController.swift,
NotificationRowView.swift,
@ -1328,7 +1327,6 @@
DBF96326262EC0A6001D8D25 /* AuthenticationServices.framework in Frameworks */,
D84FA0932AE6915800987F47 /* MBProgressHUD in Frameworks */,
D87364F92AE28DB500C8F919 /* Kanna in Frameworks */,
FB24973A2D6771D500A508B2 /* Boutique in Frameworks */,
2AAAA34E2B04DE21004C6672 /* VisionKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -3186,7 +3184,6 @@
357FEEAE29523D470021C9DC /* MastodonSDKDynamic */,
D87364F82AE28DB500C8F919 /* Kanna */,
D84FA0922AE6915800987F47 /* MBProgressHUD */,
FB2497392D6771D500A508B2 /* Boutique */,
);
productName = Mastodon;
productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */;
@ -3372,7 +3369,6 @@
2AB501192992322500346092 /* XCRemoteSwiftPackageReference "LightChart" */,
D87364F72AE28DB500C8F919 /* XCRemoteSwiftPackageReference "Kanna" */,
D84FA0912AE6915800987F47 /* XCRemoteSwiftPackageReference "MBProgressHUD" */,
FB2497382D67704100A508B2 /* XCRemoteSwiftPackageReference "Boutique" */,
);
productRefGroup = DB427DD325BAA00100D1B89D /* Products */;
projectDirPath = "";
@ -5455,14 +5451,6 @@
minimumVersion = 5.2.7;
};
};
FB2497382D67704100A508B2 /* XCRemoteSwiftPackageReference "Boutique" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/mergesort/Boutique.git";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.4.9;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
@ -5509,11 +5497,6 @@
package = D87364F72AE28DB500C8F919 /* XCRemoteSwiftPackageReference "Kanna" */;
productName = Kanna;
};
FB2497392D6771D500A508B2 /* Boutique */ = {
isa = XCSwiftPackageProductDependency;
package = FB2497382D67704100A508B2 /* XCRemoteSwiftPackageReference "Boutique" */;
productName = Boutique;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = DB427DCA25BAA00100D1B89D /* Project object */;

View File

@ -1,136 +0,0 @@
// Copyright © 2025 Mastodon gGmbH. All rights reserved.
import MastodonSDK
import Boutique
import MastodonCore
extension MastodonFeedKind {
var storageTag: String? {
switch self {
case .notificationsAll:
return "all"
case .notificationsMentionsOnly:
return "mentions"
case .notificationsWithAccount:
return nil
}
}
}
fileprivate let storageFileNameComponentSeparator = "_"
fileprivate func storeFilenameFromBasename(_ basename: String, kind: MastodonFeedKind, forUser userIdentifier: MastodonUserIdentifier) -> String {
assert(kind.storageTag != nil, "ATTEMPTING TO CACHE A FEED TYPE THAT SHOULD NOT BE CACHED")
let components = [userIdentifier.globallyUniqueUserIdentifier,
basename,
(kind.storageTag ?? "UNEXPECTED")]
return components.joined(separator: storageFileNameComponentSeparator)
}
extension Store where Item == Mastodon.Entity.Notification {
static func ungroupedNotificationStore(forKind feedKind: MastodonFeedKind, forUser userIdentifier: MastodonUserIdentifier) -> Store<Mastodon.Entity.Notification> {
return Store<Mastodon.Entity.Notification>(
storage: SQLiteStorageEngine.default(appendingPath: storeFilenameFromBasename("ungrouped_notification_store", kind: feedKind, forUser: userIdentifier)), cacheIdentifier: \.id)
}
}
extension Store where Item == Mastodon.Entity.NotificationGroup {
static func notificationGroupStore(forKind feedKind: MastodonFeedKind, forUser userIdentifier: MastodonUserIdentifier) -> Store<Mastodon.Entity.NotificationGroup> {
return Store<Mastodon.Entity.NotificationGroup>(
storage: SQLiteStorageEngine.default(appendingPath: storeFilenameFromBasename("notification_group_store", kind: feedKind, forUser: userIdentifier)), cacheIdentifier: \.id)
}
}
extension Store where Item == Mastodon.Entity.Account {
static func notificationRelevantFullAccountStore(forKind feedKind: MastodonFeedKind, forUser userIdentifier: MastodonUserIdentifier) -> Store<Mastodon.Entity.Account> {
return Store<Mastodon.Entity.Account>(
storage: SQLiteStorageEngine.default(appendingPath: storeFilenameFromBasename("notification_relevant_full_account_store", kind: feedKind, forUser: userIdentifier)), cacheIdentifier: \.id)
}
}
extension Store where Item == Mastodon.Entity.PartialAccountWithAvatar {
static func notificationRelevantPartialAccountStore(forKind feedKind: MastodonFeedKind, forUser userIdentifier: MastodonUserIdentifier) -> Store<Mastodon.Entity.PartialAccountWithAvatar> {
return Store<Mastodon.Entity.PartialAccountWithAvatar>(
storage: SQLiteStorageEngine.default(appendingPath: storeFilenameFromBasename("notification_relevant_partial_account_store", kind: feedKind, forUser: userIdentifier)), cacheIdentifier: \.id)
}
}
extension Store where Item == Mastodon.Entity.Status {
static func notificationRelevantStatusStore(forKind feedKind: MastodonFeedKind, forUser userIdentifier: MastodonUserIdentifier) -> Store<Mastodon.Entity.Status> {
return Store<Mastodon.Entity.Status>(
storage: SQLiteStorageEngine.default(appendingPath: storeFilenameFromBasename("notification_relevant_status_store", kind: feedKind, forUser: userIdentifier)), cacheIdentifier: \.id)
}
}
extension Store where Item == LastReadMarkers {
static func lastReadMarkersStore() -> Store<LastReadMarkers> {
return Store<LastReadMarkers>(
storage: SQLiteStorageEngine.default(appendingPath: "last_read_markers_store"), cacheIdentifier: \.id)
}
}
struct LastReadMarkers: Identifiable, Codable {
enum MarkerPosition: Codable {
case local(lastReadID: String)
case fromServer(Mastodon.Entity.Marker.Position)
var lastReadID: String {
switch self {
case .local(let lastReadID):
return lastReadID
case .fromServer(let position):
return position.lastReadID
}
}
}
let userGUID: String
let homeTimelineLastRead: MarkerPosition?
let notificationsLastRead: MarkerPosition?
let mentionsLastRead: MarkerPosition?
var id: String {
return userGUID
}
init(userGUID: String, home: MarkerPosition?, notifications: MarkerPosition?, mentions: MarkerPosition?) {
self.userGUID = userGUID
self.homeTimelineLastRead = home
self.notificationsLastRead = notifications
if let notifications, let mentions {
if mentions.lastReadID > notifications.lastReadID {
self.mentionsLastRead = mentions
} else {
self.mentionsLastRead = nil
}
} else {
self.mentionsLastRead = mentions
}
}
func lastRead(forKind kind: MastodonFeedKind) -> MarkerPosition? {
switch kind {
case .notificationsAll:
return notificationsLastRead
case .notificationsMentionsOnly:
return mentionsLastRead ?? notificationsLastRead
case .notificationsWithAccount:
return nil
}
}
func bySettingLastRead(_ newPosition: MarkerPosition, forKind kind: MastodonFeedKind) -> LastReadMarkers {
if let previous = lastRead(forKind: kind) {
guard previous.lastReadID < newPosition.lastReadID else { return self }
}
switch kind {
case .notificationsAll:
return LastReadMarkers(userGUID: userGUID, home: homeTimelineLastRead, notifications: newPosition, mentions: mentionsLastRead)
case .notificationsMentionsOnly:
return LastReadMarkers(userGUID: userGUID, home: homeTimelineLastRead, notifications: notificationsLastRead, mentions: newPosition)
case .notificationsWithAccount:
return self
}
}
}

View File

@ -0,0 +1,71 @@
// Copyright © 2025 Mastodon gGmbH. All rights reserved.
import MastodonSDK
import MastodonCore
import Foundation
struct LastReadMarkers: Identifiable, Codable {
enum MarkerPosition: Codable {
case local(lastReadID: String)
case fromServer(Mastodon.Entity.Marker.Position)
var lastReadID: String {
switch self {
case .local(let lastReadID):
return lastReadID
case .fromServer(let position):
return position.lastReadID
}
}
}
let userGUID: String
let homeTimelineLastRead: MarkerPosition?
let notificationsLastRead: MarkerPosition?
let mentionsLastRead: MarkerPosition?
var id: String {
return userGUID
}
init(userGUID: String, home: MarkerPosition?, notifications: MarkerPosition?, mentions: MarkerPosition?) {
self.userGUID = userGUID
self.homeTimelineLastRead = home
self.notificationsLastRead = notifications
if let notifications, let mentions {
if mentions.lastReadID > notifications.lastReadID {
self.mentionsLastRead = mentions
} else {
self.mentionsLastRead = nil
}
} else {
self.mentionsLastRead = mentions
}
}
func lastRead(forKind kind: MastodonFeedKind) -> MarkerPosition? {
switch kind {
case .notificationsAll:
return notificationsLastRead
case .notificationsMentionsOnly:
return mentionsLastRead ?? notificationsLastRead
case .notificationsWithAccount:
return nil
}
}
func bySettingLastRead(_ newPosition: MarkerPosition, forKind kind: MastodonFeedKind) -> LastReadMarkers {
if let previous = lastRead(forKind: kind) {
guard previous.lastReadID < newPosition.lastReadID else { return self }
}
switch kind {
case .notificationsAll:
return LastReadMarkers(userGUID: userGUID, home: homeTimelineLastRead, notifications: newPosition, mentions: mentionsLastRead)
case .notificationsMentionsOnly:
return LastReadMarkers(userGUID: userGUID, home: homeTimelineLastRead, notifications: notificationsLastRead, mentions: newPosition)
case .notificationsWithAccount:
return self
}
}
}

View File

@ -1,6 +1,5 @@
// Copyright © 2025 Mastodon gGmbH. All rights reserved.
import Boutique
import MastodonSDK
import MastodonCore
@ -61,7 +60,7 @@ class UngroupedNotificationCacheManager: NotificationsCacheManager {
staleResults = try PersistenceManager.shared.cached(.notificationsAll(userIdentifier))
case .notificationsMentionsOnly:
staleResults = try PersistenceManager.shared.cached(.notificationsMentions(userIdentifier))
case .notificationsWithAccount(let string):
case .notificationsWithAccount:
staleResults = nil
}
} catch {
@ -294,7 +293,7 @@ class GroupedNotificationCacheManager: NotificationsCacheManager {
accounts = (try? PersistenceManager.shared.cached(.groupedNotificationsMentionsAccounts(userIdentifier))) ?? []
partialAccounts = (try? PersistenceManager.shared.cached(.groupedNotificationsMentionsPartialAccounts(userIdentifier))) ?? []
statuses = (try? PersistenceManager.shared.cached(.groupedNotificationsMentionsStatuses(userIdentifier))) ?? []
case .notificationsWithAccount(let string):
case .notificationsWithAccount:
return mostRecentlyFetchedResults
}
staleResults = Mastodon.Entity.GroupedNotificationsResults(notificationGroups: notificationGroups, fullAccounts: accounts, partialAccounts: partialAccounts, statuses: statuses)