Commit b1fc78b637
Unsigned
Layout: unified · split
gitbay/Views/Shared/ComposeSheet.swift +23 −5
| @@ -9,11 +9,29 @@ struct ComposeSheet: View { | |||
| 9 | let errorMessage: String? | 9 | let errorMessage: String? |
| 10 | @Binding var title: String | 10 | @Binding var title: String |
| 11 | @Binding var bodyText: String | 11 | @Binding var bodyText: String |
| 12 | /// nil hides the picker entirely — the release editor has no parity | 12 | /// Held as a real `@Binding`, not `Binding<String>?`: an optional |
| 13 | /// row and passes nothing, leaving that call site untouched. | 13 | /// binding is not a dynamic property, so the sheet body never re-ran |
| 14 | var format: Binding<String>? = nil | 14 | /// when the value changed and the picker kept whatever it first saw. |
| 15 | @Binding var format: String | ||
| 16 | let showsFormat: Bool | ||
| 15 | let onSubmit: () -> Void | 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 | @Environment(\.dismiss) private var dismiss | 35 | @Environment(\.dismiss) private var dismiss |
| 18 | 36 | ||
| 19 | var body: some View { | 37 | var body: some View { |
| @@ -33,8 +51,8 @@ struct ComposeSheet: View { | |||
| 33 | .font(.gbSans(.body)) | 51 | .font(.gbSans(.body)) |
| 34 | .autocorrectionDisabled() | 52 | .autocorrectionDisabled() |
| 35 | .accessibilityIdentifier("compose-body") | 53 | .accessibilityIdentifier("compose-body") |
| 36 | if let format { | 54 | if showsFormat { |
| 37 | Picker("Format", selection: format) { | 55 | Picker("Format", selection: $format) { |
| 38 | Text("Markdown").tag("md") | 56 | Text("Markdown").tag("md") |
| 39 | Text("Org").tag("org") | 57 | Text("Org").tag("org") |
| 40 | } | 58 | } |
gitbayUITests/LiveSmokeUITests.swift +18
| @@ -188,11 +188,29 @@ final class LiveSmokeUITests: XCTestCase { | |||
| 188 | XCTAssertTrue(title.waitForExistence(timeout: 5), "edit sheet did not open") | 188 | XCTAssertTrue(title.waitForExistence(timeout: 5), "edit sheet did not open") |
| 189 | XCTAssertTrue((title.value as? String)?.contains("ui-smoke fixture") == true, | 189 | XCTAssertTrue((title.value as? String)?.contains("ui-smoke fixture") == true, |
| 190 | "edit sheet did not prefill") | 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 | app.descendants(matching: .any).matching(identifier: "compose-submit") | 197 | app.descendants(matching: .any).matching(identifier: "compose-submit") |
| 192 | .firstMatch.tap() | 198 | .firstMatch.tap() |
| 193 | // Sheet dismissal proves the save round-tripped without error. | 199 | // Sheet dismissal proves the save round-tripped without error. |
| 194 | XCTAssertTrue(waitForDisappearance(title, timeout: 15), "edit save did not dismiss") | 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 | back() // to issues list | 214 | back() // to issues list |
| 197 | back() // to repo screen | 215 | back() // to repo screen |
| 198 | 216 | ||