Fix compile errors: guard unwrap + ViewBuilder var mutation
Build iOS App / Build .ipa and publish source (push) Successful in 25s

- PRDetailView: guard let current = selectedTab ?? .overview fails because
  ?? already unwraps to non-optional. Use let current = selectedTab ?? .overview.
- MarkdownText: var inCodeBlock inside ViewBuilder is not allowed. Precompute
  lines with their code-block state as a computed property on a private struct,
  then iterate via ForEach in the builder. Bump to 3.3.
This commit is contained in:
Hermes committed 2026-08-14 09:45:44 +00:00
1 parent dd0fc84238
commit a9d408ee85
2 files changed
+57 -31

No files matched your search

+2 -2
View File
@@ -195,8 +195,8 @@ struct PRDetailView: View {
DragGesture(minimumDistance: 20) DragGesture(minimumDistance: 20)
.onEnded { value in .onEnded { value in
let tabs = DetailTab.allCases let tabs = DetailTab.allCases
guard let current = selectedTab ?? .overview, let current = selectedTab ?? .overview
let idx = tabs.firstIndex(of: current) else { return } guard let idx = tabs.firstIndex(of: current) else { return }
if value.translation.width < -40, idx < tabs.count - 1 { if value.translation.width < -40, idx < tabs.count - 1 {
withAnimation { selectedTab = tabs[idx + 1] } withAnimation { selectedTab = tabs[idx + 1] }
} else if value.translation.width > 40, idx > 0 { } else if value.translation.width > 40, idx > 0 {
+55 -29
View File
@@ -179,45 +179,71 @@ struct MarkdownText: View {
self.markdown = markdown self.markdown = markdown
} }
var body: some View { /// One markdown source line with its render type resolved upfront, so the
VStack(alignment: .leading, spacing: 6) { /// code-block state doesn't have to be mutated inside the ViewBuilder.
let lines = markdown.components(separatedBy: "\n") private struct Line: Identifiable {
enum Kind { case code, heading, bullet, text, blank }
let id = UUID()
let kind: Kind
let text: String
let level: Int // heading level
}
private var lines: [Line] {
let raw = markdown.components(separatedBy: "\n")
var out: [Line] = []
var inCodeBlock = false var inCodeBlock = false
ForEach(Array(lines.enumerated()), id: \.offset) { _, line in for line in raw {
if line.hasPrefix("```") { if line.hasPrefix("```") {
inCodeBlock.toggle() inCodeBlock.toggle()
} else if inCodeBlock { continue
Text(line) }
if inCodeBlock {
out.append(Line(kind: .code, text: line, level: 0))
} else if line.hasPrefix("# ") || line.hasPrefix("## ") || line.hasPrefix("### ") {
let level = line.prefix(while: { $0 == "#" }).count
out.append(Line(kind: .heading,
text: String(line.dropFirst(level)).trimmingCharacters(in: .whitespaces),
level: level))
} else if line.hasPrefix("- ") || line.hasPrefix("* ") {
out.append(Line(kind: .bullet,
text: String(line.dropFirst(2)),
level: 0))
} else if line.trimmingCharacters(in: .whitespaces).isEmpty {
out.append(Line(kind: .blank, text: "", level: 0))
} else {
out.append(Line(kind: .text, text: line, level: 0))
}
}
return out
}
var body: some View {
VStack(alignment: .leading, spacing: 6) {
ForEach(lines) { line in
switch line.kind {
case .code:
Text(line.text)
.font(.caption.monospaced()) .font(.caption.monospaced())
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
.padding(4) .padding(4)
.background(Color(.secondarySystemBackground)) .background(Color(.secondarySystemBackground))
} else if line.hasPrefix("# ") || line.hasPrefix("## ") || line.hasPrefix("### ") { case .heading:
heading(line) Text(line.text)
} else if line.hasPrefix("- ") || line.hasPrefix("* ") { .font(line.level == 1 ? .title2.bold() : line.level == 2 ? .title3.bold() : .headline)
bullet(line)
} else if line.trimmingCharacters(in: .whitespaces).isEmpty {
Spacer(minLength: 4)
} else {
inline(line)
}
}
}
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
} case .bullet:
private func heading(_ line: String) -> some View {
let level = line.prefix(while: { $0 == "#" }).count
let text = line.dropFirst(level).trimmingCharacters(in: .whitespaces)
return Text(text)
.font(level == 1 ? .title2.bold() : level == 2 ? .title3.bold() : .headline)
.frame(maxWidth: .infinity, alignment: .leading)
}
private func bullet(_ line: String) -> some View {
HStack(alignment: .top, spacing: 6) { HStack(alignment: .top, spacing: 6) {
Text("•") Text("•")
inline(String(line.dropFirst(2))) inline(line.text)
}
.frame(maxWidth: .infinity, alignment: .leading)
case .blank:
Spacer(minLength: 4)
case .text:
inline(line.text)
}
}
} }
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
} }