another.im-ios/ConversationsClassic/AppData/Model/Roster.swift

105 lines
2.8 KiB
Swift
Raw Normal View History

2024-06-19 15:15:27 +00:00
import Foundation
import GRDB
import Martin
struct RosterVersion: DBStorable {
static let databaseTableName = "rosterVersions"
var bareJid: String
var version: String
var id: String { bareJid }
}
struct Roster: DBStorable {
static let databaseTableName = "rosters"
var bareJid: String = ""
var contactBareJid: String
var name: String?
var subscription: String
var ask: Bool
var data: DBRosterData
var locallyDeleted: Bool = false
var id: String { "\(bareJid)-\(contactBareJid)" }
}
struct DBRosterData: Codable, DatabaseValueConvertible {
let groups: [String]
let annotations: [RosterItemAnnotation]
public var databaseValue: DatabaseValue {
let encoder = JSONEncoder()
// swiftlint:disable:next force_try
let data = try! encoder.encode(self)
return data.databaseValue
}
public static func fromDatabaseValue(_ dbValue: DatabaseValue) -> Self? {
guard let data = Data.fromDatabaseValue(dbValue) else {
return nil
}
let decoder = JSONDecoder()
// swiftlint:disable:next force_try
return try! decoder.decode(Self.self, from: data)
}
static func == (lhs: DBRosterData, rhs: DBRosterData) -> Bool {
lhs.groups == rhs.groups && lhs.annotations == rhs.annotations
}
}
extension RosterItemAnnotation: Equatable {
public static func == (lhs: RosterItemAnnotation, rhs: RosterItemAnnotation) -> Bool {
lhs.type == rhs.type && lhs.values == rhs.values
}
}
extension Roster: Equatable {
static func == (lhs: Roster, rhs: Roster) -> Bool {
lhs.bareJid == rhs.bareJid && lhs.contactBareJid == rhs.contactBareJid
}
}
extension Roster {
mutating func setLocallyDeleted(_ value: Bool) async throws {
locallyDeleted = value
let copy = self
try? await Database.shared.dbQueue.write { db in
try copy.save(db)
}
}
}
extension Roster {
static var allDeletedLocally: [Roster] {
get async {
do {
let rosters = try await Database.shared.dbQueue.read { db in
try Roster
.filter(Column("locallyDeleted") == true)
.fetchAll(db)
}
return rosters
} catch {
return []
}
}
}
static var allActive: [Roster] {
get async {
do {
let rosters = try await Database.shared.dbQueue.read { db in
try Roster
.filter(Column("locallyDeleted") == false)
.fetchAll(db)
}
return rosters
} catch {
return []
}
}
}
}