Updates for code review

This commit is contained in:
Andrew 2024-04-04 22:14:55 +10:30
parent 3ae2dc5bc5
commit 2cc83cd650
8 changed files with 110 additions and 51 deletions

View File

@ -5,7 +5,7 @@ buildscript {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.4.2'
classpath "com.android.tools.build:gradle:$gradlePluginVersion"
classpath files('libs/gradle-witness.jar')
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlinVersion"

View File

@ -14,6 +14,7 @@ import androidx.annotation.LayoutRes
import androidx.annotation.StringRes
import androidx.annotation.StyleRes
import androidx.appcompat.app.AlertDialog
import androidx.core.text.HtmlCompat
import androidx.core.view.setMargins
import androidx.core.view.setPadding
import androidx.core.view.updateMargins
@ -21,7 +22,6 @@ import androidx.fragment.app.Fragment
import network.loki.messenger.R
import org.thoughtcrime.securesms.util.toPx
@DslMarker
@Target(AnnotationTarget.CLASS, AnnotationTarget.TYPE)
annotation class DialogDsl
@ -64,7 +64,6 @@ class SessionDialogBuilder(val context: Context) {
}
}
private fun text(text: CharSequence?, @StyleRes style: Int, modify: TextView.() -> Unit) {
text ?: return
TextView(context, null, 0, style)
@ -75,6 +74,8 @@ class SessionDialogBuilder(val context: Context) {
}.let(topView::addView)
}
fun htmlText(@StringRes id: Int, @StyleRes style: Int = 0, modify: TextView.() -> Unit = {}) { text(context.resources.getText(id)) }
fun view(view: View) = contentView.addView(view)
fun view(@LayoutRes layout: Int): View = LayoutInflater.from(context).inflate(layout, contentView)

View File

@ -18,9 +18,11 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.lifecycleScope
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import network.loki.messenger.R
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.dependencies.ConfigFactory
@ -99,8 +101,8 @@ class LoadingActivity: BaseActionBarActivity() {
Column {
Spacer(modifier = Modifier.weight(1f))
ProgressArc(animatable.value, modifier = Modifier.align(Alignment.CenterHorizontally))
Text("One moment please..", modifier = Modifier.align(Alignment.CenterHorizontally), style = MaterialTheme.typography.h6)
Text("Loading your account", modifier = Modifier.align(Alignment.CenterHorizontally))
Text(stringResource(R.string.waitOneMoment), modifier = Modifier.align(Alignment.CenterHorizontally), style = MaterialTheme.typography.h6)
Text(stringResource(R.string.loadAccountProgressMessage), modifier = Modifier.align(Alignment.CenterHorizontally))
Spacer(modifier = Modifier.weight(2f))
}
}

View File

