Implements attachment previewing
This commit is contained in:
@@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user