Commit b1fc78b637
Unsigned
Layout: unified · split
gitbay/Views/Shared/ComposeSheet.swift +23 −5
| @@ -9,11 +9,29 @@ struct ComposeSheet: View { | ||
| 9 | 9 | let errorMessage: String? |
| 10 | 10 | @Binding var title: String |
| 11 | 11 | @Binding var bodyText: String |
| 12 | /// nil hides the picker entirely — the release editor has no parity | |
| 13 | /// row and passes nothing, leaving that call site untouched. | |
| 14 | var format: Binding<String>? = nil | |
| 12 | /// Held as a real `@Binding`, not `Binding<String>?`: an optional | |
| 13 | /// binding is not a dynamic property, so the sheet body never re-ran | |
| 14 | /// when the value changed and the picker kept whatever it first saw. | |
| 15 | @Binding var format: String | |
| 16 | let showsFormat: Bool | |
| 15 | 17 | let onSubmit: () -> Void |
| 16 | 18 | |
| 19 | /// A nil `format` hides the picker entirely — the release editor has | |
| 20 | /// no parity row and passes nothing, leaving that call site untouched. | |
| 21 | init(heading: String, submitLabel: String, working: Bool, errorMessage: String?, | |
| 22 | title: Binding<String>, bodyText: Binding<String>, | |
| 23 | format: Binding<String>? = nil, onSubmit: @escaping () -> Void) { | |
| 24 | self.heading = heading | |
| 25 | self.submitLabel = submitLabel | |
| 26 | self.working = working | |
| 27 | self.errorMessage = errorMessage | |
| 28 | _title = title | |
| 29 | _bodyText = bodyText | |
| 30 | _format = format ?? .constant("md") | |
| 31 | showsFormat = format != nil | |
| 32 | self.onSubmit = onSubmit | |
| 33 | } | |
| 34 | ||
| 17 | 35 | @Environment(\.dismiss) private var dismiss |
| 18 | 36 | |
| 19 | 37 | var body: some View { |
| @@ -33,8 +51,8 @@ struct ComposeSheet: View { | ||
| 33 | 51 | .font(.gbSans(.body)) |
| 34 | 52 | .autocorrectionDisabled() |
| 35 | 53 | .accessibilityIdentifier("compose-body") |
| 36 | if let format { | |
| 37 | Picker("Format", selection: format) { | |
| 54 | if showsFormat { | |
| 55 | Picker("Format", selection: $format) { | |
| 38 | 56 | Text("Markdown").tag("md") |
| 39 | 57 | Text("Org").tag("org") |
| 40 | 58 | } |
gitbayUITests/LiveSmokeUITests.swift +18
| @@ -188,11 +188,29 @@ final class LiveSmokeUITests: XCTestCase { | ||
| 188 | 188 | XCTAssertTrue(title.waitForExistence(timeout: 5), "edit sheet did not open") |
| 189 | 189 | XCTAssertTrue((title.value as? String)?.contains("ui-smoke fixture") == true, |
| 190 | 190 | "edit sheet did not prefill") |
| 191 | // Save the body as org, reopen, and the picker must start on Org: | |
| 192 | // the sheet has to read the stored format, not its own default. | |
| 193 | let format = app.segmentedControls.matching(identifier: "compose-format").firstMatch | |
| 194 | XCTAssertTrue(format.waitForExistence(timeout: 5), "format picker missing") | |
| 195 | XCTAssertTrue(format.buttons["Markdown"].isSelected, "fixture did not open on Markdown") | |
| 196 | format.buttons["Org"].tap() | |
| 191 | 197 | app.descendants(matching: .any).matching(identifier: "compose-submit") |
| 192 | 198 | .firstMatch.tap() |
| 193 | 199 | // Sheet dismissal proves the save round-tripped without error. |
| 194 | 200 | XCTAssertTrue(waitForDisappearance(title, timeout: 15), "edit save did not dismiss") |
| 195 | 201 | |
| 202 | app.descendants(matching: .any).matching(identifier: "issue-actions-menu") | |
| 203 | .firstMatch.tap() | |
| 204 | XCTAssertTrue(edit.waitForExistence(timeout: 5)) | |
| 205 | edit.tap() | |
| 206 | XCTAssertTrue(format.waitForExistence(timeout: 5), "edit sheet did not reopen") | |
| 207 | XCTAssertTrue(format.buttons["Org"].isSelected, "edit sheet did not open on the stored format") | |
| 208 | // Restore the fixture to markdown. | |
| 209 | format.buttons["Markdown"].tap() | |
| 210 | app.descendants(matching: .any).matching(identifier: "compose-submit") | |
| 211 | .firstMatch.tap() | |
| 212 | XCTAssertTrue(waitForDisappearance(title, timeout: 15), "edit save did not dismiss") | |
| 213 | ||
| 196 | 214 | back() // to issues list |
| 197 | 215 | back() // to repo screen |
| 198 | 216 | |