2021-01-27 07:50:13 +01:00
|
|
|
//
|
2021-01-28 09:10:30 +01:00
|
|
|
// Toot.swift
|
2021-01-27 07:50:13 +01:00
|
|
|
// CoreDataStack
|
|
|
|
//
|
|
|
|
// Created by MainasuK Cirno on 2021/1/27.
|
|
|
|
//
|
|
|
|
|
|
|
|
import CoreData
|
2021-02-01 11:05:34 +01:00
|
|
|
import Foundation
|
2021-01-27 07:50:13 +01:00
|
|
|
|
2021-02-01 11:05:34 +01:00
|
|
|
public final class Toot: NSManagedObject {
|
2021-01-27 07:50:13 +01:00
|
|
|
public typealias ID = String
|
2021-02-04 07:45:44 +01:00
|
|
|
|
2021-01-27 07:50:13 +01:00
|
|
|
@NSManaged public private(set) var identifier: ID
|
|
|
|
@NSManaged public private(set) var domain: String
|
|
|
|
|
|
|
|
@NSManaged public private(set) var id: String
|
2021-02-01 11:05:34 +01:00
|
|
|
@NSManaged public private(set) var uri: String
|
|
|
|
@NSManaged public private(set) var createdAt: Date
|
2021-01-27 07:50:13 +01:00
|
|
|
@NSManaged public private(set) var content: String
|
|
|
|
|
2021-02-01 11:05:34 +01:00
|
|
|
@NSManaged public private(set) var visibility: String?
|
|
|
|
@NSManaged public private(set) var sensitive: Bool
|
|
|
|
@NSManaged public private(set) var spoilerText: String?
|
2021-02-03 06:43:57 +01:00
|
|
|
@NSManaged public private(set) var application: Application?
|
2021-02-01 11:05:34 +01:00
|
|
|
|
|
|
|
// Informational
|
2021-02-02 07:10:25 +01:00
|
|
|
@NSManaged public private(set) var reblogsCount: NSNumber
|
|
|
|
@NSManaged public private(set) var favouritesCount: NSNumber
|
|
|
|
@NSManaged public private(set) var repliesCount: NSNumber?
|
2021-02-01 11:05:34 +01:00
|
|
|
|
|
|
|
@NSManaged public private(set) var url: String?
|
|
|
|
@NSManaged public private(set) var inReplyToID: Toot.ID?
|
|
|
|
@NSManaged public private(set) var inReplyToAccountID: MastodonUser.ID?
|
2021-02-02 07:10:25 +01:00
|
|
|
|
|
|
|
@NSManaged public private(set) var language: String? // (ISO 639 Part 1 two-letter language code)
|
2021-02-01 11:05:34 +01:00
|
|
|
@NSManaged public private(set) var text: String?
|
|
|
|
|
2021-02-02 07:10:25 +01:00
|
|
|
// many-to-one relastionship
|
2021-02-04 07:45:44 +01:00
|
|
|
@NSManaged public private(set) var author: MastodonUser
|
|
|
|
@NSManaged public private(set) var reblog: Toot?
|
2021-02-07 07:42:50 +01:00
|
|
|
@NSManaged public private(set) var favouritedBy: Set<MastodonUser>?
|
|
|
|
@NSManaged public private(set) var rebloggedBy: Set<MastodonUser>?
|
|
|
|
@NSManaged public private(set) var mutedBy: Set<MastodonUser>?
|
|
|
|
@NSManaged public private(set) var bookmarkedBy: Set<MastodonUser>?
|
2021-02-02 07:10:25 +01:00
|
|
|
|
|
|
|
// one-to-one relastionship
|
|
|
|
@NSManaged public private(set) var pinnedBy: MastodonUser?
|
2021-02-04 07:45:44 +01:00
|
|
|
|
2021-02-02 07:49:55 +01:00
|
|
|
// one-to-many relationship
|
|
|
|
@NSManaged public private(set) var reblogFrom: Set<Toot>?
|
2021-02-02 07:10:25 +01:00
|
|
|
@NSManaged public private(set) var mentions: Set<Mention>?
|
|
|
|
@NSManaged public private(set) var emojis: Set<Emoji>?
|
|
|
|
@NSManaged public private(set) var tags: Set<Tag>?
|
2021-01-27 07:50:13 +01:00
|
|
|
@NSManaged public private(set) var homeTimelineIndexes: Set<HomeTimelineIndex>?
|
2021-02-04 07:45:44 +01:00
|
|
|
|
|
|
|
@NSManaged public private(set) var updatedAt: Date
|
|
|
|
@NSManaged public private(set) var deletedAt: Date?
|
2021-01-27 07:50:13 +01:00
|
|
|
}
|
|
|
|
|
2021-02-01 11:05:34 +01:00
|
|
|
public extension Toot {
|
2021-01-27 07:50:13 +01:00
|
|
|
@discardableResult
|
2021-02-01 11:05:34 +01:00
|
|
|
static func insert(
|
2021-01-27 07:50:13 +01:00
|
|
|
into context: NSManagedObjectContext,
|
|
|
|
property: Property,
|
2021-02-04 07:45:44 +01:00
|
|
|
author: MastodonUser,
|
|
|
|
reblog: Toot?,
|
|
|
|
application: Application?,
|
|
|
|
mentions: [Mention]?,
|
|
|
|
emojis: [Emoji]?,
|
|
|
|
tags: [Tag]?,
|
|
|
|
favouritedBy: MastodonUser?,
|
|
|
|
rebloggedBy: MastodonUser?,
|
|
|
|
mutedBy: MastodonUser?,
|
|
|
|
bookmarkedBy: MastodonUser?,
|
|
|
|
pinnedBy: MastodonUser?
|
2021-01-28 09:10:30 +01:00
|
|
|
) -> Toot {
|
2021-02-01 11:05:34 +01:00
|
|
|
let toot: Toot = context.insertObject()
|
2021-01-27 07:50:13 +01:00
|
|
|
|
2021-02-01 11:05:34 +01:00
|
|
|
toot.identifier = property.identifier
|
|
|
|
toot.domain = property.domain
|
|
|
|
|
|
|
|
toot.id = property.id
|
|
|
|
toot.uri = property.uri
|
|
|
|
toot.createdAt = property.createdAt
|
|
|
|
toot.content = property.content
|
2021-01-27 07:50:13 +01:00
|
|
|
|
2021-02-01 11:05:34 +01:00
|
|
|
toot.visibility = property.visibility
|
|
|
|
toot.sensitive = property.sensitive
|
|
|
|
toot.spoilerText = property.spoilerText
|
2021-02-04 07:45:44 +01:00
|
|
|
toot.application = application
|
2021-01-27 07:50:13 +01:00
|
|
|
|
2021-02-01 11:05:34 +01:00
|
|
|
toot.reblogsCount = property.reblogsCount
|
|
|
|
toot.favouritesCount = property.favouritesCount
|
|
|
|
toot.repliesCount = property.repliesCount
|
2021-01-27 07:50:13 +01:00
|
|
|
|
2021-02-01 11:05:34 +01:00
|
|
|
toot.url = property.url
|
|
|
|
toot.inReplyToID = property.inReplyToID
|
|
|
|
toot.inReplyToAccountID = property.inReplyToAccountID
|
2021-02-04 07:45:44 +01:00
|
|
|
|
2021-02-01 11:05:34 +01:00
|
|
|
toot.language = property.language
|
|
|
|
toot.text = property.text
|
2021-01-27 07:50:13 +01:00
|
|
|
|
2021-02-04 07:45:44 +01:00
|
|
|
toot.author = author
|
|
|
|
toot.reblog = reblog
|
|
|
|
|
2021-02-07 07:42:50 +01:00
|
|
|
toot.pinnedBy = pinnedBy
|
|
|
|
|
2021-02-04 07:45:44 +01:00
|
|
|
if let mentions = mentions {
|
|
|
|
toot.mutableSetValue(forKey: #keyPath(Toot.mentions)).addObjects(from: mentions)
|
|
|
|
}
|
|
|
|
if let emojis = emojis {
|
|
|
|
toot.mutableSetValue(forKey: #keyPath(Toot.emojis)).addObjects(from: emojis)
|
|
|
|
}
|
|
|
|
if let tags = tags {
|
|
|
|
toot.mutableSetValue(forKey: #keyPath(Toot.tags)).addObjects(from: tags)
|
|
|
|
}
|
|
|
|
if let favouritedBy = favouritedBy {
|
2021-02-02 07:10:25 +01:00
|
|
|
toot.mutableSetValue(forKey: #keyPath(Toot.favouritedBy)).add(favouritedBy)
|
|
|
|
}
|
2021-02-04 07:45:44 +01:00
|
|
|
if let rebloggedBy = rebloggedBy {
|
2021-02-02 07:10:25 +01:00
|
|
|
toot.mutableSetValue(forKey: #keyPath(Toot.rebloggedBy)).add(rebloggedBy)
|
|
|
|
}
|
2021-02-04 07:45:44 +01:00
|
|
|
if let mutedBy = mutedBy {
|
2021-02-02 07:10:25 +01:00
|
|
|
toot.mutableSetValue(forKey: #keyPath(Toot.mutedBy)).add(mutedBy)
|
|
|
|
}
|
2021-02-04 07:45:44 +01:00
|
|
|
if let bookmarkedBy = bookmarkedBy {
|
2021-02-02 07:10:25 +01:00
|
|
|
toot.mutableSetValue(forKey: #keyPath(Toot.bookmarkedBy)).add(bookmarkedBy)
|
|
|
|
}
|
|
|
|
|
2021-02-04 07:45:44 +01:00
|
|
|
toot.updatedAt = property.networkDate
|
2021-02-01 11:05:34 +01:00
|
|
|
|
|
|
|
return toot
|
|
|
|
}
|
2021-02-03 09:37:18 +01:00
|
|
|
func update(reblogsCount: NSNumber) {
|
|
|
|
if self.reblogsCount.intValue != reblogsCount.intValue {
|
|
|
|
self.reblogsCount = reblogsCount
|
|
|
|
}
|
|
|
|
}
|
|
|
|
func update(favouritesCount: NSNumber) {
|
|
|
|
if self.favouritesCount.intValue != favouritesCount.intValue {
|
|
|
|
self.favouritesCount = favouritesCount
|
|
|
|
}
|
|
|
|
}
|
|
|
|
func update(repliesCount: NSNumber?) {
|
|
|
|
guard let count = repliesCount else {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if self.repliesCount?.intValue != count.intValue {
|
|
|
|
self.repliesCount = repliesCount
|
|
|
|
}
|
|
|
|
}
|
2021-02-08 11:29:27 +01:00
|
|
|
func update(liked: Bool, mastodonUser: MastodonUser) {
|
|
|
|
if liked {
|
|
|
|
if !(self.favouritedBy ?? Set()).contains(mastodonUser) {
|
|
|
|
self.mutableSetValue(forKey: #keyPath(Toot.favouritedBy)).addObjects(from: [mastodonUser])
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (self.favouritedBy ?? Set()).contains(mastodonUser) {
|
|
|
|
self.mutableSetValue(forKey: #keyPath(Toot.favouritedBy)).remove(mastodonUser)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-02-18 07:32:29 +01:00
|
|
|
func update(reblogged: Bool, mastodonUser: MastodonUser) {
|
|
|
|
if reblogged {
|
|
|
|
if !(self.rebloggedBy ?? Set()).contains(mastodonUser) {
|
|
|
|
self.mutableSetValue(forKey: #keyPath(Toot.rebloggedBy)).addObjects(from: [mastodonUser])
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (self.rebloggedBy ?? Set()).contains(mastodonUser) {
|
|
|
|
self.mutableSetValue(forKey: #keyPath(Toot.rebloggedBy)).remove(mastodonUser)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func update(muted: Bool, mastodonUser: MastodonUser) {
|
|
|
|
if muted {
|
|
|
|
if !(self.mutedBy ?? Set()).contains(mastodonUser) {
|
|
|
|
self.mutableSetValue(forKey: #keyPath(Toot.mutedBy)).addObjects(from: [mastodonUser])
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (self.mutedBy ?? Set()).contains(mastodonUser) {
|
|
|
|
self.mutableSetValue(forKey: #keyPath(Toot.mutedBy)).remove(mastodonUser)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func update(bookmarked: Bool, mastodonUser: MastodonUser) {
|
|
|
|
if bookmarked {
|
|
|
|
if !(self.bookmarkedBy ?? Set()).contains(mastodonUser) {
|
|
|
|
self.mutableSetValue(forKey: #keyPath(Toot.bookmarkedBy)).addObjects(from: [mastodonUser])
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (self.bookmarkedBy ?? Set()).contains(mastodonUser) {
|
|
|
|
self.mutableSetValue(forKey: #keyPath(Toot.bookmarkedBy)).remove(mastodonUser)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-03 09:37:18 +01:00
|
|
|
func didUpdate(at networkDate: Date) {
|
|
|
|
self.updatedAt = networkDate
|
|
|
|
}
|
|
|
|
|
2021-02-01 11:05:34 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public extension Toot {
|
|
|
|
struct Property {
|
2021-02-04 07:45:44 +01:00
|
|
|
|
|
|
|
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 reblogsCount: NSNumber
|
|
|
|
public let favouritesCount: NSNumber
|
|
|
|
public let repliesCount: NSNumber?
|
|
|
|
|
|
|
|
public let url: String?
|
|
|
|
public let inReplyToID: Toot.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
|
|
|
|
|
2021-01-27 07:50:13 +01:00
|
|
|
public init(
|
|
|
|
domain: String,
|
2021-02-01 11:05:34 +01:00
|
|
|
id: String,
|
|
|
|
uri: String,
|
2021-01-27 07:50:13 +01:00
|
|
|
createdAt: Date,
|
2021-02-01 11:05:34 +01:00
|
|
|
content: String,
|
|
|
|
visibility: String?,
|
|
|
|
sensitive: Bool,
|
|
|
|
spoilerText: String?,
|
2021-02-02 07:10:25 +01:00
|
|
|
reblogsCount: NSNumber,
|
|
|
|
favouritesCount: NSNumber,
|
|
|
|
repliesCount: NSNumber?,
|
2021-02-01 11:05:34 +01:00
|
|
|
url: String?,
|
|
|
|
inReplyToID: Toot.ID?,
|
|
|
|
inReplyToAccountID: MastodonUser.ID?,
|
|
|
|
language: String?,
|
|
|
|
text: String?,
|
2021-02-04 07:45:44 +01:00
|
|
|
networkDate: Date
|
|
|
|
) {
|
2021-01-27 07:50:13 +01:00
|
|
|
self.identifier = id + "@" + domain
|
|
|
|
self.domain = domain
|
|
|
|
self.id = id
|
2021-02-01 11:05:34 +01:00
|
|
|
self.uri = uri
|
2021-01-27 07:50:13 +01:00
|
|
|
self.createdAt = createdAt
|
2021-02-01 11:05:34 +01:00
|
|
|
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
|
2021-02-04 07:45:44 +01:00
|
|
|
self.networkDate = networkDate
|
2021-01-27 07:50:13 +01:00
|
|
|
}
|
2021-02-01 11:05:34 +01:00
|
|
|
|
2021-01-27 07:50:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-28 09:10:30 +01:00
|
|
|
extension Toot: Managed {
|
2021-01-27 07:50:13 +01:00
|
|
|
public static var defaultSortDescriptors: [NSSortDescriptor] {
|
2021-01-28 09:10:30 +01:00
|
|
|
return [NSSortDescriptor(keyPath: \Toot.createdAt, ascending: false)]
|
2021-01-27 07:50:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-02-04 07:45:44 +01:00
|
|
|
extension Toot {
|
|
|
|
|
|
|
|
static func predicate(domain: String) -> NSPredicate {
|
|
|
|
return NSPredicate(format: "%K == %@", #keyPath(Toot.domain), domain)
|
|
|
|
}
|
|
|
|
|
|
|
|
static func predicate(id: String) -> NSPredicate {
|
|
|
|
return NSPredicate(format: "%K == %@", #keyPath(Toot.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(Toot.id), ids)
|
2021-01-28 09:10:30 +01:00
|
|
|
}
|
|
|
|
|
2021-02-04 07:45:44 +01:00
|
|
|
public static func predicate(domain: String, ids: [String]) -> NSPredicate {
|
|
|
|
return NSCompoundPredicate(andPredicateWithSubpredicates: [
|
|
|
|
predicate(domain: domain),
|
|
|
|
predicate(ids: ids)
|
|
|
|
])
|
2021-01-28 09:10:30 +01:00
|
|
|
}
|
|
|
|
|
2021-02-04 07:45:44 +01:00
|
|
|
public static func notDeleted() -> NSPredicate {
|
2021-01-28 09:10:30 +01:00
|
|
|
return NSPredicate(format: "%K == nil", #keyPath(Toot.deletedAt))
|
|
|
|
}
|
|
|
|
|
2021-02-04 07:45:44 +01:00
|
|
|
public static func deleted() -> NSPredicate {
|
2021-01-28 09:10:30 +01:00
|
|
|
return NSPredicate(format: "%K != nil", #keyPath(Toot.deletedAt))
|
|
|
|
}
|
|
|
|
}
|