diff options
| author | Christian Cleberg <[email protected]> | 2026-03-19 16:59:16 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-03-19 16:59:16 -0500 |
| commit | b82bbeeea48ad27832a355c2a41408559c411104 (patch) | |
| tree | 0af45101300c75970471573b09f878a1b3763b38 /Hutch/Views/Inbox | |
| parent | 9065ef6e92245a44390e336cc1ae515ae706cdd7 (diff) | |
| download | hutch-b82bbeeea48ad27832a355c2a41408559c411104.tar.gz hutch-b82bbeeea48ad27832a355c2a41408559c411104.tar.bz2 hutch-b82bbeeea48ad27832a355c2a41408559c411104.zip | |
v2.1: bundled polish and fixes
Diffstat (limited to 'Hutch/Views/Inbox')
| -rw-r--r-- | Hutch/Views/Inbox/InboxView.swift | 15 | ||||
| -rw-r--r-- | Hutch/Views/Inbox/InboxViewModel.swift | 17 | ||||
| -rw-r--r-- | Hutch/Views/Inbox/ThreadDetailView.swift | 14 | ||||
| -rw-r--r-- | Hutch/Views/Inbox/ThreadViewModel.swift | 47 |
4 files changed, 11 insertions, 82 deletions
diff --git a/Hutch/Views/Inbox/InboxView.swift b/Hutch/Views/Inbox/InboxView.swift index 2b92738..74f78d5 100644 --- a/Hutch/Views/Inbox/InboxView.swift +++ b/Hutch/Views/Inbox/InboxView.swift @@ -1,7 +1,4 @@ import SwiftUI -import os - -private let inboxNavigationLogger = Logger(subsystem: "net.cleberg.Hutch", category: "InboxNavigation") struct InboxView: View { @Environment(AppState.self) private var appState @@ -101,9 +98,6 @@ struct InboxView: View { systemImage: "tray", description: Text("This thread could not be restored.") ) - .onAppear { - inboxNavigationLogger.error("Inbox navigation destination missing thread snapshot") - } } } } @@ -123,9 +117,6 @@ struct InboxView: View { private func selectThread(_ thread: InboxThreadSummary) { cacheSelectedThread(thread) isShowingThreadDetail = true - inboxNavigationLogger.debug( - "Inbox navigation triggered: threadID=\(thread.id, privacy: .public) subject=\(thread.subject, privacy: .public)" - ) } private func cacheSelectedThread(_ thread: InboxThreadSummary) { @@ -140,9 +131,6 @@ struct InboxView: View { private func handleThreadDetailDisappear(for threadID: String) { let isActiveSelection = selectedThreadID == threadID - inboxNavigationLogger.debug( - "Inbox thread detail disappeared: threadID=\(threadID, privacy: .public) activeSelection=\(isActiveSelection, privacy: .public)" - ) guard isActiveSelection else { return } clearSelection() } @@ -154,9 +142,6 @@ struct InboxView: View { } private func clearSelection() { - if let selectedThreadID { - inboxNavigationLogger.debug("Inbox selection cleared: threadID=\(selectedThreadID, privacy: .public)") - } selectedThreadID = nil selectedThreadSnapshot = nil isShowingThreadDetail = false diff --git a/Hutch/Views/Inbox/InboxViewModel.swift b/Hutch/Views/Inbox/InboxViewModel.swift index e4a0664..00d47b5 100644 --- a/Hutch/Views/Inbox/InboxViewModel.swift +++ b/Hutch/Views/Inbox/InboxViewModel.swift @@ -136,7 +136,7 @@ final class InboxViewModel { return lhs.lastActivityAt > rhs.lastActivityAt } } catch { - inboxListLogger.error("Inbox request failed: type=inbox error=\(error.localizedDescription, privacy: .public)") + inboxListLogger.error("Inbox request failed") self.error = "Failed to load inbox" } } @@ -144,17 +144,11 @@ final class InboxViewModel { func markThreadRead(_ thread: InboxThreadSummary) { let viewedAt = max(Date(), thread.lastActivityAt) InboxReadStateStore.markViewed(viewedAt, for: thread.id) - inboxListLogger.debug( - "Inbox mark read: key=\(thread.id, privacy: .public) latestActivityAt=\(thread.lastActivityAt.ISO8601Format(), privacy: .public) storedLastViewedAt=\(viewedAt.ISO8601Format(), privacy: .public)" - ) threads.removeAll { $0.id == thread.id } } func markThreadUnread(_ thread: InboxThreadSummary) { InboxReadStateStore.markUnread(for: thread.id) - inboxListLogger.debug( - "Inbox mark unread: key=\(thread.id, privacy: .public) latestActivityAt=\(thread.lastActivityAt.ISO8601Format(), privacy: .public) storedLastViewedAt=nil" - ) updateThread(thread, isUnread: true) } @@ -237,7 +231,7 @@ final class InboxViewModel { summaries.append(contentsOf: batchResult.0) failureMessages.append(contentsOf: batchResult.1) for failure in batchResult.1 { - inboxListLogger.error("Inbox request failed: type=listThreads \(failure, privacy: .public)") + inboxListLogger.error("Inbox thread list request failed: \(failure, privacy: .private)") } startIndex = endIndex } @@ -259,14 +253,7 @@ final class InboxViewModel { return response.list.threads.results.prefix(listThreadFetchLimit).map { thread in let groupingKey = "\(mailingList.rid)#\(thread.subject.replacingOccurrences(of: #"\s+"#, with: " ", options: .regularExpression).trimmingCharacters(in: .whitespacesAndNewlines).replacingOccurrences(of: #"^(?:(?:re|fwd?)\s*:\s*)+"#, with: "", options: [.regularExpression, .caseInsensitive]).lowercased())" - let lastViewedAt = InboxReadStateStore.lastViewedAt(for: groupingKey) let isUnread = InboxReadStateStore.isUnread(threadID: groupingKey, lastActivityAt: thread.updated) - inboxListLogger.debug( - "Inbox thread grouping candidate: listRID=\(mailingList.rid, privacy: .public) rootMessageID=\(thread.root.messageID, privacy: .public) rootEmailID=\(thread.root.id, privacy: .public) groupingKey=\(groupingKey, privacy: .public)" - ) - inboxListLogger.debug( - "Inbox unread state: key=\(groupingKey, privacy: .public) latestActivityAt=\(thread.updated.ISO8601Format(), privacy: .public) lastViewedAt=\(lastViewedAt?.ISO8601Format() ?? "nil", privacy: .public) isUnread=\(isUnread, privacy: .public)" - ) return InboxThreadSummary( rootEmailID: thread.root.id, rootMessageID: thread.root.messageID, diff --git a/Hutch/Views/Inbox/ThreadDetailView.swift b/Hutch/Views/Inbox/ThreadDetailView.swift index c5d26a5..e4c34e7 100644 --- a/Hutch/Views/Inbox/ThreadDetailView.swift +++ b/Hutch/Views/Inbox/ThreadDetailView.swift @@ -4,7 +4,6 @@ import SwiftUI import UIKit private let inboxReplyLogger = Logger(subsystem: "net.cleberg.Hutch", category: "InboxReply") -private let inboxThreadNavigationLogger = Logger(subsystem: "net.cleberg.Hutch", category: "InboxThreadNavigation") struct ThreadDetailView: View { let thread: InboxThreadSummary @@ -53,18 +52,12 @@ struct ThreadDetailView: View { isUnread = thread.isUnread await vm.loadThread() } - .onAppear { - inboxThreadNavigationLogger.debug("Inbox thread detail appeared: threadID=\(thread.id, privacy: .public)") - } .onChange(of: viewModel?.thread?.id) { _, threadID in guard threadID != nil, !hasMarkedCurrentThreadViewed, !suppressAutoMarkViewed else { return } hasMarkedCurrentThreadViewed = true isUnread = false onViewed() } - .onDisappear { - inboxThreadNavigationLogger.debug("Inbox thread detail view disappeared: threadID=\(thread.id, privacy: .public)") - } .sheet(item: Binding( get: { viewModel?.composeDraft }, set: { _ in viewModel?.dismissReply() } @@ -72,14 +65,13 @@ struct ThreadDetailView: View { MailComposeView(draft: draft) { result in switch result { case .failed(let message): - inboxReplyLogger.error("Inbox reply failed for thread \(thread.debugIdentifierSummary, privacy: .public): \(message, privacy: .public)") + inboxReplyLogger.error("Inbox reply failed") viewModel?.error = message case .cancelled: - inboxReplyLogger.debug("Inbox reply cancelled for thread \(thread.debugIdentifierSummary, privacy: .public)") + break case .saved: - inboxReplyLogger.debug("Inbox reply draft saved for thread \(thread.debugIdentifierSummary, privacy: .public)") + break case .sent: - inboxReplyLogger.debug("Inbox reply handed off to Mail for thread \(thread.debugIdentifierSummary, privacy: .public)") replySuccessMessage = "Reply handed off to Mail." Task { await viewModel?.loadThread() diff --git a/Hutch/Views/Inbox/ThreadViewModel.swift b/Hutch/Views/Inbox/ThreadViewModel.swift index c042fba..6b70a41 100644 --- a/Hutch/Views/Inbox/ThreadViewModel.swift +++ b/Hutch/Views/Inbox/ThreadViewModel.swift @@ -172,8 +172,6 @@ final class ThreadViewModel { partialWarning = nil defer { isLoading = false } - inboxLogger.debug("Opening inbox thread: \(self.summary.debugIdentifierSummary, privacy: .public)") - do { let threadPayloads = try await fetchThreadPayloads() @@ -207,9 +205,7 @@ final class ThreadViewModel { } } catch { hadPartialReplyFailure = true - inboxLogger.error( - "Inbox thread descendants failed for \(self.summary.debugIdentifierSummary, privacy: .public): \(error.localizedDescription, privacy: .public)" - ) + inboxLogger.error("Inbox thread descendants failed") } } @@ -241,9 +237,9 @@ final class ThreadViewModel { if thread == nil { self.error = "Failed to load thread" } else { - self.error = error.localizedDescription + self.error = error.userFacingMessage } - inboxLogger.error("Inbox thread detail failed for \(self.summary.debugIdentifierSummary, privacy: .public): \(error.localizedDescription, privacy: .public)") + inboxLogger.error("Inbox thread detail failed") } } @@ -275,17 +271,9 @@ final class ThreadViewModel { private func fetchThreadByMessageID(rootMessageID: String) async throws -> InboxThreadPayloadDetail? { let candidateMessageIDs = Self.messageIDCandidates(from: rootMessageID) - inboxLogger.debug( - "Inbox thread lookup IDs: subject=\(self.summary.subject, privacy: .public) rootEmailID=\(self.summary.rootEmailID, privacy: .public) rootMessageID=\(rootMessageID, privacy: .public) candidates=\(candidateMessageIDs.joined(separator: ", "), privacy: .public)" - ) - var lastLookupError: Error? for messageID in candidateMessageIDs { - inboxLogger.debug( - "Inbox thread detail lookup request: rid=\(self.summary.listRID, privacy: .public) messageID=\(messageID, privacy: .public)" - ) - do { let response: InboxThreadLookupResponse = try await Self.executeGraphQLRequest( client: client, @@ -303,10 +291,6 @@ final class ThreadViewModel { } catch let error as SRHTError { switch error { case .graphQLErrors(let errors): - let combinedMessage = errors.map(\.message).joined(separator: " | ") - inboxLogger.error( - "Inbox thread message lookup failed: rid=\(self.summary.listRID, privacy: .public) messageID=\(messageID, privacy: .public) errors=\(combinedMessage, privacy: .public)" - ) if errors.allSatisfy({ $0.message.localizedCaseInsensitiveContains("no rows in result set") }) { lastLookupError = error continue @@ -318,11 +302,7 @@ final class ThreadViewModel { } } - if let lastLookupError { - inboxLogger.debug( - "Inbox thread message lookup exhausted candidates for \(self.summary.debugIdentifierSummary, privacy: .public): \(lastLookupError.localizedDescription, privacy: .public)" - ) - } + _ = lastLookupError return nil } @@ -348,7 +328,7 @@ final class ThreadViewModel { ) } catch { if Self.isRecoverableNoRows(error) { - inboxLogger.error("Inbox thread page scan recoverable miss for \(self.summary.debugIdentifierSummary, privacy: .public): \(error.localizedDescription, privacy: .public)") + inboxLogger.error("Inbox thread page scan missed a recoverable result") return nil } throw error @@ -358,11 +338,6 @@ final class ThreadViewModel { return nil } - let candidates = threadPage.results.map { payload in - "subject=\(payload.subject ?? "<nil>") rootEmailID=\(payload.root?.id.map(String.init) ?? "<nil>") rootMessageID=\(payload.root?.messageID ?? "<nil>")" - }.joined(separator: " | ") - inboxLogger.debug("Inbox thread detail page candidates: \(candidates, privacy: .public)") - if let matchedThread = threadPage.results.first(where: { $0.root?.messageID == targetRootMessageID || $0.root?.id == summary.rootEmailID || @@ -428,9 +403,7 @@ final class ThreadViewModel { ) } catch { if Self.isRecoverableNoRows(error) { - inboxLogger.error( - "Inbox descendant page recoverable miss: thread=\(self.summary.debugIdentifierSummary, privacy: .public) messageID=\(messageID, privacy: .public) error=\(error.localizedDescription, privacy: .public)" - ) + inboxLogger.error("Inbox descendant page missed a recoverable result") continue } throw error @@ -449,9 +422,6 @@ final class ThreadViewModel { error = "This thread is not ready to reply to yet." return } - inboxLogger.debug( - "Preparing inbox reply: subject=\(thread.subject, privacy: .public) listRID=\(thread.listRID, privacy: .public) rootMessageID=\(thread.rootMessageID, privacy: .public) recipient=\(thread.replyRecipient, privacy: .public) senderIdentity=system-mail-account" - ) composeDraft = MailComposeDraft( recipients: [thread.replyRecipient], ccRecipients: [], @@ -732,11 +702,6 @@ final class ThreadViewModel { ) let (data, _) = try await URLSession.shared.data(for: request) - #if DEBUG - let responseBody = String(data: data, encoding: .utf8) ?? "<non-utf8 response>" - inboxLogger.debug("Inbox thread raw GraphQL response: \(responseBody, privacy: .public)") - #endif - let decoder = JSONDecoder() decoder.dateDecodingStrategy = .srhtFlexible let envelope = try decoder.decode(GraphQLResponse<T>.self, from: data) |
