mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-11 23:23:39 +00:00
Handle backpresses in onboarding
This commit is contained in:
parent
d621036af6
commit
9cf3a37a2b
@ -18,6 +18,7 @@ package org.thoughtcrime.securesms;
|
||||
import static nl.komponents.kovenant.android.KovenantAndroid.startKovenant;
|
||||
import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@ -137,7 +138,6 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
|
||||
public MessageNotifier messageNotifier = null;
|
||||
public Poller poller = null;
|
||||
public Broadcaster broadcaster = null;
|
||||
private Job firebaseInstanceIdJob;
|
||||
private WindowDebouncer conversationListDebouncer;
|
||||
private HandlerThread conversationListHandlerThread;
|
||||
private Handler conversationListHandler;
|
||||
@ -504,17 +504,9 @@ public class ApplicationContext extends Application implements DefaultLifecycleO
|
||||
});
|
||||
}
|
||||
|
||||
public void clearAllData(boolean isMigratingToV2KeyPair) {
|
||||
if (firebaseInstanceIdJob != null && firebaseInstanceIdJob.isActive()) {
|
||||
firebaseInstanceIdJob.cancel(null);
|
||||
}
|
||||
String displayName = TextSecurePreferences.getProfileName(this);
|
||||
boolean isUsingFCM = TextSecurePreferences.isPushEnabled(this);
|
||||
@SuppressLint("ApplySharedPref")
|
||||
public void clearAllData() {
|
||||
TextSecurePreferences.clearAll(this);
|
||||
if (isMigratingToV2KeyPair) {
|
||||
TextSecurePreferences.setPushEnabled(this, isUsingFCM);
|
||||
TextSecurePreferences.setProfileName(this, displayName);
|
||||
}
|
||||
getSharedPreferences(PREFERENCES_NAME, 0).edit().clear().commit();
|
||||
if (!deleteDatabase(SQLCipherOpenHelper.DATABASE_NAME)) {
|
||||
Log.d("Loki", "Failed to delete database.");
|
||||
|
@ -82,13 +82,13 @@ internal fun LandingScreen(
|
||||
text = stringResource(R.string.urlOpenBrowser),
|
||||
buttons = listOf(
|
||||
DialogButtonModel(
|
||||
GetString(R.string.activity_landing_terms_of_service),
|
||||
GetString(R.string.AccessibilityId_terms_of_service_button),
|
||||
text = GetString(R.string.activity_landing_terms_of_service),
|
||||
contentDescription = GetString(R.string.AccessibilityId_terms_of_service_button),
|
||||
onClick = openTerms
|
||||
),
|
||||
DialogButtonModel(
|
||||
GetString(R.string.activity_landing_privacy_policy),
|
||||
GetString(R.string.AccessibilityId_privacy_policy_button),
|
||||
text = GetString(R.string.activity_landing_privacy_policy),
|
||||
contentDescription = GetString(R.string.AccessibilityId_privacy_policy_button),
|
||||
onClick = openPrivacyPolicy
|
||||
)
|
||||
)
|
||||
|
@ -32,10 +32,7 @@ class LandingActivity: BaseActionBarActivity() {
|
||||
|
||||
setComposeContent {
|
||||
LandingScreen(
|
||||
createAccount = {
|
||||
prefs.setHasViewedSeed(false)
|
||||
startPickDisplayNameActivity()
|
||||
},
|
||||
createAccount = { startPickDisplayNameActivity() },
|
||||
loadAccount = { start<LoadAccountActivity>() },
|
||||
openTerms = { open("https://getsession.org/terms-of-service") },
|
||||
openPrivacyPolicy = { open("https://getsession.org/privacy-policy") }
|
||||
|
@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.onboarding.loadaccount
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import androidx.camera.core.ExperimentalGetImage
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
@ -11,14 +10,13 @@ import kotlinx.coroutines.launch
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||
import org.thoughtcrime.securesms.onboarding.loading.LoadingManager
|
||||
import org.thoughtcrime.securesms.onboarding.manager.LoadingManager
|
||||
import org.thoughtcrime.securesms.onboarding.messagenotifications.MessageNotificationsActivity
|
||||
import org.thoughtcrime.securesms.ui.setComposeContent
|
||||
import org.thoughtcrime.securesms.util.start
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@androidx.annotation.OptIn(ExperimentalGetImage::class)
|
||||
class LoadAccountActivity : BaseActionBarActivity() {
|
||||
|
||||
@Inject
|
||||
@ -31,7 +29,6 @@ class LoadAccountActivity : BaseActionBarActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
supportActionBar?.setTitle(R.string.activity_link_load_account)
|
||||
prefs.setHasViewedSeed(true)
|
||||
prefs.setConfigurationMessageSynced(false)
|
||||
prefs.setRestorationTime(System.currentTimeMillis())
|
||||
prefs.setLastProfileUpdateTime(0)
|
||||
|
@ -28,11 +28,6 @@ class LoadingActivity: BaseActionBarActivity() {
|
||||
|
||||
private val viewModel: LoadingViewModel by viewModels()
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onBackPressed() {
|
||||
return
|
||||
}
|
||||
|
||||
private fun register(loadFailed: Boolean) {
|
||||
prefs.setLastConfigurationSyncTime(System.currentTimeMillis())
|
||||
|
||||
@ -47,6 +42,8 @@ class LoadingActivity: BaseActionBarActivity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setUpActionBarSessionLogo()
|
||||
|
||||
ApplicationContext.getInstance(this).newAccount = false
|
||||
|
||||
setComposeContent {
|
||||
@ -54,8 +51,6 @@ class LoadingActivity: BaseActionBarActivity() {
|
||||
LoadingScreen(state)
|
||||
}
|
||||
|
||||
setUpActionBarSessionLogo(true)
|
||||
|
||||
lifecycleScope.launch {
|
||||
viewModel.events.collect {
|
||||
when (it) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package org.thoughtcrime.securesms.onboarding.loading
|
||||
package org.thoughtcrime.securesms.onboarding.manager
|
||||
|
||||
import android.content.Context
|
||||
import kotlinx.coroutines.CoroutineScope
|
@ -31,7 +31,11 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.onboarding.messagenotifications.MessageNotificationsViewModel.UiState
|
||||
import org.thoughtcrime.securesms.onboarding.ui.ContinuePrimaryOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.AlertDialog
|
||||
import org.thoughtcrime.securesms.ui.DialogButtonModel
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
@ -39,6 +43,7 @@ import org.thoughtcrime.securesms.ui.base
|
||||
import org.thoughtcrime.securesms.ui.color.Colors
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.color.transparentButtonColors
|
||||
import org.thoughtcrime.securesms.ui.components.CircularProgressIndicator
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.h4
|
||||
import org.thoughtcrime.securesms.ui.h8
|
||||
@ -47,10 +52,39 @@ import org.thoughtcrime.securesms.ui.small
|
||||
|
||||
@Composable
|
||||
internal fun MessageNotificationsScreen(
|
||||
state: MessageNotificationsState = MessageNotificationsState(),
|
||||
state: UiState = UiState(),
|
||||
setEnabled: (Boolean) -> Unit = {},
|
||||
onContinue: () -> Unit = {}
|
||||
onContinue: () -> Unit = {},
|
||||
quit: () -> Unit = {},
|
||||
dismissDialog: () -> Unit = {}
|
||||
) {
|
||||
if (state.clearData) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
CircularProgressIndicator(LocalColors.current.primary)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (state.showDialog) AlertDialog(
|
||||
onDismissRequest = dismissDialog,
|
||||
title = stringResource(R.string.warning),
|
||||
text = stringResource(R.string.you_cannot_go_back_further_in_order_to_stop_loading_your_account_session_needs_to_quit),
|
||||
buttons = listOf(
|
||||
DialogButtonModel(
|
||||
GetString(stringResource(R.string.quit)),
|
||||
color = LocalColors.current.danger,
|
||||
onClick = quit
|
||||
),
|
||||
DialogButtonModel(
|
||||
GetString(stringResource(R.string.cancel))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
Column {
|
||||
Spacer(Modifier.weight(1f))
|
||||
|
||||
@ -105,9 +139,15 @@ private fun NotificationRadioButton(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.border(LocalDimensions.current.borderStroke, LocalColors.current.borders, RoundedCornerShape(8.dp)),
|
||||
.border(
|
||||
LocalDimensions.current.borderStroke,
|
||||
LocalColors.current.borders,
|
||||
RoundedCornerShape(8.dp)
|
||||
),
|
||||
) {
|
||||
Column(modifier = Modifier.padding(horizontal = 15.dp).padding(top = 10.dp, bottom = 11.dp)) {
|
||||
Column(modifier = Modifier
|
||||
.padding(horizontal = 15.dp)
|
||||
.padding(top = 10.dp, bottom = 11.dp)) {
|
||||
Text(stringResource(title), style = h8)
|
||||
|
||||
Text(stringResource(explanation), style = small, modifier = Modifier.padding(top = 7.dp))
|
||||
@ -139,7 +179,9 @@ private fun RadioButtonIndicator(
|
||||
Box(modifier = modifier) {
|
||||
AnimatedVisibility(
|
||||
selected,
|
||||
modifier = Modifier.padding(2.5.dp).clip(CircleShape),
|
||||
modifier = Modifier
|
||||
.padding(2.5.dp)
|
||||
.clip(CircleShape),
|
||||
enter = scaleIn(),
|
||||
exit = scaleOut()
|
||||
) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.thoughtcrime.securesms.onboarding.messagenotifications
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import androidx.compose.runtime.Composable
|
||||
@ -12,7 +13,8 @@ import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||
import org.thoughtcrime.securesms.home.startHomeActivity
|
||||
import org.thoughtcrime.securesms.notifications.PushRegistry
|
||||
import org.thoughtcrime.securesms.onboarding.loading.LoadingActivity
|
||||
import org.thoughtcrime.securesms.onboarding.loading.LoadingManager
|
||||
import org.thoughtcrime.securesms.onboarding.manager.LoadingManager
|
||||
import org.thoughtcrime.securesms.onboarding.messagenotifications.MessageNotificationsActivity.Companion.EXTRA_PROFILE_NAME
|
||||
import org.thoughtcrime.securesms.ui.setComposeContent
|
||||
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo
|
||||
import org.thoughtcrime.securesms.util.start
|
||||
@ -21,11 +23,22 @@ import javax.inject.Inject
|
||||
@AndroidEntryPoint
|
||||
class MessageNotificationsActivity : BaseActionBarActivity() {
|
||||
|
||||
companion object {
|
||||
const val EXTRA_PROFILE_NAME = "EXTRA_PROFILE_NAME"
|
||||
}
|
||||
|
||||
@Inject
|
||||
internal lateinit var viewModelFactory: MessageNotificationsViewModel.AssistedFactory
|
||||
|
||||
@Inject lateinit var pushRegistry: PushRegistry
|
||||
@Inject lateinit var prefs: TextSecurePreferences
|
||||
@Inject lateinit var loadingManager: LoadingManager
|
||||
|
||||
private val viewModel: MessageNotificationsViewModel by viewModels()
|
||||
val profileName by lazy { intent.getStringExtra(EXTRA_PROFILE_NAME) }
|
||||
|
||||
private val viewModel: MessageNotificationsViewModel by viewModels {
|
||||
viewModelFactory.create(profileName)
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@ -35,14 +48,28 @@ class MessageNotificationsActivity : BaseActionBarActivity() {
|
||||
setComposeContent { MessageNotificationsScreen() }
|
||||
}
|
||||
|
||||
@Deprecated("Deprecated in Java")
|
||||
override fun onBackPressed() {
|
||||
if (viewModel.onBackPressed()) return
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
super.onBackPressed()
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun MessageNotificationsScreen() {
|
||||
val state by viewModel.states.collectAsState()
|
||||
MessageNotificationsScreen(state, viewModel::setEnabled, ::register)
|
||||
val uiState by viewModel.uiStates.collectAsState()
|
||||
MessageNotificationsScreen(
|
||||
uiState,
|
||||
setEnabled = viewModel::setEnabled,
|
||||
onContinue = ::register,
|
||||
quit = viewModel::quit,
|
||||
dismissDialog = viewModel::dismissDialog
|
||||
)
|
||||
}
|
||||
|
||||
private fun register() {
|
||||
prefs.setPushEnabled(viewModel.states.value.pushEnabled)
|
||||
prefs.setPushEnabled(viewModel.uiStates.value.pushEnabled)
|
||||
ApplicationContext.getInstance(this).startPollingIfNeeded()
|
||||
pushRegistry.refresh(true)
|
||||
|
||||
@ -52,3 +79,7 @@ class MessageNotificationsActivity : BaseActionBarActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun Activity.startMessageNotificationsActivity(profileName: String) {
|
||||
start<MessageNotificationsActivity> { putExtra(EXTRA_PROFILE_NAME, profileName) }
|
||||
}
|
||||
|
@ -1,22 +1,83 @@
|
||||
package org.thoughtcrime.securesms.onboarding.messagenotifications
|
||||
|
||||
import android.app.Application
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.ViewModel
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.launch
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
|
||||
@HiltViewModel
|
||||
internal class MessageNotificationsViewModel @Inject constructor(): ViewModel() {
|
||||
private val _states = MutableStateFlow(MessageNotificationsState())
|
||||
val states = _states.asStateFlow()
|
||||
internal class MessageNotificationsViewModel(
|
||||
private val state: State,
|
||||
private val application: Application
|
||||
): AndroidViewModel(application) {
|
||||
private val _uiStates = MutableStateFlow(UiState())
|
||||
val uiStates = _uiStates.asStateFlow()
|
||||
|
||||
fun setEnabled(enabled: Boolean) {
|
||||
_states.update { MessageNotificationsState(pushEnabled = enabled) }
|
||||
_uiStates.update { UiState(pushEnabled = enabled) }
|
||||
}
|
||||
|
||||
/**
|
||||
* @return [true] if the back press was handled.
|
||||
*/
|
||||
fun onBackPressed(): Boolean = when (state) {
|
||||
is State.CreateAccount -> false
|
||||
is State.LoadAccount -> {
|
||||
_uiStates.update { it.copy(showDialog = true) }
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
fun dismissDialog() {
|
||||
_uiStates.update { it.copy(showDialog = false) }
|
||||
}
|
||||
|
||||
fun quit() {
|
||||
_uiStates.update { it.copy(clearData = true) }
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
ApplicationContext.getInstance(application).clearAllData()
|
||||
}
|
||||
}
|
||||
|
||||
data class UiState(
|
||||
val pushEnabled: Boolean = true,
|
||||
val showDialog: Boolean = false,
|
||||
val clearData: Boolean = false
|
||||
) {
|
||||
val pushDisabled get() = !pushEnabled
|
||||
}
|
||||
|
||||
sealed interface State {
|
||||
class CreateAccount(val displayName: String): State
|
||||
object LoadAccount: State
|
||||
}
|
||||
|
||||
@dagger.assisted.AssistedFactory
|
||||
interface AssistedFactory {
|
||||
fun create(profileName: String?): Factory
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
class Factory @AssistedInject constructor(
|
||||
@Assisted private val profileName: String?,
|
||||
private val application: Application
|
||||
) : ViewModelProvider.Factory {
|
||||
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return MessageNotificationsViewModel(
|
||||
state = profileName?.let(State::CreateAccount) ?: State.LoadAccount,
|
||||
application = application
|
||||
) as T
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class MessageNotificationsState(val pushEnabled: Boolean = true) {
|
||||
val pushDisabled get() = !pushEnabled
|
||||
}
|
||||
|
@ -13,10 +13,9 @@ import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||
import org.thoughtcrime.securesms.home.startHomeActivity
|
||||
import org.thoughtcrime.securesms.onboarding.messagenotifications.MessageNotificationsActivity
|
||||
import org.thoughtcrime.securesms.onboarding.messagenotifications.startMessageNotificationsActivity
|
||||
import org.thoughtcrime.securesms.ui.setComposeContent
|
||||
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo
|
||||
import org.thoughtcrime.securesms.util.start
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val EXTRA_LOAD_FAILED = "extra_load_failed"
|
||||
@ -41,11 +40,12 @@ class PickDisplayNameActivity : BaseActionBarActivity() {
|
||||
|
||||
setComposeContent { DisplayNameScreen(viewModel) }
|
||||
|
||||
if (!loadFailed) prefs.setHasViewedSeed(false)
|
||||
|
||||
lifecycleScope.launch {
|
||||
viewModel.events.collect {
|
||||
if (loadFailed) startHomeActivity() else start<MessageNotificationsActivity>()
|
||||
when (it) {
|
||||
is Event.CreateAccount -> startMessageNotificationsActivity(it.profileName)
|
||||
Event.LoadAccountComplete -> startHomeActivity()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ internal class PickDisplayNameViewModel(
|
||||
_states.update { it.copy(isTextErrorColor = false, error = null) }
|
||||
|
||||
prefs.setProfileName(displayName)
|
||||
configFactory.user?.setName(displayName)
|
||||
|
||||
if (!loadFailed) {
|
||||
// This is here to resolve a case where the app restarts before a user completes onboarding
|
||||
@ -70,7 +71,13 @@ internal class PickDisplayNameViewModel(
|
||||
prefs.setRestorationTime(0)
|
||||
}
|
||||
|
||||
viewModelScope.launch { _events.emit(Event.DONE) }
|
||||
viewModelScope.launch {
|
||||
if (loadFailed) {
|
||||
_events.emit(Event.LoadAccountComplete)
|
||||
} else {
|
||||
_events.emit(Event.CreateAccount(displayName))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -116,5 +123,6 @@ fun pickNewNameState() = State(
|
||||
)
|
||||
|
||||
sealed interface Event {
|
||||
object DONE: Event
|
||||
class CreateAccount(val profileName: String): Event
|
||||
object LoadAccountComplete: Event
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ class ClearAllDataDialog : DialogFragment() {
|
||||
} catch (e: Exception) {
|
||||
Log.e("Loki", "Failed to force sync", e)
|
||||
}
|
||||
ApplicationContext.getInstance(context).clearAllData(false)
|
||||
ApplicationContext.getInstance(context).clearAllData()
|
||||
withContext(Dispatchers.Main) {
|
||||
dismiss()
|
||||
}
|
||||
@ -133,7 +133,7 @@ class ClearAllDataDialog : DialogFragment() {
|
||||
}
|
||||
} else if (result.values.all { it }) {
|
||||
// don't force sync because all the messages are deleted?
|
||||
ApplicationContext.getInstance(context).clearAllData(false)
|
||||
ApplicationContext.getInstance(context).clearAllData()
|
||||
withContext(Dispatchers.Main) {
|
||||
dismiss()
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Toast
|
||||
import androidx.compose.animation.Crossfade
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@ -25,14 +26,9 @@ import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
@ -44,11 +40,8 @@ import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.flow.startWith
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import network.loki.messenger.BuildConfig
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.ActivitySettingsBinding
|
||||
@ -420,7 +413,9 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
|
||||
Cell {
|
||||
Column {
|
||||
LargeItemButtonWithDrawable(R.string.activity_path_title, if (hasPaths) R.drawable.ic_status else R.drawable.ic_path_yellow) { show<PathActivity>() }
|
||||
Crossfade(if (hasPaths) R.drawable.ic_status else R.drawable.ic_path_yellow, label = "path") {
|
||||
LargeItemButtonWithDrawable(R.string.activity_path_title, it) { show<PathActivity>() }
|
||||
}
|
||||
Divider()
|
||||
LargeItemButton(R.string.activity_settings_privacy_button_title, R.drawable.ic_privacy_icon) { show<PrivacySettingsActivity>() }
|
||||
Divider()
|
||||
|
@ -16,7 +16,9 @@ import androidx.compose.material.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.graphics.takeOrElse
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import network.loki.messenger.R
|
||||
@ -25,7 +27,9 @@ import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
class DialogButtonModel(
|
||||
val text: GetString,
|
||||
val contentDescription: GetString = text,
|
||||
val onClick: () -> Unit
|
||||
val color: Color = Color.Unspecified,
|
||||
val dismissOnClick: Boolean = true,
|
||||
val onClick: () -> Unit = {},
|
||||
)
|
||||
|
||||
@Composable
|
||||
@ -33,6 +37,7 @@ fun AlertDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
title: String? = null,
|
||||
text: String? = null,
|
||||
content: @Composable () -> Unit = {},
|
||||
buttons: List<DialogButtonModel>? = null
|
||||
) {
|
||||
androidx.compose.material.AlertDialog(
|
||||
@ -76,6 +81,7 @@ fun AlertDialog(
|
||||
modifier = Modifier.padding(bottom = LocalDimensions.current.xxsItemSpacing)
|
||||
)
|
||||
}
|
||||
content()
|
||||
}
|
||||
buttons?.takeIf { it.isNotEmpty() }?.let {
|
||||
Row(Modifier.height(IntrinsicSize.Min)) {
|
||||
@ -85,10 +91,11 @@ fun AlertDialog(
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
.contentDescription(it.contentDescription())
|
||||
.weight(1f)
|
||||
.weight(1f),
|
||||
color = it.color
|
||||
) {
|
||||
it.onClick()
|
||||
onDismissRequest()
|
||||
if (it.dismissOnClick) onDismissRequest()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -100,7 +107,7 @@ fun AlertDialog(
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DialogButton(text: String, modifier: Modifier, onClick: () -> Unit) {
|
||||
fun DialogButton(text: String, modifier: Modifier, color: Color = Color.Unspecified, onClick: () -> Unit) {
|
||||
TextButton(
|
||||
modifier = modifier,
|
||||
shape = RectangleShape,
|
||||
@ -108,7 +115,7 @@ fun DialogButton(text: String, modifier: Modifier, onClick: () -> Unit) {
|
||||
) {
|
||||
Text(
|
||||
text,
|
||||
color = LocalColors.current.text,
|
||||
color = color.takeOrElse { LocalColors.current.text },
|
||||
style = largeBold,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.padding(
|
||||
|
@ -26,7 +26,6 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.material.ButtonColors
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.LocalContentColor
|
||||
import androidx.compose.material.MaterialTheme
|
||||
@ -69,6 +68,7 @@ import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.color.divider
|
||||
import org.thoughtcrime.securesms.ui.color.radioButtonColors
|
||||
import org.thoughtcrime.securesms.ui.color.transparentButtonColors
|
||||
import org.thoughtcrime.securesms.ui.components.SmallCircularProgressIndicator
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@ -453,11 +453,7 @@ fun LaunchedEffectAsync(block: suspend CoroutineScope.() -> Unit) {
|
||||
@Composable
|
||||
fun LoadingArcOr(loading: Boolean, content: @Composable () -> Unit) {
|
||||
AnimatedVisibility(loading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(20.dp),
|
||||
color = LocalContentColor.current,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
SmallCircularProgressIndicator(color = LocalContentColor.current)
|
||||
}
|
||||
AnimatedVisibility(!loading) {
|
||||
content()
|
||||
|
@ -0,0 +1,26 @@
|
||||
package org.thoughtcrime.securesms.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.LocalContentColor
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun CircularProgressIndicator(color: Color = LocalContentColor.current) {
|
||||
androidx.compose.material.CircularProgressIndicator(
|
||||
modifier = Modifier.size(40.dp),
|
||||
color = color,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SmallCircularProgressIndicator(color: Color = LocalContentColor.current) {
|
||||
androidx.compose.material.CircularProgressIndicator(
|
||||
modifier = Modifier.size(20.dp),
|
||||
color = color,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
}
|
@ -1140,4 +1140,7 @@
|
||||
<string name="AccessibilityId_copy_button">Copy button</string>
|
||||
<string name="AccessibilityId_view_qr_code">View QR code</string>
|
||||
<string name="AccessibilityId_qr_code">QR code</string>
|
||||
<string name="warning">Warning</string>
|
||||
<string name="you_cannot_go_back_further_in_order_to_stop_loading_your_account_session_needs_to_quit">You cannot go back further. In order to stop loading your account, Session needs to quit.</string>
|
||||
<string name="quit">Quit</string>
|
||||
</resources>
|
||||
|
Loading…
x
Reference in New Issue
Block a user