mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-10-16 00:10:56 +00:00
Merge branch 'master' into badge-in-app-checkout
This commit is contained in:
+1
-1
@@ -1115,7 +1115,7 @@ object ChatModel {
|
||||
fun updateCurrentUser(rhId: Long?, newProfile: Profile, preferences: FullChatPreferences? = null) {
|
||||
val current = currentUser.value ?: return
|
||||
val updated = current.copy(
|
||||
profile = newProfile.toLocalProfile(current.profile.profileId),
|
||||
profile = newProfile.toLocalProfile(current.profile.profileId).copy(localBadge = current.profile.localBadge, contactDomainVerified = current.profile.contactDomainVerified),
|
||||
fullPreferences = preferences ?: current.fullPreferences
|
||||
)
|
||||
val i = users.indexOfFirst { it.user.userId == current.userId && it.user.remoteHostId == rhId }
|
||||
|
||||
+15
-3
@@ -1959,8 +1959,10 @@ object ChatController {
|
||||
val r = sendCmd(rh, CC.ApiUpdateProfile(userId, profile))
|
||||
if (r is API.Result && r.res is CR.UserProfileNoChange) return profile to emptyList()
|
||||
if (r is API.Result && r.res is CR.UserProfileUpdated) return r.res.toProfile to r.res.updateSummary.changedContacts
|
||||
if (r is API.Error && r.err is ChatError.ChatErrorStore && r.err.storeError is StoreError.DuplicateName) {
|
||||
if (r is API.Error && (r.err is ChatError.ChatErrorStore && r.err.storeError is StoreError.DuplicateName || r.err is ChatError.ChatErrorChat && r.err.errorType is ChatErrorType.UserExists)) {
|
||||
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.failed_to_create_user_duplicate_title), generalGetString(MR.strings.failed_to_create_user_duplicate_desc))
|
||||
} else if (!(networkErrorAlert(r))) {
|
||||
AlertManager.shared.showAlertMsg(generalGetString(MR.strings.error_saving_profile), "${r.responseType}: ${r.details}")
|
||||
}
|
||||
Log.e(TAG, "apiUpdateProfile bad response: ${r.responseType} ${r.details}")
|
||||
return null
|
||||
@@ -1972,7 +1974,12 @@ object ChatController {
|
||||
return when {
|
||||
r is API.Result && r.res is CR.UserProfileNoChange -> null
|
||||
r is API.Result && r.res is CR.UserProfileUpdated -> r.res.user.updateRemoteHostId(rh)
|
||||
else -> throw Exception("failed to set profile address: ${r.responseType} ${r.details}")
|
||||
else -> {
|
||||
if (!(networkErrorAlert(r))) {
|
||||
apiErrorAlert("apiSetProfileAddress", generalGetString(MR.strings.error_saving_profile), r)
|
||||
}
|
||||
throw Exception("failed to set profile address: ${r.responseType} ${r.details}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4948,6 +4955,7 @@ sealed class UserServersError {
|
||||
@Serializable @SerialName("storageMissing") data class StorageMissing(val protocol: ServerProtocol, val user: UserRef?): UserServersError()
|
||||
@Serializable @SerialName("proxyMissing") data class ProxyMissing(val protocol: ServerProtocol, val user: UserRef?): UserServersError()
|
||||
@Serializable @SerialName("duplicateServer") data class DuplicateServer(val protocol: ServerProtocol, val duplicateServer: String, val duplicateHost: String): UserServersError()
|
||||
@Serializable @SerialName("tooManyHosts") data class TooManyHosts(val protocol: ServerProtocol, val tooManyHostsServer: String): UserServersError()
|
||||
@Serializable @SerialName("duplicateChatRelayAddress") data class DuplicateChatRelayAddress(val duplicateChatRelay: String, val duplicateAddress: String): UserServersError()
|
||||
|
||||
val globalError: String?
|
||||
@@ -4963,6 +4971,7 @@ sealed class UserServersError {
|
||||
is StorageMissing -> this.protocol
|
||||
is ProxyMissing -> this.protocol
|
||||
is DuplicateServer -> this.protocol
|
||||
is TooManyHosts -> this.protocol
|
||||
is DuplicateChatRelayAddress -> null
|
||||
}
|
||||
|
||||
@@ -4978,6 +4987,8 @@ sealed class UserServersError {
|
||||
is ProxyMissing -> this.user?.let { "${userStr(it)} ${generalGetString(MR.strings.no_message_servers_configured_for_private_routing)}" }
|
||||
?: generalGetString(MR.strings.no_message_servers_configured_for_private_routing)
|
||||
|
||||
is TooManyHosts -> String.format(generalGetString(MR.strings.server_has_too_many_hosts), ServerAddress.parseServerAddress(this.tooManyHostsServer)?.hostnames?.firstOrNull() ?: this.tooManyHostsServer)
|
||||
|
||||
else -> null
|
||||
}
|
||||
} else {
|
||||
@@ -7651,7 +7662,8 @@ enum class RcvSwitchStatus {
|
||||
@SerialName("switch_started") SwitchStarted,
|
||||
@SerialName("sending_qadd") SendingQADD,
|
||||
@SerialName("sending_quse") SendingQUSE,
|
||||
@SerialName("received_message") ReceivedMessage
|
||||
@SerialName("received_message") ReceivedMessage,
|
||||
@SerialName("received_qend") ReceivedQEND
|
||||
}
|
||||
|
||||
@Serializable
|
||||
|
||||
+14
-4
@@ -119,6 +119,20 @@ fun ChatView(
|
||||
}
|
||||
chat
|
||||
} }
|
||||
if (chatsCtx.secondaryContextFilter == null) {
|
||||
// cleared when the view is gone rather than on back: Android keeps it on screen while it slides out,
|
||||
// and by then a channel being created may already be using this state
|
||||
DisposableEffect(Unit) {
|
||||
onDispose {
|
||||
if (chatModel.chatId.value == null && chatModel.creatingChannelId.value == null) {
|
||||
chatModel.groupMembers.value = emptyList()
|
||||
chatModel.groupMembersIndexes.value = emptyMap()
|
||||
chatModel.membersLoaded.value = false
|
||||
ChannelRelaysModel.reset()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
val user = chatModel.currentUser.value
|
||||
val chatInfo = activeChat.value?.chatInfo
|
||||
if (chat == null || chatInfo == null || user == null) {
|
||||
@@ -382,10 +396,6 @@ fun ChatView(
|
||||
hideKeyboard(view)
|
||||
AudioPlayer.stop()
|
||||
chatModel.chatId.value = null
|
||||
chatModel.groupMembers.value = emptyList()
|
||||
chatModel.groupMembersIndexes.value = emptyMap()
|
||||
chatModel.membersLoaded.value = false
|
||||
ChannelRelaysModel.reset()
|
||||
},
|
||||
info = {
|
||||
if (ModalManager.end.hasModalsOpen()) {
|
||||
|
||||
+3
-1
@@ -2153,7 +2153,8 @@ private fun ownerRelayState(chat: Chat, chatModel: ChatModel): OwnerRelayState?
|
||||
if (!gInfo.useRelays || gInfo.membership.memberRole != GroupMemberRole.Owner ||
|
||||
gInfo.membership.memberStatus in listOf(GroupMemberStatus.MemLeft, GroupMemberStatus.MemRemoved, GroupMemberStatus.MemGroupDeleted)
|
||||
) return null
|
||||
val relays = if (ChannelRelaysModel.groupId.value == gInfo.groupId) ChannelRelaysModel.groupRelays.toList() else emptyList()
|
||||
if (ChannelRelaysModel.groupId.value != gInfo.groupId) return null
|
||||
val relays = ChannelRelaysModel.groupRelays.toList()
|
||||
if (relays.isEmpty()) return OwnerRelayState(emptyList(), 0, 0, 0, true)
|
||||
val relayMembers = relays.map { relay ->
|
||||
relay to chatModel.groupMembers.value.firstOrNull { it.groupMemberId == relay.groupMemberId }
|
||||
@@ -2186,6 +2187,7 @@ private fun subscriberRelayState(chat: Chat, chatModel: ChatModel): SubscriberRe
|
||||
val connectedCount = relayMembers.count { !relayMemberRemoved(it.memberStatus) && it.activeConn?.connStatus == ConnStatus.Ready && it.activeConn?.connFailedErr == null }
|
||||
val failedCount = relayMembers.count { !relayMemberRemoved(it.memberStatus) && it.activeConn?.connFailedErr != null }
|
||||
val total = if (relayMembers.isNotEmpty()) relayMembers.size else hostnames.size
|
||||
if (total == 0 && !chatModel.membersLoaded.value) return null
|
||||
val noActiveRelays = connectedCount == 0 && (removedCount + failedCount) == total
|
||||
return SubscriberRelayState(hostnames, relayMembers, connectedCount, removedCount, failedCount, total, noActiveRelays)
|
||||
}
|
||||
|
||||
+7
-4
@@ -265,10 +265,13 @@ suspend fun setGroupMembers(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatMo
|
||||
newMember
|
||||
}
|
||||
}
|
||||
chatModel.groupMembersIndexes.value = emptyMap()
|
||||
chatModel.groupMembers.value = newMembers
|
||||
chatModel.membersLoaded.value = true
|
||||
chatModel.populateGroupMembersIndexes()
|
||||
withContext(Dispatchers.Main) {
|
||||
if (chatModel.chatId.value != groupInfo.id) return@withContext
|
||||
chatModel.groupMembersIndexes.value = emptyMap()
|
||||
chatModel.groupMembers.value = newMembers
|
||||
chatModel.membersLoaded.value = true
|
||||
chatModel.populateGroupMembersIndexes()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
+1
@@ -63,6 +63,7 @@ fun UserAddressView(
|
||||
chatModel.updateUser(u)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
shareViaProfile.value = !on
|
||||
Log.e(TAG, "UserAddressView apiSetProfileAddress: ${e.stackTraceToString()}")
|
||||
} finally {
|
||||
progressIndicator.value = false
|
||||
|
||||
@@ -141,6 +141,7 @@
|
||||
<string name="no_message_servers_configured">No message servers.</string>
|
||||
<string name="no_message_servers_configured_for_receiving">No servers to receive messages.</string>
|
||||
<string name="no_message_servers_configured_for_private_routing">No servers for private message routing.</string>
|
||||
<string name="server_has_too_many_hosts">Server %1$s has more than two host names.</string>
|
||||
<string name="no_media_servers_configured">No media & file servers.</string>
|
||||
<string name="no_media_servers_configured_for_sending">No servers to send files.</string>
|
||||
<string name="no_media_servers_configured_for_private_routing">No servers to receive files.</string>
|
||||
@@ -255,6 +256,7 @@
|
||||
<string name="error_preparing_contact">Error opening chat</string>
|
||||
<string name="error_preparing_group">Error opening group</string>
|
||||
<string name="error_changing_user">Error changing profile</string>
|
||||
<string name="error_saving_profile">Error saving profile</string>
|
||||
|
||||
<!-- background service notice - SimpleXAPI.kt -->
|
||||
<string name="icon_descr_instant_notifications">Instant notifications</string>
|
||||
|
||||
Reference in New Issue
Block a user