Commit 596d6a1f7d

596d6a1f7d0b086e4a4a7cc31ae4c60e76b8c12c

parent: 610ff1e5f9

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-22 22:02 UTC

views: MarkupPreview, a draft rendered as the thread renders it

Layout: unified · split

gitbay/Views/Shared/MarkupPreview.swift added +40
@@ -0,0 +1,40 @@
1import SwiftUI
2
3/// A collapsed "Preview" row under a markup editor. Expanded, it renders
4/// the draft with `FormattedBodyView`, the view the app's threads use, so
5/// what it shows is what the app will show once the text is sent. It sits
6/// under the editor rather than replacing it, so the draft stays in view.
7struct MarkupPreview: View {
8
9 let text: String
10 let format: String?
11 let identifier: String
12
13 @State private var expanded = false
14
15 var body: some View {
16 DisclosureGroup("Preview", isExpanded: $expanded) {
17 if text.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
18 Text("Nothing to preview.")
19 .font(.gbSans(.subheadline))
20 .foregroundStyle(.secondary)
21 } else {
22 FormattedBodyView(text: text, format: format)
23 .padding(.vertical, 4)
24 }
25 }
26 .font(.gbSans(.subheadline))
27 .accessibilityIdentifier(identifier)
28 }
29
30 /// The format a file's contents render in, or nil for a file shown as
31 /// source. The same extensions the forge renders a README or wiki
32 /// page from.
33 static func format(forFile name: String) -> String? {
34 switch (name as NSString).pathExtension.lowercased() {
35 case "org": "org"
36 case "md", "markdown": "md"
37 default: nil
38 }
39 }
40}
gitbayTests/MarkupPreviewTests.swift added +23
@@ -0,0 +1,23 @@
1import Testing
2@testable import gitbay
3
4struct MarkupPreviewFormatTests {
5
6 @Test func orgFilesRenderAsOrg() {
7 #expect(MarkupPreview.format(forFile: "README.org") == "org")
8 #expect(MarkupPreview.format(forFile: "profile/README.org") == "org")
9 }
10
11 @Test func markdownFilesRenderAsMarkdown() {
12 #expect(MarkupPreview.format(forFile: "README.md") == "md")
13 #expect(MarkupPreview.format(forFile: "notes.markdown") == "md")
14 #expect(MarkupPreview.format(forFile: "CHANGES.MD") == "md")
15 }
16
17 /// Source files show as source, so there is nothing to preview.
18 @Test func otherFilesHaveNoPreview() {
19 #expect(MarkupPreview.format(forFile: "main.swift") == nil)
20 #expect(MarkupPreview.format(forFile: "Makefile") == nil)
21 #expect(MarkupPreview.format(forFile: "notes.txt") == nil)
22 }
23}