// // 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? // sourcery: autoUpdatableObject @NSManaged public private(set) var isContentSensitiveToggled: Bool // sourcery: autoUpdatableObject @NSManaged public private(set) var isMediaSensitiveToggled: Bool @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 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(isContentSensitiveToggled: Bool) { if self.isContentSensitiveToggled != isContentSensitiveToggled { self.isContentSensitiveToggled = isContentSensitiveToggled } } public func update(isMediaSensitiveToggled: Bool) { if self.isMediaSensitiveToggled != isMediaSensitiveToggled { self.isMediaSensitiveToggled = isMediaSensitiveToggled } } 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 // } // // } //} //