Private
Public Access
1
0

Implements attachment previewing

This commit is contained in:
2025-08-24 23:38:35 -07:00
parent 126a4cc55f
commit f0029d02e1
9 changed files with 500 additions and 178 deletions

View File

@@ -42,26 +42,35 @@ enum Display
let id: String
let sender: Sender
let text: String
let date: Date
let attachments: [ImageAttachment]
var isFromMe: Bool {
if case .me = sender { true }
else { false }
}
var isFromMe: Bool { sender.isMe }
init(from m: Serialized.Message) {
self.id = m.guid
self.text = m.text
self.sender = if m.sender == "(Me)" {
self.date = m.date
let sender: Sender = if m.sender == "(Me)" {
.me
} else {
.counterpart(m.sender)
}
self.attachments = m.attachments.map { attachment in
ImageAttachment(from: attachment, sender: sender)
}
self.sender = sender
}
init(id: String = UUID().uuidString, sender: Sender = .me, text: String) {
init(id: String = UUID().uuidString, sender: Sender = .me, date: Date = .now, text: String) {
self.id = id
self.sender = sender
self.text = text
self.date = date
self.attachments = []
}
static func == (lhs: Message, rhs: Message) -> Bool {
@@ -71,11 +80,44 @@ enum Display
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
}
struct ImageAttachment: Identifiable
{
let id: String
let sender: Sender
let data: Serialized.Attachment
enum Sender
{
case me
case counterpart(String)
var size: CGSize? {
if let attr = data.metadata?.attributionInfo, let width = attr.width, let height = attr.height {
return CGSize(width: width, height: height)
}
return nil
}
var isPreviewDownloaded: Bool {
data.isPreviewDownloaded
}
var previewPath: String {
data.previewPath
}
init(from serialized: Serialized.Attachment, sender: Sender) {
self.id = serialized.guid
self.sender = sender
self.data = serialized
}
}
enum Sender
{
case me
case counterpart(String)
var isMe: Bool {
if case .me = self { true } else { false }
}
}
}
@@ -116,6 +158,7 @@ enum Serialized
let sender: String
let text: String
let date: Date
let attachments: [Attachment]
init?(xpc dict: xpc_object_t)
{
@@ -124,11 +167,70 @@ enum Serialized
let s: String = d["sender"] ?? ""
let t: String = d["text"] ?? ""
let dd: Date = d["date"] ?? Date(timeIntervalSince1970: 0)
let atts: [Attachment] = d["attachments"] ?? []
self.guid = g
self.sender = s
self.text = t
self.date = dd
self.attachments = atts
}
}
struct Attachment: Decodable
{
let guid: String
let path: String
let previewPath: String
let isDownloaded: Bool
let isPreviewDownloaded: Bool
let metadata: Metadata?
struct Metadata: Decodable
{
let attributionInfo: AttributionInfo?
}
struct AttributionInfo: Decodable
{
let width: Int?
let height: Int?
}
}
}
extension Serialized.Attachment: XPCConvertible
{
static func fromXPC(_ value: xpc_object_t) -> Serialized.Attachment? {
guard let d = XPCDictionary(value), let guid: String = d["guid"] else { return nil }
let path: String = d["path"] ?? ""
let previewPath: String = d["preview_path"] ?? ""
// Booleans are encoded as strings in XPC
let downloadedStr: String = d["downloaded"] ?? "false"
let previewDownloadedStr: String = d["preview_downloaded"] ?? "false"
let isDownloaded = downloadedStr == "true"
let isPreviewDownloaded = previewDownloadedStr == "true"
var metadata: Serialized.Attachment.Metadata? = nil
if let metadataObj = d.object("metadata"), let md = XPCDictionary(metadataObj) {
var attribution: Serialized.Attachment.AttributionInfo? = nil
if let attrObj = md.object("attribution_info"), let ad = XPCDictionary(attrObj) {
let width: Int? = ad["width"]
let height: Int? = ad["height"]
attribution = Serialized.Attachment.AttributionInfo(width: width, height: height)
}
metadata = Serialized.Attachment.Metadata(attributionInfo: attribution)
}
return Serialized.Attachment(
guid: guid,
path: path,
previewPath: previewPath,
isDownloaded: isDownloaded,
isPreviewDownloaded: isPreviewDownloaded,
metadata: metadata
)
}
}