gitbay/Views/Repos/FileEditSheet.swift
72 lines · 2692 bytes
1 symbol in this file
1import SwiftUI
2
3/// Edit one file and commit it. The commit is unsigned — the server
4/// authors it — so a repository requiring signatures refuses, and the
5/// refusal is what the sheet shows.
6struct FileEditSheet: View {
7
8 let model: FileViewModel
9 let branch: String
10 @Binding var content: String
11 let onCommitted: () -> Void
12
13 @Environment(\.dismiss) private var dismiss
14 @State private var message = ""
15
16 var body: some View {
17 NavigationStack {
18 Form {
19 Section {
20 TextEditor(text: $content)
21 .font(.gbMono(.caption))
22 .frame(minHeight: 260)
23 .autocorrectionDisabled()
24 .textInputAutocapitalization(.never)
25 .accessibilityIdentifier("file-edit-content")
26 } header: {
27 Text(model.fileName)
28 } footer: {
29 Text("Commits to \(branch) as an unsigned commit.")
30 }
31 if let format = MarkupPreview.format(forFile: model.fileName) {
32 Section {
33 MarkupPreview(text: content, format: format, identifier: "file-edit-preview")
34 }
35 }
36 Section("Message") {
37 TextField("edit \(model.fileName)", text: $message)
38 .autocorrectionDisabled()
39 .accessibilityIdentifier("file-edit-message")
40 }
41 if let error = model.actionError {
42 Section {
43 GBNotice(error, .gbWarn)
44 }
45 }
46 }
47 .scrollDismissesKeyboard(.interactively)
48 .navigationTitle("Edit")
49 .navigationBarTitleDisplayMode(.inline)
50 .toolbar {
51 ToolbarItem(placement: .cancellationAction) {
52 Button("Cancel") { dismiss() }
53 }
54 ToolbarItem(placement: .confirmationAction) {
55 if model.working {
56 ProgressView()
57 } else {
58 Button("Commit") {
59 Task {
60 if await model.commit(content: content, message: message) {
61 onCommitted()
62 }
63 }
64 }
65 .accessibilityIdentifier("file-edit-commit")
66 }
67 }
68 }
69 .interactiveDismissDisabled(model.working)
70 }
71 }
72}