mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-15 09:10:19 +00:00
ios: disable the submit button while creating, as Kotlin already does
The form's only in-flight protection was the picker's own check-and-set, which makes a second tap a silent no-op - the button stayed live with nothing visibly happening for the whole of the create plus the profile list refresh. Kotlin gained a submitting flag for this; iOS did not. Also trims the last of the long doc comments on isLastModalOpenNotClosing.
This commit is contained in:
@@ -54,7 +54,7 @@ struct ContextProfilePickerView: View {
|
||||
NavigationView {
|
||||
CreateProfile(onSubmit: { displayName, shortDescr, image in
|
||||
try await createProfileForChat(displayName, shortDescr, image)
|
||||
})
|
||||
}, submitting: creatingProfile)
|
||||
}
|
||||
.interactiveDismissDisabled(creatingProfile)
|
||||
}
|
||||
|
||||
@@ -697,7 +697,7 @@ private struct ActiveProfilePicker: View {
|
||||
NavigationView {
|
||||
CreateProfile(onSubmit: { displayName, shortDescr, image in
|
||||
try await createProfileForConnection(displayName, shortDescr, image)
|
||||
})
|
||||
}, submitting: creatingProfile)
|
||||
}
|
||||
// The submit runs in an unstructured Task that SwiftUI does not cancel, so a
|
||||
// swipe-to-dismiss mid-create would still create the profile and switch to it
|
||||
|
||||
@@ -33,6 +33,8 @@ struct CreateProfile: View {
|
||||
// used to create a profile for an invitation (which must not switch the active user
|
||||
// until the prepared chat has been reassigned). Errors are still shown by this view.
|
||||
var onSubmit: ((_ displayName: String, _ shortDescr: String?, _ image: String?) async throws -> Void)? = nil
|
||||
/// Set while onSubmit is in flight, so the button does not stay live with nothing happening.
|
||||
var submitting: Bool = false
|
||||
@Environment(\.colorScheme) var colorScheme
|
||||
@Environment(\.dismiss) var dismiss
|
||||
@EnvironmentObject var theme: AppTheme
|
||||
@@ -108,7 +110,7 @@ struct CreateProfile: View {
|
||||
Button(action: createProfile) {
|
||||
settingsRow("checkmark", color: theme.colors.primary) { Text("Create profile") }
|
||||
}
|
||||
.disabled(!canCreateProfile(displayName) || !bioFitsLimit())
|
||||
.disabled(submitting || !canCreateProfile(displayName) || !bioFitsLimit())
|
||||
} footer: {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text("Your profile is stored on your device and only shared with your contacts.")
|
||||
|
||||
+3
-6
@@ -117,12 +117,9 @@ class ModalManager(private val placement: ModalPlacement? = null) {
|
||||
|
||||
fun isLastModalOpen(id: ModalViewId): Boolean = modalViews.lastOrNull()?.id == id
|
||||
|
||||
/** [isLastModalOpen], except that a modal already dismissed and only waiting out its
|
||||
* close animation does not count - [closeModal] leaves it in [modalViews] and stages
|
||||
* its index in [toRemove]. A caller deciding whether to close on "is my modal still the
|
||||
* last one?" needs this, or a back-tap during a long operation pops the screen beneath
|
||||
* as well. Kept separate because [isLastModalOpen] also gates secondary chat teardown,
|
||||
* which relies on the existing behaviour. */
|
||||
/** [isLastModalOpen], but a modal already dismissed and only waiting out its close
|
||||
* animation does not count - [closeModal] leaves it in [modalViews] until then. Separate
|
||||
* from [isLastModalOpen], which gates secondary chat teardown on the existing behaviour. */
|
||||
fun isLastModalOpenNotClosing(id: ModalViewId): Boolean {
|
||||
var i = modalViews.size - 1
|
||||
while (i >= 0 && i in toRemove) i--
|
||||
|
||||
Reference in New Issue
Block a user