android, desktop: show remote host info (#3423)
* android, desktop: show remote host info * hide alerts too
This commit is contained in:
parent
64520a4cf4
commit
c40bfb0f43
@ -8,15 +8,12 @@ import android.provider.MediaStore
|
||||
import android.webkit.MimeTypeMap
|
||||
import androidx.compose.ui.platform.ClipboardManager
|
||||
import androidx.compose.ui.platform.UriHandler
|
||||
import androidx.core.content.FileProvider
|
||||
import androidx.core.net.toUri
|
||||
import chat.simplex.common.helpers.*
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import java.io.BufferedOutputStream
|
||||
import java.io.File
|
||||
import chat.simplex.res.MR
|
||||
import java.io.ByteArrayOutputStream
|
||||
|
||||
actual fun ClipboardManager.shareText(text: String) {
|
||||
val sendIntent: Intent = Intent().apply {
|
||||
|
@ -4,7 +4,6 @@ import chat.simplex.common.views.helpers.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import chat.simplex.common.model.ChatModel.remoteHostId
|
||||
import chat.simplex.common.model.ChatModel.updatingChatsMutex
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import chat.simplex.common.platform.*
|
||||
@ -1845,7 +1844,13 @@ object ChatController {
|
||||
switchUIRemoteHost(r.remoteHost.remoteHostId)
|
||||
}
|
||||
is CR.RemoteHostStopped -> {
|
||||
val disconnectedHost = chatModel.remoteHosts.firstOrNull { it.remoteHostId == r.remoteHostId_ }
|
||||
chatModel.newRemoteHostPairing.value = null
|
||||
if (disconnectedHost != null) {
|
||||
showToast(
|
||||
generalGetString(MR.strings.remote_host_was_disconnected_toast).format(disconnectedHost.hostDeviceName.ifEmpty { disconnectedHost.remoteHostId.toString() })
|
||||
)
|
||||
}
|
||||
if (chatModel.currentRemoteHost.value != null) {
|
||||
chatModel.currentRemoteHost.value = null
|
||||
switchUIRemoteHost(null)
|
||||
@ -1968,6 +1973,9 @@ object ChatController {
|
||||
suspend fun switchUIRemoteHost(rhId: Long?) {
|
||||
// TODO lock the switch so that two switches can't run concurrently?
|
||||
chatModel.chatId.value = null
|
||||
ModalManager.center.closeModals()
|
||||
ModalManager.end.closeModals()
|
||||
AlertManager.shared.alertViews.clear()
|
||||
chatModel.currentRemoteHost.value = switchRemoteHost(rhId)
|
||||
reloadRemoteHosts()
|
||||
val user = apiGetActiveUser(rhId)
|
||||
|
@ -129,7 +129,7 @@ fun directChatAction(rhId: Long?, contact: Contact, chatModel: ChatModel) {
|
||||
fun groupChatAction(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatModel, inProgress: MutableState<Boolean>? = null) {
|
||||
when (groupInfo.membership.memberStatus) {
|
||||
GroupMemberStatus.MemInvited -> acceptGroupInvitationAlertDialog(rhId, groupInfo, chatModel, inProgress)
|
||||
GroupMemberStatus.MemAccepted -> groupInvitationAcceptedAlert()
|
||||
GroupMemberStatus.MemAccepted -> groupInvitationAcceptedAlert(rhId)
|
||||
else -> withBGApi { openChat(rhId, ChatInfo.Group(groupInfo), chatModel) }
|
||||
}
|
||||
}
|
||||
@ -538,7 +538,8 @@ fun contactRequestAlertDialog(rhId: Long?, contactRequest: ChatInfo.ContactReque
|
||||
Text(generalGetString(MR.strings.reject_contact_button), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = Color.Red)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
|
||||
@ -644,7 +645,8 @@ fun askCurrentOrIncognitoProfileConnectContactViaAddress(
|
||||
Text(stringResource(MR.strings.cancel_verb), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
|
||||
@ -654,7 +656,8 @@ suspend fun connectContactViaAddress(chatModel: ChatModel, rhId: Long?, contactI
|
||||
chatModel.updateContact(rhId, contact)
|
||||
AlertManager.shared.showAlertMsg(
|
||||
title = generalGetString(MR.strings.connection_request_sent),
|
||||
text = generalGetString(MR.strings.you_will_be_connected_when_your_connection_request_is_accepted)
|
||||
text = generalGetString(MR.strings.you_will_be_connected_when_your_connection_request_is_accepted),
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
return true
|
||||
}
|
||||
@ -674,7 +677,8 @@ fun acceptGroupInvitationAlertDialog(rhId: Long?, groupInfo: GroupInfo, chatMode
|
||||
}
|
||||
},
|
||||
dismissText = generalGetString(MR.strings.delete_verb),
|
||||
onDismiss = { deleteGroup(rhId, groupInfo, chatModel) }
|
||||
onDismiss = { deleteGroup(rhId, groupInfo, chatModel) },
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
|
||||
@ -700,10 +704,11 @@ fun deleteGroup(rhId: Long?, groupInfo: GroupInfo, chatModel: ChatModel) {
|
||||
}
|
||||
}
|
||||
|
||||
fun groupInvitationAcceptedAlert() {
|
||||
fun groupInvitationAcceptedAlert(rhId: Long?) {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.joining_group),
|
||||
generalGetString(MR.strings.youve_accepted_group_invitation_connecting_to_inviting_group_member)
|
||||
generalGetString(MR.strings.youve_accepted_group_invitation_connecting_to_inviting_group_member),
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package chat.simplex.common.views.helpers
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CornerSize
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
@ -14,10 +13,12 @@ import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.*
|
||||
import chat.simplex.common.model.ChatModel
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.StringResource
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
|
||||
class AlertManager {
|
||||
var alertViews = mutableStateListOf<(@Composable () -> Unit)>()
|
||||
@ -40,8 +41,11 @@ class AlertManager {
|
||||
AlertDialog(
|
||||
onDismissRequest = this::hideAlert,
|
||||
title = alertTitle(title),
|
||||
text = alertText(text),
|
||||
buttons = buttons,
|
||||
buttons = {
|
||||
AlertContent(text, null, extraPadding = true) {
|
||||
buttons()
|
||||
}
|
||||
},
|
||||
shape = RoundedCornerShape(corner = CornerSize(25.dp))
|
||||
)
|
||||
}
|
||||
@ -51,30 +55,16 @@ class AlertManager {
|
||||
title: String,
|
||||
text: AnnotatedString? = null,
|
||||
onDismissRequest: (() -> Unit)? = null,
|
||||
hostDevice: Pair<Long?, String>? = null,
|
||||
buttons: @Composable () -> Unit,
|
||||
) {
|
||||
showAlert {
|
||||
AlertDialog(
|
||||
onDismissRequest = { onDismissRequest?.invoke(); hideAlert() },
|
||||
title = {
|
||||
Text(
|
||||
title,
|
||||
Modifier.fillMaxWidth().padding(vertical = DEFAULT_PADDING),
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = 20.sp
|
||||
)
|
||||
},
|
||||
title = alertTitle(title),
|
||||
buttons = {
|
||||
Column(
|
||||
Modifier
|
||||
.padding(bottom = DEFAULT_PADDING)
|
||||
) {
|
||||
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
|
||||
if (text != null) {
|
||||
Text(text, Modifier.fillMaxWidth().padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, bottom = DEFAULT_PADDING * 1.5f), fontSize = 16.sp, textAlign = TextAlign.Center, color = MaterialTheme.colors.secondary)
|
||||
}
|
||||
buttons()
|
||||
}
|
||||
AlertContent(text, hostDevice, extraPadding = true) {
|
||||
buttons()
|
||||
}
|
||||
},
|
||||
shape = RoundedCornerShape(corner = CornerSize(25.dp))
|
||||
@ -90,30 +80,32 @@ class AlertManager {
|
||||
dismissText: String = generalGetString(MR.strings.cancel_verb),
|
||||
onDismiss: (() -> Unit)? = null,
|
||||
onDismissRequest: (() -> Unit)? = null,
|
||||
destructive: Boolean = false
|
||||
destructive: Boolean = false,
|
||||
hostDevice: Pair<Long?, String>? = null,
|
||||
) {
|
||||
showAlert {
|
||||
AlertDialog(
|
||||
onDismissRequest = { onDismissRequest?.invoke(); hideAlert() },
|
||||
title = alertTitle(title),
|
||||
text = alertText(text),
|
||||
buttons = {
|
||||
Row (
|
||||
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING).padding(bottom = DEFAULT_PADDING_HALF),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequester.requestFocus()
|
||||
AlertContent(text, hostDevice) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequester.requestFocus()
|
||||
}
|
||||
TextButton(onClick = {
|
||||
onDismiss?.invoke()
|
||||
hideAlert()
|
||||
}) { Text(dismissText) }
|
||||
TextButton(onClick = {
|
||||
onConfirm?.invoke()
|
||||
hideAlert()
|
||||
}, Modifier.focusRequester(focusRequester)) { Text(confirmText, color = if (destructive) MaterialTheme.colors.error else Color.Unspecified) }
|
||||
}
|
||||
TextButton(onClick = {
|
||||
onDismiss?.invoke()
|
||||
hideAlert()
|
||||
}) { Text(dismissText) }
|
||||
TextButton(onClick = {
|
||||
onConfirm?.invoke()
|
||||
hideAlert()
|
||||
}, Modifier.focusRequester(focusRequester)) { Text(confirmText, color = if (destructive) MaterialTheme.colors.error else Color.Unspecified) }
|
||||
}
|
||||
},
|
||||
shape = RoundedCornerShape(corner = CornerSize(25.dp))
|
||||
@ -135,20 +127,21 @@ class AlertManager {
|
||||
AlertDialog(
|
||||
onDismissRequest = { onDismissRequest?.invoke(); hideAlert() },
|
||||
title = alertTitle(title),
|
||||
text = alertText(text),
|
||||
buttons = {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING_HALF).padding(top = DEFAULT_PADDING, bottom = 2.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
TextButton(onClick = {
|
||||
onDismiss?.invoke()
|
||||
hideAlert()
|
||||
}) { Text(dismissText) }
|
||||
TextButton(onClick = {
|
||||
onConfirm?.invoke()
|
||||
hideAlert()
|
||||
}) { Text(confirmText, color = if (destructive) Color.Red else Color.Unspecified, textAlign = TextAlign.End) }
|
||||
AlertContent(text, null) {
|
||||
Column(
|
||||
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING_HALF).padding(top = DEFAULT_PADDING, bottom = 2.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
TextButton(onClick = {
|
||||
onDismiss?.invoke()
|
||||
hideAlert()
|
||||
}) { Text(dismissText) }
|
||||
TextButton(onClick = {
|
||||
onConfirm?.invoke()
|
||||
hideAlert()
|
||||
}) { Text(confirmText, color = if (destructive) Color.Red else Color.Unspecified, textAlign = TextAlign.End) }
|
||||
}
|
||||
}
|
||||
},
|
||||
shape = RoundedCornerShape(corner = CornerSize(25.dp))
|
||||
@ -158,29 +151,31 @@ class AlertManager {
|
||||
|
||||
fun showAlertMsg(
|
||||
title: String, text: String? = null,
|
||||
confirmText: String = generalGetString(MR.strings.ok)
|
||||
confirmText: String = generalGetString(MR.strings.ok),
|
||||
hostDevice: Pair<Long?, String>? = null,
|
||||
) {
|
||||
showAlert {
|
||||
AlertDialog(
|
||||
onDismissRequest = this::hideAlert,
|
||||
title = alertTitle(title),
|
||||
text = alertText(text),
|
||||
buttons = {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequester.requestFocus()
|
||||
}
|
||||
Row(
|
||||
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING).padding(bottom = DEFAULT_PADDING_HALF),
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
TextButton(
|
||||
onClick = {
|
||||
hideAlert()
|
||||
},
|
||||
Modifier.focusRequester(focusRequester)
|
||||
AlertContent(text, hostDevice, extraPadding = true) {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequester.requestFocus()
|
||||
}
|
||||
Row(
|
||||
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING),
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(confirmText, color = Color.Unspecified)
|
||||
TextButton(
|
||||
onClick = {
|
||||
hideAlert()
|
||||
},
|
||||
Modifier.focusRequester(focusRequester)
|
||||
) {
|
||||
Text(confirmText, color = Color.Unspecified)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -191,16 +186,17 @@ class AlertManager {
|
||||
|
||||
fun showAlertMsgWithProgress(
|
||||
title: String,
|
||||
text: String? = null
|
||||
text: String? = null,
|
||||
) {
|
||||
showAlert {
|
||||
AlertDialog(
|
||||
onDismissRequest = this::hideAlert,
|
||||
title = alertTitle(title),
|
||||
text = alertText(text),
|
||||
buttons = {
|
||||
Box(Modifier.fillMaxWidth().height(72.dp).padding(bottom = DEFAULT_PADDING * 2), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator(Modifier.size(36.dp).padding(4.dp), color = MaterialTheme.colors.secondary, strokeWidth = 3.dp)
|
||||
AlertContent(text, null) {
|
||||
Box(Modifier.fillMaxWidth().height(72.dp).padding(bottom = DEFAULT_PADDING * 2), contentAlignment = Alignment.Center) {
|
||||
CircularProgressIndicator(Modifier.size(36.dp).padding(4.dp), color = MaterialTheme.colors.secondary, strokeWidth = 3.dp)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -211,7 +207,8 @@ class AlertManager {
|
||||
title: StringResource,
|
||||
text: StringResource? = null,
|
||||
confirmText: StringResource = MR.strings.ok,
|
||||
) = showAlertMsg(generalGetString(title), if (text != null) generalGetString(text) else null, generalGetString(confirmText))
|
||||
hostDevice: Pair<Long?, String>? = null,
|
||||
) = showAlertMsg(generalGetString(title), if (text != null) generalGetString(text) else null, generalGetString(confirmText), hostDevice)
|
||||
|
||||
@Composable
|
||||
fun showInView() {
|
||||
@ -234,18 +231,75 @@ private fun alertTitle(title: String): (@Composable () -> Unit)? {
|
||||
}
|
||||
}
|
||||
|
||||
private fun alertText(text: String?): (@Composable () -> Unit)? {
|
||||
return if (text == null) {
|
||||
null
|
||||
} else {
|
||||
({
|
||||
Text(
|
||||
escapedHtmlToAnnotatedString(text, LocalDensity.current),
|
||||
Modifier.fillMaxWidth(),
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = 16.sp,
|
||||
color = MaterialTheme.colors.secondary
|
||||
)
|
||||
})
|
||||
@Composable
|
||||
private fun AlertContent(text: String?, hostDevice: Pair<Long?, String>?, extraPadding: Boolean = false, content: @Composable (() -> Unit)) {
|
||||
Column(
|
||||
Modifier
|
||||
.padding(bottom = if (appPlatform.isDesktop) DEFAULT_PADDING else DEFAULT_PADDING_HALF)
|
||||
) {
|
||||
if (appPlatform.isDesktop) {
|
||||
HostDeviceTitle(hostDevice, extraPadding = extraPadding)
|
||||
} else {
|
||||
Spacer(Modifier.size(DEFAULT_PADDING_HALF))
|
||||
}
|
||||
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
|
||||
if (text != null) {
|
||||
Text(
|
||||
escapedHtmlToAnnotatedString(text, LocalDensity.current),
|
||||
Modifier.fillMaxWidth().padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, bottom = DEFAULT_PADDING * 1.5f),
|
||||
fontSize = 16.sp,
|
||||
textAlign = TextAlign.Center,
|
||||
color = MaterialTheme.colors.secondary
|
||||
)
|
||||
}
|
||||
}
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AlertContent(text: AnnotatedString?, hostDevice: Pair<Long?, String>?, extraPadding: Boolean = false, content: @Composable (() -> Unit)) {
|
||||
Column(
|
||||
Modifier
|
||||
.padding(bottom = if (appPlatform.isDesktop) DEFAULT_PADDING else DEFAULT_PADDING_HALF)
|
||||
) {
|
||||
if (appPlatform.isDesktop) {
|
||||
HostDeviceTitle(hostDevice, extraPadding = extraPadding)
|
||||
} else {
|
||||
Spacer(Modifier.size(DEFAULT_PADDING_HALF))
|
||||
}
|
||||
CompositionLocalProvider(LocalContentAlpha provides ContentAlpha.high) {
|
||||
if (text != null) {
|
||||
Text(
|
||||
text,
|
||||
Modifier.fillMaxWidth().padding(start = DEFAULT_PADDING, end = DEFAULT_PADDING, bottom = DEFAULT_PADDING * 1.5f),
|
||||
fontSize = 16.sp,
|
||||
textAlign = TextAlign.Center,
|
||||
color = MaterialTheme.colors.secondary
|
||||
)
|
||||
}
|
||||
}
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
fun hostDevice(rhId: Long?): Pair<Long?, String>? = if (rhId == null && chatModel.remoteHosts.isNotEmpty()) {
|
||||
null to ChatModel.controller.appPrefs.deviceNameForRemoteAccess.get()!!
|
||||
} else if (rhId == null) {
|
||||
null
|
||||
} else {
|
||||
rhId to (chatModel.remoteHosts.firstOrNull { it.remoteHostId == rhId }?.hostDeviceName?.ifEmpty { rhId.toString() } ?: rhId.toString())
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HostDeviceTitle(hostDevice: Pair<Long?, String>?, extraPadding: Boolean = false) {
|
||||
if (hostDevice != null) {
|
||||
Row(Modifier.fillMaxWidth().padding(top = 5.dp, bottom = if (extraPadding) DEFAULT_PADDING * 2 else DEFAULT_PADDING_HALF), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.Center) {
|
||||
Icon(painterResource(if (hostDevice.first == null) MR.images.ic_desktop else MR.images.ic_smartphone_300), null, Modifier.size(15.dp), tint = MaterialTheme.colors.secondary)
|
||||
Spacer(Modifier.width(10.dp))
|
||||
Text(hostDevice.second, color = MaterialTheme.colors.secondary)
|
||||
}
|
||||
} else {
|
||||
Spacer(Modifier.height(if (extraPadding) DEFAULT_PADDING * 2 else 0.dp))
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import SectionBottomSpacer
|
||||
import SectionItemView
|
||||
import SectionTextFooter
|
||||
import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import chat.simplex.common.platform.Log
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
@ -17,7 +16,7 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.platform.TAG
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.chatlist.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
@ -65,6 +64,7 @@ suspend fun planAndConnect(
|
||||
confirmText = if (incognito) generalGetString(MR.strings.connect_via_link_incognito) else generalGetString(MR.strings.connect_via_link_verb),
|
||||
onConfirm = { withApi { connectViaUri(chatModel, rhId, uri, incognito, connectionPlan, close) } },
|
||||
destructive = true,
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
} else {
|
||||
askCurrentOrIncognitoProfileAlert(
|
||||
@ -82,12 +82,14 @@ suspend fun planAndConnect(
|
||||
openKnownContact(chatModel, rhId, close, contact)
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.contact_already_exists),
|
||||
String.format(generalGetString(MR.strings.connect_plan_you_are_already_connecting_to_vName), contact.displayName)
|
||||
String.format(generalGetString(MR.strings.connect_plan_you_are_already_connecting_to_vName), contact.displayName),
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
} else {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.connect_plan_already_connecting),
|
||||
generalGetString(MR.strings.connect_plan_you_are_already_connecting_via_this_one_time_link)
|
||||
generalGetString(MR.strings.connect_plan_you_are_already_connecting_via_this_one_time_link),
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -97,7 +99,8 @@ suspend fun planAndConnect(
|
||||
openKnownContact(chatModel, rhId, close, contact)
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.contact_already_exists),
|
||||
String.format(generalGetString(MR.strings.you_are_already_connected_to_vName_via_this_link), contact.displayName)
|
||||
String.format(generalGetString(MR.strings.you_are_already_connected_to_vName_via_this_link), contact.displayName),
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -124,6 +127,7 @@ suspend fun planAndConnect(
|
||||
confirmText = if (incognito) generalGetString(MR.strings.connect_via_link_incognito) else generalGetString(MR.strings.connect_via_link_verb),
|
||||
onConfirm = { withApi { connectViaUri(chatModel, rhId, uri, incognito, connectionPlan, close) } },
|
||||
destructive = true,
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
} else {
|
||||
askCurrentOrIncognitoProfileAlert(
|
||||
@ -143,6 +147,7 @@ suspend fun planAndConnect(
|
||||
confirmText = if (incognito) generalGetString(MR.strings.connect_via_link_incognito) else generalGetString(MR.strings.connect_via_link_verb),
|
||||
onConfirm = { withApi { connectViaUri(chatModel, rhId, uri, incognito, connectionPlan, close) } },
|
||||
destructive = true,
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
} else {
|
||||
askCurrentOrIncognitoProfileAlert(
|
||||
@ -159,7 +164,8 @@ suspend fun planAndConnect(
|
||||
openKnownContact(chatModel, rhId, close, contact)
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.contact_already_exists),
|
||||
String.format(generalGetString(MR.strings.connect_plan_you_are_already_connecting_to_vName), contact.displayName)
|
||||
String.format(generalGetString(MR.strings.connect_plan_you_are_already_connecting_to_vName), contact.displayName),
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
is ContactAddressPlan.Known -> {
|
||||
@ -168,7 +174,8 @@ suspend fun planAndConnect(
|
||||
openKnownContact(chatModel, rhId, close, contact)
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.contact_already_exists),
|
||||
String.format(generalGetString(MR.strings.you_are_already_connected_to_vName_via_this_link), contact.displayName)
|
||||
String.format(generalGetString(MR.strings.you_are_already_connected_to_vName_via_this_link), contact.displayName),
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
is ContactAddressPlan.ContactViaAddress -> {
|
||||
@ -190,7 +197,8 @@ suspend fun planAndConnect(
|
||||
title = generalGetString(MR.strings.connect_via_group_link),
|
||||
text = generalGetString(MR.strings.you_will_join_group),
|
||||
confirmText = if (incognito) generalGetString(MR.strings.join_group_incognito_button) else generalGetString(MR.strings.join_group_button),
|
||||
onConfirm = { withApi { connectViaUri(chatModel, rhId, uri, incognito, connectionPlan, close) } }
|
||||
onConfirm = { withApi { connectViaUri(chatModel, rhId, uri, incognito, connectionPlan, close) } },
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
} else {
|
||||
askCurrentOrIncognitoProfileAlert(
|
||||
@ -215,6 +223,7 @@ suspend fun planAndConnect(
|
||||
confirmText = if (incognito) generalGetString(MR.strings.join_group_incognito_button) else generalGetString(MR.strings.join_group_button),
|
||||
onConfirm = { withApi { connectViaUri(chatModel, rhId, uri, incognito, connectionPlan, close) } },
|
||||
destructive = true,
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
} else {
|
||||
askCurrentOrIncognitoProfileAlert(
|
||||
@ -236,7 +245,8 @@ suspend fun planAndConnect(
|
||||
} else {
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.connect_plan_already_joining_the_group),
|
||||
generalGetString(MR.strings.connect_plan_you_are_already_joining_the_group_via_this_link)
|
||||
generalGetString(MR.strings.connect_plan_you_are_already_joining_the_group_via_this_link),
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -246,7 +256,8 @@ suspend fun planAndConnect(
|
||||
openKnownGroup(chatModel, rhId, close, groupInfo)
|
||||
AlertManager.shared.showAlertMsg(
|
||||
generalGetString(MR.strings.connect_plan_group_already_exists),
|
||||
String.format(generalGetString(MR.strings.connect_plan_you_are_already_in_group_vName), groupInfo.displayName)
|
||||
String.format(generalGetString(MR.strings.connect_plan_you_are_already_in_group_vName), groupInfo.displayName),
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -284,7 +295,8 @@ suspend fun connectViaUri(
|
||||
ConnectionLinkType.CONTACT -> generalGetString(MR.strings.you_will_be_connected_when_your_connection_request_is_accepted)
|
||||
ConnectionLinkType.INVITATION -> generalGetString(MR.strings.you_will_be_connected_when_your_contacts_device_is_online)
|
||||
ConnectionLinkType.GROUP -> generalGetString(MR.strings.you_will_be_connected_when_group_host_device_is_online)
|
||||
}
|
||||
},
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
return r
|
||||
@ -336,7 +348,8 @@ fun askCurrentOrIncognitoProfileAlert(
|
||||
Text(stringResource(MR.strings.cancel_verb), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
|
||||
@ -411,7 +424,8 @@ fun ownGroupLinkConfirmConnect(
|
||||
Text(stringResource(MR.strings.cancel_verb), Modifier.fillMaxWidth(), textAlign = TextAlign.Center, color = MaterialTheme.colors.primary)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
hostDevice = hostDevice(rhId),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -1668,6 +1668,7 @@
|
||||
<string name="unlink_desktop_question">Unlink desktop?</string>
|
||||
<string name="unlink_desktop">Unlink</string>
|
||||
<string name="disconnect_remote_host">Disconnect</string>
|
||||
<string name="remote_host_was_disconnected_toast"><![CDATA[Remote host was disconnected: <b>%s</b>]]></string>
|
||||
<string name="disconnect_desktop_question">Disconnect desktop?</string>
|
||||
<string name="only_one_device_can_work_at_the_same_time">Only one device can work at the same time</string>
|
||||
<string name="open_on_mobile_and_scan_qr_code"><![CDATA[Open <i>Use from desktop</i> in mobile app and scan QR code]]></string>
|
||||
|
@ -10,6 +10,7 @@ import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.key.*
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.*
|
||||
import chat.simplex.common.model.ChatController
|
||||
@ -19,6 +20,7 @@ import chat.simplex.common.ui.theme.DEFAULT_START_MODAL_WIDTH
|
||||
import chat.simplex.common.ui.theme.SimpleXTheme
|
||||
import chat.simplex.common.views.TerminalView
|
||||
import chat.simplex.common.views.helpers.FileDialogChooser
|
||||
import chat.simplex.common.views.helpers.escapedHtmlToAnnotatedString
|
||||
import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.*
|
||||
@ -80,7 +82,7 @@ fun showApp() = application {
|
||||
if (toast != null) {
|
||||
Box(Modifier.fillMaxSize().padding(bottom = 20.dp), contentAlignment = Alignment.BottomCenter) {
|
||||
Text(
|
||||
toast.first,
|
||||
escapedHtmlToAnnotatedString(toast.first, LocalDensity.current),
|
||||
Modifier.background(MaterialTheme.colors.primary, RoundedCornerShape(100)).padding(vertical = 5.dp, horizontal = 10.dp),
|
||||
color = MaterialTheme.colors.onPrimary,
|
||||
style = MaterialTheme.typography.body1
|
||||
|
@ -4,7 +4,6 @@ import androidx.compose.ui.platform.ClipboardManager
|
||||
import androidx.compose.ui.platform.UriHandler
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import chat.simplex.common.model.*
|
||||
import chat.simplex.common.views.helpers.getAppFileUri
|
||||
import chat.simplex.common.views.helpers.withApi
|
||||
import java.io.File
|
||||
import java.net.URI
|
||||
|
@ -19,7 +19,6 @@ import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
@Composable
|
||||
actual fun ReactionIcon(text: String, fontSize: TextUnit) {
|
||||
|
Loading…
Reference in New Issue
Block a user