Skip to content

Commit 9e8b3b3

Browse files
rvanbaalenclaude
andauthored
fix: markdown rendering and focus issues (#34)
- Convert ### headings to bold text for proper AttributedString rendering - Add focus management to move focus to download button when popup appears - Disable hit testing and focusability on background when popup is shown Co-authored-by: Claude <noreply@anthropic.com>
1 parent 87887e4 commit 9e8b3b3

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

SpreadPaper/SpreadPaperApp.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ struct SpreadPaperApp: App {
1717
var body: some Scene {
1818
WindowGroup {
1919
ContentView()
20+
.allowsHitTesting(!showUpdatePopup)
21+
.focusable(!showUpdatePopup)
2022
.overlay {
2123
if showUpdatePopup {
2224
updatePopupOverlay

SpreadPaper/UpdatePopupView.swift

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import AppKit
1111
struct UpdatePopupView: View {
1212
@ObservedObject var updateChecker: UpdateChecker
1313
@Binding var isPresented: Bool
14+
@FocusState private var isDownloadButtonFocused: Bool
1415

1516
var body: some View {
1617
VStack(spacing: 0) {
@@ -39,6 +40,11 @@ struct UpdatePopupView: View {
3940
.background(Color(NSColor.windowBackgroundColor))
4041
.cornerRadius(12)
4142
.shadow(color: .black.opacity(0.2), radius: 20, x: 0, y: 10)
43+
.task {
44+
// Small delay to ensure view hierarchy is ready for focus
45+
try? await Task.sleep(nanoseconds: 100_000_000)
46+
isDownloadButtonFocused = true
47+
}
4248
}
4349

4450
// MARK: - Header Section
@@ -179,7 +185,9 @@ struct UpdatePopupView: View {
179185

180186
private func changelogContent(_ content: String) -> some View {
181187
Group {
182-
if let attributedString = try? AttributedString(markdown: content) {
188+
let processedContent = preprocessMarkdownHeadings(content)
189+
190+
if let attributedString = try? AttributedString(markdown: processedContent) {
183191
Text(attributedString)
184192
.font(.subheadline)
185193
.foregroundStyle(.secondary)
@@ -191,6 +199,21 @@ struct UpdatePopupView: View {
191199
}
192200
}
193201

202+
/// Converts markdown ### headings to bold text with proper line breaks.
203+
/// SwiftUI's AttributedString doesn't render headings as block elements,
204+
/// so we convert them to bold text for better display.
205+
private func preprocessMarkdownHeadings(_ content: String) -> String {
206+
content
207+
.components(separatedBy: "\n")
208+
.map { line in
209+
if line.hasPrefix("### ") {
210+
return "**\(line.dropFirst(4))**\n"
211+
}
212+
return line
213+
}
214+
.joined(separator: "\n")
215+
}
216+
194217
// MARK: - Action Buttons Section
195218

196219
private var actionButtonsSection: some View {
@@ -216,6 +239,7 @@ struct UpdatePopupView: View {
216239
}
217240
.buttonStyle(.borderedProminent)
218241
.controlSize(.large)
242+
.focused($isDownloadButtonFocused)
219243
} else if info.zipUrl != nil {
220244
Button(action: {
221245
updateChecker.downloadZIP()
@@ -229,6 +253,7 @@ struct UpdatePopupView: View {
229253
}
230254
.buttonStyle(.borderedProminent)
231255
.controlSize(.large)
256+
.focused($isDownloadButtonFocused)
232257
} else {
233258
Button(action: {
234259
updateChecker.openReleasePage()
@@ -242,6 +267,7 @@ struct UpdatePopupView: View {
242267
}
243268
.buttonStyle(.borderedProminent)
244269
.controlSize(.large)
270+
.focused($isDownloadButtonFocused)
245271
}
246272
}
247273
}

0 commit comments

Comments
 (0)