mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2024-12-17 17:20:21 +01:00
Merge branch 'master' into master-ios
This commit is contained in:
@@ -736,22 +736,18 @@ open class ChatController(var ctrl: ChatCtrl?, val ntfManager: NtfManager, val a
|
||||
return null
|
||||
}
|
||||
|
||||
suspend fun apiSwitchContact(contactId: Long) {
|
||||
return when (val r = sendCmd(CC.APISwitchContact(contactId))) {
|
||||
is CR.CmdOk -> {}
|
||||
else -> {
|
||||
apiErrorAlert("apiSwitchContact", generalGetString(R.string.error_changing_address), r)
|
||||
}
|
||||
}
|
||||
suspend fun apiSwitchContact(contactId: Long): ConnectionStats? {
|
||||
val r = sendCmd(CC.APISwitchContact(contactId))
|
||||
if (r is CR.ContactSwitchStarted) return r.connectionStats
|
||||
apiErrorAlert("apiSwitchContact", generalGetString(R.string.error_changing_address), r)
|
||||
return null
|
||||
}
|
||||
|
||||
suspend fun apiSwitchGroupMember(groupId: Long, groupMemberId: Long) {
|
||||
return when (val r = sendCmd(CC.APISwitchGroupMember(groupId, groupMemberId))) {
|
||||
is CR.CmdOk -> {}
|
||||
else -> {
|
||||
apiErrorAlert("apiSwitchGroupMember", generalGetString(R.string.error_changing_address), r)
|
||||
}
|
||||
}
|
||||
suspend fun apiSwitchGroupMember(groupId: Long, groupMemberId: Long): ConnectionStats? {
|
||||
val r = sendCmd(CC.APISwitchGroupMember(groupId, groupMemberId))
|
||||
if (r is CR.GroupMemberSwitchStarted) return r.connectionStats
|
||||
apiErrorAlert("apiSwitchGroupMember", generalGetString(R.string.error_changing_address), r)
|
||||
return null
|
||||
}
|
||||
|
||||
suspend fun apiAbortSwitchContact(contactId: Long): ConnectionStats? {
|
||||
@@ -3298,6 +3294,8 @@ sealed class CR {
|
||||
@Serializable @SerialName("networkConfig") class NetworkConfig(val networkConfig: NetCfg): CR()
|
||||
@Serializable @SerialName("contactInfo") class ContactInfo(val user: User, val contact: Contact, val connectionStats: ConnectionStats, val customUserProfile: Profile? = null): CR()
|
||||
@Serializable @SerialName("groupMemberInfo") class GroupMemberInfo(val user: User, val groupInfo: GroupInfo, val member: GroupMember, val connectionStats_: ConnectionStats? = null): CR()
|
||||
@Serializable @SerialName("contactSwitchStarted") class ContactSwitchStarted(val user: User, val contact: Contact, val connectionStats: ConnectionStats): CR()
|
||||
@Serializable @SerialName("groupMemberSwitchStarted") class GroupMemberSwitchStarted(val user: User, val groupInfo: GroupInfo, val member: GroupMember, val connectionStats: ConnectionStats): CR()
|
||||
@Serializable @SerialName("contactSwitchAborted") class ContactSwitchAborted(val user: User, val contact: Contact, val connectionStats: ConnectionStats): CR()
|
||||
@Serializable @SerialName("groupMemberSwitchAborted") class GroupMemberSwitchAborted(val user: User, val groupInfo: GroupInfo, val member: GroupMember, val connectionStats: ConnectionStats): CR()
|
||||
@Serializable @SerialName("contactCode") class ContactCode(val user: User, val contact: Contact, val connectionCode: String): CR()
|
||||
@@ -3414,6 +3412,8 @@ sealed class CR {
|
||||
is NetworkConfig -> "networkConfig"
|
||||
is ContactInfo -> "contactInfo"
|
||||
is GroupMemberInfo -> "groupMemberInfo"
|
||||
is ContactSwitchStarted -> "contactSwitchStarted"
|
||||
is GroupMemberSwitchStarted -> "groupMemberSwitchStarted"
|
||||
is ContactSwitchAborted -> "contactSwitchAborted"
|
||||
is GroupMemberSwitchAborted -> "groupMemberSwitchAborted"
|
||||
is ContactCode -> "contactCode"
|
||||
@@ -3527,6 +3527,8 @@ sealed class CR {
|
||||
is NetworkConfig -> json.encodeToString(networkConfig)
|
||||
is ContactInfo -> withUser(user, "contact: ${json.encodeToString(contact)}\nconnectionStats: ${json.encodeToString(connectionStats)}")
|
||||
is GroupMemberInfo -> withUser(user, "group: ${json.encodeToString(groupInfo)}\nmember: ${json.encodeToString(member)}\nconnectionStats: ${json.encodeToString(connectionStats_)}")
|
||||
is ContactSwitchStarted -> withUser(user, "contact: ${json.encodeToString(contact)}\nconnectionStats: ${json.encodeToString(connectionStats)}")
|
||||
is GroupMemberSwitchStarted -> withUser(user, "group: ${json.encodeToString(groupInfo)}\nmember: ${json.encodeToString(member)}\nconnectionStats: ${json.encodeToString(connectionStats)}")
|
||||
is ContactSwitchAborted -> withUser(user, "contact: ${json.encodeToString(contact)}\nconnectionStats: ${json.encodeToString(connectionStats)}")
|
||||
is GroupMemberSwitchAborted -> withUser(user, "group: ${json.encodeToString(groupInfo)}\nmember: ${json.encodeToString(member)}\nconnectionStats: ${json.encodeToString(connectionStats)}")
|
||||
is ContactCode -> withUser(user, "contact: ${json.encodeToString(contact)}\nconnectionCode: $connectionCode")
|
||||
|
||||
@@ -83,7 +83,7 @@ fun ChatInfoView(
|
||||
switchContactAddress = {
|
||||
showSwitchAddressAlert(switchAddress = {
|
||||
withApi {
|
||||
chatModel.controller.apiSwitchContact(contact.contactId)
|
||||
connStats.value = chatModel.controller.apiSwitchContact(contact.contactId)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
@@ -790,9 +790,7 @@ fun ComposeView(
|
||||
}
|
||||
}
|
||||
|
||||
// TODO in 5.2 - allow if ttl is not configured
|
||||
// val timedMessageAllowed = remember(chat.chatInfo) { chat.chatInfo.featureEnabled(ChatFeature.TimedMessages) }
|
||||
val timedMessageAllowed = remember(chat.chatInfo) { chat.chatInfo.featureEnabled(ChatFeature.TimedMessages) && chat.chatInfo.timedMessagesTTL != null }
|
||||
val timedMessageAllowed = remember(chat.chatInfo) { chat.chatInfo.featureEnabled(ChatFeature.TimedMessages) }
|
||||
SendMsgView(
|
||||
composeState,
|
||||
showVoiceRecordIcon = true,
|
||||
|
||||
@@ -95,11 +95,11 @@ private fun ContactPreferencesLayout(
|
||||
applyPrefs(featuresAllowed.copy(fullDelete = it))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
// val allowReactions: MutableState<ContactFeatureAllowed> = remember(featuresAllowed) { mutableStateOf(featuresAllowed.reactions) }
|
||||
// FeatureSection(ChatFeature.Reactions, user.fullPreferences.reactions.allow, contact.mergedPreferences.reactions, allowReactions) {
|
||||
// applyPrefs(featuresAllowed.copy(reactions = it))
|
||||
// }
|
||||
// SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
val allowReactions: MutableState<ContactFeatureAllowed> = remember(featuresAllowed) { mutableStateOf(featuresAllowed.reactions) }
|
||||
FeatureSection(ChatFeature.Reactions, user.fullPreferences.reactions.allow, contact.mergedPreferences.reactions, allowReactions) {
|
||||
applyPrefs(featuresAllowed.copy(reactions = it))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
val allowVoice: MutableState<ContactFeatureAllowed> = remember(featuresAllowed) { mutableStateOf(featuresAllowed.voice) }
|
||||
FeatureSection(ChatFeature.Voice, user.fullPreferences.voice.allow, contact.mergedPreferences.voice, allowVoice) {
|
||||
applyPrefs(featuresAllowed.copy(voice = it))
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@ fun GroupMemberInfoView(
|
||||
switchMemberAddress = {
|
||||
showSwitchAddressAlert(switchAddress = {
|
||||
withApi {
|
||||
chatModel.controller.apiSwitchGroupMember(groupInfo.apiId, member.groupMemberId)
|
||||
connStats.value = chatModel.controller.apiSwitchGroupMember(groupInfo.apiId, member.groupMemberId)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
+11
-11
@@ -30,9 +30,9 @@ fun GroupPreferencesView(m: ChatModel, chatId: String, close: () -> Unit,) {
|
||||
fun savePrefs(afterSave: () -> Unit = {}) {
|
||||
withApi {
|
||||
val gp = gInfo.groupProfile.copy(groupPreferences = preferences.toGroupPreferences())
|
||||
val gInfo = m.controller.apiUpdateGroup(gInfo.groupId, gp)
|
||||
if (gInfo != null) {
|
||||
m.updateGroup(gInfo)
|
||||
val g = m.controller.apiUpdateGroup(gInfo.groupId, gp)
|
||||
if (g != null) {
|
||||
m.updateGroup(g)
|
||||
currentPreferences = preferences
|
||||
}
|
||||
afterSave()
|
||||
@@ -74,11 +74,11 @@ private fun GroupPreferencesLayout(
|
||||
AppBarTitle(stringResource(R.string.group_preferences))
|
||||
val timedMessages = remember(preferences) { mutableStateOf(preferences.timedMessages.enable) }
|
||||
val onTTLUpdated = { ttl: Int? ->
|
||||
applyPrefs(preferences.copy(timedMessages = preferences.timedMessages.copy(ttl = ttl ?: 86400)))
|
||||
applyPrefs(preferences.copy(timedMessages = preferences.timedMessages.copy(ttl = ttl)))
|
||||
}
|
||||
FeatureSection(GroupFeature.TimedMessages, timedMessages, groupInfo, preferences, onTTLUpdated) { enable ->
|
||||
if (enable == GroupFeatureEnabled.ON) {
|
||||
applyPrefs(preferences.copy(timedMessages = TimedMessagesGroupPreference(enable = enable, ttl = preferences.timedMessages.ttl ?: 86400)))
|
||||
applyPrefs(preferences.copy(timedMessages = TimedMessagesGroupPreference(enable = enable, ttl = preferences.timedMessages.ttl ?: 86400)))
|
||||
} else {
|
||||
applyPrefs(preferences.copy(timedMessages = TimedMessagesGroupPreference(enable = enable, ttl = currentPreferences.timedMessages.ttl)))
|
||||
}
|
||||
@@ -94,11 +94,11 @@ private fun GroupPreferencesLayout(
|
||||
applyPrefs(preferences.copy(fullDelete = GroupPreference(enable = it)))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
// val allowReactions = remember(preferences) { mutableStateOf(preferences.reactions.enable) }
|
||||
// FeatureSection(GroupFeature.Reactions, allowReactions, groupInfo, preferences, onTTLUpdated) {
|
||||
// applyPrefs(preferences.copy(reactions = GroupPreference(enable = it)))
|
||||
// }
|
||||
// SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
val allowReactions = remember(preferences) { mutableStateOf(preferences.reactions.enable) }
|
||||
FeatureSection(GroupFeature.Reactions, allowReactions, groupInfo, preferences, onTTLUpdated) {
|
||||
applyPrefs(preferences.copy(reactions = GroupPreference(enable = it)))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
val allowVoice = remember(preferences) { mutableStateOf(preferences.voice.enable) }
|
||||
FeatureSection(GroupFeature.Voice, allowVoice, groupInfo, preferences, onTTLUpdated) {
|
||||
applyPrefs(preferences.copy(voice = GroupPreference(enable = it)))
|
||||
@@ -144,7 +144,7 @@ private fun FeatureSection(
|
||||
selection = ttl,
|
||||
propagateExternalSelectionUpdate = true, // for Reset
|
||||
label = generalGetString(R.string.delete_after),
|
||||
dropdownValues = TimedMessagesPreference.ttlValues.filterNotNull(), // TODO in 5.2 - allow "off"
|
||||
dropdownValues = TimedMessagesPreference.ttlValues,
|
||||
customPickerTitle = generalGetString(R.string.delete_after),
|
||||
customPickerConfirmButtonText = generalGetString(R.string.custom_time_picker_select),
|
||||
onSelected = onTTLUpdated
|
||||
|
||||
@@ -123,8 +123,8 @@ data class TimeUnitLimits(
|
||||
CustomTimeUnit.Minute -> TimeUnitLimits(CustomTimeUnit.Minute, maxValue = 120)
|
||||
CustomTimeUnit.Hour -> TimeUnitLimits(CustomTimeUnit.Hour, maxValue = 72)
|
||||
CustomTimeUnit.Day -> TimeUnitLimits(CustomTimeUnit.Day, maxValue = 60)
|
||||
CustomTimeUnit.Week -> TimeUnitLimits(CustomTimeUnit.Week, maxValue = 12) // TODO in 5.2 - 54
|
||||
CustomTimeUnit.Month -> TimeUnitLimits(CustomTimeUnit.Month, maxValue = 3) // TODO in 5.2 - 12
|
||||
CustomTimeUnit.Week -> TimeUnitLimits(CustomTimeUnit.Week, maxValue = 52)
|
||||
CustomTimeUnit.Month -> TimeUnitLimits(CustomTimeUnit.Month, maxValue = 12)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-15
@@ -9,7 +9,6 @@ import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@@ -45,15 +44,14 @@ fun CreateSimpleXAddress(m: ChatModel) {
|
||||
val connReqContact = m.controller.apiCreateUserAddress()
|
||||
if (connReqContact != null) {
|
||||
m.userAddress.value = UserContactLinkRec(connReqContact)
|
||||
// TODO uncomment in v5.2
|
||||
// try {
|
||||
// val u = m.controller.apiSetProfileAddress(true)
|
||||
// if (u != null) {
|
||||
// m.updateUser(u)
|
||||
// }
|
||||
// } catch (e: Exception) {
|
||||
// Log.e(TAG, "CreateSimpleXAddress apiSetProfileAddress: ${e.stackTraceToString()}")
|
||||
// }
|
||||
try {
|
||||
val u = m.controller.apiSetProfileAddress(true)
|
||||
if (u != null) {
|
||||
m.updateUser(u)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "CreateSimpleXAddress apiSetProfileAddress: ${e.stackTraceToString()}")
|
||||
}
|
||||
progressIndicator = false
|
||||
}
|
||||
}
|
||||
@@ -94,8 +92,7 @@ private fun CreateSimpleXAddressLayout(
|
||||
ContinueButton(nextStep)
|
||||
} else {
|
||||
CreateAddressButton(createAddress)
|
||||
// TODO remove color in v5.2
|
||||
TextBelowButton(stringResource(R.string.your_contacts_will_see_it), color = Color.Transparent)
|
||||
TextBelowButton(stringResource(R.string.your_contacts_will_see_it))
|
||||
Spacer(Modifier.weight(1f))
|
||||
SkipButton(nextStep)
|
||||
}
|
||||
@@ -144,8 +141,7 @@ private fun SkipButton(onClick: () -> Unit) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TextBelowButton(text: String, color: Color = Color.Unspecified) {
|
||||
// TODO remove color in v5.2
|
||||
private fun TextBelowButton(text: String) {
|
||||
Text(
|
||||
text,
|
||||
Modifier
|
||||
@@ -153,7 +149,6 @@ private fun TextBelowButton(text: String, color: Color = Color.Unspecified) {
|
||||
.padding(horizontal = DEFAULT_PADDING * 3),
|
||||
style = MaterialTheme.typography.subtitle1,
|
||||
textAlign = TextAlign.Center,
|
||||
color = color
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -71,11 +71,11 @@ private fun PreferencesLayout(
|
||||
applyPrefs(preferences.copy(fullDelete = SimpleChatPreference(allow = it)))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
// val allowReactions = remember(preferences) { mutableStateOf(preferences.reactions.allow) }
|
||||
// FeatureSection(ChatFeature.Reactions, allowReactions) {
|
||||
// applyPrefs(preferences.copy(reactions = SimpleChatPreference(allow = it)))
|
||||
// }
|
||||
// SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
val allowReactions = remember(preferences) { mutableStateOf(preferences.reactions.allow) }
|
||||
FeatureSection(ChatFeature.Reactions, allowReactions) {
|
||||
applyPrefs(preferences.copy(reactions = SimpleChatPreference(allow = it)))
|
||||
}
|
||||
SectionDividerSpaced(true, maxBottomPadding = false)
|
||||
val allowVoice = remember(preferences) { mutableStateOf(preferences.voice.allow) }
|
||||
FeatureSection(ChatFeature.Voice, allowVoice) {
|
||||
applyPrefs(preferences.copy(voice = SimpleChatPreference(allow = it)))
|
||||
|
||||
+10
-12
@@ -69,16 +69,15 @@ fun UserAddressView(
|
||||
if (connReqContact != null) {
|
||||
chatModel.userAddress.value = UserContactLinkRec(connReqContact)
|
||||
|
||||
// TODO uncomment in v5.2
|
||||
// AlertManager.shared.showAlertDialog(
|
||||
// title = generalGetString(R.string.share_address_with_contacts_question),
|
||||
// text = generalGetString(R.string.add_address_to_your_profile),
|
||||
// confirmText = generalGetString(R.string.share_verb),
|
||||
// onConfirm = {
|
||||
// setProfileAddress(true)
|
||||
// shareViaProfile.value = true
|
||||
// }
|
||||
// )
|
||||
AlertManager.shared.showAlertDialog(
|
||||
title = generalGetString(R.string.share_address_with_contacts_question),
|
||||
text = generalGetString(R.string.add_address_to_your_profile),
|
||||
confirmText = generalGetString(R.string.share_verb),
|
||||
onConfirm = {
|
||||
setProfileAddress(true)
|
||||
shareViaProfile.value = true
|
||||
}
|
||||
)
|
||||
}
|
||||
progressIndicator = false
|
||||
}
|
||||
@@ -204,8 +203,7 @@ private fun UserAddressLayout(
|
||||
QRCode(userAddress.connReqContact, Modifier.padding(horizontal = DEFAULT_PADDING, vertical = DEFAULT_PADDING_HALF).aspectRatio(1f))
|
||||
ShareAddressButton { share(userAddress.connReqContact) }
|
||||
ShareViaEmailButton { sendEmail(userAddress) }
|
||||
// TODO uncomment in v5.2
|
||||
// ShareWithContactsButton(shareViaProfile, setProfileAddress)
|
||||
ShareWithContactsButton(shareViaProfile, setProfileAddress)
|
||||
AutoAcceptToggle(autoAcceptState) { saveAas(autoAcceptState.value, autoAcceptStateSaved) }
|
||||
LearnMoreButton(learnMore)
|
||||
}
|
||||
|
||||
@@ -480,12 +480,16 @@ func apiGroupMemberInfo(_ groupId: Int64, _ groupMemberId: Int64) throws -> (Con
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiSwitchContact(contactId: Int64) async throws {
|
||||
try await sendCommandOkResp(.apiSwitchContact(contactId: contactId))
|
||||
func apiSwitchContact(contactId: Int64) throws -> ConnectionStats {
|
||||
let r = chatSendCmdSync(.apiSwitchContact(contactId: contactId))
|
||||
if case let .contactSwitchStarted(_, _, connectionStats) = r { return connectionStats }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiSwitchGroupMember(_ groupId: Int64, _ groupMemberId: Int64) async throws {
|
||||
try await sendCommandOkResp(.apiSwitchGroupMember(groupId: groupId, groupMemberId: groupMemberId))
|
||||
func apiSwitchGroupMember(_ groupId: Int64, _ groupMemberId: Int64) throws -> ConnectionStats {
|
||||
let r = chatSendCmdSync(.apiSwitchGroupMember(groupId: groupId, groupMemberId: groupMemberId))
|
||||
if case let .groupMemberSwitchStarted(_, _, _, connectionStats) = r { return connectionStats }
|
||||
throw r
|
||||
}
|
||||
|
||||
func apiAbortSwitchContact(_ contactId: Int64) throws -> ConnectionStats {
|
||||
|
||||
@@ -368,7 +368,8 @@ struct ChatInfoView: View {
|
||||
private func switchContactAddress() {
|
||||
Task {
|
||||
do {
|
||||
try await apiSwitchContact(contactId: contact.apiId)
|
||||
let stats = try apiSwitchContact(contactId: contact.apiId)
|
||||
connectionStats = stats
|
||||
} catch let error {
|
||||
logger.error("switchContactAddress apiSwitchContact error: \(responseError(error))")
|
||||
let a = getErrorAlert(error, "Error changing address")
|
||||
|
||||
@@ -296,9 +296,7 @@ struct ComposeView: View {
|
||||
},
|
||||
finishVoiceMessageRecording: finishVoiceMessageRecording,
|
||||
allowVoiceMessagesToContact: allowVoiceMessagesToContact,
|
||||
// TODO in 5.2 - allow if ttl is not configured
|
||||
// timedMessageAllowed: chat.chatInfo.featureEnabled(.timedMessages),
|
||||
timedMessageAllowed: chat.chatInfo.featureEnabled(.timedMessages) && chat.chatInfo.timedMessagesTTL != nil,
|
||||
timedMessageAllowed: chat.chatInfo.featureEnabled(.timedMessages),
|
||||
onMediaAdded: { media in if !media.isEmpty { chosenMedia = media }},
|
||||
keyboardVisible: $keyboardVisible
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ struct ContactPreferencesView: View {
|
||||
List {
|
||||
timedMessagesFeatureSection()
|
||||
featureSection(.fullDelete, user.fullPreferences.fullDelete.allow, contact.mergedPreferences.fullDelete, $featuresAllowed.fullDelete)
|
||||
// featureSection(.reactions, user.fullPreferences.reactions.allow, contact.mergedPreferences.reactions, $featuresAllowed.reactions)
|
||||
featureSection(.reactions, user.fullPreferences.reactions.allow, contact.mergedPreferences.reactions, $featuresAllowed.reactions)
|
||||
featureSection(.voice, user.fullPreferences.voice.allow, contact.mergedPreferences.voice, $featuresAllowed.voice)
|
||||
featureSection(.calls, user.fullPreferences.calls.allow, contact.mergedPreferences.calls, $featuresAllowed.calls)
|
||||
|
||||
|
||||
@@ -356,7 +356,8 @@ struct GroupMemberInfoView: View {
|
||||
private func switchMemberAddress() {
|
||||
Task {
|
||||
do {
|
||||
try await apiSwitchGroupMember(groupInfo.apiId, member.groupMemberId)
|
||||
let stats = try apiSwitchGroupMember(groupInfo.apiId, member.groupMemberId)
|
||||
connectionStats = stats
|
||||
} catch let error {
|
||||
logger.error("switchMemberAddress apiSwitchGroupMember error: \(responseError(error))")
|
||||
let a = getErrorAlert(error, "Error changing address")
|
||||
|
||||
@@ -25,7 +25,7 @@ struct GroupPreferencesView: View {
|
||||
featureSection(.timedMessages, $preferences.timedMessages.enable)
|
||||
featureSection(.fullDelete, $preferences.fullDelete.enable)
|
||||
featureSection(.directMessages, $preferences.directMessages.enable)
|
||||
// featureSection(.reactions, $preferences.reactions.enable)
|
||||
featureSection(.reactions, $preferences.reactions.enable)
|
||||
featureSection(.voice, $preferences.voice.enable)
|
||||
|
||||
if groupInfo.canEdit {
|
||||
@@ -79,7 +79,7 @@ struct GroupPreferencesView: View {
|
||||
DropdownCustomTimePicker(
|
||||
selection: $preferences.timedMessages.ttl,
|
||||
label: "Delete after",
|
||||
dropdownValues: TimedMessagesPreference.ttlValues.filter { $0 != nil }, // TODO in 5.2 - allow "off"
|
||||
dropdownValues: TimedMessagesPreference.ttlValues,
|
||||
customPickerConfirmButtonText: "Select",
|
||||
customPickerDescription: "Delete after"
|
||||
)
|
||||
|
||||
@@ -26,8 +26,8 @@ struct CustomTimePicker: View {
|
||||
case .minute: return TimeUnitLimits.init(timeUnit: .minute, maxValue: 120)
|
||||
case .hour: return TimeUnitLimits.init(timeUnit: .hour, maxValue: 72)
|
||||
case .day: return TimeUnitLimits.init(timeUnit: .day, maxValue: 60)
|
||||
case .week: return TimeUnitLimits.init(timeUnit: .week, maxValue: 12) // TODO in 5.2 - 54
|
||||
case .month: return TimeUnitLimits.init(timeUnit: .month, maxValue: 3) // TODO in 5.2 - 12
|
||||
case .week: return TimeUnitLimits.init(timeUnit: .week, maxValue: 52)
|
||||
case .month: return TimeUnitLimits.init(timeUnit: .month, maxValue: 12)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -81,12 +81,11 @@ struct CreateSimpleXAddress: View {
|
||||
DispatchQueue.main.async {
|
||||
m.userAddress = UserContactLink(connReqContact: connReqContact)
|
||||
}
|
||||
// TODO uncomment in v5.2
|
||||
// if let u = try await apiSetProfileAddress(on: true) {
|
||||
// DispatchQueue.main.async {
|
||||
// m.updateUser(u)
|
||||
// }
|
||||
// }
|
||||
if let u = try await apiSetProfileAddress(on: true) {
|
||||
DispatchQueue.main.async {
|
||||
m.updateUser(u)
|
||||
}
|
||||
}
|
||||
await MainActor.run { progressIndicator = false }
|
||||
} catch let error {
|
||||
logger.error("CreateSimpleXAddress create address: \(responseError(error))")
|
||||
@@ -102,11 +101,9 @@ struct CreateSimpleXAddress: View {
|
||||
Text("Create SimpleX address").font(.title)
|
||||
}
|
||||
Text("Your contacts in SimpleX will see it.\nYou can change it in Settings.")
|
||||
// TODO remove in in v5.2
|
||||
.foregroundColor(.clear)
|
||||
.multilineTextAlignment(.center)
|
||||
.font(.footnote)
|
||||
.padding(.horizontal, 32)
|
||||
.multilineTextAlignment(.center)
|
||||
.font(.footnote)
|
||||
.padding(.horizontal, 32)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ struct PreferencesView: View {
|
||||
List {
|
||||
timedMessagesFeatureSection($preferences.timedMessages.allow)
|
||||
featureSection(.fullDelete, $preferences.fullDelete.allow)
|
||||
// featureSection(.reactions, $preferences.reactions.allow)
|
||||
featureSection(.reactions, $preferences.reactions.allow)
|
||||
featureSection(.voice, $preferences.voice.allow)
|
||||
featureSection(.calls, $preferences.calls.allow)
|
||||
|
||||
|
||||
@@ -195,8 +195,7 @@ struct UserAddressView: View {
|
||||
if MFMailComposeViewController.canSendMail() {
|
||||
shareViaEmailButton(userAddress)
|
||||
}
|
||||
// TODO uncomment in 5.2
|
||||
// shareWithContactsButton()
|
||||
shareWithContactsButton()
|
||||
autoAcceptToggle()
|
||||
learnMoreButton()
|
||||
} header: {
|
||||
@@ -223,8 +222,7 @@ struct UserAddressView: View {
|
||||
let connReqContact = try await apiCreateUserAddress()
|
||||
DispatchQueue.main.async {
|
||||
chatModel.userAddress = UserContactLink(connReqContact: connReqContact)
|
||||
// TODO uncomment in 5.2
|
||||
// alert = .shareOnCreate
|
||||
alert = .shareOnCreate
|
||||
progressIndicator = false
|
||||
}
|
||||
} catch let error {
|
||||
|
||||
@@ -403,6 +403,8 @@ public enum ChatResponse: Decodable, Error {
|
||||
case networkConfig(networkConfig: NetCfg)
|
||||
case contactInfo(user: User, contact: Contact, connectionStats: ConnectionStats, customUserProfile: Profile?)
|
||||
case groupMemberInfo(user: User, groupInfo: GroupInfo, member: GroupMember, connectionStats_: ConnectionStats?)
|
||||
case contactSwitchStarted(user: User, contact: Contact, connectionStats: ConnectionStats)
|
||||
case groupMemberSwitchStarted(user: User, groupInfo: GroupInfo, member: GroupMember, connectionStats: ConnectionStats)
|
||||
case contactSwitchAborted(user: User, contact: Contact, connectionStats: ConnectionStats)
|
||||
case groupMemberSwitchAborted(user: User, groupInfo: GroupInfo, member: GroupMember, connectionStats: ConnectionStats)
|
||||
case contactCode(user: User, contact: Contact, connectionCode: String)
|
||||
@@ -524,6 +526,8 @@ public enum ChatResponse: Decodable, Error {
|
||||
case .networkConfig: return "networkConfig"
|
||||
case .contactInfo: return "contactInfo"
|
||||
case .groupMemberInfo: return "groupMemberInfo"
|
||||
case .contactSwitchStarted: return "contactSwitchStarted"
|
||||
case .groupMemberSwitchStarted: return "groupMemberSwitchStarted"
|
||||
case .contactSwitchAborted: return "contactSwitchAborted"
|
||||
case .groupMemberSwitchAborted: return "groupMemberSwitchAborted"
|
||||
case .contactCode: return "contactCode"
|
||||
@@ -644,6 +648,8 @@ public enum ChatResponse: Decodable, Error {
|
||||
case let .networkConfig(networkConfig): return String(describing: networkConfig)
|
||||
case let .contactInfo(u, contact, connectionStats, customUserProfile): return withUser(u, "contact: \(String(describing: contact))\nconnectionStats: \(String(describing: connectionStats))\ncustomUserProfile: \(String(describing: customUserProfile))")
|
||||
case let .groupMemberInfo(u, groupInfo, member, connectionStats_): return withUser(u, "groupInfo: \(String(describing: groupInfo))\nmember: \(String(describing: member))\nconnectionStats_: \(String(describing: connectionStats_))")
|
||||
case let .contactSwitchStarted(u, contact, connectionStats): return withUser(u, "contact: \(String(describing: contact))\nconnectionStats: \(String(describing: connectionStats))")
|
||||
case let .groupMemberSwitchStarted(u, groupInfo, member, connectionStats): return withUser(u, "groupInfo: \(String(describing: groupInfo))\nmember: \(String(describing: member))\nconnectionStats: \(String(describing: connectionStats))")
|
||||
case let .contactSwitchAborted(u, contact, connectionStats): return withUser(u, "contact: \(String(describing: contact))\nconnectionStats: \(String(describing: connectionStats))")
|
||||
case let .groupMemberSwitchAborted(u, groupInfo, member, connectionStats): return withUser(u, "groupInfo: \(String(describing: groupInfo))\nmember: \(String(describing: member))\nconnectionStats: \(String(describing: connectionStats))")
|
||||
case let .contactCode(u, contact, connectionCode): return withUser(u, "contact: \(String(describing: contact))\nconnectionCode: \(connectionCode)")
|
||||
|
||||
@@ -201,7 +201,7 @@ myAddressHelpInfo =
|
||||
styleMarkdown
|
||||
[ green "Your contact address commands:",
|
||||
indent <> highlight "/address " <> " - create your address",
|
||||
-- indent <> highlight "/profile_address on/off " <> " - share address with your contacts (it will be added to your profile)",
|
||||
indent <> highlight "/profile_address on/off " <> " - share address with your contacts (it will be added to your profile)",
|
||||
indent <> highlight "/delete_address " <> " - delete your address (accepted contacts will remain connected)",
|
||||
indent <> highlight "/show_address " <> " - show your address",
|
||||
indent <> highlight "/accept <name> " <> " - accept contact request",
|
||||
|
||||
@@ -641,7 +641,7 @@ connReqContact_ intro cReq =
|
||||
"",
|
||||
"Anybody can send you contact requests with: " <> highlight' "/c <contact_link_above>",
|
||||
"to show it again: " <> highlight' "/sa",
|
||||
-- "to share with your contacts: " <> highlight' "/profile_address on",
|
||||
"to share with your contacts: " <> highlight' "/profile_address on",
|
||||
"to delete it: " <> highlight' "/da" <> " (accepted contacts will remain connected)"
|
||||
]
|
||||
|
||||
|
||||
@@ -358,7 +358,7 @@ getContactLink cc created = do
|
||||
cc <## ""
|
||||
cc <## "Anybody can send you contact requests with: /c <contact_link_above>"
|
||||
cc <## "to show it again: /sa"
|
||||
-- cc <## "to share with your contacts: /profile_address on"
|
||||
cc <## "to share with your contacts: /profile_address on"
|
||||
cc <## "to delete it: /da (accepted contacts will remain connected)"
|
||||
pure link
|
||||
|
||||
|
||||
Reference in New Issue
Block a user