Kurdtvs-Live-Kurdish-TV-Kur.../Mastodon/Persistence/Persistence+Status.swift

221 lines
7.3 KiB
Swift
Raw Normal View History

Release v1.3.0 (#347) * New translations app.json (Thai) * New translations app.json (Spanish) * New translations Localizable.stringsdict (Spanish) * New translations app.json (Thai) * New translations app.json (Thai) * feat: adapt the app to async & await. Update timeline UI * fix: update the Xcode version to fix the CI failure * fix: remove unavailable framework import * fix: project dependency issue * feat: add content warning for post spoiler * feat: add content warning for post media * chore: update version to 1.3.0 (92) * New translations app.json (French) * New translations Intents.strings (French) * New translations app.json (Thai) * feat: update report flow * feat: update setting scene UI * feat: update status content warning UI * feat: add notification gap fetcher * chore: update version to 1.3.0 (93) * feat: add video player for audio/video kind media * chore: update version to 1.3.0 (94) * fix: text strip wrong color in the Dark Mode issue * chore: remove spoiler toggle animation for table cell * fix: add missing shadow for compose publish button * fix: add missing margin for timeline with horizontal regular size class * fix: profile segmented controls missing margin issue * fix: the profile segmented control use wrong selection tint color under force light UI style issue * fix: add notification count clear logic back * fix: add missing home timeline bottom fetcher * fix: [WIP] add suggestion account scene back * New translations app.json (Kabyle) * New translations ios-infoPlist.json (Kabyle) * New translations Localizable.stringsdict (Kabyle) * New translations Intents.strings (Kabyle) * New translations Intents.stringsdict (Kabyle) * feat: make the home timeline readable for VoiceOver * chore: update version to 1.3.0 (95) * New translations app.json (French) * New translations Intents.strings (French) * New translations app.json (Kabyle) * New translations ios-infoPlist.json (Kabyle) * New translations Localizable.stringsdict (Kabyle) * New translations Intents.strings (Kabyle) * New translations Intents.stringsdict (Kabyle) * New translations Localizable.stringsdict (French) * New translations app.json (Kabyle) * New translations app.json (French) * chore: update action toolbar icons * fix: instal state missing issue * fix: follow push notification deep-link not works issue * fix: foreground notification not trigger tab bell icon update issue * feat: add notification timeline fetcher * feat: add content warning toggle button * chore: update version to 1.3.0 (96) * New translations app.json (Thai) * New translations app.json (Russian) * New translations app.json (Kurmanji (Kurdish)) * New translations app.json (Scottish Gaelic) * New translations app.json (Welsh) * New translations app.json (Hindi) * New translations app.json (Spanish, Argentina) * New translations app.json (Indonesian) * New translations app.json (Portuguese, Brazilian) * New translations app.json (English) * New translations app.json (Chinese Traditional) * New translations app.json (Chinese Simplified) * New translations app.json (Swedish) * New translations app.json (Portuguese) * New translations app.json (Dutch) * New translations app.json (Korean) * New translations app.json (Japanese) * New translations app.json (Basque) * New translations app.json (German) * New translations app.json (Danish) * New translations app.json (Catalan) * New translations app.json (Arabic) * New translations app.json (Spanish) * New translations app.json (Romanian) * New translations app.json (Kabyle) * New translations app.json (French) * New translations app.json (Swedish, Finland) * New translations app.json (Spanish, Argentina) * New translations app.json (Kurmanji (Kurdish)) * fix: notification i18n word typo * New translations app.json (Thai) * New translations app.json (Swedish) * New translations Localizable.stringsdict (Swedish) * New translations app.json (Swedish, Finland) * New translations app.json (Kurmanji (Kurdish)) * New translations app.json (Scottish Gaelic) * New translations app.json (Welsh) * New translations app.json (Hindi) * New translations app.json (Indonesian) * New translations app.json (Portuguese, Brazilian) * New translations app.json (English) * New translations app.json (Chinese Traditional) * New translations app.json (Chinese Simplified) * New translations app.json (Russian) * New translations app.json (Portuguese) * New translations app.json (Dutch) * New translations app.json (Korean) * New translations app.json (Japanese) * New translations app.json (Basque) * New translations app.json (German) * New translations app.json (Danish) * New translations app.json (Catalan) * New translations app.json (Arabic) * New translations app.json (Spanish) * New translations app.json (Romanian) * New translations app.json (Kabyle) * New translations app.json (French) * New translations Intents.strings (Swedish) * New translations app.json (Swedish) * New translations Localizable.stringsdict (Japanese) * New translations app.json (Thai) * New translations app.json (Thai) * New translations Localizable.stringsdict (Swedish) * New translations app.json (Kabyle) * New translations ios-infoPlist.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (French) * New translations app.json (French) * feat: restore scroll-to-top tap gesture for TabBar * feat: add cell height cache for user timeline * feat: display no results when profile field empty * New translations app.json (Chinese Traditional) * New translations app.json (Chinese Traditional) * New translations Intents.strings (Japanese) * feat: make status detail accessible * chore: restore the appearance settings * chore: update version to 1.3.0 (97) * New translations app.json (Kabyle) * New translations Intents.strings (Japanese) * New translations app.json (Swedish) * New translations app.json (Basque) * New translations app.json (Basque) * chore: add a11y hint for profile dashboard * feat: add media interaction for notification timeline * New translations app.json (Chinese Simplified) * New translations app.json (Chinese Simplified) * chore: update i18n strings * fix: setting switch use wrong tint color issue * chore: restore RTL layout for post content * chore: update profile relationship button UI * chore: update color panel * fix: post reblog header may display empty reblogger name issue * fix: wrong reply header redirect logic issue * feat: restore post filter supports * chore: update version to 1.3.0 (98) * chore: update post content sensitive style * fix: blurhash image not display during image loading issue * chore: update version to 1.3.0 (99) * feat: restore user recommend scene * chore: update badge tint color * feat: restore keyboard shortcut supports * chore: update version to 1.3.0 (100) * fix: relationship background use wrong color when force dark style * fix: player button icon not reset issue * chore: update version to 1.3.0 (101) * fix: profile relationship button fill the width on iPad issue * fix: inputAssistantItem duplicate setup issue * chore: update textView minimum height from 88 to 64 * chore: update version to 1.3.0 (102) * chore: update status timeline margin * chore: update sidebar background color * fix: split view column state after size class transition not stable issue * chore: update notification timeline margin * chore: update profile header and segmented bar margin * fix: profile segmented bar use wrong tint color when force Dark Mode issue * chore: update horizontal compact mode notification timeline margin looks like * chore: update version to 1.3.0 (103) * feat: dismiss image preview when tap empty area * chore: update version to 1.3.0 (104) * New translations app.json (Italian) * New translations ios-infoPlist.json (Italian) * New translations Localizable.stringsdict (Italian) * New translations Intents.strings (Italian) * New translations Intents.stringsdict (Italian) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Japanese) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Spanish) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Kabyle) * New translations ios-infoPlist.json (Kabyle) * New translations Localizable.stringsdict (Kabyle) * New translations Localizable.stringsdict (Kabyle) * New translations Intents.strings (Kabyle) * New translations app.json (Kabyle) * New translations Intents.strings (Kabyle) * New translations Intents.stringsdict (Kabyle) * New translations app.json (Kabyle) * New translations app.json (Scottish Gaelic) * New translations app.json (Scottish Gaelic) * New translations app.json (Thai) * New translations app.json (Thai) * feat: add UITests for snapshots * feat: add snapshot UITest and document * New translations app.json (Thai) * feat: add notification snapshot * chore: add domain and update guide for the snapshot UITest * chore: use the first photo for compose snapshot * New translations app.json (Thai) * New translations app.json (German) * New translations app.json (German) * chore: update settings scene UI * chore: update i18n for open link words * chore: update i18n resources * fix: share extension not accept plaintext content issue. resolve #335 * chore: update version to 1.3.0 (105) * New translations app.json (Japanese) * New translations app.json (Japanese) * New translations app.json (Japanese) * feat: add onion domain ATS exception rule. resolve #338 * chore: update app version footer and i18n strings * chore: update version to 1.3.0 (106) * chore: update version to 1.3.0 (108) * Handle onboarding authentication errors in /api/v1/instance * New translations app.json (Kurmanji (Kurdish)) * New translations app.json (Kurmanji (Kurdish)) * chore: update Xcode schemes index * chore: update the snapshot documents and UITests * chore: update i18n resources. resolve #343 * chore: retain the API model semantic * fix: force LTR for some text fields. #318 * fix: textView break IME input issue. resolve #342 * chore: update version to 1.3.0 (109) * chore: update README * chore: fix typo * chore: add bug report template and contributing document Co-authored-by: Eugen Rochko <eugen@zeonfederated.com> Co-authored-by: Zac West <zacwest@gmail.com>
2022-03-29 11:51:14 +02:00
//
// Persistence+Status.swift
// Persistence+Status
//
// Created by Cirno MainasuK on 2021-8-27.
// Copyright © 2021 Twidere. All rights reserved.
//
import CoreData
import CoreDataStack
import Foundation
import MastodonSDK
import os.log
extension Persistence.Status {
public struct PersistContext {
public let domain: String
public let entity: Mastodon.Entity.Status
public let me: MastodonUser?
public let statusCache: Persistence.PersistCache<Status>?
public let userCache: Persistence.PersistCache<MastodonUser>?
public let networkDate: Date
public let log = OSLog.api
public init(
domain: String,
entity: Mastodon.Entity.Status,
me: MastodonUser?,
statusCache: Persistence.PersistCache<Status>?,
userCache: Persistence.PersistCache<MastodonUser>?,
networkDate: Date
) {
self.domain = domain
self.entity = entity
self.me = me
self.statusCache = statusCache
self.userCache = userCache
self.networkDate = networkDate
}
}
public struct PersistResult {
public let status: Status
public let isNewInsertion: Bool
public let isNewInsertionAuthor: Bool
public init(
status: Status,
isNewInsertion: Bool,
isNewInsertionAuthor: Bool
) {
self.status = status
self.isNewInsertion = isNewInsertion
self.isNewInsertionAuthor = isNewInsertionAuthor
}
#if DEBUG
public let logger = Logger(subsystem: "Persistence.Status.PersistResult", category: "Persist")
public func log() {
let statusInsertionFlag = isNewInsertion ? "+" : "-"
let authorInsertionFlag = isNewInsertionAuthor ? "+" : "-"
let contentPreview = status.content.prefix(32).replacingOccurrences(of: "\n", with: " ")
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [\(statusInsertionFlag)](\(status.id))[\(authorInsertionFlag)](\(status.author.id))@\(status.author.username): \(contentPreview)")
}
#endif
}
public static func createOrMerge(
in managedObjectContext: NSManagedObjectContext,
context: PersistContext
) -> PersistResult {
let reblog = context.entity.reblog.flatMap { entity -> Status in
let result = createOrMerge(
in: managedObjectContext,
context: PersistContext(
domain: context.domain,
entity: entity,
me: context.me,
statusCache: context.statusCache,
userCache: context.userCache,
networkDate: context.networkDate
)
)
return result.status
}
if let oldStatus = fetch(in: managedObjectContext, context: context) {
merge(mastodonStatus: oldStatus, context: context)
return PersistResult(
status: oldStatus,
isNewInsertion: false,
isNewInsertionAuthor: false
)
} else {
let poll: Poll? = {
guard let entity = context.entity.poll else { return nil }
let result = Persistence.Poll.createOrMerge(
in: managedObjectContext,
context: Persistence.Poll.PersistContext(
domain: context.domain,
entity: entity,
me: context.me,
networkDate: context.networkDate
)
)
return result.poll
}()
let authorResult = Persistence.MastodonUser.createOrMerge(
in: managedObjectContext,
context: Persistence.MastodonUser.PersistContext(
domain: context.domain,
entity: context.entity.account,
cache: context.userCache,
networkDate: context.networkDate
)
)
let author = authorResult.user
let relationship = Status.Relationship(
author: author,
reblog: reblog,
poll: poll
)
let status = create(
in: managedObjectContext,
context: context,
relationship: relationship
)
return PersistResult(
status: status,
isNewInsertion: true,
isNewInsertionAuthor: authorResult.isNewInsertion
)
}
}
}
extension Persistence.Status {
public static func fetch(
in managedObjectContext: NSManagedObjectContext,
context: PersistContext
) -> Status? {
if let cache = context.statusCache {
return cache.dictionary[context.entity.id]
} else {
let request = Status.sortedFetchRequest
request.predicate = Status.predicate(domain: context.domain, id: context.entity.id)
request.fetchLimit = 1
do {
return try managedObjectContext.fetch(request).first
} catch {
assertionFailure(error.localizedDescription)
return nil
}
}
}
@discardableResult
public static func create(
in managedObjectContext: NSManagedObjectContext,
context: PersistContext,
relationship: Status.Relationship
) -> Status {
let property = Status.Property(
entity: context.entity,
domain: context.domain,
networkDate: context.networkDate
)
let status = Status.insert(
into: managedObjectContext,
property: property,
relationship: relationship
)
update(status: status, context: context)
return status
}
public static func merge(
mastodonStatus status: Status,
context: PersistContext
) {
guard context.networkDate > status.updatedAt else { return }
let property = Status.Property(
entity: context.entity,
domain: context.domain,
networkDate: context.networkDate
)
status.update(property: property)
if let poll = status.poll, let entity = context.entity.poll {
Persistence.Poll.merge(
poll: poll,
context: Persistence.Poll.PersistContext(
domain: context.domain,
entity: entity,
me: context.me,
networkDate: context.networkDate
)
)
}
update(status: status, context: context)
}
private static func update(
status: Status,
context: PersistContext
) {
// update friendships
if let user = context.me {
context.entity.reblogged.flatMap { status.update(reblogged: $0, by: user) }
context.entity.favourited.flatMap { status.update(liked: $0, by: user) }
}
}
}