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
|
|
|
|
}
|
|
|
|
}
|
2024-08-11 00:28:01 +00:00
|
|
|
|
|
|
|
extension Roster {
|
2024-08-11 17:07:02 +00:00
|
|
|
mutating func setLocallyDeleted(_ value: Bool) async throws {
|
|
|
|
locallyDeleted = value
|
|
|
|
let copy = self
|
|
|
|
try? await Database.shared.dbQueue.write { db in
|
|
|
|
try copy.save(db)
|
2024-08-11 00:28:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-11 21:52:01 +00:00
|
|
|
|
|
|
|
extension Roster {
|
2024-08-18 16:27:18 +00:00
|
|
|
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 []
|
|
|
|
}
|
2024-08-11 21:52:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|