summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-04-01 14:04:27 -0500
committerChristian Cleberg <[email protected]>2026-04-01 14:04:27 -0500
commit209155dc431cf70d9c8dba20625bab7e3b1a5085 (patch)
tree42d2c2c1b2ab0863b69bd57c9c6d2ab27fe1594c
parente84e5543be9be548784859f4b082b9d7a3122f15 (diff)
downloadhutch-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.swift7
-rw-r--r--Hutch/Views/Inbox/InboxView.swift3
-rw-r--r--Hutch/Views/Repositories/DiffView.swift10
-rw-r--r--Hutch/Views/Repositories/FileTreeView.swift18
-rw-r--r--Hutch/Views/Settings/SettingsView.swift11
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: {