diff options
| author | Christian Cleberg <[email protected]> | 2026-04-01 14:04:27 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-01 14:04:27 -0500 |
| commit | 209155dc431cf70d9c8dba20625bab7e3b1a5085 (patch) | |
| tree | 42d2c2c1b2ab0863b69bd57c9c6d2ab27fe1594c | |
| parent | e84e5543be9be548784859f4b082b9d7a3122f15 (diff) | |
| download | hutch-2.6.1.tar.gz hutch-2.6.1.tar.bz2 hutch-2.6.1.zip | |
Fix several bugs ahead of 2.6.1v2.6.1
FileTreeView: when wrap is OFF, activate an explicit width constraint on
the code container derived from the widest line, giving the horizontal
scroll view a defined content size. Previously the constraint was
deactivated with nothing to replace it, making horizontal scrolling
unreliable. Also set horizontalScrollView.isScrollEnabled = !wrapLines
to prevent gesture conflicts when wrap is ON.
InboxView: remove the unnecessary loadThreads() network call fired after
markAllThreadsRead(). The threads array is already updated optimistically
and read state is persisted via InboxReadStateStore, so the refetch was
redundant and caused a brief loading flash.
HomeView: add scenePhase onChange handler to refresh dashboard data when
the app returns to the foreground, matching the existing pattern in
InboxView.
DiffView: wrap DiffBlockView content in a horizontal ScrollView so long
diff lines are readable. Switch inner VStack to LazyVStack for better
performance on large diffs.
SettingsView: replace direct UserDefaults access in behaviorSection with
@AppStorage, consistent with the rest of the app.
| -rw-r--r-- | Hutch/Views/Home/HomeView.swift | 7 | ||||
| -rw-r--r-- | Hutch/Views/Inbox/InboxView.swift | 3 | ||||
| -rw-r--r-- | Hutch/Views/Repositories/DiffView.swift | 10 | ||||
| -rw-r--r-- | Hutch/Views/Repositories/FileTreeView.swift | 18 | ||||
| -rw-r--r-- | Hutch/Views/Settings/SettingsView.swift | 11 |
5 files changed, 32 insertions, 17 deletions
diff --git a/Hutch/Views/Home/HomeView.swift b/Hutch/Views/Home/HomeView.swift index 35e8f7c..f9d3de5 100644 --- a/Hutch/Views/Home/HomeView.swift +++ b/Hutch/Views/Home/HomeView.swift @@ -3,6 +3,7 @@ import SwiftUI struct HomeView: View { @AppStorage(AppStorageKeys.swipeActionsEnabled) private var swipeActionsEnabled = true @Environment(AppState.self) private var appState + @Environment(\.scenePhase) private var scenePhase @State private var viewModel: HomeViewModel? private let previewLimit = 4 private let projectPreviewLimit = 3 @@ -39,6 +40,12 @@ struct HomeView: View { await vm.loadDashboard() } + .onChange(of: scenePhase) { _, newPhase in + guard newPhase == .active, let viewModel else { return } + Task { + await viewModel.loadDashboard() + } + } } @ViewBuilder diff --git a/Hutch/Views/Inbox/InboxView.swift b/Hutch/Views/Inbox/InboxView.swift index 6ca66ac..aa3765c 100644 --- a/Hutch/Views/Inbox/InboxView.swift +++ b/Hutch/Views/Inbox/InboxView.swift @@ -70,9 +70,6 @@ struct InboxView: View { withAnimation(.easeInOut(duration: 0.2)) { viewModel.markAllThreadsRead() } - Task { - await viewModel.loadThreads() - } } } } diff --git a/Hutch/Views/Repositories/DiffView.swift b/Hutch/Views/Repositories/DiffView.swift index 4b8e512..a370dfb 100644 --- a/Hutch/Views/Repositories/DiffView.swift +++ b/Hutch/Views/Repositories/DiffView.swift @@ -76,13 +76,15 @@ private struct DiffBlockView: View { let lines: [String] var body: some View { - VStack(alignment: .leading, spacing: 0) { - ForEach(Array(lines.enumerated()), id: \.offset) { _, line in - DiffLineView(line: line) + ScrollView(.horizontal, showsIndicators: false) { + LazyVStack(alignment: .leading, spacing: 0) { + ForEach(Array(lines.enumerated()), id: \.offset) { _, line in + DiffLineView(line: line) + } } + .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading) } .font(.system(.caption, design: .monospaced)) - .frame(maxWidth: .infinity, alignment: .leading) .background(Color(.secondarySystemBackground)) } } diff --git a/Hutch/Views/Repositories/FileTreeView.swift b/Hutch/Views/Repositories/FileTreeView.swift index 8bedb73..adacb2e 100644 --- a/Hutch/Views/Repositories/FileTreeView.swift +++ b/Hutch/Views/Repositories/FileTreeView.swift @@ -441,6 +441,7 @@ private final class CodeFileUIView: UIView { private let codeStackView = UIStackView() private var codeContainerWidthConstraint: NSLayoutConstraint? + private var codeContainerExplicitWidthConstraint: NSLayoutConstraint? private var gutterWidthConstraint: NSLayoutConstraint? private var rows: [LineRow] = [] @@ -524,6 +525,7 @@ private final class CodeFileUIView: UIView { codeContainerView.addSubview(codeStackView) codeContainerWidthConstraint = codeContainerView.widthAnchor.constraint(equalTo: horizontalScrollView.frameLayoutGuide.widthAnchor) + codeContainerExplicitWidthConstraint = codeContainerView.widthAnchor.constraint(equalToConstant: 0) gutterWidthConstraint = gutterContainerView.widthAnchor.constraint(equalToConstant: 0) NSLayoutConstraint.activate([ @@ -627,12 +629,14 @@ private final class CodeFileUIView: UIView { private func updateWrapConfiguration(resetHorizontalOffset: Bool) { horizontalScrollView.alwaysBounceHorizontal = !wrapLines - horizontalScrollView.isScrollEnabled = true + horizontalScrollView.isScrollEnabled = !wrapLines if wrapLines { codeContainerWidthConstraint?.isActive = true + codeContainerExplicitWidthConstraint?.isActive = false } else { codeContainerWidthConstraint?.isActive = false + codeContainerExplicitWidthConstraint?.isActive = true } for row in rows { @@ -664,6 +668,18 @@ private final class CodeFileUIView: UIView { row.codeHeightConstraint.constant = rowHeight } + if wrapLines { + codeContainerExplicitWidthConstraint?.constant = 0 + } else { + let maxLineWidth = rows.reduce(CGFloat(0)) { partialResult, row in + let measuredWidth = row.codeLabel.sizeThatFits( + CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude) + ).width + return max(partialResult, ceil(measuredWidth)) + } + codeContainerExplicitWidthConstraint?.constant = max(maxLineWidth, availableWidth) + } + needsLineLayoutUpdate = false } diff --git a/Hutch/Views/Settings/SettingsView.swift b/Hutch/Views/Settings/SettingsView.swift index e90f4e3..237c076 100644 --- a/Hutch/Views/Settings/SettingsView.swift +++ b/Hutch/Views/Settings/SettingsView.swift @@ -8,6 +8,7 @@ private let settingsBioMarkdownOptions = AttributedString.MarkdownParsingOptions struct SettingsView: View { @Environment(AppState.self) private var appState @Environment(\.colorScheme) private var colorScheme + @AppStorage(AppStorageKeys.swipeActionsEnabled) private var swipeActionsEnabled = true @State private var viewModel: SettingsViewModel? @State private var pendingDestructiveAction: SettingsDestructiveAction? @@ -389,15 +390,7 @@ struct SettingsView: View { @ViewBuilder private func behaviorSection() -> some View { Section { - Toggle( - "Swipe actions", - isOn: Binding( - get: { - UserDefaults.standard.object(forKey: AppStorageKeys.swipeActionsEnabled) as? Bool ?? true - }, - set: { UserDefaults.standard.set($0, forKey: AppStorageKeys.swipeActionsEnabled) } - ) - ) + Toggle("Swipe actions", isOn: $swipeActionsEnabled) } header: { Text("Behavior") } footer: { |
