mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
Finalising the debug menu
We can now switch environments between mainnet and testnet
This commit is contained in:
parent
89b3c616d7
commit
bc001e3a45
@ -45,6 +45,7 @@ import org.session.libsession.snode.SnodeModule;
|
|||||||
import org.session.libsession.utilities.Address;
|
import org.session.libsession.utilities.Address;
|
||||||
import org.session.libsession.utilities.ConfigFactoryUpdateListener;
|
import org.session.libsession.utilities.ConfigFactoryUpdateListener;
|
||||||
import org.session.libsession.utilities.Device;
|
import org.session.libsession.utilities.Device;
|
||||||
|
import org.session.libsession.utilities.Environment;
|
||||||
import org.session.libsession.utilities.ProfilePictureUtilities;
|
import org.session.libsession.utilities.ProfilePictureUtilities;
|
||||||
import org.session.libsession.utilities.SSKEnvironment;
|
import org.session.libsession.utilities.SSKEnvironment;
|
||||||
import org.session.libsession.utilities.TextSecurePreferences;
|
import org.session.libsession.utilities.TextSecurePreferences;
|
||||||
@ -237,7 +238,8 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
|
|||||||
messageNotifier = new OptimizedMessageNotifier(new DefaultMessageNotifier());
|
messageNotifier = new OptimizedMessageNotifier(new DefaultMessageNotifier());
|
||||||
broadcaster = new Broadcaster(this);
|
broadcaster = new Broadcaster(this);
|
||||||
LokiAPIDatabase apiDB = getDatabaseComponent().lokiAPIDatabase();
|
LokiAPIDatabase apiDB = getDatabaseComponent().lokiAPIDatabase();
|
||||||
SnodeModule.Companion.configure(apiDB, broadcaster);
|
boolean useTestNet = textSecurePreferences.getEnvironment() == Environment.TEST_NET;
|
||||||
|
SnodeModule.Companion.configure(apiDB, broadcaster, useTestNet);
|
||||||
initializeExpiringMessageManager();
|
initializeExpiringMessageManager();
|
||||||
initializeTypingStatusRepository();
|
initializeTypingStatusRepository();
|
||||||
initializeTypingStatusSender();
|
initializeTypingStatusSender();
|
||||||
@ -507,7 +509,7 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
|
|||||||
// Method to clear the local data - returns true on success otherwise false
|
// Method to clear the local data - returns true on success otherwise false
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all local profile data and message history then restart the app after a brief delay.
|
* Clear all local profile data and message history.
|
||||||
* @return true on success, false otherwise.
|
* @return true on success, false otherwise.
|
||||||
*/
|
*/
|
||||||
@SuppressLint("ApplySharedPref")
|
@SuppressLint("ApplySharedPref")
|
||||||
@ -519,6 +521,16 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
configFactory.keyPairChanged();
|
configFactory.keyPairChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear all local profile data and message history then restart the app after a brief delay.
|
||||||
|
* @return true on success, false otherwise.
|
||||||
|
*/
|
||||||
|
@SuppressLint("ApplySharedPref")
|
||||||
|
public boolean clearAllDataAndRestart() {
|
||||||
|
clearAllData();
|
||||||
Util.runOnMain(() -> new Handler().postDelayed(ApplicationContext.this::restartApplication, 200));
|
Util.runOnMain(() -> new Handler().postDelayed(ApplicationContext.this::restartApplication, 200));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1,33 +1,37 @@
|
|||||||
package org.thoughtcrime.securesms.debugmenu
|
package org.thoughtcrime.securesms.debugmenu
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.ColumnScope
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
import androidx.compose.foundation.layout.IntrinsicSize
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.SnackbarHost
|
||||||
|
import androidx.compose.material3.SnackbarHostState
|
||||||
import androidx.compose.material3.Text
|
import androidx.compose.material3.Text
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import network.loki.messenger.BuildConfig
|
import network.loki.messenger.BuildConfig
|
||||||
|
import network.loki.messenger.R
|
||||||
|
import org.thoughtcrime.securesms.debugmenu.DebugMenuViewModel.Commands.ChangeEnvironment
|
||||||
|
import org.thoughtcrime.securesms.debugmenu.DebugMenuViewModel.Commands.HideEnvironmentWarningDialog
|
||||||
|
import org.thoughtcrime.securesms.debugmenu.DebugMenuViewModel.Commands.ShowEnvironmentWarningDialog
|
||||||
|
import org.thoughtcrime.securesms.ui.AlertDialog
|
||||||
import org.thoughtcrime.securesms.ui.Cell
|
import org.thoughtcrime.securesms.ui.Cell
|
||||||
import org.thoughtcrime.securesms.ui.components.AppBarCloseIcon
|
import org.thoughtcrime.securesms.ui.DialogButtonModel
|
||||||
import org.thoughtcrime.securesms.ui.components.AppBarText
|
import org.thoughtcrime.securesms.ui.GetString
|
||||||
|
import org.thoughtcrime.securesms.ui.LoadingDialog
|
||||||
import org.thoughtcrime.securesms.ui.components.BackAppBar
|
import org.thoughtcrime.securesms.ui.components.BackAppBar
|
||||||
import org.thoughtcrime.securesms.ui.components.DropDown
|
import org.thoughtcrime.securesms.ui.components.DropDown
|
||||||
import org.thoughtcrime.securesms.ui.components.appBarColors
|
|
||||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||||
@ -42,37 +46,84 @@ fun DebugMenu(
|
|||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
onClose: () -> Unit
|
onClose: () -> Unit
|
||||||
){
|
){
|
||||||
Column(
|
val snackbarHostState = remember { SnackbarHostState() }
|
||||||
modifier = modifier
|
|
||||||
.fillMaxSize()
|
Scaffold(
|
||||||
.background(color = LocalColors.current.background)
|
modifier = modifier.fillMaxSize(),
|
||||||
) {
|
snackbarHost = {
|
||||||
// App bar
|
SnackbarHost(hostState = snackbarHostState)
|
||||||
BackAppBar(title = "Debug Menu", onBack = onClose)
|
}
|
||||||
|
) { contentPadding ->
|
||||||
|
// display a snackbar when required
|
||||||
|
LaunchedEffect(uiState.snackMessage) {
|
||||||
|
if(!uiState.snackMessage.isNullOrEmpty()){
|
||||||
|
snackbarHostState.showSnackbar(uiState.snackMessage)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Alert dialogs
|
||||||
|
if (uiState.showEnvironmentWarningDialog) {
|
||||||
|
AlertDialog(
|
||||||
|
onDismissRequest = { sendCommand(HideEnvironmentWarningDialog) },
|
||||||
|
title = "Are you sure you want to switch environments?",
|
||||||
|
text = "Changing this setting will result in all conversations and Snode data being cleared...",
|
||||||
|
showCloseButton = false, // display the 'x' button
|
||||||
|
buttons = listOf(
|
||||||
|
DialogButtonModel(
|
||||||
|
text = GetString(R.string.cancel),
|
||||||
|
contentDescription = GetString(R.string.cancel),
|
||||||
|
onClick = { sendCommand(HideEnvironmentWarningDialog) }
|
||||||
|
),
|
||||||
|
DialogButtonModel(
|
||||||
|
text = GetString(R.string.ok),
|
||||||
|
contentDescription = GetString(R.string.ok),
|
||||||
|
onClick = { sendCommand(ChangeEnvironment) }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uiState.showEnvironmentLoadingDialog) {
|
||||||
|
LoadingDialog(title = "Changing Environment...")
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(horizontal = LocalDimensions.current.spacing)
|
.padding(contentPadding)
|
||||||
.verticalScroll(rememberScrollState())
|
.fillMaxSize()
|
||||||
|
.background(color = LocalColors.current.background)
|
||||||
) {
|
) {
|
||||||
// Info pane
|
// App bar
|
||||||
DebugCell("App Info"){
|
BackAppBar(title = "Debug Menu", onBack = onClose)
|
||||||
Text(
|
|
||||||
text = "Version: ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE} - ${BuildConfig.GIT_HASH.take(6)})",
|
|
||||||
style = LocalType.current.base
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Environment
|
Column(
|
||||||
DebugCell("Environment"){
|
modifier = Modifier
|
||||||
DropDown(
|
.padding(horizontal = LocalDimensions.current.spacing)
|
||||||
modifier = Modifier.fillMaxWidth(0.6f),
|
.verticalScroll(rememberScrollState())
|
||||||
selectedText = uiState.currentEnvironment,
|
) {
|
||||||
values = uiState.environments,
|
// Info pane
|
||||||
onValueSelected = {
|
DebugCell("App Info") {
|
||||||
sendCommand(DebugMenuViewModel.Commands.ChangeEnvironment(it))
|
Text(
|
||||||
}
|
text = "Version: ${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE} - ${
|
||||||
)
|
BuildConfig.GIT_HASH.take(
|
||||||
|
6
|
||||||
|
)
|
||||||
|
})",
|
||||||
|
style = LocalType.current.base
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Environment
|
||||||
|
DebugCell("Environment") {
|
||||||
|
DropDown(
|
||||||
|
modifier = Modifier.fillMaxWidth(0.6f),
|
||||||
|
selectedText = uiState.currentEnvironment,
|
||||||
|
values = uiState.environments,
|
||||||
|
onValueSelected = {
|
||||||
|
sendCommand(ShowEnvironmentWarningDialog(it))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +160,10 @@ fun PreviewDebugMenu(){
|
|||||||
DebugMenu(
|
DebugMenu(
|
||||||
uiState = DebugMenuViewModel.UIState(
|
uiState = DebugMenuViewModel.UIState(
|
||||||
currentEnvironment = "Development",
|
currentEnvironment = "Development",
|
||||||
environments = listOf("Development", "Production")
|
environments = listOf("Development", "Production"),
|
||||||
|
snackMessage = null,
|
||||||
|
showEnvironmentWarningDialog = false,
|
||||||
|
showEnvironmentLoadingDialog = false
|
||||||
),
|
),
|
||||||
sendCommand = {},
|
sendCommand = {},
|
||||||
onClose = {}
|
onClose = {}
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
package org.thoughtcrime.securesms.debugmenu
|
package org.thoughtcrime.securesms.debugmenu
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.Dispatchers.Main
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import network.loki.messenger.R
|
||||||
import org.session.libsession.messaging.open_groups.OpenGroupApi
|
import org.session.libsession.messaging.open_groups.OpenGroupApi
|
||||||
import org.session.libsession.snode.SnodeAPI
|
import org.session.libsession.snode.SnodeAPI
|
||||||
import org.session.libsession.utilities.TextSecurePreferences
|
import org.session.libsession.utilities.TextSecurePreferences
|
||||||
@ -14,6 +19,7 @@ import org.session.libsignal.utilities.Log
|
|||||||
import org.thoughtcrime.securesms.ApplicationContext
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.session.libsession.utilities.Environment
|
import org.session.libsession.utilities.Environment
|
||||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||||
|
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@ -26,59 +32,84 @@ class DebugMenuViewModel @Inject constructor(
|
|||||||
private val _uiState = MutableStateFlow(
|
private val _uiState = MutableStateFlow(
|
||||||
UIState(
|
UIState(
|
||||||
currentEnvironment = textSecurePreferences.getEnvironment().label,
|
currentEnvironment = textSecurePreferences.getEnvironment().label,
|
||||||
environments = Environment.entries.map { it.label }
|
environments = Environment.entries.map { it.label },
|
||||||
|
snackMessage = null,
|
||||||
|
showEnvironmentWarningDialog = false,
|
||||||
|
showEnvironmentLoadingDialog = false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
val uiState: StateFlow<UIState>
|
val uiState: StateFlow<UIState>
|
||||||
get() = _uiState
|
get() = _uiState
|
||||||
|
|
||||||
|
private var temporaryEnv: Environment? = null
|
||||||
|
|
||||||
fun onCommand(command: Commands) {
|
fun onCommand(command: Commands) {
|
||||||
when (command) {
|
when (command) {
|
||||||
is Commands.ChangeEnvironment -> changeEnvironment(command.environment)
|
is Commands.ChangeEnvironment -> changeEnvironment()
|
||||||
|
|
||||||
|
is Commands.HideEnvironmentWarningDialog -> _uiState.value =
|
||||||
|
_uiState.value.copy(showEnvironmentWarningDialog = false)
|
||||||
|
|
||||||
|
is Commands.ShowEnvironmentWarningDialog ->
|
||||||
|
showEnvironmentWarningDialog(command.environment)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun changeEnvironment(environment: String) {
|
private fun showEnvironmentWarningDialog(environment: String) {
|
||||||
if(environment == _uiState.value.currentEnvironment) return
|
if(environment == _uiState.value.currentEnvironment) return
|
||||||
val env = Environment.entries.firstOrNull { it.label == environment } ?: return
|
val env = Environment.entries.firstOrNull { it.label == environment } ?: return
|
||||||
|
|
||||||
|
temporaryEnv = env
|
||||||
|
|
||||||
|
_uiState.value = _uiState.value.copy(showEnvironmentWarningDialog = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun changeEnvironment() {
|
||||||
|
val env = temporaryEnv ?: return
|
||||||
|
|
||||||
// show a loading state
|
// show a loading state
|
||||||
|
_uiState.value = _uiState.value.copy(
|
||||||
|
showEnvironmentWarningDialog = false,
|
||||||
|
showEnvironmentLoadingDialog = true
|
||||||
|
)
|
||||||
|
|
||||||
// clear remote and local data, then restart the app
|
// clear remote and local data, then restart the app
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val deletionResultMap: Map<String, Boolean>? = try {
|
try {
|
||||||
val openGroups =
|
ConfigurationMessageUtilities.forceSyncConfigurationNowIfNeeded(application).get()
|
||||||
DatabaseComponent.get(application).lokiThreadDatabase().getAllOpenGroups()
|
|
||||||
openGroups.map { it.value.server }.toSet().forEach { server ->
|
|
||||||
OpenGroupApi.deleteAllInboxMessages(server).get()
|
|
||||||
}
|
|
||||||
SnodeAPI.deleteAllMessages().get()
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(
|
// we can ignore fails here as we might be switching environments before the user gets a public key
|
||||||
TAG, "Failed to delete network message from debug menu", e
|
|
||||||
)
|
|
||||||
null
|
|
||||||
}
|
}
|
||||||
|
ApplicationContext.getInstance(application).clearAllData().let { success ->
|
||||||
// If the network data deletion was successful proceed to delete the local data as well.
|
if(success){
|
||||||
if (deletionResultMap?.values?.all { it } == true) {
|
// save the environment
|
||||||
// save the environment
|
textSecurePreferences.setEnvironment(env)
|
||||||
textSecurePreferences.setEnvironment(env)
|
delay(500)
|
||||||
|
ApplicationContext.getInstance(application).restartApplication()
|
||||||
// clear local data and restart
|
} else {
|
||||||
ApplicationContext.getInstance(application).clearAllData()
|
_uiState.value = _uiState.value.copy(
|
||||||
} else { // the remote deletion failed, show an error
|
showEnvironmentWarningDialog = false,
|
||||||
|
showEnvironmentLoadingDialog = false
|
||||||
|
)
|
||||||
|
Log.e(TAG, "Failed to force sync when deleting data")
|
||||||
|
_uiState.value = _uiState.value.copy(snackMessage = "Sorry, something went wrong...")
|
||||||
|
return@launch
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class UIState(
|
data class UIState(
|
||||||
val currentEnvironment: String,
|
val currentEnvironment: String,
|
||||||
val environments: List<String>
|
val environments: List<String>,
|
||||||
|
val snackMessage: String?,
|
||||||
|
val showEnvironmentWarningDialog: Boolean,
|
||||||
|
val showEnvironmentLoadingDialog: Boolean
|
||||||
)
|
)
|
||||||
|
|
||||||
sealed class Commands {
|
sealed class Commands {
|
||||||
data class ChangeEnvironment(val environment: String) : Commands()
|
object ChangeEnvironment : Commands()
|
||||||
|
data class ShowEnvironmentWarningDialog(val environment: String) : Commands()
|
||||||
|
object HideEnvironmentWarningDialog : Commands()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -45,7 +45,7 @@ internal fun MessageNotificationsScreen(
|
|||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
contentAlignment = Alignment.Center
|
contentAlignment = Alignment.Center
|
||||||
) {
|
) {
|
||||||
CircularProgressIndicator(LocalColors.current.primary)
|
CircularProgressIndicator(color = LocalColors.current.primary)
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -72,7 +72,7 @@ internal class MessageNotificationsViewModel(
|
|||||||
_uiStates.update { it.copy(clearData = true) }
|
_uiStates.update { it.copy(clearData = true) }
|
||||||
|
|
||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
ApplicationContext.getInstance(application).clearAllData()
|
ApplicationContext.getInstance(application).clearAllDataAndRestart()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ class ClearAllDataDialog : DialogFragment() {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ApplicationContext.getInstance(context).clearAllData().let { success ->
|
ApplicationContext.getInstance(context).clearAllDataAndRestart().let { success ->
|
||||||
withContext(Main) {
|
withContext(Main) {
|
||||||
if (success) {
|
if (success) {
|
||||||
dismiss()
|
dismiss()
|
||||||
@ -162,7 +162,7 @@ class ClearAllDataDialog : DialogFragment() {
|
|||||||
}
|
}
|
||||||
else if (deletionResultMap.values.all { it }) {
|
else if (deletionResultMap.values.all { it }) {
|
||||||
// ..otherwise if the network data deletion was successful proceed to delete the local data as well.
|
// ..otherwise if the network data deletion was successful proceed to delete the local data as well.
|
||||||
ApplicationContext.getInstance(context).clearAllData()
|
ApplicationContext.getInstance(context).clearAllDataAndRestart()
|
||||||
withContext(Main) { dismiss() }
|
withContext(Main) { dismiss() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,8 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
|||||||
btnGroupNameDisplay.text = getDisplayName()
|
btnGroupNameDisplay.text = getDisplayName()
|
||||||
publicKeyTextView.text = hexEncodedPublicKey
|
publicKeyTextView.text = hexEncodedPublicKey
|
||||||
val gitCommitFirstSixChars = BuildConfig.GIT_HASH.take(6)
|
val gitCommitFirstSixChars = BuildConfig.GIT_HASH.take(6)
|
||||||
versionTextView.text = String.format(getString(R.string.version_s), "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE} - $gitCommitFirstSixChars)")
|
val environment: String = if(BuildConfig.BUILD_TYPE == "release") "" else " - ${prefs.getEnvironment().label}"
|
||||||
|
versionTextView.text = String.format(getString(R.string.version_s), "${BuildConfig.VERSION_NAME} (${BuildConfig.VERSION_CODE} - $gitCommitFirstSixChars) $environment")
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.composeView.setThemedContent {
|
binding.composeView.setThemedContent {
|
||||||
|
@ -3,13 +3,16 @@ package org.thoughtcrime.securesms.ui
|
|||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.BoxScope
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.IntrinsicSize
|
import androidx.compose.foundation.layout.IntrinsicSize
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.fillMaxHeight
|
import androidx.compose.foundation.layout.fillMaxHeight
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.layout.width
|
||||||
import androidx.compose.material3.BasicAlertDialog
|
import androidx.compose.material3.BasicAlertDialog
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
@ -29,6 +32,7 @@ import androidx.compose.ui.text.style.TextAlign
|
|||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
|
import org.thoughtcrime.securesms.ui.components.CircularProgressIndicator
|
||||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||||
@ -48,6 +52,7 @@ class DialogButtonModel(
|
|||||||
@Composable
|
@Composable
|
||||||
fun AlertDialog(
|
fun AlertDialog(
|
||||||
onDismissRequest: () -> Unit,
|
onDismissRequest: () -> Unit,
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
title: String? = null,
|
title: String? = null,
|
||||||
text: String? = null,
|
text: String? = null,
|
||||||
buttons: List<DialogButtonModel>? = null,
|
buttons: List<DialogButtonModel>? = null,
|
||||||
@ -55,18 +60,10 @@ fun AlertDialog(
|
|||||||
content: @Composable () -> Unit = {}
|
content: @Composable () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
BasicAlertDialog(
|
BasicAlertDialog(
|
||||||
|
modifier = modifier,
|
||||||
onDismissRequest = onDismissRequest,
|
onDismissRequest = onDismissRequest,
|
||||||
content = {
|
content = {
|
||||||
Box(
|
DialogBg {
|
||||||
modifier = Modifier.background(
|
|
||||||
color = LocalColors.current.backgroundSecondary,
|
|
||||||
shape = MaterialTheme.shapes.small)
|
|
||||||
.border(
|
|
||||||
width = 1.dp,
|
|
||||||
color = LocalColors.current.borders,
|
|
||||||
shape = MaterialTheme.shapes.small)
|
|
||||||
|
|
||||||
) {
|
|
||||||
// only show the 'x' button is required
|
// only show the 'x' button is required
|
||||||
if (showCloseButton) {
|
if (showCloseButton) {
|
||||||
IconButton(
|
IconButton(
|
||||||
@ -133,7 +130,7 @@ fun AlertDialog(
|
|||||||
@Composable
|
@Composable
|
||||||
fun DialogButton(
|
fun DialogButton(
|
||||||
text: String,
|
text: String,
|
||||||
modifier: Modifier,
|
modifier: Modifier = Modifier,
|
||||||
color: Color = Color.Unspecified,
|
color: Color = Color.Unspecified,
|
||||||
onClick: () -> Unit
|
onClick: () -> Unit
|
||||||
) {
|
) {
|
||||||
@ -154,6 +151,62 @@ fun DialogButton(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun DialogBg(
|
||||||
|
content: @Composable BoxScope.() -> Unit
|
||||||
|
){
|
||||||
|
Box(
|
||||||
|
modifier = Modifier
|
||||||
|
.background(
|
||||||
|
color = LocalColors.current.backgroundSecondary,
|
||||||
|
shape = MaterialTheme.shapes.small
|
||||||
|
)
|
||||||
|
.border(
|
||||||
|
width = 1.dp,
|
||||||
|
color = LocalColors.current.borders,
|
||||||
|
shape = MaterialTheme.shapes.small
|
||||||
|
)
|
||||||
|
|
||||||
|
) {
|
||||||
|
content()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
|
@Composable
|
||||||
|
fun LoadingDialog(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
title: String? = null,
|
||||||
|
){
|
||||||
|
BasicAlertDialog(
|
||||||
|
modifier = modifier,
|
||||||
|
onDismissRequest = {},
|
||||||
|
content = {
|
||||||
|
DialogBg {
|
||||||
|
Column(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(LocalDimensions.current.spacing)
|
||||||
|
) {
|
||||||
|
CircularProgressIndicator(
|
||||||
|
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||||
|
)
|
||||||
|
|
||||||
|
Spacer(modifier = Modifier.height(LocalDimensions.current.spacing))
|
||||||
|
|
||||||
|
title?.let {
|
||||||
|
Text(
|
||||||
|
it,
|
||||||
|
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||||
|
style = LocalType.current.large
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Preview
|
@Preview
|
||||||
@Composable
|
@Composable
|
||||||
fun PreviewSimpleDialog() {
|
fun PreviewSimpleDialog() {
|
||||||
@ -200,3 +253,13 @@ fun PreviewXCloseDialog() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
fun PreviewLoadingDialog() {
|
||||||
|
PreviewTheme {
|
||||||
|
LoadingDialog(
|
||||||
|
title = stringResource(R.string.warning)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -8,18 +8,24 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun CircularProgressIndicator(color: Color = LocalContentColor.current) {
|
fun CircularProgressIndicator(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
color: Color = LocalContentColor.current
|
||||||
|
) {
|
||||||
androidx.compose.material3.CircularProgressIndicator(
|
androidx.compose.material3.CircularProgressIndicator(
|
||||||
modifier = Modifier.size(40.dp),
|
modifier = modifier.size(40.dp),
|
||||||
color = color,
|
color = color,
|
||||||
strokeWidth = 2.dp
|
strokeWidth = 2.dp
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SmallCircularProgressIndicator(color: Color = LocalContentColor.current) {
|
fun SmallCircularProgressIndicator(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
color: Color = LocalContentColor.current
|
||||||
|
) {
|
||||||
androidx.compose.material3.CircularProgressIndicator(
|
androidx.compose.material3.CircularProgressIndicator(
|
||||||
modifier = Modifier.size(20.dp),
|
modifier = modifier.size(20.dp),
|
||||||
color = color,
|
color = color,
|
||||||
strokeWidth = 2.dp
|
strokeWidth = 2.dp
|
||||||
)
|
)
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
package org.session.libsession.snode
|
package org.session.libsession.snode
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import com.goterl.lazysodium.exceptions.SodiumException
|
import com.goterl.lazysodium.exceptions.SodiumException
|
||||||
import com.goterl.lazysodium.interfaces.GenericHash
|
import com.goterl.lazysodium.interfaces.GenericHash
|
||||||
import com.goterl.lazysodium.interfaces.PwHash
|
import com.goterl.lazysodium.interfaces.PwHash
|
||||||
@ -76,9 +75,7 @@ object SnodeAPI {
|
|||||||
// Use port 4433 to enforce pinned certificates
|
// Use port 4433 to enforce pinned certificates
|
||||||
private val seedNodePort = 4443
|
private val seedNodePort = 4443
|
||||||
|
|
||||||
private const val useTestnet = false
|
private val seedNodePool = if (SnodeModule.shared.useTestNet) setOf(
|
||||||
|
|
||||||
private val seedNodePool = if (useTestnet) setOf(
|
|
||||||
"http://public.loki.foundation:38157"
|
"http://public.loki.foundation:38157"
|
||||||
) else setOf(
|
) else setOf(
|
||||||
"https://seed1.getsession.org:$seedNodePort",
|
"https://seed1.getsession.org:$seedNodePort",
|
||||||
|
@ -3,16 +3,18 @@ package org.session.libsession.snode
|
|||||||
import org.session.libsignal.database.LokiAPIDatabaseProtocol
|
import org.session.libsignal.database.LokiAPIDatabaseProtocol
|
||||||
import org.session.libsignal.utilities.Broadcaster
|
import org.session.libsignal.utilities.Broadcaster
|
||||||
|
|
||||||
class SnodeModule(val storage: LokiAPIDatabaseProtocol, val broadcaster: Broadcaster) {
|
class SnodeModule(
|
||||||
|
val storage: LokiAPIDatabaseProtocol, val broadcaster: Broadcaster, val useTestNet: Boolean
|
||||||
|
) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
lateinit var shared: SnodeModule
|
lateinit var shared: SnodeModule
|
||||||
|
|
||||||
val isInitialized: Boolean get() = Companion::shared.isInitialized
|
val isInitialized: Boolean get() = Companion::shared.isInitialized
|
||||||
|
|
||||||
fun configure(storage: LokiAPIDatabaseProtocol, broadcaster: Broadcaster) {
|
fun configure(storage: LokiAPIDatabaseProtocol, broadcaster: Broadcaster, useTestNet: Boolean) {
|
||||||
if (isInitialized) { return }
|
if (isInitialized) { return }
|
||||||
shared = SnodeModule(storage, broadcaster)
|
shared = SnodeModule(storage, broadcaster, useTestNet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user