mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-05-14 23:25:33 +00:00
mobile: Calls chat preference (#2195)
* ios: add calls to chat preferences * android: types and strings for Calls preference * android: UI for Calls preference
This commit is contained in:
committed by
GitHub
parent
e6c87ff00b
commit
6913bf1a46
@@ -729,6 +729,7 @@ data class Contact(
|
||||
ChatFeature.TimedMessages -> mergedPreferences.timedMessages.enabled.forUser
|
||||
ChatFeature.FullDelete -> mergedPreferences.fullDelete.enabled.forUser
|
||||
ChatFeature.Voice -> mergedPreferences.voice.enabled.forUser
|
||||
ChatFeature.Calls -> mergedPreferences.calls.enabled.forUser
|
||||
}
|
||||
override val timedMessagesTTL: Int? get() = with(mergedPreferences.timedMessages) { if (enabled.forUser) userPreference.pref.ttl else null }
|
||||
override val displayName get() = localAlias.ifEmpty { profile.displayName }
|
||||
@@ -747,12 +748,14 @@ data class Contact(
|
||||
ChatFeature.TimedMessages -> mergedPreferences.timedMessages.contactPreference.allow != FeatureAllowed.NO
|
||||
ChatFeature.FullDelete -> mergedPreferences.fullDelete.contactPreference.allow != FeatureAllowed.NO
|
||||
ChatFeature.Voice -> mergedPreferences.voice.contactPreference.allow != FeatureAllowed.NO
|
||||
ChatFeature.Calls -> mergedPreferences.calls.contactPreference.allow != FeatureAllowed.NO
|
||||
}
|
||||
|
||||
fun userAllowsFeature(feature: ChatFeature): Boolean = when (feature) {
|
||||
ChatFeature.TimedMessages -> mergedPreferences.timedMessages.userPreference.pref.allow != FeatureAllowed.NO
|
||||
ChatFeature.FullDelete -> mergedPreferences.fullDelete.userPreference.pref.allow != FeatureAllowed.NO
|
||||
ChatFeature.Voice -> mergedPreferences.voice.userPreference.pref.allow != FeatureAllowed.NO
|
||||
ChatFeature.Calls -> mergedPreferences.calls.userPreference.pref.allow != FeatureAllowed.NO
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -882,6 +885,7 @@ data class GroupInfo (
|
||||
ChatFeature.TimedMessages -> fullGroupPreferences.timedMessages.on
|
||||
ChatFeature.FullDelete -> fullGroupPreferences.fullDelete.on
|
||||
ChatFeature.Voice -> fullGroupPreferences.voice.on
|
||||
ChatFeature.Calls -> false
|
||||
}
|
||||
override val timedMessagesTTL: Int? get() = with(fullGroupPreferences.timedMessages) { if (on) ttl else null }
|
||||
override val displayName get() = groupProfile.displayName
|
||||
|
||||
@@ -2410,14 +2410,16 @@ data class FullChatPreferences(
|
||||
val timedMessages: TimedMessagesPreference,
|
||||
val fullDelete: SimpleChatPreference,
|
||||
val voice: SimpleChatPreference,
|
||||
val calls: SimpleChatPreference,
|
||||
) {
|
||||
fun toPreferences(): ChatPreferences = ChatPreferences(timedMessages = timedMessages, fullDelete = fullDelete, voice = voice)
|
||||
fun toPreferences(): ChatPreferences = ChatPreferences(timedMessages = timedMessages, fullDelete = fullDelete, voice = voice, calls = calls)
|
||||
|
||||
companion object {
|
||||
val sampleData = FullChatPreferences(
|
||||
timedMessages = TimedMessagesPreference(allow = FeatureAllowed.NO),
|
||||
fullDelete = SimpleChatPreference(allow = FeatureAllowed.NO),
|
||||
voice = SimpleChatPreference(allow = FeatureAllowed.YES)
|
||||
voice = SimpleChatPreference(allow = FeatureAllowed.YES),
|
||||
calls = SimpleChatPreference(allow = FeatureAllowed.YES),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2427,19 +2429,22 @@ data class ChatPreferences(
|
||||
val timedMessages: TimedMessagesPreference?,
|
||||
val fullDelete: SimpleChatPreference?,
|
||||
val voice: SimpleChatPreference?,
|
||||
val calls: SimpleChatPreference?,
|
||||
) {
|
||||
fun setAllowed(feature: ChatFeature, allowed: FeatureAllowed = FeatureAllowed.YES, param: Int? = null): ChatPreferences =
|
||||
when (feature) {
|
||||
ChatFeature.TimedMessages -> this.copy(timedMessages = TimedMessagesPreference(allow = allowed, ttl = param ?: this.timedMessages?.ttl))
|
||||
ChatFeature.FullDelete -> this.copy(fullDelete = SimpleChatPreference(allow = allowed))
|
||||
ChatFeature.Voice -> this.copy(voice = SimpleChatPreference(allow = allowed))
|
||||
ChatFeature.Calls -> this.copy(calls = SimpleChatPreference(allow = allowed))
|
||||
}
|
||||
|
||||
companion object {
|
||||
val sampleData = ChatPreferences(
|
||||
timedMessages = TimedMessagesPreference(allow = FeatureAllowed.NO),
|
||||
fullDelete = SimpleChatPreference(allow = FeatureAllowed.NO),
|
||||
voice = SimpleChatPreference(allow = FeatureAllowed.YES)
|
||||
voice = SimpleChatPreference(allow = FeatureAllowed.YES),
|
||||
calls = SimpleChatPreference(allow = FeatureAllowed.YES),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2511,11 +2516,13 @@ data class ContactUserPreferences(
|
||||
val timedMessages: ContactUserPreferenceTimed,
|
||||
val fullDelete: ContactUserPreference,
|
||||
val voice: ContactUserPreference,
|
||||
val calls: ContactUserPreference,
|
||||
) {
|
||||
fun toPreferences(): ChatPreferences = ChatPreferences(
|
||||
timedMessages = timedMessages.userPreference.pref,
|
||||
fullDelete = fullDelete.userPreference.pref,
|
||||
voice = voice.userPreference.pref
|
||||
voice = voice.userPreference.pref,
|
||||
calls = calls.userPreference.pref
|
||||
)
|
||||
|
||||
companion object {
|
||||
@@ -2534,7 +2541,12 @@ data class ContactUserPreferences(
|
||||
enabled = FeatureEnabled(forUser = true, forContact = true),
|
||||
userPreference = ContactUserPref.User(preference = SimpleChatPreference(allow = FeatureAllowed.YES)),
|
||||
contactPreference = SimpleChatPreference(allow = FeatureAllowed.YES)
|
||||
)
|
||||
),
|
||||
calls = ContactUserPreference(
|
||||
enabled = FeatureEnabled(forUser = true, forContact = true),
|
||||
userPreference = ContactUserPref.User(preference = SimpleChatPreference(allow = FeatureAllowed.YES)),
|
||||
contactPreference = SimpleChatPreference(allow = FeatureAllowed.YES)
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2620,7 +2632,8 @@ interface Feature {
|
||||
enum class ChatFeature: Feature {
|
||||
@SerialName("timedMessages") TimedMessages,
|
||||
@SerialName("fullDelete") FullDelete,
|
||||
@SerialName("voice") Voice;
|
||||
@SerialName("voice") Voice,
|
||||
@SerialName("calls") Calls;
|
||||
|
||||
val asymmetric: Boolean get() = when (this) {
|
||||
TimedMessages -> false
|
||||
@@ -2637,6 +2650,7 @@ enum class ChatFeature: Feature {
|
||||
TimedMessages -> generalGetString(R.string.timed_messages)
|
||||
FullDelete -> generalGetString(R.string.full_deletion)
|
||||
Voice -> generalGetString(R.string.voice_messages)
|
||||
Calls -> generalGetString(R.string.audio_video_calls)
|
||||
}
|
||||
|
||||
val icon: ImageVector
|
||||
@@ -2644,6 +2658,7 @@ enum class ChatFeature: Feature {
|
||||
TimedMessages -> Icons.Outlined.Timer
|
||||
FullDelete -> Icons.Outlined.DeleteForever
|
||||
Voice -> Icons.Outlined.KeyboardVoice
|
||||
Calls -> Icons.Outlined.Phone
|
||||
}
|
||||
|
||||
override val iconFilled: ImageVector
|
||||
@@ -2651,6 +2666,7 @@ enum class ChatFeature: Feature {
|
||||
TimedMessages -> Icons.Filled.Timer
|
||||
FullDelete -> Icons.Filled.DeleteForever
|
||||
Voice -> Icons.Filled.KeyboardVoice
|
||||
Calls -> Icons.Filled.Phone
|
||||
}
|
||||
|
||||
fun allowDescription(allowed: FeatureAllowed): String =
|
||||
@@ -2670,6 +2686,11 @@ enum class ChatFeature: Feature {
|
||||
FeatureAllowed.YES -> generalGetString(R.string.allow_voice_messages_only_if)
|
||||
FeatureAllowed.NO -> generalGetString(R.string.prohibit_sending_voice_messages)
|
||||
}
|
||||
Calls -> when (allowed) {
|
||||
FeatureAllowed.ALWAYS -> generalGetString(R.string.allow_your_contacts_to_call)
|
||||
FeatureAllowed.YES -> generalGetString(R.string.allow_calls_only_if)
|
||||
FeatureAllowed.NO -> generalGetString(R.string.prohibit_calls)
|
||||
}
|
||||
}
|
||||
|
||||
fun enabledDescription(enabled: FeatureEnabled): String =
|
||||
@@ -2692,7 +2713,13 @@ enum class ChatFeature: Feature {
|
||||
enabled.forContact -> generalGetString(R.string.only_your_contact_can_send_voice)
|
||||
else -> generalGetString(R.string.voice_prohibited_in_this_chat)
|
||||
}
|
||||
}
|
||||
Calls -> when {
|
||||
enabled.forUser && enabled.forContact -> generalGetString(R.string.both_you_and_your_contact_can_make_calls)
|
||||
enabled.forUser -> generalGetString(R.string.only_you_can_make_calls)
|
||||
enabled.forContact -> generalGetString(R.string.only_your_contact_can_make_calls)
|
||||
else -> generalGetString(R.string.calls_prohibited_with_this_contact)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
@@ -2805,14 +2832,16 @@ data class ContactFeaturesAllowed(
|
||||
val timedMessagesAllowed: Boolean,
|
||||
val timedMessagesTTL: Int?,
|
||||
val fullDelete: ContactFeatureAllowed,
|
||||
val voice: ContactFeatureAllowed
|
||||
val voice: ContactFeatureAllowed,
|
||||
val calls: ContactFeatureAllowed,
|
||||
) {
|
||||
companion object {
|
||||
val sampleData = ContactFeaturesAllowed(
|
||||
timedMessagesAllowed = false,
|
||||
timedMessagesTTL = null,
|
||||
fullDelete = ContactFeatureAllowed.UserDefault(FeatureAllowed.NO),
|
||||
voice = ContactFeatureAllowed.UserDefault(FeatureAllowed.YES)
|
||||
voice = ContactFeatureAllowed.UserDefault(FeatureAllowed.YES),
|
||||
calls = ContactFeatureAllowed.UserDefault(FeatureAllowed.YES),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2824,7 +2853,8 @@ fun contactUserPrefsToFeaturesAllowed(contactUserPreferences: ContactUserPrefere
|
||||
timedMessagesAllowed = allow == FeatureAllowed.YES || allow == FeatureAllowed.ALWAYS,
|
||||
timedMessagesTTL = pref.pref.ttl,
|
||||
fullDelete = contactUserPrefToFeatureAllowed(contactUserPreferences.fullDelete),
|
||||
voice = contactUserPrefToFeatureAllowed(contactUserPreferences.voice)
|
||||
voice = contactUserPrefToFeatureAllowed(contactUserPreferences.voice),
|
||||
calls = contactUserPrefToFeatureAllowed(contactUserPreferences.calls),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2842,7 +2872,8 @@ fun contactFeaturesAllowedToPrefs(contactFeaturesAllowed: ContactFeaturesAllowed
|
||||
ChatPreferences(
|
||||
timedMessages = TimedMessagesPreference(if (contactFeaturesAllowed.timedMessagesAllowed) FeatureAllowed.YES else FeatureAllowed.NO, contactFeaturesAllowed.timedMessagesTTL),
|
||||
fullDelete = contactFeatureAllowedToPref(contactFeaturesAllowed.fullDelete),
|
||||
voice = contactFeatureAllowedToPref(contactFeaturesAllowed.voice)
|
||||
voice = contactFeatureAllowedToPref(contactFeaturesAllowed.voice),
|
||||
calls = contactFeatureAllowedToPref(contactFeaturesAllowed.calls),
|
||||
)
|
||||
|
||||
fun contactFeatureAllowedToPref(contactFeatureAllowed: ContactFeatureAllowed): SimpleChatPreference? =
|
||||
|
||||
@@ -398,7 +398,7 @@ fun ChatInfoToolbar(
|
||||
})
|
||||
}
|
||||
|
||||
if (chat.chatInfo is ChatInfo.Direct) {
|
||||
if (chat.chatInfo is ChatInfo.Direct && chat.chatInfo.contact.allowsFeature(ChatFeature.Calls)) {
|
||||
barButtons.add {
|
||||
IconButton({
|
||||
showMenu = false
|
||||
|
||||
@@ -104,6 +104,11 @@ private fun ContactPreferencesLayout(
|
||||
applyPrefs(featuresAllowed.copy(voice = it))
|
||||
}
|
||||
SectionSpacer()
|
||||
val allowCalls: MutableState<ContactFeatureAllowed> = remember(featuresAllowed) { mutableStateOf(featuresAllowed.calls) }
|
||||
FeatureSection(ChatFeature.Calls, user.fullPreferences.calls.allow, contact.mergedPreferences.calls, allowCalls) {
|
||||
applyPrefs(featuresAllowed.copy(calls = it))
|
||||
}
|
||||
SectionSpacer()
|
||||
ResetSaveButtons(
|
||||
reset = reset,
|
||||
save = savePrefs,
|
||||
@@ -138,6 +143,7 @@ private fun FeatureSection(
|
||||
ContactFeatureAllowed.values(userDefault).map { it to it.text },
|
||||
allowFeature,
|
||||
icon = null,
|
||||
enabled = remember { mutableStateOf(feature != ChatFeature.Calls) },
|
||||
onSelected = onSelected
|
||||
)
|
||||
}
|
||||
@@ -147,7 +153,7 @@ private fun FeatureSection(
|
||||
pref.contactPreference.allow.text
|
||||
)
|
||||
}
|
||||
SectionTextFooter(feature.enabledDescription(enabled))
|
||||
SectionTextFooter(feature.enabledDescription(enabled) + (if (feature == ChatFeature.Calls) generalGetString(R.string.available_in_v51) else ""))
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -80,6 +80,11 @@ private fun PreferencesLayout(
|
||||
applyPrefs(preferences.copy(voice = SimpleChatPreference(allow = it)))
|
||||
}
|
||||
SectionSpacer()
|
||||
val allowCalls = remember(preferences) { mutableStateOf(preferences.calls.allow) }
|
||||
FeatureSection(ChatFeature.Calls, allowCalls) {
|
||||
applyPrefs(preferences.copy(calls = SimpleChatPreference(allow = it)))
|
||||
}
|
||||
SectionSpacer()
|
||||
ResetSaveButtons(
|
||||
reset = reset,
|
||||
save = savePrefs,
|
||||
@@ -97,11 +102,12 @@ private fun FeatureSection(feature: ChatFeature, allowFeature: State<FeatureAllo
|
||||
FeatureAllowed.values().map { it to it.text },
|
||||
allowFeature,
|
||||
icon = feature.icon,
|
||||
onSelected = onSelected
|
||||
enabled = remember { mutableStateOf(feature != ChatFeature.Calls) },
|
||||
onSelected = onSelected,
|
||||
)
|
||||
}
|
||||
}
|
||||
SectionTextFooter(feature.allowDescription(allowFeature.value))
|
||||
SectionTextFooter(feature.allowDescription(allowFeature.value) + (if (feature == ChatFeature.Calls) generalGetString(R.string.available_in_v51) else ""))
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
||||
@@ -1176,6 +1176,8 @@
|
||||
<string name="direct_messages">Direct messages</string>
|
||||
<string name="full_deletion">Delete for everyone</string>
|
||||
<string name="voice_messages">Voice messages</string>
|
||||
<string name="audio_video_calls">Audio/video calls</string>
|
||||
<string name="available_in_v51">\nAvailable in v5.1</string>
|
||||
<string name="feature_enabled">enabled</string>
|
||||
<string name="feature_enabled_for_you">enabled for you</string>
|
||||
<string name="feature_enabled_for_contact">enabled for contact</string>
|
||||
@@ -1192,6 +1194,9 @@
|
||||
<string name="allow_your_contacts_to_send_voice_messages">Allow your contacts to send voice messages.</string>
|
||||
<string name="allow_voice_messages_only_if">Allow voice messages only if your contact allows them.</string>
|
||||
<string name="prohibit_sending_voice_messages">Prohibit sending voice messages.</string>
|
||||
<string name="allow_your_contacts_to_call">Allow your contacts to call you.</string>
|
||||
<string name="allow_calls_only_if">Allow calls only if your contact allows them.</string>
|
||||
<string name="prohibit_calls">Prohibit audio/video calls.</string>
|
||||
<string name="both_you_and_your_contact_can_send_disappearing">Both you and your contact can send disappearing messages.</string>
|
||||
<string name="only_you_can_send_disappearing">Only you can send disappearing messages.</string>
|
||||
<string name="only_your_contact_can_send_disappearing">Only your contact can send disappearing messages.</string>
|
||||
@@ -1204,6 +1209,10 @@
|
||||
<string name="only_you_can_send_voice">Only you can send voice messages.</string>
|
||||
<string name="only_your_contact_can_send_voice">Only your contact can send voice messages.</string>
|
||||
<string name="voice_prohibited_in_this_chat">Voice messages are prohibited in this chat.</string>
|
||||
<string name="both_you_and_your_contact_can_make_calls">Both you and your contact can make calls.</string>
|
||||
<string name="only_you_can_make_calls">Only you can make calls.</string>
|
||||
<string name="only_your_contact_can_make_calls">Only your contact can make calls.</string>
|
||||
<string name="calls_prohibited_with_this_contact">Audio/video calls are prohibited.</string>
|
||||
<string name="allow_to_send_disappearing">Allow to send disappearing messages.</string>
|
||||
<string name="prohibit_sending_disappearing">Prohibit sending disappearing messages.</string>
|
||||
<string name="allow_direct_messages">Allow sending direct messages to members.</string>
|
||||
|
||||
@@ -140,12 +140,16 @@ struct ChatView: View {
|
||||
switch cInfo {
|
||||
case let .direct(contact):
|
||||
HStack {
|
||||
callButton(contact, .audio, imageName: "phone")
|
||||
if contact.allowsFeature(.calls) {
|
||||
callButton(contact, .audio, imageName: "phone")
|
||||
}
|
||||
Menu {
|
||||
Button {
|
||||
CallController.shared.startCall(contact, .video)
|
||||
} label: {
|
||||
Label("Video call", systemImage: "video")
|
||||
if contact.allowsFeature(.calls) {
|
||||
Button {
|
||||
CallController.shared.startCall(contact, .video)
|
||||
} label: {
|
||||
Label("Video call", systemImage: "video")
|
||||
}
|
||||
}
|
||||
searchButton()
|
||||
toggleNtfsButton(chat)
|
||||
|
||||
@@ -25,6 +25,7 @@ struct ContactPreferencesView: View {
|
||||
timedMessagesFeatureSection()
|
||||
featureSection(.fullDelete, user.fullPreferences.fullDelete.allow, contact.mergedPreferences.fullDelete, $featuresAllowed.fullDelete)
|
||||
featureSection(.voice, user.fullPreferences.voice.allow, contact.mergedPreferences.voice, $featuresAllowed.voice)
|
||||
featureSection(.calls, user.fullPreferences.calls.allow, contact.mergedPreferences.calls, $featuresAllowed.calls).disabled(true)
|
||||
|
||||
Section {
|
||||
Button("Reset") { featuresAllowed = currentFeaturesAllowed }
|
||||
@@ -106,7 +107,7 @@ struct ContactPreferencesView: View {
|
||||
}
|
||||
|
||||
private func featureFooter(_ feature: ChatFeature, _ enabled: FeatureEnabled) -> some View {
|
||||
Text(feature.enabledDescription(enabled))
|
||||
(Text(feature.enabledDescription(enabled)) + (feature == .calls ? Text("\nAvailable in v5.1").bold() : Text("")))
|
||||
.frame(height: 36, alignment: .topLeading)
|
||||
}
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ struct PreferencesView: View {
|
||||
timedMessagesFeatureSection($preferences.timedMessages.allow)
|
||||
featureSection(.fullDelete, $preferences.fullDelete.allow)
|
||||
featureSection(.voice, $preferences.voice.allow)
|
||||
featureSection(.calls, $preferences.calls.allow).disabled(true)
|
||||
|
||||
Section {
|
||||
Button("Reset") { preferences = currentPreferences }
|
||||
@@ -60,7 +61,7 @@ struct PreferencesView: View {
|
||||
}
|
||||
|
||||
private func featureFooter(_ feature: ChatFeature, _ allowFeature: Binding<FeatureAllowed>) -> some View {
|
||||
Text(feature.allowDescription(allowFeature.wrappedValue))
|
||||
(Text(feature.allowDescription(allowFeature.wrappedValue)) + (feature == .calls ? Text("\nAvailable in v5.1").bold() : Text("")))
|
||||
.frame(height: 36, alignment: .topLeading)
|
||||
}
|
||||
|
||||
|
||||
@@ -162,17 +162,20 @@ public struct FullPreferences: Decodable, Equatable {
|
||||
public var timedMessages: TimedMessagesPreference
|
||||
public var fullDelete: SimplePreference
|
||||
public var voice: SimplePreference
|
||||
public var calls: SimplePreference
|
||||
|
||||
public init(timedMessages: TimedMessagesPreference, fullDelete: SimplePreference, voice: SimplePreference) {
|
||||
public init(timedMessages: TimedMessagesPreference, fullDelete: SimplePreference, voice: SimplePreference, calls: SimplePreference) {
|
||||
self.timedMessages = timedMessages
|
||||
self.fullDelete = fullDelete
|
||||
self.voice = voice
|
||||
self.calls = calls
|
||||
}
|
||||
|
||||
public static let sampleData = FullPreferences(
|
||||
timedMessages: TimedMessagesPreference(allow: .no),
|
||||
fullDelete: SimplePreference(allow: .no),
|
||||
voice: SimplePreference(allow: .yes)
|
||||
voice: SimplePreference(allow: .yes),
|
||||
calls: SimplePreference(allow: .yes)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -180,18 +183,21 @@ public struct Preferences: Codable {
|
||||
public var timedMessages: TimedMessagesPreference?
|
||||
public var fullDelete: SimplePreference?
|
||||
public var voice: SimplePreference?
|
||||
public var calls: SimplePreference?
|
||||
|
||||
public init(timedMessages: TimedMessagesPreference?, fullDelete: SimplePreference?, voice: SimplePreference?) {
|
||||
public init(timedMessages: TimedMessagesPreference?, fullDelete: SimplePreference?, voice: SimplePreference?, calls: SimplePreference?) {
|
||||
self.timedMessages = timedMessages
|
||||
self.fullDelete = fullDelete
|
||||
self.voice = voice
|
||||
self.calls = calls
|
||||
}
|
||||
|
||||
func copy(timedMessages: TimedMessagesPreference? = nil, fullDelete: SimplePreference? = nil, voice: SimplePreference? = nil) -> Preferences {
|
||||
func copy(timedMessages: TimedMessagesPreference? = nil, fullDelete: SimplePreference? = nil, voice: SimplePreference? = nil, calls: SimplePreference? = nil) -> Preferences {
|
||||
Preferences(
|
||||
timedMessages: timedMessages ?? self.timedMessages,
|
||||
fullDelete: fullDelete ?? self.fullDelete,
|
||||
voice: voice ?? self.voice
|
||||
voice: voice ?? self.voice,
|
||||
calls: calls ?? self.calls
|
||||
)
|
||||
}
|
||||
|
||||
@@ -200,13 +206,15 @@ public struct Preferences: Codable {
|
||||
case .timedMessages: return copy(timedMessages: TimedMessagesPreference(allow: allowed, ttl: param ?? timedMessages?.ttl))
|
||||
case .fullDelete: return copy(fullDelete: SimplePreference(allow: allowed))
|
||||
case .voice: return copy(voice: SimplePreference(allow: allowed))
|
||||
case .calls: return copy(calls: SimplePreference(allow: allowed))
|
||||
}
|
||||
}
|
||||
|
||||
public static let sampleData = Preferences(
|
||||
timedMessages: TimedMessagesPreference(allow: .no),
|
||||
fullDelete: SimplePreference(allow: .no),
|
||||
voice: SimplePreference(allow: .yes)
|
||||
voice: SimplePreference(allow: .yes),
|
||||
calls: SimplePreference(allow: .yes)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -214,7 +222,8 @@ public func fullPreferencesToPreferences(_ fullPreferences: FullPreferences) ->
|
||||
Preferences(
|
||||
timedMessages: fullPreferences.timedMessages,
|
||||
fullDelete: fullPreferences.fullDelete,
|
||||
voice: fullPreferences.voice
|
||||
voice: fullPreferences.voice,
|
||||
calls: fullPreferences.calls
|
||||
)
|
||||
}
|
||||
|
||||
@@ -222,7 +231,8 @@ public func contactUserPreferencesToPreferences(_ contactUserPreferences: Contac
|
||||
Preferences(
|
||||
timedMessages: contactUserPreferences.timedMessages.userPreference.preference,
|
||||
fullDelete: contactUserPreferences.fullDelete.userPreference.preference,
|
||||
voice: contactUserPreferences.voice.userPreference.preference
|
||||
voice: contactUserPreferences.voice.userPreference.preference,
|
||||
calls: contactUserPreferences.calls.userPreference.preference
|
||||
)
|
||||
}
|
||||
|
||||
@@ -308,15 +318,18 @@ public struct ContactUserPreferences: Decodable {
|
||||
public var timedMessages: ContactUserPreference<TimedMessagesPreference>
|
||||
public var fullDelete: ContactUserPreference<SimplePreference>
|
||||
public var voice: ContactUserPreference<SimplePreference>
|
||||
public var calls: ContactUserPreference<SimplePreference>
|
||||
|
||||
public init(
|
||||
timedMessages: ContactUserPreference<TimedMessagesPreference>,
|
||||
fullDelete: ContactUserPreference<SimplePreference>,
|
||||
voice: ContactUserPreference<SimplePreference>
|
||||
voice: ContactUserPreference<SimplePreference>,
|
||||
calls: ContactUserPreference<SimplePreference>
|
||||
) {
|
||||
self.timedMessages = timedMessages
|
||||
self.fullDelete = fullDelete
|
||||
self.voice = voice
|
||||
self.calls = calls
|
||||
}
|
||||
|
||||
public static let sampleData = ContactUserPreferences(
|
||||
@@ -334,6 +347,11 @@ public struct ContactUserPreferences: Decodable {
|
||||
enabled: FeatureEnabled(forUser: true, forContact: true),
|
||||
userPreference: ContactUserPref<SimplePreference>.user(preference: SimplePreference(allow: .yes)),
|
||||
contactPreference: SimplePreference(allow: .yes)
|
||||
),
|
||||
calls: ContactUserPreference<SimplePreference>(
|
||||
enabled: FeatureEnabled(forUser: true, forContact: true),
|
||||
userPreference: ContactUserPref<SimplePreference>.user(preference: SimplePreference(allow: .yes)),
|
||||
contactPreference: SimplePreference(allow: .yes)
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -405,6 +423,7 @@ public enum ChatFeature: String, Decodable, Feature {
|
||||
case timedMessages
|
||||
case fullDelete
|
||||
case voice
|
||||
case calls
|
||||
|
||||
public var values: [ChatFeature] { [.fullDelete, .voice] }
|
||||
|
||||
@@ -429,6 +448,7 @@ public enum ChatFeature: String, Decodable, Feature {
|
||||
case .timedMessages: return NSLocalizedString("Disappearing messages", comment: "chat feature")
|
||||
case .fullDelete: return NSLocalizedString("Delete for everyone", comment: "chat feature")
|
||||
case .voice: return NSLocalizedString("Voice messages", comment: "chat feature")
|
||||
case .calls: return NSLocalizedString("Audio/video calls", comment: "chat feature")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,6 +457,7 @@ public enum ChatFeature: String, Decodable, Feature {
|
||||
case .timedMessages: return "stopwatch"
|
||||
case .fullDelete: return "trash.slash"
|
||||
case .voice: return "mic"
|
||||
case .calls: return "phone"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,6 +466,7 @@ public enum ChatFeature: String, Decodable, Feature {
|
||||
case .timedMessages: return "stopwatch.fill"
|
||||
case .fullDelete: return "trash.slash.fill"
|
||||
case .voice: return "mic.fill"
|
||||
case .calls: return "phone.fill"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -475,6 +497,12 @@ public enum ChatFeature: String, Decodable, Feature {
|
||||
case .yes: return "Allow voice messages only if your contact allows them."
|
||||
case .no: return "Prohibit sending voice messages."
|
||||
}
|
||||
case .calls:
|
||||
switch allowed {
|
||||
case .always: return "Allow your contacts to call you."
|
||||
case .yes: return "Allow calls only if your contact allows them."
|
||||
case .no: return "Prohibit audio/video calls."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -504,6 +532,14 @@ public enum ChatFeature: String, Decodable, Feature {
|
||||
: enabled.forContact
|
||||
? "Only your contact can send voice messages."
|
||||
: "Voice messages are prohibited in this chat."
|
||||
case .calls:
|
||||
return enabled.forUser && enabled.forContact
|
||||
? "Both you and your contact can make calls."
|
||||
: enabled.forUser
|
||||
? "Only you can make calls."
|
||||
: enabled.forContact
|
||||
? "Only your contact can make calls."
|
||||
: "Audio/video calls are prohibited."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -646,19 +682,22 @@ public struct ContactFeaturesAllowed: Equatable {
|
||||
public var timedMessagesTTL: Int?
|
||||
public var fullDelete: ContactFeatureAllowed
|
||||
public var voice: ContactFeatureAllowed
|
||||
public var calls: ContactFeatureAllowed
|
||||
|
||||
public init(timedMessagesAllowed: Bool, timedMessagesTTL: Int?, fullDelete: ContactFeatureAllowed, voice: ContactFeatureAllowed) {
|
||||
public init(timedMessagesAllowed: Bool, timedMessagesTTL: Int?, fullDelete: ContactFeatureAllowed, voice: ContactFeatureAllowed, calls: ContactFeatureAllowed) {
|
||||
self.timedMessagesAllowed = timedMessagesAllowed
|
||||
self.timedMessagesTTL = timedMessagesTTL
|
||||
self.fullDelete = fullDelete
|
||||
self.voice = voice
|
||||
self.calls = calls
|
||||
}
|
||||
|
||||
public static let sampleData = ContactFeaturesAllowed(
|
||||
timedMessagesAllowed: false,
|
||||
timedMessagesTTL: nil,
|
||||
fullDelete: ContactFeatureAllowed.userDefault(.no),
|
||||
voice: ContactFeatureAllowed.userDefault(.yes)
|
||||
voice: ContactFeatureAllowed.userDefault(.yes),
|
||||
calls: ContactFeatureAllowed.userDefault(.yes)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -669,7 +708,8 @@ public func contactUserPrefsToFeaturesAllowed(_ contactUserPreferences: ContactU
|
||||
timedMessagesAllowed: allow == .yes || allow == .always,
|
||||
timedMessagesTTL: pref.preference.ttl,
|
||||
fullDelete: contactUserPrefToFeatureAllowed(contactUserPreferences.fullDelete),
|
||||
voice: contactUserPrefToFeatureAllowed(contactUserPreferences.voice)
|
||||
voice: contactUserPrefToFeatureAllowed(contactUserPreferences.voice),
|
||||
calls: contactUserPrefToFeatureAllowed(contactUserPreferences.calls)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -689,7 +729,8 @@ public func contactFeaturesAllowedToPrefs(_ contactFeaturesAllowed: ContactFeatu
|
||||
Preferences(
|
||||
timedMessages: TimedMessagesPreference(allow: contactFeaturesAllowed.timedMessagesAllowed ? .yes : .no, ttl: contactFeaturesAllowed.timedMessagesTTL),
|
||||
fullDelete: contactFeatureAllowedToPref(contactFeaturesAllowed.fullDelete),
|
||||
voice: contactFeatureAllowedToPref(contactFeaturesAllowed.voice)
|
||||
voice: contactFeatureAllowedToPref(contactFeaturesAllowed.voice),
|
||||
calls: contactFeatureAllowedToPref(contactFeaturesAllowed.calls)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -977,6 +1018,7 @@ public enum ChatInfo: Identifiable, Decodable, NamedChat {
|
||||
case .timedMessages: return cups.timedMessages.enabled.forUser
|
||||
case .fullDelete: return cups.fullDelete.enabled.forUser
|
||||
case .voice: return cups.voice.enabled.forUser
|
||||
case .calls: return cups.calls.enabled.forUser
|
||||
}
|
||||
case let .group(groupInfo):
|
||||
let prefs = groupInfo.fullGroupPreferences
|
||||
@@ -984,6 +1026,7 @@ public enum ChatInfo: Identifiable, Decodable, NamedChat {
|
||||
case .timedMessages: return prefs.timedMessages.on
|
||||
case .fullDelete: return prefs.fullDelete.on
|
||||
case .voice: return prefs.voice.on
|
||||
case .calls: return false
|
||||
}
|
||||
default: return false
|
||||
}
|
||||
@@ -1137,6 +1180,7 @@ public struct Contact: Identifiable, Decodable, NamedChat {
|
||||
case .timedMessages: return mergedPreferences.timedMessages.contactPreference.allow != .no
|
||||
case .fullDelete: return mergedPreferences.fullDelete.contactPreference.allow != .no
|
||||
case .voice: return mergedPreferences.voice.contactPreference.allow != .no
|
||||
case .calls: return mergedPreferences.calls.contactPreference.allow != .no
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1145,6 +1189,7 @@ public struct Contact: Identifiable, Decodable, NamedChat {
|
||||
case .timedMessages: return mergedPreferences.timedMessages.userPreference.preference.allow != .no
|
||||
case .fullDelete: return mergedPreferences.fullDelete.userPreference.preference.allow != .no
|
||||
case .voice: return mergedPreferences.voice.userPreference.preference.allow != .no
|
||||
case .calls: return mergedPreferences.calls.userPreference.preference.allow != .no
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user