desktop: enhancements to remote hosts experience (#3428)
This commit is contained in:
parent
9442121efa
commit
48d7afc959
@ -126,7 +126,7 @@ fun processIntent(intent: Intent?) {
|
||||
when (intent?.action) {
|
||||
"android.intent.action.VIEW" -> {
|
||||
val uri = intent.data
|
||||
if (uri != null) connectIfOpenedViaUri(chatModel.remoteHostId, uri.toURI(), ChatModel)
|
||||
if (uri != null) connectIfOpenedViaUri(chatModel.remoteHostId(), uri.toURI(), ChatModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class SimplexApp: Application(), LifecycleEventObserver {
|
||||
updatingChatsMutex.withLock {
|
||||
kotlin.runCatching {
|
||||
val currentUserId = chatModel.currentUser.value?.userId
|
||||
val chats = ArrayList(chatController.apiGetChats(chatModel.remoteHostId))
|
||||
val chats = ArrayList(chatController.apiGetChats(chatModel.remoteHostId()))
|
||||
/** Active user can be changed in background while [ChatController.apiGetChats] is executing */
|
||||
if (chatModel.currentUser.value?.userId == currentUserId) {
|
||||
val currentChatId = chatModel.chatId.value
|
||||
|
@ -111,7 +111,8 @@ object ChatModel {
|
||||
// remote controller
|
||||
val remoteHosts = mutableStateListOf<RemoteHostInfo>()
|
||||
val currentRemoteHost = mutableStateOf<RemoteHostInfo?>(null)
|
||||
val remoteHostId: Long? get() = currentRemoteHost?.value?.remoteHostId
|
||||
val remoteHostId: Long? @Composable get() = remember { currentRemoteHost }.value?.remoteHostId
|
||||
fun remoteHostId(): Long? = currentRemoteHost.value?.remoteHostId
|
||||
val newRemoteHostPairing = mutableStateOf<Pair<RemoteHostInfo?, RemoteHostSessionState>?>(null)
|
||||
val remoteCtrlSession = mutableStateOf<RemoteCtrlSession?>(null)
|
||||
|
||||
|
@ -1625,7 +1625,7 @@ object ChatController {
|
||||
|| (mc is MsgContent.MCVoice && file.fileSize <= MAX_VOICE_SIZE_AUTO_RCV && file.fileStatus !is CIFileStatus.RcvAccepted))) {
|
||||
withApi { receiveFile(rhId, r.user, file.fileId, encrypted = cItem.encryptLocalFile && chatController.appPrefs.privacyEncryptLocalFiles.get(), auto = true) }
|
||||
}
|
||||
if (cItem.showNotification && (allowedToShowNotification() || chatModel.chatId.value != cInfo.id || chatModel.remoteHostId != rhId)) {
|
||||
if (cItem.showNotification && (allowedToShowNotification() || chatModel.chatId.value != cInfo.id || chatModel.remoteHostId() != rhId)) {
|
||||
ntfManager.notifyMessageReceived(r.user, cInfo, cItem)
|
||||
}
|
||||
}
|
||||
@ -1913,7 +1913,7 @@ object ChatController {
|
||||
}
|
||||
|
||||
private fun activeUser(rhId: Long?, user: UserLike): Boolean =
|
||||
rhId == chatModel.remoteHostId && user.userId == chatModel.currentUser.value?.userId
|
||||
rhId == chatModel.remoteHostId() && user.userId == chatModel.currentUser.value?.userId
|
||||
|
||||
private fun withCall(r: CR, contact: Contact, perform: (Call) -> Unit) {
|
||||
val call = chatModel.activeCall.value
|
||||
|
@ -54,7 +54,7 @@ private fun sendCommand(chatModel: ChatModel, composeState: MutableState<Compose
|
||||
withApi {
|
||||
// show "in progress"
|
||||
// TODO show active remote host in chat console?
|
||||
chatModel.controller.sendCmd(chatModel.remoteHostId, CC.Console(s))
|
||||
chatModel.controller.sendCmd(chatModel.remoteHostId(), CC.Console(s))
|
||||
composeState.value = ComposeState(useLinkPreviews = false)
|
||||
// hide "in progress"
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ fun CreateFirstProfile(chatModel: ChatModel, close: () -> Unit) {
|
||||
|
||||
fun createProfileInProfiles(chatModel: ChatModel, displayName: String, close: () -> Unit) {
|
||||
withApi {
|
||||
val rhId = chatModel.remoteHostId
|
||||
val rhId = chatModel.remoteHostId()
|
||||
val user = chatModel.controller.apiCreateActiveUser(
|
||||
rhId, Profile(displayName.trim(), "", null)
|
||||
) ?: return@withApi
|
||||
|
@ -17,7 +17,7 @@ fun ScanCodeView(verifyCode: (String?, cb: (Boolean) -> Unit) -> Unit, close: ()
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = DEFAULT_PADDING)
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.scan_code), false)
|
||||
AppBarTitle(stringResource(MR.strings.scan_code), withPadding = false)
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
|
@ -63,7 +63,7 @@ private fun VerifyCodeLayout(
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = DEFAULT_PADDING)
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.security_code), false)
|
||||
AppBarTitle(stringResource(MR.strings.security_code), withPadding = false)
|
||||
val splitCode = splitToParts(connectionCode, 24)
|
||||
Row(Modifier.fillMaxWidth().padding(bottom = DEFAULT_PADDING_HALF), horizontalArrangement = Arrangement.Center) {
|
||||
if (connectionVerified) {
|
||||
|
@ -53,7 +53,7 @@ fun ChatListView(chatModel: ChatModel, settingsState: SettingsViewState, setPerf
|
||||
val url = chatModel.appOpenUrl.value
|
||||
if (url != null) {
|
||||
chatModel.appOpenUrl.value = null
|
||||
connectIfOpenedViaUri(chatModel.remoteHostId, url, chatModel)
|
||||
connectIfOpenedViaUri(chatModel.remoteHostId(), url, chatModel)
|
||||
}
|
||||
}
|
||||
if (appPlatform.isDesktop) {
|
||||
|
@ -26,8 +26,7 @@ import chat.simplex.common.model.ChatModel.controller
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.common.views.helpers.*
|
||||
import chat.simplex.common.platform.*
|
||||
import chat.simplex.common.views.remote.ConnectDesktopView
|
||||
import chat.simplex.common.views.remote.connectMobileDevice
|
||||
import chat.simplex.common.views.remote.*
|
||||
import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
import kotlinx.coroutines.delay
|
||||
@ -84,7 +83,7 @@ fun UserPicker(
|
||||
.filter { it }
|
||||
.collect {
|
||||
try {
|
||||
val updatedUsers = chatModel.controller.listUsers(chatModel.remoteHostId).sortedByDescending { it.user.activeUser }
|
||||
val updatedUsers = chatModel.controller.listUsers(chatModel.remoteHostId()).sortedByDescending { it.user.activeUser }
|
||||
var same = users.size == updatedUsers.size
|
||||
if (same) {
|
||||
for (i in 0 until minOf(users.size, updatedUsers.size)) {
|
||||
@ -213,6 +212,14 @@ fun UserPicker(
|
||||
userPickerState.value = AnimatedViewState.GONE
|
||||
}
|
||||
Divider(Modifier.requiredHeight(1.dp))
|
||||
} else if (remoteHosts.isEmpty()) {
|
||||
LinkAMobilePickerItem {
|
||||
ModalManager.start.showModal {
|
||||
ConnectMobileView()
|
||||
}
|
||||
userPickerState.value = AnimatedViewState.GONE
|
||||
}
|
||||
Divider(Modifier.requiredHeight(1.dp))
|
||||
}
|
||||
if (showSettings) {
|
||||
SettingsPickerItem(settingsClicked)
|
||||
@ -384,6 +391,16 @@ private fun UseFromDesktopPickerItem(onClick: () -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LinkAMobilePickerItem(onClick: () -> Unit) {
|
||||
SectionItemView(onClick, padding = PaddingValues(start = DEFAULT_PADDING + 7.dp, end = DEFAULT_PADDING), minHeight = 68.dp) {
|
||||
val text = generalGetString(MR.strings.link_a_mobile)
|
||||
Icon(painterResource(MR.images.ic_smartphone_300), text, Modifier.size(20.dp), tint = MaterialTheme.colors.onBackground)
|
||||
Spacer(Modifier.width(DEFAULT_PADDING + 6.dp))
|
||||
Text(text, color = if (isInDarkTheme()) MenuTextColorDark else Color.Black)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SettingsPickerItem(onClick: () -> Unit) {
|
||||
SectionItemView(onClick, padding = PaddingValues(start = DEFAULT_PADDING + 7.dp, end = DEFAULT_PADDING), minHeight = 68.dp) {
|
||||
|
@ -627,7 +627,7 @@ private fun afterSetCiTTL(
|
||||
try {
|
||||
updatingChatsMutex.withLock {
|
||||
// this is using current remote host on purpose - if it changes during update, it will load correct chats
|
||||
val chats = m.controller.apiGetChats(m.remoteHostId)
|
||||
val chats = m.controller.apiGetChats(m.remoteHostId())
|
||||
m.updateChats(chats)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
|
@ -88,7 +88,7 @@ class AlertManager {
|
||||
onDismissRequest = { onDismissRequest?.invoke(); hideAlert() },
|
||||
title = alertTitle(title),
|
||||
buttons = {
|
||||
AlertContent(text, hostDevice) {
|
||||
AlertContent(text, hostDevice, true) {
|
||||
Row(
|
||||
Modifier.fillMaxWidth().padding(horizontal = DEFAULT_PADDING),
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
|
@ -14,6 +14,8 @@ import androidx.compose.desktop.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.simplex.common.ui.theme.*
|
||||
import chat.simplex.res.MR
|
||||
import dev.icerock.moko.resources.compose.painterResource
|
||||
|
||||
@Composable
|
||||
fun CloseSheetBar(close: (() -> Unit)?, showClose: Boolean = true, endButtons: @Composable RowScope.() -> Unit = {}) {
|
||||
@ -47,23 +49,38 @@ fun CloseSheetBar(close: (() -> Unit)?, showClose: Boolean = true, endButtons: @
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun AppBarTitle(title: String, withPadding: Boolean = true, bottomPadding: Dp = DEFAULT_PADDING * 1.5f) {
|
||||
fun AppBarTitle(title: String, hostDevice: Pair<Long?, String>? = null, withPadding: Boolean = true, bottomPadding: Dp = DEFAULT_PADDING * 1.5f) {
|
||||
val theme = CurrentColors.collectAsState()
|
||||
val titleColor = CurrentColors.collectAsState().value.appColors.title
|
||||
val brush = if (theme.value.base == DefaultTheme.SIMPLEX)
|
||||
Brush.linearGradient(listOf(titleColor.darker(0.2f), titleColor.lighter(0.35f)), Offset(0f, Float.POSITIVE_INFINITY), Offset(Float.POSITIVE_INFINITY, 0f))
|
||||
else // color is not updated when changing themes if I pass null here
|
||||
Brush.linearGradient(listOf(titleColor, titleColor), Offset(0f, Float.POSITIVE_INFINITY), Offset(Float.POSITIVE_INFINITY, 0f))
|
||||
Text(
|
||||
title,
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(bottom = bottomPadding, start = if (withPadding) DEFAULT_PADDING else 0.dp, end = if (withPadding) DEFAULT_PADDING else 0.dp,),
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.h1.copy(brush = brush),
|
||||
color = MaterialTheme.colors.primaryVariant,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Column {
|
||||
Text(
|
||||
title,
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = if (withPadding) DEFAULT_PADDING else 0.dp, end = if (withPadding) DEFAULT_PADDING else 0.dp,),
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
style = MaterialTheme.typography.h1.copy(brush = brush),
|
||||
color = MaterialTheme.colors.primaryVariant,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
if (hostDevice != null) {
|
||||
HostDeviceTitle(hostDevice)
|
||||
}
|
||||
Spacer(Modifier.height(bottomPadding))
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HostDeviceTitle(hostDevice: Pair<Long?, String>, extraPadding: Boolean = false) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview/*(
|
||||
|
@ -373,7 +373,7 @@ inline fun <reified T> serializableSaver(): Saver<T, *> = Saver(
|
||||
fun UriHandler.openVerifiedSimplexUri(uri: String) {
|
||||
val URI = try { URI.create(uri) } catch (e: Exception) { null }
|
||||
if (URI != null) {
|
||||
connectIfOpenedViaUri(chatModel.remoteHostId, URI, ChatModel)
|
||||
connectIfOpenedViaUri(chatModel.remoteHostId(), URI, ChatModel)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,7 +79,7 @@ fun AddContactLayout(
|
||||
.verticalScroll(rememberScrollState()),
|
||||
verticalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.add_contact))
|
||||
AppBarTitle(stringResource(MR.strings.add_contact), hostDevice(rh?.remoteHostId))
|
||||
|
||||
SectionView(stringResource(MR.strings.one_time_link_short).uppercase()) {
|
||||
if (connReq.isNotEmpty()) {
|
||||
|
@ -58,6 +58,7 @@ fun AddGroupView(chatModel: ChatModel, rh: RemoteHostInfo?, close: () -> Unit) {
|
||||
}
|
||||
},
|
||||
incognitoPref = chatModel.controller.appPrefs.incognito,
|
||||
rhId,
|
||||
close
|
||||
)
|
||||
}
|
||||
@ -66,6 +67,7 @@ fun AddGroupView(chatModel: ChatModel, rh: RemoteHostInfo?, close: () -> Unit) {
|
||||
fun AddGroupLayout(
|
||||
createGroup: (Boolean, GroupProfile) -> Unit,
|
||||
incognitoPref: SharedPreference<Boolean>,
|
||||
rhId: Long?,
|
||||
close: () -> Unit
|
||||
) {
|
||||
val bottomSheetModalState = rememberModalBottomSheetState(initialValue = ModalBottomSheetValue.Hidden)
|
||||
@ -98,7 +100,7 @@ fun AddGroupLayout(
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = DEFAULT_PADDING)
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.create_secret_group_title))
|
||||
AppBarTitle(stringResource(MR.strings.create_secret_group_title), hostDevice(rhId))
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
@ -174,7 +176,8 @@ fun PreviewAddGroupLayout() {
|
||||
AddGroupLayout(
|
||||
createGroup = { _, _ -> },
|
||||
incognitoPref = SharedPreference({ false }, {}),
|
||||
close = {}
|
||||
close = {},
|
||||
rhId = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -56,6 +56,7 @@ fun ContactConnectionInfoView(
|
||||
connReq = connReqInvitation,
|
||||
contactConnection = contactConnection,
|
||||
focusAlias = focusAlias,
|
||||
rhId = rhId,
|
||||
deleteConnection = { deleteContactConnectionAlert(rhId, contactConnection, chatModel, close) },
|
||||
onLocalAliasChanged = { setContactAlias(rhId, contactConnection, it, chatModel) },
|
||||
share = { if (connReqInvitation != null) clipboard.shareText(connReqInvitation) },
|
||||
@ -80,6 +81,7 @@ private fun ContactConnectionInfoLayout(
|
||||
connReq: String?,
|
||||
contactConnection: PendingContactConnection,
|
||||
focusAlias: Boolean,
|
||||
rhId: Long?,
|
||||
deleteConnection: () -> Unit,
|
||||
onLocalAliasChanged: (String) -> Unit,
|
||||
share: () -> Unit,
|
||||
@ -114,7 +116,8 @@ private fun ContactConnectionInfoLayout(
|
||||
stringResource(
|
||||
if (contactConnection.initiated) MR.strings.you_invited_a_contact
|
||||
else MR.strings.you_accepted_connection
|
||||
)
|
||||
),
|
||||
hostDevice(rhId)
|
||||
)
|
||||
Text(
|
||||
stringResource(
|
||||
@ -185,6 +188,7 @@ private fun PreviewContactConnectionInfoView() {
|
||||
connReq = "https://simplex.chat/contact#/?v=1&smp=smp%3A%2F%2FPQUV2eL0t7OStZOoAsPEV2QYWt4-xilbakvGUGOItUo%3D%40smp6.simplex.im%2FK1rslx-m5bpXVIdMZg9NLUZ_8JBm8xTt%23MCowBQYDK2VuAyEALDeVe-sG8mRY22LsXlPgiwTNs9dbiLrNuA7f3ZMAJ2w%3D",
|
||||
contactConnection = PendingContactConnection.getSampleData(),
|
||||
focusAlias = false,
|
||||
rhId = null,
|
||||
deleteConnection = {},
|
||||
onLocalAliasChanged = {},
|
||||
share = {},
|
||||
|
@ -67,7 +67,7 @@ fun PasteToConnectLayout(
|
||||
Modifier.verticalScroll(rememberScrollState()).padding(horizontal = DEFAULT_PADDING),
|
||||
verticalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.connect_via_link), false)
|
||||
AppBarTitle(stringResource(MR.strings.connect_via_link), hostDevice(rhId), withPadding = false)
|
||||
|
||||
Box(Modifier.padding(top = DEFAULT_PADDING, bottom = 6.dp)) {
|
||||
TextEditor(
|
||||
|
@ -469,7 +469,7 @@ fun ConnectContactLayout(
|
||||
Modifier.verticalScroll(rememberScrollState()).padding(horizontal = DEFAULT_PADDING),
|
||||
verticalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.scan_QR_code), false)
|
||||
AppBarTitle(stringResource(MR.strings.scan_QR_code), hostDevice(rh?.remoteHostId), withPadding = false)
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
|
@ -26,7 +26,7 @@ fun HowItWorks(user: User?, onboardingStage: SharedPreference<OnboardingStage>?
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = DEFAULT_PADDING),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.how_simplex_works), false)
|
||||
AppBarTitle(stringResource(MR.strings.how_simplex_works), withPadding = false)
|
||||
ReadableText(MR.strings.many_people_asked_how_can_it_deliver)
|
||||
ReadableText(MR.strings.to_protect_privacy_simplex_has_ids_for_queues)
|
||||
ReadableText(MR.strings.you_control_servers_to_receive_your_contacts_to_send)
|
||||
|
@ -36,12 +36,10 @@ import dev.icerock.moko.resources.compose.painterResource
|
||||
import dev.icerock.moko.resources.compose.stringResource
|
||||
|
||||
@Composable
|
||||
fun ConnectMobileView(
|
||||
m: ChatModel
|
||||
) {
|
||||
fun ConnectMobileView() {
|
||||
val connecting = rememberSaveable() { mutableStateOf(false) }
|
||||
val remoteHosts = remember { chatModel.remoteHosts }
|
||||
val deviceName = m.controller.appPrefs.deviceNameForRemoteAccess
|
||||
val deviceName = chatModel.controller.appPrefs.deviceNameForRemoteAccess
|
||||
LaunchedEffect(Unit) {
|
||||
controller.reloadRemoteHosts()
|
||||
}
|
||||
@ -49,11 +47,11 @@ fun ConnectMobileView(
|
||||
deviceName = remember { deviceName.state },
|
||||
remoteHosts = remoteHosts,
|
||||
connecting,
|
||||
connectedHost = remember { m.currentRemoteHost },
|
||||
connectedHost = remember { chatModel.currentRemoteHost },
|
||||
updateDeviceName = {
|
||||
withBGApi {
|
||||
if (it != "") {
|
||||
m.controller.setLocalDeviceName(it)
|
||||
chatModel.controller.setLocalDeviceName(it)
|
||||
deviceName.set(it)
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ fun HelpLayout(userDisplayName: String) {
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(horizontal = DEFAULT_PADDING),
|
||||
){
|
||||
AppBarTitle(String.format(stringResource(MR.strings.personal_welcome), userDisplayName), false)
|
||||
AppBarTitle(String.format(stringResource(MR.strings.personal_welcome), userDisplayName), withPadding = false)
|
||||
ChatHelpView()
|
||||
}
|
||||
}
|
||||
|
@ -29,13 +29,12 @@ import kotlinx.coroutines.launch
|
||||
|
||||
@Composable
|
||||
fun ProtocolServersView(m: ChatModel, rhId: Long?, serverProtocol: ServerProtocol, close: () -> Unit) {
|
||||
// TODO close if remote host changes
|
||||
var presetServers by remember { mutableStateOf(emptyList<String>()) }
|
||||
var servers by remember {
|
||||
var presetServers by remember(rhId) { mutableStateOf(emptyList<String>()) }
|
||||
var servers by remember(rhId) {
|
||||
mutableStateOf(m.userSMPServersUnsaved.value ?: emptyList())
|
||||
}
|
||||
val currServers = remember { mutableStateOf(servers) }
|
||||
val testing = rememberSaveable { mutableStateOf(false) }
|
||||
val currServers = remember(rhId) { mutableStateOf(servers) }
|
||||
val testing = rememberSaveable(rhId) { mutableStateOf(false) }
|
||||
val serversUnchanged = remember { derivedStateOf { servers == currServers.value || testing.value } }
|
||||
val allServersDisabled = remember { derivedStateOf { servers.all { !it.enabled } } }
|
||||
val saveDisabled = remember {
|
||||
@ -51,7 +50,12 @@ fun ProtocolServersView(m: ChatModel, rhId: Long?, serverProtocol: ServerProtoco
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
KeyChangeEffect(rhId) {
|
||||
m.userSMPServersUnsaved.value = null
|
||||
servers = emptyList()
|
||||
}
|
||||
|
||||
LaunchedEffect(rhId) {
|
||||
val res = m.controller.getUserProtoServers(rhId, serverProtocol)
|
||||
if (res != null) {
|
||||
currServers.value = res.protoServers
|
||||
|
@ -22,7 +22,7 @@ fun ScanProtocolServerLayout(rhId: Long?, onNext: (ServerCfg) -> Unit) {
|
||||
.fillMaxSize()
|
||||
.padding(horizontal = DEFAULT_PADDING)
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.smp_servers_scan_qr), false)
|
||||
AppBarTitle(stringResource(MR.strings.smp_servers_scan_qr), withPadding = false)
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
|
@ -158,7 +158,7 @@ fun SettingsLayout(
|
||||
SettingsActionItem(painterResource(MR.images.ic_qr_code), stringResource(MR.strings.your_simplex_contact_address), showCustomModal { it, close -> UserAddressView(it, it.currentUser.value?.remoteHostId, shareViaProfile = it.currentUser.value!!.addressShared, close = close) }, disabled = stopped, extraPadding = true)
|
||||
ChatPreferencesItem(showCustomModal, stopped = stopped)
|
||||
if (appPlatform.isDesktop) {
|
||||
SettingsActionItem(painterResource(MR.images.ic_smartphone), stringResource(if (remember { chatModel.remoteHosts }.isEmpty()) MR.strings.link_a_mobile else MR.strings.linked_mobiles), showModal { ConnectMobileView(it) }, disabled = stopped, extraPadding = true)
|
||||
SettingsActionItem(painterResource(MR.images.ic_smartphone), stringResource(if (remember { chatModel.remoteHosts }.isEmpty()) MR.strings.link_a_mobile else MR.strings.linked_mobiles), showModal { ConnectMobileView() }, disabled = stopped, extraPadding = true)
|
||||
} else {
|
||||
SettingsActionItem(painterResource(MR.images.ic_desktop), stringResource(MR.strings.settings_section_title_use_from_desktop), showCustomModal{ it, close -> ConnectDesktopView(close) }, disabled = stopped, extraPadding = true)
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ fun UserAddressView(
|
||||
UserAddressLayout(
|
||||
userAddress = userAddress.value,
|
||||
shareViaProfile,
|
||||
rhId,
|
||||
onCloseHandler,
|
||||
createAddress = {
|
||||
withApi {
|
||||
@ -169,6 +170,7 @@ fun UserAddressView(
|
||||
private fun UserAddressLayout(
|
||||
userAddress: UserContactLinkRec?,
|
||||
shareViaProfile: MutableState<Boolean>,
|
||||
rhId: Long?,
|
||||
onCloseHandler: MutableState<(close: () -> Unit) -> Unit>,
|
||||
createAddress: () -> Unit,
|
||||
learnMore: () -> Unit,
|
||||
@ -181,7 +183,7 @@ private fun UserAddressLayout(
|
||||
Column(
|
||||
Modifier.verticalScroll(rememberScrollState()),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.simplex_address), false)
|
||||
AppBarTitle(stringResource(MR.strings.simplex_address), hostDevice(rhId), withPadding = false)
|
||||
Column(
|
||||
Modifier.fillMaxWidth().padding(bottom = DEFAULT_PADDING_HALF),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
@ -438,6 +440,7 @@ fun PreviewUserAddressLayoutNoAddress() {
|
||||
setProfileAddress = { _ -> },
|
||||
learnMore = {},
|
||||
shareViaProfile = remember { mutableStateOf(false) },
|
||||
rhId = null,
|
||||
onCloseHandler = remember { mutableStateOf({}) },
|
||||
sendEmail = {},
|
||||
)
|
||||
@ -471,6 +474,7 @@ fun PreviewUserAddressLayoutAddressCreated() {
|
||||
setProfileAddress = { _ -> },
|
||||
learnMore = {},
|
||||
shareViaProfile = remember { mutableStateOf(false) },
|
||||
rhId = null,
|
||||
onCloseHandler = remember { mutableStateOf({}) },
|
||||
sendEmail = {},
|
||||
)
|
||||
|
@ -18,7 +18,7 @@ fun VersionInfoView(info: CoreVersionInfo) {
|
||||
Column(
|
||||
Modifier.padding(horizontal = DEFAULT_PADDING),
|
||||
) {
|
||||
AppBarTitle(stringResource(MR.strings.app_version_title), false)
|
||||
AppBarTitle(stringResource(MR.strings.app_version_title), withPadding = false)
|
||||
if (appPlatform.isAndroid) {
|
||||
Text(String.format(stringResource(MR.strings.app_version_name), BuildConfigCommon.ANDROID_VERSION_NAME))
|
||||
Text(String.format(stringResource(MR.strings.app_version_code), BuildConfigCommon.ANDROID_VERSION_CODE))
|
||||
|
Loading…
Reference in New Issue
Block a user