Ability to disable notifications per chat (#964)
* Ability to disable notifications per chat * All Buttons in AlertDialog replaced with TextButtons * update icon * update strings Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
a06499d710
commit
04592f52de
@@ -325,6 +325,7 @@ interface SomeChat {
|
|||||||
val apiId: Long
|
val apiId: Long
|
||||||
val ready: Boolean
|
val ready: Boolean
|
||||||
val sendMsgEnabled: Boolean
|
val sendMsgEnabled: Boolean
|
||||||
|
val ntfsEnabled: Boolean
|
||||||
val createdAt: Instant
|
val createdAt: Instant
|
||||||
val updatedAt: Instant
|
val updatedAt: Instant
|
||||||
}
|
}
|
||||||
@@ -383,6 +384,7 @@ sealed class ChatInfo: SomeChat, NamedChat {
|
|||||||
override val apiId get() = contact.apiId
|
override val apiId get() = contact.apiId
|
||||||
override val ready get() = contact.ready
|
override val ready get() = contact.ready
|
||||||
override val sendMsgEnabled get() = contact.sendMsgEnabled
|
override val sendMsgEnabled get() = contact.sendMsgEnabled
|
||||||
|
override val ntfsEnabled get() = contact.chatSettings.enableNtfs
|
||||||
override val createdAt get() = contact.createdAt
|
override val createdAt get() = contact.createdAt
|
||||||
override val updatedAt get() = contact.updatedAt
|
override val updatedAt get() = contact.updatedAt
|
||||||
override val displayName get() = contact.displayName
|
override val displayName get() = contact.displayName
|
||||||
@@ -402,6 +404,7 @@ sealed class ChatInfo: SomeChat, NamedChat {
|
|||||||
override val apiId get() = groupInfo.apiId
|
override val apiId get() = groupInfo.apiId
|
||||||
override val ready get() = groupInfo.ready
|
override val ready get() = groupInfo.ready
|
||||||
override val sendMsgEnabled get() = groupInfo.sendMsgEnabled
|
override val sendMsgEnabled get() = groupInfo.sendMsgEnabled
|
||||||
|
override val ntfsEnabled get() = groupInfo.chatSettings.enableNtfs
|
||||||
override val createdAt get() = groupInfo.createdAt
|
override val createdAt get() = groupInfo.createdAt
|
||||||
override val updatedAt get() = groupInfo.updatedAt
|
override val updatedAt get() = groupInfo.updatedAt
|
||||||
override val displayName get() = groupInfo.displayName
|
override val displayName get() = groupInfo.displayName
|
||||||
@@ -421,6 +424,7 @@ sealed class ChatInfo: SomeChat, NamedChat {
|
|||||||
override val apiId get() = contactRequest.apiId
|
override val apiId get() = contactRequest.apiId
|
||||||
override val ready get() = contactRequest.ready
|
override val ready get() = contactRequest.ready
|
||||||
override val sendMsgEnabled get() = contactRequest.sendMsgEnabled
|
override val sendMsgEnabled get() = contactRequest.sendMsgEnabled
|
||||||
|
override val ntfsEnabled get() = false
|
||||||
override val createdAt get() = contactRequest.createdAt
|
override val createdAt get() = contactRequest.createdAt
|
||||||
override val updatedAt get() = contactRequest.updatedAt
|
override val updatedAt get() = contactRequest.updatedAt
|
||||||
override val displayName get() = contactRequest.displayName
|
override val displayName get() = contactRequest.displayName
|
||||||
@@ -440,6 +444,7 @@ sealed class ChatInfo: SomeChat, NamedChat {
|
|||||||
override val apiId get() = contactConnection.apiId
|
override val apiId get() = contactConnection.apiId
|
||||||
override val ready get() = contactConnection.ready
|
override val ready get() = contactConnection.ready
|
||||||
override val sendMsgEnabled get() = contactConnection.sendMsgEnabled
|
override val sendMsgEnabled get() = contactConnection.sendMsgEnabled
|
||||||
|
override val ntfsEnabled get() = false
|
||||||
override val createdAt get() = contactConnection.createdAt
|
override val createdAt get() = contactConnection.createdAt
|
||||||
override val updatedAt get() = contactConnection.updatedAt
|
override val updatedAt get() = contactConnection.updatedAt
|
||||||
override val displayName get() = contactConnection.displayName
|
override val displayName get() = contactConnection.displayName
|
||||||
@@ -454,13 +459,13 @@ sealed class ChatInfo: SomeChat, NamedChat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class Contact(
|
data class Contact(
|
||||||
val contactId: Long,
|
val contactId: Long,
|
||||||
override val localDisplayName: String,
|
override val localDisplayName: String,
|
||||||
val profile: Profile,
|
val profile: Profile,
|
||||||
val activeConn: Connection,
|
val activeConn: Connection,
|
||||||
val viaGroup: Long? = null,
|
val viaGroup: Long? = null,
|
||||||
// val chatSettings: ChatSettings,
|
val chatSettings: ChatSettings,
|
||||||
override val createdAt: Instant,
|
override val createdAt: Instant,
|
||||||
override val updatedAt: Instant
|
override val updatedAt: Instant
|
||||||
): SomeChat, NamedChat {
|
): SomeChat, NamedChat {
|
||||||
@@ -469,6 +474,7 @@ class Contact(
|
|||||||
override val apiId get() = contactId
|
override val apiId get() = contactId
|
||||||
override val ready get() = activeConn.connStatus == ConnStatus.Ready
|
override val ready get() = activeConn.connStatus == ConnStatus.Ready
|
||||||
override val sendMsgEnabled get() = true
|
override val sendMsgEnabled get() = true
|
||||||
|
override val ntfsEnabled get() = chatSettings.enableNtfs
|
||||||
override val displayName get() = profile.displayName
|
override val displayName get() = profile.displayName
|
||||||
override val fullName get() = profile.fullName
|
override val fullName get() = profile.fullName
|
||||||
override val image get() = profile.image
|
override val image get() = profile.image
|
||||||
@@ -482,6 +488,7 @@ class Contact(
|
|||||||
localDisplayName = "alice",
|
localDisplayName = "alice",
|
||||||
profile = Profile.sampleData,
|
profile = Profile.sampleData,
|
||||||
activeConn = Connection.sampleData,
|
activeConn = Connection.sampleData,
|
||||||
|
chatSettings = ChatSettings(true),
|
||||||
createdAt = Clock.System.now(),
|
createdAt = Clock.System.now(),
|
||||||
updatedAt = Clock.System.now()
|
updatedAt = Clock.System.now()
|
||||||
)
|
)
|
||||||
@@ -536,12 +543,12 @@ class Group (
|
|||||||
)
|
)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class GroupInfo (
|
data class GroupInfo (
|
||||||
val groupId: Long,
|
val groupId: Long,
|
||||||
override val localDisplayName: String,
|
override val localDisplayName: String,
|
||||||
val groupProfile: GroupProfile,
|
val groupProfile: GroupProfile,
|
||||||
val membership: GroupMember,
|
val membership: GroupMember,
|
||||||
// val chatSettings: ChatSettings,
|
val chatSettings: ChatSettings,
|
||||||
override val createdAt: Instant,
|
override val createdAt: Instant,
|
||||||
override val updatedAt: Instant
|
override val updatedAt: Instant
|
||||||
): SomeChat, NamedChat {
|
): SomeChat, NamedChat {
|
||||||
@@ -550,6 +557,7 @@ class GroupInfo (
|
|||||||
override val apiId get() = groupId
|
override val apiId get() = groupId
|
||||||
override val ready get() = true
|
override val ready get() = true
|
||||||
override val sendMsgEnabled get() = membership.memberActive
|
override val sendMsgEnabled get() = membership.memberActive
|
||||||
|
override val ntfsEnabled get() = chatSettings.enableNtfs
|
||||||
override val displayName get() = groupProfile.displayName
|
override val displayName get() = groupProfile.displayName
|
||||||
override val fullName get() = groupProfile.fullName
|
override val fullName get() = groupProfile.fullName
|
||||||
override val image get() = groupProfile.image
|
override val image get() = groupProfile.image
|
||||||
@@ -569,6 +577,7 @@ class GroupInfo (
|
|||||||
localDisplayName = "team",
|
localDisplayName = "team",
|
||||||
groupProfile = GroupProfile.sampleData,
|
groupProfile = GroupProfile.sampleData,
|
||||||
membership = GroupMember.sampleData,
|
membership = GroupMember.sampleData,
|
||||||
|
chatSettings = ChatSettings(true),
|
||||||
createdAt = Clock.System.now(),
|
createdAt = Clock.System.now(),
|
||||||
updatedAt = Clock.System.now()
|
updatedAt = Clock.System.now()
|
||||||
)
|
)
|
||||||
@@ -770,6 +779,7 @@ class UserContactRequest (
|
|||||||
override val apiId get() = contactRequestId
|
override val apiId get() = contactRequestId
|
||||||
override val ready get() = true
|
override val ready get() = true
|
||||||
override val sendMsgEnabled get() = false
|
override val sendMsgEnabled get() = false
|
||||||
|
override val ntfsEnabled get() = false
|
||||||
override val displayName get() = profile.displayName
|
override val displayName get() = profile.displayName
|
||||||
override val fullName get() = profile.fullName
|
override val fullName get() = profile.fullName
|
||||||
override val image get() = profile.image
|
override val image get() = profile.image
|
||||||
@@ -799,6 +809,7 @@ class PendingContactConnection(
|
|||||||
override val apiId get() = pccConnId
|
override val apiId get() = pccConnId
|
||||||
override val ready get() = false
|
override val ready get() = false
|
||||||
override val sendMsgEnabled get() = false
|
override val sendMsgEnabled get() = false
|
||||||
|
override val ntfsEnabled get() = false
|
||||||
override val localDisplayName get() = String.format(generalGetString(R.string.connection_local_display_name), pccConnId)
|
override val localDisplayName get() = String.format(generalGetString(R.string.connection_local_display_name), pccConnId)
|
||||||
override val displayName: String get() {
|
override val displayName: String get() {
|
||||||
val initiated = pccConnStatus.initiated
|
val initiated = pccConnStatus.initiated
|
||||||
|
|||||||
@@ -64,6 +64,8 @@ class NtfManager(val context: Context, private val appPreferences: AppPreference
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun notifyMessageReceived(cInfo: ChatInfo, cItem: ChatItem) {
|
fun notifyMessageReceived(cInfo: ChatInfo, cItem: ChatItem) {
|
||||||
|
if (!cInfo.ntfsEnabled) return
|
||||||
|
|
||||||
notifyMessageReceived(chatId = cInfo.id, displayName = cInfo.displayName, msgText = hideSecrets(cItem))
|
notifyMessageReceived(chatId = cInfo.id, displayName = cInfo.displayName, msgText = hideSecrets(cItem))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -388,6 +388,17 @@ open class ChatController(private val ctrl: ChatCtrl, val ntfManager: NtfManager
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun apiSetSettings(type: ChatType,id: Long, settings: ChatSettings): Boolean {
|
||||||
|
val r = sendCmd(CC.APISetChatSettings(type, id, settings))
|
||||||
|
return when (r) {
|
||||||
|
is CR.CmdOk -> true
|
||||||
|
else -> {
|
||||||
|
Log.e(TAG, "apiSetSettings bad response: ${r.responseType} ${r.details}")
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun apiContactInfo(contactId: Long): ConnectionStats? {
|
suspend fun apiContactInfo(contactId: Long): ConnectionStats? {
|
||||||
val r = sendCmd(CC.APIContactInfo(contactId))
|
val r = sendCmd(CC.APIContactInfo(contactId))
|
||||||
if (r is CR.ContactInfo) return r.connectionStats
|
if (r is CR.ContactInfo) return r.connectionStats
|
||||||
@@ -942,7 +953,7 @@ open class ChatController(private val ctrl: ChatCtrl, val ntfManager: NtfManager
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
Button(onClick = AlertManager.shared::hideAlert) { Text(stringResource(R.string.ok)) }
|
TextButton(onClick = AlertManager.shared::hideAlert) { Text(stringResource(R.string.ok)) }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -973,7 +984,7 @@ open class ChatController(private val ctrl: ChatCtrl, val ntfManager: NtfManager
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
Button(onClick = ignoreOptimization) { Text(stringResource(R.string.ok)) }
|
TextButton(onClick = ignoreOptimization) { Text(stringResource(R.string.ok)) }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -999,7 +1010,7 @@ open class ChatController(private val ctrl: ChatCtrl, val ntfManager: NtfManager
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
Button(onClick = AlertManager.shared::hideAlert) { Text(stringResource(R.string.ok)) }
|
TextButton(onClick = AlertManager.shared::hideAlert) { Text(stringResource(R.string.ok)) }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,11 +43,43 @@ fun ChatInfoView(chatModel: ChatModel, connStats: ConnectionStats?, close: () ->
|
|||||||
connStats,
|
connStats,
|
||||||
developerTools,
|
developerTools,
|
||||||
deleteContact = { deleteContactDialog(chat.chatInfo, chatModel, close) },
|
deleteContact = { deleteContactDialog(chat.chatInfo, chatModel, close) },
|
||||||
clearChat = { clearChatDialog(chat.chatInfo, chatModel, close) }
|
clearChat = { clearChatDialog(chat.chatInfo, chatModel, close) },
|
||||||
|
changeNtfsState = { enabled ->
|
||||||
|
changeNtfsState(enabled, chat, chatModel)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun changeNtfsState(enabled: Boolean, chat: Chat, chatModel: ChatModel) {
|
||||||
|
val newChatInfo = when(chat.chatInfo) {
|
||||||
|
is ChatInfo.Direct -> with (chat.chatInfo) {
|
||||||
|
ChatInfo.Direct(contact.copy(chatSettings = contact.chatSettings.copy(enableNtfs = enabled)))
|
||||||
|
}
|
||||||
|
is ChatInfo.Group -> with(chat.chatInfo) {
|
||||||
|
ChatInfo.Group(groupInfo.copy(chatSettings = groupInfo.chatSettings.copy(enableNtfs = enabled)))
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
withApi {
|
||||||
|
val res = when (newChatInfo) {
|
||||||
|
is ChatInfo.Direct -> with(newChatInfo) {
|
||||||
|
chatModel.controller.apiSetSettings(chatType, apiId, contact.chatSettings)
|
||||||
|
}
|
||||||
|
is ChatInfo.Group -> with(newChatInfo) {
|
||||||
|
chatModel.controller.apiSetSettings(chatType, apiId, groupInfo.chatSettings)
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
if (res && newChatInfo != null) {
|
||||||
|
chatModel.updateChatInfo(newChatInfo)
|
||||||
|
if (!enabled) {
|
||||||
|
chatModel.controller.ntfManager.cancelNotificationsForChat(chat.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun deleteContactDialog(chatInfo: ChatInfo, chatModel: ChatModel, close: (() -> Unit)? = null) {
|
fun deleteContactDialog(chatInfo: ChatInfo, chatModel: ChatModel, close: (() -> Unit)? = null) {
|
||||||
AlertManager.shared.showAlertMsg(
|
AlertManager.shared.showAlertMsg(
|
||||||
title = generalGetString(R.string.delete_contact_question),
|
title = generalGetString(R.string.delete_contact_question),
|
||||||
@@ -91,7 +123,8 @@ fun ChatInfoLayout(
|
|||||||
connStats: ConnectionStats?,
|
connStats: ConnectionStats?,
|
||||||
developerTools: Boolean,
|
developerTools: Boolean,
|
||||||
deleteContact: () -> Unit,
|
deleteContact: () -> Unit,
|
||||||
clearChat: () -> Unit
|
clearChat: () -> Unit,
|
||||||
|
changeNtfsState: (Boolean) -> Unit,
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
Modifier
|
Modifier
|
||||||
@@ -126,6 +159,17 @@ fun ChatInfoLayout(
|
|||||||
SectionSpacer()
|
SectionSpacer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ntfsEnabled by remember { mutableStateOf(chat.chatInfo.ntfsEnabled) }
|
||||||
|
SectionView(title = stringResource(R.string.settings_section_title_settings)) {
|
||||||
|
SectionItemView {
|
||||||
|
NtfsSwitch(ntfsEnabled) {
|
||||||
|
ntfsEnabled = !ntfsEnabled
|
||||||
|
changeNtfsState(ntfsEnabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionSpacer()
|
||||||
|
|
||||||
SectionView {
|
SectionView {
|
||||||
SectionItemView {
|
SectionItemView {
|
||||||
ClearChatButton(clearChat)
|
ClearChatButton(clearChat)
|
||||||
@@ -236,6 +280,38 @@ fun SimplexServers(text: String, servers: List<String>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun NtfsSwitch(
|
||||||
|
ntfsEnabled: Boolean,
|
||||||
|
toggleNtfs: (Boolean) -> Unit
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
Modifier.fillMaxWidth(),
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.SpaceBetween
|
||||||
|
) {
|
||||||
|
Row(
|
||||||
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
|
horizontalArrangement = Arrangement.spacedBy(8.dp)
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Outlined.Notifications,
|
||||||
|
stringResource(R.string.notifications),
|
||||||
|
tint = HighOrLowlight
|
||||||
|
)
|
||||||
|
Text(stringResource(R.string.notifications))
|
||||||
|
}
|
||||||
|
Switch(
|
||||||
|
checked = ntfsEnabled,
|
||||||
|
onCheckedChange = toggleNtfs,
|
||||||
|
colors = SwitchDefaults.colors(
|
||||||
|
checkedThumbColor = MaterialTheme.colors.primary,
|
||||||
|
uncheckedThumbColor = HighOrLowlight
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ClearChatButton(clearChat: () -> Unit) {
|
fun ClearChatButton(clearChat: () -> Unit) {
|
||||||
Row(
|
Row(
|
||||||
@@ -282,6 +358,7 @@ fun PreviewChatInfoLayout() {
|
|||||||
chatItems = arrayListOf(),
|
chatItems = arrayListOf(),
|
||||||
serverInfo = Chat.ServerInfo(Chat.NetworkStatus.Error("agent BROKER TIMEOUT"))
|
serverInfo = Chat.ServerInfo(Chat.NetworkStatus.Error("agent BROKER TIMEOUT"))
|
||||||
),
|
),
|
||||||
|
changeNtfsState = {},
|
||||||
developerTools = false,
|
developerTools = false,
|
||||||
connStats = null,
|
connStats = null,
|
||||||
deleteContact = {}, clearChat = {}
|
deleteContact = {}, clearChat = {}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import androidx.compose.foundation.layout.*
|
|||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.outlined.*
|
import androidx.compose.material.icons.outlined.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
@@ -72,7 +72,10 @@ fun GroupChatInfoView(chatModel: ChatModel, close: () -> Unit) {
|
|||||||
},
|
},
|
||||||
deleteGroup = { deleteGroupDialog(chat.chatInfo, chatModel, close) },
|
deleteGroup = { deleteGroupDialog(chat.chatInfo, chatModel, close) },
|
||||||
clearChat = { clearChatDialog(chat.chatInfo, chatModel, close) },
|
clearChat = { clearChatDialog(chat.chatInfo, chatModel, close) },
|
||||||
leaveGroup = { leaveGroupDialog(groupInfo, chatModel, close) }
|
leaveGroup = { leaveGroupDialog(groupInfo, chatModel, close) },
|
||||||
|
changeNtfsState = { enabled ->
|
||||||
|
changeNtfsState(enabled, chat, chatModel)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -122,6 +125,7 @@ fun GroupChatInfoLayout(
|
|||||||
deleteGroup: () -> Unit,
|
deleteGroup: () -> Unit,
|
||||||
clearChat: () -> Unit,
|
clearChat: () -> Unit,
|
||||||
leaveGroup: () -> Unit,
|
leaveGroup: () -> Unit,
|
||||||
|
changeNtfsState: (Boolean) -> Unit,
|
||||||
) {
|
) {
|
||||||
Column(
|
Column(
|
||||||
Modifier
|
Modifier
|
||||||
@@ -154,6 +158,17 @@ fun GroupChatInfoLayout(
|
|||||||
}
|
}
|
||||||
SectionSpacer()
|
SectionSpacer()
|
||||||
|
|
||||||
|
var ntfsEnabled by remember { mutableStateOf(chat.chatInfo.ntfsEnabled) }
|
||||||
|
SectionView(title = stringResource(R.string.settings_section_title_settings)) {
|
||||||
|
SectionItemView {
|
||||||
|
NtfsSwitch(ntfsEnabled) {
|
||||||
|
ntfsEnabled = !ntfsEnabled
|
||||||
|
changeNtfsState(ntfsEnabled)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SectionSpacer()
|
||||||
|
|
||||||
SectionView {
|
SectionView {
|
||||||
if (groupInfo.canEdit) {
|
if (groupInfo.canEdit) {
|
||||||
SectionItemView {
|
SectionItemView {
|
||||||
@@ -322,7 +337,8 @@ fun PreviewGroupChatInfoLayout() {
|
|||||||
groupInfo = GroupInfo.sampleData,
|
groupInfo = GroupInfo.sampleData,
|
||||||
members = listOf(GroupMember.sampleData, GroupMember.sampleData, GroupMember.sampleData),
|
members = listOf(GroupMember.sampleData, GroupMember.sampleData, GroupMember.sampleData),
|
||||||
developerTools = false,
|
developerTools = false,
|
||||||
addMembers = {}, showMemberInfo = {}, editGroupProfile = {}, deleteGroup = {}, clearChat = {}, leaveGroup = {}
|
addMembers = {}, showMemberInfo = {}, editGroupProfile = {}, deleteGroup = {}, clearChat = {}, leaveGroup = {},
|
||||||
|
changeNtfsState = {},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,13 +184,13 @@ fun deleteMessageAlertDialog(chatItem: ChatItem, deleteMessage: (Long, CIDeleteM
|
|||||||
.padding(horizontal = 8.dp, vertical = 2.dp),
|
.padding(horizontal = 8.dp, vertical = 2.dp),
|
||||||
horizontalArrangement = Arrangement.End,
|
horizontalArrangement = Arrangement.End,
|
||||||
) {
|
) {
|
||||||
Button(onClick = {
|
TextButton(onClick = {
|
||||||
deleteMessage(chatItem.id, CIDeleteMode.cidmInternal)
|
deleteMessage(chatItem.id, CIDeleteMode.cidmInternal)
|
||||||
AlertManager.shared.hideAlert()
|
AlertManager.shared.hideAlert()
|
||||||
}) { Text(stringResource(R.string.for_me_only)) }
|
}) { Text(stringResource(R.string.for_me_only)) }
|
||||||
if (chatItem.meta.editable) {
|
if (chatItem.meta.editable) {
|
||||||
Spacer(Modifier.padding(horizontal = 4.dp))
|
Spacer(Modifier.padding(horizontal = 4.dp))
|
||||||
Button(onClick = {
|
TextButton(onClick = {
|
||||||
deleteMessage(chatItem.id, CIDeleteMode.cidmBroadcast)
|
deleteMessage(chatItem.id, CIDeleteMode.cidmBroadcast)
|
||||||
AlertManager.shared.hideAlert()
|
AlertManager.shared.hideAlert()
|
||||||
}) { Text(stringResource(R.string.for_everybody)) }
|
}) { Text(stringResource(R.string.for_everybody)) }
|
||||||
|
|||||||
@@ -119,6 +119,7 @@ fun ContactMenuItems(chat: Chat, chatModel: ChatModel, showMenu: MutableState<Bo
|
|||||||
if (showMarkRead) {
|
if (showMarkRead) {
|
||||||
MarkReadChatAction(chat, chatModel, showMenu)
|
MarkReadChatAction(chat, chatModel, showMenu)
|
||||||
}
|
}
|
||||||
|
ToggleNotificationsChatAction(chat, chatModel, chat.chatInfo.ntfsEnabled, showMenu)
|
||||||
ClearChatAction(chat, chatModel, showMenu)
|
ClearChatAction(chat, chatModel, showMenu)
|
||||||
DeleteContactAction(chat, chatModel, showMenu)
|
DeleteContactAction(chat, chatModel, showMenu)
|
||||||
}
|
}
|
||||||
@@ -136,6 +137,7 @@ fun GroupMenuItems(chat: Chat, groupInfo: GroupInfo, chatModel: ChatModel, showM
|
|||||||
if (showMarkRead) {
|
if (showMarkRead) {
|
||||||
MarkReadChatAction(chat, chatModel, showMenu)
|
MarkReadChatAction(chat, chatModel, showMenu)
|
||||||
}
|
}
|
||||||
|
ToggleNotificationsChatAction(chat, chatModel, chat.chatInfo.ntfsEnabled, showMenu)
|
||||||
ClearChatAction(chat, chatModel, showMenu)
|
ClearChatAction(chat, chatModel, showMenu)
|
||||||
if (groupInfo.membership.memberCurrent) {
|
if (groupInfo.membership.memberCurrent) {
|
||||||
LeaveGroupAction(groupInfo, chatModel, showMenu)
|
LeaveGroupAction(groupInfo, chatModel, showMenu)
|
||||||
@@ -160,6 +162,18 @@ fun MarkReadChatAction(chat: Chat, chatModel: ChatModel, showMenu: MutableState<
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ToggleNotificationsChatAction(chat: Chat, chatModel: ChatModel, ntfsEnabled: Boolean, showMenu: MutableState<Boolean>) {
|
||||||
|
ItemAction(
|
||||||
|
if (ntfsEnabled) stringResource(R.string.mute_chat) else stringResource(R.string.unmute_chat),
|
||||||
|
if (ntfsEnabled) Icons.Outlined.NotificationsOff else Icons.Outlined.Notifications,
|
||||||
|
onClick = {
|
||||||
|
changeNtfsState(!ntfsEnabled, chat, chatModel)
|
||||||
|
showMenu.value = false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ClearChatAction(chat: Chat, chatModel: ChatModel, showMenu: MutableState<Boolean>) {
|
fun ClearChatAction(chat: Chat, chatModel: ChatModel, showMenu: MutableState<Boolean>) {
|
||||||
ItemAction(
|
ItemAction(
|
||||||
@@ -318,14 +332,14 @@ fun contactConnectionAlertDialog(connection: PendingContactConnection, chatModel
|
|||||||
.padding(horizontal = 8.dp, vertical = 2.dp),
|
.padding(horizontal = 8.dp, vertical = 2.dp),
|
||||||
horizontalArrangement = Arrangement.End,
|
horizontalArrangement = Arrangement.End,
|
||||||
) {
|
) {
|
||||||
Button(onClick = {
|
TextButton(onClick = {
|
||||||
AlertManager.shared.hideAlert()
|
AlertManager.shared.hideAlert()
|
||||||
deleteContactConnectionAlert(connection, chatModel)
|
deleteContactConnectionAlert(connection, chatModel)
|
||||||
}) {
|
}) {
|
||||||
Text(stringResource(R.string.delete_verb))
|
Text(stringResource(R.string.delete_verb))
|
||||||
}
|
}
|
||||||
Spacer(Modifier.padding(horizontal = 4.dp))
|
Spacer(Modifier.padding(horizontal = 4.dp))
|
||||||
Button(onClick = { AlertManager.shared.hideAlert() }) {
|
TextButton(onClick = { AlertManager.shared.hideAlert() }) {
|
||||||
Text(stringResource(R.string.ok))
|
Text(stringResource(R.string.ok))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ import androidx.compose.foundation.shape.CircleShape
|
|||||||
import androidx.compose.material.*
|
import androidx.compose.material.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.Cancel
|
import androidx.compose.material.icons.filled.Cancel
|
||||||
import androidx.compose.material.icons.outlined.ErrorOutline
|
import androidx.compose.material.icons.filled.NotificationsOff
|
||||||
|
import androidx.compose.material.icons.outlined.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -23,8 +24,7 @@ import chat.simplex.app.R
|
|||||||
import chat.simplex.app.model.*
|
import chat.simplex.app.model.*
|
||||||
import chat.simplex.app.ui.theme.*
|
import chat.simplex.app.ui.theme.*
|
||||||
import chat.simplex.app.views.chat.item.MarkdownText
|
import chat.simplex.app.views.chat.item.MarkdownText
|
||||||
import chat.simplex.app.views.helpers.ChatInfoImage
|
import chat.simplex.app.views.helpers.*
|
||||||
import chat.simplex.app.views.helpers.badgeLayout
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChatPreviewView(chat: Chat, stopped: Boolean) {
|
fun ChatPreviewView(chat: Chat, stopped: Boolean) {
|
||||||
@@ -134,6 +134,7 @@ fun ChatPreviewView(chat: Chat, stopped: Boolean) {
|
|||||||
modifier = Modifier.padding(bottom = 5.dp)
|
modifier = Modifier.padding(bottom = 5.dp)
|
||||||
)
|
)
|
||||||
val n = chat.chatStats.unreadCount
|
val n = chat.chatStats.unreadCount
|
||||||
|
val showNtfsIcon = !chat.chatInfo.ntfsEnabled && (chat.chatInfo is ChatInfo.Direct || chat.chatInfo is ChatInfo.Group)
|
||||||
if (n > 0) {
|
if (n > 0) {
|
||||||
Box(
|
Box(
|
||||||
Modifier.padding(top = 24.dp),
|
Modifier.padding(top = 24.dp),
|
||||||
@@ -144,12 +145,27 @@ fun ChatPreviewView(chat: Chat, stopped: Boolean) {
|
|||||||
color = MaterialTheme.colors.onPrimary,
|
color = MaterialTheme.colors.onPrimary,
|
||||||
fontSize = 11.sp,
|
fontSize = 11.sp,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.background(if (stopped) HighOrLowlight else MaterialTheme.colors.primary, shape = CircleShape)
|
.background(if (stopped || showNtfsIcon) HighOrLowlight else MaterialTheme.colors.primary, shape = CircleShape)
|
||||||
.badgeLayout()
|
.badgeLayout()
|
||||||
.padding(horizontal = 3.dp)
|
.padding(horizontal = 3.dp)
|
||||||
.padding(vertical = 1.dp)
|
.padding(vertical = 1.dp)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
} else if (showNtfsIcon) {
|
||||||
|
Box(
|
||||||
|
Modifier.padding(top = 24.dp),
|
||||||
|
contentAlignment = Alignment.Center
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.Filled.NotificationsOff,
|
||||||
|
contentDescription = generalGetString(R.string.notifications),
|
||||||
|
tint = HighOrLowlight,
|
||||||
|
modifier = Modifier
|
||||||
|
.padding(horizontal = 3.dp)
|
||||||
|
.padding(vertical = 1.dp)
|
||||||
|
.size(17.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (cInfo is ChatInfo.Direct) {
|
if (cInfo is ChatInfo.Direct) {
|
||||||
Box(
|
Box(
|
||||||
|
|||||||
@@ -53,13 +53,13 @@ class AlertManager {
|
|||||||
title = { Text(title) },
|
title = { Text(title) },
|
||||||
text = alertText,
|
text = alertText,
|
||||||
confirmButton = {
|
confirmButton = {
|
||||||
Button(onClick = {
|
TextButton(onClick = {
|
||||||
onConfirm?.invoke()
|
onConfirm?.invoke()
|
||||||
hideAlert()
|
hideAlert()
|
||||||
}) { Text(confirmText) }
|
}) { Text(confirmText) }
|
||||||
},
|
},
|
||||||
dismissButton = {
|
dismissButton = {
|
||||||
Button(onClick = {
|
TextButton(onClick = {
|
||||||
onDismiss?.invoke()
|
onDismiss?.invoke()
|
||||||
hideAlert()
|
hideAlert()
|
||||||
}) { Text(dismissText) }
|
}) { Text(dismissText) }
|
||||||
|
|||||||
@@ -141,6 +141,9 @@
|
|||||||
<string name="file_not_found">Файл не найден</string>
|
<string name="file_not_found">Файл не найден</string>
|
||||||
<string name="error_saving_file">Ошибка сохранения файла</string>
|
<string name="error_saving_file">Ошибка сохранения файла</string>
|
||||||
|
|
||||||
|
<!-- Chat Info Settings - ChatInfoView.kt -->
|
||||||
|
<string name="notifications">Уведомления</string>
|
||||||
|
|
||||||
<!-- Chat Info Actions - ChatInfoView.kt -->
|
<!-- Chat Info Actions - ChatInfoView.kt -->
|
||||||
<string name="delete_contact_question">Удалить контакт?</string>
|
<string name="delete_contact_question">Удалить контакт?</string>
|
||||||
<string name="delete_contact_all_messages_deleted_cannot_undo_warning">Контакт и все сообщения будут удалены - это действие нельзя отменить!</string>
|
<string name="delete_contact_all_messages_deleted_cannot_undo_warning">Контакт и все сообщения будут удалены - это действие нельзя отменить!</string>
|
||||||
@@ -205,6 +208,10 @@
|
|||||||
<string name="clear_chat_button">Очистить чат</string>
|
<string name="clear_chat_button">Очистить чат</string>
|
||||||
<string name="mark_read">Прочитано</string>
|
<string name="mark_read">Прочитано</string>
|
||||||
|
|
||||||
|
<!-- Actions - ChatListNavLinkView.kt -->
|
||||||
|
<string name="mute_chat">Без звука</string>
|
||||||
|
<string name="unmute_chat">Уведомлять</string>
|
||||||
|
|
||||||
<!-- Pending contact connection alert dialogues -->
|
<!-- Pending contact connection alert dialogues -->
|
||||||
<string name="you_invited_your_contact">Вы пригласили ваш контакт</string>
|
<string name="you_invited_your_contact">Вы пригласили ваш контакт</string>
|
||||||
<string name="you_accepted_connection">Вы приняли приглашение соединиться</string>
|
<string name="you_accepted_connection">Вы приняли приглашение соединиться</string>
|
||||||
|
|||||||
@@ -141,6 +141,9 @@
|
|||||||
<string name="file_not_found">File not found</string>
|
<string name="file_not_found">File not found</string>
|
||||||
<string name="error_saving_file">Error saving file</string>
|
<string name="error_saving_file">Error saving file</string>
|
||||||
|
|
||||||
|
<!-- Chat Info Settings - ChatInfoView.kt -->
|
||||||
|
<string name="notifications">Notifications</string>
|
||||||
|
|
||||||
<!-- Chat Info Actions - ChatInfoView.kt -->
|
<!-- Chat Info Actions - ChatInfoView.kt -->
|
||||||
<string name="delete_contact_question">Delete contact?</string>
|
<string name="delete_contact_question">Delete contact?</string>
|
||||||
<string name="delete_contact_all_messages_deleted_cannot_undo_warning">Contact and all messages will be deleted - this cannot be undone!</string>
|
<string name="delete_contact_all_messages_deleted_cannot_undo_warning">Contact and all messages will be deleted - this cannot be undone!</string>
|
||||||
@@ -205,6 +208,10 @@
|
|||||||
<string name="clear_chat_button">Clear chat</string>
|
<string name="clear_chat_button">Clear chat</string>
|
||||||
<string name="mark_read">Mark read</string>
|
<string name="mark_read">Mark read</string>
|
||||||
|
|
||||||
|
<!-- Actions - ChatListNavLinkView.kt -->
|
||||||
|
<string name="mute_chat">Mute</string>
|
||||||
|
<string name="unmute_chat">Unmute</string>
|
||||||
|
|
||||||
<!-- Pending contact connection alert dialogues -->
|
<!-- Pending contact connection alert dialogues -->
|
||||||
<string name="you_invited_your_contact">You invited your contact</string>
|
<string name="you_invited_your_contact">You invited your contact</string>
|
||||||
<string name="you_accepted_connection">You accepted connection</string>
|
<string name="you_accepted_connection">You accepted connection</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user