@ -61,16 +61,16 @@ class MessageNotificationsActivity : BaseActionBarActivity() {
TextSecurePreferences.setHasSeenWelcomeScreen(this, true)
ComposeView(this)
.apply { setContent { MessageNotifications() } }
.apply { setContent { MessageNotificationsScreen() } }
.let(::setContentView)
}
@Composable
private fun MessageNotifications() {
private fun MessageNotificationsScreen() {
val state by viewModel.stateFlow.collectAsState()
AppTheme {
MessageNotifications(state, viewModel::setEnabled, ::register)
MessageNotificationsScreen(state, viewModel::setEnabled, ::register)
}
}
@ -87,25 +87,25 @@ class MessageNotificationsActivity : BaseActionBarActivity() {
@Preview
@Composable
fun MessageNotificationsPreview(
fun MessageNotificationsScreenPreview(
@PreviewParameter(ThemeResPreviewParameterProvider::class) themeResId: Int
) {
PreviewTheme(themeResId) {
MessageNotifications()
MessageNotificationsScreen()
}
}
@Composable
fun MessageNotifications(
fun MessageNotificationsScreen(
state: MessageNotificationsState = MessageNotificationsState(),
setEnabled: (Boolean) -> Unit = {},
onContinue: () -> Unit = {}
) {
Column(Modifier.padding(horizontal = 32.dp)) {
Spacer(Modifier.weight(1f))
Text("Message notifications", style = MaterialTheme.typography.h4)
Text(stringResource(R.string.notificationsMessage), style = MaterialTheme.typography.h4)
Spacer(Modifier.height(16.dp))
Text("There are two ways Session can notify you of new messages.")
Text(stringResource(R.string.onboardingMessageNotificationExplaination))
Spacer(Modifier.height(16.dp))
NotificationRadioButton(
R.string.activity_pn_mode_fast_mode,
@ -125,8 +125,8 @@ fun MessageNotifications(
OutlineButton(
stringResource(R.string.continue_2),
modifier = Modifier
.align(Alignment.CenterHorizontally)
.width(262.dp),
.align(Alignment.CenterHorizontally)
.width(262.dp),
onClick = onContinue
)
Spacer(modifier = Modifier.height(12.dp))

View File

@ -7,6 +7,8 @@ import android.os.Bundle
import androidx.activity.viewModels
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.Crossfade
import androidx.compose.animation.core.animateValue
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
@ -27,9 +29,11 @@ import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
@ -41,6 +45,9 @@ import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import network.loki.messenger.R
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.showSessionDialog
@ -55,6 +62,7 @@ import org.thoughtcrime.securesms.ui.classicDarkColors
import org.thoughtcrime.securesms.ui.colorDestructive
import org.thoughtcrime.securesms.ui.h8
import org.thoughtcrime.securesms.ui.small
import kotlin.time.Duration.Companion.seconds
class RecoveryPasswordActivity : BaseActionBarActivity() {
@ -73,20 +81,18 @@ class RecoveryPasswordActivity : BaseActionBarActivity() {
private fun onHide() {
showSessionDialog {
title("Hide Recovery Password Permanently")
text("Without your recovery password, you cannot load your account on new devices.\n" +
"\n" +
"We strongly recommend you save your recovery password in a safe and secure place before continuing.")
title(R.string.recoveryPasswordHidePermanently)
htmlText(R.string.recoveryPasswordHidePermanentlyDescription1)
destructiveButton(R.string.continue_2) { onHideConfirm() }
button(R.string.cancel) {}
cancelButton()
}
}
private fun onHideConfirm() {
showSessionDialog {
title("Hide Recovery Password Permanently")
text("Are you sure you want to permanently hide your recovery password on this device? This cannot be undone.")
button(R.string.cancel) {}
title(R.string.recoveryPasswordHidePermanently)
text(R.string.recoveryPasswordHidePermanentlyDescription2)
cancelButton()
destructiveButton(R.string.yes) {
viewModel.permanentlyHidePassword()
finish()
@ -131,31 +137,27 @@ fun RecoveryPasswordCell(seed: String = "", qrBitmap: Bitmap? = null, copySeed:(
mutableStateOf(false)
}
val copied = remember {
mutableStateOf(false)
}
CellWithPaddingAndMargin {
Column {
Row {
Text("Recovery Password")
Text(stringResource(R.string.sessionRecoveryPassword))
Spacer(Modifier.width(8.dp))
SessionShieldIcon()
}
Text("Use your recovery password to load your account on new devices.\n\nYour account cannot be recovered without your recovery password. Make sure it's stored somewhere safe and secure — and don't share it with anyone.")
Text(stringResource(R.string.recoveryPasswordDescription))
AnimatedVisibility(!showQr.value) {
Text(
seed,
modifier = Modifier
.padding(vertical = 24.dp)
.border(
width = 1.dp,
color = classicDarkColors[3],
shape = RoundedCornerShape(11.dp)
)
.padding(24.dp),
.padding(vertical = 24.dp)
.border(
width = 1.dp,
color = classicDarkColors[3],
shape = RoundedCornerShape(11.dp)
)
.padding(24.dp),
style = MaterialTheme.typography.small.copy(fontFamily = FontFamily.Monospace),
color = LocalExtraColors.current.prominentButtonColor,
)
@ -166,8 +168,8 @@ fun RecoveryPasswordCell(seed: String = "", qrBitmap: Bitmap? = null, copySeed:(
backgroundColor = LocalExtraColors.current.lightCell,
elevation = 0.dp,
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(vertical = 24.dp)
.align(Alignment.CenterHorizontally)
.padding(vertical = 24.dp)
) {
Box {
qrBitmap?.let {
@ -183,11 +185,11 @@ fun RecoveryPasswordCell(seed: String = "", qrBitmap: Bitmap? = null, copySeed:(
contentDescription = "",
tint = LocalExtraColors.current.onLightCell,
modifier = Modifier
.align(Alignment.Center)
.width(46.dp)
.height(56.dp)
.background(color = LocalExtraColors.current.lightCell)
.padding(horizontal = 3.dp, vertical = 1.dp)
.align(Alignment.Center)
.width(46.dp)
.height(56.dp)
.background(color = LocalExtraColors.current.lightCell)
.padding(horizontal = 3.dp, vertical = 1.dp)
)
}
}
@ -195,16 +197,36 @@ fun RecoveryPasswordCell(seed: String = "", qrBitmap: Bitmap? = null, copySeed:(
AnimatedVisibility(!showQr.value) {
Row(horizontalArrangement = Arrangement.spacedBy(32.dp)) {
Crossfade(targetState = if (copied.value) R.string.copied else R.string.copy, modifier = Modifier.weight(1f), label = "Copy to Copied CrossFade") {
OutlineButton(text = stringResource(it), modifier = Modifier.fillMaxWidth(), color = MaterialTheme.colors.onPrimary) { copySeed(); copied.value = true }
val scope = rememberCoroutineScope()
val revertCopiedTextJob = remember { mutableStateOf<Job?>(null) }
val copied = remember { mutableStateOf(false) }
OutlineButton(
modifier = Modifier.weight(1f),
color = MaterialTheme.colors.onPrimary,
onClick = {
copySeed()
revertCopiedTextJob.value?.cancel()
revertCopiedTextJob.value = scope.launch {
copied.value = true
delay(2.seconds)
copied.value = false
}
}
) {
AnimatedVisibility(!copied.value) {
Text(stringResource(R.string.copy))
}
AnimatedVisibility(copied.value) {
Text(stringResource(R.string.copied))
}
}
OutlineButton(text = "View QR", modifier = Modifier.weight(1f), color = MaterialTheme.colors.onPrimary) { showQr.toggle() }
OutlineButton(text = stringResource(R.string.qrView), modifier = Modifier.weight(1f), color = MaterialTheme.colors.onPrimary) { showQr.toggle() }
}
}
AnimatedVisibility(showQr.value, modifier = Modifier.align(Alignment.CenterHorizontally)) {
OutlineButton(
text = "View Password",
text = stringResource(R.string.recoveryPasswordView),
color = MaterialTheme.colors.onPrimary,
modifier = Modifier.align(Alignment.CenterHorizontally)
) { showQr.toggle() }
@ -220,11 +242,11 @@ fun HideRecoveryPasswordCell(onHide: () -> Unit = {}) {
CellWithPaddingAndMargin {
Row {
Column(Modifier.weight(1f)) {
Text(text = "Hide Recovery Password", style = MaterialTheme.typography.h8)
Text(text = "Permanently hide your recovery password on this device.")
Text(text = stringResource(R.string.recoveryPasswordHideRecoveryPassword), style = MaterialTheme.typography.h8)
Text(text = stringResource(R.string.recoveryPasswordHideRecoveryPasswordDescription))
}
OutlineButton(
"Hide",
stringResource(R.string.hide),
modifier = Modifier.align(Alignment.CenterVertically),
color = colorDestructive
) { onHide() }

View File

@ -84,6 +84,27 @@ fun OutlineButton(
}
}
@Composable
fun OutlineButton(
modifier: Modifier = Modifier,
color: Color = LocalExtraColors.current.prominentButtonColor,
onClick: () -> Unit = {},
content: @Composable () -> Unit = {}
) {
OutlinedButton(
modifier = modifier,
onClick = onClick,
border = BorderStroke(1.dp, color),
shape = RoundedCornerShape(50), // = 50% percent
colors = ButtonDefaults.outlinedButtonColors(
contentColor = color,
backgroundColor = Color.Unspecified
)
) {
content()
}
}
@Composable
fun FilledButton(text: String, modifier: Modifier = Modifier, onClick: () -> Unit) {
OutlinedButton(

View File

@ -1081,4 +1081,17 @@
<string name="activity_link_load_account">Load Account</string>
<string name="activity_link_camera_permission_permanently_denied_configure_in_settings">Camera Permission permanently denied. Configure in settings.</string>
<string name="activity_link_enter_your_recovery_password_to_load_your_account_if_you_haven_t_saved_it_you_can_find_it_in_your_app_settings">Enter your recovery password to load your account. If you haven\'t saved it, you can find it in your app settings.</string>
<string name="waitOneMoment">One moment please..</string>
<string name="loadAccountProgressMessage">Loading your account</string>
<string name="notificationsMessage">Message notifications</string>
<string name="onboardingMessageNotificationExplaination">There are two ways Session can notify you of new messages.</string>
<string name="recoveryPasswordHidePermanently">Hide Recovery Password Permanently</string>
<string name="recoveryPasswordHidePermanentlyDescription1"><![CDATA[Without your recovery password, you cannot load your account on new devices. <br /><br />We strongly recommend you save your recovery password in a safe and secure place before continuing.]]></string>
<string name="recoveryPasswordHidePermanentlyDescription2">Are you sure you want to permanently hide your recovery password on this device? This cannot be undone.</string>
<string name="recoveryPasswordDescription">Use your recovery password to load your account on new devices. Your account cannot be recovered without your recovery password. Make sure it\'s stored somewhere safe and secure — and don\'t share it with anyone.</string>
<string name="hide">Hide</string>
<string name="recoveryPasswordHideRecoveryPassword">Hide Recovery Password</string>
<string name="qrView">View QR</string>
<string name="recoveryPasswordView">View Password</string>
<string name="recoveryPasswordHideRecoveryPasswordDescription">Permanently hide your recovery password on this device.</string>
</resources>

View File

@ -16,7 +16,7 @@ android.enableJetifier=true
org.gradle.jvmargs=-Xmx2048M -Dkotlin.daemon.jvm.options\="-Xmx2048M"
org.gradle.unsafe.configuration-cache=true
gradlePluginVersion=7.3.1
gradlePluginVersion=7.4.2
googleServicesVersion=4.3.12
kotlinVersion=1.8.21
android.useAndroidX=true