better alert when saving names

This commit is contained in:
Evgeny @ SimpleX Chat
2026-07-01 16:35:10 +00:00
parent f7b6a7fad7
commit fbb171019f
4 changed files with 36 additions and 27 deletions
+18 -12
View File
@@ -1366,22 +1366,27 @@ func apiSetProfileAddress(on: Bool) async throws -> User? {
}
// name is the encoded SimplexName (e.g. "@alice.simplex"); nil clears it
func setSimplexNameError(_ error: Error, isChannel: Bool) -> String {
if let e = error as? ChatError, case let .error(.simplexName(name, .noValidLink)) = e {
return isChannel
? "The SimpleX name \(name.shortName) is registered without channel link. Add channel link to the name via the registration page."
: "The SimpleX name \(name.shortName) is registered without SimpleX address. Add your SimpleX address to the name via the registration page."
// owner-specific SNENoValidLink wording; everything else reuses the general apiConnectResponseAlert
func showSetSimplexNameError<R>(_ r: APIResult<R>, isChannel: Bool) {
if case let .error(.simplexName(name, .noValidLink)) = r.unexpected {
let format = isChannel
? NSLocalizedString("The SimpleX name %@ is registered without channel link. Add channel link to the name via the registration page.", comment: "alert message")
: NSLocalizedString("The SimpleX name %@ is registered without SimpleX address. Add your SimpleX address to the name via the registration page.", comment: "alert message")
showAlert(NSLocalizedString("Error saving name", comment: "alert title"), message: String.localizedStringWithFormat(format, name.shortName))
} else {
AlertManager.shared.showAlert(apiConnectResponseAlert(r))
}
return responseError(error)
}
func apiSetUserName(_ name: String?) async throws -> User {
let userId = try currentUserId("apiSetUserName")
let r: ChatResponse1 = try await chatSendCmd(.apiSetUserName(userId: userId, name: name))
let r: APIResult<ChatResponse1> = await chatApiSendCmd(.apiSetUserName(userId: userId, name: name))
switch r {
case let .userProfileUpdated(user, _, _, _): return user
case let .userProfileNoChange(user): return user
default: throw r.unexpected
case let .result(.userProfileUpdated(user, _, _, _)): return user
case let .result(.userProfileNoChange(user)): return user
default:
showSetSimplexNameError(r, isChannel: false)
throw r.unexpected
}
}
@@ -2064,8 +2069,9 @@ func apiUpdateGroup(_ groupId: Int64, _ groupProfile: GroupProfile) async throws
}
func apiSetPublicGroupAccess(_ groupId: Int64, access: PublicGroupAccess) async throws -> GroupInfo {
let r: ChatResponse2 = try await chatSendCmd(.apiSetPublicGroupAccess(groupId: groupId, access: access))
if case let .groupUpdated(_, toGroup) = r { return toGroup }
let r: APIResult<ChatResponse2> = await chatApiSendCmd(.apiSetPublicGroupAccess(groupId: groupId, access: access))
if case let .result(.groupUpdated(_, toGroup)) = r { return toGroup }
showSetSimplexNameError(r, isChannel: true)
throw r.unexpected
}
@@ -263,9 +263,9 @@ struct GroupChatInfoView: View {
chatModel.updateGroup(gInfo)
groupInfo = gInfo
}
return nil
return true
} catch {
return setSimplexNameError(error, isChannel: true)
return false
}
}
)
@@ -202,9 +202,9 @@ struct UserAddressView: View {
do {
let u = try await apiSetUserName(name)
await MainActor.run { chatModel.updateUser(u) }
return nil
return true
} catch {
return setSimplexNameError(error, isChannel: false)
return false
}
}
)
@@ -718,7 +718,7 @@ struct SetSimplexNameView: View {
let footer: LocalizedStringKey
let prefix: String
@State var nameText: String
let save: (String?) async -> String?
let save: (String?) async -> Bool
@Environment(\.dismiss) var dismiss
@EnvironmentObject var theme: AppTheme
@State private var saving = false
@@ -738,14 +738,10 @@ struct SetSimplexNameView: View {
Button {
saving = true
Task {
let err = await save(normalized())
let ok = await save(normalized())
await MainActor.run {
saving = false
if let err {
showAlert(NSLocalizedString("Error saving name", comment: "alert title"), message: err)
} else {
dismiss()
}
if ok { dismiss() }
}
}
} label: {
@@ -1629,12 +1629,13 @@ object ChatController {
}
}
fun setSimplexNameErrorText(err: ChatError, isChannel: Boolean): String =
// owner-specific wording for setting one's own/channel name; null for other errors (handled by apiConnectResponseAlert)
fun simplexNameOwnerError(err: ChatError, isChannel: Boolean): String? =
if (err is ChatError.ChatErrorChat && err.errorType is ChatErrorType.SimplexName && err.errorType.simplexNameError is SimplexNameError.NoValidLink) {
val name = err.errorType.simplexName.shortName
if (isChannel) generalGetString(MR.strings.simplex_name_owner_no_channel_link).format(name)
else generalGetString(MR.strings.simplex_name_owner_no_address).format(name)
} else err.string
} else null
fun connErrorText(e: ChatError): String = when {
e is ChatError.ChatErrorChat && e.errorType is ChatErrorType.InvalidConnReq ->
@@ -1829,7 +1830,11 @@ object ChatController {
r is API.Result && r.res is CR.UserProfileUpdated -> r.res.user.updateRemoteHostId(rh)
r is API.Result && r.res is CR.UserProfileNoChange -> r.res.user.updateRemoteHostId(rh)
else -> {
if (r is API.Error) AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_saving_simplex_name), setSimplexNameErrorText(r.err, false))
if (r is API.Error) {
val ownerMsg = simplexNameOwnerError(r.err, isChannel = false)
if (ownerMsg != null) AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_saving_simplex_name), ownerMsg)
else apiConnectResponseAlert(r)
}
throw Exception("failed to set SimpleX name: ${r.responseType} ${r.details}")
}
}
@@ -2395,7 +2400,9 @@ object ChatController {
return when {
r is API.Result && r.res is CR.GroupUpdated -> r.res.toGroup
r is API.Error -> {
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_saving_simplex_name), setSimplexNameErrorText(r.err, true))
val ownerMsg = simplexNameOwnerError(r.err, isChannel = true)
if (ownerMsg != null) AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_saving_simplex_name), ownerMsg)
else apiConnectResponseAlert(r)
null
}
else -> {