diff --git a/AppShared/Info.plist b/AppShared/Info.plist
index f652792e..697cdf4d 100644
--- a/AppShared/Info.plist
+++ b/AppShared/Info.plist
@@ -17,6 +17,6 @@
CFBundleShortVersionString
1.3.0
CFBundleVersion
- 90
+ 91
diff --git a/CoreDataStack/.sourcery.yml b/CoreDataStack/.sourcery.yml
new file mode 100644
index 00000000..ac3ddce8
--- /dev/null
+++ b/CoreDataStack/.sourcery.yml
@@ -0,0 +1,6 @@
+sources:
+ - .
+templates:
+ - ./Template
+output:
+ Generated
\ No newline at end of file
diff --git a/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion b/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion
index 3d5e5761..cdd244c9 100644
--- a/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion
+++ b/CoreDataStack/CoreData.xcdatamodeld/.xccurrentversion
@@ -3,6 +3,6 @@
_XCCurrentVersionName
- CoreData 2.xcdatamodel
+ CoreData 3.xcdatamodel
diff --git a/CoreDataStack/CoreData.xcdatamodeld/CoreData 2.xcdatamodel/contents b/CoreDataStack/CoreData.xcdatamodeld/CoreData 2.xcdatamodel/contents
index 6d576ca1..f4a7b801 100644
--- a/CoreDataStack/CoreData.xcdatamodeld/CoreData 2.xcdatamodel/contents
+++ b/CoreDataStack/CoreData.xcdatamodeld/CoreData 2.xcdatamodel/contents
@@ -1,5 +1,5 @@
-
+
diff --git a/CoreDataStack/CoreData.xcdatamodeld/CoreData 3.xcdatamodel/contents b/CoreDataStack/CoreData.xcdatamodeld/CoreData 3.xcdatamodel/contents
new file mode 100644
index 00000000..cba342df
--- /dev/null
+++ b/CoreDataStack/CoreData.xcdatamodeld/CoreData 3.xcdatamodel/contents
@@ -0,0 +1,283 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/CoreDataStack/Entity/App/Feed.swift b/CoreDataStack/Entity/App/Feed.swift
new file mode 100644
index 00000000..0a44a409
--- /dev/null
+++ b/CoreDataStack/Entity/App/Feed.swift
@@ -0,0 +1,198 @@
+//
+// Feed.swift
+// CoreDataStack
+//
+// Created by MainasuK on 2022-1-11.
+//
+
+import Foundation
+import CoreData
+
+final public class Feed: NSManagedObject {
+
+ @NSManaged public private(set) var acctRaw: String
+ // sourcery: autoGenerateProperty
+ public var acct: Acct {
+ get {
+ Acct(rawValue: acctRaw) ?? .none
+ }
+ set {
+ acctRaw = newValue.rawValue
+ }
+ }
+
+ @NSManaged public private(set) var kindRaw: String
+ // sourcery: autoGenerateProperty
+ public var kind: Kind {
+ get {
+ Kind(rawValue: kindRaw) ?? .none
+ }
+ set {
+ kindRaw = newValue.rawValue
+ }
+ }
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var hasMore: Bool
+ // sourcery: autoUpdatableObject
+ @NSManaged public private(set) var isLoadingMore: Bool
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var createdAt: Date
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var updatedAt: Date
+
+ // one-to-one relationship
+ @NSManaged public private(set) var status: Status?
+ @NSManaged public private(set) var notification: Notification?
+
+}
+
+extension Feed {
+
+ @discardableResult
+ public static func insert(
+ into context: NSManagedObjectContext,
+ property: Property
+ ) -> Feed {
+ let object: Feed = context.insertObject()
+ object.configure(property: property)
+ return object
+ }
+
+}
+
+extension Feed: Managed {
+ public static var defaultSortDescriptors: [NSSortDescriptor] {
+ return [NSSortDescriptor(keyPath: \Feed.createdAt, ascending: false)]
+ }
+}
+
+extension Feed {
+
+ static func predicate(kind: Kind) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(Feed.kindRaw), kind.rawValue)
+ }
+
+ static func predicate(acct: Acct) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(Feed.acctRaw), acct.rawValue)
+ }
+
+ public static func predicate(kind: Kind, acct: Acct) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ Feed.predicate(kind: kind),
+ Feed.predicate(acct: acct)
+ ])
+ }
+
+ public static func nonePredicate() -> NSPredicate {
+ return predicate(kind: .none, acct: .none)
+ }
+
+ public static func hasMorePredicate() -> NSPredicate {
+ return NSPredicate(format: "%K == YES", #keyPath(Feed.hasMore))
+ }
+
+ public static func hasNotificationPredicate() -> NSPredicate {
+ return NSPredicate(format: "%K != nil", #keyPath(Feed.notification))
+ }
+
+ public static func notificationTypePredicate(types: [MastodonNotificationType]) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ hasNotificationPredicate(),
+ NSPredicate(
+ format: "%K.%K IN %@",
+ #keyPath(Feed.notification),
+ #keyPath(Notification.typeRaw),
+ types.map { $0.rawValue }
+ )
+ ])
+ }
+
+}
+
+// MARK: - AutoGenerateProperty
+extension Feed: AutoGenerateProperty {
+ // sourcery:inline:Feed.AutoGenerateProperty
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public struct Property {
+ public let acct: Acct
+ public let kind: Kind
+ public let hasMore: Bool
+ public let createdAt: Date
+ public let updatedAt: Date
+
+ public init(
+ acct: Acct,
+ kind: Kind,
+ hasMore: Bool,
+ createdAt: Date,
+ updatedAt: Date
+ ) {
+ self.acct = acct
+ self.kind = kind
+ self.hasMore = hasMore
+ self.createdAt = createdAt
+ self.updatedAt = updatedAt
+ }
+ }
+
+ public func configure(property: Property) {
+ self.acct = property.acct
+ self.kind = property.kind
+ self.hasMore = property.hasMore
+ self.createdAt = property.createdAt
+ self.updatedAt = property.updatedAt
+ }
+
+ public func update(property: Property) {
+ update(hasMore: property.hasMore)
+ update(createdAt: property.createdAt)
+ update(updatedAt: property.updatedAt)
+ }
+ // sourcery:end
+}
+
+// MARK: - AutoUpdatableObject
+extension Feed: AutoUpdatableObject {
+ // sourcery:inline:Feed.AutoUpdatableObject
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public func update(hasMore: Bool) {
+ if self.hasMore != hasMore {
+ self.hasMore = hasMore
+ }
+ }
+ public func update(isLoadingMore: Bool) {
+ if self.isLoadingMore != isLoadingMore {
+ self.isLoadingMore = isLoadingMore
+ }
+ }
+ public func update(createdAt: Date) {
+ if self.createdAt != createdAt {
+ self.createdAt = createdAt
+ }
+ }
+ public func update(updatedAt: Date) {
+ if self.updatedAt != updatedAt {
+ self.updatedAt = updatedAt
+ }
+ }
+ // sourcery:end
+}
+
+public protocol FeedIndexable {
+ var feeds: Set { get }
+ func feed(kind: Feed.Kind, acct: Feed.Acct) -> Feed?
+}
+
+extension FeedIndexable {
+ public func feed(kind: Feed.Kind, acct: Feed.Acct) -> Feed? {
+ return feeds.first(where: { feed in
+ feed.kind == kind && feed.acct == acct
+ })
+ }
+}
diff --git a/CoreDataStack/Entity/HomeTimelineIndex.swift b/CoreDataStack/Entity/App/HomeTimelineIndex.swift
similarity index 100%
rename from CoreDataStack/Entity/HomeTimelineIndex.swift
rename to CoreDataStack/Entity/App/HomeTimelineIndex.swift
diff --git a/CoreDataStack/Entity/Setting.swift b/CoreDataStack/Entity/App/Setting.swift
similarity index 100%
rename from CoreDataStack/Entity/Setting.swift
rename to CoreDataStack/Entity/App/Setting.swift
diff --git a/CoreDataStack/Entity/Attachment.swift b/CoreDataStack/Entity/Attachment.swift
deleted file mode 100644
index f3f5d262..00000000
--- a/CoreDataStack/Entity/Attachment.swift
+++ /dev/null
@@ -1,126 +0,0 @@
-//
-// Attachment.swift
-// CoreDataStack
-//
-// Created by MainasuK Cirno on 2021-2-23.
-//
-
-import CoreData
-import Foundation
-
-public final class Attachment: NSManagedObject {
- public typealias ID = String
-
- @NSManaged public private(set) var id: ID
- @NSManaged public private(set) var domain: String
- @NSManaged public private(set) var typeRaw: String
- @NSManaged public private(set) var url: String
- @NSManaged public private(set) var previewURL: String?
-
- @NSManaged public private(set) var remoteURL: String?
- @NSManaged public private(set) var metaData: Data?
- @NSManaged public private(set) var textURL: String?
- @NSManaged public private(set) var descriptionString: String?
- @NSManaged public private(set) var blurhash: String?
-
- @NSManaged public private(set) var createdAt: Date
- @NSManaged public private(set) var updatedAt: Date
- @NSManaged public private(set) var index: NSNumber
-
- // many-to-one relationship
- @NSManaged public private(set) var status: Status?
-
-}
-
-public extension Attachment {
-
- override func awakeFromInsert() {
- super.awakeFromInsert()
- setPrimitiveValue(Date(), forKey: #keyPath(Attachment.createdAt))
- }
-
- @discardableResult
- static func insert(
- into context: NSManagedObjectContext,
- property: Property
- ) -> Attachment {
- let attachment: Attachment = context.insertObject()
-
- attachment.domain = property.domain
- attachment.index = property.index
-
- attachment.id = property.id
- attachment.typeRaw = property.typeRaw
- attachment.url = property.url
- attachment.previewURL = property.previewURL
-
- attachment.remoteURL = property.remoteURL
- attachment.metaData = property.metaData
- attachment.textURL = property.textURL
- attachment.descriptionString = property.descriptionString
- attachment.blurhash = property.blurhash
-
- attachment.updatedAt = property.networkDate
-
- return attachment
- }
-
- func didUpdate(at networkDate: Date) {
- self.updatedAt = networkDate
- }
-
-}
-
-public extension Attachment {
- struct Property {
- public let domain: String
- public let index: NSNumber
-
- public let id: ID
- public let typeRaw: String
- public let url: String
-
- public let previewURL: String?
- public let remoteURL: String?
- public let metaData: Data?
- public let textURL: String?
- public let descriptionString: String?
- public let blurhash: String?
-
- public let networkDate: Date
-
- public init(
- domain: String,
- index: Int,
- id: Attachment.ID,
- typeRaw: String,
- url: String,
- previewURL: String?,
- remoteURL: String?,
- metaData: Data?,
- textURL: String?,
- descriptionString: String?,
- blurhash: String?,
- networkDate: Date
- ) {
- self.domain = domain
- self.index = NSNumber(value: index)
- self.id = id
- self.typeRaw = typeRaw
- self.url = url
- self.previewURL = previewURL
- self.remoteURL = remoteURL
- self.metaData = metaData
- self.textURL = textURL
- self.descriptionString = descriptionString
- self.blurhash = blurhash
- self.networkDate = networkDate
- }
- }
-}
-
-extension Attachment: Managed {
- public static var defaultSortDescriptors: [NSSortDescriptor] {
- return [NSSortDescriptor(keyPath: \Attachment.createdAt, ascending: false)]
- }
-}
diff --git a/CoreDataStack/Entity/Application.swift b/CoreDataStack/Entity/Mastodon/Application.swift
similarity index 100%
rename from CoreDataStack/Entity/Application.swift
rename to CoreDataStack/Entity/Mastodon/Application.swift
diff --git a/CoreDataStack/Entity/DomainBlock.swift b/CoreDataStack/Entity/Mastodon/DomainBlock.swift
similarity index 100%
rename from CoreDataStack/Entity/DomainBlock.swift
rename to CoreDataStack/Entity/Mastodon/DomainBlock.swift
diff --git a/CoreDataStack/Entity/Emoji.swift b/CoreDataStack/Entity/Mastodon/Emoji.swift
similarity index 100%
rename from CoreDataStack/Entity/Emoji.swift
rename to CoreDataStack/Entity/Mastodon/Emoji.swift
diff --git a/CoreDataStack/Entity/History.swift b/CoreDataStack/Entity/Mastodon/History.swift
similarity index 100%
rename from CoreDataStack/Entity/History.swift
rename to CoreDataStack/Entity/Mastodon/History.swift
diff --git a/CoreDataStack/Entity/Instance.swift b/CoreDataStack/Entity/Mastodon/Instance.swift
similarity index 100%
rename from CoreDataStack/Entity/Instance.swift
rename to CoreDataStack/Entity/Mastodon/Instance.swift
diff --git a/CoreDataStack/Entity/MastodonAuthentication.swift b/CoreDataStack/Entity/Mastodon/MastodonAuthentication.swift
similarity index 100%
rename from CoreDataStack/Entity/MastodonAuthentication.swift
rename to CoreDataStack/Entity/Mastodon/MastodonAuthentication.swift
diff --git a/CoreDataStack/Entity/Mastodon/MastodonUser.swift b/CoreDataStack/Entity/Mastodon/MastodonUser.swift
new file mode 100644
index 00000000..3def7efd
--- /dev/null
+++ b/CoreDataStack/Entity/Mastodon/MastodonUser.swift
@@ -0,0 +1,604 @@
+//
+// MastodonUser.swift
+// CoreDataStack
+//
+// Created by MainasuK Cirno on 2021/1/27.
+//
+
+import CoreData
+import Foundation
+
+final public class MastodonUser: NSManagedObject {
+
+ public typealias ID = String
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var identifier: ID
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var domain: String
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var id: ID
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var acct: String
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var username: String
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var displayName: String
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var avatar: String
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var avatarStatic: String?
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var header: String
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var headerStatic: String?
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var note: String?
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var url: String?
+
+ @NSManaged public private(set) var emojisData: Data?
+ @NSManaged public private(set) var fieldsData: Data?
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var statusesCount: Int64
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var followingCount: Int64
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var followersCount: Int64
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var locked: Bool
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var bot: Bool
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var suspended: Bool
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var createdAt: Date
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var updatedAt: Date
+
+ // one-to-one relationship
+ @NSManaged public private(set) var pinnedStatus: Status?
+ @NSManaged public private(set) var mastodonAuthentication: MastodonAuthentication?
+
+ // one-to-many relationship
+ @NSManaged public private(set) var statuses: Set
+ @NSManaged public private(set) var notifications: Set
+ @NSManaged public private(set) var searchHistories: Set
+
+ // many-to-many relationship
+ @NSManaged public private(set) var favourite: Set
+ @NSManaged public private(set) var reblogged: Set
+ @NSManaged public private(set) var muted: Set
+ @NSManaged public private(set) var bookmarked: Set
+ @NSManaged public private(set) var votePollOptions: Set
+ @NSManaged public private(set) var votePolls: Set
+ // relationships
+ @NSManaged public private(set) var following: Set
+ @NSManaged public private(set) var followingBy: Set
+ @NSManaged public private(set) var followRequested: Set
+ @NSManaged public private(set) var followRequestedBy: Set
+ @NSManaged public private(set) var muting: Set
+ @NSManaged public private(set) var mutingBy: Set
+ @NSManaged public private(set) var blocking: Set
+ @NSManaged public private(set) var blockingBy: Set
+ @NSManaged public private(set) var endorsed: Set
+ @NSManaged public private(set) var endorsedBy: Set
+ @NSManaged public private(set) var domainBlocking: Set
+ @NSManaged public private(set) var domainBlockingBy: Set
+
+}
+
+extension MastodonUser {
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @objc public var emojis: [MastodonEmoji] {
+ get {
+ let keyPath = #keyPath(MastodonUser.emojis)
+ willAccessValue(forKey: keyPath)
+ let _data = primitiveValue(forKey: keyPath) as? Data
+ didAccessValue(forKey: keyPath)
+ do {
+ guard let data = _data else { return [] }
+ let emojis = try JSONDecoder().decode([MastodonEmoji].self, from: data)
+ return emojis
+ } catch {
+ assertionFailure(error.localizedDescription)
+ return []
+ }
+ }
+ set {
+ let keyPath = #keyPath(MastodonUser.emojis)
+ let data = try? JSONEncoder().encode(newValue)
+ willChangeValue(forKey: keyPath)
+ setPrimitiveValue(data, forKey: keyPath)
+ didChangeValue(forKey: keyPath)
+ }
+ }
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @objc public var fields: [MastodonField] {
+ get {
+ let keyPath = #keyPath(MastodonUser.fields)
+ willAccessValue(forKey: keyPath)
+ let _data = primitiveValue(forKey: keyPath) as? Data
+ didAccessValue(forKey: keyPath)
+ do {
+ guard let data = _data else { return [] }
+ let fields = try JSONDecoder().decode([MastodonField].self, from: data)
+ return fields
+ } catch {
+ assertionFailure(error.localizedDescription)
+ return []
+ }
+ }
+ set {
+ let keyPath = #keyPath(MastodonUser.fields)
+ let data = try? JSONEncoder().encode(newValue)
+ willChangeValue(forKey: keyPath)
+ setPrimitiveValue(data, forKey: keyPath)
+ didChangeValue(forKey: keyPath)
+ }
+ }
+}
+
+extension MastodonUser {
+
+ @discardableResult
+ public static func insert(
+ into context: NSManagedObjectContext,
+ property: Property
+ ) -> MastodonUser {
+ let object: MastodonUser = context.insertObject()
+ object.configure(property: property)
+ return object
+ }
+
+}
+
+extension MastodonUser: Managed {
+ public static var defaultSortDescriptors: [NSSortDescriptor] {
+ return [NSSortDescriptor(keyPath: \MastodonUser.createdAt, ascending: false)]
+ }
+}
+
+extension MastodonUser {
+
+ static func predicate(domain: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(MastodonUser.domain), domain)
+ }
+
+ static func predicate(id: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(MastodonUser.id), id)
+ }
+
+ public static func predicate(domain: String, id: String) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ MastodonUser.predicate(domain: domain),
+ MastodonUser.predicate(id: id)
+ ])
+ }
+
+ static func predicate(ids: [String]) -> NSPredicate {
+ return NSPredicate(format: "%K IN %@", #keyPath(MastodonUser.id), ids)
+ }
+
+ public static func predicate(domain: String, ids: [String]) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ MastodonUser.predicate(domain: domain),
+ MastodonUser.predicate(ids: ids)
+ ])
+ }
+
+ static func predicate(username: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(MastodonUser.username), username)
+ }
+
+ public static func predicate(domain: String, username: String) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ MastodonUser.predicate(domain: domain),
+ MastodonUser.predicate(username: username)
+ ])
+ }
+
+}
+
+
+extension MastodonUser {
+
+ public func findSearchHistory(
+ domain: String,
+ userID: MastodonUser.ID
+ ) -> SearchHistory? {
+ return searchHistories.first { searchHistory in
+ return searchHistory.domain == domain
+ && searchHistory.userID == userID
+ }
+ }
+
+ public func findSearchHistory(for user: MastodonUser) -> SearchHistory? {
+ return searchHistories.first { searchHistory in
+ return searchHistory.domain == user.domain
+ && searchHistory.userID == user.id
+ }
+ }
+
+}
+
+// MARK: - AutoGenerateProperty
+extension MastodonUser: AutoGenerateProperty {
+ // sourcery:inline:MastodonUser.AutoGenerateProperty
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public struct Property {
+ public let identifier: ID
+ public let domain: String
+ public let id: ID
+ public let acct: String
+ public let username: String
+ public let displayName: String
+ public let avatar: String
+ public let avatarStatic: String?
+ public let header: String
+ public let headerStatic: String?
+ public let note: String?
+ public let url: String?
+ public let statusesCount: Int64
+ public let followingCount: Int64
+ public let followersCount: Int64
+ public let locked: Bool
+ public let bot: Bool
+ public let suspended: Bool
+ public let createdAt: Date
+ public let updatedAt: Date
+ public let emojis: [MastodonEmoji]
+ public let fields: [MastodonField]
+
+ public init(
+ identifier: ID,
+ domain: String,
+ id: ID,
+ acct: String,
+ username: String,
+ displayName: String,
+ avatar: String,
+ avatarStatic: String?,
+ header: String,
+ headerStatic: String?,
+ note: String?,
+ url: String?,
+ statusesCount: Int64,
+ followingCount: Int64,
+ followersCount: Int64,
+ locked: Bool,
+ bot: Bool,
+ suspended: Bool,
+ createdAt: Date,
+ updatedAt: Date,
+ emojis: [MastodonEmoji],
+ fields: [MastodonField]
+ ) {
+ self.identifier = identifier
+ self.domain = domain
+ self.id = id
+ self.acct = acct
+ self.username = username
+ self.displayName = displayName
+ self.avatar = avatar
+ self.avatarStatic = avatarStatic
+ self.header = header
+ self.headerStatic = headerStatic
+ self.note = note
+ self.url = url
+ self.statusesCount = statusesCount
+ self.followingCount = followingCount
+ self.followersCount = followersCount
+ self.locked = locked
+ self.bot = bot
+ self.suspended = suspended
+ self.createdAt = createdAt
+ self.updatedAt = updatedAt
+ self.emojis = emojis
+ self.fields = fields
+ }
+ }
+
+ public func configure(property: Property) {
+ self.identifier = property.identifier
+ self.domain = property.domain
+ self.id = property.id
+ self.acct = property.acct
+ self.username = property.username
+ self.displayName = property.displayName
+ self.avatar = property.avatar
+ self.avatarStatic = property.avatarStatic
+ self.header = property.header
+ self.headerStatic = property.headerStatic
+ self.note = property.note
+ self.url = property.url
+ self.statusesCount = property.statusesCount
+ self.followingCount = property.followingCount
+ self.followersCount = property.followersCount
+ self.locked = property.locked
+ self.bot = property.bot
+ self.suspended = property.suspended
+ self.createdAt = property.createdAt
+ self.updatedAt = property.updatedAt
+ self.emojis = property.emojis
+ self.fields = property.fields
+ }
+
+ public func update(property: Property) {
+ update(acct: property.acct)
+ update(username: property.username)
+ update(displayName: property.displayName)
+ update(avatar: property.avatar)
+ update(avatarStatic: property.avatarStatic)
+ update(header: property.header)
+ update(headerStatic: property.headerStatic)
+ update(note: property.note)
+ update(url: property.url)
+ update(statusesCount: property.statusesCount)
+ update(followingCount: property.followingCount)
+ update(followersCount: property.followersCount)
+ update(locked: property.locked)
+ update(bot: property.bot)
+ update(suspended: property.suspended)
+ update(createdAt: property.createdAt)
+ update(updatedAt: property.updatedAt)
+ update(emojis: property.emojis)
+ update(fields: property.fields)
+ }
+ // sourcery:end
+}
+
+//extension MastodonUser {
+// public struct Property {
+// public let identifier: String
+// public let domain: String
+//
+// public let id: String
+// public let acct: String
+// public let username: String
+// public let displayName: String
+// public let avatar: String
+// public let avatarStatic: String?
+// public let header: String
+// public let headerStatic: String?
+// public let note: String?
+// public let url: String?
+// public let emojisData: Data?
+// public let fieldsData: Data?
+// public let statusesCount: Int
+// public let followingCount: Int
+// public let followersCount: Int
+// public let locked: Bool
+// public let bot: Bool?
+// public let suspended: Bool?
+//
+// public let createdAt: Date
+// public let networkDate: Date
+//
+// public init(
+// id: String,
+// domain: String,
+// acct: String,
+// username: String,
+// displayName: String,
+// avatar: String,
+// avatarStatic: String?,
+// header: String,
+// headerStatic: String?,
+// note: String?,
+// url: String?,
+// emojisData: Data?,
+// fieldsData: Data?,
+// statusesCount: Int,
+// followingCount: Int,
+// followersCount: Int,
+// locked: Bool,
+// bot: Bool?,
+// suspended: Bool?,
+// createdAt: Date,
+// networkDate: Date
+// ) {
+// self.identifier = id + "@" + domain
+// self.domain = domain
+// self.id = id
+// self.acct = acct
+// self.username = username
+// self.displayName = displayName
+// self.avatar = avatar
+// self.avatarStatic = avatarStatic
+// self.header = header
+// self.headerStatic = headerStatic
+// self.note = note
+// self.url = url
+// self.emojisData = emojisData
+// self.fieldsData = fieldsData
+// self.statusesCount = statusesCount
+// self.followingCount = followingCount
+// self.followersCount = followersCount
+// self.locked = locked
+// self.bot = bot
+// self.suspended = suspended
+// self.createdAt = createdAt
+// self.networkDate = networkDate
+// }
+// }
+//}
+
+// MARK: - AutoUpdatableObject
+extension MastodonUser: AutoUpdatableObject {
+ // sourcery:inline:MastodonUser.AutoUpdatableObject
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public func update(acct: String) {
+ if self.acct != acct {
+ self.acct = acct
+ }
+ }
+ public func update(username: String) {
+ if self.username != username {
+ self.username = username
+ }
+ }
+ public func update(displayName: String) {
+ if self.displayName != displayName {
+ self.displayName = displayName
+ }
+ }
+ public func update(avatar: String) {
+ if self.avatar != avatar {
+ self.avatar = avatar
+ }
+ }
+ public func update(avatarStatic: String?) {
+ if self.avatarStatic != avatarStatic {
+ self.avatarStatic = avatarStatic
+ }
+ }
+ public func update(header: String) {
+ if self.header != header {
+ self.header = header
+ }
+ }
+ public func update(headerStatic: String?) {
+ if self.headerStatic != headerStatic {
+ self.headerStatic = headerStatic
+ }
+ }
+ public func update(note: String?) {
+ if self.note != note {
+ self.note = note
+ }
+ }
+ public func update(url: String?) {
+ if self.url != url {
+ self.url = url
+ }
+ }
+ public func update(statusesCount: Int64) {
+ if self.statusesCount != statusesCount {
+ self.statusesCount = statusesCount
+ }
+ }
+ public func update(followingCount: Int64) {
+ if self.followingCount != followingCount {
+ self.followingCount = followingCount
+ }
+ }
+ public func update(followersCount: Int64) {
+ if self.followersCount != followersCount {
+ self.followersCount = followersCount
+ }
+ }
+ public func update(locked: Bool) {
+ if self.locked != locked {
+ self.locked = locked
+ }
+ }
+ public func update(bot: Bool) {
+ if self.bot != bot {
+ self.bot = bot
+ }
+ }
+ public func update(suspended: Bool) {
+ if self.suspended != suspended {
+ self.suspended = suspended
+ }
+ }
+ public func update(createdAt: Date) {
+ if self.createdAt != createdAt {
+ self.createdAt = createdAt
+ }
+ }
+ public func update(updatedAt: Date) {
+ if self.updatedAt != updatedAt {
+ self.updatedAt = updatedAt
+ }
+ }
+ public func update(emojis: [MastodonEmoji]) {
+ if self.emojis != emojis {
+ self.emojis = emojis
+ }
+ }
+ public func update(fields: [MastodonField]) {
+ if self.fields != fields {
+ self.fields = fields
+ }
+ }
+ // sourcery:end
+
+ public func update(isFollowing: Bool, by mastodonUser: MastodonUser) {
+ if isFollowing {
+ if !self.followingBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.followingBy)).add(mastodonUser)
+ }
+ } else {
+ if self.followingBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.followingBy)).remove(mastodonUser)
+ }
+ }
+ }
+ public func update(isFollowRequested: Bool, by mastodonUser: MastodonUser) {
+ if isFollowRequested {
+ if !self.followRequestedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.followRequestedBy)).add(mastodonUser)
+ }
+ } else {
+ if self.followRequestedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.followRequestedBy)).remove(mastodonUser)
+ }
+ }
+ }
+ public func update(isMuting: Bool, by mastodonUser: MastodonUser) {
+ if isMuting {
+ if !self.mutingBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.mutingBy)).add(mastodonUser)
+ }
+ } else {
+ if self.mutingBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.mutingBy)).remove(mastodonUser)
+ }
+ }
+ }
+ public func update(isBlocking: Bool, by mastodonUser: MastodonUser) {
+ if isBlocking {
+ if !self.blockingBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.blockingBy)).add(mastodonUser)
+ }
+ } else {
+ if self.blockingBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.blockingBy)).remove(mastodonUser)
+ }
+ }
+ }
+ public func update(isEndorsed: Bool, by mastodonUser: MastodonUser) {
+ if isEndorsed {
+ if !self.endorsedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.endorsedBy)).add(mastodonUser)
+ }
+ } else {
+ if self.endorsedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.endorsedBy)).remove(mastodonUser)
+ }
+ }
+ }
+ public func update(isDomainBlocking: Bool, by mastodonUser: MastodonUser) {
+ if isDomainBlocking {
+ if !self.domainBlockingBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.domainBlockingBy)).add(mastodonUser)
+ }
+ } else {
+ if self.domainBlockingBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(MastodonUser.domainBlockingBy)).remove(mastodonUser)
+ }
+ }
+ }
+
+}
diff --git a/CoreDataStack/Entity/Mastodon/Notification.swift b/CoreDataStack/Entity/Mastodon/Notification.swift
new file mode 100644
index 00000000..85019b0d
--- /dev/null
+++ b/CoreDataStack/Entity/Mastodon/Notification.swift
@@ -0,0 +1,207 @@
+//
+// Notification.swift
+// CoreDataStack
+//
+// Created by sxiaojian on 2021/4/13.
+//
+
+import Foundation
+import CoreData
+
+public final class Notification: NSManagedObject {
+ public typealias ID = String
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var id: ID
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var typeRaw: String
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var domain: String
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var userID: String
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var createAt: Date
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var updatedAt: Date
+
+ // one-to-one relationship
+ // sourcery: autoGenerateRelationship
+ @NSManaged public private(set) var account: MastodonUser
+ // sourcery: autoGenerateRelationship
+ @NSManaged public private(set) var status: Status?
+
+ // many-to-one relationship
+ @NSManaged public private(set) var feeds: Set
+
+}
+
+extension Notification: FeedIndexable { }
+
+extension Notification {
+ @discardableResult
+ public static func insert(
+ into context: NSManagedObjectContext,
+ property: Property,
+ relationship: Relationship
+ ) -> Notification {
+ let object: Notification = context.insertObject()
+
+ object.configure(property: property)
+ object.configure(relationship: relationship)
+
+ return object
+ }
+}
+
+extension Notification: Managed {
+ public static var defaultSortDescriptors: [NSSortDescriptor] {
+ return [NSSortDescriptor(keyPath: \Notification.createAt, ascending: false)]
+ }
+}
+
+extension Notification {
+ static func predicate(domain: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(Notification.domain), domain)
+ }
+
+ static func predicate(userID: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(Notification.userID), userID)
+ }
+
+ static func predicate(id: ID) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(Notification.id), id)
+ }
+
+ static func predicate(typeRaw: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(Notification.typeRaw), typeRaw)
+ }
+
+ public static func predicate(
+ domain: String,
+ userID: String,
+ id: ID
+ ) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ Notification.predicate(domain: domain),
+ Notification.predicate(userID: userID),
+ Notification.predicate(id: id)
+ ])
+ }
+
+ public static func predicate(
+ domain: String,
+ userID: String,
+ typeRaw: String? = nil
+ ) -> NSPredicate {
+ if let typeRaw = typeRaw {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ Notification.predicate(domain: domain),
+ Notification.predicate(typeRaw: typeRaw),
+ Notification.predicate(userID: userID),
+ ])
+ } else {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ Notification.predicate(domain: domain),
+ Notification.predicate(userID: userID)
+ ])
+ }
+ }
+
+ public static func predicate(validTypesRaws types: [String]) -> NSPredicate {
+ return NSPredicate(format: "%K IN %@", #keyPath(Notification.typeRaw), types)
+ }
+
+}
+
+// MARK: - AutoGenerateProperty
+extension Notification: AutoGenerateProperty {
+ // sourcery:inline:Notification.AutoGenerateProperty
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public struct Property {
+ public let id: ID
+ public let typeRaw: String
+ public let domain: String
+ public let userID: String
+ public let createAt: Date
+ public let updatedAt: Date
+
+ public init(
+ id: ID,
+ typeRaw: String,
+ domain: String,
+ userID: String,
+ createAt: Date,
+ updatedAt: Date
+ ) {
+ self.id = id
+ self.typeRaw = typeRaw
+ self.domain = domain
+ self.userID = userID
+ self.createAt = createAt
+ self.updatedAt = updatedAt
+ }
+ }
+
+ public func configure(property: Property) {
+ self.id = property.id
+ self.typeRaw = property.typeRaw
+ self.domain = property.domain
+ self.userID = property.userID
+ self.createAt = property.createAt
+ self.updatedAt = property.updatedAt
+ }
+
+ public func update(property: Property) {
+ update(updatedAt: property.updatedAt)
+ }
+ // sourcery:end
+}
+
+// MARK: - AutoGenerateRelationship
+extension Notification: AutoGenerateRelationship {
+ // sourcery:inline:Notification.AutoGenerateRelationship
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public struct Relationship {
+ public let account: MastodonUser
+ public let status: Status?
+
+ public init(
+ account: MastodonUser,
+ status: Status?
+ ) {
+ self.account = account
+ self.status = status
+ }
+ }
+
+ public func configure(relationship: Relationship) {
+ self.account = relationship.account
+ self.status = relationship.status
+ }
+ // sourcery:end
+}
+
+// MARK: - AutoUpdatableObject
+extension Notification: AutoUpdatableObject {
+ // sourcery:inline:Notification.AutoUpdatableObject
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public func update(updatedAt: Date) {
+ if self.updatedAt != updatedAt {
+ self.updatedAt = updatedAt
+ }
+ }
+ // sourcery:end
+}
+
+extension Notification {
+ public func attach(feed: Feed) {
+ mutableSetValue(forKey: #keyPath(Notification.feeds)).add(feed)
+ }
+}
diff --git a/CoreDataStack/Entity/Mastodon/Poll.swift b/CoreDataStack/Entity/Mastodon/Poll.swift
new file mode 100644
index 00000000..a237f539
--- /dev/null
+++ b/CoreDataStack/Entity/Mastodon/Poll.swift
@@ -0,0 +1,326 @@
+//
+// Poll.swift
+// CoreDataStack
+//
+// Created by MainasuK Cirno on 2021-3-2.
+//
+
+import Foundation
+import CoreData
+
+public final class Poll: NSManagedObject {
+ public typealias ID = String
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var domain: String
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var id: ID
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var expiresAt: Date?
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var expired: Bool
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var multiple: Bool
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var votesCount: Int64
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var votersCount: Int64
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var createdAt: Date
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var updatedAt: Date
+
+ // sourcery: autoUpdatableObject
+ @NSManaged public private(set) var isVoting: Bool
+
+ // one-to-one relationship
+ @NSManaged public private(set) var status: Status
+
+ // one-to-many relationship
+ @NSManaged public private(set) var options: Set
+
+ // many-to-many relationship
+ @NSManaged public private(set) var votedBy: Set?
+}
+
+extension Poll {
+
+ @discardableResult
+ public static func insert(
+ into context: NSManagedObjectContext,
+ property: Property
+ ) -> Poll {
+ let object: Poll = context.insertObject()
+
+ object.configure(property: property)
+
+ return object
+ }
+
+}
+
+extension Poll: Managed {
+ public static var defaultSortDescriptors: [NSSortDescriptor] {
+ return [NSSortDescriptor(keyPath: \Poll.createdAt, ascending: false)]
+ }
+}
+
+extension Poll {
+ static func predicate(domain: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(Poll.domain), domain)
+ }
+
+ static func predicate(id: ID) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(Poll.id), id)
+ }
+
+ static func predicate(ids: [ID]) -> NSPredicate {
+ return NSPredicate(format: "%K IN %@", #keyPath(Poll.id), ids)
+ }
+
+ public static func predicate(domain: String, id: ID) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ predicate(domain: domain),
+ predicate(id: id)
+ ])
+ }
+
+ public static func predicate(domain: String, ids: [ID]) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ predicate(domain: domain),
+ predicate(ids: ids)
+ ])
+ }
+}
+
+//extension Poll {
+//
+// public override func awakeFromInsert() {
+// super.awakeFromInsert()
+// setPrimitiveValue(Date(), forKey: #keyPath(Poll.createdAt))
+// }
+//
+// @discardableResult
+// public static func insert(
+// into context: NSManagedObjectContext,
+// property: Property,
+// votedBy: MastodonUser?,
+// options: [PollOption]
+// ) -> Poll {
+// let poll: Poll = context.insertObject()
+//
+// poll.id = property.id
+// poll.expiresAt = property.expiresAt
+// poll.expired = property.expired
+// poll.multiple = property.multiple
+// poll.votesCount = property.votesCount
+// poll.votersCount = property.votersCount
+//
+//
+// poll.updatedAt = property.networkDate
+//
+// if let votedBy = votedBy {
+// poll.mutableSetValue(forKey: #keyPath(Poll.votedBy)).add(votedBy)
+// }
+// poll.mutableSetValue(forKey: #keyPath(Poll.options)).addObjects(from: options)
+//
+// return poll
+// }
+//
+// public func update(expiresAt: Date?) {
+// if self.expiresAt != expiresAt {
+// self.expiresAt = expiresAt
+// }
+// }
+//
+// public func update(expired: Bool) {
+// if self.expired != expired {
+// self.expired = expired
+// }
+// }
+//
+// public func update(votesCount: Int) {
+// if self.votesCount.intValue != votesCount {
+// self.votesCount = NSNumber(value: votesCount)
+// }
+// }
+//
+// public func update(votersCount: Int?) {
+// if self.votersCount?.intValue != votersCount {
+// self.votersCount = votersCount.flatMap { NSNumber(value: $0) }
+// }
+// }
+//
+// public func update(voted: Bool, by: MastodonUser) {
+// if voted {
+// if !(votedBy ?? Set()).contains(by) {
+// mutableSetValue(forKey: #keyPath(Poll.votedBy)).add(by)
+// }
+// } else {
+// if (votedBy ?? Set()).contains(by) {
+// mutableSetValue(forKey: #keyPath(Poll.votedBy)).remove(by)
+// }
+// }
+// }
+//
+// public func didUpdate(at networkDate: Date) {
+// self.updatedAt = networkDate
+// }
+//
+//}
+
+//extension Poll {
+// public struct Property {
+// public let id: ID
+// public let expiresAt: Date?
+// public let expired: Bool
+// public let multiple: Bool
+// public let votesCount: NSNumber
+// public let votersCount: NSNumber?
+//
+// public let networkDate: Date
+//
+// public init(
+// id: Poll.ID,
+// expiresAt: Date?,
+// expired: Bool,
+// multiple: Bool,
+// votesCount: Int,
+// votersCount: Int?,
+// networkDate: Date
+// ) {
+// self.id = id
+// self.expiresAt = expiresAt
+// self.expired = expired
+// self.multiple = multiple
+// self.votesCount = NSNumber(value: votesCount)
+// self.votersCount = votersCount.flatMap { NSNumber(value: $0) }
+// self.networkDate = networkDate
+// }
+// }
+//}
+
+// MARK: - AutoGenerateProperty
+extension Poll: AutoGenerateProperty {
+ // sourcery:inline:Poll.AutoGenerateProperty
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public struct Property {
+ public let domain: String
+ public let id: ID
+ public let expiresAt: Date?
+ public let expired: Bool
+ public let multiple: Bool
+ public let votesCount: Int64
+ public let votersCount: Int64
+ public let createdAt: Date
+ public let updatedAt: Date
+
+ public init(
+ domain: String,
+ id: ID,
+ expiresAt: Date?,
+ expired: Bool,
+ multiple: Bool,
+ votesCount: Int64,
+ votersCount: Int64,
+ createdAt: Date,
+ updatedAt: Date
+ ) {
+ self.domain = domain
+ self.id = id
+ self.expiresAt = expiresAt
+ self.expired = expired
+ self.multiple = multiple
+ self.votesCount = votesCount
+ self.votersCount = votersCount
+ self.createdAt = createdAt
+ self.updatedAt = updatedAt
+ }
+ }
+
+ public func configure(property: Property) {
+ self.domain = property.domain
+ self.id = property.id
+ self.expiresAt = property.expiresAt
+ self.expired = property.expired
+ self.multiple = property.multiple
+ self.votesCount = property.votesCount
+ self.votersCount = property.votersCount
+ self.createdAt = property.createdAt
+ self.updatedAt = property.updatedAt
+ }
+
+ public func update(property: Property) {
+ update(expiresAt: property.expiresAt)
+ update(expired: property.expired)
+ update(votesCount: property.votesCount)
+ update(votersCount: property.votersCount)
+ update(updatedAt: property.updatedAt)
+ }
+ // sourcery:end
+
+}
+
+// MARK: - AutoUpdatableObject
+extension Poll: AutoUpdatableObject {
+ // sourcery:inline:Poll.AutoUpdatableObject
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public func update(expiresAt: Date?) {
+ if self.expiresAt != expiresAt {
+ self.expiresAt = expiresAt
+ }
+ }
+ public func update(expired: Bool) {
+ if self.expired != expired {
+ self.expired = expired
+ }
+ }
+ public func update(votesCount: Int64) {
+ if self.votesCount != votesCount {
+ self.votesCount = votesCount
+ }
+ }
+ public func update(votersCount: Int64) {
+ if self.votersCount != votersCount {
+ self.votersCount = votersCount
+ }
+ }
+ public func update(updatedAt: Date) {
+ if self.updatedAt != updatedAt {
+ self.updatedAt = updatedAt
+ }
+ }
+ public func update(isVoting: Bool) {
+ if self.isVoting != isVoting {
+ self.isVoting = isVoting
+ }
+ }
+ // sourcery:end
+
+ public func update(voted: Bool, by: MastodonUser) {
+ if voted {
+ if !(votedBy ?? Set()).contains(by) {
+ mutableSetValue(forKey: #keyPath(Poll.votedBy)).add(by)
+ }
+ } else {
+ if (votedBy ?? Set()).contains(by) {
+ mutableSetValue(forKey: #keyPath(Poll.votedBy)).remove(by)
+ }
+ }
+ }
+
+ public func attach(options: [PollOption]) {
+ for option in options {
+ guard !self.options.contains(option) else { continue }
+ self.mutableSetValue(forKey: #keyPath(Poll.options)).add(option)
+ }
+ }
+}
diff --git a/CoreDataStack/Entity/Mastodon/PollOption.swift b/CoreDataStack/Entity/Mastodon/PollOption.swift
new file mode 100644
index 00000000..2799dd0a
--- /dev/null
+++ b/CoreDataStack/Entity/Mastodon/PollOption.swift
@@ -0,0 +1,199 @@
+//
+// PollOption.swift
+// CoreDataStack
+//
+// Created by MainasuK Cirno on 2021-3-2.
+//
+
+import Foundation
+import CoreData
+
+public final class PollOption: NSManagedObject {
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var index: Int64
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var title: String
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var votesCount: Int64
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var createdAt: Date
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var updatedAt: Date
+
+ // sourcery: autoUpdatableObject
+ @NSManaged public private(set) var isSelected: Bool
+
+ // many-to-one relationship
+ @NSManaged public private(set) var poll: Poll
+
+ // many-to-many relationship
+ @NSManaged public private(set) var votedBy: Set?
+}
+
+
+extension PollOption {
+
+ @discardableResult
+ public static func insert(
+ into context: NSManagedObjectContext,
+ property: Property
+ ) -> PollOption {
+ let object: PollOption = context.insertObject()
+
+ object.configure(property: property)
+
+ return object
+ }
+
+}
+
+extension PollOption: Managed {
+ public static var defaultSortDescriptors: [NSSortDescriptor] {
+ return [NSSortDescriptor(keyPath: \PollOption.createdAt, ascending: false)]
+ }
+}
+
+//extension PollOption {
+//
+// public override func awakeFromInsert() {
+// super.awakeFromInsert()
+// setPrimitiveValue(Date(), forKey: #keyPath(PollOption.createdAt))
+// }
+//
+// @discardableResult
+// public static func insert(
+// into context: NSManagedObjectContext,
+// property: Property,
+// votedBy: MastodonUser?
+// ) -> PollOption {
+// let option: PollOption = context.insertObject()
+//
+// option.index = property.index
+// option.title = property.title
+// option.votesCount = property.votesCount
+// option.updatedAt = property.networkDate
+//
+// if let votedBy = votedBy {
+// option.mutableSetValue(forKey: #keyPath(PollOption.votedBy)).add(votedBy)
+// }
+//
+// return option
+// }
+//
+// public func update(votesCount: Int?) {
+// if self.votesCount?.intValue != votesCount {
+// self.votesCount = votesCount.flatMap { NSNumber(value: $0) }
+// }
+// }
+//
+// public func didUpdate(at networkDate: Date) {
+// self.updatedAt = networkDate
+// }
+//
+//}
+
+//extension PollOption {
+// public struct Property {
+// public let index: NSNumber
+// public let title: String
+// public let votesCount: NSNumber?
+//
+// public let networkDate: Date
+//
+// public init(index: Int, title: String, votesCount: Int?, networkDate: Date) {
+// self.index = NSNumber(value: index)
+// self.title = title
+// self.votesCount = votesCount.flatMap { NSNumber(value: $0) }
+// self.networkDate = networkDate
+// }
+// }
+//}
+//
+
+// MARK: - AutoGenerateProperty
+extension PollOption: AutoGenerateProperty {
+ // sourcery:inline:PollOption.AutoGenerateProperty
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public struct Property {
+ public let index: Int64
+ public let title: String
+ public let votesCount: Int64
+ public let createdAt: Date
+ public let updatedAt: Date
+
+ public init(
+ index: Int64,
+ title: String,
+ votesCount: Int64,
+ createdAt: Date,
+ updatedAt: Date
+ ) {
+ self.index = index
+ self.title = title
+ self.votesCount = votesCount
+ self.createdAt = createdAt
+ self.updatedAt = updatedAt
+ }
+ }
+
+ public func configure(property: Property) {
+ self.index = property.index
+ self.title = property.title
+ self.votesCount = property.votesCount
+ self.createdAt = property.createdAt
+ self.updatedAt = property.updatedAt
+ }
+
+ public func update(property: Property) {
+ update(title: property.title)
+ update(votesCount: property.votesCount)
+ update(updatedAt: property.updatedAt)
+ }
+ // sourcery:end
+}
+
+// MARK: - AutoUpdatableObject
+extension PollOption: AutoUpdatableObject {
+ // sourcery:inline:PollOption.AutoUpdatableObject
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public func update(title: String) {
+ if self.title != title {
+ self.title = title
+ }
+ }
+ public func update(votesCount: Int64) {
+ if self.votesCount != votesCount {
+ self.votesCount = votesCount
+ }
+ }
+ public func update(updatedAt: Date) {
+ if self.updatedAt != updatedAt {
+ self.updatedAt = updatedAt
+ }
+ }
+ public func update(isSelected: Bool) {
+ if self.isSelected != isSelected {
+ self.isSelected = isSelected
+ }
+ }
+ // sourcery:end
+
+ public func update(voted: Bool, by: MastodonUser) {
+ if voted {
+ if !(self.votedBy ?? Set()).contains(by) {
+ self.mutableSetValue(forKey: #keyPath(PollOption.votedBy)).add(by)
+ }
+ } else {
+ if (self.votedBy ?? Set()).contains(by) {
+ self.mutableSetValue(forKey: #keyPath(PollOption.votedBy)).remove(by)
+ }
+ }
+ }
+}
diff --git a/CoreDataStack/Entity/PrivateNote.swift b/CoreDataStack/Entity/Mastodon/PrivateNote.swift
similarity index 100%
rename from CoreDataStack/Entity/PrivateNote.swift
rename to CoreDataStack/Entity/Mastodon/PrivateNote.swift
diff --git a/CoreDataStack/Entity/Mastodon/SearchHistory.swift b/CoreDataStack/Entity/Mastodon/SearchHistory.swift
new file mode 100644
index 00000000..c3c6d28c
--- /dev/null
+++ b/CoreDataStack/Entity/Mastodon/SearchHistory.swift
@@ -0,0 +1,158 @@
+//
+// SearchHistory.swift
+// CoreDataStack
+//
+// Created by sxiaojian on 2021/4/7.
+//
+
+import Foundation
+import CoreData
+
+public final class SearchHistory: NSManagedObject {
+ public typealias ID = UUID
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var identifier: ID
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var domain: String
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var userID: MastodonUser.ID
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var createAt: Date
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var updatedAt: Date
+
+ // many-to-one relationship
+ // sourcery: autoGenerateRelationship
+ @NSManaged public private(set) var account: MastodonUser?
+ // sourcery: autoGenerateRelationship
+ @NSManaged public private(set) var hashtag: Tag?
+ // sourcery: autoGenerateRelationship
+ @NSManaged public private(set) var status: Status?
+
+}
+
+extension SearchHistory {
+ @discardableResult
+ public static func insert(
+ into context: NSManagedObjectContext,
+ property: Property,
+ relationship: Relationship
+ ) -> SearchHistory {
+ let object: SearchHistory = context.insertObject()
+
+ object.configure(property: property)
+ object.configure(relationship: relationship)
+
+ return object
+ }
+}
+
+extension SearchHistory: Managed {
+ public static var defaultSortDescriptors: [NSSortDescriptor] {
+ return [NSSortDescriptor(keyPath: \SearchHistory.updatedAt, ascending: false)]
+ }
+}
+
+extension SearchHistory {
+ static func predicate(domain: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(SearchHistory.domain), domain)
+ }
+
+ static func predicate(userID: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(SearchHistory.userID), userID)
+ }
+
+ public static func predicate(domain: String, userID: String) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ predicate(domain: domain),
+ predicate(userID: userID)
+ ])
+ }
+}
+
+// MARK: - AutoGenerateProperty
+extension SearchHistory: AutoGenerateProperty {
+ // sourcery:inline:SearchHistory.AutoGenerateProperty
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public struct Property {
+ public let identifier: ID
+ public let domain: String
+ public let userID: MastodonUser.ID
+ public let createAt: Date
+ public let updatedAt: Date
+
+ public init(
+ identifier: ID,
+ domain: String,
+ userID: MastodonUser.ID,
+ createAt: Date,
+ updatedAt: Date
+ ) {
+ self.identifier = identifier
+ self.domain = domain
+ self.userID = userID
+ self.createAt = createAt
+ self.updatedAt = updatedAt
+ }
+ }
+
+ public func configure(property: Property) {
+ self.identifier = property.identifier
+ self.domain = property.domain
+ self.userID = property.userID
+ self.createAt = property.createAt
+ self.updatedAt = property.updatedAt
+ }
+
+ public func update(property: Property) {
+ update(updatedAt: property.updatedAt)
+ }
+ // sourcery:end
+}
+
+// MARK: - AutoGenerateRelationship
+extension SearchHistory: AutoGenerateRelationship {
+ // sourcery:inline:SearchHistory.AutoGenerateRelationship
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public struct Relationship {
+ public let account: MastodonUser?
+ public let hashtag: Tag?
+ public let status: Status?
+
+ public init(
+ account: MastodonUser?,
+ hashtag: Tag?,
+ status: Status?
+ ) {
+ self.account = account
+ self.hashtag = hashtag
+ self.status = status
+ }
+ }
+
+ public func configure(relationship: Relationship) {
+ self.account = relationship.account
+ self.hashtag = relationship.hashtag
+ self.status = relationship.status
+ }
+ // sourcery:end
+}
+
+// MARK: - AutoUpdatableObject
+extension SearchHistory: AutoUpdatableObject {
+ // sourcery:inline:SearchHistory.AutoUpdatableObject
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public func update(updatedAt: Date) {
+ if self.updatedAt != updatedAt {
+ self.updatedAt = updatedAt
+ }
+ }
+ // sourcery:end
+}
diff --git a/CoreDataStack/Entity/Mastodon/Status.swift b/CoreDataStack/Entity/Mastodon/Status.swift
new file mode 100644
index 00000000..c506536d
--- /dev/null
+++ b/CoreDataStack/Entity/Mastodon/Status.swift
@@ -0,0 +1,802 @@
+//
+// Status.swift
+// CoreDataStack
+//
+// Created by MainasuK Cirno on 2021/1/27.
+//
+
+import CoreData
+import Foundation
+
+public final class Status: NSManagedObject {
+ public typealias ID = String
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var identifier: ID
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var domain: String
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var id: String
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var uri: String
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var createdAt: Date
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var content: String
+
+ @NSManaged public private(set) var visibilityRaw: String
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ public var visibility: MastodonVisibility {
+ get {
+ let rawValue = visibilityRaw
+ return MastodonVisibility(rawValue: rawValue) ?? ._other(rawValue)
+ }
+ set {
+ visibilityRaw = newValue.rawValue
+ }
+ }
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var sensitive: Bool
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var spoilerText: String?
+
+ @NSManaged public private(set) var application: Application?
+
+ // Informational
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var reblogsCount: Int64
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var favouritesCount: Int64
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var repliesCount: Int64
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var url: String?
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var inReplyToID: Status.ID?
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var inReplyToAccountID: MastodonUser.ID?
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var language: String? // (ISO 639 Part 1 two-letter language code)
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var text: String?
+
+ // many-to-one relationship
+ // sourcery: autoGenerateRelationship
+ @NSManaged public private(set) var author: MastodonUser
+ // sourcery: autoGenerateRelationship
+ @NSManaged public private(set) var reblog: Status?
+ // sourcery: autoUpdatableObject
+ @NSManaged public private(set) var replyTo: Status?
+
+ // many-to-many relationship
+ @NSManaged public private(set) var favouritedBy: Set
+ @NSManaged public private(set) var rebloggedBy: Set
+ @NSManaged public private(set) var mutedBy: Set
+ @NSManaged public private(set) var bookmarkedBy: Set
+
+ // one-to-one relationship
+ @NSManaged public private(set) var pinnedBy: MastodonUser?
+ // sourcery: autoGenerateRelationship
+ @NSManaged public private(set) var poll: Poll?
+
+ // one-to-many relationship
+ @NSManaged public private(set) var feeds: Set
+
+ @NSManaged public private(set) var reblogFrom: Set
+// @NSManaged public private(set) var mentions: Set?
+// @NSManaged public private(set) var homeTimelineIndexes: Set?
+// @NSManaged public private(set) var mediaAttachments: Set?
+ @NSManaged public private(set) var replyFrom: Set
+ @NSManaged public private(set) var notifications: Set
+ @NSManaged public private(set) var searchHistories: Set
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var updatedAt: Date
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var deletedAt: Date?
+ // sourcery: autoUpdatableObject
+ @NSManaged public private(set) var revealedAt: Date?
+}
+
+extension Status {
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @objc public var attachments: [MastodonAttachment] {
+ get {
+ let keyPath = #keyPath(Status.attachments)
+ willAccessValue(forKey: keyPath)
+ let _data = primitiveValue(forKey: keyPath) as? Data
+ didAccessValue(forKey: keyPath)
+ do {
+ guard let data = _data else { return [] }
+ let attachments = try JSONDecoder().decode([MastodonAttachment].self, from: data)
+ return attachments
+ } catch {
+ assertionFailure(error.localizedDescription)
+ return []
+ }
+ }
+ set {
+ let keyPath = #keyPath(Status.attachments)
+ let data = try? JSONEncoder().encode(newValue)
+ willChangeValue(forKey: keyPath)
+ setPrimitiveValue(data, forKey: keyPath)
+ didChangeValue(forKey: keyPath)
+ }
+ }
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @objc public var emojis: [MastodonEmoji] {
+ get {
+ let keyPath = #keyPath(Status.emojis)
+ willAccessValue(forKey: keyPath)
+ let _data = primitiveValue(forKey: keyPath) as? Data
+ didAccessValue(forKey: keyPath)
+ do {
+ guard let data = _data else { return [] }
+ let emojis = try JSONDecoder().decode([MastodonEmoji].self, from: data)
+ return emojis
+ } catch {
+ assertionFailure(error.localizedDescription)
+ return []
+ }
+ }
+ set {
+ let keyPath = #keyPath(Status.emojis)
+ let data = try? JSONEncoder().encode(newValue)
+ willChangeValue(forKey: keyPath)
+ setPrimitiveValue(data, forKey: keyPath)
+ didChangeValue(forKey: keyPath)
+ }
+ }
+
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @objc public var mentions: [MastodonMention] {
+ get {
+ let keyPath = #keyPath(Status.mentions)
+ willAccessValue(forKey: keyPath)
+ let _data = primitiveValue(forKey: keyPath) as? Data
+ didAccessValue(forKey: keyPath)
+ do {
+ guard let data = _data else { return [] }
+ let emojis = try JSONDecoder().decode([MastodonMention].self, from: data)
+ return emojis
+ } catch {
+ assertionFailure(error.localizedDescription)
+ return []
+ }
+ }
+ set {
+ let keyPath = #keyPath(Status.mentions)
+ let data = try? JSONEncoder().encode(newValue)
+ willChangeValue(forKey: keyPath)
+ setPrimitiveValue(data, forKey: keyPath)
+ didChangeValue(forKey: keyPath)
+ }
+ }
+}
+
+extension Status: FeedIndexable { }
+
+extension Status {
+
+ @discardableResult
+ public static func insert(
+ into context: NSManagedObjectContext,
+ property: Property,
+ relationship: Relationship
+ ) -> Status {
+ let object: Status = context.insertObject()
+
+ object.configure(property: property)
+ object.configure(relationship: relationship)
+
+ return object
+ }
+
+// @discardableResult
+// public static func insert(
+// into context: NSManagedObjectContext,
+// property: Property,
+// author: MastodonUser,
+// reblog: Status?,
+// application: Application?,
+// replyTo: Status?,
+// poll: Poll?,
+// mentions: [Mention]?,
+// mediaAttachments: [Attachment]?,
+// favouritedBy: MastodonUser?,
+// rebloggedBy: MastodonUser?,
+// mutedBy: MastodonUser?,
+// bookmarkedBy: MastodonUser?,
+// pinnedBy: MastodonUser?
+// ) -> Status {
+// let status: Status = context.insertObject()
+//
+// status.identifier = property.identifier
+// status.domain = property.domain
+//
+// status.id = property.id
+// status.uri = property.uri
+// status.createdAt = property.createdAt
+// status.content = property.content
+//
+// status.visibility = property.visibility
+// status.sensitive = property.sensitive
+// status.spoilerText = property.spoilerText
+// status.application = application
+//
+// status.emojisData = property.emojisData
+//
+// status.reblogsCount = property.reblogsCount
+// status.favouritesCount = property.favouritesCount
+// status.repliesCount = property.repliesCount
+//
+// status.url = property.url
+// status.inReplyToID = property.inReplyToID
+// status.inReplyToAccountID = property.inReplyToAccountID
+//
+// status.language = property.language
+// status.text = property.text
+//
+// status.author = author
+// status.reblog = reblog
+//
+// status.pinnedBy = pinnedBy
+// status.poll = poll
+//
+// if let mentions = mentions {
+// status.mutableSetValue(forKey: #keyPath(Status.mentions)).addObjects(from: mentions)
+// }
+// if let mediaAttachments = mediaAttachments {
+// status.mutableSetValue(forKey: #keyPath(Status.mediaAttachments)).addObjects(from: mediaAttachments)
+// }
+// if let favouritedBy = favouritedBy {
+// status.mutableSetValue(forKey: #keyPath(Status.favouritedBy)).add(favouritedBy)
+// }
+// if let rebloggedBy = rebloggedBy {
+// status.mutableSetValue(forKey: #keyPath(Status.rebloggedBy)).add(rebloggedBy)
+// }
+// if let mutedBy = mutedBy {
+// status.mutableSetValue(forKey: #keyPath(Status.mutedBy)).add(mutedBy)
+// }
+// if let bookmarkedBy = bookmarkedBy {
+// status.mutableSetValue(forKey: #keyPath(Status.bookmarkedBy)).add(bookmarkedBy)
+// }
+//
+// status.updatedAt = property.networkDate
+//
+// return status
+// }
+//
+// public func update(emojisData: Data?) {
+// if self.emojisData != emojisData {
+// self.emojisData = emojisData
+// }
+// }
+//
+// public func update(reblogsCount: NSNumber) {
+// if self.reblogsCount.intValue != reblogsCount.intValue {
+// self.reblogsCount = reblogsCount
+// }
+// }
+//
+// public func update(favouritesCount: NSNumber) {
+// if self.favouritesCount.intValue != favouritesCount.intValue {
+// self.favouritesCount = favouritesCount
+// }
+// }
+//
+// public func update(repliesCount: NSNumber?) {
+// guard let count = repliesCount else {
+// return
+// }
+// if self.repliesCount?.intValue != count.intValue {
+// self.repliesCount = repliesCount
+// }
+// }
+//
+// public func update(replyTo: Status?) {
+// if self.replyTo != replyTo {
+// self.replyTo = replyTo
+// }
+// }
+//
+// public func update(liked: Bool, by mastodonUser: MastodonUser) {
+// if liked {
+// if !(self.favouritedBy ?? Set()).contains(mastodonUser) {
+// self.mutableSetValue(forKey: #keyPath(Status.favouritedBy)).add(mastodonUser)
+// }
+// } else {
+// if (self.favouritedBy ?? Set()).contains(mastodonUser) {
+// self.mutableSetValue(forKey: #keyPath(Status.favouritedBy)).remove(mastodonUser)
+// }
+// }
+// }
+//
+// public func update(reblogged: Bool, by mastodonUser: MastodonUser) {
+// if reblogged {
+// if !(self.rebloggedBy ?? Set()).contains(mastodonUser) {
+// self.mutableSetValue(forKey: #keyPath(Status.rebloggedBy)).add(mastodonUser)
+// }
+// } else {
+// if (self.rebloggedBy ?? Set()).contains(mastodonUser) {
+// self.mutableSetValue(forKey: #keyPath(Status.rebloggedBy)).remove(mastodonUser)
+// }
+// }
+// }
+//
+// public func update(muted: Bool, by mastodonUser: MastodonUser) {
+// if muted {
+// if !(self.mutedBy ?? Set()).contains(mastodonUser) {
+// self.mutableSetValue(forKey: #keyPath(Status.mutedBy)).add(mastodonUser)
+// }
+// } else {
+// if (self.mutedBy ?? Set()).contains(mastodonUser) {
+// self.mutableSetValue(forKey: #keyPath(Status.mutedBy)).remove(mastodonUser)
+// }
+// }
+// }
+//
+// public func update(bookmarked: Bool, by mastodonUser: MastodonUser) {
+// if bookmarked {
+// if !(self.bookmarkedBy ?? Set()).contains(mastodonUser) {
+// self.mutableSetValue(forKey: #keyPath(Status.bookmarkedBy)).add(mastodonUser)
+// }
+// } else {
+// if (self.bookmarkedBy ?? Set()).contains(mastodonUser) {
+// self.mutableSetValue(forKey: #keyPath(Status.bookmarkedBy)).remove(mastodonUser)
+// }
+// }
+// }
+//
+// public func didUpdate(at networkDate: Date) {
+// self.updatedAt = networkDate
+// }
+
+}
+
+extension Status: Managed {
+ public static var defaultSortDescriptors: [NSSortDescriptor] {
+ return [NSSortDescriptor(keyPath: \Status.createdAt, ascending: false)]
+ }
+}
+
+extension Status {
+
+ static func predicate(domain: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(Status.domain), domain)
+ }
+
+ static func predicate(id: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(Status.id), id)
+ }
+
+ public static func predicate(domain: String, id: String) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ predicate(domain: domain),
+ predicate(id: id)
+ ])
+ }
+
+ static func predicate(ids: [String]) -> NSPredicate {
+ return NSPredicate(format: "%K IN %@", #keyPath(Status.id), ids)
+ }
+
+ public static func predicate(domain: String, ids: [String]) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ predicate(domain: domain),
+ predicate(ids: ids)
+ ])
+ }
+
+ public static func notDeleted() -> NSPredicate {
+ return NSPredicate(format: "%K == nil", #keyPath(Status.deletedAt))
+ }
+
+ public static func deleted() -> NSPredicate {
+ return NSPredicate(format: "%K != nil", #keyPath(Status.deletedAt))
+ }
+
+}
+
+// MARK: - AutoGenerateProperty
+extension Status: AutoGenerateProperty {
+ // sourcery:inline:Status.AutoGenerateProperty
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public struct Property {
+ public let identifier: ID
+ public let domain: String
+ public let id: String
+ public let uri: String
+ public let createdAt: Date
+ public let content: String
+ public let visibility: MastodonVisibility
+ public let sensitive: Bool
+ public let spoilerText: String?
+ public let reblogsCount: Int64
+ public let favouritesCount: Int64
+ public let repliesCount: Int64
+ public let url: String?
+ public let inReplyToID: Status.ID?
+ public let inReplyToAccountID: MastodonUser.ID?
+ public let language: String?
+ public let text: String?
+ public let updatedAt: Date
+ public let deletedAt: Date?
+ public let attachments: [MastodonAttachment]
+ public let emojis: [MastodonEmoji]
+ public let mentions: [MastodonMention]
+
+ public init(
+ identifier: ID,
+ domain: String,
+ id: String,
+ uri: String,
+ createdAt: Date,
+ content: String,
+ visibility: MastodonVisibility,
+ sensitive: Bool,
+ spoilerText: String?,
+ reblogsCount: Int64,
+ favouritesCount: Int64,
+ repliesCount: Int64,
+ url: String?,
+ inReplyToID: Status.ID?,
+ inReplyToAccountID: MastodonUser.ID?,
+ language: String?,
+ text: String?,
+ updatedAt: Date,
+ deletedAt: Date?,
+ attachments: [MastodonAttachment],
+ emojis: [MastodonEmoji],
+ mentions: [MastodonMention]
+ ) {
+ self.identifier = identifier
+ self.domain = domain
+ self.id = id
+ self.uri = uri
+ self.createdAt = createdAt
+ self.content = content
+ self.visibility = visibility
+ self.sensitive = sensitive
+ self.spoilerText = spoilerText
+ self.reblogsCount = reblogsCount
+ self.favouritesCount = favouritesCount
+ self.repliesCount = repliesCount
+ self.url = url
+ self.inReplyToID = inReplyToID
+ self.inReplyToAccountID = inReplyToAccountID
+ self.language = language
+ self.text = text
+ self.updatedAt = updatedAt
+ self.deletedAt = deletedAt
+ self.attachments = attachments
+ self.emojis = emojis
+ self.mentions = mentions
+ }
+ }
+
+ public func configure(property: Property) {
+ self.identifier = property.identifier
+ self.domain = property.domain
+ self.id = property.id
+ self.uri = property.uri
+ self.createdAt = property.createdAt
+ self.content = property.content
+ self.visibility = property.visibility
+ self.sensitive = property.sensitive
+ self.spoilerText = property.spoilerText
+ self.reblogsCount = property.reblogsCount
+ self.favouritesCount = property.favouritesCount
+ self.repliesCount = property.repliesCount
+ self.url = property.url
+ self.inReplyToID = property.inReplyToID
+ self.inReplyToAccountID = property.inReplyToAccountID
+ self.language = property.language
+ self.text = property.text
+ self.updatedAt = property.updatedAt
+ self.deletedAt = property.deletedAt
+ self.attachments = property.attachments
+ self.emojis = property.emojis
+ self.mentions = property.mentions
+ }
+
+ public func update(property: Property) {
+ update(createdAt: property.createdAt)
+ update(content: property.content)
+ update(visibility: property.visibility)
+ update(sensitive: property.sensitive)
+ update(spoilerText: property.spoilerText)
+ update(reblogsCount: property.reblogsCount)
+ update(favouritesCount: property.favouritesCount)
+ update(repliesCount: property.repliesCount)
+ update(url: property.url)
+ update(inReplyToID: property.inReplyToID)
+ update(inReplyToAccountID: property.inReplyToAccountID)
+ update(language: property.language)
+ update(text: property.text)
+ update(updatedAt: property.updatedAt)
+ update(deletedAt: property.deletedAt)
+ update(attachments: property.attachments)
+ update(emojis: property.emojis)
+ update(mentions: property.mentions)
+ }
+ // sourcery:end
+}
+
+// MARK: - AutoGenerateRelationship
+extension Status: AutoGenerateRelationship {
+ // sourcery:inline:Status.AutoGenerateRelationship
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public struct Relationship {
+ public let author: MastodonUser
+ public let reblog: Status?
+ public let poll: Poll?
+
+ public init(
+ author: MastodonUser,
+ reblog: Status?,
+ poll: Poll?
+ ) {
+ self.author = author
+ self.reblog = reblog
+ self.poll = poll
+ }
+ }
+
+ public func configure(relationship: Relationship) {
+ self.author = relationship.author
+ self.reblog = relationship.reblog
+ self.poll = relationship.poll
+ }
+ // sourcery:end
+}
+
+// MARK: - AutoUpdatableObject
+extension Status: AutoUpdatableObject {
+ // sourcery:inline:Status.AutoUpdatableObject
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public func update(createdAt: Date) {
+ if self.createdAt != createdAt {
+ self.createdAt = createdAt
+ }
+ }
+ public func update(content: String) {
+ if self.content != content {
+ self.content = content
+ }
+ }
+ public func update(visibility: MastodonVisibility) {
+ if self.visibility != visibility {
+ self.visibility = visibility
+ }
+ }
+ public func update(sensitive: Bool) {
+ if self.sensitive != sensitive {
+ self.sensitive = sensitive
+ }
+ }
+ public func update(spoilerText: String?) {
+ if self.spoilerText != spoilerText {
+ self.spoilerText = spoilerText
+ }
+ }
+ public func update(reblogsCount: Int64) {
+ if self.reblogsCount != reblogsCount {
+ self.reblogsCount = reblogsCount
+ }
+ }
+ public func update(favouritesCount: Int64) {
+ if self.favouritesCount != favouritesCount {
+ self.favouritesCount = favouritesCount
+ }
+ }
+ public func update(repliesCount: Int64) {
+ if self.repliesCount != repliesCount {
+ self.repliesCount = repliesCount
+ }
+ }
+ public func update(url: String?) {
+ if self.url != url {
+ self.url = url
+ }
+ }
+ public func update(inReplyToID: Status.ID?) {
+ if self.inReplyToID != inReplyToID {
+ self.inReplyToID = inReplyToID
+ }
+ }
+ public func update(inReplyToAccountID: MastodonUser.ID?) {
+ if self.inReplyToAccountID != inReplyToAccountID {
+ self.inReplyToAccountID = inReplyToAccountID
+ }
+ }
+ public func update(language: String?) {
+ if self.language != language {
+ self.language = language
+ }
+ }
+ public func update(text: String?) {
+ if self.text != text {
+ self.text = text
+ }
+ }
+ public func update(replyTo: Status?) {
+ if self.replyTo != replyTo {
+ self.replyTo = replyTo
+ }
+ }
+ public func update(updatedAt: Date) {
+ if self.updatedAt != updatedAt {
+ self.updatedAt = updatedAt
+ }
+ }
+ public func update(deletedAt: Date?) {
+ if self.deletedAt != deletedAt {
+ self.deletedAt = deletedAt
+ }
+ }
+ public func update(revealedAt: Date?) {
+ if self.revealedAt != revealedAt {
+ self.revealedAt = revealedAt
+ }
+ }
+ public func update(attachments: [MastodonAttachment]) {
+ if self.attachments != attachments {
+ self.attachments = attachments
+ }
+ }
+ public func update(emojis: [MastodonEmoji]) {
+ if self.emojis != emojis {
+ self.emojis = emojis
+ }
+ }
+ public func update(mentions: [MastodonMention]) {
+ if self.mentions != mentions {
+ self.mentions = mentions
+ }
+ }
+ // sourcery:end
+
+ public func update(liked: Bool, by mastodonUser: MastodonUser) {
+ if liked {
+ if !self.favouritedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(Status.favouritedBy)).add(mastodonUser)
+ }
+ } else {
+ if self.favouritedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(Status.favouritedBy)).remove(mastodonUser)
+ }
+ }
+ }
+
+ public func update(reblogged: Bool, by mastodonUser: MastodonUser) {
+ if reblogged {
+ if !self.rebloggedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(Status.rebloggedBy)).add(mastodonUser)
+ }
+ } else {
+ if self.rebloggedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(Status.rebloggedBy)).remove(mastodonUser)
+ }
+ }
+ }
+
+ public func update(muted: Bool, by mastodonUser: MastodonUser) {
+ if muted {
+ if !self.mutedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(Status.mutedBy)).add(mastodonUser)
+ }
+ } else {
+ if self.mutedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(Status.mutedBy)).remove(mastodonUser)
+ }
+ }
+ }
+
+ public func update(bookmarked: Bool, by mastodonUser: MastodonUser) {
+ if bookmarked {
+ if !self.bookmarkedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(Status.bookmarkedBy)).add(mastodonUser)
+ }
+ } else {
+ if self.bookmarkedBy.contains(mastodonUser) {
+ self.mutableSetValue(forKey: #keyPath(Status.bookmarkedBy)).remove(mastodonUser)
+ }
+ }
+ }
+
+ public func update(isReveal: Bool) {
+ revealedAt = isReveal ? Date() : nil
+ }
+}
+
+extension Status {
+ public func attach(feed: Feed) {
+ mutableSetValue(forKey: #keyPath(Status.feeds)).add(feed)
+ }
+}
+
+
+//extension Status {
+// public struct Property {
+//
+// public let identifier: ID
+// public let domain: String
+//
+// public let id: String
+// public let uri: String
+// public let createdAt: Date
+// public let content: String
+//
+// public let visibility: String?
+// public let sensitive: Bool
+// public let spoilerText: String?
+//
+// public let emojisData: Data?
+//
+// public let reblogsCount: NSNumber
+// public let favouritesCount: NSNumber
+// public let repliesCount: NSNumber?
+//
+// public let url: String?
+// public let inReplyToID: Status.ID?
+// public let inReplyToAccountID: MastodonUser.ID?
+// public let language: String? // (ISO 639 Part @1 two-letter language code)
+// public let text: String?
+//
+// public let networkDate: Date
+//
+// public init(
+// domain: String,
+// id: String,
+// uri: String,
+// createdAt: Date,
+// content: String,
+// visibility: String?,
+// sensitive: Bool,
+// spoilerText: String?,
+// emojisData: Data?,
+// reblogsCount: NSNumber,
+// favouritesCount: NSNumber,
+// repliesCount: NSNumber?,
+// url: String?,
+// inReplyToID: Status.ID?,
+// inReplyToAccountID: MastodonUser.ID?,
+// language: String?,
+// text: String?,
+// networkDate: Date
+// ) {
+// self.identifier = id + "@" + domain
+// self.domain = domain
+// self.id = id
+// self.uri = uri
+// self.createdAt = createdAt
+// self.content = content
+// self.visibility = visibility
+// self.sensitive = sensitive
+// self.spoilerText = spoilerText
+// self.emojisData = emojisData
+// self.reblogsCount = reblogsCount
+// self.favouritesCount = favouritesCount
+// self.repliesCount = repliesCount
+// self.url = url
+// self.inReplyToID = inReplyToID
+// self.inReplyToAccountID = inReplyToAccountID
+// self.language = language
+// self.text = text
+// self.networkDate = networkDate
+// }
+//
+// }
+//}
+//
diff --git a/CoreDataStack/Entity/Subscription.swift b/CoreDataStack/Entity/Mastodon/Subscription.swift
similarity index 100%
rename from CoreDataStack/Entity/Subscription.swift
rename to CoreDataStack/Entity/Mastodon/Subscription.swift
diff --git a/CoreDataStack/Entity/SubscriptionAlerts.swift b/CoreDataStack/Entity/Mastodon/SubscriptionAlerts.swift
similarity index 100%
rename from CoreDataStack/Entity/SubscriptionAlerts.swift
rename to CoreDataStack/Entity/Mastodon/SubscriptionAlerts.swift
diff --git a/CoreDataStack/Entity/Mastodon/Tag.swift b/CoreDataStack/Entity/Mastodon/Tag.swift
new file mode 100644
index 00000000..b5c335db
--- /dev/null
+++ b/CoreDataStack/Entity/Mastodon/Tag.swift
@@ -0,0 +1,218 @@
+//
+// Tag.swift
+// CoreDataStack
+//
+// Created by sxiaojian on 2021/2/1.
+//
+
+import CoreData
+import Foundation
+
+public final class Tag: NSManagedObject {
+ public typealias ID = UUID
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var identifier: ID
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var domain: String
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var createAt: Date
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var updatedAt: Date
+
+ // sourcery: autoGenerateProperty
+ @NSManaged public private(set) var name: String
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @NSManaged public private(set) var url: String
+
+ // one-to-one relationship
+
+ // many-to-many relationship
+
+ // one-to-many relationship
+ @NSManaged public private(set) var searchHistories: Set
+}
+
+extension Tag {
+ // sourcery: autoUpdatableObject, autoGenerateProperty
+ @objc public var histories: [MastodonTagHistory] {
+ get {
+ let keyPath = #keyPath(Tag.histories)
+ willAccessValue(forKey: keyPath)
+ let _data = primitiveValue(forKey: keyPath) as? Data
+ didAccessValue(forKey: keyPath)
+ do {
+ guard let data = _data else { return [] }
+ let attachments = try JSONDecoder().decode([MastodonTagHistory].self, from: data)
+ return attachments
+ } catch {
+ assertionFailure(error.localizedDescription)
+ return []
+ }
+ }
+ set {
+ let keyPath = #keyPath(Tag.histories)
+ let data = try? JSONEncoder().encode(newValue)
+ willChangeValue(forKey: keyPath)
+ setPrimitiveValue(data, forKey: keyPath)
+ didChangeValue(forKey: keyPath)
+ }
+ }
+}
+
+extension Tag {
+ @discardableResult
+ public static func insert(
+ into context: NSManagedObjectContext,
+ property: Property
+ ) -> Tag {
+ let object: Tag = context.insertObject()
+
+ object.configure(property: property)
+
+ return object
+ }
+}
+
+
+extension Tag: Managed {
+ public static var defaultSortDescriptors: [NSSortDescriptor] {
+ [NSSortDescriptor(keyPath: \Tag.createAt, ascending: false)]
+ }
+}
+
+public extension Tag {
+
+ static func predicate(domain: String) -> NSPredicate {
+ NSPredicate(format: "%K == %@", #keyPath(Tag.domain), domain)
+ }
+
+ static func predicate(name: String) -> NSPredicate {
+ NSPredicate(format: "%K == %@", #keyPath(Tag.name), name)
+ }
+
+ static func predicate(domain: String, name: String) -> NSPredicate {
+ NSCompoundPredicate(andPredicateWithSubpredicates: [
+ predicate(domain: domain),
+ predicate(name: name),
+ ])
+ }
+}
+
+// MARK: - AutoGenerateProperty
+extension Tag: AutoGenerateProperty {
+ // sourcery:inline:Tag.AutoGenerateProperty
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public struct Property {
+ public let identifier: ID
+ public let domain: String
+ public let createAt: Date
+ public let updatedAt: Date
+ public let name: String
+ public let url: String
+ public let histories: [MastodonTagHistory]
+
+ public init(
+ identifier: ID,
+ domain: String,
+ createAt: Date,
+ updatedAt: Date,
+ name: String,
+ url: String,
+ histories: [MastodonTagHistory]
+ ) {
+ self.identifier = identifier
+ self.domain = domain
+ self.createAt = createAt
+ self.updatedAt = updatedAt
+ self.name = name
+ self.url = url
+ self.histories = histories
+ }
+ }
+
+ public func configure(property: Property) {
+ self.identifier = property.identifier
+ self.domain = property.domain
+ self.createAt = property.createAt
+ self.updatedAt = property.updatedAt
+ self.name = property.name
+ self.url = property.url
+ self.histories = property.histories
+ }
+
+ public func update(property: Property) {
+ update(updatedAt: property.updatedAt)
+ update(url: property.url)
+ update(histories: property.histories)
+ }
+ // sourcery:end
+}
+
+// MARK: - AutoUpdatableObject
+extension Tag: AutoUpdatableObject {
+ // sourcery:inline:Tag.AutoUpdatableObject
+
+ // Generated using Sourcery
+ // DO NOT EDIT
+ public func update(updatedAt: Date) {
+ if self.updatedAt != updatedAt {
+ self.updatedAt = updatedAt
+ }
+ }
+ public func update(url: String) {
+ if self.url != url {
+ self.url = url
+ }
+ }
+ public func update(histories: [MastodonTagHistory]) {
+ if self.histories != histories {
+ self.histories = histories
+ }
+ }
+ // sourcery:end
+}
+
+
+extension Tag {
+
+ public func findSearchHistory(domain: String, userID: MastodonUser.ID) -> SearchHistory? {
+ return searchHistories.first { searchHistory in
+ return searchHistory.domain == domain
+ && searchHistory.userID == userID
+ }
+ }
+
+ public func findSearchHistory(for user: MastodonUser) -> SearchHistory? {
+ return searchHistories.first { searchHistory in
+ return searchHistory.domain == user.domain
+ && searchHistory.userID == user.id
+ }
+ }
+
+}
+
+public extension Tag {
+// func updateHistory(index: Int, day: Date, uses: String, account: String) {
+// let histories = self.histories.sorted {
+// $0.createAt.compare($1.createAt) == .orderedAscending
+// }
+// guard index < histories.count else { return }
+// let history = histories[index]
+// history.update(day: day)
+// history.update(uses: uses)
+// history.update(accounts: account)
+// }
+//
+// func appendHistory(history: History) {
+// self.mutableSetValue(forKeyPath: #keyPath(Tag.histories)).add(history)
+// }
+//
+// func update(url: String) {
+// if self.url != url {
+// self.url = url
+// }
+// }
+}
diff --git a/CoreDataStack/Entity/MastodonUser.swift b/CoreDataStack/Entity/MastodonUser.swift
deleted file mode 100644
index 913aa1f1..00000000
--- a/CoreDataStack/Entity/MastodonUser.swift
+++ /dev/null
@@ -1,407 +0,0 @@
-//
-// MastodonUser.swift
-// CoreDataStack
-//
-// Created by MainasuK Cirno on 2021/1/27.
-//
-
-import CoreData
-import Foundation
-
-final public class MastodonUser: NSManagedObject {
-
- public typealias ID = String
-
- @NSManaged public private(set) var identifier: ID
- @NSManaged public private(set) var domain: String
-
- @NSManaged public private(set) var id: ID
- @NSManaged public private(set) var acct: String
- @NSManaged public private(set) var username: String
- @NSManaged public private(set) var displayName: String
- @NSManaged public private(set) var avatar: String
- @NSManaged public private(set) var avatarStatic: String?
- @NSManaged public private(set) var header: String
- @NSManaged public private(set) var headerStatic: String?
- @NSManaged public private(set) var note: String?
- @NSManaged public private(set) var url: String?
-
- @NSManaged public private(set) var emojisData: Data?
- @NSManaged public private(set) var fieldsData: Data?
-
- @NSManaged public private(set) var statusesCount: NSNumber
- @NSManaged public private(set) var followingCount: NSNumber
- @NSManaged public private(set) var followersCount: NSNumber
-
- @NSManaged public private(set) var locked: Bool
- @NSManaged public private(set) var bot: Bool
- @NSManaged public private(set) var suspended: Bool
-
- @NSManaged public private(set) var createdAt: Date
- @NSManaged public private(set) var updatedAt: Date
-
- // one-to-one relationship
- @NSManaged public private(set) var pinnedStatus: Status?
- @NSManaged public private(set) var mastodonAuthentication: MastodonAuthentication?
-
- // one-to-many relationship
- @NSManaged public private(set) var statuses: Set?
- @NSManaged public private(set) var notifications: Set?
- @NSManaged public private(set) var searchHistories: Set
-
- // many-to-many relationship
- @NSManaged public private(set) var favourite: Set?
- @NSManaged public private(set) var reblogged: Set?
- @NSManaged public private(set) var muted: Set?
- @NSManaged public private(set) var bookmarked: Set?
- @NSManaged public private(set) var votePollOptions: Set?
- @NSManaged public private(set) var votePolls: Set?
- // relationships
- @NSManaged public private(set) var following: Set?
- @NSManaged public private(set) var followingBy: Set?
- @NSManaged public private(set) var followRequested: Set?
- @NSManaged public private(set) var followRequestedBy: Set?
- @NSManaged public private(set) var muting: Set?
- @NSManaged public private(set) var mutingBy: Set?
- @NSManaged public private(set) var blocking: Set?
- @NSManaged public private(set) var blockingBy: Set?
- @NSManaged public private(set) var endorsed: Set?
- @NSManaged public private(set) var endorsedBy: Set?
- @NSManaged public private(set) var domainBlocking: Set?
- @NSManaged public private(set) var domainBlockingBy: Set?
-
-}
-
-extension MastodonUser {
-
- @discardableResult
- public static func insert(
- into context: NSManagedObjectContext,
- property: Property
- ) -> MastodonUser {
- let user: MastodonUser = context.insertObject()
-
- user.identifier = property.identifier
- user.domain = property.domain
-
- user.id = property.id
- user.acct = property.acct
- user.username = property.username
- user.displayName = property.displayName
- user.avatar = property.avatar
- user.avatarStatic = property.avatarStatic
- user.header = property.header
- user.headerStatic = property.headerStatic
- user.note = property.note
- user.url = property.url
- user.emojisData = property.emojisData
- user.fieldsData = property.fieldsData
-
- user.statusesCount = NSNumber(value: property.statusesCount)
- user.followingCount = NSNumber(value: property.followingCount)
- user.followersCount = NSNumber(value: property.followersCount)
-
- user.locked = property.locked
- user.bot = property.bot ?? false
- user.suspended = property.suspended ?? false
-
- // Mastodon do not provide relationship on the `Account`
- // Update relationship via attribute updating interface
-
- user.createdAt = property.createdAt
- user.updatedAt = property.networkDate
-
- return user
- }
-
-
- public func update(acct: String) {
- if self.acct != acct {
- self.acct = acct
- }
- }
- public func update(username: String) {
- if self.username != username {
- self.username = username
- }
- }
- public func update(displayName: String) {
- if self.displayName != displayName {
- self.displayName = displayName
- }
- }
- public func update(avatar: String) {
- if self.avatar != avatar {
- self.avatar = avatar
- }
- }
- public func update(avatarStatic: String?) {
- if self.avatarStatic != avatarStatic {
- self.avatarStatic = avatarStatic
- }
- }
- public func update(header: String) {
- if self.header != header {
- self.header = header
- }
- }
- public func update(headerStatic: String?) {
- if self.headerStatic != headerStatic {
- self.headerStatic = headerStatic
- }
- }
- public func update(note: String?) {
- if self.note != note {
- self.note = note
- }
- }
- public func update(url: String?) {
- if self.url != url {
- self.url = url
- }
- }
- public func update(emojisData: Data?) {
- if self.emojisData != emojisData {
- self.emojisData = emojisData
- }
- }
- public func update(fieldsData: Data?) {
- if self.fieldsData != fieldsData {
- self.fieldsData = fieldsData
- }
- }
- public func update(statusesCount: Int) {
- if self.statusesCount.intValue != statusesCount {
- self.statusesCount = NSNumber(value: statusesCount)
- }
- }
- public func update(followingCount: Int) {
- if self.followingCount.intValue != followingCount {
- self.followingCount = NSNumber(value: followingCount)
- }
- }
- public func update(followersCount: Int) {
- if self.followersCount.intValue != followersCount {
- self.followersCount = NSNumber(value: followersCount)
- }
- }
- public func update(locked: Bool) {
- if self.locked != locked {
- self.locked = locked
- }
- }
- public func update(bot: Bool) {
- if self.bot != bot {
- self.bot = bot
- }
- }
- public func update(suspended: Bool) {
- if self.suspended != suspended {
- self.suspended = suspended
- }
- }
-
- public func update(isFollowing: Bool, by mastodonUser: MastodonUser) {
- if isFollowing {
- if !(self.followingBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.followingBy)).add(mastodonUser)
- }
- } else {
- if (self.followingBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.followingBy)).remove(mastodonUser)
- }
- }
- }
- public func update(isFollowRequested: Bool, by mastodonUser: MastodonUser) {
- if isFollowRequested {
- if !(self.followRequestedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.followRequestedBy)).add(mastodonUser)
- }
- } else {
- if (self.followRequestedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.followRequestedBy)).remove(mastodonUser)
- }
- }
- }
- public func update(isMuting: Bool, by mastodonUser: MastodonUser) {
- if isMuting {
- if !(self.mutingBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.mutingBy)).add(mastodonUser)
- }
- } else {
- if (self.mutingBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.mutingBy)).remove(mastodonUser)
- }
- }
- }
- public func update(isBlocking: Bool, by mastodonUser: MastodonUser) {
- if isBlocking {
- if !(self.blockingBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.blockingBy)).add(mastodonUser)
- }
- } else {
- if (self.blockingBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.blockingBy)).remove(mastodonUser)
- }
- }
- }
- public func update(isEndorsed: Bool, by mastodonUser: MastodonUser) {
- if isEndorsed {
- if !(self.endorsedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.endorsedBy)).add(mastodonUser)
- }
- } else {
- if (self.endorsedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.endorsedBy)).remove(mastodonUser)
- }
- }
- }
- public func update(isDomainBlocking: Bool, by mastodonUser: MastodonUser) {
- if isDomainBlocking {
- if !(self.domainBlockingBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.domainBlockingBy)).add(mastodonUser)
- }
- } else {
- if (self.domainBlockingBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(MastodonUser.domainBlockingBy)).remove(mastodonUser)
- }
- }
- }
-
- public func didUpdate(at networkDate: Date) {
- self.updatedAt = networkDate
- }
-
-}
-
-extension MastodonUser {
- public func findSearchHistory(domain: String, userID: MastodonUser.ID) -> SearchHistory? {
- return searchHistories.first { searchHistory in
- return searchHistory.domain == domain
- && searchHistory.userID == userID
- }
- }
-}
-
-extension MastodonUser {
- public struct Property {
- public let identifier: String
- public let domain: String
-
- public let id: String
- public let acct: String
- public let username: String
- public let displayName: String
- public let avatar: String
- public let avatarStatic: String?
- public let header: String
- public let headerStatic: String?
- public let note: String?
- public let url: String?
- public let emojisData: Data?
- public let fieldsData: Data?
- public let statusesCount: Int
- public let followingCount: Int
- public let followersCount: Int
- public let locked: Bool
- public let bot: Bool?
- public let suspended: Bool?
-
- public let createdAt: Date
- public let networkDate: Date
-
- public init(
- id: String,
- domain: String,
- acct: String,
- username: String,
- displayName: String,
- avatar: String,
- avatarStatic: String?,
- header: String,
- headerStatic: String?,
- note: String?,
- url: String?,
- emojisData: Data?,
- fieldsData: Data?,
- statusesCount: Int,
- followingCount: Int,
- followersCount: Int,
- locked: Bool,
- bot: Bool?,
- suspended: Bool?,
- createdAt: Date,
- networkDate: Date
- ) {
- self.identifier = id + "@" + domain
- self.domain = domain
- self.id = id
- self.acct = acct
- self.username = username
- self.displayName = displayName
- self.avatar = avatar
- self.avatarStatic = avatarStatic
- self.header = header
- self.headerStatic = headerStatic
- self.note = note
- self.url = url
- self.emojisData = emojisData
- self.fieldsData = fieldsData
- self.statusesCount = statusesCount
- self.followingCount = followingCount
- self.followersCount = followersCount
- self.locked = locked
- self.bot = bot
- self.suspended = suspended
- self.createdAt = createdAt
- self.networkDate = networkDate
- }
- }
-}
-
-extension MastodonUser: Managed {
- public static var defaultSortDescriptors: [NSSortDescriptor] {
- return [NSSortDescriptor(keyPath: \MastodonUser.createdAt, ascending: false)]
- }
-}
-
-extension MastodonUser {
-
- static func predicate(domain: String) -> NSPredicate {
- return NSPredicate(format: "%K == %@", #keyPath(MastodonUser.domain), domain)
- }
-
- static func predicate(id: String) -> NSPredicate {
- return NSPredicate(format: "%K == %@", #keyPath(MastodonUser.id), id)
- }
-
- public static func predicate(domain: String, id: String) -> NSPredicate {
- return NSCompoundPredicate(andPredicateWithSubpredicates: [
- MastodonUser.predicate(domain: domain),
- MastodonUser.predicate(id: id)
- ])
- }
-
- static func predicate(ids: [String]) -> NSPredicate {
- return NSPredicate(format: "%K IN %@", #keyPath(MastodonUser.id), ids)
- }
-
- public static func predicate(domain: String, ids: [String]) -> NSPredicate {
- return NSCompoundPredicate(andPredicateWithSubpredicates: [
- MastodonUser.predicate(domain: domain),
- MastodonUser.predicate(ids: ids)
- ])
- }
-
- static func predicate(username: String) -> NSPredicate {
- return NSPredicate(format: "%K == %@", #keyPath(MastodonUser.username), username)
- }
-
- public static func predicate(domain: String, username: String) -> NSPredicate {
- return NSCompoundPredicate(andPredicateWithSubpredicates: [
- MastodonUser.predicate(domain: domain),
- MastodonUser.predicate(username: username)
- ])
- }
-
-}
diff --git a/CoreDataStack/Entity/Mention.swift b/CoreDataStack/Entity/Mention.swift
deleted file mode 100644
index 864ca494..00000000
--- a/CoreDataStack/Entity/Mention.swift
+++ /dev/null
@@ -1,71 +0,0 @@
-//
-// Mention.swift
-// CoreDataStack
-//
-// Created by sxiaojian on 2021/2/1.
-//
-
-import CoreData
-import Foundation
-
-public final class Mention: NSManagedObject {
- public typealias ID = UUID
-
- @NSManaged public private(set) var index: NSNumber
-
- @NSManaged public private(set) var identifier: ID
- @NSManaged public private(set) var id: String
- @NSManaged public private(set) var createAt: Date
-
- @NSManaged public private(set) var username: String
- @NSManaged public private(set) var acct: String
- @NSManaged public private(set) var url: String
-
- // many-to-one relationship
- @NSManaged public private(set) var status: Status
-}
-
-public extension Mention {
- override func awakeFromInsert() {
- super.awakeFromInsert()
-
- setPrimitiveValue(UUID(), forKey: #keyPath(Mention.identifier))
- }
-
- @discardableResult
- static func insert(
- into context: NSManagedObjectContext,
- property: Property,
- index: Int
- ) -> Mention {
- let mention: Mention = context.insertObject()
- mention.index = NSNumber(value: index)
- mention.id = property.id
- mention.username = property.username
- mention.acct = property.acct
- mention.url = property.url
- return mention
- }
-}
-
-public extension Mention {
- struct Property {
- public let id: String
- public let username: String
- public let acct: String
- public let url: String
-
- public init(id: String, username: String, acct: String, url: String) {
- self.id = id
- self.username = username
- self.acct = acct
- self.url = url
- }
- }
-}
-
-extension Mention: Managed {
- public static var defaultSortDescriptors: [NSSortDescriptor] {
- return [NSSortDescriptor(keyPath: \Mention.createAt, ascending: false)]
- }
-}
diff --git a/CoreDataStack/Entity/Notification.swift b/CoreDataStack/Entity/Notification.swift
deleted file mode 100644
index 04f8e9fd..00000000
--- a/CoreDataStack/Entity/Notification.swift
+++ /dev/null
@@ -1,115 +0,0 @@
-//
-// MastodonNotification.swift
-// CoreDataStack
-//
-// Created by sxiaojian on 2021/4/13.
-//
-
-import Foundation
-import CoreData
-
-public final class MastodonNotification: NSManagedObject {
- public typealias ID = UUID
- @NSManaged public private(set) var identifier: ID
- @NSManaged public private(set) var id: String
- @NSManaged public private(set) var createAt: Date
- @NSManaged public private(set) var updatedAt: Date
- @NSManaged public private(set) var typeRaw: String
- @NSManaged public private(set) var account: MastodonUser
- @NSManaged public private(set) var status: Status?
-
- @NSManaged public private(set) var domain: String
- @NSManaged public private(set) var userID: String
-}
-
-extension MastodonNotification {
- public override func awakeFromInsert() {
- super.awakeFromInsert()
- setPrimitiveValue(UUID(), forKey: #keyPath(MastodonNotification.identifier))
- }
-}
-
-public extension MastodonNotification {
- @discardableResult
- static func insert(
- into context: NSManagedObjectContext,
- domain: String,
- userID: String,
- networkDate: Date,
- property: Property
- ) -> MastodonNotification {
- let notification: MastodonNotification = context.insertObject()
- notification.id = property.id
- notification.createAt = property.createdAt
- notification.updatedAt = networkDate
- notification.typeRaw = property.typeRaw
- notification.account = property.account
- notification.status = property.status
- notification.domain = domain
- notification.userID = userID
- return notification
- }
-}
-
-public extension MastodonNotification {
- struct Property {
- public init(id: String,
- typeRaw: String,
- account: MastodonUser,
- status: Status?,
- createdAt: Date
- ) {
- self.id = id
- self.typeRaw = typeRaw
- self.account = account
- self.status = status
- self.createdAt = createdAt
- }
-
- public let id: String
- public let typeRaw: String
- public let account: MastodonUser
- public let status: Status?
- public let createdAt: Date
- }
-}
-
-extension MastodonNotification {
- static func predicate(domain: String) -> NSPredicate {
- return NSPredicate(format: "%K == %@", #keyPath(MastodonNotification.domain), domain)
- }
-
- static func predicate(userID: String) -> NSPredicate {
- return NSPredicate(format: "%K == %@", #keyPath(MastodonNotification.userID), userID)
- }
-
- static func predicate(typeRaw: String) -> NSPredicate {
- return NSPredicate(format: "%K == %@", #keyPath(MastodonNotification.typeRaw), typeRaw)
- }
-
- public static func predicate(domain: String, userID: String, typeRaw: String? = nil) -> NSPredicate {
- if let typeRaw = typeRaw {
- return NSCompoundPredicate(andPredicateWithSubpredicates: [
- MastodonNotification.predicate(domain: domain),
- MastodonNotification.predicate(typeRaw: typeRaw),
- MastodonNotification.predicate(userID: userID),
- ])
- } else {
- return NSCompoundPredicate(andPredicateWithSubpredicates: [
- MastodonNotification.predicate(domain: domain),
- MastodonNotification.predicate(userID: userID)
- ])
- }
- }
-
- public static func predicate(validTypesRaws types: [String]) -> NSPredicate {
- return NSPredicate(format: "%K IN %@", #keyPath(MastodonNotification.typeRaw), types)
- }
-
-}
-
-extension MastodonNotification: Managed {
- public static var defaultSortDescriptors: [NSSortDescriptor] {
- return [NSSortDescriptor(keyPath: \MastodonNotification.createAt, ascending: false)]
- }
-}
diff --git a/CoreDataStack/Entity/Poll.swift b/CoreDataStack/Entity/Poll.swift
deleted file mode 100644
index 3ab48b44..00000000
--- a/CoreDataStack/Entity/Poll.swift
+++ /dev/null
@@ -1,145 +0,0 @@
-//
-// Poll.swift
-// CoreDataStack
-//
-// Created by MainasuK Cirno on 2021-3-2.
-//
-
-import Foundation
-import CoreData
-
-public final class Poll: NSManagedObject {
- public typealias ID = String
-
- @NSManaged public private(set) var id: ID
- @NSManaged public private(set) var expiresAt: Date?
- @NSManaged public private(set) var expired: Bool
- @NSManaged public private(set) var multiple: Bool
- @NSManaged public private(set) var votesCount: NSNumber
- @NSManaged public private(set) var votersCount: NSNumber?
-
- @NSManaged public private(set) var createdAt: Date
- @NSManaged public private(set) var updatedAt: Date
-
- // one-to-one relationship
- @NSManaged public private(set) var status: Status
-
- // one-to-many relationship
- @NSManaged public private(set) var options: Set
-
- // many-to-many relationship
- @NSManaged public private(set) var votedBy: Set?
-}
-
-extension Poll {
-
- public override func awakeFromInsert() {
- super.awakeFromInsert()
- setPrimitiveValue(Date(), forKey: #keyPath(Poll.createdAt))
- }
-
- @discardableResult
- public static func insert(
- into context: NSManagedObjectContext,
- property: Property,
- votedBy: MastodonUser?,
- options: [PollOption]
- ) -> Poll {
- let poll: Poll = context.insertObject()
-
- poll.id = property.id
- poll.expiresAt = property.expiresAt
- poll.expired = property.expired
- poll.multiple = property.multiple
- poll.votesCount = property.votesCount
- poll.votersCount = property.votersCount
-
-
- poll.updatedAt = property.networkDate
-
- if let votedBy = votedBy {
- poll.mutableSetValue(forKey: #keyPath(Poll.votedBy)).add(votedBy)
- }
- poll.mutableSetValue(forKey: #keyPath(Poll.options)).addObjects(from: options)
-
- return poll
- }
-
- public func update(expiresAt: Date?) {
- if self.expiresAt != expiresAt {
- self.expiresAt = expiresAt
- }
- }
-
- public func update(expired: Bool) {
- if self.expired != expired {
- self.expired = expired
- }
- }
-
- public func update(votesCount: Int) {
- if self.votesCount.intValue != votesCount {
- self.votesCount = NSNumber(value: votesCount)
- }
- }
-
- public func update(votersCount: Int?) {
- if self.votersCount?.intValue != votersCount {
- self.votersCount = votersCount.flatMap { NSNumber(value: $0) }
- }
- }
-
- public func update(voted: Bool, by: MastodonUser) {
- if voted {
- if !(votedBy ?? Set()).contains(by) {
- mutableSetValue(forKey: #keyPath(Poll.votedBy)).add(by)
- }
- } else {
- if (votedBy ?? Set()).contains(by) {
- mutableSetValue(forKey: #keyPath(Poll.votedBy)).remove(by)
- }
- }
- }
-
- public func didUpdate(at networkDate: Date) {
- self.updatedAt = networkDate
- }
-
-}
-
-extension Poll {
- public struct Property {
- public let id: ID
- public let expiresAt: Date?
- public let expired: Bool
- public let multiple: Bool
- public let votesCount: NSNumber
- public let votersCount: NSNumber?
-
- public let networkDate: Date
-
- public init(
- id: Poll.ID,
- expiresAt: Date?,
- expired: Bool,
- multiple: Bool,
- votesCount: Int,
- votersCount: Int?,
- networkDate: Date
- ) {
- self.id = id
- self.expiresAt = expiresAt
- self.expired = expired
- self.multiple = multiple
- self.votesCount = NSNumber(value: votesCount)
- self.votersCount = votersCount.flatMap { NSNumber(value: $0) }
- self.networkDate = networkDate
- }
- }
-}
-
-extension Poll: Managed {
- public static var defaultSortDescriptors: [NSSortDescriptor] {
- return [NSSortDescriptor(keyPath: \Poll.createdAt, ascending: false)]
- }
-}
diff --git a/CoreDataStack/Entity/PollOption.swift b/CoreDataStack/Entity/PollOption.swift
deleted file mode 100644
index 8917a753..00000000
--- a/CoreDataStack/Entity/PollOption.swift
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// PollOption.swift
-// CoreDataStack
-//
-// Created by MainasuK Cirno on 2021-3-2.
-//
-
-import Foundation
-import CoreData
-
-public final class PollOption: NSManagedObject {
- @NSManaged public private(set) var index: NSNumber
- @NSManaged public private(set) var title: String
- @NSManaged public private(set) var votesCount: NSNumber?
-
- @NSManaged public private(set) var createdAt: Date
- @NSManaged public private(set) var updatedAt: Date
-
- // many-to-one relationship
- @NSManaged public private(set) var poll: Poll
-
- // many-to-many relationship
- @NSManaged public private(set) var votedBy: Set?
-}
-
-extension PollOption {
-
- public override func awakeFromInsert() {
- super.awakeFromInsert()
- setPrimitiveValue(Date(), forKey: #keyPath(PollOption.createdAt))
- }
-
- @discardableResult
- public static func insert(
- into context: NSManagedObjectContext,
- property: Property,
- votedBy: MastodonUser?
- ) -> PollOption {
- let option: PollOption = context.insertObject()
-
- option.index = property.index
- option.title = property.title
- option.votesCount = property.votesCount
- option.updatedAt = property.networkDate
-
- if let votedBy = votedBy {
- option.mutableSetValue(forKey: #keyPath(PollOption.votedBy)).add(votedBy)
- }
-
- return option
- }
-
- public func update(votesCount: Int?) {
- if self.votesCount?.intValue != votesCount {
- self.votesCount = votesCount.flatMap { NSNumber(value: $0) }
- }
- }
-
- public func update(voted: Bool, by: MastodonUser) {
- if voted {
- if !(self.votedBy ?? Set()).contains(by) {
- self.mutableSetValue(forKey: #keyPath(PollOption.votedBy)).add(by)
- }
- } else {
- if (self.votedBy ?? Set()).contains(by) {
- self.mutableSetValue(forKey: #keyPath(PollOption.votedBy)).remove(by)
- }
- }
- }
-
- public func didUpdate(at networkDate: Date) {
- self.updatedAt = networkDate
- }
-
-}
-
-extension PollOption {
- public struct Property {
- public let index: NSNumber
- public let title: String
- public let votesCount: NSNumber?
-
- public let networkDate: Date
-
- public init(index: Int, title: String, votesCount: Int?, networkDate: Date) {
- self.index = NSNumber(value: index)
- self.title = title
- self.votesCount = votesCount.flatMap { NSNumber(value: $0) }
- self.networkDate = networkDate
- }
- }
-}
-
-extension PollOption: Managed {
- public static var defaultSortDescriptors: [NSSortDescriptor] {
- return [NSSortDescriptor(keyPath: \PollOption.createdAt, ascending: false)]
- }
-}
diff --git a/CoreDataStack/Entity/SearchHistory.swift b/CoreDataStack/Entity/SearchHistory.swift
deleted file mode 100644
index 05e44190..00000000
--- a/CoreDataStack/Entity/SearchHistory.swift
+++ /dev/null
@@ -1,118 +0,0 @@
-//
-// SearchHistory.swift
-// CoreDataStack
-//
-// Created by sxiaojian on 2021/4/7.
-//
-
-import Foundation
-import CoreData
-
-public final class SearchHistory: NSManagedObject {
- public typealias ID = UUID
- @NSManaged public private(set) var identifier: ID
- @NSManaged public private(set) var domain: String
- @NSManaged public private(set) var userID: MastodonUser.ID
- @NSManaged public private(set) var createAt: Date
- @NSManaged public private(set) var updatedAt: Date
-
- // many-to-one relationship
- @NSManaged public private(set) var account: MastodonUser?
- @NSManaged public private(set) var hashtag: Tag?
- @NSManaged public private(set) var status: Status?
-
-}
-
-extension SearchHistory {
- public override func awakeFromInsert() {
- super.awakeFromInsert()
- setPrimitiveValue(UUID(), forKey: #keyPath(SearchHistory.identifier))
- setPrimitiveValue(Date(), forKey: #keyPath(SearchHistory.createAt))
- setPrimitiveValue(Date(), forKey: #keyPath(SearchHistory.updatedAt))
- }
-
-// public override func willSave() {
-// super.willSave()
-// setPrimitiveValue(Date(), forKey: #keyPath(SearchHistory.updatedAt))
-// }
-
- @discardableResult
- public static func insert(
- into context: NSManagedObjectContext,
- property: Property,
- account: MastodonUser
- ) -> SearchHistory {
- let searchHistory: SearchHistory = context.insertObject()
- searchHistory.domain = property.domain
- searchHistory.userID = property.userID
- searchHistory.account = account
- return searchHistory
- }
-
- @discardableResult
- public static func insert(
- into context: NSManagedObjectContext,
- property: Property,
- hashtag: Tag
- ) -> SearchHistory {
- let searchHistory: SearchHistory = context.insertObject()
- searchHistory.domain = property.domain
- searchHistory.userID = property.userID
- searchHistory.hashtag = hashtag
- return searchHistory
- }
-
- @discardableResult
- public static func insert(
- into context: NSManagedObjectContext,
- property: Property,
- status: Status
- ) -> SearchHistory {
- let searchHistory: SearchHistory = context.insertObject()
- searchHistory.domain = property.domain
- searchHistory.userID = property.userID
- searchHistory.status = status
- return searchHistory
- }
-}
-
-extension SearchHistory {
- public func update(updatedAt: Date) {
- setValue(updatedAt, forKey: #keyPath(SearchHistory.updatedAt))
- }
-}
-
-extension SearchHistory {
- public struct Property {
- public let domain: String
- public let userID: MastodonUser.ID
-
- public init(domain: String, userID: MastodonUser.ID) {
- self.domain = domain
- self.userID = userID
- }
- }
-}
-
-extension SearchHistory: Managed {
- public static var defaultSortDescriptors: [NSSortDescriptor] {
- return [NSSortDescriptor(keyPath: \SearchHistory.updatedAt, ascending: false)]
- }
-}
-
-extension SearchHistory {
- static func predicate(domain: String) -> NSPredicate {
- return NSPredicate(format: "%K == %@", #keyPath(SearchHistory.domain), domain)
- }
-
- static func predicate(userID: String) -> NSPredicate {
- return NSPredicate(format: "%K == %@", #keyPath(SearchHistory.userID), userID)
- }
-
- public static func predicate(domain: String, userID: String) -> NSPredicate {
- return NSCompoundPredicate(andPredicateWithSubpredicates: [
- predicate(domain: domain),
- predicate(userID: userID)
- ])
- }
-}
diff --git a/CoreDataStack/Entity/Status.swift b/CoreDataStack/Entity/Status.swift
deleted file mode 100644
index ee168e41..00000000
--- a/CoreDataStack/Entity/Status.swift
+++ /dev/null
@@ -1,355 +0,0 @@
-//
-// Status.swift
-// CoreDataStack
-//
-// Created by MainasuK Cirno on 2021/1/27.
-//
-
-import CoreData
-import Foundation
-
-public final class Status: NSManagedObject {
- public typealias ID = String
-
- @NSManaged public private(set) var identifier: ID
- @NSManaged public private(set) var domain: String
-
- @NSManaged public private(set) var id: String
- @NSManaged public private(set) var uri: String
- @NSManaged public private(set) var createdAt: Date
- @NSManaged public private(set) var content: String
-
- @NSManaged public private(set) var visibility: String?
- @NSManaged public private(set) var sensitive: Bool
- @NSManaged public private(set) var spoilerText: String?
- @NSManaged public private(set) var application: Application?
-
- @NSManaged public private(set) var emojisData: Data?
-
- // Informational
- @NSManaged public private(set) var reblogsCount: NSNumber
- @NSManaged public private(set) var favouritesCount: NSNumber
- @NSManaged public private(set) var repliesCount: NSNumber?
-
- @NSManaged public private(set) var url: String?
- @NSManaged public private(set) var inReplyToID: Status.ID?
- @NSManaged public private(set) var inReplyToAccountID: MastodonUser.ID?
-
- @NSManaged public private(set) var language: String? // (ISO 639 Part 1 two-letter language code)
- @NSManaged public private(set) var text: String?
-
- // many-to-one relationship
- @NSManaged public private(set) var author: MastodonUser
- @NSManaged public private(set) var reblog: Status?
- @NSManaged public private(set) var replyTo: Status?
-
- // many-to-many relationship
- @NSManaged public private(set) var favouritedBy: Set?
- @NSManaged public private(set) var rebloggedBy: Set?
- @NSManaged public private(set) var mutedBy: Set?
- @NSManaged public private(set) var bookmarkedBy: Set?
-
- // one-to-one relationship
- @NSManaged public private(set) var pinnedBy: MastodonUser?
- @NSManaged public private(set) var poll: Poll?
-
- // one-to-many relationship
- @NSManaged public private(set) var reblogFrom: Set?
- @NSManaged public private(set) var mentions: Set?
- @NSManaged public private(set) var homeTimelineIndexes: Set?
- @NSManaged public private(set) var mediaAttachments: Set?
- @NSManaged public private(set) var replyFrom: Set?
-
- @NSManaged public private(set) var inNotifications: Set?
-
- @NSManaged public private(set) var searchHistories: Set
-
- @NSManaged public private(set) var updatedAt: Date
- @NSManaged public private(set) var deletedAt: Date?
- @NSManaged public private(set) var revealedAt: Date?
-}
-
-extension Status {
-
- @discardableResult
- public static func insert(
- into context: NSManagedObjectContext,
- property: Property,
- author: MastodonUser,
- reblog: Status?,
- application: Application?,
- replyTo: Status?,
- poll: Poll?,
- mentions: [Mention]?,
- mediaAttachments: [Attachment]?,
- favouritedBy: MastodonUser?,
- rebloggedBy: MastodonUser?,
- mutedBy: MastodonUser?,
- bookmarkedBy: MastodonUser?,
- pinnedBy: MastodonUser?
- ) -> Status {
- let status: Status = context.insertObject()
-
- status.identifier = property.identifier
- status.domain = property.domain
-
- status.id = property.id
- status.uri = property.uri
- status.createdAt = property.createdAt
- status.content = property.content
-
- status.visibility = property.visibility
- status.sensitive = property.sensitive
- status.spoilerText = property.spoilerText
- status.application = application
-
- status.emojisData = property.emojisData
-
- status.reblogsCount = property.reblogsCount
- status.favouritesCount = property.favouritesCount
- status.repliesCount = property.repliesCount
-
- status.url = property.url
- status.inReplyToID = property.inReplyToID
- status.inReplyToAccountID = property.inReplyToAccountID
-
- status.language = property.language
- status.text = property.text
-
- status.author = author
- status.reblog = reblog
-
- status.pinnedBy = pinnedBy
- status.poll = poll
-
- if let mentions = mentions {
- status.mutableSetValue(forKey: #keyPath(Status.mentions)).addObjects(from: mentions)
- }
- if let mediaAttachments = mediaAttachments {
- status.mutableSetValue(forKey: #keyPath(Status.mediaAttachments)).addObjects(from: mediaAttachments)
- }
- if let favouritedBy = favouritedBy {
- status.mutableSetValue(forKey: #keyPath(Status.favouritedBy)).add(favouritedBy)
- }
- if let rebloggedBy = rebloggedBy {
- status.mutableSetValue(forKey: #keyPath(Status.rebloggedBy)).add(rebloggedBy)
- }
- if let mutedBy = mutedBy {
- status.mutableSetValue(forKey: #keyPath(Status.mutedBy)).add(mutedBy)
- }
- if let bookmarkedBy = bookmarkedBy {
- status.mutableSetValue(forKey: #keyPath(Status.bookmarkedBy)).add(bookmarkedBy)
- }
-
- status.updatedAt = property.networkDate
-
- return status
- }
-
- public func update(emojisData: Data?) {
- if self.emojisData != emojisData {
- self.emojisData = emojisData
- }
- }
-
- public func update(reblogsCount: NSNumber) {
- if self.reblogsCount.intValue != reblogsCount.intValue {
- self.reblogsCount = reblogsCount
- }
- }
-
- public func update(favouritesCount: NSNumber) {
- if self.favouritesCount.intValue != favouritesCount.intValue {
- self.favouritesCount = favouritesCount
- }
- }
-
- public func update(repliesCount: NSNumber?) {
- guard let count = repliesCount else {
- return
- }
- if self.repliesCount?.intValue != count.intValue {
- self.repliesCount = repliesCount
- }
- }
-
- public func update(replyTo: Status?) {
- if self.replyTo != replyTo {
- self.replyTo = replyTo
- }
- }
-
- public func update(liked: Bool, by mastodonUser: MastodonUser) {
- if liked {
- if !(self.favouritedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(Status.favouritedBy)).add(mastodonUser)
- }
- } else {
- if (self.favouritedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(Status.favouritedBy)).remove(mastodonUser)
- }
- }
- }
-
- public func update(reblogged: Bool, by mastodonUser: MastodonUser) {
- if reblogged {
- if !(self.rebloggedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(Status.rebloggedBy)).add(mastodonUser)
- }
- } else {
- if (self.rebloggedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(Status.rebloggedBy)).remove(mastodonUser)
- }
- }
- }
-
- public func update(muted: Bool, by mastodonUser: MastodonUser) {
- if muted {
- if !(self.mutedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(Status.mutedBy)).add(mastodonUser)
- }
- } else {
- if (self.mutedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(Status.mutedBy)).remove(mastodonUser)
- }
- }
- }
-
- public func update(bookmarked: Bool, by mastodonUser: MastodonUser) {
- if bookmarked {
- if !(self.bookmarkedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(Status.bookmarkedBy)).add(mastodonUser)
- }
- } else {
- if (self.bookmarkedBy ?? Set()).contains(mastodonUser) {
- self.mutableSetValue(forKey: #keyPath(Status.bookmarkedBy)).remove(mastodonUser)
- }
- }
- }
-
- public func update(isReveal: Bool) {
- revealedAt = isReveal ? Date() : nil
- }
-
- public func didUpdate(at networkDate: Date) {
- self.updatedAt = networkDate
- }
-
-}
-
-extension Status {
- public struct Property {
-
- public let identifier: ID
- public let domain: String
-
- public let id: String
- public let uri: String
- public let createdAt: Date
- public let content: String
-
- public let visibility: String?
- public let sensitive: Bool
- public let spoilerText: String?
-
- public let emojisData: Data?
-
- public let reblogsCount: NSNumber
- public let favouritesCount: NSNumber
- public let repliesCount: NSNumber?
-
- public let url: String?
- public let inReplyToID: Status.ID?
- public let inReplyToAccountID: MastodonUser.ID?
- public let language: String? // (ISO 639 Part @1 two-letter language code)
- public let text: String?
-
- public let networkDate: Date
-
- public init(
- domain: String,
- id: String,
- uri: String,
- createdAt: Date,
- content: String,
- visibility: String?,
- sensitive: Bool,
- spoilerText: String?,
- emojisData: Data?,
- reblogsCount: NSNumber,
- favouritesCount: NSNumber,
- repliesCount: NSNumber?,
- url: String?,
- inReplyToID: Status.ID?,
- inReplyToAccountID: MastodonUser.ID?,
- language: String?,
- text: String?,
- networkDate: Date
- ) {
- self.identifier = id + "@" + domain
- self.domain = domain
- self.id = id
- self.uri = uri
- self.createdAt = createdAt
- self.content = content
- self.visibility = visibility
- self.sensitive = sensitive
- self.spoilerText = spoilerText
- self.emojisData = emojisData
- self.reblogsCount = reblogsCount
- self.favouritesCount = favouritesCount
- self.repliesCount = repliesCount
- self.url = url
- self.inReplyToID = inReplyToID
- self.inReplyToAccountID = inReplyToAccountID
- self.language = language
- self.text = text
- self.networkDate = networkDate
- }
-
- }
-}
-
-extension Status: Managed {
- public static var defaultSortDescriptors: [NSSortDescriptor] {
- return [NSSortDescriptor(keyPath: \Status.createdAt, ascending: false)]
- }
-}
-
-extension Status {
-
- static func predicate(domain: String) -> NSPredicate {
- return NSPredicate(format: "%K == %@", #keyPath(Status.domain), domain)
- }
-
- static func predicate(id: String) -> NSPredicate {
- return NSPredicate(format: "%K == %@", #keyPath(Status.id), id)
- }
-
- public static func predicate(domain: String, id: String) -> NSPredicate {
- return NSCompoundPredicate(andPredicateWithSubpredicates: [
- predicate(domain: domain),
- predicate(id: id)
- ])
- }
-
- static func predicate(ids: [String]) -> NSPredicate {
- return NSPredicate(format: "%K IN %@", #keyPath(Status.id), ids)
- }
-
- public static func predicate(domain: String, ids: [String]) -> NSPredicate {
- return NSCompoundPredicate(andPredicateWithSubpredicates: [
- predicate(domain: domain),
- predicate(ids: ids)
- ])
- }
-
- public static func notDeleted() -> NSPredicate {
- return NSPredicate(format: "%K == nil", #keyPath(Status.deletedAt))
- }
-
- public static func deleted() -> NSPredicate {
- return NSPredicate(format: "%K != nil", #keyPath(Status.deletedAt))
- }
-
-}
diff --git a/CoreDataStack/Entity/Tag.swift b/CoreDataStack/Entity/Tag.swift
deleted file mode 100644
index fa9e098d..00000000
--- a/CoreDataStack/Entity/Tag.swift
+++ /dev/null
@@ -1,112 +0,0 @@
-//
-// Tag.swift
-// CoreDataStack
-//
-// Created by sxiaojian on 2021/2/1.
-//
-
-import CoreData
-import Foundation
-
-public final class Tag: NSManagedObject {
- public typealias ID = UUID
- @NSManaged public private(set) var identifier: ID
- @NSManaged public private(set) var createAt: Date
- @NSManaged public private(set) var updatedAt: Date
-
- @NSManaged public private(set) var name: String
- @NSManaged public private(set) var url: String
-
- // one-to-one relationship
-
- // many-to-many relationship
-
- // one-to-many relationship
- @NSManaged public private(set) var histories: Set?
- @NSManaged public private(set) var searchHistories: Set
-}
-
-public extension Tag {
- override func awakeFromInsert() {
- super.awakeFromInsert()
- setPrimitiveValue(UUID(), forKey: #keyPath(Tag.identifier))
- setPrimitiveValue(Date(), forKey: #keyPath(Tag.createAt))
- setPrimitiveValue(Date(), forKey: #keyPath(Tag.updatedAt))
- }
-
- override func willSave() {
- super.willSave()
- setPrimitiveValue(Date(), forKey: #keyPath(Tag.updatedAt))
- }
-
- @discardableResult
- static func insert(
- into context: NSManagedObjectContext,
- property: Property
- ) -> Tag {
- let tag: Tag = context.insertObject()
- tag.name = property.name
- tag.url = property.url
- if let histories = property.histories {
- tag.mutableSetValue(forKey: #keyPath(Tag.histories)).addObjects(from: histories)
- }
- return tag
- }
-}
-
-extension Tag {
- public func findSearchHistory(domain: String, userID: MastodonUser.ID) -> SearchHistory? {
- return searchHistories.first { searchHistory in
- return searchHistory.domain == domain
- && searchHistory.userID == userID
- }
- }
-}
-
-public extension Tag {
- struct Property {
- public let name: String
- public let url: String
- public let histories: [History]?
-
- public init(name: String, url: String, histories: [History]?) {
- self.name = name
- self.url = url
- self.histories = histories
- }
- }
-}
-
-public extension Tag {
- func updateHistory(index: Int, day: Date, uses: String, account: String) {
- guard let histories = self.histories?.sorted(by: {
- $0.createAt.compare($1.createAt) == .orderedAscending
- }) else { return }
- let history = histories[index]
- history.update(day: day)
- history.update(uses: uses)
- history.update(accounts: account)
- }
-
- func appendHistory(history: History) {
- self.mutableSetValue(forKeyPath: #keyPath(Tag.histories)).add(history)
- }
-
- func update(url: String) {
- if self.url != url {
- self.url = url
- }
- }
-}
-
-extension Tag: Managed {
- public static var defaultSortDescriptors: [NSSortDescriptor] {
- [NSSortDescriptor(keyPath: \Tag.createAt, ascending: false)]
- }
-}
-
-public extension Tag {
- static func predicate(name: String) -> NSPredicate {
- NSPredicate(format: "%K == %@", #keyPath(Tag.name), name)
- }
-}
diff --git a/CoreDataStack/Entity/Transient/Acct.swift b/CoreDataStack/Entity/Transient/Acct.swift
new file mode 100644
index 00000000..fe59bb9d
--- /dev/null
+++ b/CoreDataStack/Entity/Transient/Acct.swift
@@ -0,0 +1,46 @@
+//
+// Feed+Acct.swift
+// Feed+Acct
+//
+// Created by Cirno MainasuK on 2021-8-26.
+// Copyright © 2021 Twidere. All rights reserved.
+//
+
+import Foundation
+
+extension Feed {
+ public enum Acct: RawRepresentable {
+ case none
+ case mastodon(domain: String, userID: MastodonUser.ID)
+
+ public init?(rawValue: String) {
+ let components = rawValue.split(separator: "@", maxSplits: 2)
+ guard components.count == 3 else { return nil }
+ let userID = String(components[1]).escape
+ let domain = String(components[2]).escape
+
+ switch components[0] {
+ case "M":
+ self = .mastodon(domain: domain, userID: userID)
+ default:
+ self = .none
+ }
+
+ }
+
+ public var rawValue: String {
+ switch self {
+ case .none:
+ return "none@userID@domain"
+ case .mastodon(let domain, let userID):
+ return "M@\(userID.escape)@\(domain.escape)"
+ }
+ }
+ }
+}
+
+extension String {
+ fileprivate var escape: String {
+ replacingOccurrences(of: "@", with: "_at_")
+ }
+}
diff --git a/CoreDataStack/Entity/Transient/Feed+Kind.swift b/CoreDataStack/Entity/Transient/Feed+Kind.swift
new file mode 100644
index 00000000..de32d949
--- /dev/null
+++ b/CoreDataStack/Entity/Transient/Feed+Kind.swift
@@ -0,0 +1,17 @@
+//
+// Feed+Kind.swift
+// CoreDataStack
+//
+// Created by MainasuK on 2022-1-11.
+//
+
+import Foundation
+
+extension Feed {
+ public enum Kind: String, CaseIterable, Hashable {
+ case none
+ case home
+ case notificationAll
+ case notificationMentions
+ }
+}
diff --git a/CoreDataStack/Entity/Transient/MastodonAttachment.swift b/CoreDataStack/Entity/Transient/MastodonAttachment.swift
new file mode 100644
index 00000000..aa25ada1
--- /dev/null
+++ b/CoreDataStack/Entity/Transient/MastodonAttachment.swift
@@ -0,0 +1,58 @@
+//
+// MastodonAttachment.swift
+// MastodonAttachment
+//
+// Created by Cirno MainasuK on 2021-8-30.
+// Copyright © 2021 Twidere. All rights reserved.
+//
+
+import Foundation
+import CoreGraphics
+
+public final class MastodonAttachment: NSObject, Codable {
+ public typealias ID = String
+
+ public let id: ID
+ public let kind: Kind
+ public let size: CGSize
+ public let focus: CGPoint?
+ public let blurhash: String?
+ public let assetURL: String?
+ public let previewURL: String?
+ public let textURL: String?
+ public let durationMS: Int?
+ public let altDescription: String?
+
+ public init(
+ id: MastodonAttachment.ID,
+ kind: MastodonAttachment.Kind,
+ size: CGSize,
+ focus: CGPoint?,
+ blurhash: String?,
+ assetURL: String?,
+ previewURL: String?,
+ textURL: String?,
+ durationMS: Int?,
+ altDescription: String?
+ ) {
+ self.id = id
+ self.kind = kind
+ self.size = size
+ self.focus = focus
+ self.blurhash = blurhash
+ self.assetURL = assetURL
+ self.previewURL = previewURL
+ self.textURL = textURL
+ self.durationMS = durationMS
+ self.altDescription = altDescription
+ }
+}
+
+extension MastodonAttachment {
+ public enum Kind: String, Codable {
+ case image
+ case video
+ case gifv
+ case audio
+ }
+}
diff --git a/CoreDataStack/Entity/Transient/MastodonEmoji.swift b/CoreDataStack/Entity/Transient/MastodonEmoji.swift
new file mode 100644
index 00000000..b067849c
--- /dev/null
+++ b/CoreDataStack/Entity/Transient/MastodonEmoji.swift
@@ -0,0 +1,30 @@
+//
+// MastodonEmoji.swift
+// MastodonEmoji
+//
+// Created by Cirno MainasuK on 2021-9-2.
+// Copyright © 2021 Twidere. All rights reserved.
+//
+
+import Foundation
+
+public final class MastodonEmoji: NSObject, Codable {
+ public let code: String
+ public let url: String
+ public let staticURL: String
+ public let visibleInPicker: Bool
+ public let category: String?
+
+ public init(code:
+ String, url:
+ String, staticURL:
+ String, visibleInPicker:
+ Bool, category: String?
+ ) {
+ self.code = code
+ self.url = url
+ self.staticURL = staticURL
+ self.visibleInPicker = visibleInPicker
+ self.category = category
+ }
+}
diff --git a/CoreDataStack/Entity/Transient/MastodonField.swift b/CoreDataStack/Entity/Transient/MastodonField.swift
new file mode 100644
index 00000000..507f6f9a
--- /dev/null
+++ b/CoreDataStack/Entity/Transient/MastodonField.swift
@@ -0,0 +1,25 @@
+//
+// MastodonField.swift
+// CoreDataStack
+//
+// Created by Cirno MainasuK on 2021-9-18.
+// Copyright © 2021 Twidere. All rights reserved.
+//
+
+import Foundation
+
+public final class MastodonField: NSObject, Codable {
+ public let name: String
+ public let value: String
+ public let verifiedAt: Date?
+
+ public init(
+ name: String,
+ value: String,
+ verifiedAt: Date?
+ ) {
+ self.name = name
+ self.value = value
+ self.verifiedAt = verifiedAt
+ }
+}
diff --git a/CoreDataStack/Entity/Transient/MastodonMention.swift b/CoreDataStack/Entity/Transient/MastodonMention.swift
new file mode 100644
index 00000000..ee53222c
--- /dev/null
+++ b/CoreDataStack/Entity/Transient/MastodonMention.swift
@@ -0,0 +1,31 @@
+//
+// MastodonMention.swift
+// CoreDataStack
+//
+// Created by MainasuK on 2022-1-17.
+//
+
+import Foundation
+
+public final class MastodonMention: NSObject, Codable {
+
+ public typealias ID = String
+
+ public let id: ID
+ public let username: String
+ public let acct: String
+ public let url: String
+
+ public init(
+ id: MastodonMention.ID,
+ username: String,
+ acct: String,
+ url: String
+ ) {
+ self.id = id
+ self.username = username
+ self.acct = acct
+ self.url = url
+ }
+
+}
diff --git a/CoreDataStack/Entity/Transient/MastodonNotificationType.swift b/CoreDataStack/Entity/Transient/MastodonNotificationType.swift
new file mode 100644
index 00000000..a982fda9
--- /dev/null
+++ b/CoreDataStack/Entity/Transient/MastodonNotificationType.swift
@@ -0,0 +1,46 @@
+//
+// MastodonNotificationType.swift
+// CoreDataStack
+//
+// Created by MainasuK on 2022-1-21.
+//
+
+import Foundation
+
+public enum MastodonNotificationType: RawRepresentable {
+ case follow
+ case followRequest
+ case mention
+ case reblog
+ case favourite // same to API
+ case poll
+ case status
+
+ case _other(String)
+
+ public init?(rawValue: String) {
+ switch rawValue {
+ case "follow": self = .follow
+ case "followRequest": self = .followRequest
+ case "mention": self = .mention
+ case "reblog": self = .reblog
+ case "favourite": self = .favourite
+ case "poll": self = .poll
+ case "status": self = .status
+ default: self = ._other(rawValue)
+ }
+ }
+
+ public var rawValue: String {
+ switch self {
+ case .follow: return "follow"
+ case .followRequest: return "followRequest"
+ case .mention: return "mention"
+ case .reblog: return "reblog"
+ case .favourite: return "favourite"
+ case .poll: return "poll"
+ case .status: return "status"
+ case ._other(let value): return value
+ }
+ }
+}
diff --git a/CoreDataStack/Entity/Transient/MastodonTagHistory.swift b/CoreDataStack/Entity/Transient/MastodonTagHistory.swift
new file mode 100644
index 00000000..f2d1cf71
--- /dev/null
+++ b/CoreDataStack/Entity/Transient/MastodonTagHistory.swift
@@ -0,0 +1,24 @@
+//
+// MastodonTagHistory.swift
+// CoreDataStack
+//
+// Created by MainasuK on 2022-1-20.
+//
+
+import Foundation
+
+public final class MastodonTagHistory: NSObject, Codable {
+
+ /// UNIX timestamp on midnight of the given day
+ public let day: Date
+ public let uses: String
+ public let accounts: String
+
+ public init(day: Date, uses: String, accounts: String) {
+ self.day = day
+ self.uses = uses
+ self.accounts = accounts
+ }
+
+}
+
diff --git a/CoreDataStack/Entity/Transient/MastodonVisibility.swift b/CoreDataStack/Entity/Transient/MastodonVisibility.swift
new file mode 100644
index 00000000..798db208
--- /dev/null
+++ b/CoreDataStack/Entity/Transient/MastodonVisibility.swift
@@ -0,0 +1,38 @@
+//
+// MastodonVisibility.swift
+// MastodonVisibility
+//
+// Created by Cirno MainasuK on 2021-8-27.
+// Copyright © 2021 Twidere. All rights reserved.
+//
+
+import Foundation
+
+public enum MastodonVisibility: RawRepresentable {
+ case `public`
+ case unlisted
+ case `private`
+ case direct
+
+ case _other(String)
+
+ public init?(rawValue: String) {
+ switch rawValue {
+ case "public": self = .public
+ case "unlisted": self = .unlisted
+ case "private": self = .private
+ case "direct": self = .direct
+ default: self = ._other(rawValue)
+ }
+ }
+
+ public var rawValue: String {
+ switch self {
+ case .public: return "public"
+ case .unlisted: return "unlisted"
+ case .private: return "private"
+ case .direct: return "direct"
+ case ._other(let value): return value
+ }
+ }
+}
diff --git a/CoreDataStack/Extension/NSManagedObjectContext.swift b/CoreDataStack/Extension/NSManagedObjectContext.swift
index e3f6600c..a3baf4dc 100644
--- a/CoreDataStack/Extension/NSManagedObjectContext.swift
+++ b/CoreDataStack/Extension/NSManagedObjectContext.swift
@@ -47,3 +47,66 @@ extension NSManagedObjectContext {
}
}
}
+
+extension NSManagedObjectContext {
+ public func perform(block: @escaping () throws -> T) async throws -> T {
+ if #available(iOSApplicationExtension 15.0, *) {
+ return try await perform(schedule: .enqueued) {
+ try block()
+ }
+ } else {
+ return try await withCheckedThrowingContinuation { continuation in
+ self.perform {
+ do {
+ let value = try block()
+ continuation.resume(returning: value)
+ } catch {
+ continuation.resume(throwing: error)
+ }
+ }
+ } // end return
+ }
+ }
+
+ public func performChanges(block: @escaping () throws -> T) async throws -> T {
+ if #available(iOS 15.0, *) {
+ return try await perform(schedule: .enqueued) {
+ let value = try block()
+ try self.saveOrRollback()
+ return value
+ }
+ } else {
+ return try await withCheckedThrowingContinuation { continuation in
+ self.perform {
+ do {
+ let value = try block()
+ try self.saveOrRollback()
+ continuation.resume(returning: value)
+ } catch {
+ continuation.resume(throwing: error)
+ }
+ }
+ } // end return
+ }
+ } // end func
+}
+
+extension NSManagedObjectContext {
+ static let objectCacheKey = "ObjectCacheKey"
+ private typealias ObjectCache = [String: NSManagedObject]
+
+ public func cache(
+ _ object: NSManagedObject?,
+ key: String
+ ) {
+ var cache = userInfo[NSManagedObjectContext.objectCacheKey] as? ObjectCache ?? [:]
+ cache[key] = object
+ userInfo[NSManagedObjectContext.objectCacheKey] = cache
+ }
+
+ public func cache(froKey key: String) -> NSManagedObject? {
+ guard let cache = userInfo[NSManagedObjectContext.objectCacheKey] as? ObjectCache
+ else { return nil }
+ return cache[key]
+ }
+}
diff --git a/CoreDataStack/Info.plist b/CoreDataStack/Info.plist
index f652792e..697cdf4d 100644
--- a/CoreDataStack/Info.plist
+++ b/CoreDataStack/Info.plist
@@ -17,6 +17,6 @@
CFBundleShortVersionString
1.3.0
CFBundleVersion
- 90
+ 91
diff --git a/CoreDataStack/Stack/ManagedObjectContextObjectsDidChange.swift b/CoreDataStack/Stack/ManagedObjectContextObjectsDidChange.swift
index 980a2a5e..33cbf08d 100644
--- a/CoreDataStack/Stack/ManagedObjectContextObjectsDidChange.swift
+++ b/CoreDataStack/Stack/ManagedObjectContextObjectsDidChange.swift
@@ -10,10 +10,10 @@ import CoreData
public struct ManagedObjectContextObjectsDidChangeNotification {
- public let notification: Notification
+ public let notification: Foundation.Notification
public let managedObjectContext: NSManagedObjectContext
- public init?(notification: Notification) {
+ public init?(notification: Foundation.Notification) {
guard notification.name == .NSManagedObjectContextObjectsDidChange,
let managedObjectContext = notification.object as? NSManagedObjectContext else {
return nil
diff --git a/CoreDataStack/Stack/ManagedObjectObserver.swift b/CoreDataStack/Stack/ManagedObjectObserver.swift
index 3681fee9..c1fbb5b8 100644
--- a/CoreDataStack/Stack/ManagedObjectObserver.swift
+++ b/CoreDataStack/Stack/ManagedObjectObserver.swift
@@ -2,7 +2,8 @@
// ManagedObjectObserver.swift
// CoreDataStack
//
-// Created by sxiaojian on 2021/2/8.
+// Created by Cirno MainasuK on 2020-6-12.
+// Copyright © 2020 Dimension. All rights reserved.
//
import Foundation
@@ -15,6 +16,26 @@ final public class ManagedObjectObserver {
extension ManagedObjectObserver {
+ public static func observe(context: NSManagedObjectContext) -> AnyPublisher {
+
+ return NotificationCenter.default.publisher(for: .NSManagedObjectContextObjectsDidChange, object: context)
+ .tryMap { notification in
+ guard let notification = ManagedObjectContextObjectsDidChangeNotification(notification: notification) else {
+ throw Error.notManagedObjectChangeNotification
+ }
+
+ let changeTypes = ManagedObjectObserver.changeTypes(in: notification)
+ return Changes(
+ changeTypes: changeTypes,
+ changeNotification: notification
+ )
+ }
+ .mapError { error -> Error in
+ return (error as? Error) ?? .unknown(error)
+ }
+ .eraseToAnyPublisher()
+ }
+
public static func observe(object: NSManagedObject) -> AnyPublisher {
guard let context = object.managedObjectContext else {
return Fail(error: .noManagedObjectContext).eraseToAnyPublisher()
@@ -41,10 +62,26 @@ extension ManagedObjectObserver {
}
extension ManagedObjectObserver {
+ private static func changeTypes(in notification: ManagedObjectContextObjectsDidChangeNotification) -> [ChangeType] {
+ var changeTypes: [ChangeType] = []
+
+ let deleted = notification.deletedObjects.union(notification.invalidedObjects)
+ for object in deleted {
+ changeTypes.append(.delete(object))
+ }
+
+ let updated = notification.updatedObjects.union(notification.refreshedObjects)
+ for object in updated {
+ changeTypes.append(.update(object))
+ }
+
+ return changeTypes
+ }
+
private static func changeType(of object: NSManagedObject, in notification: ManagedObjectContextObjectsDidChangeNotification) -> ChangeType? {
let deleted = notification.deletedObjects.union(notification.invalidedObjects)
if notification.invalidatedAllObjects || deleted.contains(where: { $0 === object }) {
- return .delete
+ return .delete(object)
}
let updated = notification.updatedObjects.union(notification.refreshedObjects)
@@ -57,6 +94,16 @@ extension ManagedObjectObserver {
}
extension ManagedObjectObserver {
+ public struct Changes {
+ public let changeTypes: [ChangeType]
+ public let changeNotification: ManagedObjectContextObjectsDidChangeNotification
+
+ init(changeTypes: [ManagedObjectObserver.ChangeType], changeNotification: ManagedObjectContextObjectsDidChangeNotification) {
+ self.changeTypes = changeTypes
+ self.changeNotification = changeNotification
+ }
+ }
+
public struct Change {
public let changeType: ChangeType?
public let changeNotification: ManagedObjectContextObjectsDidChangeNotification
@@ -65,10 +112,10 @@ extension ManagedObjectObserver {
self.changeType = changeType
self.changeNotification = changeNotification
}
-
}
+
public enum ChangeType {
- case delete
+ case delete(NSManagedObject)
case update(NSManagedObject)
}
diff --git a/CoreDataStack/Template/AutoGenerateProperty.swift b/CoreDataStack/Template/AutoGenerateProperty.swift
new file mode 100644
index 00000000..e36b9369
--- /dev/null
+++ b/CoreDataStack/Template/AutoGenerateProperty.swift
@@ -0,0 +1,14 @@
+//
+// AutoGenerateProperty.swift
+// AutoGenerateProperty
+//
+// Created by Cirno MainasuK on 2021-8-18.
+// Copyright © 2021 Twidere. All rights reserved.
+//
+
+import Foundation
+
+// Stencil protocol
+protocol AutoGenerateProperty { }
+
+// - autoGenerateProperty
diff --git a/CoreDataStack/Template/AutoGenerateRelationship.swift b/CoreDataStack/Template/AutoGenerateRelationship.swift
new file mode 100644
index 00000000..caeed0de
--- /dev/null
+++ b/CoreDataStack/Template/AutoGenerateRelationship.swift
@@ -0,0 +1,14 @@
+//
+// AutoGenerateRelationship.swift
+// AutoGenerateRelationship
+//
+// Created by Cirno MainasuK on 2021-8-19.
+// Copyright © 2021 Twidere. All rights reserved.
+//
+
+import Foundation
+
+// Stencil protocol
+protocol AutoGenerateRelationship { }
+
+// - autoGenerateRelationship
diff --git a/CoreDataStack/Template/AutoUpdatableObject.swift b/CoreDataStack/Template/AutoUpdatableObject.swift
new file mode 100644
index 00000000..ad031db2
--- /dev/null
+++ b/CoreDataStack/Template/AutoUpdatableObject.swift
@@ -0,0 +1,14 @@
+//
+// AutoUpdatableObject.swift
+// AutoUpdatableObject
+//
+// Created by Cirno MainasuK on 2021-8-18.
+// Copyright © 2021 Twidere. All rights reserved.
+//
+
+import Foundation
+
+// Stencil protocol
+protocol AutoUpdatableObject { }
+
+// - autoUpdatableObject
diff --git a/CoreDataStack/Template/Stencil/AutoGenerateProperty.stencil b/CoreDataStack/Template/Stencil/AutoGenerateProperty.stencil
new file mode 100644
index 00000000..2c14bab2
--- /dev/null
+++ b/CoreDataStack/Template/Stencil/AutoGenerateProperty.stencil
@@ -0,0 +1,45 @@
+{% for type in types.implementing.AutoGenerateProperty %}
+// sourcery:inline:{{type.name}}.AutoGenerateProperty
+
+// Generated using Sourcery
+// DO NOT EDIT
+public struct Property {
+ {% for variable in type.variables|instance where
+ variable|annotated:"autoGenerateProperty"
+ %}
+ public let {{variable.name}}: {{variable.typeName}}
+ {% endfor %}
+
+ public init(
+ {% for variable in type.variables|instance where
+ variable|annotated:"autoGenerateProperty"
+ %}
+ {{variable.name}}: {{variable.typeName}}{% if not forloop.last %},{% endif %}
+ {% endfor %}
+ ) {
+ {% for variable in type.variables|instance where
+ variable|annotated:"autoGenerateProperty"
+ %}
+ self.{{variable.name}} = {{variable.name}}
+ {% endfor %}
+ }
+}
+
+public func configure(property: Property) {
+ {% for variable in type.variables|instance where
+ variable|annotated:"autoGenerateProperty"
+ %}
+ self.{{variable.name}} = property.{{variable.name}}
+ {% endfor %}
+}
+
+public func update(property: Property) {
+ {% for variable in type.variables|instance where
+ variable|annotated:"autoUpdatableObject" and
+ variable|annotated:"autoGenerateProperty"
+ %}
+ update({{variable.name}}: property.{{variable.name}})
+ {% endfor %}
+}
+// sourcery:end
+{% endfor %}
diff --git a/CoreDataStack/Template/Stencil/AutoGenerateRelationship.stencil b/CoreDataStack/Template/Stencil/AutoGenerateRelationship.stencil
new file mode 100644
index 00000000..8b549023
--- /dev/null
+++ b/CoreDataStack/Template/Stencil/AutoGenerateRelationship.stencil
@@ -0,0 +1,29 @@
+{% for type in types.implementing.AutoGenerateRelationship %}
+// sourcery:inline:{{type.name}}.AutoGenerateRelationship
+
+// Generated using Sourcery
+// DO NOT EDIT
+public struct Relationship {
+ {% for variable in type.storedVariables|annotated:"autoGenerateRelationship" %}
+ public let {{variable.name}}: {{variable.typeName}}
+ {% endfor %}
+
+ public init(
+ {% for variable in type.storedVariables|annotated:"autoGenerateRelationship" %}
+ {{variable.name}}: {{variable.typeName}}{% if not forloop.last %},{% endif %}
+ {% endfor %}
+ ) {
+ {% for variable in type.storedVariables|annotated:"autoGenerateRelationship" %}
+ self.{{variable.name}} = {{variable.name}}
+ {% endfor %}
+ }
+}
+
+public func configure(relationship: Relationship) {
+ {% for variable in type.storedVariables|annotated:"autoGenerateRelationship" %}
+ self.{{variable.name}} = relationship.{{variable.name}}
+ {% endfor %}
+}
+
+// sourcery:end
+{% endfor %}
diff --git a/CoreDataStack/Template/Stencil/AutoUpdatableObject.stencil b/CoreDataStack/Template/Stencil/AutoUpdatableObject.stencil
new file mode 100644
index 00000000..4e81c8b4
--- /dev/null
+++ b/CoreDataStack/Template/Stencil/AutoUpdatableObject.stencil
@@ -0,0 +1,16 @@
+{% for type in types.implementing.AutoUpdatableObject %}
+// sourcery:inline:{{type.name}}.AutoUpdatableObject
+
+// Generated using Sourcery
+// DO NOT EDIT
+{% for variable in type.variables|instance where
+variable|annotated:"autoUpdatableObject"
+%}
+public func update({{variable.name}}: {{variable.typeName}}) {
+ if self.{{variable.name}} != {{variable.name}} {
+ self.{{variable.name}} = {{variable.name}}
+ }
+}
+{% endfor %}
+// sourcery:end
+{% endfor %}
diff --git a/CoreDataStack/Utility/ManagedObjectRecord.swift b/CoreDataStack/Utility/ManagedObjectRecord.swift
new file mode 100644
index 00000000..dbdce6c3
--- /dev/null
+++ b/CoreDataStack/Utility/ManagedObjectRecord.swift
@@ -0,0 +1,32 @@
+//
+// ManagedObjectRecord.swift
+// ManagedObjectRecord
+//
+// Created by Cirno MainasuK on 2021-8-25.
+// Copyright © 2021 Twidere. All rights reserved.
+//
+
+import Foundation
+import CoreData
+
+public class ManagedObjectRecord: Hashable {
+
+ public let objectID: NSManagedObjectID
+
+ public init(objectID: NSManagedObjectID) {
+ self.objectID = objectID
+ }
+
+ public func object(in managedObjectContext: NSManagedObjectContext) -> T? {
+ return managedObjectContext.object(with: objectID) as? T
+ }
+
+ public static func == (lhs: ManagedObjectRecord, rhs: ManagedObjectRecord) -> Bool {
+ return lhs.objectID == rhs.objectID
+ }
+
+ public func hash(into hasher: inout Hasher) {
+ hasher.combine(objectID)
+ }
+
+}
diff --git a/CoreDataStackTests/Info.plist b/CoreDataStackTests/Info.plist
index f652792e..697cdf4d 100644
--- a/CoreDataStackTests/Info.plist
+++ b/CoreDataStackTests/Info.plist
@@ -17,6 +17,6 @@
CFBundleShortVersionString
1.3.0
CFBundleVersion
- 90
+ 91
diff --git a/Localization/StringsConvertor/Sources/StringsConvertor/main.swift b/Localization/StringsConvertor/Sources/StringsConvertor/main.swift
index 6507986b..79ee6b49 100644
--- a/Localization/StringsConvertor/Sources/StringsConvertor/main.swift
+++ b/Localization/StringsConvertor/Sources/StringsConvertor/main.swift
@@ -1,11 +1,6 @@
import os.log
import Foundation
-let currentFileURL = URL(fileURLWithPath: "\(#file)", isDirectory: false)
-let packageRootURL = currentFileURL.deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent()
-let inputDirectoryURL = packageRootURL.appendingPathComponent("input", isDirectory: true)
-let outputDirectoryURL = packageRootURL.appendingPathComponent("output", isDirectory: true)
-
// conver i18n JSON templates to strings files
private func convert(from inputDirectoryURL: URL, to outputDirectory: URL) {
do {
@@ -17,7 +12,6 @@ private func convert(from inputDirectoryURL: URL, to outputDirectory: URL) {
for inputLanguageDirectoryURL in inputLanguageDirectoryURLs {
let language = inputLanguageDirectoryURL.lastPathComponent
guard let mappedLanguage = map(language: language) else { continue }
- let outputDirectoryURL = outputDirectory.appendingPathComponent(mappedLanguage + ".lproj", isDirectory: true)
os_log("%{public}s[%{public}ld], %{public}s: process %s -> %s", ((#file as NSString).lastPathComponent), #line, #function, language, mappedLanguage)
let fileURLs = try FileManager.default.contentsOfDirectory(
@@ -29,9 +23,19 @@ private func convert(from inputDirectoryURL: URL, to outputDirectory: URL) {
os_log("%{public}s[%{public}ld], %{public}s: process %s", ((#file as NSString).lastPathComponent), #line, #function, jsonURL.debugDescription)
let filename = jsonURL.deletingPathExtension().lastPathComponent
guard let (mappedFilename, keyStyle) = map(filename: filename) else { continue }
- let outputFileURL = outputDirectoryURL.appendingPathComponent(mappedFilename).appendingPathExtension("strings")
+ guard let bundle = bundle(filename: filename) else { continue }
+
+ let outputDirectoryURL = outputDirectory
+ .appendingPathComponent(bundle, isDirectory: true)
+ .appendingPathComponent(mappedLanguage + ".lproj", isDirectory: true)
+
+ let outputFileURL = outputDirectoryURL
+ .appendingPathComponent(mappedFilename)
+ .appendingPathExtension("strings")
+
let strings = try process(url: jsonURL, keyStyle: keyStyle)
try? FileManager.default.createDirectory(at: outputDirectoryURL, withIntermediateDirectories: true, attributes: nil)
+
try strings.write(to: outputFileURL, atomically: true, encoding: .utf8)
}
}
@@ -44,6 +48,7 @@ private func convert(from inputDirectoryURL: URL, to outputDirectory: URL) {
private func map(language: String) -> String? {
switch language {
case "ar_SA": return "ar" // Arabic (Saudi Arabia)
+ case "eu_ES": return "eu-ES" // Basque
case "ca_ES": return "ca" // Catalan
case "zh_CN": return "zh-Hans" // Chinese Simplified
case "nl_NL": return "nl" // Dutch
@@ -56,6 +61,7 @@ private func map(language: String) -> String? {
case "gd_GB": return "gd-GB" // Scottish Gaelic
case "es_ES": return "es" // Spanish
case "es_AR": return "es-419" // Spanish, Argentina
+ case "sv_FI": return "sv_FI" // Swedish, Finland
case "th_TH": return "th" // Thai
default: return nil
}
@@ -69,6 +75,14 @@ private func map(filename: String) -> (filename: String, keyStyle: Parser.KeySty
}
}
+private func bundle(filename: String) -> String? {
+ switch filename {
+ case "app": return "module"
+ case "ios-infoPlist": return "main"
+ default: return nil
+ }
+}
+
private func process(url: URL, keyStyle: Parser.KeyStyle) throws -> String {
do {
let data = try Data(contentsOf: url)
@@ -115,9 +129,16 @@ private func move(from inputDirectoryURL: URL, to outputDirectoryURL: URL, pathE
}
}
-// i18n from "input" to "output"
+
+let currentFileURL = URL(fileURLWithPath: "\(#file)", isDirectory: false)
+let packageRootURL = currentFileURL.deletingLastPathComponent().deletingLastPathComponent().deletingLastPathComponent()
+
+let inputDirectoryURL = packageRootURL.appendingPathComponent("input", isDirectory: true)
+let outputDirectoryURL = packageRootURL.appendingPathComponent("output", isDirectory: true)
convert(from: inputDirectoryURL, to: outputDirectoryURL)
-move(from: inputDirectoryURL, to: outputDirectoryURL, pathExtension: "stringsdict")
+
+let moduleDirectoryURL = outputDirectoryURL.appendingPathComponent("module", isDirectory: true)
+move(from: inputDirectoryURL, to: moduleDirectoryURL, pathExtension: "stringsdict")
// i18n from "Intents/input" to "Intents/output"
let intentsDirectoryURL = packageRootURL.appendingPathComponent("Intents", isDirectory: true)
diff --git a/Localization/app.json b/Localization/app.json
index 0071f6f9..b6da7c4e 100644
--- a/Localization/app.json
+++ b/Localization/app.json
@@ -45,8 +45,8 @@
"message": "Please enable the photo library access permission to save the photo."
},
"delete_post": {
- "title": "Are you sure you want to delete this post?",
- "delete": "Delete"
+ "title": "Delete Post",
+ "message": "Are you sure you want to delete this post?"
},
"clean_cache": {
"title": "Clean Cache",
@@ -412,14 +412,24 @@
"segmented_control": {
"posts": "Posts",
"replies": "Replies",
- "media": "Media"
+ "posts_and_replies": "Posts and Replies",
+ "media": "Media",
+ "about": "About"
},
"relationship_action_alert": {
+ "confirm_mute_user": {
+ "title": "Mute Account",
+ "message": "Confirm to mute %s"
+ },
"confirm_unmute_user": {
"title": "Unmute Account",
"message": "Confirm to unmute %s"
},
- "confirm_unblock_usre": {
+ "confirm_block_user": {
+ "title": "Block Account",
+ "message": "Confirm to block %s"
+ },
+ "confirm_unblock_user": {
"title": "Unblock Account",
"message": "Confirm to unblock %s"
}
@@ -472,12 +482,14 @@
"Everything": "Everything",
"Mentions": "Mentions"
},
- "user_followed_you": "%s followed you",
- "user_favorited your post": "%s favorited your post",
- "user_reblogged_your_post": "%s reblogged your post",
- "user_mentioned_you": "%s mentioned you",
- "user_requested_to_follow_you": "%s requested to follow you",
- "user_your_poll_has_ended": "%s Your poll has ended",
+ "notification_description": {
+ "followed_you": "followd you",
+ "favorited_your_post": "favorited your post",
+ "reblogged_your_post": "reblogged your post",
+ "mentioned_you": "mentioned you",
+ "request_to_follow_you": "request to follow you",
+ "poll_has_ended": "poll has ended"
+ },
"keyobard": {
"show_everything": "Show Everything",
"show_mentions": "Show Mentions"
@@ -564,4 +576,4 @@
"accessibility_hint": "Double tap to dismiss this wizard"
}
}
-}
+}
\ No newline at end of file
diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj
index b79fb901..16a36e6d 100644
--- a/Mastodon.xcodeproj/project.pbxproj
+++ b/Mastodon.xcodeproj/project.pbxproj
@@ -11,11 +11,8 @@
0F2021FB2613262F000C64BF /* HashtagTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F2021FA2613262F000C64BF /* HashtagTimelineViewController.swift */; };
0F202201261326E6000C64BF /* HashtagTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F202200261326E6000C64BF /* HashtagTimelineViewModel.swift */; };
0F20220726134DA4000C64BF /* HashtagTimelineViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F20220626134DA4000C64BF /* HashtagTimelineViewModel+Diffable.swift */; };
- 0F20220D26134E3F000C64BF /* HashtagTimelineViewModel+LoadLatestState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F20220C26134E3F000C64BF /* HashtagTimelineViewModel+LoadLatestState.swift */; };
0F202213261351F5000C64BF /* APIService+HashtagTimeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F202212261351F5000C64BF /* APIService+HashtagTimeline.swift */; };
- 0F202227261411BB000C64BF /* HashtagTimelineViewController+Provider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F202226261411BA000C64BF /* HashtagTimelineViewController+Provider.swift */; };
0F20222D261457EE000C64BF /* HashtagTimelineViewModel+LoadOldestState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F20222C261457EE000C64BF /* HashtagTimelineViewModel+LoadOldestState.swift */; };
- 0F20223326145E51000C64BF /* HashtagTimelineViewModel+LoadMiddleState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F20223226145E51000C64BF /* HashtagTimelineViewModel+LoadMiddleState.swift */; };
0F20223926146553000C64BF /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F20223826146553000C64BF /* Array.swift */; };
0FAA0FDF25E0B57E0017CCDE /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA0FDE25E0B57E0017CCDE /* WelcomeViewController.swift */; };
0FAA101225E105390017CCDE /* PrimaryActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA101125E105390017CCDE /* PrimaryActionButton.swift */; };
@@ -23,18 +20,13 @@
0FAA102725E1126A0017CCDE /* MastodonPickServerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA102625E1126A0017CCDE /* MastodonPickServerViewController.swift */; };
0FB3D2F725E4C24D00AAD544 /* MastodonPickServerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D2F625E4C24D00AAD544 /* MastodonPickServerViewModel.swift */; };
0FB3D2FE25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D2FD25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift */; };
- 0FB3D30825E524C600AAD544 /* PickServerCategoriesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D30725E524C600AAD544 /* PickServerCategoriesCell.swift */; };
0FB3D30F25E525CD00AAD544 /* PickServerCategoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.swift */; };
0FB3D31E25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D31D25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift */; };
- 0FB3D33225E5F50E00AAD544 /* PickServerSearchCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D33125E5F50E00AAD544 /* PickServerSearchCell.swift */; };
0FB3D33825E6401400AAD544 /* PickServerCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D33725E6401400AAD544 /* PickServerCell.swift */; };
164F0EBC267D4FE400249499 /* BoopSound.caf in Resources */ = {isa = PBXBuildFile; fileRef = 164F0EBB267D4FE400249499 /* BoopSound.caf */; };
18BC7629F65E6DB12CB8416D /* Pods_Mastodon_MastodonUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3C030226D3C73DCC23D67452 /* Pods_Mastodon_MastodonUITests.framework */; };
- 2D04F42525C255B9003F936F /* APIService+PublicTimeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D04F42425C255B9003F936F /* APIService+PublicTimeline.swift */; };
2D084B8D26258EA3003AA3AF /* NotificationViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D084B8C26258EA3003AA3AF /* NotificationViewModel+Diffable.swift */; };
- 2D084B9326259545003AA3AF /* NotificationViewModel+LoadLatestState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D084B9226259545003AA3AF /* NotificationViewModel+LoadLatestState.swift */; };
2D0B7A1D261D839600B44727 /* SearchHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D0B7A1C261D839600B44727 /* SearchHistory.swift */; };
- 2D152A8C25C295CC009AA50C /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D152A8B25C295CC009AA50C /* StatusView.swift */; };
2D152A9225C2980C009AA50C /* UIFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D152A9125C2980C009AA50C /* UIFont.swift */; };
2D198643261BF09500F0B013 /* SearchResultItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D198642261BF09500F0B013 /* SearchResultItem.swift */; };
2D198649261C0B8500F0B013 /* SearchResultSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D198648261C0B8500F0B013 /* SearchResultSection.swift */; };
@@ -42,33 +34,21 @@
2D206B8625F5FB0900143C56 /* Double.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D206B8525F5FB0900143C56 /* Double.swift */; };
2D206B8C25F6015000143C56 /* AudioPlaybackService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D206B8B25F6015000143C56 /* AudioPlaybackService.swift */; };
2D206B9225F60EA700143C56 /* UIControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D206B9125F60EA700143C56 /* UIControl.swift */; };
- 2D24E11D2626D8B100A59D4F /* NotificationStatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D24E11C2626D8B100A59D4F /* NotificationStatusTableViewCell.swift */; };
2D24E1232626ED9D00A59D4F /* UIView+Gesture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D24E1222626ED9D00A59D4F /* UIView+Gesture.swift */; };
- 2D24E12D2626FD2E00A59D4F /* NotificationViewModel+LoadOldestState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D24E12C2626FD2E00A59D4F /* NotificationViewModel+LoadOldestState.swift */; };
2D32EAAC25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAAB25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift */; };
2D32EABA25CB9B0500C9ED86 /* UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAB925CB9B0500C9ED86 /* UIView.swift */; };
- 2D32EADA25CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D32EAD925CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift */; };
- 2D34D9CB261489930081BFC0 /* SearchViewController+Recommend.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D34D9CA261489930081BFC0 /* SearchViewController+Recommend.swift */; };
2D34D9D126148D9E0081BFC0 /* APIService+Recommend.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D34D9D026148D9E0081BFC0 /* APIService+Recommend.swift */; };
2D34D9DB261494120081BFC0 /* APIService+Search.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D34D9DA261494120081BFC0 /* APIService+Search.swift */; };
- 2D34D9E226149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D34D9E126149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift */; };
2D35237A26256D920031AF25 /* NotificationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D35237926256D920031AF25 /* NotificationSection.swift */; };
2D364F7225E66D7500204FDC /* MastodonResendEmailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */; };
2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */; };
2D38F1C625CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */; };
2D38F1D525CD465300561493 /* HomeTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1D425CD465300561493 /* HomeTimelineViewController.swift */; };
- 2D38F1DF25CD46A400561493 /* HomeTimelineViewController+Provider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1DE25CD46A400561493 /* HomeTimelineViewController+Provider.swift */; };
2D38F1E525CD46C100561493 /* HomeTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1E425CD46C100561493 /* HomeTimelineViewModel.swift */; };
2D38F1EB25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1EA25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift */; };
- 2D38F1F125CD477D00561493 /* HomeTimelineViewModel+LoadMiddleState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1F025CD477D00561493 /* HomeTimelineViewModel+LoadMiddleState.swift */; };
2D38F1F725CD47AC00561493 /* HomeTimelineViewModel+LoadOldestState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1F625CD47AC00561493 /* HomeTimelineViewModel+LoadOldestState.swift */; };
- 2D38F1FE25CD481700561493 /* StatusProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F1FD25CD481700561493 /* StatusProvider.swift */; };
2D38F20825CD491300561493 /* DisposeBagCollectable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D38F20725CD491300561493 /* DisposeBagCollectable.swift */; };
2D3F9E0425DFA133004262D9 /* UITapGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */; };
- 2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF7D25C82218004A627A /* ActionToolBarContainer.swift */; };
- 2D42FF8525C8224F004A627A /* HitTestExpandedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF8425C8224F004A627A /* HitTestExpandedButton.swift */; };
- 2D42FF8F25C8228A004A627A /* UIButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF8E25C8228A004A627A /* UIButton.swift */; };
- 2D45E5BF25C9549700A6D639 /* PublicTimelineViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D45E5BE25C9549700A6D639 /* PublicTimelineViewModel+State.swift */; };
2D4AD89C263165B500613EFC /* SuggestionAccountCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4AD89B263165B500613EFC /* SuggestionAccountCollectionViewCell.swift */; };
2D4AD8A226316CD200613EFC /* SelectedAccountSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4AD8A126316CD200613EFC /* SelectedAccountSection.swift */; };
2D4AD8A826316D3500613EFC /* SelectedAccountItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D4AD8A726316D3500613EFC /* SelectedAccountItem.swift */; };
@@ -83,30 +63,20 @@
2D607AD826242FC500B70763 /* NotificationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D607AD726242FC500B70763 /* NotificationViewModel.swift */; };
2D6125472625436B00299647 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D6125462625436B00299647 /* Notification.swift */; };
2D61254D262547C200299647 /* APIService+Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D61254C262547C200299647 /* APIService+Notification.swift */; };
- 2D61335825C188A000CAE157 /* APIService+Persist+Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D61335725C188A000CAE157 /* APIService+Persist+Status.swift */; };
2D61335E25C1894B00CAE157 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D61335D25C1894B00CAE157 /* APIService.swift */; };
2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */ = {isa = PBXBuildFile; productRef = 2D61336825C18A4F00CAE157 /* AlamofireNetworkActivityIndicator */; };
2D650FAB25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D650FAA25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift */; };
2D694A7425F9EB4E0038ADDC /* ContentWarningOverlayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D694A7325F9EB4E0038ADDC /* ContentWarningOverlayView.swift */; };
- 2D69CFF425CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69CFF325CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift */; };
- 2D69D00A25CAA00300C3A1B2 /* APIService+CoreData+Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69D00925CAA00300C3A1B2 /* APIService+CoreData+Status.swift */; };
2D6DE40026141DF600A63F6A /* SearchViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D6DE3FF26141DF600A63F6A /* SearchViewModel.swift */; };
- 2D76316525C14BD100929FB9 /* PublicTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76316425C14BD100929FB9 /* PublicTimelineViewController.swift */; };
- 2D76316B25C14D4C00929FB9 /* PublicTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76316A25C14D4C00929FB9 /* PublicTimelineViewModel.swift */; };
- 2D76317D25C14DF500929FB9 /* PublicTimelineViewController+Provider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76317C25C14DF400929FB9 /* PublicTimelineViewController+Provider.swift */; };
- 2D76318325C14E8F00929FB9 /* PublicTimelineViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76318225C14E8F00929FB9 /* PublicTimelineViewModel+Diffable.swift */; };
2D76319F25C1521200929FB9 /* StatusSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76319E25C1521200929FB9 /* StatusSection.swift */; };
2D7631A825C1535600929FB9 /* StatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D7631A725C1535600929FB9 /* StatusTableViewCell.swift */; };
- 2D7631B325C159F700929FB9 /* Item.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D7631B225C159F700929FB9 /* Item.swift */; };
2D7867192625B77500211898 /* NotificationItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D7867182625B77500211898 /* NotificationItem.swift */; };
- 2D79E701261EA5550011E398 /* APIService+CoreData+Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D79E700261EA5550011E398 /* APIService+CoreData+Tag.swift */; };
2D82B9FF25E7863200E36F0F /* OnboardingViewControllerAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D82B9FE25E7863200E36F0F /* OnboardingViewControllerAppearance.swift */; };
2D82BA0525E7897700E36F0F /* MastodonResendEmailViewModelNavigationDelegateShim.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D82BA0425E7897700E36F0F /* MastodonResendEmailViewModelNavigationDelegateShim.swift */; };
2D8434F525FF465D00EECE90 /* HomeTimelineNavigationBarTitleViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D8434F425FF465D00EECE90 /* HomeTimelineNavigationBarTitleViewModel.swift */; };
2D8434FB25FF46B300EECE90 /* HomeTimelineNavigationBarTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D8434FA25FF46B300EECE90 /* HomeTimelineNavigationBarTitleView.swift */; };
2D84350525FF858100EECE90 /* UIScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D84350425FF858100EECE90 /* UIScrollView.swift */; };
2D8FCA082637EABB00137F46 /* APIService+FollowRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D8FCA072637EABB00137F46 /* APIService+FollowRequest.swift */; };
- 2D927F0225C7E4F2004F19B8 /* Mention.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F0125C7E4F2004F19B8 /* Mention.swift */; };
2D927F0825C7E9A8004F19B8 /* Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F0725C7E9A8004F19B8 /* Tag.swift */; };
2D927F0E25C7E9C9004F19B8 /* History.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F0D25C7E9C9004F19B8 /* History.swift */; };
2D927F1425C7EDD9004F19B8 /* Emoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D927F1325C7EDD9004F19B8 /* Emoji.swift */; };
@@ -127,16 +97,11 @@
2DAC9E46262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DAC9E45262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift */; };
2DB72C8C262D764300CE6173 /* Mastodon+Entity+Notification+Type.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DB72C8B262D764300CE6173 /* Mastodon+Entity+Notification+Type.swift */; };
2DCB73FD2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DCB73FC2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift */; };
- 2DE0FAC12615F04D00CDF649 /* RecommendHashTagSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE0FAC02615F04D00CDF649 /* RecommendHashTagSection.swift */; };
- 2DE0FAC82615F5F000CDF649 /* SearchRecommendAccountsCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE0FAC72615F5F000CDF649 /* SearchRecommendAccountsCollectionViewCell.swift */; };
2DE0FACE2615F7AD00CDF649 /* RecommendAccountSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DE0FACD2615F7AD00CDF649 /* RecommendAccountSection.swift */; };
2DF123A725C3B0210020F248 /* ActiveLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF123A625C3B0210020F248 /* ActiveLabel.swift */; };
- 2DF75B9B25D0E27500694EC8 /* StatusProviderFacade.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75B9A25D0E27500694EC8 /* StatusProviderFacade.swift */; };
- 2DF75BA125D0E29D00694EC8 /* StatusProvider+StatusTableViewCellDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BA025D0E29D00694EC8 /* StatusProvider+StatusTableViewCellDelegate.swift */; };
2DF75BA725D10E1000694EC8 /* APIService+Favorite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BA625D10E1000694EC8 /* APIService+Favorite.swift */; };
2DF75BB925D1474100694EC8 /* ManagedObjectObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BB825D1474100694EC8 /* ManagedObjectObserver.swift */; };
2DF75BC725D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BC625D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift */; };
- 2DFAD5372617010500F9EE7C /* SearchResultTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DFAD5362617010500F9EE7C /* SearchResultTableViewCell.swift */; };
4278334D6033AEEE0A1C5155 /* Pods_ShareActionExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A32B0CACBF35F4CC3CFAA043 /* Pods_ShareActionExtension.framework */; };
5B24BBDA262DB14800A9381B /* ReportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBD7262DB14800A9381B /* ReportViewModel.swift */; };
5B24BBDB262DB14800A9381B /* ReportViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBD8262DB14800A9381B /* ReportViewModel+Diffable.swift */; };
@@ -168,9 +133,7 @@
5DF1054725F8870E00D6C0D4 /* VideoPlayerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1054625F8870E00D6C0D4 /* VideoPlayerViewModel.swift */; };
5DF1056425F887CB00D6C0D4 /* AVPlayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */; };
5DF1057925F88A1D00D6C0D4 /* PlayerContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1057825F88A1D00D6C0D4 /* PlayerContainerView.swift */; };
- 5DF1057F25F88A4100D6C0D4 /* TouchBlockingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1057E25F88A4100D6C0D4 /* TouchBlockingView.swift */; };
5DF1058525F88AE500D6C0D4 /* NeedsDependency+AVPlayerViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1058425F88AE500D6C0D4 /* NeedsDependency+AVPlayerViewControllerDelegate.swift */; };
- 5DFC35DF262068D20045711D /* SearchViewController+Follow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DFC35DE262068D20045711D /* SearchViewController+Follow.swift */; };
5E0DEC05797A7E6933788DDB /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */; };
5E44BF88AD33646E64727BCF /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */; };
87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; };
@@ -183,6 +146,20 @@
DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140CE25C42AEE00F9F3CF /* OSLog.swift */; };
DB01E23326A98F0900C3965B /* MastodonMeta in Frameworks */ = {isa = PBXBuildFile; productRef = DB01E23226A98F0900C3965B /* MastodonMeta */; };
DB01E23526A98F0900C3965B /* MetaTextKit in Frameworks */ = {isa = PBXBuildFile; productRef = DB01E23426A98F0900C3965B /* MetaTextKit */; };
+ DB023D26279FFB0A005AC798 /* ShareActivityProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB023D25279FFB0A005AC798 /* ShareActivityProvider.swift */; };
+ DB023D2827A0FABD005AC798 /* NotificationTableViewCellDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB023D2727A0FABD005AC798 /* NotificationTableViewCellDelegate.swift */; };
+ DB023D2A27A0FE5C005AC798 /* DataSourceProvider+NotificationTableViewCellDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB023D2927A0FE5C005AC798 /* DataSourceProvider+NotificationTableViewCellDelegate.swift */; };
+ DB023D2C27A10464005AC798 /* NotificationTimelineViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB023D2B27A10464005AC798 /* NotificationTimelineViewController+DataSourceProvider.swift */; };
+ DB025B78278D606A002F581E /* StatusItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB025B77278D606A002F581E /* StatusItem.swift */; };
+ DB025B84278D6272002F581E /* AutoGenerateProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB025B81278D6271002F581E /* AutoGenerateProperty.swift */; };
+ DB025B85278D6272002F581E /* AutoUpdatableObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB025B82278D6272002F581E /* AutoUpdatableObject.swift */; };
+ DB025B86278D6272002F581E /* AutoGenerateRelationship.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB025B83278D6272002F581E /* AutoGenerateRelationship.swift */; };
+ DB025B89278D6339002F581E /* Feed.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB025B88278D6339002F581E /* Feed.swift */; };
+ DB025B8C278D6374002F581E /* Acct.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB025B8B278D6374002F581E /* Acct.swift */; };
+ DB025B90278D6489002F581E /* Feed+Kind.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB025B8F278D6489002F581E /* Feed+Kind.swift */; };
+ DB025B93278D6501002F581E /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB025B92278D6501002F581E /* Persistence.swift */; };
+ DB025B95278D6530002F581E /* Persistence+MastodonUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB025B94278D6530002F581E /* Persistence+MastodonUser.swift */; };
+ DB025B97278D66D5002F581E /* MastodonUser+Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB025B96278D66D5002F581E /* MastodonUser+Property.swift */; };
DB029E95266A20430062874E /* MastodonAuthenticationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB029E94266A20430062874E /* MastodonAuthenticationController.swift */; };
DB02CDAB26256A9500D0A2AF /* ThreadReplyLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB02CDAA26256A9500D0A2AF /* ThreadReplyLoaderTableViewCell.swift */; };
DB02CDBF2625AE5000D0A2AF /* AdaptiveUserInterfaceStyleBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB02CDBE2625AE5000D0A2AF /* AdaptiveUserInterfaceStyleBarButtonItem.swift */; };
@@ -206,23 +183,44 @@
DB084B5725CBC56C00F898ED /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB084B5625CBC56C00F898ED /* Status.swift */; };
DB0AC6FC25CD02E600D75117 /* APIService+Instance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */; };
DB0C946526A6FD4D0088FB11 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = DB0C946426A6FD4D0088FB11 /* AlamofireImage */; };
- DB0C946B26A700AB0088FB11 /* MastodonUser+Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0C946A26A700AB0088FB11 /* MastodonUser+Property.swift */; };
- DB0C946C26A700CE0088FB11 /* MastodonUser+Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0C946A26A700AB0088FB11 /* MastodonUser+Property.swift */; };
- DB0C946F26A7D2A80088FB11 /* AvatarImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0C946E26A7D2A80088FB11 /* AvatarImageView.swift */; };
- DB0C947226A7D2D70088FB11 /* AvatarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0C947126A7D2D70088FB11 /* AvatarButton.swift */; };
DB0C947726A7FE840088FB11 /* NotificationAvatarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0C947626A7FE840088FB11 /* NotificationAvatarButton.swift */; };
- DB0E91EA26A9675100BD2ACC /* MetaLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0E91E926A9675100BD2ACC /* MetaLabel.swift */; };
DB0EF72B26FDB1D200347686 /* SidebarListCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0EF72A26FDB1D200347686 /* SidebarListCollectionViewCell.swift */; };
DB0EF72E26FDB24F00347686 /* SidebarListContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0EF72D26FDB24F00347686 /* SidebarListContentView.swift */; };
DB0F8150264D1E2500F2A12B /* PickServerLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0F814F264D1E2500F2A12B /* PickServerLoaderTableViewCell.swift */; };
+ DB0FCB68279507EF006C02E2 /* DataSourceFacade+Meta.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB67279507EF006C02E2 /* DataSourceFacade+Meta.swift */; };
+ DB0FCB6A27950CB3006C02E2 /* MastodonMention.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB6927950CB3006C02E2 /* MastodonMention.swift */; };
+ DB0FCB6C27950E29006C02E2 /* MastodonMentionContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB6B27950E29006C02E2 /* MastodonMentionContainer.swift */; };
+ DB0FCB6E27950E6B006C02E2 /* MastodonMention.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB6D27950E6B006C02E2 /* MastodonMention.swift */; };
+ DB0FCB7027951368006C02E2 /* TimelineMiddleLoaderTableViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB6F27951368006C02E2 /* TimelineMiddleLoaderTableViewCell+ViewModel.swift */; };
+ DB0FCB7227952986006C02E2 /* NamingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB7127952986006C02E2 /* NamingState.swift */; };
+ DB0FCB7427956939006C02E2 /* DataSourceFacade+Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB7327956939006C02E2 /* DataSourceFacade+Status.swift */; };
+ DB0FCB76279571C5006C02E2 /* ThreadViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB75279571C5006C02E2 /* ThreadViewController+DataSourceProvider.swift */; };
+ DB0FCB7827957678006C02E2 /* DataSourceProvider+UITableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB7727957678006C02E2 /* DataSourceProvider+UITableViewDelegate.swift */; };
+ DB0FCB7A279576A2006C02E2 /* DataSourceFacade+Thread.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB79279576A2006C02E2 /* DataSourceFacade+Thread.swift */; };
+ DB0FCB7C2795821F006C02E2 /* StatusThreadRootTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB7B2795821F006C02E2 /* StatusThreadRootTableViewCell.swift */; };
+ DB0FCB7E27958957006C02E2 /* StatusThreadRootTableViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB7D27958957006C02E2 /* StatusThreadRootTableViewCell+ViewModel.swift */; };
+ DB0FCB8027968F70006C02E2 /* MastodonStatusThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB7F27968F70006C02E2 /* MastodonStatusThreadViewModel.swift */; };
+ DB0FCB822796AC78006C02E2 /* UserTimelineViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB812796AC78006C02E2 /* UserTimelineViewController+DataSourceProvider.swift */; };
+ DB0FCB842796B2A2006C02E2 /* FavoriteViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB832796B2A2006C02E2 /* FavoriteViewController+DataSourceProvider.swift */; };
+ DB0FCB862796BDA1006C02E2 /* SearchSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB852796BDA1006C02E2 /* SearchSection.swift */; };
+ DB0FCB882796BDA9006C02E2 /* SearchItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB872796BDA9006C02E2 /* SearchItem.swift */; };
+ DB0FCB8C2796BF8D006C02E2 /* SearchViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB8B2796BF8D006C02E2 /* SearchViewModel+Diffable.swift */; };
+ DB0FCB8E2796C0B7006C02E2 /* TrendCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB8D2796C0B7006C02E2 /* TrendCollectionViewCell.swift */; };
+ DB0FCB902796C5EB006C02E2 /* APIService+Trend.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB8F2796C5EB006C02E2 /* APIService+Trend.swift */; };
+ DB0FCB922796DE19006C02E2 /* TrendSectionHeaderCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB912796DE19006C02E2 /* TrendSectionHeaderCollectionReusableView.swift */; };
+ DB0FCB942797E2B0006C02E2 /* SearchResultViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB932797E2B0006C02E2 /* SearchResultViewModel+Diffable.swift */; };
+ DB0FCB962797E6C2006C02E2 /* SearchResultViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB952797E6C2006C02E2 /* SearchResultViewController+DataSourceProvider.swift */; };
+ DB0FCB982797F6BF006C02E2 /* UserTableViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB972797F6BF006C02E2 /* UserTableViewCell+ViewModel.swift */; };
+ DB0FCB9A2797F7AD006C02E2 /* UserView+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB992797F7AD006C02E2 /* UserView+Configuration.swift */; };
+ DB0FCB9C27980AB6006C02E2 /* HashtagTimelineViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0FCB9B27980AB6006C02E2 /* HashtagTimelineViewController+DataSourceProvider.swift */; };
DB118A8225E4B6E600FAB162 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB118A8125E4B6E600FAB162 /* Preview Assets.xcassets */; };
+ DB159C2B27A17BAC0068DC77 /* DataSourceFacade+Media.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB159C2A27A17BAC0068DC77 /* DataSourceFacade+Media.swift */; };
+ DB179267278D5A4A00B71DEB /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DB179266278D5A4A00B71DEB /* MastodonSDK */; };
DB1D186C25EF5BA7003F1F23 /* PollTableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D186B25EF5BA7003F1F23 /* PollTableView.swift */; };
DB1D61CF26F1B33600DA8662 /* WelcomeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D61CE26F1B33600DA8662 /* WelcomeViewModel.swift */; };
- DB1D842C26551A1C000346B3 /* StatusProvider+StatusTableViewKeyCommandNavigateable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D842B26551A1C000346B3 /* StatusProvider+StatusTableViewKeyCommandNavigateable.swift */; };
DB1D842E26552C4D000346B3 /* StatusTableViewControllerNavigateable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D842D26552C4D000346B3 /* StatusTableViewControllerNavigateable.swift */; };
DB1D843026566512000346B3 /* KeyboardPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D842F26566512000346B3 /* KeyboardPreference.swift */; };
DB1D843426579931000346B3 /* TableViewControllerNavigateable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D843326579931000346B3 /* TableViewControllerNavigateable.swift */; };
- DB1D843626579DB5000346B3 /* StatusProvider+TableViewControllerNavigateable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D843526579DB5000346B3 /* StatusProvider+TableViewControllerNavigateable.swift */; };
DB1D84382657B275000346B3 /* SegmentedControlNavigateable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1D84372657B275000346B3 /* SegmentedControlNavigateable.swift */; };
DB1E346825F518E20079D7DF /* CategoryPickerSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1E346725F518E20079D7DF /* CategoryPickerSection.swift */; };
DB1E347825F519300079D7DF /* PickServerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1E347725F519300079D7DF /* PickServerItem.swift */; };
@@ -235,8 +233,27 @@
DB2B3ABC25E37E15007045F9 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DB2B3ABE25E37E15007045F9 /* InfoPlist.strings */; };
DB2F073525E8ECF000957B2D /* AuthenticationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */; };
DB2FF510260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB2FF50F260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift */; };
+ DB336F1C278D697E0031E64B /* MastodonUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FAE225CA7181005A8AC7 /* MastodonUser.swift */; };
+ DB336F1E278D6C3A0031E64B /* MastodonEmoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F1D278D6C3A0031E64B /* MastodonEmoji.swift */; };
+ DB336F21278D6D960031E64B /* MastodonEmoji.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F20278D6D960031E64B /* MastodonEmoji.swift */; };
+ DB336F23278D6DED0031E64B /* MastodonEmojiContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F22278D6DED0031E64B /* MastodonEmojiContainer.swift */; };
+ DB336F26278D6E8F0031E64B /* MastodonField.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F25278D6E8F0031E64B /* MastodonField.swift */; };
+ DB336F28278D6EC70031E64B /* MastodonFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F27278D6EC70031E64B /* MastodonFieldContainer.swift */; };
+ DB336F2A278D6F2B0031E64B /* MastodonField.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F29278D6F2B0031E64B /* MastodonField.swift */; };
+ DB336F2C278D6FC30031E64B /* Persistence+Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F2B278D6FC30031E64B /* Persistence+Status.swift */; };
+ DB336F2E278D71AF0031E64B /* Status+Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F2D278D71AF0031E64B /* Status+Property.swift */; };
+ DB336F30278D723D0031E64B /* MastodonVisibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F2F278D723D0031E64B /* MastodonVisibility.swift */; };
+ DB336F32278D77330031E64B /* Persistence+Poll.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F31278D77330031E64B /* Persistence+Poll.swift */; };
+ DB336F34278D77730031E64B /* Persistence+PollOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F33278D77730031E64B /* Persistence+PollOption.swift */; };
+ DB336F36278D77A40031E64B /* PollOption+Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F35278D77A40031E64B /* PollOption+Property.swift */; };
+ DB336F38278D7AAF0031E64B /* Poll+Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F37278D7AAF0031E64B /* Poll+Property.swift */; };
+ DB336F3A278D7D1F0031E64B /* ManagedObjectRecord.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F39278D7D1F0031E64B /* ManagedObjectRecord.swift */; };
+ DB336F3D278D80040031E64B /* FeedFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F3C278D80040031E64B /* FeedFetchedResultsController.swift */; };
+ DB336F3F278E668C0031E64B /* StatusTableViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F3E278E668C0031E64B /* StatusTableViewCell+ViewModel.swift */; };
+ DB336F41278E68480031E64B /* StatusView+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F40278E68480031E64B /* StatusView+Configuration.swift */; };
+ DB336F43278EB1690031E64B /* MediaView+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F42278EB1680031E64B /* MediaView+Configuration.swift */; };
+ DB336F45278EB1D70031E64B /* MastodonAttachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB336F44278EB1D70031E64B /* MastodonAttachment.swift */; };
DB35FC1F2612F1D9006193C9 /* ProfileRelationshipActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB35FC1E2612F1D9006193C9 /* ProfileRelationshipActionButton.swift */; };
- DB35FC252612FD7A006193C9 /* ProfileFieldView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB35FC242612FD7A006193C9 /* ProfileFieldView.swift */; };
DB36679D268AB91B0027D07F /* ComposeStatusAttachmentTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB36679C268AB91B0027D07F /* ComposeStatusAttachmentTableViewCell.swift */; };
DB36679F268ABAF20027D07F /* ComposeStatusAttachmentSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB36679E268ABAF20027D07F /* ComposeStatusAttachmentSection.swift */; };
DB3667A1268ABB2E0027D07F /* ComposeStatusAttachmentItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB3667A0268ABB2E0027D07F /* ComposeStatusAttachmentItem.swift */; };
@@ -244,7 +261,6 @@
DB3667A6268AE2620027D07F /* ComposeStatusPollSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB3667A5268AE2620027D07F /* ComposeStatusPollSection.swift */; };
DB3667A8268AE2900027D07F /* ComposeStatusPollItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB3667A7268AE2900027D07F /* ComposeStatusPollItem.swift */; };
DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = DB3D0FF225BAA61700EAA174 /* AlamofireImage */; };
- DB3D100D25BAA75E00EAA174 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DB3D100F25BAA75E00EAA174 /* Localizable.strings */; };
DB427DD625BAA00100D1B89D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DD525BAA00100D1B89D /* AppDelegate.swift */; };
DB427DD825BAA00100D1B89D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DD725BAA00100D1B89D /* SceneDelegate.swift */; };
DB427DDD25BAA00100D1B89D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DB427DDB25BAA00100D1B89D /* Main.storyboard */; };
@@ -261,11 +277,8 @@
DB4481AD25EE155900BEFB67 /* Poll.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4481AC25EE155900BEFB67 /* Poll.swift */; };
DB4481B325EE16D000BEFB67 /* PollOption.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4481B225EE16D000BEFB67 /* PollOption.swift */; };
DB4481B925EE289600BEFB67 /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4481B825EE289600BEFB67 /* UITableView.swift */; };
- DB4481C625EE2ADA00BEFB67 /* PollSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4481C525EE2ADA00BEFB67 /* PollSection.swift */; };
- DB4481CC25EE2AFE00BEFB67 /* PollItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4481CB25EE2AFE00BEFB67 /* PollItem.swift */; };
DB45FAB625CA5485005A8AC7 /* UIAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FAB525CA5485005A8AC7 /* UIAlertController.swift */; };
DB45FAD725CA6C76005A8AC7 /* UIBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FAD625CA6C76005A8AC7 /* UIBarButtonItem.swift */; };
- DB45FADD25CA6F6B005A8AC7 /* APIService+CoreData+MastodonUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FADC25CA6F6B005A8AC7 /* APIService+CoreData+MastodonUser.swift */; };
DB45FAE325CA7181005A8AC7 /* MastodonUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FAE225CA7181005A8AC7 /* MastodonUser.swift */; };
DB45FAED25CA7A9A005A8AC7 /* MastodonAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FAEC25CA7A9A005A8AC7 /* MastodonAuthentication.swift */; };
DB45FAF925CA80A2005A8AC7 /* APIService+CoreData+MastodonAuthentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FAF825CA80A2005A8AC7 /* APIService+CoreData+MastodonAuthentication.swift */; };
@@ -273,11 +286,9 @@
DB45FB1D25CA9D23005A8AC7 /* APIService+HomeTimeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FB1C25CA9D23005A8AC7 /* APIService+HomeTimeline.swift */; };
DB47229725F9EFAD00DA7F53 /* NSManagedObjectContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB47229625F9EFAD00DA7F53 /* NSManagedObjectContext.swift */; };
DB482A3F261331E8008AE74C /* UserTimelineViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB482A3E261331E8008AE74C /* UserTimelineViewModel+State.swift */; };
- DB482A45261335BA008AE74C /* UserTimelineViewController+Provider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB482A44261335BA008AE74C /* UserTimelineViewController+Provider.swift */; };
DB482A4B261340A7008AE74C /* APIService+UserTimeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB482A4A261340A7008AE74C /* APIService+UserTimeline.swift */; };
DB4924E226312AB200E9DB22 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4924E126312AB200E9DB22 /* NotificationService.swift */; };
DB4932B126F1FB5300EF46D4 /* WizardCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4932B026F1FB5300EF46D4 /* WizardCardView.swift */; };
- DB4932B326F2054200EF46D4 /* CircleAvatarButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4932B226F2054200EF46D4 /* CircleAvatarButton.swift */; };
DB4932B726F30F0700EF46D4 /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F20223826146553000C64BF /* Array.swift */; };
DB4932B926F31AD300EF46D4 /* BadgeButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4932B826F31AD300EF46D4 /* BadgeButton.swift */; };
DB49A61425FF2C5600B98345 /* EmojiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB49A61325FF2C5600B98345 /* EmojiService.swift */; };
@@ -289,7 +300,6 @@
DB4F0966269ED52200D62E92 /* SearchResultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0965269ED52200D62E92 /* SearchResultViewModel.swift */; };
DB4F0968269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0967269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift */; };
DB4F096A269EDAD200D62E92 /* SearchResultViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F0969269EDAD200D62E92 /* SearchResultViewModel+State.swift */; };
- DB4F096C269EFA2000D62E92 /* SearchResultViewController+StatusProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F096B269EFA2000D62E92 /* SearchResultViewController+StatusProvider.swift */; };
DB4F097526A037F500D62E92 /* SearchHistoryViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F097426A037F500D62E92 /* SearchHistoryViewModel.swift */; };
DB4F097B26A039FF00D62E92 /* SearchHistorySection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F097A26A039FF00D62E92 /* SearchHistorySection.swift */; };
DB4F097D26A03A5B00D62E92 /* SearchHistoryItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F097C26A03A5B00D62E92 /* SearchHistoryItem.swift */; };
@@ -299,17 +309,14 @@
DB51D172262832380062B7A1 /* BlurHashDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB51D170262832380062B7A1 /* BlurHashDecode.swift */; };
DB51D173262832380062B7A1 /* BlurHashEncode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB51D171262832380062B7A1 /* BlurHashEncode.swift */; };
DB552D4F26BBD10C00E481F6 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = DB552D4E26BBD10C00E481F6 /* OrderedCollections */; };
- DB564BD0269F2F83001E39A7 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DB564BCE269F2F83001E39A7 /* Localizable.stringsdict */; };
DB564BD3269F3B35001E39A7 /* StatusFilterService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB564BD2269F3B35001E39A7 /* StatusFilterService.swift */; };
- DB59F0FE25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB59F0FD25EF5D96001F1DAB /* StatusProvider+UITableViewDelegate.swift */; };
- DB59F10425EF5EBC001F1DAB /* TableViewCellHeightCacheableContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB59F10325EF5EBC001F1DAB /* TableViewCellHeightCacheableContainer.swift */; };
DB59F10E25EF724F001F1DAB /* APIService+Poll.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB59F10D25EF724F001F1DAB /* APIService+Poll.swift */; };
- DB59F11825EFA35B001F1DAB /* StripProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB59F11725EFA35B001F1DAB /* StripProgressView.swift */; };
DB5B7295273112B100081888 /* FollowingListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B7294273112B100081888 /* FollowingListViewController.swift */; };
DB5B7298273112C800081888 /* FollowingListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B7297273112C800081888 /* FollowingListViewModel.swift */; };
- DB5B729A2731137900081888 /* FollowingListViewController+Provider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B72992731137900081888 /* FollowingListViewController+Provider.swift */; };
DB5B729C273113C200081888 /* FollowingListViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B729B273113C200081888 /* FollowingListViewModel+Diffable.swift */; };
DB5B729E273113F300081888 /* FollowingListViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B729D273113F300081888 /* FollowingListViewModel+State.swift */; };
+ DB603111279EB38500A935FE /* DataSourceFacade+Mute.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB603110279EB38500A935FE /* DataSourceFacade+Mute.swift */; };
+ DB603113279EBEBA00A935FE /* DataSourceFacade+Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB603112279EBEBA00A935FE /* DataSourceFacade+Block.swift */; };
DB6180DD263918E30018D199 /* MediaPreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6180DC263918E30018D199 /* MediaPreviewViewController.swift */; };
DB6180E02639194B0018D199 /* MediaPreviewPagingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6180DF2639194B0018D199 /* MediaPreviewPagingViewController.swift */; };
DB6180E326391A4C0018D199 /* ViewControllerAnimatedTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6180E226391A4C0018D199 /* ViewControllerAnimatedTransitioning.swift */; };
@@ -323,11 +330,43 @@
DB6180F626391D580018D199 /* MediaPreviewableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6180F526391D580018D199 /* MediaPreviewableViewController.swift */; };
DB6180F826391D660018D199 /* MediaPreviewingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6180F726391D660018D199 /* MediaPreviewingViewController.swift */; };
DB6180FA26391F2E0018D199 /* MediaPreviewViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6180F926391F2E0018D199 /* MediaPreviewViewModel.swift */; };
- DB63BE7F268DD1070011D3F9 /* NotificationViewController+StatusProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63BE7E268DD1070011D3F9 /* NotificationViewController+StatusProvider.swift */; };
+ DB63F7452799056400455B82 /* HashtagTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F7442799056400455B82 /* HashtagTableViewCell.swift */; };
+ DB63F74727990B0600455B82 /* DataSourceFacade+Hashtag.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F74627990B0600455B82 /* DataSourceFacade+Hashtag.swift */; };
+ DB63F7492799126300455B82 /* FollowerListViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F7482799126300455B82 /* FollowerListViewController+DataSourceProvider.swift */; };
+ DB63F74B279914A000455B82 /* FollowingListViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F74A279914A000455B82 /* FollowingListViewController+DataSourceProvider.swift */; };
+ DB63F74D27993F5B00455B82 /* SearchHistoryUserCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F74C27993F5B00455B82 /* SearchHistoryUserCollectionViewCell.swift */; };
+ DB63F74F2799405600455B82 /* SearchHistoryViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F74E2799405600455B82 /* SearchHistoryViewModel+Diffable.swift */; };
+ DB63F752279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F751279944AA00455B82 /* SearchHistorySectionHeaderCollectionReusableView.swift */; };
+ DB63F7542799491600455B82 /* DataSourceFacade+SearchHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F7532799491600455B82 /* DataSourceFacade+SearchHistory.swift */; };
+ DB63F756279949BD00455B82 /* Persistence+SearchHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F755279949BD00455B82 /* Persistence+SearchHistory.swift */; };
+ DB63F75A279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F759279953F200455B82 /* SearchHistoryUserCollectionViewCell+ViewModel.swift */; };
+ DB63F75C279956D000455B82 /* Persistence+Tag.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F75B279956D000455B82 /* Persistence+Tag.swift */; };
+ DB63F75E27995B3B00455B82 /* Tag+Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F75D27995B3B00455B82 /* Tag+Property.swift */; };
+ DB63F76027995ECE00455B82 /* MastodonTagHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F75F27995ECE00455B82 /* MastodonTagHistory.swift */; };
+ DB63F76227996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F76127996B6600455B82 /* SearchHistoryViewController+DataSourceProvider.swift */; };
+ DB63F764279A5E3C00455B82 /* NotificationTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F763279A5E3C00455B82 /* NotificationTimelineViewController.swift */; };
+ DB63F767279A5EB300455B82 /* NotificationTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F766279A5EB300455B82 /* NotificationTimelineViewModel.swift */; };
+ DB63F769279A5EBB00455B82 /* NotificationTimelineViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F768279A5EBB00455B82 /* NotificationTimelineViewModel+Diffable.swift */; };
+ DB63F76B279A5ED300455B82 /* NotificationTimelineViewModel+LoadOldestState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F76A279A5ED300455B82 /* NotificationTimelineViewModel+LoadOldestState.swift */; };
+ DB63F76D279A67BD00455B82 /* MastodonNotificationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F76C279A67BD00455B82 /* MastodonNotificationType.swift */; };
+ DB63F76F279A7D1100455B82 /* NotificationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F76E279A7D1100455B82 /* NotificationTableViewCell.swift */; };
+ DB63F771279A858500455B82 /* Persistence+Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F770279A858500455B82 /* Persistence+Notification.swift */; };
+ DB63F773279A87DC00455B82 /* Notification+Property.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F772279A87DC00455B82 /* Notification+Property.swift */; };
+ DB63F775279A997D00455B82 /* NotificationTableViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F774279A997D00455B82 /* NotificationTableViewCell+ViewModel.swift */; };
+ DB63F777279A9A2A00455B82 /* NotificationView+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F776279A9A2A00455B82 /* NotificationView+Configuration.swift */; };
+ DB63F779279ABF9C00455B82 /* DataSourceFacade+Reblog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F778279ABF9C00455B82 /* DataSourceFacade+Reblog.swift */; };
+ DB63F77B279ACAE500455B82 /* DataSourceFacade+Favorite.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F77A279ACAE500455B82 /* DataSourceFacade+Favorite.swift */; };
DB647C5926F1EA2700F7F82C /* WizardPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB647C5826F1EA2700F7F82C /* WizardPreference.swift */; };
+ DB65C63727A2AF6C008BAC2E /* ReportItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB65C63627A2AF6C008BAC2E /* ReportItem.swift */; };
DB66728C25F9F8DC00D60309 /* ComposeViewModel+DataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB66728B25F9F8DC00D60309 /* ComposeViewModel+DataSource.swift */; };
DB66729625F9F91600D60309 /* ComposeStatusSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB66729525F9F91600D60309 /* ComposeStatusSection.swift */; };
DB66729C25F9F91F00D60309 /* ComposeStatusItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB66729B25F9F91F00D60309 /* ComposeStatusItem.swift */; };
+ DB6746E7278ED633008A6B94 /* MastodonAuthenticationBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC50C0278ED49200AF0CC6 /* MastodonAuthenticationBox.swift */; };
+ DB6746E8278ED639008A6B94 /* MastodonAuthenticationBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC50C0278ED49200AF0CC6 /* MastodonAuthenticationBox.swift */; };
+ DB6746E9278ED63F008A6B94 /* MastodonAuthenticationBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC50C0278ED49200AF0CC6 /* MastodonAuthenticationBox.swift */; };
+ DB6746EB278ED8B0008A6B94 /* PollOptionView+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6746EA278ED8B0008A6B94 /* PollOptionView+Configuration.swift */; };
+ DB6746ED278F45F0008A6B94 /* AutoGenerateProtocolRelayDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6746EC278F45F0008A6B94 /* AutoGenerateProtocolRelayDelegate.swift */; };
+ DB6746F0278F463B008A6B94 /* AutoGenerateProtocolDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6746EF278F463B008A6B94 /* AutoGenerateProtocolDelegate.swift */; };
DB67D08427312970006A36CF /* APIService+Following.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB67D08327312970006A36CF /* APIService+Following.swift */; };
DB67D08627312E67006A36CF /* WizardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB67D08527312E67006A36CF /* WizardViewController.swift */; };
DB67D089273256D7006A36CF /* StoreReviewPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB67D088273256D7006A36CF /* StoreReviewPreference.swift */; };
@@ -347,18 +386,24 @@
DB68A04A25E9027700CFDF14 /* AdaptiveStatusBarStyleNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB68A04925E9027700CFDF14 /* AdaptiveStatusBarStyleNavigationController.swift */; };
DB68A05D25E9055900CFDF14 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = DB68A05C25E9055900CFDF14 /* Settings.bundle */; };
DB68A06325E905E000CFDF14 /* UIApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB68A06225E905E000CFDF14 /* UIApplication.swift */; };
+ DB697DD1278F4871004EF2F7 /* AutoGenerateTableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB697DD0278F4871004EF2F7 /* AutoGenerateTableViewDelegate.swift */; };
+ DB697DD4278F4927004EF2F7 /* StatusTableViewCellDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB697DD3278F4927004EF2F7 /* StatusTableViewCellDelegate.swift */; };
+ DB697DD6278F4C29004EF2F7 /* DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB697DD5278F4C29004EF2F7 /* DataSourceProvider.swift */; };
+ DB697DD9278F4CED004EF2F7 /* HomeTimelineViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB697DD8278F4CED004EF2F7 /* HomeTimelineViewController+DataSourceProvider.swift */; };
+ DB697DDB278F4DE3004EF2F7 /* DataSourceProvider+StatusTableViewCellDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB697DDA278F4DE3004EF2F7 /* DataSourceProvider+StatusTableViewCellDelegate.swift */; };
+ DB697DDD278F521D004EF2F7 /* DataSourceFacade.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB697DDC278F521D004EF2F7 /* DataSourceFacade.swift */; };
+ DB697DDF278F524F004EF2F7 /* DataSourceFacade+Profile.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB697DDE278F524F004EF2F7 /* DataSourceFacade+Profile.swift */; };
+ DB697DE1278F5296004EF2F7 /* DataSourceFacade+Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB697DE0278F5296004EF2F7 /* DataSourceFacade+Model.swift */; };
DB6B35182601FA3400DC1E11 /* MastodonAttachmentService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B35172601FA3400DC1E11 /* MastodonAttachmentService.swift */; };
DB6B351E2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B351D2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift */; };
DB6B74EF272FB55000C70B6E /* FollowerListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B74EE272FB55000C70B6E /* FollowerListViewController.swift */; };
DB6B74F2272FB67600C70B6E /* FollowerListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B74F1272FB67600C70B6E /* FollowerListViewModel.swift */; };
DB6B74F4272FBAE700C70B6E /* FollowerListViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B74F3272FBAE700C70B6E /* FollowerListViewModel+Diffable.swift */; };
DB6B74F6272FBCDB00C70B6E /* FollowerListViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B74F5272FBCDB00C70B6E /* FollowerListViewModel+State.swift */; };
- DB6B74F8272FBFB100C70B6E /* FollowerListViewController+Provider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B74F7272FBFB100C70B6E /* FollowerListViewController+Provider.swift */; };
DB6B74FA272FC2B500C70B6E /* APIService+Follower.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B74F9272FC2B500C70B6E /* APIService+Follower.swift */; };
DB6B74FC272FF55800C70B6E /* UserSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B74FB272FF55800C70B6E /* UserSection.swift */; };
DB6B74FE272FF59000C70B6E /* UserItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B74FD272FF59000C70B6E /* UserItem.swift */; };
DB6B7500272FF73800C70B6E /* UserTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B74FF272FF73800C70B6E /* UserTableViewCell.swift */; };
- DB6B75022730060700C70B6E /* UserProviderFacade+UITableViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B75012730060700C70B6E /* UserProviderFacade+UITableViewDelegate.swift */; };
DB6B750427300B4000C70B6E /* TimelineFooterTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6B750327300B4000C70B6E /* TimelineFooterTableViewCell.swift */; };
DB6C8C0F25F0A6AE00AAA452 /* Mastodon+Entity+Error.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6C8C0E25F0A6AE00AAA452 /* Mastodon+Entity+Error.swift */; };
DB6D1B3D2636857500ACB481 /* AppearancePreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6D1B3C2636857500ACB481 /* AppearancePreference.swift */; };
@@ -378,11 +423,6 @@
DB6F5E38264E994A009108F4 /* AutoCompleteTopChevronView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6F5E37264E994A009108F4 /* AutoCompleteTopChevronView.swift */; };
DB71C7CB271D5A0300BE3819 /* LineChartView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71C7CA271D5A0300BE3819 /* LineChartView.swift */; };
DB71C7CD271D7F4300BE3819 /* CurveAlgorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71C7CC271D7F4300BE3819 /* CurveAlgorithm.swift */; };
- DB71FD2C25F86A5100512AE1 /* AvatarStackContainerButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71FD2B25F86A5100512AE1 /* AvatarStackContainerButton.swift */; };
- DB71FD3625F8A16C00512AE1 /* APIService+Persist+PersistMemo.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71FD3525F8A16C00512AE1 /* APIService+Persist+PersistMemo.swift */; };
- DB71FD3C25F8A1C500512AE1 /* APIService+Persist+PersistCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71FD3B25F8A1C500512AE1 /* APIService+Persist+PersistCache.swift */; };
- DB71FD4625F8C6D200512AE1 /* StatusProvider+UITableViewDataSourcePrefetching.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71FD4525F8C6D200512AE1 /* StatusProvider+UITableViewDataSourcePrefetching.swift */; };
- DB71FD4C25F8C80E00512AE1 /* StatusPrefetchingService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71FD4B25F8C80E00512AE1 /* StatusPrefetchingService.swift */; };
DB71FD5225F8CCAA00512AE1 /* APIService+Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB71FD5125F8CCAA00512AE1 /* APIService+Status.swift */; };
DB72601C25E36A2100235243 /* MastodonServerRulesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB72601B25E36A2100235243 /* MastodonServerRulesViewController.swift */; };
DB72602725E36A6F00235243 /* MastodonServerRulesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB72602625E36A6F00235243 /* MastodonServerRulesViewModel.swift */; };
@@ -406,9 +446,7 @@
DB852D1C26FB021500FC9D81 /* RootSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB852D1B26FB021500FC9D81 /* RootSplitViewController.swift */; };
DB852D1F26FB037800FC9D81 /* SidebarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB852D1E26FB037800FC9D81 /* SidebarViewModel.swift */; };
DB87D4452609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB87D4442609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift */; };
- DB87D44B2609C11900D12C0D /* PollOptionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB87D44A2609C11900D12C0D /* PollOptionView.swift */; };
DB87D4512609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB87D4502609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift */; };
- DB87D4572609DD5300D12C0D /* DeleteBackwardResponseTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB87D4562609DD5300D12C0D /* DeleteBackwardResponseTextField.swift */; };
DB89B9F725C10FD0008580ED /* CoreDataStack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB89B9EE25C10FD0008580ED /* CoreDataStack.framework */; };
DB89B9FE25C10FD0008580ED /* CoreDataStackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB89B9FD25C10FD0008580ED /* CoreDataStackTests.swift */; };
DB89BA0025C10FD0008580ED /* CoreDataStack.h in Headers */ = {isa = PBXBuildFile; fileRef = DB89B9F025C10FD0008580ED /* CoreDataStack.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -431,13 +469,13 @@
DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF54F25C13703002E6C99 /* MainTabBarController.swift */; };
DB8AF55D25C138B7002E6C99 /* UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF55C25C138B7002E6C99 /* UIViewController.swift */; };
DB8AF56825C13E2A002E6C99 /* HomeTimelineIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF56725C13E2A002E6C99 /* HomeTimelineIndex.swift */; };
+ DB8F7076279E954700E1225B /* DataSourceFacade+Follow.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8F7075279E954700E1225B /* DataSourceFacade+Follow.swift */; };
DB8FABC726AEC7B2008E5AF4 /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB8FAB9E26AEC3A2008E5AF4 /* Intents.framework */; };
DB8FABCA26AEC7B2008E5AF4 /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8FABC926AEC7B2008E5AF4 /* IntentHandler.swift */; };
DB8FABCE26AEC7B2008E5AF4 /* MastodonIntent.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = DB8FABC626AEC7B2008E5AF4 /* MastodonIntent.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
DB8FABD726AEC873008E5AF4 /* AppShared.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB68047F2637CD4C00430867 /* AppShared.framework */; };
DB8FABDC26AEC87B008E5AF4 /* CoreDataStack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB89B9EE25C10FD0008580ED /* CoreDataStack.framework */; };
DB9282B225F3222800823B15 /* PickServerEmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9282B125F3222800823B15 /* PickServerEmptyStateView.swift */; };
- DB92CF7225E7BB98002C1017 /* PollOptionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB92CF7125E7BB98002C1017 /* PollOptionTableViewCell.swift */; };
DB938EE62623F50700E5B6C1 /* ThreadViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB938EE52623F50700E5B6C1 /* ThreadViewController.swift */; };
DB938EED2623F79B00E5B6C1 /* ThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB938EEC2623F79B00E5B6C1 /* ThreadViewModel.swift */; };
DB938F0326240EA300E5B6C1 /* CachedThreadViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB938F0226240EA300E5B6C1 /* CachedThreadViewModel.swift */; };
@@ -445,14 +483,10 @@
DB938F0F2624119800E5B6C1 /* ThreadViewModel+LoadThreadState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB938F0E2624119800E5B6C1 /* ThreadViewModel+LoadThreadState.swift */; };
DB938F1526241FDF00E5B6C1 /* APIService+Thread.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB938F1426241FDF00E5B6C1 /* APIService+Thread.swift */; };
DB938F1F2624382F00E5B6C1 /* ThreadViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB938F1E2624382F00E5B6C1 /* ThreadViewModel+Diffable.swift */; };
- DB938F25262438D600E5B6C1 /* ThreadViewController+Provider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB938F24262438D600E5B6C1 /* ThreadViewController+Provider.swift */; };
DB938F3326243D6200E5B6C1 /* TimelineTopLoaderTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB938F3226243D6200E5B6C1 /* TimelineTopLoaderTableViewCell.swift */; };
- DB97131F2666078B00BD1E90 /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB97131E2666078B00BD1E90 /* Date.swift */; };
DB98336B25C9420100AD9700 /* APIService+App.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98336A25C9420100AD9700 /* APIService+App.swift */; };
DB98337125C9443200AD9700 /* APIService+Authentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98337025C9443200AD9700 /* APIService+Authentication.swift */; };
DB98337F25C9452D00AD9700 /* APIService+APIError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98337E25C9452D00AD9700 /* APIService+APIError.swift */; };
- DB98338725C945ED00AD9700 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98338525C945ED00AD9700 /* Strings.swift */; };
- DB98338825C945ED00AD9700 /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98338625C945ED00AD9700 /* Assets.swift */; };
DB98339C25C96DE600AD9700 /* APIService+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98339B25C96DE600AD9700 /* APIService+Account.swift */; };
DB9A486C26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A486B26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift */; };
DB9A487E2603456B008B817C /* UITextView+Placeholder in Frameworks */ = {isa = PBXBuildFile; productRef = DB9A487D2603456B008B817C /* UITextView+Placeholder */; };
@@ -464,8 +498,6 @@
DB9D6BFF25E4F5940051B173 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6BFE25E4F5940051B173 /* ProfileViewController.swift */; };
DB9D6C0E25E4F9780051B173 /* MosaicImageViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C0D25E4F9780051B173 /* MosaicImageViewContainer.swift */; };
DB9D6C2425E502C60051B173 /* MosaicImageViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C2225E502C60051B173 /* MosaicImageViewModel.swift */; };
- DB9D6C2E25E504AC0051B173 /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C2D25E504AC0051B173 /* Attachment.swift */; };
- DB9D6C3825E508BE0051B173 /* Attachment.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6C3725E508BE0051B173 /* Attachment.swift */; };
DB9D7C21269824B80054B3DF /* APIService+Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D7C20269824B80054B3DF /* APIService+Filter.swift */; };
DB9E0D6F25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */; };
DB9F58EC26EF435000E7BBE9 /* AccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58EB26EF435000E7BBE9 /* AccountViewController.swift */; };
@@ -473,7 +505,6 @@
DB9F58F126EF512300E7BBE9 /* AccountListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9F58F026EF512300E7BBE9 /* AccountListTableViewCell.swift */; };
DBA088DF26958164003EB4B2 /* UserFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA088DE26958164003EB4B2 /* UserFetchedResultsController.swift */; };
DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */; };
- DBA1DB80268F84F80052DB59 /* NotificationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA1DB7F268F84F80052DB59 /* NotificationType.swift */; };
DBA465932696B495002B41DB /* APIService+WebFinger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA465922696B495002B41DB /* APIService+WebFinger.swift */; };
DBA465952696E387002B41DB /* AppPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA465942696E387002B41DB /* AppPreference.swift */; };
DBA4B0F626C269880077136E /* Intents.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DBA4B0F926C269880077136E /* Intents.stringsdict */; };
@@ -487,23 +518,17 @@
DBA5E7AB263BD3F5004598BB /* TimelineTableViewCellContextMenuConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA5E7AA263BD3F5004598BB /* TimelineTableViewCellContextMenuConfiguration.swift */; };
DBA94434265CBB5300C537E1 /* ProfileFieldSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA94433265CBB5300C537E1 /* ProfileFieldSection.swift */; };
DBA94436265CBB7400C537E1 /* ProfileFieldItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA94435265CBB7400C537E1 /* ProfileFieldItem.swift */; };
- DBA94438265CBD4D00C537E1 /* ProfileHeaderViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA94437265CBD4D00C537E1 /* ProfileHeaderViewModel+Diffable.swift */; };
- DBA9443A265CC0FC00C537E1 /* Fields.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA94439265CC0FC00C537E1 /* Fields.swift */; };
DBA9443E265CFA6400C537E1 /* ProfileFieldCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA9443D265CFA6400C537E1 /* ProfileFieldCollectionViewCell.swift */; };
DBA94440265D137600C537E1 /* Mastodon+Entity+Field.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA9443F265D137600C537E1 /* Mastodon+Entity+Field.swift */; };
DBABE3EC25ECAC4B00879EE5 /* WelcomeIllustrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBABE3EB25ECAC4B00879EE5 /* WelcomeIllustrationView.swift */; };
DBAC6483267D0B21007FE9FD /* DifferenceKit in Frameworks */ = {isa = PBXBuildFile; productRef = DBAC6482267D0B21007FE9FD /* DifferenceKit */; };
DBAC649E267DFE43007FE9FD /* DiffableDataSources in Frameworks */ = {isa = PBXBuildFile; productRef = DBAC649D267DFE43007FE9FD /* DiffableDataSources */; };
DBAC64A1267E6D02007FE9FD /* Fuzi in Frameworks */ = {isa = PBXBuildFile; productRef = DBAC64A0267E6D02007FE9FD /* Fuzi */; };
- DBAE3F682615DD60004B8251 /* UserProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBAE3F672615DD60004B8251 /* UserProvider.swift */; };
- DBAE3F822615DDA3004B8251 /* ProfileViewController+UserProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBAE3F812615DDA3004B8251 /* ProfileViewController+UserProvider.swift */; };
- DBAE3F882615DDF4004B8251 /* UserProviderFacade.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBAE3F872615DDF4004B8251 /* UserProviderFacade.swift */; };
DBAE3F8E2616E0B1004B8251 /* APIService+Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBAE3F8D2616E0B1004B8251 /* APIService+Block.swift */; };
DBAE3F942616E28B004B8251 /* APIService+Follow.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBAE3F932616E28B004B8251 /* APIService+Follow.swift */; };
DBAE3F9E2616E308004B8251 /* APIService+Mute.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBAE3F9D2616E308004B8251 /* APIService+Mute.swift */; };
DBAE3FAF26172FC0004B8251 /* RemoteProfileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBAE3FAE26172FC0004B8251 /* RemoteProfileViewModel.swift */; };
DBAEDE5C267A058D00D25FF5 /* BlurhashImageCacheService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBAEDE5B267A058D00D25FF5 /* BlurhashImageCacheService.swift */; };
- DBAFB7352645463500371D5F /* Emojis.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBAFB7342645463500371D5F /* Emojis.swift */; };
DBB3BA2A26A81C020004F2D4 /* FLAnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB3BA2926A81C020004F2D4 /* FLAnimatedImageView.swift */; };
DBB3BA2B26A81D060004F2D4 /* FLAnimatedImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB3BA2926A81C020004F2D4 /* FLAnimatedImageView.swift */; };
DBB525082611EAC0002F1F29 /* Tabman in Frameworks */ = {isa = PBXBuildFile; productRef = DBB525072611EAC0002F1F29 /* Tabman */; };
@@ -522,19 +547,12 @@
DBB8AB4826AED09C00F6D281 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DBB8AB4726AED09C00F6D281 /* MastodonSDK */; };
DBB8AB4A26AED0B500F6D281 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB8AB4926AED0B500F6D281 /* APIService.swift */; };
DBB8AB4C26AED11300F6D281 /* APIService+APIError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98337E25C9452D00AD9700 /* APIService+APIError.swift */; };
- DBB8AB4D26AED12B00F6D281 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98338525C945ED00AD9700 /* Strings.swift */; };
- DBB8AB4E26AED12E00F6D281 /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98338625C945ED00AD9700 /* Assets.swift */; };
DBB8AB4F26AED13F00F6D281 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB427DDE25BAA00100D1B89D /* Assets.xcassets */; };
- DBB8AB5026AED14400F6D281 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DB564BCE269F2F83001E39A7 /* Localizable.stringsdict */; };
- DBB8AB5126AED14600F6D281 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DB3D100F25BAA75E00EAA174 /* Localizable.strings */; };
DBB8AB5226AED1B300F6D281 /* APIService+Status+Publish.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF07A26A6BCE8006D7ED1 /* APIService+Status+Publish.swift */; };
- DBB8AB5326AED25100F6D281 /* MastodonAuthenticationBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF07626A691FB006D7ED1 /* MastodonAuthenticationBox.swift */; };
DBB9759C262462E1004620BD /* ThreadMetaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB9759B262462E1004620BD /* ThreadMetaView.swift */; };
DBBC24A826A52F9000398BB9 /* ComposeToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24A726A52F9000398BB9 /* ComposeToolbarView.swift */; };
DBBC24AA26A5301B00398BB9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DBBC24A926A5301B00398BB9 /* MastodonSDK */; };
DBBC24AC26A53D9300398BB9 /* ComposeStatusContentTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24AB26A53D9300398BB9 /* ComposeStatusContentTableViewCell.swift */; };
- DBBC24AE26A53DC100398BB9 /* ReplicaStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24AD26A53DC100398BB9 /* ReplicaStatusView.swift */; };
- DBBC24B526A540AE00398BB9 /* AvatarConfigurableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24B426A540AE00398BB9 /* AvatarConfigurableView.swift */; };
DBBC24B826A5421800398BB9 /* CommonOSLog in Frameworks */ = {isa = PBXBuildFile; productRef = DBBC24B726A5421800398BB9 /* CommonOSLog */; };
DBBC24BC26A542F500398BB9 /* ThemeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24BB26A542F500398BB9 /* ThemeService.swift */; };
DBBC24C026A5443100398BB9 /* MastodonTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24BE26A5443100398BB9 /* MastodonTheme.swift */; };
@@ -545,12 +563,11 @@
DBBC24C826A5456400398BB9 /* ThemeService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24BB26A542F500398BB9 /* ThemeService.swift */; };
DBBC24C926A5456400398BB9 /* MastodonTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24BE26A5443100398BB9 /* MastodonTheme.swift */; };
DBBC24CB26A546C000398BB9 /* ThemePreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBD376AB2692ECDB007FEC24 /* ThemePreference.swift */; };
- DBBC24CD26A5471E00398BB9 /* MastodonExtension in Frameworks */ = {isa = PBXBuildFile; productRef = DBBC24CC26A5471E00398BB9 /* MastodonExtension */; };
DBBC24CF26A547AE00398BB9 /* ThemeService+Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24CE26A547AE00398BB9 /* ThemeService+Appearance.swift */; };
DBBC24D126A5484F00398BB9 /* UITextView+Placeholder in Frameworks */ = {isa = PBXBuildFile; productRef = DBBC24D026A5484F00398BB9 /* UITextView+Placeholder */; };
- DBBC24D226A5488600398BB9 /* AvatarConfigurableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24B426A540AE00398BB9 /* AvatarConfigurableView.swift */; };
DBBC24DC26A54BCB00398BB9 /* MastodonRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24D626A54BCB00398BB9 /* MastodonRegex.swift */; };
DBBC24DE26A54BCB00398BB9 /* MastodonMetricFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24D826A54BCB00398BB9 /* MastodonMetricFormatter.swift */; };
+ DBBC50BF278ED0E700AF0CC6 /* Date.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC50BE278ED0E700AF0CC6 /* Date.swift */; };
DBBE1B4525F3474B0081417A /* MastodonPickServerAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBE1B4425F3474B0081417A /* MastodonPickServerAppearance.swift */; };
DBBF1DBF2652401B00E5B703 /* AutoCompleteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBF1DBE2652401B00E5B703 /* AutoCompleteViewModel.swift */; };
DBBF1DC226524D2900E5B703 /* AutoCompleteTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBF1DC126524D2900E5B703 /* AutoCompleteTableViewCell.swift */; };
@@ -562,13 +579,7 @@
DBC6461826A170AB00B0E31B /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DBC6461626A170AB00B0E31B /* MainInterface.storyboard */; };
DBC6461C26A170AB00B0E31B /* ShareActionExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
DBC6462326A1712000B0E31B /* ShareViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC6462226A1712000B0E31B /* ShareViewModel.swift */; };
- DBC6462526A1720B00B0E31B /* MastodonUI in Frameworks */ = {isa = PBXBuildFile; productRef = DBC6462426A1720B00B0E31B /* MastodonUI */; };
- DBC6462626A1736000B0E31B /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DB564BCE269F2F83001E39A7 /* Localizable.stringsdict */; };
- DBC6462726A1736000B0E31B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DB3D100F25BAA75E00EAA174 /* Localizable.strings */; };
DBC6462826A1736300B0E31B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB427DDE25BAA00100D1B89D /* Assets.xcassets */; };
- DBC6462926A1736700B0E31B /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98338525C945ED00AD9700 /* Strings.swift */; };
- DBC6462B26A1738900B0E31B /* MastodonUI in Frameworks */ = {isa = PBXBuildFile; productRef = DBC6462A26A1738900B0E31B /* MastodonUI */; };
- DBC6462C26A176B000B0E31B /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98338625C945ED00AD9700 /* Assets.swift */; };
DBC6463326A195DB00B0E31B /* AppShared.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB68047F2637CD4C00430867 /* AppShared.framework */; };
DBC6463726A195DB00B0E31B /* CoreDataStack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB89B9EE25C10FD0008580ED /* CoreDataStack.framework */; };
DBC7A672260C897100E57475 /* StatusContentWarningEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC7A671260C897100E57475 /* StatusContentWarningEditorView.swift */; };
@@ -594,7 +605,6 @@
DBE3CDFB261C6CA500430CC6 /* FavoriteViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CDFA261C6CA500430CC6 /* FavoriteViewModel.swift */; };
DBE3CE01261D623D00430CC6 /* FavoriteViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CE00261D623D00430CC6 /* FavoriteViewModel+State.swift */; };
DBE3CE07261D6A0E00430CC6 /* FavoriteViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CE06261D6A0E00430CC6 /* FavoriteViewModel+Diffable.swift */; };
- DBE3CE0D261D767100430CC6 /* FavoriteViewController+Provider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CE0C261D767100430CC6 /* FavoriteViewController+Provider.swift */; };
DBE3CE13261D7D4200430CC6 /* StatusTableViewControllerAspect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CE12261D7D4200430CC6 /* StatusTableViewControllerAspect.swift */; };
DBE54AC62636C89F004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; };
DBE54ACC2636C8FD004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; };
@@ -613,6 +623,10 @@
DBF96326262EC0A6001D8D25 /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DBF96325262EC0A6001D8D25 /* AuthenticationServices.framework */; };
DBF9814A265E24F500E4BA07 /* ProfileFieldCollectionViewHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF98149265E24F500E4BA07 /* ProfileFieldCollectionViewHeaderFooterView.swift */; };
DBF9814C265E339500E4BA07 /* ProfileFieldAddEntryCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF9814B265E339500E4BA07 /* ProfileFieldAddEntryCollectionViewCell.swift */; };
+ DBFEEC96279BDC67004F81DD /* ProfileAboutViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEEC95279BDC67004F81DD /* ProfileAboutViewController.swift */; };
+ 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 */; };
DBFEF05B26A57715006D7ED1 /* ComposeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF05726A576EE006D7ED1 /* ComposeViewModel.swift */; };
DBFEF05C26A57715006D7ED1 /* StatusEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF05526A576EE006D7ED1 /* StatusEditorView.swift */; };
DBFEF05D26A57715006D7ED1 /* ContentWarningEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF05826A576EE006D7ED1 /* ContentWarningEditorView.swift */; };
@@ -625,8 +639,6 @@
DBFEF06F26A690C4006D7ED1 /* APIService+APIError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98337E25C9452D00AD9700 /* APIService+APIError.swift */; };
DBFEF07326A6913D006D7ED1 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF07226A6913D006D7ED1 /* APIService.swift */; };
DBFEF07526A69192006D7ED1 /* APIService+Media.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A488F26035963008B817C /* APIService+Media.swift */; };
- DBFEF07726A691FB006D7ED1 /* MastodonAuthenticationBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF07626A691FB006D7ED1 /* MastodonAuthenticationBox.swift */; };
- DBFEF07826A69209006D7ED1 /* MastodonAuthenticationBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF07626A691FB006D7ED1 /* MastodonAuthenticationBox.swift */; };
DBFEF07B26A6BCE8006D7ED1 /* APIService+Status+Publish.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF07A26A6BCE8006D7ED1 /* APIService+Status+Publish.swift */; };
DBFEF07C26A6BD0A006D7ED1 /* APIService+Status+Publish.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF07A26A6BCE8006D7ED1 /* APIService+Status+Publish.swift */; };
EE93E8E8F9E0C39EAAEBD92F /* Pods_AppShared.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4A2A2D7000E477CA459ADA9 /* Pods_AppShared.framework */; };
@@ -780,11 +792,8 @@
0F2021FA2613262F000C64BF /* HashtagTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineViewController.swift; sourceTree = ""; };
0F202200261326E6000C64BF /* HashtagTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineViewModel.swift; sourceTree = ""; };
0F20220626134DA4000C64BF /* HashtagTimelineViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HashtagTimelineViewModel+Diffable.swift"; sourceTree = ""; };
- 0F20220C26134E3F000C64BF /* HashtagTimelineViewModel+LoadLatestState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HashtagTimelineViewModel+LoadLatestState.swift"; sourceTree = ""; };
0F202212261351F5000C64BF /* APIService+HashtagTimeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+HashtagTimeline.swift"; sourceTree = ""; };
- 0F202226261411BA000C64BF /* HashtagTimelineViewController+Provider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HashtagTimelineViewController+Provider.swift"; sourceTree = ""; };
0F20222C261457EE000C64BF /* HashtagTimelineViewModel+LoadOldestState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HashtagTimelineViewModel+LoadOldestState.swift"; sourceTree = ""; };
- 0F20223226145E51000C64BF /* HashtagTimelineViewModel+LoadMiddleState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HashtagTimelineViewModel+LoadMiddleState.swift"; sourceTree = ""; };
0F20223826146553000C64BF /* Array.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Array.swift; sourceTree = ""; };
0FAA0FDE25E0B57E0017CCDE /* WelcomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeViewController.swift; sourceTree = ""; };
0FAA101125E105390017CCDE /* PrimaryActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryActionButton.swift; sourceTree = ""; };
@@ -792,19 +801,14 @@
0FAA102625E1126A0017CCDE /* MastodonPickServerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonPickServerViewController.swift; sourceTree = ""; };
0FB3D2F625E4C24D00AAD544 /* MastodonPickServerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonPickServerViewModel.swift; sourceTree = ""; };
0FB3D2FD25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingHeadlineTableViewCell.swift; sourceTree = ""; };
- 0FB3D30725E524C600AAD544 /* PickServerCategoriesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoriesCell.swift; sourceTree = ""; };
0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoryView.swift; sourceTree = ""; };
0FB3D31D25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoryCollectionViewCell.swift; sourceTree = ""; };
- 0FB3D33125E5F50E00AAD544 /* PickServerSearchCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerSearchCell.swift; sourceTree = ""; };
0FB3D33725E6401400AAD544 /* PickServerCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCell.swift; sourceTree = ""; };
159AC43EFE0A1F95FCB358A4 /* Pods-MastodonIntent.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.release.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.release.xcconfig"; sourceTree = ""; };
164F0EBB267D4FE400249499 /* BoopSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = BoopSound.caf; sourceTree = ""; };
1D6D967E77A5357E2C6110D9 /* Pods-Mastodon.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk - debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk - debug.xcconfig"; sourceTree = ""; };
- 2D04F42425C255B9003F936F /* APIService+PublicTimeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+PublicTimeline.swift"; sourceTree = ""; };
2D084B8C26258EA3003AA3AF /* NotificationViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationViewModel+Diffable.swift"; sourceTree = ""; };
- 2D084B9226259545003AA3AF /* NotificationViewModel+LoadLatestState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationViewModel+LoadLatestState.swift"; sourceTree = ""; };
2D0B7A1C261D839600B44727 /* SearchHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchHistory.swift; sourceTree = ""; };
- 2D152A8B25C295CC009AA50C /* StatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusView.swift; sourceTree = ""; };
2D152A9125C2980C009AA50C /* UIFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFont.swift; sourceTree = ""; };
2D198642261BF09500F0B013 /* SearchResultItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultItem.swift; sourceTree = ""; };
2D198648261C0B8500F0B013 /* SearchResultSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultSection.swift; sourceTree = ""; };
@@ -812,33 +816,21 @@
2D206B8525F5FB0900143C56 /* Double.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Double.swift; sourceTree = ""; };
2D206B8B25F6015000143C56 /* AudioPlaybackService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioPlaybackService.swift; sourceTree = ""; };
2D206B9125F60EA700143C56 /* UIControl.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIControl.swift; sourceTree = ""; };
- 2D24E11C2626D8B100A59D4F /* NotificationStatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationStatusTableViewCell.swift; sourceTree = ""; };
2D24E1222626ED9D00A59D4F /* UIView+Gesture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Gesture.swift"; sourceTree = ""; };
- 2D24E12C2626FD2E00A59D4F /* NotificationViewModel+LoadOldestState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationViewModel+LoadOldestState.swift"; sourceTree = ""; };
2D32EAAB25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMiddleLoaderTableViewCell.swift; sourceTree = ""; };
2D32EAB925CB9B0500C9ED86 /* UIView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIView.swift; sourceTree = ""; };
- 2D32EAD925CBCC3300C9ED86 /* PublicTimelineViewModel+LoadMiddleState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PublicTimelineViewModel+LoadMiddleState.swift"; sourceTree = ""; };
- 2D34D9CA261489930081BFC0 /* SearchViewController+Recommend.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchViewController+Recommend.swift"; sourceTree = ""; };
2D34D9D026148D9E0081BFC0 /* APIService+Recommend.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Recommend.swift"; sourceTree = ""; };
2D34D9DA261494120081BFC0 /* APIService+Search.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Search.swift"; sourceTree = ""; };
- 2D34D9E126149C920081BFC0 /* SearchRecommendTagsCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRecommendTagsCollectionViewCell.swift; sourceTree = ""; };
2D35237926256D920031AF25 /* NotificationSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationSection.swift; sourceTree = ""; };
2D364F7125E66D7500204FDC /* MastodonResendEmailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewController.swift; sourceTree = ""; };
2D364F7725E66D8300204FDC /* MastodonResendEmailViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewModel.swift; sourceTree = ""; };
2D38F1C525CD37F400561493 /* ContentOffsetAdjustableTimelineViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentOffsetAdjustableTimelineViewControllerDelegate.swift; sourceTree = ""; };
2D38F1D425CD465300561493 /* HomeTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineViewController.swift; sourceTree = ""; };
- 2D38F1DE25CD46A400561493 /* HomeTimelineViewController+Provider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeTimelineViewController+Provider.swift"; sourceTree = ""; };
2D38F1E425CD46C100561493 /* HomeTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineViewModel.swift; sourceTree = ""; };
2D38F1EA25CD477000561493 /* HomeTimelineViewModel+LoadLatestState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeTimelineViewModel+LoadLatestState.swift"; sourceTree = ""; };
- 2D38F1F025CD477D00561493 /* HomeTimelineViewModel+LoadMiddleState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeTimelineViewModel+LoadMiddleState.swift"; sourceTree = ""; };
2D38F1F625CD47AC00561493 /* HomeTimelineViewModel+LoadOldestState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeTimelineViewModel+LoadOldestState.swift"; sourceTree = ""; };
- 2D38F1FD25CD481700561493 /* StatusProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusProvider.swift; sourceTree = ""; };
2D38F20725CD491300561493 /* DisposeBagCollectable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisposeBagCollectable.swift; sourceTree = ""; };
2D3F9E0325DFA133004262D9 /* UITapGestureRecognizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITapGestureRecognizer.swift; sourceTree = ""; };
- 2D42FF7D25C82218004A627A /* ActionToolBarContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionToolBarContainer.swift; sourceTree = ""; };
- 2D42FF8425C8224F004A627A /* HitTestExpandedButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HitTestExpandedButton.swift; sourceTree = ""; };
- 2D42FF8E25C8228A004A627A /* UIButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIButton.swift; sourceTree = ""; };
- 2D45E5BE25C9549700A6D639 /* PublicTimelineViewModel+State.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "PublicTimelineViewModel+State.swift"; sourceTree = ""; };
2D4AD89B263165B500613EFC /* SuggestionAccountCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionAccountCollectionViewCell.swift; sourceTree = ""; };
2D4AD8A126316CD200613EFC /* SelectedAccountSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedAccountSection.swift; sourceTree = ""; };
2D4AD8A726316D3500613EFC /* SelectedAccountItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedAccountItem.swift; sourceTree = ""; };
@@ -852,29 +844,19 @@
2D607AD726242FC500B70763 /* NotificationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationViewModel.swift; sourceTree = ""; };
2D6125462625436B00299647 /* Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = ""; };
2D61254C262547C200299647 /* APIService+Notification.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Notification.swift"; sourceTree = ""; };
- 2D61335725C188A000CAE157 /* APIService+Persist+Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Persist+Status.swift"; sourceTree = ""; };
2D61335D25C1894B00CAE157 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = ""; };
2D650FAA25ECDC9300851B58 /* Mastodon+Entity+Error+Detail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Entity+Error+Detail.swift"; sourceTree = ""; };
2D694A7325F9EB4E0038ADDC /* ContentWarningOverlayView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentWarningOverlayView.swift; sourceTree = ""; };
- 2D69CFF325CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadMoreConfigurableTableViewContainer.swift; sourceTree = ""; };
- 2D69D00925CAA00300C3A1B2 /* APIService+CoreData+Status.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "APIService+CoreData+Status.swift"; sourceTree = ""; };
2D6DE3FF26141DF600A63F6A /* SearchViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchViewModel.swift; sourceTree = ""; };
- 2D76316425C14BD100929FB9 /* PublicTimelineViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicTimelineViewController.swift; sourceTree = ""; };
- 2D76316A25C14D4C00929FB9 /* PublicTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublicTimelineViewModel.swift; sourceTree = ""; };
- 2D76317C25C14DF400929FB9 /* PublicTimelineViewController+Provider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PublicTimelineViewController+Provider.swift"; sourceTree = ""; };
- 2D76318225C14E8F00929FB9 /* PublicTimelineViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PublicTimelineViewModel+Diffable.swift"; sourceTree = ""; };
2D76319E25C1521200929FB9 /* StatusSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusSection.swift; sourceTree = ""; };
2D7631A725C1535600929FB9 /* StatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusTableViewCell.swift; sourceTree = ""; };
- 2D7631B225C159F700929FB9 /* Item.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Item.swift; sourceTree = ""; };
2D7867182625B77500211898 /* NotificationItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationItem.swift; sourceTree = ""; };
- 2D79E700261EA5550011E398 /* APIService+CoreData+Tag.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "APIService+CoreData+Tag.swift"; sourceTree = ""; };
2D82B9FE25E7863200E36F0F /* OnboardingViewControllerAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingViewControllerAppearance.swift; sourceTree = ""; };
2D82BA0425E7897700E36F0F /* MastodonResendEmailViewModelNavigationDelegateShim.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonResendEmailViewModelNavigationDelegateShim.swift; sourceTree = ""; };
2D8434F425FF465D00EECE90 /* HomeTimelineNavigationBarTitleViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineNavigationBarTitleViewModel.swift; sourceTree = ""; };
2D8434FA25FF46B300EECE90 /* HomeTimelineNavigationBarTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineNavigationBarTitleView.swift; sourceTree = ""; };
2D84350425FF858100EECE90 /* UIScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIScrollView.swift; sourceTree = ""; };
2D8FCA072637EABB00137F46 /* APIService+FollowRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+FollowRequest.swift"; sourceTree = ""; };
- 2D927F0125C7E4F2004F19B8 /* Mention.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Mention.swift; sourceTree = ""; };
2D927F0725C7E9A8004F19B8 /* Tag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tag.swift; sourceTree = ""; };
2D927F0D25C7E9C9004F19B8 /* History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = History.swift; sourceTree = ""; };
2D927F1325C7EDD9004F19B8 /* Emoji.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Emoji.swift; sourceTree = ""; };
@@ -895,16 +877,11 @@
2DAC9E45262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestionAccountTableViewCell.swift; sourceTree = ""; };
2DB72C8B262D764300CE6173 /* Mastodon+Entity+Notification+Type.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Entity+Notification+Type.swift"; sourceTree = ""; };
2DCB73FC2615C13900EC03D4 /* SearchRecommendCollectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRecommendCollectionHeader.swift; sourceTree = ""; };
- 2DE0FAC02615F04D00CDF649 /* RecommendHashTagSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendHashTagSection.swift; sourceTree = ""; };
- 2DE0FAC72615F5F000CDF649 /* SearchRecommendAccountsCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchRecommendAccountsCollectionViewCell.swift; sourceTree = ""; };
2DE0FACD2615F7AD00CDF649 /* RecommendAccountSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecommendAccountSection.swift; sourceTree = ""; };
2DF123A625C3B0210020F248 /* ActiveLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActiveLabel.swift; sourceTree = ""; };
- 2DF75B9A25D0E27500694EC8 /* StatusProviderFacade.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusProviderFacade.swift; sourceTree = ""; };
- 2DF75BA025D0E29D00694EC8 /* StatusProvider+StatusTableViewCellDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusProvider+StatusTableViewCellDelegate.swift"; sourceTree = ""; };
2DF75BA625D10E1000694EC8 /* APIService+Favorite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Favorite.swift"; sourceTree = ""; };
2DF75BB825D1474100694EC8 /* ManagedObjectObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedObjectObserver.swift; sourceTree = ""; };
2DF75BC625D1475D00694EC8 /* ManagedObjectContextObjectsDidChange.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedObjectContextObjectsDidChange.swift; sourceTree = ""; };
- 2DFAD5362617010500F9EE7C /* SearchResultTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultTableViewCell.swift; sourceTree = ""; };
2E1F6A67FDF9771D3E064FDC /* Pods-Mastodon.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.debug.xcconfig"; sourceTree = ""; };
374AA339A20E0FAC75BCDA6D /* Pods_NotificationService.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_NotificationService.framework; sourceTree = BUILT_PRODUCTS_DIR; };
3B7FD8F28DDA8FBCE5562B78 /* Pods-NotificationService.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.asdk - debug.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.asdk - debug.xcconfig"; sourceTree = ""; };
@@ -943,9 +920,7 @@
5DF1054625F8870E00D6C0D4 /* VideoPlayerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoPlayerViewModel.swift; sourceTree = ""; };
5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVPlayer.swift; sourceTree = ""; };
5DF1057825F88A1D00D6C0D4 /* PlayerContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerContainerView.swift; sourceTree = ""; };
- 5DF1057E25F88A4100D6C0D4 /* TouchBlockingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TouchBlockingView.swift; sourceTree = ""; };
5DF1058425F88AE500D6C0D4 /* NeedsDependency+AVPlayerViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NeedsDependency+AVPlayerViewControllerDelegate.swift"; sourceTree = ""; };
- 5DFC35DE262068D20045711D /* SearchViewController+Follow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchViewController+Follow.swift"; sourceTree = ""; };
6130CBE4B26E3C976ACC1688 /* Pods-ShareActionExtension.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareActionExtension.asdk - debug.xcconfig"; path = "Target Support Files/Pods-ShareActionExtension/Pods-ShareActionExtension.asdk - debug.xcconfig"; sourceTree = ""; };
75E3471C898DDD9631729B6E /* Pods-Mastodon.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.release.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.release.xcconfig"; sourceTree = ""; };
77EE917BC055E6621C0452B6 /* Pods-ShareActionExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareActionExtension.debug.xcconfig"; path = "Target Support Files/Pods-ShareActionExtension/Pods-ShareActionExtension.debug.xcconfig"; sourceTree = ""; };
@@ -974,6 +949,24 @@
DB0009A826AEE5DC009B9D2D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/Intents.intentdefinition; sourceTree = ""; };
DB0009AD26AEE5E4009B9D2D /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Intents.strings; sourceTree = ""; };
DB0140CE25C42AEE00F9F3CF /* OSLog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSLog.swift; sourceTree = ""; };
+ DB023D25279FFB0A005AC798 /* ShareActivityProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareActivityProvider.swift; sourceTree = ""; };
+ DB023D2727A0FABD005AC798 /* NotificationTableViewCellDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationTableViewCellDelegate.swift; sourceTree = ""; };
+ DB023D2927A0FE5C005AC798 /* DataSourceProvider+NotificationTableViewCellDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceProvider+NotificationTableViewCellDelegate.swift"; sourceTree = ""; };
+ DB023D2B27A10464005AC798 /* NotificationTimelineViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NotificationTimelineViewController+DataSourceProvider.swift"; sourceTree = ""; };
+ DB025B77278D606A002F581E /* StatusItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusItem.swift; sourceTree = ""; };
+ DB025B79278D6138002F581E /* CoreData 3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "CoreData 3.xcdatamodel"; sourceTree = ""; };
+ DB025B7D278D6247002F581E /* AutoGenerateProperty.stencil */ = {isa = PBXFileReference; lastKnownFileType = text; path = AutoGenerateProperty.stencil; sourceTree = ""; };
+ DB025B7E278D6247002F581E /* AutoUpdatableObject.stencil */ = {isa = PBXFileReference; lastKnownFileType = text; path = AutoUpdatableObject.stencil; sourceTree = ""; };
+ DB025B7F278D6247002F581E /* AutoGenerateRelationship.stencil */ = {isa = PBXFileReference; lastKnownFileType = text; path = AutoGenerateRelationship.stencil; sourceTree = ""; };
+ DB025B81278D6271002F581E /* AutoGenerateProperty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoGenerateProperty.swift; sourceTree = ""; };
+ DB025B82278D6272002F581E /* AutoUpdatableObject.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoUpdatableObject.swift; sourceTree = ""; };
+ DB025B83278D6272002F581E /* AutoGenerateRelationship.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AutoGenerateRelationship.swift; sourceTree = ""; };
+ DB025B88278D6339002F581E /* Feed.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Feed.swift; sourceTree = ""; };
+ DB025B8B278D6374002F581E /* Acct.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Acct.swift; sourceTree = ""; };
+ DB025B8F278D6489002F581E /* Feed+Kind.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Feed+Kind.swift"; sourceTree = ""; };
+ DB025B92278D6501002F581E /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; };
+ DB025B94278D6530002F581E /* Persistence+MastodonUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Persistence+MastodonUser.swift"; sourceTree = ""; };
+ DB025B96278D66D5002F581E /* MastodonUser+Property.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonUser+Property.swift"; sourceTree = ""; };
DB029E94266A20430062874E /* MastodonAuthenticationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonAuthenticationController.swift; sourceTree = ""; };
DB02CDAA26256A9500D0A2AF /* ThreadReplyLoaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadReplyLoaderTableViewCell.swift; sourceTree = ""; };
DB02CDBE2625AE5000D0A2AF /* AdaptiveUserInterfaceStyleBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdaptiveUserInterfaceStyleBarButtonItem.swift; sourceTree = ""; };
@@ -996,24 +989,50 @@
DB0618092785B2AB0030EE79 /* MastodonRegisterAvatarTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonRegisterAvatarTableViewCell.swift; sourceTree = ""; };
DB084B5625CBC56C00F898ED /* Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Status.swift; sourceTree = ""; };
DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Instance.swift"; sourceTree = ""; };
- DB0C946A26A700AB0088FB11 /* MastodonUser+Property.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonUser+Property.swift"; sourceTree = ""; };
- DB0C946E26A7D2A80088FB11 /* AvatarImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarImageView.swift; sourceTree = ""; };
- DB0C947126A7D2D70088FB11 /* AvatarButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarButton.swift; sourceTree = ""; };
DB0C947626A7FE840088FB11 /* NotificationAvatarButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationAvatarButton.swift; sourceTree = ""; };
- DB0E91E926A9675100BD2ACC /* MetaLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetaLabel.swift; sourceTree = ""; };
DB0EF72A26FDB1D200347686 /* SidebarListCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarListCollectionViewCell.swift; sourceTree = ""; };
DB0EF72D26FDB24F00347686 /* SidebarListContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarListContentView.swift; sourceTree = ""; };
- DB0F814D264CFFD300F2A12B /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Localizable.strings; sourceTree = ""; };
DB0F814E264CFFD300F2A12B /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/InfoPlist.strings; sourceTree = ""; };
DB0F814F264D1E2500F2A12B /* PickServerLoaderTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerLoaderTableViewCell.swift; sourceTree = ""; };
+ DB0FCB67279507EF006C02E2 /* DataSourceFacade+Meta.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Meta.swift"; sourceTree = ""; };
+ DB0FCB6927950CB3006C02E2 /* MastodonMention.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonMention.swift; sourceTree = ""; };
+ DB0FCB6B27950E29006C02E2 /* MastodonMentionContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonMentionContainer.swift; sourceTree = ""; };
+ DB0FCB6D27950E6B006C02E2 /* MastodonMention.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonMention.swift; sourceTree = ""; };
+ DB0FCB6F27951368006C02E2 /* TimelineMiddleLoaderTableViewCell+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TimelineMiddleLoaderTableViewCell+ViewModel.swift"; sourceTree = ""; };
+ DB0FCB7127952986006C02E2 /* NamingState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NamingState.swift; sourceTree = ""; };
+ DB0FCB7327956939006C02E2 /* DataSourceFacade+Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Status.swift"; sourceTree = ""; };
+ DB0FCB75279571C5006C02E2 /* ThreadViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ThreadViewController+DataSourceProvider.swift"; sourceTree = ""; };
+ DB0FCB7727957678006C02E2 /* DataSourceProvider+UITableViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceProvider+UITableViewDelegate.swift"; sourceTree = ""; };
+ DB0FCB79279576A2006C02E2 /* DataSourceFacade+Thread.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Thread.swift"; sourceTree = ""; };
+ DB0FCB7B2795821F006C02E2 /* StatusThreadRootTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusThreadRootTableViewCell.swift; sourceTree = ""; };
+ DB0FCB7D27958957006C02E2 /* StatusThreadRootTableViewCell+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusThreadRootTableViewCell+ViewModel.swift"; sourceTree = ""; };
+ DB0FCB7F27968F70006C02E2 /* MastodonStatusThreadViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonStatusThreadViewModel.swift; sourceTree = ""; };
+ DB0FCB812796AC78006C02E2 /* UserTimelineViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserTimelineViewController+DataSourceProvider.swift"; sourceTree = ""; };
+ DB0FCB832796B2A2006C02E2 /* FavoriteViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FavoriteViewController+DataSourceProvider.swift"; sourceTree = ""; };
+ DB0FCB852796BDA1006C02E2 /* SearchSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchSection.swift; sourceTree = "