Message Edited icon

This commit is contained in:
Djorkaeff Alexandre 2024-02-23 14:10:31 -03:00
parent 591da320ed
commit bf812c0220
7 changed files with 58 additions and 32 deletions

View File

@ -1,12 +1,16 @@
import Foundation import Foundation
struct AttachmentResponse: Codable, Hashable { struct AttachmentResponse: Codable, Hashable {
let title: String?
let imageURL: URL? let imageURL: URL?
let audioURL: URL?
let description: String? let description: String?
let dimensions: Dimensions? let dimensions: Dimensions?
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case imageURL = "image_url" case imageURL = "image_url"
case audioURL = "audio_url"
case title
case description case description
case dimensions = "image_dimensions" case dimensions = "image_dimensions"
} }

View File

@ -9,4 +9,5 @@ struct MessageResponse: Codable, Hashable {
let attachments: [AttachmentResponse]? let attachments: [AttachmentResponse]?
let t: String? let t: String?
let groupable: Bool? let groupable: Bool?
let editedAt: Date?
} }

View File

@ -2,12 +2,14 @@
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22222" systemVersion="22G120" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithSwiftData="YES" userDefinedModelVersionIdentifier=""> <model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="22222" systemVersion="22G120" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithSwiftData="YES" userDefinedModelVersionIdentifier="">
<entity name="Attachment" representedClassName="Attachment" syncable="YES" codeGenerationType="class"> <entity name="Attachment" representedClassName="Attachment" syncable="YES" codeGenerationType="class">
<attribute name="height" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/> <attribute name="height" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
<attribute name="id" optional="YES" attributeType="String"/>
<attribute name="imageURL" optional="YES" attributeType="URI"/> <attribute name="imageURL" optional="YES" attributeType="URI"/>
<attribute name="msg" optional="YES" attributeType="String"/> <attribute name="msg" optional="YES" attributeType="String"/>
<attribute name="width" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/> <attribute name="width" optional="YES" attributeType="Double" defaultValueString="0.0" usesScalarValueType="YES"/>
<relationship name="message" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Message" inverseName="attachments" inverseEntity="Message"/> <relationship name="message" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Message" inverseName="attachments" inverseEntity="Message"/>
</entity> </entity>
<entity name="Message" representedClassName="Message" syncable="YES" codeGenerationType="class"> <entity name="Message" representedClassName="Message" syncable="YES" codeGenerationType="class">
<attribute name="editedAt" optional="YES" attributeType="Date" usesScalarValueType="NO"/>
<attribute name="groupable" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/> <attribute name="groupable" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="id" optional="YES" attributeType="String"/> <attribute name="id" optional="YES" attributeType="String"/>
<attribute name="msg" optional="YES" attributeType="String"/> <attribute name="msg" optional="YES" attributeType="String"/>

View File

