diff options
| author | Dustin Mierau <dustin@mierau.me> | 2025-10-24 23:02:12 -0700 |
|---|---|---|
| committer | Dustin Mierau <dustin@mierau.me> | 2025-10-24 23:02:12 -0700 |
| commit | fefede829c12d9f69db72d70231291d973b0c1a2 (patch) | |
| tree | e51caa817df6fb00063c5179ff0a8a77753a21ae /Hotline | |
| parent | cf113ea053334175b93770b025c1f7d22eda6eab (diff) | |
Further polish on chat. Try not to persist back to back disconnect messages.
Diffstat (limited to 'Hotline')
| -rw-r--r-- | Hotline/Models/ChatMessage.swift | 5 | ||||
| -rw-r--r-- | Hotline/Models/Hotline.swift | 14 | ||||
| -rw-r--r-- | Hotline/iOS/ChatView.swift | 11 | ||||
| -rw-r--r-- | Hotline/macOS/ChatView.swift | 97 |
4 files changed, 47 insertions, 80 deletions
diff --git a/Hotline/Models/ChatMessage.swift b/Hotline/Models/ChatMessage.swift index 365f91f..744a5d2 100644 --- a/Hotline/Models/ChatMessage.swift +++ b/Hotline/Models/ChatMessage.swift @@ -2,7 +2,6 @@ import SwiftUI enum ChatMessageType { case agreement - case status case joined case left case message @@ -15,8 +14,6 @@ extension ChatMessageType { switch self { case .agreement: return "agreement" - case .status: - return "status" case .joined: return "joined" case .left: @@ -34,8 +31,6 @@ extension ChatMessageType { switch storageKey { case "agreement": self = .agreement - case "status": - self = .status case "joined": self = .joined case "left": diff --git a/Hotline/Models/Hotline.swift b/Hotline/Models/Hotline.swift index 8cdeccd..08b79a1 100644 --- a/Hotline/Models/Hotline.swift +++ b/Hotline/Models/Hotline.swift @@ -196,6 +196,7 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega @ObservationIgnored private var chatSessionKey: ChatStore.SessionKey? @ObservationIgnored private var restoredChatSessionKey: ChatStore.SessionKey? @ObservationIgnored private var chatHistoryObserver: NSObjectProtocol? + @ObservationIgnored private var lastPersistedMessageType: ChatMessageType? #if os(macOS) var bannerImage: NSImage? = nil #elseif os(iOS) @@ -244,6 +245,7 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega let key = sessionKey(for: server) self.chatSessionKey = key self.restoredChatSessionKey = nil + self.lastPersistedMessageType = nil self.chat = [] self.restoreChatHistory(for: key) @@ -1132,6 +1134,7 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega self.chatSessionKey = nil self.restoredChatSessionKey = nil + self.lastPersistedMessageType = nil } else if status == .loggedIn { if Prefs.shared.playSounds && Prefs.shared.playLoggedInSound { @@ -1395,12 +1398,19 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega } private func recordChatMessage(_ message: ChatMessage, persist: Bool = true, display: Bool = true) { + let shouldPersist = persist && message.type != .agreement + if shouldPersist, + message.type == .signOut, + lastPersistedMessageType == .signOut { + return + } + if display { self.chat.append(message) } - let shouldPersist = persist && message.type != .agreement guard shouldPersist, let key = chatSessionKey else { return } + self.lastPersistedMessageType = message.type let entry = ChatStore.Entry( id: message.id, body: message.text, @@ -1438,6 +1448,7 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega return ChatMessage(text: renderedText, type: chatType, date: entry.date) } self.chat = historyMessages + currentMessages + self.lastPersistedMessageType = historyMessages.last?.type self.unreadPublicChat = false self.restoredChatSessionKey = key } @@ -1448,6 +1459,7 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileDownloadClientDelega self.chat = [] self.unreadPublicChat = false self.restoredChatSessionKey = nil + self.lastPersistedMessageType = nil } func updateServerTitle() { diff --git a/Hotline/iOS/ChatView.swift b/Hotline/iOS/ChatView.swift index 0ad41e0..e320dbf 100644 --- a/Hotline/iOS/ChatView.swift +++ b/Hotline/iOS/ChatView.swift @@ -52,17 +52,6 @@ struct ChatView: View { .frame(maxWidth: .infinity) .padding() } - else if msg.type == .status { - HStack { - Spacer() - Text(msg.text) - .lineLimit(1) - .truncationMode(.middle) - .opacity(0.3) - Spacer() - } - .padding() - } else if msg.type == .signOut { HStack { Spacer() diff --git a/Hotline/macOS/ChatView.swift b/Hotline/macOS/ChatView.swift index 12e6c94..a45e7ed 100644 --- a/Hotline/macOS/ChatView.swift +++ b/Hotline/macOS/ChatView.swift @@ -4,35 +4,11 @@ enum FocusedField: Int, Hashable { case chatInput } -struct ChatStatusMessageView: View { - let message: ChatMessage - - var body: some View { - HStack(alignment: .center, spacing: 8) { - Image(systemName: "arrow.right") - .resizable() - .scaledToFit() - .fontWeight(.semibold) - .foregroundStyle(.primary) - .frame(width: 14, height: 14) - - Text(message.text) - .lineLimit(1) - .truncationMode(.middle) - .textSelection(.disabled) - - Spacer() - } - .opacity(0.3) - } -} - - struct ChatJoinedMessageView: View { let message: ChatMessage var body: some View { - HStack(alignment: .center, spacing: 8) { + HStack(alignment: .center, spacing: 4) { Image(systemName: "arrow.right") .resizable() .scaledToFit() @@ -56,7 +32,7 @@ struct ChatLeftMessageView: View { let message: ChatMessage var body: some View { - HStack(alignment: .center, spacing: 8) { + HStack(alignment: .center, spacing: 4) { Image(systemName: "arrow.left") .resizable() .scaledToFit() @@ -206,14 +182,9 @@ struct ChatView: View { } .padding(.vertical, 24) } - // MARK: Server Message else if msg.type == .server { ServerMessageView(message: msg.text) } - // MARK: Status - else if msg.type == .status { - ChatStatusMessageView(message: msg) - } else if msg.type == .joined { ChatJoinedMessageView(message: msg) } @@ -313,38 +284,38 @@ struct ChatView: View { } } - private func prepareChatDocument() -> Bool { - var text: String = String() - - self.chatDocument.text = "" - for msg in model.chat { - if msg.type == .agreement { - text.append(msg.text) - text.append("\n\n") - } - else if msg.type == .message { - if let username = msg.username { - text.append("\(username): \(msg.text)") - } - else { - text.append(msg.text) - } - text.append("\n") - } - else if msg.type == .status { - text.append(msg.text) - text.append("\n") - } - } - - if text.isEmpty { - return false - } - - self.chatDocument.text = text - - return true - } +// private func prepareChatDocument() -> Bool { +// var text: String = String() +// +// self.chatDocument.text = "" +// for msg in model.chat { +// if msg.type == .agreement { +// text.append(msg.text) +// text.append("\n\n") +// } +// else if msg.type == .message { +// if let username = msg.username { +// text.append("\(username): \(msg.text)") +// } +// else { +// text.append(msg.text) +// } +// text.append("\n") +// } +// else if msg.type == .status { +// text.append(msg.text) +// text.append("\n") +// } +// } +// +// if text.isEmpty { +// return false +// } +// +// self.chatDocument.text = text +// +// return true +// } } #Preview { |