mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-24 16:57:50 +00:00
Improve themes, styling and animations
This commit is contained in:
parent
89d93bc80d
commit
ff64a8bc13
@ -1,5 +1,6 @@
|
||||
package org.thoughtcrime.securesms.conversation.disappearingmessages.ui
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@ -24,8 +25,8 @@ import org.thoughtcrime.securesms.ui.Callbacks
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.NoOpCallbacks
|
||||
import org.thoughtcrime.securesms.ui.OptionsCard
|
||||
import org.thoughtcrime.securesms.ui.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.RadioOption
|
||||
import org.thoughtcrime.securesms.ui.components.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.fadingEdges
|
||||
|
||||
@ -64,9 +65,9 @@ fun DisappearingMessages(
|
||||
}
|
||||
|
||||
if (state.showSetButton) OutlineButton(
|
||||
GetString(R.string.disappearing_messages_set_button_title),
|
||||
textId = R.string.disappearing_messages_set_button_title,
|
||||
modifier = Modifier
|
||||
.contentDescription(GetString(R.string.AccessibilityId_set_button))
|
||||
.contentDescription(R.string.AccessibilityId_set_button)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(bottom = 20.dp),
|
||||
onClick = callbacks::onSetClick
|
||||
|
@ -1,12 +1,10 @@
|
||||
package org.thoughtcrime.securesms.dms
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
@ -17,13 +15,13 @@ import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
@ -41,14 +39,16 @@ import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||
import org.thoughtcrime.securesms.showOpenUrlDialog
|
||||
import org.thoughtcrime.securesms.ui.AppTheme
|
||||
import org.thoughtcrime.securesms.ui.BorderlessButtonSecondary
|
||||
import org.thoughtcrime.securesms.ui.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.LoadingArcOr
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.components.AppBar
|
||||
import org.thoughtcrime.securesms.ui.components.BorderlessButtonSecondary
|
||||
import org.thoughtcrime.securesms.ui.components.MaybeScanQrCode
|
||||
import org.thoughtcrime.securesms.ui.components.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.components.SessionOutlinedTextField
|
||||
import org.thoughtcrime.securesms.ui.components.SessionTabRow
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
|
||||
@AndroidEntryPoint
|
||||
class NewMessageFragment : Fragment() {
|
||||
@ -157,12 +157,16 @@ fun EnterAccountId(
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
|
||||
OutlineButton(
|
||||
text = stringResource(id = R.string.continue_2),
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(horizontal = 64.dp, vertical = 20.dp)
|
||||
.width(200.dp),
|
||||
loading = state.loading
|
||||
) { callbacks.onContinue() }
|
||||
.width(200.dp)
|
||||
.contentDescription(R.string.continue_2),
|
||||
onClick = { callbacks.onContinue() }
|
||||
) {
|
||||
LoadingArcOr(state.loading) {
|
||||
Text(stringResource(R.string.continue_2))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -98,11 +98,11 @@ import org.thoughtcrime.securesms.preferences.SettingsActivity
|
||||
import org.thoughtcrime.securesms.showMuteDialog
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.ui.AppTheme
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionShieldIcon
|
||||
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.components.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.h8
|
||||
import org.thoughtcrime.securesms.ui.small
|
||||
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||
@ -372,10 +372,11 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
|
||||
}
|
||||
Spacer(Modifier.width(12.dp))
|
||||
OutlineButton(
|
||||
stringResource(R.string.continue_2),
|
||||
Modifier.align(Alignment.CenterVertically),
|
||||
contentDescription = GetString(R.string.AccessibilityId_reveal_recovery_phrase_button)
|
||||
) { start<RecoveryPasswordActivity>() }
|
||||
textId = R.string.continue_2,
|
||||
Modifier.align(Alignment.CenterVertically)
|
||||
.contentDescription(R.string.AccessibilityId_reveal_recovery_phrase_button),
|
||||
onClick = { start<RecoveryPasswordActivity>() }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,15 +32,14 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||
import org.thoughtcrime.securesms.onboarding.pickname.startPickDisplayNameActivity
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService
|
||||
import org.thoughtcrime.securesms.showOpenUrlDialog
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.ui.AppTheme
|
||||
import org.thoughtcrime.securesms.ui.BorderlessButton
|
||||
import org.thoughtcrime.securesms.ui.FilledButton
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.classicDarkColors
|
||||
import org.thoughtcrime.securesms.ui.components.BorderlessButton
|
||||
import org.thoughtcrime.securesms.ui.components.FilledButton
|
||||
import org.thoughtcrime.securesms.ui.components.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.session_accent
|
||||
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo
|
||||
@ -94,28 +93,30 @@ class LandingActivity : BaseActionBarActivity() {
|
||||
OutlineButton(
|
||||
text = stringResource(R.string.onboardingAccountCreate),
|
||||
modifier = Modifier
|
||||
.contentDescription(R.string.AccessibilityId_create_account_button)
|
||||
.width(262.dp)
|
||||
.align(Alignment.CenterHorizontally),
|
||||
contentDescription = GetString(R.string.AccessibilityId_create_account_button)
|
||||
) { startPickDisplayNameActivity() }
|
||||
onClick = ::startPickDisplayNameActivity
|
||||
)
|
||||
Spacer(modifier = Modifier.height(14.dp))
|
||||
FilledButton(
|
||||
text = stringResource(R.string.onboardingAccountExists),
|
||||
modifier = Modifier
|
||||
.width(262.dp)
|
||||
.align(Alignment.CenterHorizontally),
|
||||
contentDescription = GetString(R.string.AccessibilityId_restore_account_button)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.contentDescription(R.string.AccessibilityId_restore_account_button)
|
||||
) { startLinkDeviceActivity() }
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
BorderlessButton(
|
||||
text = stringResource(R.string.onboardingTosPrivacy),
|
||||
modifier = Modifier
|
||||
.width(262.dp)
|
||||
.align(Alignment.CenterHorizontally),
|
||||
contentDescription = GetString(R.string.AccessibilityId_privacy_policy_link),
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.contentDescription(R.string.AccessibilityId_privacy_policy_link),
|
||||
fontSize = 11.sp,
|
||||
lineHeight = 13.sp
|
||||
) { openDialog() }
|
||||
lineHeight = 13.sp,
|
||||
onClick = ::openDialog
|
||||
)
|
||||
Spacer(modifier = Modifier.height(8.dp))
|
||||
}
|
||||
}
|
||||
@ -136,44 +137,44 @@ class LandingActivity : BaseActionBarActivity() {
|
||||
private fun open(url: String) {
|
||||
Intent(Intent.ACTION_VIEW, Uri.parse(url)).let(::startActivity)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun IncomingText(text: String) {
|
||||
ChatText(
|
||||
text,
|
||||
color = classicDarkColors[2]
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.OutgoingText(text: String) {
|
||||
ChatText(
|
||||
text,
|
||||
color = session_accent,
|
||||
textColor = MaterialTheme.colors.primary,
|
||||
modifier = Modifier.align(Alignment.End)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ChatText(
|
||||
text: String,
|
||||
color: Color,
|
||||
modifier: Modifier = Modifier,
|
||||
textColor: Color = Color.Unspecified
|
||||
) {
|
||||
Text(
|
||||
text,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 19.sp,
|
||||
color = textColor,
|
||||
modifier = modifier
|
||||
.fillMaxWidth(0.666f)
|
||||
.background(
|
||||
color = color,
|
||||
shape = RoundedCornerShape(size = 13.dp)
|
||||
)
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun IncomingText(text: String) {
|
||||
ChatText(
|
||||
text,
|
||||
color = classicDarkColors[2]
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ColumnScope.OutgoingText(text: String) {
|
||||
ChatText(
|
||||
text,
|
||||
color = session_accent,
|
||||
textColor = MaterialTheme.colors.primary,
|
||||
modifier = Modifier.align(Alignment.End)
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ChatText(
|
||||
text: String,
|
||||
color: Color,
|
||||
modifier: Modifier = Modifier,
|
||||
textColor: Color = Color.Unspecified
|
||||
) {
|
||||
Text(
|
||||
text,
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 19.sp,
|
||||
color = textColor,
|
||||
modifier = modifier
|
||||
.fillMaxWidth(0.666f)
|
||||
.background(
|
||||
color = color,
|
||||
shape = RoundedCornerShape(size = 13.dp)
|
||||
)
|
||||
.padding(horizontal = 16.dp, vertical = 12.dp)
|
||||
)
|
||||
}
|
||||
|
@ -40,9 +40,9 @@ import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||
import org.thoughtcrime.securesms.ui.AppTheme
|
||||
import org.thoughtcrime.securesms.ui.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.baseBold
|
||||
import org.thoughtcrime.securesms.ui.components.MaybeScanQrCode
|
||||
import org.thoughtcrime.securesms.ui.components.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.components.SessionOutlinedTextField
|
||||
import org.thoughtcrime.securesms.ui.components.SessionTabRow
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
@ -150,12 +150,13 @@ fun RecoveryPassword(state: LinkDeviceState, onChange: (String) -> Unit = {}, on
|
||||
}
|
||||
Spacer(Modifier.weight(2f))
|
||||
OutlineButton(
|
||||
text = stringResource(id = R.string.continue_2),
|
||||
textId = R.string.continue_2,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(horizontal = 64.dp, vertical = 20.dp)
|
||||
.width(200.dp)
|
||||
) { onContinue() }
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(horizontal = 64.dp, vertical = 20.dp)
|
||||
.width(200.dp),
|
||||
onClick = onContinue
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,10 +38,9 @@ import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||
import org.thoughtcrime.securesms.home.HomeActivity
|
||||
import org.thoughtcrime.securesms.notifications.PushRegistry
|
||||
import org.thoughtcrime.securesms.ui.AppTheme
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.components.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.h8
|
||||
import org.thoughtcrime.securesms.ui.h9
|
||||
@ -127,7 +126,7 @@ fun MessageNotificationsScreen(
|
||||
)
|
||||
Spacer(Modifier.weight(1f))
|
||||
OutlineButton(
|
||||
stringResource(R.string.continue_2),
|
||||
textId = R.string.continue_2,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.width(262.dp),
|
||||
|
@ -36,10 +36,10 @@ import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||
import org.thoughtcrime.securesms.onboarding.messagenotifications.startPNModeActivity
|
||||
import org.thoughtcrime.securesms.ui.AppTheme
|
||||
import org.thoughtcrime.securesms.ui.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.base
|
||||
import org.thoughtcrime.securesms.ui.baseBold
|
||||
import org.thoughtcrime.securesms.ui.components.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.outlinedTextFieldColors
|
||||
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo
|
||||
@ -129,11 +129,12 @@ class PickDisplayNameActivity : BaseActionBarActivity() {
|
||||
Spacer(modifier = Modifier.weight(2f))
|
||||
|
||||
OutlineButton(
|
||||
stringResource(R.string.continue_2),
|
||||
textId = R.string.continue_2,
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.width(262.dp)
|
||||
) { onContinue() }
|
||||
.width(262.dp),
|
||||
onClick = onContinue,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,5 @@
|
||||
package org.thoughtcrime.securesms.onboarding.recoverypassword
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
@ -13,15 +10,19 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentWidth
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
@ -35,15 +36,16 @@ import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.ui.AppTheme
|
||||
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.LocalExtraColors
|
||||
import org.thoughtcrime.securesms.ui.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.LocalButtonColor
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionShieldIcon
|
||||
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.classicDarkColors
|
||||
import org.thoughtcrime.securesms.ui.colorDestructive
|
||||
import org.thoughtcrime.securesms.ui.components.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.components.QrImageCard
|
||||
import org.thoughtcrime.securesms.ui.components.SmallButtons
|
||||
import org.thoughtcrime.securesms.ui.components.TemporaryStateButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.h8
|
||||
import org.thoughtcrime.securesms.ui.small
|
||||
@ -114,15 +116,17 @@ fun RecoveryPassword(
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(bottom = 16.dp)
|
||||
) {
|
||||
RecoveryPasswordCell(seed, copySeed)
|
||||
HideRecoveryPasswordCell(onHide)
|
||||
SmallButtons {
|
||||
RecoveryPasswordCell(seed, copySeed)
|
||||
HideRecoveryPasswordCell(onHide)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun RecoveryPasswordCell(seed: String, copySeed:() -> Unit = {}) {
|
||||
val showQr = remember {
|
||||
var showQr by remember {
|
||||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
@ -136,7 +140,7 @@ fun RecoveryPasswordCell(seed: String, copySeed:() -> Unit = {}) {
|
||||
|
||||
Text(stringResource(R.string.recoveryPasswordDescription))
|
||||
|
||||
AnimatedVisibility(!showQr.value) {
|
||||
AnimatedVisibility(!showQr) {
|
||||
Text(
|
||||
seed,
|
||||
modifier = Modifier
|
||||
@ -149,62 +153,70 @@ fun RecoveryPasswordCell(seed: String, copySeed:() -> Unit = {}) {
|
||||
)
|
||||
.padding(24.dp),
|
||||
style = MaterialTheme.typography.small.copy(fontFamily = FontFamily.Monospace),
|
||||
color = LocalExtraColors.current.prominentButtonColor,
|
||||
color = MaterialTheme.colors.run { if (isLight) onSurface else secondary },
|
||||
)
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
showQr.value,
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally).padding(vertical = 24.dp)
|
||||
showQr,
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||
) {
|
||||
QrImageCard(
|
||||
seed,
|
||||
modifier = Modifier.padding(vertical = 24.dp),
|
||||
contentDescription = "QR code of your recovery password",
|
||||
icon = R.drawable.session_shield
|
||||
)
|
||||
}
|
||||
|
||||
AnimatedVisibility(!showQr.value) {
|
||||
AnimatedVisibility(!showQr) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(32.dp)) {
|
||||
OutlineButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
color = MaterialTheme.colors.onPrimary,
|
||||
onClick = copySeed,
|
||||
temporaryContent = { Text(stringResource(R.string.copied)) }
|
||||
) {
|
||||
Text(stringResource(R.string.copy))
|
||||
TemporaryStateButton { source, temporary ->
|
||||
OutlineButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
interactionSource = source,
|
||||
onClick = { copySeed() },
|
||||
) {
|
||||
AnimatedVisibility(temporary) { Text(stringResource(R.string.copied)) }
|
||||
AnimatedVisibility(!temporary) { Text(stringResource(R.string.copy)) }
|
||||
}
|
||||
}
|
||||
OutlineButton(text = stringResource(R.string.qrView), modifier = Modifier.weight(1f), color = MaterialTheme.colors.onPrimary) { showQr.toggle() }
|
||||
OutlineButton(textId = R.string.qrView, modifier = Modifier.weight(1f), onClick = { showQr = !showQr })
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedVisibility(showQr.value, modifier = Modifier.align(Alignment.CenterHorizontally)) {
|
||||
AnimatedVisibility(showQr, modifier = Modifier.align(Alignment.CenterHorizontally)) {
|
||||
OutlineButton(
|
||||
text = stringResource(R.string.recoveryPasswordView),
|
||||
color = MaterialTheme.colors.onPrimary,
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||
) { showQr.toggle() }
|
||||
textId = R.string.recoveryPasswordView,
|
||||
onClick = { showQr = !showQr }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun MutableState<Boolean>.toggle() { value = !value }
|
||||
|
||||
@Composable
|
||||
fun HideRecoveryPasswordCell(onHide: () -> Unit = {}) {
|
||||
CellWithPaddingAndMargin {
|
||||
Row {
|
||||
Column(Modifier.weight(1f)) {
|
||||
Column(
|
||||
Modifier.weight(1f)
|
||||
) {
|
||||
Text(text = stringResource(R.string.recoveryPasswordHideRecoveryPassword), style = MaterialTheme.typography.h8)
|
||||
Text(text = stringResource(R.string.recoveryPasswordHideRecoveryPasswordDescription))
|
||||
}
|
||||
OutlineButton(
|
||||
stringResource(R.string.hide),
|
||||
contentDescription = GetString(R.string.AccessibilityId_hide_recovery_password_button),
|
||||
modifier = Modifier.align(Alignment.CenterVertically),
|
||||
color = colorDestructive
|
||||
) { onHide() }
|
||||
CompositionLocalProvider(
|
||||
LocalButtonColor provides colorDestructive,
|
||||
) {
|
||||
OutlineButton(
|
||||
textId = R.string.hide,
|
||||
modifier = Modifier
|
||||
.wrapContentWidth()
|
||||
.align(Alignment.CenterVertically)
|
||||
.contentDescription(R.string.AccessibilityId_hide_recovery_password_button),
|
||||
onClick = onHide
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,15 @@ import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Toast
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.interaction.InteractionSource
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
@ -84,19 +87,16 @@ import org.thoughtcrime.securesms.preferences.appearance.AppearanceSettingsActiv
|
||||
import org.thoughtcrime.securesms.profiles.ProfileMediaConstraints
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.ui.AppTheme
|
||||
import org.thoughtcrime.securesms.ui.BorderlessButton
|
||||
import org.thoughtcrime.securesms.ui.Cell
|
||||
import org.thoughtcrime.securesms.ui.Divider
|
||||
import org.thoughtcrime.securesms.ui.ItemButton
|
||||
import org.thoughtcrime.securesms.ui.ItemButtonWithDrawable
|
||||
import org.thoughtcrime.securesms.ui.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.components.OutlineButton
|
||||
import org.thoughtcrime.securesms.ui.components.TemporaryStateButton
|
||||
import org.thoughtcrime.securesms.ui.destructiveButtonColors
|
||||
import org.thoughtcrime.securesms.util.BitmapDecodingException
|
||||
import org.thoughtcrime.securesms.util.BitmapUtil
|
||||
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||
import org.thoughtcrime.securesms.util.disableClipping
|
||||
import org.thoughtcrime.securesms.util.push
|
||||
import org.thoughtcrime.securesms.util.show
|
||||
import java.io.File
|
||||
@ -429,20 +429,25 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
fun Buttons() {
|
||||
Column {
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = 24.dp),
|
||||
modifier = Modifier.padding(horizontal = 24.dp).padding(top = 8.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
) {
|
||||
OutlineButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
onClick = { sharePublicKey() }
|
||||
) { Text(stringResource(R.string.share)) }
|
||||
|
||||
OutlineButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
onClick = { copyPublicKey() },
|
||||
temporaryContent = { Text(stringResource(R.string.copied)) }
|
||||
onClick = ::sharePublicKey
|
||||
) {
|
||||
Text(stringResource(R.string.copy))
|
||||
Text(stringResource(R.string.share))
|
||||
}
|
||||
|
||||
TemporaryStateButton { source, temporary ->
|
||||
OutlineButton(
|
||||
modifier = Modifier.weight(1f),
|
||||
interactionSource = source,
|
||||
onClick = { copyPublicKey() },
|
||||
) {
|
||||
AnimatedVisibility(temporary) { Text(stringResource(R.string.copied)) }
|
||||
AnimatedVisibility(!temporary) { Text(stringResource(R.string.copy)) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,6 @@ import android.os.Parcelable
|
||||
import android.util.SparseArray
|
||||
import android.view.View
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.widget.SwitchCompat
|
||||
import androidx.core.view.children
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
@ -31,8 +30,8 @@ class AppearanceSettingsActivity: PassphraseRequiredActionBarActivity(), View.On
|
||||
|
||||
var currentTheme: ThemeState? = null
|
||||
|
||||
private val accentColors
|
||||
get() = mapOf(
|
||||
private val accentColors by lazy {
|
||||
mapOf(
|
||||
binding.accentGreen to R.style.PrimaryGreen,
|
||||
binding.accentBlue to R.style.PrimaryBlue,
|
||||
binding.accentYellow to R.style.PrimaryYellow,
|
||||
@ -41,9 +40,10 @@ class AppearanceSettingsActivity: PassphraseRequiredActionBarActivity(), View.On
|
||||
binding.accentOrange to R.style.PrimaryOrange,
|
||||
binding.accentRed to R.style.PrimaryRed
|
||||
)
|
||||
}
|
||||
|
||||
private val themeViews
|
||||
get() = listOf(
|
||||
private val themeViews by lazy {
|
||||
listOf(
|
||||
binding.themeOptionClassicDark,
|
||||
binding.themeRadioClassicDark,
|
||||
binding.themeOptionClassicLight,
|
||||
@ -53,6 +53,7 @@ class AppearanceSettingsActivity: PassphraseRequiredActionBarActivity(), View.On
|
||||
binding.themeOptionOceanLight,
|
||||
binding.themeRadioOceanLight
|
||||
)
|
||||
}
|
||||
|
||||
override fun onClick(v: View?) {
|
||||
v ?: return
|
||||
|
@ -1,14 +1,13 @@
|
||||
package org.thoughtcrime.securesms.ui
|
||||
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
@ -27,7 +26,6 @@ import androidx.compose.foundation.layout.wrapContentSize
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.itemsIndexed
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Button
|
||||
import androidx.compose.material.ButtonColors
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.Card
|
||||
@ -35,12 +33,14 @@ import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.Colors
|
||||
import androidx.compose.material.ContentAlpha
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.LocalContentColor
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.OutlinedButton
|
||||
import androidx.compose.material.RadioButton
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@ -49,6 +49,7 @@ import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.drawWithContent
|
||||
import androidx.compose.ui.geometry.Size
|
||||
@ -57,7 +58,6 @@ import androidx.compose.ui.graphics.Brush
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.graphics.StrokeCap
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.graphics.drawscope.Stroke
|
||||
import androidx.compose.ui.graphics.graphicsLayer
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
@ -71,10 +71,9 @@ import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import com.google.accompanist.drawablepainter.rememberDrawablePainter
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
@ -83,155 +82,6 @@ import org.thoughtcrime.securesms.components.ProfilePictureView
|
||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.OptionsCard
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@Composable
|
||||
fun OutlineButton(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
contentDescription: GetString = GetString(text),
|
||||
color: Color = LocalExtraColors.current.prominentButtonColor,
|
||||
loading: Boolean = false,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
OutlinedButton(
|
||||
modifier = modifier.contentDescription(contentDescription),
|
||||
onClick = onClick,
|
||||
border = BorderStroke(1.dp, color),
|
||||
shape = RoundedCornerShape(50), // = 50% percent
|
||||
colors = ButtonDefaults.outlinedButtonColors(
|
||||
contentColor = color,
|
||||
backgroundColor = Color.Unspecified
|
||||
)
|
||||
) {
|
||||
AnimatedVisibility(loading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(20.dp),
|
||||
color = color,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(!loading) { Text(text = text) }
|
||||
}
|
||||
}
|
||||
|
||||
@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(percent = 50),
|
||||
colors = ButtonDefaults.outlinedButtonColors(
|
||||
contentColor = color,
|
||||
backgroundColor = Color.Unspecified
|
||||
)
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OutlineButton(
|
||||
temporaryContent: @Composable () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
color: Color = LocalExtraColors.current.prominentButtonColor,
|
||||
onClick: () -> Unit = {},
|
||||
content: @Composable () -> Unit = {}
|
||||
) {
|
||||
var clicked by remember { mutableStateOf(false) }
|
||||
if (clicked) LaunchedEffectAsync {
|
||||
delay(2.seconds)
|
||||
clicked = false
|
||||
}
|
||||
|
||||
OutlinedButton(
|
||||
modifier = modifier,
|
||||
onClick = {
|
||||
onClick()
|
||||
clicked = true
|
||||
},
|
||||
border = BorderStroke(1.dp, color),
|
||||
shape = RoundedCornerShape(percent = 50),
|
||||
colors = ButtonDefaults.outlinedButtonColors(
|
||||
contentColor = color,
|
||||
backgroundColor = Color.Unspecified
|
||||
)
|
||||
) {
|
||||
AnimatedVisibility(clicked) {
|
||||
temporaryContent()
|
||||
}
|
||||
AnimatedVisibility(!clicked) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun FilledButton(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
contentDescription: GetString? = GetString(text),
|
||||
onClick: () -> Unit) {
|
||||
OutlinedButton(
|
||||
modifier = modifier.size(108.dp, 34.dp),
|
||||
onClick = onClick,
|
||||
shape = RoundedCornerShape(50), // = 50% percent
|
||||
colors = ButtonDefaults.outlinedButtonColors(
|
||||
contentColor = MaterialTheme.colors.background,
|
||||
backgroundColor = LocalExtraColors.current.prominentButtonColor
|
||||
)
|
||||
) {
|
||||
Text(text = text)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BorderlessButtonSecondary(
|
||||
text: String,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
BorderlessButton(
|
||||
text,
|
||||
contentColor = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
|
||||
onClick = onClick
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BorderlessButton(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
contentDescription: GetString = GetString(text),
|
||||
fontSize: TextUnit = TextUnit.Unspecified,
|
||||
lineHeight: TextUnit = TextUnit.Unspecified,
|
||||
contentColor: Color = MaterialTheme.colors.onBackground,
|
||||
backgroundColor: Color = Color.Transparent,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
TextButton(
|
||||
onClick = onClick,
|
||||
modifier = modifier.contentDescription(contentDescription),
|
||||
shape = RoundedCornerShape(percent = 50),
|
||||
colors = ButtonDefaults.outlinedButtonColors(
|
||||
contentColor = contentColor,
|
||||
backgroundColor = backgroundColor
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = fontSize,
|
||||
lineHeight = lineHeight,
|
||||
modifier = Modifier.padding(horizontal = 2.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
interface Callbacks<in T> {
|
||||
fun onSetClick(): Any?
|
||||
@ -367,16 +217,18 @@ fun CellWithPaddingAndMargin(
|
||||
margin: Dp = 32.dp,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
Card(
|
||||
backgroundColor = MaterialTheme.colors.cellColor,
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
elevation = 0.dp,
|
||||
modifier = Modifier
|
||||
.wrapContentHeight()
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = margin),
|
||||
) {
|
||||
Box(Modifier.padding(padding)) { content() }
|
||||
CompositionLocalProvider(LocalButtonColor provides MaterialTheme.colors.onPrimary) {
|
||||
Card(
|
||||
backgroundColor = LocalCellColor.current,
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
elevation = 0.dp,
|
||||
modifier = Modifier
|
||||
.wrapContentHeight()
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = margin),
|
||||
) {
|
||||
Box(Modifier.padding(padding)) { content() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -434,27 +286,10 @@ fun Modifier.contentDescription(id: Int?): Modifier {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OutlineButton(text: GetString, contentDescription: GetString? = text, modifier: Modifier = Modifier, onClick: () -> Unit) {
|
||||
OutlinedButton(
|
||||
modifier = modifier
|
||||
.size(108.dp, 34.dp)
|
||||
.contentDescription(contentDescription),
|
||||
onClick = onClick,
|
||||
border = BorderStroke(1.dp, LocalExtraColors.current.prominentButtonColor),
|
||||
shape = RoundedCornerShape(50), // = 50% percent
|
||||
colors = ButtonDefaults.outlinedButtonColors(
|
||||
contentColor = LocalExtraColors.current.prominentButtonColor,
|
||||
backgroundColor = MaterialTheme.colors.background
|
||||
)
|
||||
){
|
||||
Text(text = text())
|
||||
}
|
||||
fun Modifier.contentDescription(text: String?): Modifier {
|
||||
return text?.let { semantics { contentDescription = it } } ?: this
|
||||
}
|
||||
|
||||
private val Colors.cellColor: Color
|
||||
@Composable
|
||||
get() = LocalExtraColors.current.settingsBackground
|
||||
|
||||
fun Modifier.fadingEdges(
|
||||
scrollState: ScrollState,
|
||||
topEdgeHeight: Dp = 0.dp,
|
||||
@ -577,5 +412,20 @@ fun RowScope.SessionShieldIcon() {
|
||||
|
||||
@Composable
|
||||
fun LaunchedEffectAsync(block: suspend CoroutineScope.() -> Unit) {
|
||||
rememberCoroutineScope().apply { LaunchedEffect(Unit) { launch { block() } } }
|
||||
val scope = rememberCoroutineScope()
|
||||
LaunchedEffect(Unit) { scope.launch(Dispatchers.IO) { block() } }
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun LoadingArcOr(loading: Boolean, content: @Composable () -> Unit) {
|
||||
AnimatedVisibility(loading) {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.size(20.dp),
|
||||
color = LocalContentColor.current,
|
||||
strokeWidth = 2.dp
|
||||
)
|
||||
}
|
||||
AnimatedVisibility(!loading) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
@ -27,15 +27,10 @@ import com.google.accompanist.themeadapter.appcompat.createAppCompatTheme
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import network.loki.messenger.R
|
||||
|
||||
val LocalExtraColors = staticCompositionLocalOf<ExtraColors> { error("No Custom Attribute value provided") }
|
||||
|
||||
|
||||
data class ExtraColors(
|
||||
val settingsBackground: Color,
|
||||
val prominentButtonColor: Color,
|
||||
val lightCell: Color,
|
||||
val onLightCell: Color,
|
||||
)
|
||||
val LocalCellColor = staticCompositionLocalOf { Color.Black }
|
||||
val LocalButtonColor = staticCompositionLocalOf { Color.Black }
|
||||
val LocalLightCell = staticCompositionLocalOf { Color.Black }
|
||||
val LocalOnLightCell = staticCompositionLocalOf { Color.Black }
|
||||
|
||||
/**
|
||||
* Converts current Theme to Compose Theme.
|
||||
@ -46,19 +41,16 @@ fun AppTheme(
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
val extraColors = context.run {
|
||||
ExtraColors(
|
||||
settingsBackground = getColorFromTheme(R.attr.colorSettingsBackground),
|
||||
prominentButtonColor = getColorFromTheme(R.attr.prominentButtonColor),
|
||||
lightCell = getColorFromTheme(R.attr.lightCell),
|
||||
onLightCell = getColorFromTheme(R.attr.onLightCell),
|
||||
)
|
||||
}
|
||||
|
||||
val surface = context.getColorFromTheme(R.attr.colorSettingsBackground)
|
||||
|
||||
|
||||
CompositionLocalProvider(LocalExtraColors provides extraColors) {
|
||||
CompositionLocalProvider(
|
||||
*listOf(
|
||||
LocalCellColor to R.attr.colorSettingsBackground,
|
||||
LocalButtonColor to R.attr.prominentButtonColor,
|
||||
LocalLightCell to R.attr.lightCell,
|
||||
LocalOnLightCell to R.attr.onLightCell
|
||||
).map { (local, attr) -> local provides context.getColorFromTheme(attr) }.toTypedArray()
|
||||
) {
|
||||
AppCompatTheme(surface = surface) {
|
||||
CompositionLocalProvider(LocalTextSelectionColors provides TextSelectionColors(
|
||||
handleColor = MaterialTheme.colors.secondary,
|
||||
|
@ -0,0 +1,174 @@
|
||||
package org.thoughtcrime.securesms.ui.components
|
||||
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.interaction.PressInteraction
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.ContentAlpha
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.OutlinedButton
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.LaunchedEffectAsync
|
||||
import org.thoughtcrime.securesms.ui.LocalButtonColor
|
||||
import org.thoughtcrime.securesms.ui.colorDestructive
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
val LocalButtonSize = staticCompositionLocalOf { mediumButton }
|
||||
val LocalButtonShape = staticCompositionLocalOf<Shape> { RoundedCornerShape(percent = 50) }
|
||||
|
||||
@Composable
|
||||
fun Modifier.applyButtonSize() = then(LocalButtonSize.current)
|
||||
|
||||
val mediumButton = Modifier.height(41.dp)
|
||||
val smallButton = Modifier.wrapContentHeight()
|
||||
|
||||
@Composable
|
||||
fun OutlineButton(@StringRes textId: Int, modifier: Modifier = Modifier, onClick: () -> Unit) {
|
||||
OutlineButton(stringResource(textId), modifier, onClick)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OutlineButton(text: String, modifier: Modifier = Modifier, onClick: () -> Unit) {
|
||||
OutlineButton(modifier.contentDescription(text), onClick = onClick) { Text(text) }
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun OutlineButton(
|
||||
modifier: Modifier = Modifier,
|
||||
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
|
||||
onClick: () -> Unit,
|
||||
content: @Composable () -> Unit = {}
|
||||
) {
|
||||
OutlinedButton(
|
||||
modifier = modifier.applyButtonSize(),
|
||||
interactionSource = interactionSource,
|
||||
onClick = onClick,
|
||||
border = BorderStroke(1.dp, LocalButtonColor.current),
|
||||
shape = LocalButtonShape.current,
|
||||
colors = ButtonDefaults.outlinedButtonColors(
|
||||
contentColor = LocalButtonColor.current,
|
||||
backgroundColor = Color.Unspecified
|
||||
)
|
||||
) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun TemporaryStateButton(
|
||||
content: @Composable (MutableInteractionSource, Boolean) -> Unit,
|
||||
) {
|
||||
val interactions = remember { MutableInteractionSource() }
|
||||
|
||||
var clicked by remember { mutableStateOf(false) }
|
||||
|
||||
content(interactions, clicked)
|
||||
|
||||
LaunchedEffectAsync {
|
||||
interactions.releases.collectLatest {
|
||||
clicked = true
|
||||
delay(2.seconds)
|
||||
clicked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun FilledButton(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
OutlinedButton(
|
||||
modifier = modifier.size(108.dp, 34.dp),
|
||||
onClick = onClick,
|
||||
shape = RoundedCornerShape(50),
|
||||
colors = ButtonDefaults.outlinedButtonColors(
|
||||
contentColor = MaterialTheme.colors.background,
|
||||
backgroundColor = LocalButtonColor.current
|
||||
)
|
||||
) {
|
||||
Text(text = text)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BorderlessButtonSecondary(
|
||||
text: String,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
BorderlessButton(
|
||||
text,
|
||||
contentColor = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium),
|
||||
onClick = onClick
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun BorderlessButton(
|
||||
text: String,
|
||||
modifier: Modifier = Modifier,
|
||||
contentDescription: GetString = GetString(text),
|
||||
fontSize: TextUnit = TextUnit.Unspecified,
|
||||
lineHeight: TextUnit = TextUnit.Unspecified,
|
||||
contentColor: Color = MaterialTheme.colors.onBackground,
|
||||
backgroundColor: Color = Color.Transparent,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
TextButton(
|
||||
onClick = onClick,
|
||||
modifier = modifier.contentDescription(contentDescription),
|
||||
shape = RoundedCornerShape(percent = 50),
|
||||
colors = ButtonDefaults.outlinedButtonColors(
|
||||
contentColor = contentColor,
|
||||
backgroundColor = backgroundColor
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = text,
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = fontSize,
|
||||
lineHeight = lineHeight,
|
||||
modifier = Modifier.padding(horizontal = 2.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private val MutableInteractionSource.releases
|
||||
get() = interactions.filter { it is PressInteraction.Release }
|
||||
|
||||
@Composable
|
||||
fun SmallButtons(content: @Composable () -> Unit) {
|
||||
CompositionLocalProvider(LocalButtonSize provides smallButton) { content() }
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun DestructiveButtons(content: @Composable () -> Unit) {
|
||||
CompositionLocalProvider(LocalButtonColor provides colorDestructive) { content() }
|
||||
}
|
@ -52,7 +52,6 @@ import kotlinx.coroutines.flow.emptyFlow
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.onboarding.Analyzer
|
||||
import org.thoughtcrime.securesms.ui.OutlineButton
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
typealias CameraPreview = androidx.camera.core.Preview
|
||||
@ -96,17 +95,18 @@ fun MaybeScanQrCode(
|
||||
)
|
||||
Spacer(modifier = Modifier.size(20.dp))
|
||||
OutlineButton(
|
||||
text = stringResource(R.string.sessionSettings),
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||
onClick = onClickSettings
|
||||
)
|
||||
) {
|
||||
Text(stringResource(R.string.sessionSettings))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
OutlineButton(
|
||||
text = stringResource(R.string.cameraGrantAccess),
|
||||
modifier = Modifier.align(Alignment.Center)
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
onClick = { cameraPermissionState.run { launchPermissionRequest() } }
|
||||
) {
|
||||
cameraPermissionState.run { launchPermissionRequest() }
|
||||
Text(stringResource(R.string.cameraGrantAccess))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -173,12 +173,12 @@ fun ScanQrCode(errors: Flow<String>, onScan: (String) -> Unit) {
|
||||
)
|
||||
|
||||
Box(
|
||||
Modifier
|
||||
.aspectRatio(1f)
|
||||
.padding(20.dp)
|
||||
.clip(shape = RoundedCornerShape(20.dp))
|
||||
.background(Color(0x33ffffff))
|
||||
.align(Alignment.Center)
|
||||
Modifier
|
||||
.aspectRatio(1f)
|
||||
.padding(20.dp)
|
||||
.clip(shape = RoundedCornerShape(20.dp))
|
||||
.background(Color(0x33ffffff))
|
||||
.align(Alignment.Center)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
package org.thoughtcrime.securesms.ui.components
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.scaleIn
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
@ -25,7 +29,8 @@ import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.LocalExtraColors
|
||||
import org.thoughtcrime.securesms.ui.LocalLightCell
|
||||
import org.thoughtcrime.securesms.ui.LocalOnLightCell
|
||||
import org.thoughtcrime.securesms.util.QRCodeUtilities
|
||||
|
||||
@Composable
|
||||
@ -36,7 +41,7 @@ fun QrImageCard(
|
||||
icon: Int = R.drawable.session_shield
|
||||
) {
|
||||
Card(
|
||||
backgroundColor = LocalExtraColors.current.lightCell,
|
||||
backgroundColor = LocalLightCell.current,
|
||||
elevation = 0.dp,
|
||||
modifier = modifier
|
||||
) { QrImage(string, contentDescription, icon) }
|
||||
@ -55,24 +60,37 @@ fun QrImage(string: String, contentDescription: String, icon: Int = R.drawable.s
|
||||
}
|
||||
}
|
||||
|
||||
Box {
|
||||
bitmap?.let {
|
||||
Image(
|
||||
bitmap = it.asImageBitmap(),
|
||||
contentDescription = contentDescription,
|
||||
colorFilter = ColorFilter.tint(LocalExtraColors.current.onLightCell)
|
||||
)
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1f)
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = bitmap != null,
|
||||
enter = scaleIn()
|
||||
) {
|
||||
bitmap?.let {
|
||||
Image(
|
||||
bitmap = it.asImageBitmap(),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.aspectRatio(1f),
|
||||
contentDescription = contentDescription,
|
||||
colorFilter = ColorFilter.tint(LocalOnLightCell.current)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Icon(
|
||||
painter = painterResource(id = icon),
|
||||
contentDescription = "",
|
||||
tint = LocalExtraColors.current.onLightCell,
|
||||
tint = LocalOnLightCell.current,
|
||||
modifier = Modifier
|
||||
.align(Alignment.Center)
|
||||
.width(46.dp)
|
||||
.height(56.dp)
|
||||
.background(color = LocalExtraColors.current.lightCell)
|
||||
.background(color = LocalLightCell.current)
|
||||
.padding(horizontal = 3.dp, vertical = 1.dp)
|
||||
)
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.LocalExtraColors
|
||||
import org.thoughtcrime.securesms.ui.LocalButtonColor
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
|
||||
|
||||
@ -31,7 +31,7 @@ fun SessionTabRow(pagerState: PagerState, titles: List<Int>) {
|
||||
TabRow(
|
||||
backgroundColor = Color.Unspecified,
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
contentColor = LocalExtraColors.current.prominentButtonColor,
|
||||
contentColor = LocalButtonColor.current,
|
||||
divider = { TabRowDefaults.Divider(color = MaterialTheme.colors.onPrimary.copy(alpha = TabRowDefaults.DividerOpacity)) },
|
||||
modifier = Modifier
|
||||
.height(48.dp)
|
||||
|
Loading…
x
Reference in New Issue
Block a user