@ -80,9 +80,9 @@ final class RocketChatDatabase: Database {
return message return message
} }
func createAttachment(url: String) -> Attachment { func createAttachment(identifier: String) -> Attachment {
let attachment = Attachment(context: viewContext) let attachment = Attachment(context: viewContext)
attachment.imageURL = URL(string: url) attachment.id = identifier
return attachment return attachment
} }
@ -140,9 +140,9 @@ final class RocketChatDatabase: Database {
return try? viewContext.fetch(request).first return try? viewContext.fetch(request).first
} }
func attachment(url: String) -> Attachment? { func attachment(identifier: String) -> Attachment? {
let request = Attachment.fetchRequest() let request = Attachment.fetchRequest()
request.predicate = NSPredicate(format: "imageURL == %@", url) request.predicate = NSPredicate(format: "id == %@", identifier)
return try? viewContext.fetch(request).first return try? viewContext.fetch(request).first
} }
@ -169,6 +169,7 @@ final class RocketChatDatabase: Database {
message.user = user message.user = user
message.t = updatedMessage.t message.t = updatedMessage.t
message.groupable = updatedMessage.groupable ?? true message.groupable = updatedMessage.groupable ?? true
message.editedAt = updatedMessage.editedAt
updatedMessage.attachments?.forEach { attachment in updatedMessage.attachments?.forEach { attachment in
process(updatedAttachment: attachment, in: message) process(updatedAttachment: attachment, in: message)
@ -178,11 +179,13 @@ final class RocketChatDatabase: Database {
} }
func process(updatedAttachment: AttachmentResponse, in message: Message) { func process(updatedAttachment: AttachmentResponse, in message: Message) {
guard let url = updatedAttachment.imageURL?.absoluteString else { let identifier = updatedAttachment.imageURL ?? updatedAttachment.audioURL
guard let identifier = identifier?.absoluteString ?? updatedAttachment.title else {
return return
} }
let attachment = attachment(url: url) ?? createAttachment(url: url) let attachment = attachment(identifier: identifier) ?? createAttachment(identifier: identifier)
attachment.msg = updatedAttachment.description attachment.msg = updatedAttachment.description
attachment.message = message attachment.message = message

View File

@ -1,6 +1,9 @@
{ {
"sourceLanguage" : "en", "sourceLanguage" : "en",
"strings" : { "strings" : {
"Attachment not supported." : {
},
"Delete" : { "Delete" : {
}, },

View File

@ -1,36 +1,38 @@
import SwiftUI import SwiftUI
struct AttachmentView: View { struct AttachmentView: View {
private let attachment: Attachment @Dependency private var client: RocketChatClientProtocol
private let client: RocketChatClientProtocol
init(attachment: Attachment, client: RocketChatClientProtocol) { private let attachment: Attachment
init(attachment: Attachment) {
self.attachment = attachment self.attachment = attachment
self.client = client
} }
var body: some View { var body: some View {
if let rawURL = attachment.imageURL { VStack(alignment: .leading) {
VStack(alignment: .leading) { if let msg = attachment.msg {
if let msg = attachment.msg { Text(msg)
Text(msg) .font(.caption)
.font(.caption) .foregroundStyle(.white)
.foregroundStyle(.white) }
} if let rawURL = attachment.imageURL {
AsyncImage(url: client.authorizedURL(url: rawURL)) { image in AsyncImage(url: client.authorizedURL(url: rawURL)) { image in
image image
.resizable() .resizable()
.scaledToFit() .scaledToFit()
} placeholder: { } placeholder: {
Rectangle() Rectangle()
.foregroundStyle(.secondary) .foregroundStyle(.secondary)
.aspectRatio(attachment.aspectRatio, contentMode: .fit) .aspectRatio(attachment.aspectRatio, contentMode: .fit)
.overlay(ProgressView()) .overlay(ProgressView())
} }
.cornerRadius(4) .cornerRadius(4)
} else {
Text("Attachment not supported.")
.font(.caption.italic())
.foregroundStyle(.primary)
} }
} else {
EmptyView()
} }
} }
} }

View File

@ -70,6 +70,11 @@ struct MessageView: View {
.lineLimit(1) .lineLimit(1)
.font(.footnote) .font(.footnote)
.foregroundStyle(.secondary) .foregroundStyle(.secondary)
if viewModel.message.editedAt != nil {
Image(systemName: "pencil")
.font(.caption)
.foregroundStyle(.secondary)
}
} }
} }
if let text = viewModel.info { if let text = viewModel.info {
@ -77,7 +82,7 @@ struct MessageView: View {
.font(.caption.italic()) .font(.caption.italic())
.foregroundStyle(.primary) .foregroundStyle(.primary)
} else if let text = viewModel.message.msg { } else if let text = viewModel.message.msg {
HStack { HStack(alignment: .top) {
Text(text) Text(text)
.font(.caption) .font(.caption)
.foregroundStyle(viewModel.message.status == "temp" ? .secondary : .primary) .foregroundStyle(viewModel.message.status == "temp" ? .secondary : .primary)
@ -95,11 +100,17 @@ struct MessageView: View {
) )
.buttonStyle(PlainButtonStyle()) .buttonStyle(PlainButtonStyle())
} }
if viewModel.message.editedAt != nil && !viewModel.isHeader {
Image(systemName: "pencil")
.font(.caption)
.foregroundStyle(.secondary)
}
} }
} }
if let attachments = viewModel.message.attachments?.allObjects as? Array<Attachment> { if let attachments = viewModel.message.attachments?.allObjects as? Array<Attachment> {
ForEach(attachments) { attachment in ForEach(attachments) { attachment in
AttachmentView(attachment: attachment, client: client) AttachmentView(attachment: attachment)
} }
} }
} }