Commit 596d6a1f7d
Verified · cmc
Layout: unified · split
gitbay/Views/Shared/MarkupPreview.swift added +40
| @@ -0,0 +1,40 @@ | |||
| 1 | import 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. | ||
| 7 | struct 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 @@ | |||
| 1 | import Testing | ||
| 2 | @testable import gitbay | ||
| 3 | |||
| 4 | struct 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 | } | ||