mirror of
https://github.com/oxen-io/session-android.git
synced 2025-01-12 20:53:38 +00:00
Feature/compose cleanup (#1543)
* Moving color files * Moving theme classes into their own package * Only obtain new theme when required * UI Tweaks Using the proper color for danger as opposed to one hardcoded color Reusing BlackAlpha40 Using the right delete icon in settings * matching figma * Matching signature across buttons * Dialogs do not have a 'x' button by default * Updated typography Updated the typography in an composition local so it can be accessed from anyehere in compose and matching the figma declarations. * Centered text in control messages * Fixing new color access for action items * renaming spacing to be more general * Unifying dimensions and rectifying design inconsistencies Unifying spacing values and reusing common ones Identified spacing issues and inconsistencies in design and figma * Rounded corners for the new conversation sheet * Rounding sheets corners * Spacing fixes and UI consolidating Discussed with QA to make sure the 'new message' screen should indeed behave as the other screens and use disabled state instead of disappearing * Disappearing messages tweaks Re-using our new radio buttons in disappearing messages Tweaking UI to match designs * Cleaning up spaces * Migrating to Material3 * Fixing UI issues found * PR feedbacks --------- Co-authored-by: bemusementpark <bemusementpark>
This commit is contained in:
parent
c31e89a13d
commit
9e2b24f7b9
@ -381,7 +381,7 @@ dependencies {
|
||||
implementation "androidx.compose.ui:ui-tooling:$composeVersion"
|
||||
implementation "androidx.compose.runtime:runtime-livedata:$composeVersion"
|
||||
implementation "androidx.compose.foundation:foundation-layout:$composeVersion"
|
||||
implementation "androidx.compose.material:material:$composeVersion"
|
||||
implementation "androidx.compose.material3:material3:1.2.1"
|
||||
androidTestImplementation "androidx.compose.ui:ui-test-junit4-android:$composeVersion"
|
||||
debugImplementation "androidx.compose.ui:ui-test-manifest:$composeVersion"
|
||||
|
||||
|
@ -114,14 +114,14 @@ class SessionDialogBuilder(val context: Context) {
|
||||
options,
|
||||
) { dialog, it -> onSelect(it); dialog.dismiss() }
|
||||
|
||||
fun destructiveButton(
|
||||
fun dangerButton(
|
||||
@StringRes text: Int,
|
||||
@StringRes contentDescription: Int = text,
|
||||
listener: () -> Unit = {}
|
||||
) = button(
|
||||
text,
|
||||
contentDescription,
|
||||
R.style.Widget_Session_Button_Dialog_DestructiveText,
|
||||
R.style.Widget_Session_Button_Dialog_DangerText,
|
||||
) { listener() }
|
||||
|
||||
fun okButton(listener: (() -> Unit) = {}) = button(android.R.string.ok) { listener() }
|
||||
|
@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.components.menu
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.ColorRes
|
||||
import androidx.annotation.ColorInt
|
||||
|
||||
/**
|
||||
* Represents an action to be rendered
|
||||
@ -13,5 +13,5 @@ data class ActionItem(
|
||||
val action: Runnable,
|
||||
val contentDescription: Int? = null,
|
||||
val subtitle: ((Context) -> CharSequence?)? = null,
|
||||
@ColorRes val color: Int? = null,
|
||||
@ColorInt val color: Int? = null,
|
||||
)
|
||||
|
@ -78,7 +78,7 @@ class ContextMenuList(recyclerView: RecyclerView, onItemClick: () -> Unit) {
|
||||
|
||||
override fun bind(model: DisplayItem) {
|
||||
val item = model.item
|
||||
val color = item.color?.let { ContextCompat.getColor(context, it) }
|
||||
val color = item.color
|
||||
|
||||
if (item.iconRes > 0) {
|
||||
val typedValue = TypedValue()
|
||||
|
@ -14,7 +14,6 @@ import org.session.libsession.utilities.ExpirationUtil
|
||||
import org.session.libsession.utilities.SSKEnvironment.MessageExpirationManagerProtocol
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsession.utilities.getExpirationTypeDisplayValue
|
||||
import org.thoughtcrime.securesms.database.ThreadDatabase
|
||||
import org.thoughtcrime.securesms.database.model.MessageRecord
|
||||
import org.thoughtcrime.securesms.showSessionDialog
|
||||
import org.thoughtcrime.securesms.util.ConfigurationMessageUtilities
|
||||
@ -57,7 +56,7 @@ class DisappearingMessages @Inject constructor(
|
||||
context.getExpirationTypeDisplayValue(message.isNotDisappearAfterRead)
|
||||
)
|
||||
})
|
||||
destructiveButton(
|
||||
dangerButton(
|
||||
text = if (message.expiresIn == 0L) R.string.dialog_disappearing_messages_follow_setting_confirm else R.string.dialog_disappearing_messages_follow_setting_set,
|
||||
contentDescription = if (message.expiresIn == 0L) R.string.AccessibilityId_confirm else R.string.AccessibilityId_set_button
|
||||
) {
|
||||
|
@ -13,8 +13,8 @@ import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
fun State.toUiState() = UiState(
|
||||
cards = listOfNotNull(
|
||||
typeOptions()?.let { ExpiryOptionsCard(GetString(R.string.activity_disappearing_messages_delete_type), it) },
|
||||
timeOptions()?.let { ExpiryOptionsCard(GetString(R.string.activity_disappearing_messages_timer), it) }
|
||||
typeOptions()?.let { ExpiryOptionsCardData(GetString(R.string.activity_disappearing_messages_delete_type), it) },
|
||||
timeOptions()?.let { ExpiryOptionsCardData(GetString(R.string.activity_disappearing_messages_timer), it) }
|
||||
),
|
||||
showGroupFooter = isGroup && isNewConfigEnabled,
|
||||
showSetButton = isSelfAdmin
|
||||
|
@ -3,11 +3,13 @@ package org.thoughtcrime.securesms.conversation.disappearingmessages.ui
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -18,15 +20,15 @@ import androidx.compose.ui.unit.dp
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import org.thoughtcrime.securesms.ui.Callbacks
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.NoOpCallbacks
|
||||
import org.thoughtcrime.securesms.ui.OptionsCard
|
||||
import org.thoughtcrime.securesms.ui.RadioOption
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.components.SlimOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.extraSmall
|
||||
import org.thoughtcrime.securesms.ui.fadingEdges
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
|
||||
typealias ExpiryCallbacks = Callbacks<ExpiryMode>
|
||||
typealias ExpiryRadioOption = RadioOption<ExpiryMode>
|
||||
@ -39,26 +41,32 @@ fun DisappearingMessages(
|
||||
) {
|
||||
val scrollState = rememberScrollState()
|
||||
|
||||
Column(modifier = modifier.padding(horizontal = LocalDimensions.current.margin)) {
|
||||
Column(modifier = modifier.padding(horizontal = LocalDimensions.current.spacing)) {
|
||||
Box(modifier = Modifier.weight(1f)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(bottom = 20.dp)
|
||||
.padding(vertical = LocalDimensions.current.spacing)
|
||||
.verticalScroll(scrollState)
|
||||
.fadingEdges(scrollState),
|
||||
verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallItemSpacing)
|
||||
) {
|
||||
state.cards.forEach {
|
||||
OptionsCard(it, callbacks)
|
||||
state.cards.forEachIndexed { index, option ->
|
||||
OptionsCard(option, callbacks)
|
||||
|
||||
// add spacing if not the last item
|
||||
if(index != state.cards.lastIndex){
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.spacing))
|
||||
}
|
||||
}
|
||||
|
||||
if (state.showGroupFooter) Text(
|
||||
text = stringResource(R.string.activity_disappearing_messages_group_footer),
|
||||
style = extraSmall,
|
||||
style = LocalType.current.extraSmall,
|
||||
fontWeight = FontWeight(400),
|
||||
color = LocalColors.current.textSecondary,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = LocalDimensions.current.xsSpacing)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -68,7 +76,7 @@ fun DisappearingMessages(
|
||||
modifier = Modifier
|
||||
.contentDescription(R.string.AccessibilityId_set_button)
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(bottom = 20.dp),
|
||||
.padding(bottom = LocalDimensions.current.spacing),
|
||||
onClick = callbacks::onSetClick
|
||||
)
|
||||
}
|
||||
|
@ -10,9 +10,9 @@ import androidx.compose.ui.unit.dp
|
||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.ExpiryType
|
||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.State
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.color.Colors
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.ThemeColors
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
|
||||
@Preview(widthDp = 450, heightDp = 700)
|
||||
@Composable
|
||||
@ -51,7 +51,7 @@ class StatePreviewParameterProvider : PreviewParameterProvider<State> {
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewThemes(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
DisappearingMessages(
|
||||
|
@ -5,15 +5,15 @@ import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.RadioOption
|
||||
|
||||
typealias ExpiryOptionsCard = OptionsCard<ExpiryMode>
|
||||
typealias ExpiryOptionsCardData = OptionsCardData<ExpiryMode>
|
||||
|
||||
data class UiState(
|
||||
val cards: List<ExpiryOptionsCard> = emptyList(),
|
||||
val cards: List<ExpiryOptionsCardData> = emptyList(),
|
||||
val showGroupFooter: Boolean = false,
|
||||
val showSetButton: Boolean = true
|
||||
) {
|
||||
constructor(
|
||||
vararg cards: ExpiryOptionsCard,
|
||||
vararg cards: ExpiryOptionsCardData,
|
||||
showGroupFooter: Boolean = false,
|
||||
showSetButton: Boolean = true,
|
||||
): this(
|
||||
@ -23,7 +23,7 @@ data class UiState(
|
||||
)
|
||||
}
|
||||
|
||||
data class OptionsCard<T>(
|
||||
data class OptionsCardData<T>(
|
||||
val title: GetString,
|
||||
val options: List<RadioOption<T>>
|
||||
) {
|
||||
|
@ -7,8 +7,9 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
@ -21,23 +22,25 @@ import org.thoughtcrime.securesms.conversation.start.NullStartConversationDelega
|
||||
import org.thoughtcrime.securesms.conversation.start.StartConversationDelegate
|
||||
import org.thoughtcrime.securesms.ui.Divider
|
||||
import org.thoughtcrime.securesms.ui.ItemButton
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.color.Colors
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.ThemeColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.components.AppBar
|
||||
import org.thoughtcrime.securesms.ui.components.QrImage
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.small
|
||||
import org.thoughtcrime.securesms.ui.xl
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
|
||||
@Composable
|
||||
internal fun StartConversationScreen(
|
||||
accountId: String,
|
||||
delegate: StartConversationDelegate
|
||||
) {
|
||||
Column(modifier = Modifier.background(LocalColors.current.backgroundSecondary)) {
|
||||
Column(modifier = Modifier.background(
|
||||
LocalColors.current.backgroundSecondary,
|
||||
shape = MaterialTheme.shapes.small
|
||||
)) {
|
||||
AppBar(stringResource(R.string.dialog_start_conversation_title), onClose = delegate::onDialogClosePressed)
|
||||
Surface(
|
||||
modifier = Modifier.nestedScroll(rememberNestedScrollInteropConnection()),
|
||||
@ -74,18 +77,18 @@ internal fun StartConversationScreen(
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = LocalDimensions.current.margin)
|
||||
.padding(top = LocalDimensions.current.itemSpacing)
|
||||
.padding(bottom = LocalDimensions.current.margin)
|
||||
.padding(horizontal = LocalDimensions.current.spacing)
|
||||
.padding(top = LocalDimensions.current.spacing)
|
||||
.padding(bottom = LocalDimensions.current.spacing)
|
||||
) {
|
||||
Text(stringResource(R.string.accountIdYours), style = xl)
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xxxsItemSpacing))
|
||||
Text(stringResource(R.string.accountIdYours), style = LocalType.current.xl)
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xxsSpacing))
|
||||
Text(
|
||||
text = stringResource(R.string.qrYoursDescription),
|
||||
color = LocalColors.current.textSecondary,
|
||||
style = small
|
||||
style = LocalType.current.small
|
||||
)
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallItemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallSpacing))
|
||||
QrImage(
|
||||
string = accountId,
|
||||
Modifier.contentDescription(R.string.AccessibilityId_qr_code),
|
||||
@ -100,7 +103,7 @@ internal fun StartConversationScreen(
|
||||
@Preview
|
||||
@Composable
|
||||
private fun PreviewStartConversationScreen(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
StartConversationScreen(
|
||||
|
@ -8,23 +8,23 @@ import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.base
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.components.AppBar
|
||||
import org.thoughtcrime.securesms.ui.components.SlimOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.components.SlimOutlineCopyButton
|
||||
import org.thoughtcrime.securesms.ui.components.border
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.small
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
|
||||
@Composable
|
||||
internal fun InviteFriend(
|
||||
@ -34,10 +34,14 @@ internal fun InviteFriend(
|
||||
copyPublicKey: () -> Unit = {},
|
||||
sendInvitation: () -> Unit = {},
|
||||
) {
|
||||
Column(modifier = Modifier.background(LocalColors.current.backgroundSecondary)) {
|
||||
Column(modifier = Modifier.background(
|
||||
LocalColors.current.backgroundSecondary,
|
||||
shape = MaterialTheme.shapes.small
|
||||
)) {
|
||||
AppBar(stringResource(R.string.invite_a_friend), onBack = onBack, onClose = onClose)
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.itemSpacing),
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.spacing)
|
||||
.padding(top = LocalDimensions.current.spacing),
|
||||
) {
|
||||
Text(
|
||||
accountId,
|
||||
@ -45,24 +49,24 @@ internal fun InviteFriend(
|
||||
.contentDescription(R.string.AccessibilityId_account_id)
|
||||
.fillMaxWidth()
|
||||
.border()
|
||||
.padding(LocalDimensions.current.smallMargin),
|
||||
.padding(LocalDimensions.current.spacing),
|
||||
textAlign = TextAlign.Center,
|
||||
style = base
|
||||
style = LocalType.current.base
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xsItemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xsSpacing))
|
||||
|
||||
Text(
|
||||
stringResource(R.string.invite_your_friend_to_chat_with_you_on_session_by_sharing_your_account_id_with_them),
|
||||
textAlign = TextAlign.Center,
|
||||
style = small,
|
||||
style = LocalType.current.small,
|
||||
color = LocalColors.current.textSecondary,
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.smallItemSpacing)
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.smallSpacing)
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallItemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallSpacing))
|
||||
|
||||
Row(horizontalArrangement = spacedBy(LocalDimensions.current.smallItemSpacing)) {
|
||||
Row(horizontalArrangement = spacedBy(LocalDimensions.current.smallSpacing)) {
|
||||
SlimOutlineButton(
|
||||
stringResource(R.string.share),
|
||||
modifier = Modifier
|
||||
|
@ -3,17 +3,19 @@ package org.thoughtcrime.securesms.conversation.start.newmessage
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -23,12 +25,13 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.emptyFlow
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.onboarding.ui.ContinuePrimaryOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.LoadingArcOr
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.color.Colors
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.ThemeColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.components.AppBar
|
||||
import org.thoughtcrime.securesms.ui.components.BorderlessButtonWithIcon
|
||||
import org.thoughtcrime.securesms.ui.components.MaybeScanQrCode
|
||||
@ -36,7 +39,7 @@ import org.thoughtcrime.securesms.ui.components.PrimaryOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.components.SessionOutlinedTextField
|
||||
import org.thoughtcrime.securesms.ui.components.SessionTabRow
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.small
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
|
||||
private val TITLES = listOf(R.string.enter_account_id, R.string.qrScan)
|
||||
|
||||
@ -52,7 +55,10 @@ internal fun NewMessage(
|
||||
) {
|
||||
val pagerState = rememberPagerState { TITLES.size }
|
||||
|
||||
Column(modifier = Modifier.background(LocalColors.current.backgroundSecondary)) {
|
||||
Column(modifier = Modifier.background(
|
||||
LocalColors.current.backgroundSecondary,
|
||||
shape = MaterialTheme.shapes.small
|
||||
)) {
|
||||
AppBar(stringResource(R.string.messageNew), onClose = onClose, onBack = onBack)
|
||||
SessionTabRow(pagerState, TITLES)
|
||||
HorizontalPager(pagerState) {
|
||||
@ -70,7 +76,6 @@ private fun EnterAccountId(
|
||||
callbacks: Callbacks,
|
||||
onHelp: () -> Unit = {}
|
||||
) {
|
||||
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
@ -78,14 +83,13 @@ private fun EnterAccountId(
|
||||
.imePadding()
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.xxsMargin, vertical = LocalDimensions.current.xsMargin),
|
||||
modifier = Modifier.padding(vertical = LocalDimensions.current.spacing),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.xsMargin)
|
||||
) {
|
||||
SessionOutlinedTextField(
|
||||
text = state.newMessageIdOrOns,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = LocalDimensions.current.smallMargin),
|
||||
.padding(horizontal = LocalDimensions.current.spacing),
|
||||
contentDescription = "Session id input box",
|
||||
placeholder = stringResource(R.string.accountIdOrOnsEnter),
|
||||
onChange = callbacks::onChange,
|
||||
@ -94,31 +98,36 @@ private fun EnterAccountId(
|
||||
isTextErrorColor = state.isTextErrorColor
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xxxsSpacing))
|
||||
|
||||
BorderlessButtonWithIcon(
|
||||
text = stringResource(R.string.messageNewDescription),
|
||||
modifier = Modifier
|
||||
.contentDescription(R.string.AccessibilityId_help_desk_link)
|
||||
.padding(horizontal = LocalDimensions.current.margin)
|
||||
.padding(horizontal = LocalDimensions.current.mediumSpacing)
|
||||
.fillMaxWidth(),
|
||||
style = small,
|
||||
style = LocalType.current.small,
|
||||
color = LocalColors.current.textSecondary,
|
||||
iconRes = R.drawable.ic_circle_question_mark,
|
||||
onClick = onHelp
|
||||
)
|
||||
}
|
||||
|
||||
AnimatedVisibility(state.isNextButtonVisible) {
|
||||
PrimaryOutlineButton(
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(horizontal = LocalDimensions.current.largeMargin)
|
||||
.fillMaxWidth()
|
||||
.contentDescription(R.string.next),
|
||||
onClick = callbacks::onContinue
|
||||
) {
|
||||
LoadingArcOr(state.loading) {
|
||||
Text(stringResource(R.string.next))
|
||||
}
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallSpacing))
|
||||
Spacer(Modifier.weight(2f))
|
||||
|
||||
PrimaryOutlineButton(
|
||||
modifier = Modifier
|
||||
.align(Alignment.CenterHorizontally)
|
||||
.padding(horizontal = LocalDimensions.current.xlargeSpacing)
|
||||
.padding(bottom = LocalDimensions.current.smallSpacing)
|
||||
.fillMaxWidth()
|
||||
.contentDescription(R.string.next),
|
||||
enabled = state.isNextButtonEnabled,
|
||||
onClick = callbacks::onContinue
|
||||
) {
|
||||
LoadingArcOr(state.loading) {
|
||||
Text(stringResource(R.string.next))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -127,7 +136,7 @@ private fun EnterAccountId(
|
||||
@Preview
|
||||
@Composable
|
||||
private fun PreviewNewMessage(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
NewMessage(State("z"))
|
||||
|
@ -6,7 +6,6 @@ import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.TimeoutCancellationException
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@ -22,8 +21,6 @@ import org.session.libsignal.utilities.timeout
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import java.util.concurrent.TimeoutException
|
||||
import javax.inject.Inject
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@HiltViewModel
|
||||
internal class NewMessageViewModel @Inject constructor(
|
||||
@ -112,7 +109,7 @@ internal data class State(
|
||||
val error: GetString? = null,
|
||||
val loading: Boolean = false
|
||||
) {
|
||||
val isNextButtonVisible: Boolean get() = newMessageIdOrOns.isNotBlank()
|
||||
val isNextButtonEnabled: Boolean get() = newMessageIdOrOns.isNotBlank()
|
||||
}
|
||||
|
||||
internal data class Success(val publicKey: String)
|
||||
|
@ -1120,7 +1120,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
showSessionDialog {
|
||||
title(R.string.RecipientPreferenceActivity_block_this_contact_question)
|
||||
text(R.string.RecipientPreferenceActivity_you_will_no_longer_receive_messages_and_calls_from_this_contact)
|
||||
destructiveButton(R.string.RecipientPreferenceActivity_block, R.string.AccessibilityId_block_confirm) {
|
||||
dangerButton(R.string.RecipientPreferenceActivity_block, R.string.AccessibilityId_block_confirm) {
|
||||
viewModel.block()
|
||||
if (deleteThread) {
|
||||
viewModel.deleteThread()
|
||||
@ -1163,7 +1163,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
showSessionDialog {
|
||||
title(R.string.ConversationActivity_unblock_this_contact_question)
|
||||
text(R.string.ConversationActivity_you_will_once_again_be_able_to_receive_messages_and_calls_from_this_contact)
|
||||
destructiveButton(
|
||||
dangerButton(
|
||||
R.string.ConversationActivity_unblock,
|
||||
R.string.AccessibilityId_block_confirm
|
||||
) { viewModel.unblock() }
|
||||
|
@ -545,7 +545,8 @@ class ConversationReactionOverlay : FrameLayout {
|
||||
}
|
||||
// Delete message
|
||||
if (userCanDeleteSelectedItems(context, message, openGroup, userPublicKey, blindedPublicKey)) {
|
||||
items += ActionItem(R.attr.menu_trash_icon, R.string.delete, { handleActionItemClicked(Action.DELETE) }, R.string.AccessibilityId_delete_message, message.subtitle, R.color.destructive)
|
||||
items += ActionItem(R.attr.menu_trash_icon, R.string.delete, { handleActionItemClicked(Action.DELETE) },
|
||||
R.string.AccessibilityId_delete_message, message.subtitle, ThemeUtil.getThemedColor(context, R.attr.danger))
|
||||
}
|
||||
// Ban user
|
||||
if (userCanBanSelectedUsers(context, message, openGroup, userPublicKey, blindedPublicKey)) {
|
||||
|
@ -27,9 +27,9 @@ import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
@ -63,20 +63,19 @@ import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
|
||||
import org.thoughtcrime.securesms.ui.Divider
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.HorizontalPagerIndicator
|
||||
import org.thoughtcrime.securesms.ui.ItemButton
|
||||
import org.thoughtcrime.securesms.ui.LargeItemButton
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.TitledText
|
||||
import org.thoughtcrime.securesms.ui.base
|
||||
import org.thoughtcrime.securesms.ui.baseBold
|
||||
import org.thoughtcrime.securesms.ui.baseMonospace
|
||||
import org.thoughtcrime.securesms.ui.color.Colors
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.color.blackAlpha40
|
||||
import org.thoughtcrime.securesms.ui.color.destructiveButtonColors
|
||||
import org.thoughtcrime.securesms.ui.theme.ThemeColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.blackAlpha40
|
||||
import org.thoughtcrime.securesms.ui.theme.dangerButtonColors
|
||||
import org.thoughtcrime.securesms.ui.setComposeContent
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.ui.theme.bold
|
||||
import org.thoughtcrime.securesms.ui.theme.monospace
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@ -152,12 +151,12 @@ fun MessageDetails(
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(vertical = LocalDimensions.current.smallItemSpacing),
|
||||
verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallItemSpacing)
|
||||
.padding(vertical = LocalDimensions.current.smallSpacing),
|
||||
verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallSpacing)
|
||||
) {
|
||||
state.record?.let { message ->
|
||||
AndroidView(
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.margin),
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.spacing),
|
||||
factory = {
|
||||
ViewVisibleMessageContentBinding.inflate(LayoutInflater.from(it)).mainContainerConstraint.apply {
|
||||
bind(
|
||||
@ -193,7 +192,7 @@ fun CellMetadata(
|
||||
state.apply {
|
||||
if (listOfNotNull(sent, received, error, senderInfo).isEmpty()) return
|
||||
CellWithPaddingAndMargin {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallItemSpacing)) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallSpacing)) {
|
||||
TitledText(sent)
|
||||
TitledText(received)
|
||||
TitledErrorText(error)
|
||||
@ -237,7 +236,7 @@ fun CellButtons(
|
||||
LargeItemButton(
|
||||
R.string.delete,
|
||||
R.drawable.ic_message_details__trash,
|
||||
colors = destructiveButtonColors(),
|
||||
colors = dangerButtonColors(),
|
||||
onClick = onDelete
|
||||
)
|
||||
}
|
||||
@ -251,7 +250,7 @@ fun Carousel(attachments: List<Attachment>, onClick: (Int) -> Unit) {
|
||||
|
||||
val pagerState = rememberPagerState { attachments.size }
|
||||
|
||||
Column(verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallItemSpacing)) {
|
||||
Column(verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallSpacing)) {
|
||||
Row {
|
||||
CarouselPrevButton(pagerState)
|
||||
Box(modifier = Modifier.weight(1f)) {
|
||||
@ -260,7 +259,7 @@ fun Carousel(attachments: List<Attachment>, onClick: (Int) -> Unit) {
|
||||
ExpandButton(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomEnd)
|
||||
.padding(LocalDimensions.current.xxsItemSpacing)
|
||||
.padding(LocalDimensions.current.xxsSpacing)
|
||||
) { onClick(pagerState.currentPage) }
|
||||
}
|
||||
CarouselNextButton(pagerState)
|
||||
@ -313,7 +312,7 @@ fun ExpandButton(modifier: Modifier = Modifier, onClick: () -> Unit) {
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewMessageDetails(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
MessageDetails(
|
||||
@ -340,8 +339,8 @@ fun FileDetails(fileDetails: List<TitledText>) {
|
||||
|
||||
Cell {
|
||||
FlowRow(
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.xsItemSpacing, vertical = LocalDimensions.current.itemSpacing),
|
||||
verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallItemSpacing)
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.xsSpacing, vertical = LocalDimensions.current.spacing),
|
||||
verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallSpacing)
|
||||
) {
|
||||
fileDetails.forEach {
|
||||
BoxWithConstraints {
|
||||
@ -349,7 +348,7 @@ fun FileDetails(fileDetails: List<TitledText>) {
|
||||
it,
|
||||
modifier = Modifier
|
||||
.widthIn(min = maxWidth.div(2))
|
||||
.padding(horizontal = LocalDimensions.current.xsItemSpacing)
|
||||
.padding(horizontal = LocalDimensions.current.xsSpacing)
|
||||
.width(IntrinsicSize.Max)
|
||||
)
|
||||
}
|
||||
@ -362,7 +361,7 @@ fun FileDetails(fileDetails: List<TitledText>) {
|
||||
fun TitledErrorText(titledText: TitledText?) {
|
||||
TitledText(
|
||||
titledText,
|
||||
style = base,
|
||||
style = LocalType.current.base,
|
||||
color = LocalColors.current.danger
|
||||
)
|
||||
}
|
||||
@ -371,7 +370,7 @@ fun TitledErrorText(titledText: TitledText?) {
|
||||
fun TitledMonospaceText(titledText: TitledText?) {
|
||||
TitledText(
|
||||
titledText,
|
||||
style = baseMonospace
|
||||
style = LocalType.current.base.monospace()
|
||||
)
|
||||
}
|
||||
|
||||
@ -379,7 +378,7 @@ fun TitledMonospaceText(titledText: TitledText?) {
|
||||
fun TitledText(
|
||||
titledText: TitledText?,
|
||||
modifier: Modifier = Modifier,
|
||||
style: TextStyle = base,
|
||||
style: TextStyle = LocalType.current.base,
|
||||
color: Color = Color.Unspecified
|
||||
) {
|
||||
titledText?.apply {
|
||||
@ -396,8 +395,8 @@ fun TitledText(
|
||||
|
||||
@Composable
|
||||
fun TitledView(title: GetString, modifier: Modifier = Modifier, content: @Composable () -> Unit) {
|
||||
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.xxxsItemSpacing)) {
|
||||
Text(title.string(), style = baseBold)
|
||||
Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.xxxsSpacing)) {
|
||||
Text(title.string(), style = LocalType.current.base.bold())
|
||||
content()
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,7 @@ import org.session.libsession.messaging.contacts.Contact.ContactContext
|
||||
import org.session.libsession.messaging.open_groups.OpenGroupApi
|
||||
import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment
|
||||
import org.session.libsession.utilities.Address
|
||||
import org.session.libsession.utilities.ThemeUtil.getThemedColor
|
||||
import org.session.libsession.utilities.ViewUtil
|
||||
import org.session.libsession.utilities.getColorFromAttr
|
||||
import org.session.libsession.utilities.modifyLayoutParams
|
||||
@ -382,7 +383,7 @@ class VisibleMessageView : FrameLayout {
|
||||
private fun getMessageStatusInfo(message: MessageRecord): MessageStatusInfo = when {
|
||||
message.isFailed ->
|
||||
MessageStatusInfo(R.drawable.ic_delivery_status_failed,
|
||||
resources.getColor(R.color.destructive, context.theme),
|
||||
getThemedColor(context, R.attr.danger),
|
||||
R.string.delivery_status_failed
|
||||
)
|
||||
message.isSyncFailed ->
|
||||
|
@ -15,6 +15,7 @@ import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import network.loki.messenger.R
|
||||
import network.loki.messenger.databinding.ViewConversationBinding
|
||||
import org.session.libsession.utilities.ThemeUtil
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.thoughtcrime.securesms.conversation.v2.utilities.MentionUtilities.highlightMentions
|
||||
import org.thoughtcrime.securesms.database.RecipientDatabase.NOTIFY_TYPE_ALL
|
||||
@ -67,7 +68,7 @@ class ConversationView : LinearLayout {
|
||||
}
|
||||
val unreadCount = thread.unreadCount
|
||||
if (thread.recipient.isBlocked) {
|
||||
binding.accentView.setBackgroundResource(R.color.destructive)
|
||||
binding.accentView.setBackgroundColor(ThemeUtil.getThemedColor(context, R.attr.danger))
|
||||
binding.accentView.visibility = View.VISIBLE
|
||||
} else {
|
||||
val accentColor = context.getAccentColor()
|
||||
@ -120,7 +121,7 @@ class ConversationView : LinearLayout {
|
||||
!thread.isOutgoing -> binding.statusIndicatorImageView.visibility = View.GONE
|
||||
thread.isFailed -> {
|
||||
val drawable = ContextCompat.getDrawable(context, R.drawable.ic_error)?.mutate()
|
||||
drawable?.setTint(ContextCompat.getColor(context, R.color.destructive))
|
||||
drawable?.setTint(ThemeUtil.getThemedColor(context, R.attr.danger))
|
||||
binding.statusIndicatorImageView.setImageDrawable(drawable)
|
||||
}
|
||||
thread.isPending -> binding.statusIndicatorImageView.setImageResource(R.drawable.ic_circle_dot_dot_dot)
|
||||
|
@ -3,8 +3,8 @@ package org.thoughtcrime.securesms.home
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -14,24 +14,22 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
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.ui.Divider
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
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.h4
|
||||
import org.thoughtcrime.securesms.ui.h8
|
||||
import org.thoughtcrime.securesms.ui.small
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.ThemeColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
|
||||
@Composable
|
||||
internal fun EmptyView(newAccount: Boolean) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.padding(horizontal = LocalDimensions.current.homeEmptyViewMargin)
|
||||
.padding(horizontal = 50.dp)
|
||||
) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Icon(
|
||||
@ -42,27 +40,27 @@ internal fun EmptyView(newAccount: Boolean) {
|
||||
if (newAccount) {
|
||||
Text(
|
||||
stringResource(R.string.onboardingAccountCreated),
|
||||
style = h4,
|
||||
style = LocalType.current.h4,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Text(
|
||||
stringResource(R.string.welcome_to_session),
|
||||
style = base,
|
||||
style = LocalType.current.base,
|
||||
color = LocalColors.current.primary,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
}
|
||||
|
||||
Divider(modifier = Modifier.padding(vertical = LocalDimensions.current.xsMargin))
|
||||
Divider(modifier = Modifier.padding(vertical = LocalDimensions.current.smallSpacing))
|
||||
|
||||
Text(
|
||||
stringResource(R.string.conversationsNone),
|
||||
style = h8,
|
||||
style = LocalType.current.h8,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.padding(bottom = LocalDimensions.current.xsItemSpacing))
|
||||
modifier = Modifier.padding(bottom = LocalDimensions.current.xsSpacing))
|
||||
Text(
|
||||
stringResource(R.string.onboardingHitThePlusButton),
|
||||
style = small,
|
||||
style = LocalType.current.small,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(2f))
|
||||
@ -72,7 +70,7 @@ internal fun EmptyView(newAccount: Boolean) {
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewEmptyView(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
EmptyView(newAccount = false)
|
||||
@ -82,7 +80,7 @@ fun PreviewEmptyView(
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewEmptyViewNew(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
EmptyView(newAccount = true)
|
||||
|
@ -10,7 +10,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.requiredWidth
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -18,16 +18,15 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.SessionShieldIcon
|
||||
import org.thoughtcrime.securesms.ui.color.Colors
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.ThemeColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.components.SlimPrimaryOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.h8
|
||||
import org.thoughtcrime.securesms.ui.small
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
|
||||
@Composable
|
||||
internal fun SeedReminder(startRecoveryPasswordActivity: () -> Unit) {
|
||||
@ -43,25 +42,25 @@ internal fun SeedReminder(startRecoveryPasswordActivity: () -> Unit) {
|
||||
Modifier
|
||||
.background(LocalColors.current.backgroundSecondary)
|
||||
.padding(
|
||||
horizontal = LocalDimensions.current.smallMargin,
|
||||
vertical = LocalDimensions.current.xsMargin
|
||||
horizontal = LocalDimensions.current.spacing,
|
||||
vertical = LocalDimensions.current.smallSpacing
|
||||
)
|
||||
) {
|
||||
Column(Modifier.weight(1f)) {
|
||||
Row {
|
||||
Text(
|
||||
stringResource(R.string.save_your_recovery_password),
|
||||
style = h8
|
||||
style = LocalType.current.h8
|
||||
)
|
||||
Spacer(Modifier.requiredWidth(LocalDimensions.current.xxsItemSpacing))
|
||||
Spacer(Modifier.requiredWidth(LocalDimensions.current.xxsSpacing))
|
||||
SessionShieldIcon()
|
||||
}
|
||||
Text(
|
||||
stringResource(R.string.save_your_recovery_password_to_make_sure_you_don_t_lose_access_to_your_account),
|
||||
style = small
|
||||
style = LocalType.current.small
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.width(LocalDimensions.current.xxsMargin))
|
||||
Spacer(Modifier.width(LocalDimensions.current.xsSpacing))
|
||||
SlimPrimaryOutlineButton(
|
||||
text = stringResource(R.string.continue_2),
|
||||
modifier = Modifier
|
||||
@ -76,7 +75,7 @@ internal fun SeedReminder(startRecoveryPasswordActivity: () -> Unit) {
|
||||
@Preview
|
||||
@Composable
|
||||
private fun PreviewSeedReminder(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
SeedReminder {}
|
||||
|
@ -10,6 +10,7 @@ import android.view.ViewGroup
|
||||
import android.widget.PopupMenu
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.ThemeUtil
|
||||
import org.thoughtcrime.securesms.database.CursorRecyclerViewAdapter
|
||||
import org.thoughtcrime.securesms.database.model.ThreadRecord
|
||||
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
|
||||
@ -60,8 +61,9 @@ class MessageRequestsAdapter(
|
||||
for (i in 0 until popupMenu.menu.size()) {
|
||||
val item = popupMenu.menu.getItem(i)
|
||||
val s = SpannableString(item.title)
|
||||
s.setSpan(ForegroundColorSpan(context.getColor(R.color.destructive)), 0, s.length, 0)
|
||||
item.iconTintList = ColorStateList.valueOf(context.getColor(R.color.destructive))
|
||||
val danger = ThemeUtil.getThemedColor(context, R.attr.danger)
|
||||
s.setSpan(ForegroundColorSpan(danger), 0, s.length, 0)
|
||||
item.iconTintList = ColorStateList.valueOf(danger)
|
||||
item.title = s
|
||||
}
|
||||
popupMenu.setForceShowIcon(true)
|
||||
|
@ -7,7 +7,7 @@ import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.AlertDialog
|
||||
import org.thoughtcrime.securesms.ui.DialogButtonModel
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
|
||||
@Composable
|
||||
fun OnboardingBackPressAlertDialog(
|
||||
|
@ -5,6 +5,7 @@ import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
@ -16,10 +17,8 @@ import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@ -40,23 +39,22 @@ import network.loki.messenger.R
|
||||
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
|
||||
import org.thoughtcrime.securesms.ui.color.Colors
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.components.BorderlessHtmlButton
|
||||
import org.thoughtcrime.securesms.ui.components.PrimaryFillButton
|
||||
import org.thoughtcrime.securesms.ui.components.PrimaryOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.h4
|
||||
import org.thoughtcrime.securesms.ui.large
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.ThemeColors
|
||||
import kotlin.time.Duration.Companion.milliseconds
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun PreviewLandingScreen(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
LandingScreen({}, {}, {}, {})
|
||||
@ -80,6 +78,7 @@ internal fun LandingScreen(
|
||||
onDismissRequest = { isUrlDialogVisible = false },
|
||||
title = stringResource(R.string.urlOpen),
|
||||
text = stringResource(R.string.urlOpenBrowser),
|
||||
showCloseButton = true, // display the 'x' button
|
||||
buttons = listOf(
|
||||
DialogButtonModel(
|
||||
text = GetString(R.string.activity_landing_terms_of_service),
|
||||
@ -107,24 +106,24 @@ internal fun LandingScreen(
|
||||
Column {
|
||||
Column(modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(horizontal = LocalDimensions.current.onboardingMargin)
|
||||
.padding(horizontal = LocalDimensions.current.mediumSpacing)
|
||||
) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Text(
|
||||
stringResource(R.string.onboardingBubblePrivacyInYourPocket),
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||
style = h4,
|
||||
style = LocalType.current.h4,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.itemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.spacing))
|
||||
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
modifier = Modifier
|
||||
.heightIn(min = LocalDimensions.current.minScrollableViewHeight)
|
||||
.heightIn(min = 200.dp)
|
||||
.fillMaxWidth()
|
||||
.weight(3f),
|
||||
verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallItemSpacing)
|
||||
verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallSpacing)
|
||||
) {
|
||||
items(
|
||||
MESSAGES.take(count),
|
||||
@ -140,7 +139,7 @@ internal fun LandingScreen(
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
}
|
||||
|
||||
Column(modifier = Modifier.padding(horizontal = LocalDimensions.current.largeMargin)) {
|
||||
Column(modifier = Modifier.padding(horizontal = LocalDimensions.current.xlargeSpacing)) {
|
||||
PrimaryFillButton(
|
||||
text = stringResource(R.string.onboardingAccountCreate),
|
||||
modifier = Modifier
|
||||
@ -149,7 +148,7 @@ internal fun LandingScreen(
|
||||
.contentDescription(R.string.AccessibilityId_create_account_button),
|
||||
onClick = createAccount
|
||||
)
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallItemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallSpacing))
|
||||
PrimaryOutlineButton(
|
||||
stringResource(R.string.onboardingAccountExists),
|
||||
modifier = Modifier
|
||||
@ -166,7 +165,7 @@ internal fun LandingScreen(
|
||||
.contentDescription(R.string.AccessibilityId_open_url),
|
||||
onClick = { isUrlDialogVisible = true }
|
||||
)
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xxsItemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xxsSpacing))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -195,7 +194,7 @@ private fun MessageText(text: String, isOutgoing: Boolean, modifier: Modifier) {
|
||||
Box(modifier = modifier then Modifier.fillMaxWidth()) {
|
||||
MessageText(
|
||||
text,
|
||||
color = if (isOutgoing) LocalColors.current.backgroundBubbleSent else LocalColors.current.backgroundBubbleReceived,
|
||||
color = if (isOutgoing) LocalColors.current.primary else LocalColors.current.backgroundBubbleReceived,
|
||||
textColor = if (isOutgoing) LocalColors.current.textBubbleSent else LocalColors.current.textBubbleReceived,
|
||||
modifier = Modifier.align(if (isOutgoing) Alignment.TopEnd else Alignment.TopStart)
|
||||
)
|
||||
@ -209,19 +208,17 @@ private fun MessageText(
|
||||
modifier: Modifier = Modifier,
|
||||
textColor: Color = Color.Unspecified
|
||||
) {
|
||||
Card(
|
||||
modifier = modifier.fillMaxWidth(0.666f),
|
||||
shape = MaterialTheme.shapes.small,
|
||||
backgroundColor = color,
|
||||
elevation = 0.dp
|
||||
Box(
|
||||
modifier = modifier.fillMaxWidth(0.666f)
|
||||
.background(color = color, shape = MaterialTheme.shapes.small)
|
||||
) {
|
||||
Text(
|
||||
text,
|
||||
style = large,
|
||||
style = LocalType.current.large,
|
||||
color = textColor,
|
||||
modifier = Modifier.padding(
|
||||
horizontal = LocalDimensions.current.smallItemSpacing,
|
||||
vertical = LocalDimensions.current.xsItemSpacing
|
||||
horizontal = LocalDimensions.current.smallSpacing,
|
||||
vertical = LocalDimensions.current.xsSpacing
|
||||
)
|
||||
)
|
||||
}
|
||||
|
@ -13,8 +13,8 @@ import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -24,13 +24,12 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.onboarding.ui.ContinuePrimaryOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.base
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.components.MaybeScanQrCode
|
||||
import org.thoughtcrime.securesms.ui.components.SessionOutlinedTextField
|
||||
import org.thoughtcrime.securesms.ui.components.SessionTabRow
|
||||
import org.thoughtcrime.securesms.ui.h4
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
|
||||
private val TITLES = listOf(R.string.sessionRecoveryPassword, R.string.qrScan)
|
||||
|
||||
@ -75,29 +74,29 @@ private fun RecoveryPassword(state: State, onChange: (String) -> Unit = {}, onCo
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
Spacer(Modifier.weight(1f))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallItemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallSpacing))
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.largeMargin)
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.mediumSpacing)
|
||||
) {
|
||||
Row {
|
||||
Text(
|
||||
text = stringResource(R.string.sessionRecoveryPassword),
|
||||
style = h4
|
||||
style = LocalType.current.h4
|
||||
)
|
||||
Spacer(Modifier.width(LocalDimensions.current.xxsItemSpacing))
|
||||
Spacer(Modifier.width(LocalDimensions.current.xxsSpacing))
|
||||
Icon(
|
||||
modifier = Modifier.align(Alignment.CenterVertically),
|
||||
painter = painterResource(id = R.drawable.ic_shield_outline),
|
||||
contentDescription = null,
|
||||
)
|
||||
}
|
||||
Spacer(Modifier.height(LocalDimensions.current.smallItemSpacing))
|
||||
Spacer(Modifier.height(LocalDimensions.current.smallSpacing))
|
||||
Text(
|
||||
stringResource(R.string.activity_link_enter_your_recovery_password_to_load_your_account_if_you_haven_t_saved_it_you_can_find_it_in_your_app_settings),
|
||||
style = base
|
||||
style = LocalType.current.base
|
||||
)
|
||||
Spacer(Modifier.height(LocalDimensions.current.itemSpacing))
|
||||
Spacer(Modifier.height(LocalDimensions.current.spacing))
|
||||
SessionOutlinedTextField(
|
||||
text = state.recoveryPhrase,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@ -110,7 +109,7 @@ private fun RecoveryPassword(state: State, onChange: (String) -> Unit = {}, onCo
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallItemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallSpacing))
|
||||
Spacer(Modifier.weight(2f))
|
||||
|
||||
ContinuePrimaryOutlineButton(modifier = Modifier.align(Alignment.CenterHorizontally), onContinue)
|
||||
|
@ -3,17 +3,16 @@ package org.thoughtcrime.securesms.onboarding.loading
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.ProgressArc
|
||||
import org.thoughtcrime.securesms.ui.base
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.h7
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
|
||||
@Composable
|
||||
internal fun LoadingScreen(progress: Float) {
|
||||
@ -25,12 +24,12 @@ internal fun LoadingScreen(progress: Float) {
|
||||
)
|
||||
Text(
|
||||
stringResource(R.string.waitOneMoment),
|
||||
style = h7
|
||||
style = LocalType.current.h7
|
||||
)
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xxxsItemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xxxsSpacing))
|
||||
Text(
|
||||
stringResource(R.string.loadAccountProgressMessage),
|
||||
style = base
|
||||
style = LocalType.current.base
|
||||
)
|
||||
Spacer(modifier = Modifier.weight(2f))
|
||||
}
|
||||
|
@ -10,7 +10,7 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -22,22 +22,15 @@ import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.onboarding.OnboardingBackPressAlertDialog
|
||||
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
|
||||
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.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.ThemeColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.components.CircularProgressIndicator
|
||||
import org.thoughtcrime.securesms.ui.components.RadioButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.h4
|
||||
import org.thoughtcrime.securesms.ui.h8
|
||||
import org.thoughtcrime.securesms.ui.h9
|
||||
import org.thoughtcrime.securesms.ui.small
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
|
||||
@Composable
|
||||
internal fun MessageNotificationsScreen(
|
||||
@ -63,11 +56,11 @@ internal fun MessageNotificationsScreen(
|
||||
Column {
|
||||
Spacer(Modifier.weight(1f))
|
||||
|
||||
Column(modifier = Modifier.padding(horizontal = LocalDimensions.current.onboardingMargin)) {
|
||||
Text(stringResource(R.string.notificationsMessage), style = h4)
|
||||
Spacer(Modifier.height(LocalDimensions.current.xsMargin))
|
||||
Text(stringResource(R.string.onboardingMessageNotificationExplaination), style = base)
|
||||
Spacer(Modifier.height(LocalDimensions.current.itemSpacing))
|
||||
Column(modifier = Modifier.padding(horizontal = LocalDimensions.current.mediumSpacing)) {
|
||||
Text(stringResource(R.string.notificationsMessage), style = LocalType.current.h4)
|
||||
Spacer(Modifier.height(LocalDimensions.current.smallSpacing))
|
||||
Text(stringResource(R.string.onboardingMessageNotificationExplaination), style = LocalType.current.base)
|
||||
Spacer(Modifier.height(LocalDimensions.current.spacing))
|
||||
}
|
||||
|
||||
NotificationRadioButton(
|
||||
@ -107,8 +100,8 @@ private fun NotificationRadioButton(
|
||||
RadioButton(
|
||||
onClick = onClick,
|
||||
modifier = modifier,
|
||||
checked = checked,
|
||||
contentPadding = PaddingValues(horizontal = LocalDimensions.current.margin, vertical = 7.dp)
|
||||
selected = checked,
|
||||
contentPadding = PaddingValues(horizontal = LocalDimensions.current.mediumSpacing, vertical = 7.dp)
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
@ -120,17 +113,18 @@ private fun NotificationRadioButton(
|
||||
),
|
||||
) {
|
||||
Column(modifier = Modifier
|
||||
.padding(horizontal = 15.dp)
|
||||
.padding(top = 10.dp, bottom = 11.dp)) {
|
||||
Text(stringResource(title), style = h8)
|
||||
.padding(horizontal = LocalDimensions.current.smallSpacing,
|
||||
vertical = LocalDimensions.current.xsSpacing)
|
||||
) {
|
||||
Text(stringResource(title), style = LocalType.current.h8)
|
||||
|
||||
Text(stringResource(explanation), style = small, modifier = Modifier.padding(top = 7.dp))
|
||||
Text(stringResource(explanation), style = LocalType.current.small, modifier = Modifier.padding(top = LocalDimensions.current.xxsSpacing))
|
||||
tag?.let {
|
||||
Text(
|
||||
stringResource(it),
|
||||
modifier = Modifier.padding(top = 6.dp),
|
||||
modifier = Modifier.padding(top = LocalDimensions.current.xxsSpacing),
|
||||
color = LocalColors.current.primary,
|
||||
style = h9
|
||||
style = LocalType.current.h9
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -141,7 +135,7 @@ private fun NotificationRadioButton(
|
||||
@Preview
|
||||
@Composable
|
||||
private fun MessageNotificationsScreenPreview(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
MessageNotificationsScreen()
|
||||
|
@ -8,7 +8,7 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -17,11 +17,10 @@ import androidx.compose.ui.tooling.preview.Preview
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.onboarding.OnboardingBackPressAlertDialog
|
||||
import org.thoughtcrime.securesms.onboarding.ui.ContinuePrimaryOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.base
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.components.SessionOutlinedTextField
|
||||
import org.thoughtcrime.securesms.ui.h4
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
@ -52,18 +51,18 @@ internal fun PickDisplayName(
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
Spacer(Modifier.weight(1f))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallItemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallSpacing))
|
||||
|
||||
Column(
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.largeMargin)
|
||||
modifier = Modifier.padding(horizontal = LocalDimensions.current.mediumSpacing)
|
||||
) {
|
||||
Text(stringResource(state.title), style = h4)
|
||||
Spacer(Modifier.height(LocalDimensions.current.smallItemSpacing))
|
||||
Text(stringResource(state.title), style = LocalType.current.h4)
|
||||
Spacer(Modifier.height(LocalDimensions.current.smallSpacing))
|
||||
Text(
|
||||
stringResource(state.description),
|
||||
style = base,
|
||||
modifier = Modifier.padding(bottom = LocalDimensions.current.xsItemSpacing))
|
||||
Spacer(Modifier.height(LocalDimensions.current.itemSpacing))
|
||||
style = LocalType.current.base,
|
||||
modifier = Modifier.padding(bottom = LocalDimensions.current.xsSpacing))
|
||||
Spacer(Modifier.height(LocalDimensions.current.spacing))
|
||||
SessionOutlinedTextField(
|
||||
text = state.displayName,
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@ -76,7 +75,7 @@ internal fun PickDisplayName(
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallItemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.smallSpacing))
|
||||
Spacer(Modifier.weight(2f))
|
||||
|
||||
ContinuePrimaryOutlineButton(modifier = Modifier.align(Alignment.CenterHorizontally), onContinue)
|
||||
|
@ -6,7 +6,7 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.components.PrimaryOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
|
||||
@ -17,8 +17,8 @@ fun ContinuePrimaryOutlineButton(modifier: Modifier, onContinue: () -> Unit) {
|
||||
modifier = modifier
|
||||
.contentDescription(R.string.AccessibilityId_continue)
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = LocalDimensions.current.largeMargin)
|
||||
.padding(bottom = LocalDimensions.current.xxsMargin),
|
||||
.padding(horizontal = LocalDimensions.current.xlargeSpacing)
|
||||
.padding(bottom = LocalDimensions.current.smallSpacing),
|
||||
onClick = onContinue,
|
||||
)
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
@ -25,14 +25,14 @@ import org.session.libsignal.utilities.PublicKeyValidation
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity
|
||||
import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
|
||||
import org.thoughtcrime.securesms.database.threadDatabase
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.components.MaybeScanQrCode
|
||||
import org.thoughtcrime.securesms.ui.components.QrImage
|
||||
import org.thoughtcrime.securesms.ui.components.SessionTabRow
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.setComposeContent
|
||||
import org.thoughtcrime.securesms.ui.small
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.util.start
|
||||
|
||||
private val TITLES = listOf(R.string.view, R.string.scan)
|
||||
@ -93,14 +93,14 @@ private fun Tabs(accountId: String, errors: Flow<String>, onScan: (String) -> Un
|
||||
fun QrPage(string: String) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(LocalColors.current.backgroundSecondary)
|
||||
.padding(horizontal = LocalDimensions.current.margin)
|
||||
.background(LocalColors.current.background)
|
||||
.padding(horizontal = LocalDimensions.current.mediumSpacing)
|
||||
.fillMaxSize()
|
||||
) {
|
||||
QrImage(
|
||||
string = string,
|
||||
modifier = Modifier
|
||||
.padding(top = LocalDimensions.current.margin, bottom = LocalDimensions.current.xxsMargin)
|
||||
.padding(top = LocalDimensions.current.mediumSpacing, bottom = LocalDimensions.current.xsSpacing)
|
||||
.contentDescription(R.string.AccessibilityId_qr_code),
|
||||
icon = R.drawable.session
|
||||
)
|
||||
@ -109,7 +109,7 @@ fun QrPage(string: String) {
|
||||
text = stringResource(R.string.this_is_your_account_id_other_users_can_scan_it_to_start_a_conversation_with_you),
|
||||
color = LocalColors.current.textSecondary,
|
||||
textAlign = TextAlign.Center,
|
||||
style = small
|
||||
style = LocalType.current.small
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -77,8 +77,8 @@ import org.thoughtcrime.securesms.ui.Cell
|
||||
import org.thoughtcrime.securesms.ui.Divider
|
||||
import org.thoughtcrime.securesms.ui.LargeItemButton
|
||||
import org.thoughtcrime.securesms.ui.LargeItemButtonWithDrawable
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.color.destructiveButtonColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.dangerButtonColors
|
||||
import org.thoughtcrime.securesms.ui.components.PrimaryOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.components.PrimaryOutlineCopyButton
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
@ -448,9 +448,9 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
Column {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = LocalDimensions.current.smallMargin)
|
||||
.padding(top = LocalDimensions.current.xxxsMargin),
|
||||
horizontalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallItemSpacing),
|
||||
.padding(horizontal = LocalDimensions.current.spacing)
|
||||
.padding(top = LocalDimensions.current.xxsSpacing),
|
||||
horizontalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallSpacing),
|
||||
) {
|
||||
PrimaryOutlineButton(
|
||||
stringResource(R.string.share),
|
||||
@ -464,7 +464,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.itemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.spacing))
|
||||
|
||||
val hasPaths by hasPaths().collectAsState(initial = false)
|
||||
|
||||
@ -492,7 +492,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
|
||||
}
|
||||
LargeItemButton(R.string.activity_settings_help_button, R.drawable.ic_help, Modifier.contentDescription(R.string.AccessibilityId_help)) { show<HelpSettingsActivity>() }
|
||||
Divider()
|
||||
LargeItemButton(R.string.activity_settings_clear_all_data_button_title, R.drawable.ic_clear_data, Modifier.contentDescription(R.string.AccessibilityId_clear_data), destructiveButtonColors()) { ClearAllDataDialog().show(supportFragmentManager, "Clear All Data Dialog") }
|
||||
LargeItemButton(R.string.activity_settings_clear_all_data_button_title, R.drawable.ic_message_details__trash, Modifier.contentDescription(R.string.AccessibilityId_clear_data), dangerButtonColors()) { ClearAllDataDialog().show(supportFragmentManager, "Clear All Data Dialog") }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -509,4 +509,4 @@ private fun LocalBroadcastManager.hasPaths(): Flow<Boolean> = callbackFlow {
|
||||
registerReceiver(receiver, IntentFilter("pathsBuilt"))
|
||||
|
||||
awaitClose { unregisterReceiver(receiver) }
|
||||
}.onStart { emit(Unit) }.map { OnionRequestAPI.paths.isNotEmpty() }
|
||||
}.onStart { emit(Unit) }.map { OnionRequestAPI.paths.isNotEmpty() }
|
@ -6,6 +6,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.ui.theme.selectedTheme
|
||||
import org.thoughtcrime.securesms.util.ThemeState
|
||||
import org.thoughtcrime.securesms.util.themeState
|
||||
import javax.inject.Inject
|
||||
@ -26,11 +27,17 @@ class AppearanceSettingsViewModel @Inject constructor(private val prefs: TextSec
|
||||
prefs.setThemeStyle(newThemeStyle)
|
||||
// update UI state
|
||||
_uiState.value = prefs.themeState()
|
||||
|
||||
// force compose to refresh its style reference
|
||||
selectedTheme = null
|
||||
}
|
||||
|
||||
fun setNewFollowSystemSettings(followSystemSettings: Boolean) {
|
||||
prefs.setFollowSystemSettings(followSystemSettings)
|
||||
_uiState.value = prefs.themeState()
|
||||
|
||||
// force compose to refresh its style reference
|
||||
selectedTheme = null
|
||||
}
|
||||
|
||||
}
|
@ -11,7 +11,7 @@ import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.wrapContentWidth
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@ -26,20 +26,19 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.unit.dp
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.SessionShieldIcon
|
||||
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.theme.ThemeColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.components.QrImage
|
||||
import org.thoughtcrime.securesms.ui.components.SlimOutlineButton
|
||||
import org.thoughtcrime.securesms.ui.components.SlimOutlineCopyButton
|
||||
import org.thoughtcrime.securesms.ui.components.border
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.extraSmallMonospace
|
||||
import org.thoughtcrime.securesms.ui.h8
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.ui.theme.monospace
|
||||
|
||||
@Composable
|
||||
internal fun RecoveryPasswordScreen(
|
||||
@ -49,11 +48,11 @@ internal fun RecoveryPasswordScreen(
|
||||
onHide:() -> Unit = {}
|
||||
) {
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.xsMargin),
|
||||
verticalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallSpacing),
|
||||
modifier = Modifier
|
||||
.contentDescription(R.string.AccessibilityId_recovery_password)
|
||||
.verticalScroll(rememberScrollState())
|
||||
.padding(bottom = LocalDimensions.current.xsMargin)
|
||||
.padding(bottom = LocalDimensions.current.smallSpacing)
|
||||
) {
|
||||
RecoveryPasswordCell(mnemonic, seed, copyMnemonic)
|
||||
HideRecoveryPasswordCell(onHide)
|
||||
@ -75,17 +74,17 @@ private fun RecoveryPasswordCell(
|
||||
Row {
|
||||
Text(
|
||||
stringResource(R.string.sessionRecoveryPassword),
|
||||
style = h8
|
||||
style = LocalType.current.h8
|
||||
)
|
||||
Spacer(Modifier.width(LocalDimensions.current.xxsItemSpacing))
|
||||
Spacer(Modifier.width(LocalDimensions.current.xxsSpacing))
|
||||
SessionShieldIcon()
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xxxsMargin))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xxsSpacing))
|
||||
|
||||
Text(
|
||||
stringResource(R.string.recoveryPasswordDescription),
|
||||
style = base
|
||||
style = LocalType.current.base
|
||||
)
|
||||
|
||||
AnimatedVisibility(!showQr) {
|
||||
@ -99,7 +98,7 @@ private fun RecoveryPasswordCell(
|
||||
QrImage(
|
||||
seed,
|
||||
modifier = Modifier
|
||||
.padding(vertical = LocalDimensions.current.smallMargin)
|
||||
.padding(vertical = LocalDimensions.current.spacing)
|
||||
.contentDescription(R.string.AccessibilityId_qr_code),
|
||||
contentPadding = 10.dp,
|
||||
icon = R.drawable.session_shield
|
||||
@ -108,7 +107,7 @@ private fun RecoveryPasswordCell(
|
||||
|
||||
AnimatedVisibility(!showQr) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallItemSpacing),
|
||||
horizontalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallSpacing),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
SlimOutlineCopyButton(
|
||||
@ -138,11 +137,11 @@ private fun RecoveryPassword(mnemonic: String) {
|
||||
mnemonic,
|
||||
modifier = Modifier
|
||||
.contentDescription(R.string.AccessibilityId_recovery_password_container)
|
||||
.padding(vertical = LocalDimensions.current.smallMargin)
|
||||
.padding(vertical = LocalDimensions.current.spacing)
|
||||
.border()
|
||||
.padding(LocalDimensions.current.smallMargin),
|
||||
.padding(LocalDimensions.current.spacing),
|
||||
textAlign = TextAlign.Center,
|
||||
style = extraSmallMonospace,
|
||||
style = LocalType.current.extraSmall.monospace(),
|
||||
color = LocalColors.current.run { if (isLight) text else primary },
|
||||
)
|
||||
}
|
||||
@ -156,14 +155,14 @@ private fun HideRecoveryPasswordCell(onHide: () -> Unit = {}) {
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.recoveryPasswordHideRecoveryPassword),
|
||||
style = h8
|
||||
style = LocalType.current.h8
|
||||
)
|
||||
Text(
|
||||
stringResource(R.string.recoveryPasswordHideRecoveryPasswordDescription),
|
||||
style = base
|
||||
style = LocalType.current.base
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.width(LocalDimensions.current.xxsMargin))
|
||||
Spacer(modifier = Modifier.width(LocalDimensions.current.xsSpacing))
|
||||
SlimOutlineButton(
|
||||
text = stringResource(R.string.hide),
|
||||
modifier = Modifier
|
||||
@ -180,7 +179,7 @@ private fun HideRecoveryPasswordCell(onHide: () -> Unit = {}) {
|
||||
@Preview
|
||||
@Composable
|
||||
private fun PreviewRecoveryPasswordScreen(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
RecoveryPasswordScreen(mnemonic = "voyage urban toyed maverick peculiar tuxedo penguin tree grass building listen speak withdraw terminal plane")
|
||||
|
@ -34,7 +34,7 @@ class RecoveryPasswordActivity : BaseActionBarActivity() {
|
||||
showSessionDialog {
|
||||
title(R.string.recoveryPasswordHidePermanently)
|
||||
htmlText(R.string.recoveryPasswordHidePermanentlyDescription1)
|
||||
destructiveButton(R.string.continue_2, R.string.AccessibilityId_continue) { onHideConfirm() }
|
||||
dangerButton(R.string.continue_2, R.string.AccessibilityId_continue) { onHideConfirm() }
|
||||
cancelButton()
|
||||
}
|
||||
}
|
||||
@ -44,7 +44,7 @@ class RecoveryPasswordActivity : BaseActionBarActivity() {
|
||||
title(R.string.recoveryPasswordHidePermanently)
|
||||
text(R.string.recoveryPasswordHidePermanentlyDescription2)
|
||||
cancelButton()
|
||||
destructiveButton(
|
||||
dangerButton(
|
||||
R.string.yes,
|
||||
contentDescription = R.string.AccessibilityId_confirm_button
|
||||
) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package org.thoughtcrime.securesms.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
@ -8,11 +9,13 @@ import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.material3.BasicAlertDialog
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -20,9 +23,16 @@ 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.res.stringResource
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.bold
|
||||
|
||||
|
||||
class DialogButtonModel(
|
||||
val text: GetString,
|
||||
@ -32,29 +42,35 @@ class DialogButtonModel(
|
||||
val onClick: () -> Unit = {},
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun AlertDialog(
|
||||
onDismissRequest: () -> Unit,
|
||||
title: String? = null,
|
||||
text: String? = null,
|
||||
content: @Composable () -> Unit = {},
|
||||
buttons: List<DialogButtonModel>? = null
|
||||
buttons: List<DialogButtonModel>? = null,
|
||||
showCloseButton: Boolean = false,
|
||||
content: @Composable () -> Unit = {}
|
||||
) {
|
||||
androidx.compose.material.AlertDialog(
|
||||
onDismissRequest,
|
||||
shape = MaterialTheme.shapes.small,
|
||||
backgroundColor = LocalColors.current.backgroundSecondary,
|
||||
buttons = {
|
||||
Box {
|
||||
IconButton(
|
||||
onClick = onDismissRequest,
|
||||
modifier = Modifier.align(Alignment.TopEnd)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_dialog_x),
|
||||
tint = LocalColors.current.text,
|
||||
contentDescription = "back"
|
||||
)
|
||||
BasicAlertDialog(
|
||||
onDismissRequest = onDismissRequest,
|
||||
content = {
|
||||
Box(
|
||||
modifier = Modifier.background(color = LocalColors.current.backgroundSecondary,
|
||||
shape = MaterialTheme.shapes.small)
|
||||
) {
|
||||
// only show the 'x' button is required
|
||||
if(showCloseButton) {
|
||||
IconButton(
|
||||
onClick = onDismissRequest,
|
||||
modifier = Modifier.align(Alignment.TopEnd)
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_dialog_x),
|
||||
tint = LocalColors.current.text,
|
||||
contentDescription = "back"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Column(modifier = Modifier.fillMaxWidth()) {
|
||||
@ -62,23 +78,23 @@ fun AlertDialog(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = LocalDimensions.current.smallItemSpacing)
|
||||
.padding(horizontal = LocalDimensions.current.smallItemSpacing)
|
||||
.padding(top = LocalDimensions.current.smallSpacing)
|
||||
.padding(horizontal = LocalDimensions.current.smallSpacing)
|
||||
) {
|
||||
title?.let {
|
||||
Text(
|
||||
it,
|
||||
textAlign = TextAlign.Center,
|
||||
style = h7,
|
||||
modifier = Modifier.padding(bottom = LocalDimensions.current.xxsItemSpacing)
|
||||
style = LocalType.current.h7,
|
||||
modifier = Modifier.padding(bottom = LocalDimensions.current.xxsSpacing)
|
||||
)
|
||||
}
|
||||
text?.let {
|
||||
Text(
|
||||
it,
|
||||
textAlign = TextAlign.Center,
|
||||
style = large,
|
||||
modifier = Modifier.padding(bottom = LocalDimensions.current.xxsItemSpacing)
|
||||
style = LocalType.current.large,
|
||||
modifier = Modifier.padding(bottom = LocalDimensions.current.xxsSpacing)
|
||||
)
|
||||
}
|
||||
content()
|
||||
@ -116,12 +132,59 @@ fun DialogButton(text: String, modifier: Modifier, color: Color = Color.Unspecif
|
||||
Text(
|
||||
text,
|
||||
color = color.takeOrElse { LocalColors.current.text },
|
||||
style = largeBold,
|
||||
style = LocalType.current.large.bold(),
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.padding(
|
||||
top = LocalDimensions.current.smallItemSpacing,
|
||||
bottom = LocalDimensions.current.itemSpacing
|
||||
top = LocalDimensions.current.smallSpacing,
|
||||
bottom = LocalDimensions.current.spacing
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewSimpleDialog(){
|
||||
PreviewTheme {
|
||||
AlertDialog(
|
||||
onDismissRequest = {},
|
||||
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 = {}
|
||||
),
|
||||
DialogButtonModel(
|
||||
GetString(stringResource(R.string.cancel))
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewXCloseDialog(){
|
||||
PreviewTheme {
|
||||
AlertDialog(
|
||||
title = stringResource(R.string.urlOpen),
|
||||
text = stringResource(R.string.urlOpenBrowser),
|
||||
showCloseButton = true, // display the 'x' button
|
||||
buttons = listOf(
|
||||
DialogButtonModel(
|
||||
text = GetString(R.string.activity_landing_terms_of_service),
|
||||
contentDescription = GetString(R.string.AccessibilityId_terms_of_service_button),
|
||||
onClick = {}
|
||||
),
|
||||
DialogButtonModel(
|
||||
text = GetString(R.string.activity_landing_privacy_policy),
|
||||
contentDescription = GetString(R.string.AccessibilityId_privacy_policy_button),
|
||||
onClick = {}
|
||||
)
|
||||
),
|
||||
onDismissRequest = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -16,12 +16,8 @@ import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.pager.PagerState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.ContentAlpha
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.LocalContentAlpha
|
||||
import androidx.compose.material.LocalContentColor
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
@ -37,26 +33,27 @@ import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.launch
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.blackAlpha40
|
||||
import org.thoughtcrime.securesms.ui.theme.pillShape
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.math.sign
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun BoxScope.HorizontalPagerIndicator(pagerState: PagerState) {
|
||||
if (pagerState.pageCount >= 2) Card(
|
||||
shape = pillShape,
|
||||
backgroundColor = Color.Black.copy(alpha = 0.4f),
|
||||
if (pagerState.pageCount >= 2) Box(
|
||||
modifier = Modifier
|
||||
.background(color = blackAlpha40, shape = pillShape)
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(8.dp)
|
||||
.padding(LocalDimensions.current.xxsSpacing)
|
||||
) {
|
||||
Box(modifier = Modifier.padding(8.dp)) {
|
||||
Box(modifier = Modifier.padding(LocalDimensions.current.xxsSpacing)) {
|
||||
ClickableHorizontalPagerIndicator(
|
||||
pagerState = pagerState,
|
||||
pageCount = pagerState.pageCount,
|
||||
activeColor = Color.White,
|
||||
inactiveColor = LocalColors.current.textSecondary)
|
||||
pageCount = pagerState.pageCount
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -73,9 +70,9 @@ fun ClickableHorizontalPagerIndicator(
|
||||
pageCount: Int,
|
||||
modifier: Modifier = Modifier,
|
||||
pageIndexMapping: (Int) -> Int = { it },
|
||||
activeColor: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
|
||||
inactiveColor: Color = activeColor.copy(ContentAlpha.disabled),
|
||||
indicatorWidth: Dp = 8.dp,
|
||||
activeColor: Color = Color.White,
|
||||
inactiveColor: Color = LocalColors.current.disabled,
|
||||
indicatorWidth: Dp = LocalDimensions.current.xxsSpacing,
|
||||
indicatorHeight: Dp = indicatorWidth,
|
||||
spacing: Dp = indicatorWidth,
|
||||
indicatorShape: Shape = CircleShape,
|
||||
@ -115,9 +112,9 @@ private fun HorizontalPagerIndicator(
|
||||
pageCount: Int,
|
||||
modifier: Modifier = Modifier,
|
||||
pageIndexMapping: (Int) -> Int = { it },
|
||||
activeColor: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current),
|
||||
inactiveColor: Color = activeColor.copy(ContentAlpha.disabled),
|
||||
indicatorWidth: Dp = 8.dp,
|
||||
activeColor: Color = Color.White,
|
||||
inactiveColor: Color = LocalColors.current.disabled,
|
||||
indicatorWidth: Dp = LocalDimensions.current.xxsSpacing,
|
||||
indicatorHeight: Dp = indicatorWidth,
|
||||
spacing: Dp = indicatorWidth,
|
||||
indicatorShape: Shape = CircleShape,
|
||||
|
@ -7,13 +7,13 @@ import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.Canvas
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
@ -24,14 +24,14 @@ import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.layout.wrapContentSize
|
||||
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.Icon
|
||||
import androidx.compose.material.LocalContentColor
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.RadioButton
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.material3.ButtonColors
|
||||
import androidx.compose.material3.Card
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
@ -52,6 +52,7 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.contentDescription
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
@ -61,14 +62,15 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsession.utilities.runIf
|
||||
import org.thoughtcrime.securesms.components.ProfilePictureView
|
||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.OptionsCard
|
||||
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.conversation.disappearingmessages.ui.OptionsCardData
|
||||
import org.thoughtcrime.securesms.ui.components.SmallCircularProgressIndicator
|
||||
import org.thoughtcrime.securesms.ui.components.TitledRadioButton
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.transparentButtonColors
|
||||
import kotlin.math.min
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@ -92,18 +94,25 @@ data class RadioOption<T>(
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun <T> OptionsCard(card: OptionsCard<T>, callbacks: Callbacks<T>) {
|
||||
Text(
|
||||
card.title(),
|
||||
style = base
|
||||
)
|
||||
CellNoMargin {
|
||||
LazyColumn(
|
||||
modifier = Modifier.heightIn(max = 5000.dp)
|
||||
) {
|
||||
itemsIndexed(card.options) { i, it ->
|
||||
if (i != 0) Divider()
|
||||
TitledRadioButton(it) { callbacks.setValue(it.value) }
|
||||
fun <T> OptionsCard(card: OptionsCardData<T>, callbacks: Callbacks<T>) {
|
||||
Column {
|
||||
Text(
|
||||
modifier = Modifier.padding(start = LocalDimensions.current.smallSpacing),
|
||||
text = card.title(),
|
||||
style = LocalType.current.base,
|
||||
color = LocalColors.current.textSecondary
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xsSpacing))
|
||||
|
||||
CellNoMargin {
|
||||
LazyColumn(
|
||||
modifier = Modifier.heightIn(max = 5000.dp)
|
||||
) {
|
||||
itemsIndexed(card.options) { i, it ->
|
||||
if (i != 0) Divider()
|
||||
TitledRadioButton(option = it) { callbacks.setValue(it.value) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,7 +126,10 @@ fun LargeItemButtonWithDrawable(
|
||||
colors: ButtonColors = transparentButtonColors(),
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
ItemButtonWithDrawable(textId, icon, modifier.heightIn(min = LocalDimensions.current.minLargeItemButtonHeight), h8, colors, onClick)
|
||||
ItemButtonWithDrawable(
|
||||
textId, icon, modifier.heightIn(min = LocalDimensions.current.minLargeItemButtonHeight),
|
||||
LocalType.current.h8, colors, onClick
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
@ -125,7 +137,7 @@ fun ItemButtonWithDrawable(
|
||||
@StringRes textId: Int,
|
||||
@DrawableRes icon: Int,
|
||||
modifier: Modifier = Modifier,
|
||||
textStyle: TextStyle = xl,
|
||||
textStyle: TextStyle = LocalType.current.xl,
|
||||
colors: ButtonColors = transparentButtonColors(),
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
@ -155,7 +167,10 @@ fun LargeItemButton(
|
||||
colors: ButtonColors = transparentButtonColors(),
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
ItemButton(textId, icon, modifier.heightIn(min = LocalDimensions.current.minLargeItemButtonHeight), h8, colors, onClick)
|
||||
ItemButton(
|
||||
textId, icon, modifier.heightIn(min = LocalDimensions.current.minLargeItemButtonHeight),
|
||||
LocalType.current.h8, colors, onClick
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -166,7 +181,7 @@ fun ItemButton(
|
||||
@StringRes textId: Int,
|
||||
@DrawableRes icon: Int,
|
||||
modifier: Modifier = Modifier,
|
||||
textStyle: TextStyle = xl,
|
||||
textStyle: TextStyle = LocalType.current.xl,
|
||||
colors: ButtonColors = transparentButtonColors(),
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
@ -196,7 +211,7 @@ fun ItemButton(
|
||||
text: String,
|
||||
icon: @Composable BoxScope.() -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
textStyle: TextStyle = xl,
|
||||
textStyle: TextStyle = LocalType.current.xl,
|
||||
colors: ButtonColors = transparentButtonColors(),
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
@ -208,27 +223,42 @@ fun ItemButton(
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.width(80.dp)
|
||||
.width(50.dp)
|
||||
.wrapContentHeight()
|
||||
.align(Alignment.CenterVertically)
|
||||
) {
|
||||
icon()
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.width(LocalDimensions.current.smallSpacing))
|
||||
|
||||
Text(
|
||||
text,
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = LocalDimensions.current.xsItemSpacing)
|
||||
.padding(vertical = LocalDimensions.current.xsSpacing)
|
||||
.align(Alignment.CenterVertically),
|
||||
style = textStyle
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PrewviewItemButton() {
|
||||
PreviewTheme {
|
||||
ItemButton(
|
||||
textId = R.string.activity_create_group_title,
|
||||
icon = R.drawable.ic_group,
|
||||
onClick = {}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Cell(
|
||||
padding: Dp = 0.dp,
|
||||
margin: Dp = LocalDimensions.current.margin,
|
||||
margin: Dp = LocalDimensions.current.spacing,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
CellWithPaddingAndMargin(padding, margin) { content() }
|
||||
@ -240,64 +270,22 @@ fun CellNoMargin(content: @Composable () -> Unit) {
|
||||
|
||||
@Composable
|
||||
fun CellWithPaddingAndMargin(
|
||||
padding: Dp = LocalDimensions.current.smallMargin,
|
||||
margin: Dp = LocalDimensions.current.margin,
|
||||
padding: Dp = LocalDimensions.current.spacing,
|
||||
margin: Dp = LocalDimensions.current.spacing,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
Card(
|
||||
backgroundColor = LocalColors.current.backgroundSecondary,
|
||||
shape = MaterialTheme.shapes.medium,
|
||||
elevation = 0.dp,
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = margin)
|
||||
.background(color = LocalColors.current.backgroundSecondary,
|
||||
shape = MaterialTheme.shapes.small)
|
||||
.wrapContentHeight()
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = margin),
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Box(Modifier.padding(padding)) { content() }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T> TitledRadioButton(option: RadioOption<T>, onClick: () -> Unit) {
|
||||
val color = if (option.enabled) LocalColors.current.text else LocalColors.current.disabled
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(LocalDimensions.current.smallItemSpacing),
|
||||
modifier = Modifier
|
||||
.runIf(option.enabled) { clickable { if (!option.selected) onClick() } }
|
||||
.heightIn(min = 60.dp)
|
||||
.padding(horizontal = LocalDimensions.current.margin)
|
||||
.contentDescription(option.contentDescription)
|
||||
) {
|
||||
Column(modifier = Modifier
|
||||
.weight(1f)
|
||||
.align(Alignment.CenterVertically)) {
|
||||
Column {
|
||||
Text(
|
||||
text = option.title(),
|
||||
style = large,
|
||||
color = color
|
||||
)
|
||||
option.subtitle?.let {
|
||||
Text(
|
||||
text = it(),
|
||||
style = extraSmall,
|
||||
color = color
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
RadioButton(
|
||||
selected = option.selected,
|
||||
onClick = null,
|
||||
modifier = Modifier
|
||||
.height(26.dp)
|
||||
.align(Alignment.CenterVertically),
|
||||
enabled = option.enabled,
|
||||
colors = LocalColors.current.radioButtonColors()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Modifier.contentDescription(text: GetString?): Modifier {
|
||||
return text?.let {
|
||||
@ -357,10 +345,10 @@ fun Modifier.fadingEdges(
|
||||
|
||||
@Composable
|
||||
fun Divider(modifier: Modifier = Modifier, startIndent: Dp = 0.dp) {
|
||||
androidx.compose.material.Divider(
|
||||
modifier = modifier.padding(horizontal = LocalDimensions.current.xsMargin),
|
||||
color = LocalColors.current.divider,
|
||||
startIndent = startIndent
|
||||
HorizontalDivider(
|
||||
modifier = modifier.padding(horizontal = LocalDimensions.current.smallSpacing)
|
||||
.padding(start = startIndent),
|
||||
color = LocalColors.current.borders,
|
||||
)
|
||||
}
|
||||
|
||||
@ -392,7 +380,7 @@ fun ProgressArc(progress: Float, modifier: Modifier = Modifier) {
|
||||
"${text}%",
|
||||
color = Color.White,
|
||||
modifier = Modifier.align(Alignment.Center),
|
||||
style = h2
|
||||
style = LocalType.current.h2
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +0,0 @@
|
||||
package org.thoughtcrime.securesms.ui
|
||||
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
val LocalDimensions = staticCompositionLocalOf { Dimensions() }
|
||||
|
||||
data class Dimensions(
|
||||
val xxxsItemSpacing: Dp = 4.dp,
|
||||
val xxsItemSpacing: Dp = 8.dp,
|
||||
val xsItemSpacing: Dp = 12.dp,
|
||||
val smallItemSpacing: Dp = 16.dp,
|
||||
val itemSpacing: Dp = 24.dp,
|
||||
|
||||
val xxxsMargin: Dp = 8.dp,
|
||||
val xxsMargin: Dp = 12.dp,
|
||||
val xsMargin: Dp = 16.dp,
|
||||
val smallMargin: Dp = 24.dp,
|
||||
val margin: Dp = 32.dp,
|
||||
val onboardingMargin: Dp = 36.dp,
|
||||
val largeMargin: Dp = 64.dp,
|
||||
val homeEmptyViewMargin: Dp = 50.dp,
|
||||
|
||||
val dividerIndent: Dp = 80.dp,
|
||||
val appBarHeight: Dp = 64.dp,
|
||||
val minScrollableViewHeight: Dp = 200.dp,
|
||||
val minLargeItemButtonHeight: Dp = 60.dp,
|
||||
|
||||
val indicatorHeight: Dp = 4.dp,
|
||||
val borderStroke: Dp = 1.dp
|
||||
)
|
@ -1,59 +0,0 @@
|
||||
package org.thoughtcrime.securesms.ui
|
||||
|
||||
import androidx.compose.material.Typography
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontFamily.Companion.Monospace
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
fun boldStyle(size: TextUnit) = TextStyle.Default.copy(
|
||||
fontSize = size,
|
||||
lineHeight = size * 1.2,
|
||||
fontWeight = FontWeight.Bold,
|
||||
)
|
||||
|
||||
fun defaultStyle(size: TextUnit, fontFamily: FontFamily? = TextStyle.Default.fontFamily) = TextStyle.Default.copy(
|
||||
fontSize = size,
|
||||
lineHeight = size * 1.2,
|
||||
fontFamily = fontFamily
|
||||
)
|
||||
|
||||
val xl = defaultStyle(18.sp)
|
||||
|
||||
val large = defaultStyle(16.sp)
|
||||
val largeBold = boldStyle(16.sp)
|
||||
|
||||
val base = defaultStyle(14.sp)
|
||||
val baseBold = boldStyle(14.sp)
|
||||
val baseMonospace = defaultStyle(14.sp, fontFamily = Monospace)
|
||||
|
||||
val small = defaultStyle(12.sp)
|
||||
val smallBold = boldStyle(12.sp)
|
||||
val smallMonospace = defaultStyle(12.sp, fontFamily = Monospace)
|
||||
|
||||
val extraSmall = defaultStyle(11.sp)
|
||||
val extraSmallBold = boldStyle(11.sp)
|
||||
val extraSmallMonospace = defaultStyle(11.sp, fontFamily = Monospace)
|
||||
|
||||
val fine = defaultStyle(9.sp)
|
||||
|
||||
val h1 = boldStyle(36.sp)
|
||||
val h2 = boldStyle(32.sp)
|
||||
val h3 = boldStyle(29.sp)
|
||||
val h4 = boldStyle(26.sp)
|
||||
val h5 = boldStyle(23.sp)
|
||||
val h6 = boldStyle(20.sp)
|
||||
val h7 = boldStyle(18.sp)
|
||||
val h8 = boldStyle(16.sp)
|
||||
val h9 = boldStyle(14.sp)
|
||||
|
||||
val sessionTypography = Typography(
|
||||
h1 = h1,
|
||||
h2 = h2,
|
||||
h3 = h3,
|
||||
h4 = h4,
|
||||
h5 = h5,
|
||||
h6 = h6,
|
||||
)
|
@ -5,6 +5,7 @@ import android.content.Context
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.ComposeView
|
||||
import androidx.fragment.app.Fragment
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionMaterialTheme
|
||||
|
||||
fun Activity.setComposeContent(content: @Composable () -> Unit) {
|
||||
ComposeView(this)
|
||||
|
@ -1,233 +0,0 @@
|
||||
package org.thoughtcrime.securesms.ui.color
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.text.selection.TextSelectionColors
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.RadioButtonDefaults
|
||||
import androidx.compose.material.TabRowDefaults
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TextFieldDefaults
|
||||
import androidx.compose.material.primarySurface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.takeOrElse
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.base
|
||||
|
||||
val LocalColors = staticCompositionLocalOf<Colors> { ClassicDark() }
|
||||
|
||||
interface Colors {
|
||||
val isLight: Boolean
|
||||
val primary: Color
|
||||
val danger: Color
|
||||
val disabled: Color
|
||||
val background: Color
|
||||
val backgroundSecondary: Color
|
||||
val text: Color
|
||||
val textSecondary: Color
|
||||
val borders: Color
|
||||
val textBubbleSent: Color
|
||||
val backgroundBubbleReceived: Color
|
||||
val textBubbleReceived: Color
|
||||
val backgroundBubbleSent: Color get() = primary
|
||||
val qrCodeContent: Color
|
||||
val qrCodeBackground: Color
|
||||
val primaryButtonFill: Color
|
||||
val primaryButtonFillText: Color
|
||||
}
|
||||
|
||||
fun Colors.text(isError: Boolean): Color = if (isError) danger else text
|
||||
fun Colors.textSecondary(isError: Boolean): Color = if (isError) danger else textSecondary
|
||||
fun Colors.borders(isError: Boolean): Color = if (isError) danger else borders
|
||||
|
||||
val Colors.textSelectionColors get() = TextSelectionColors(
|
||||
handleColor = primary,
|
||||
backgroundColor = primary.copy(alpha = 0.5f)
|
||||
)
|
||||
|
||||
data class ClassicDark(override val primary: Color = primaryGreen): Colors {
|
||||
override val isLight = false
|
||||
override val danger = dangerDark
|
||||
override val disabled = disabledDark
|
||||
override val background = classicDark0
|
||||
override val backgroundSecondary = classicDark1
|
||||
override val text = classicDark6
|
||||
override val textSecondary = classicDark5
|
||||
override val borders = classicDark3
|
||||
override val textBubbleSent = Color.Black
|
||||
override val backgroundBubbleReceived = classicDark2
|
||||
override val textBubbleReceived = Color.White
|
||||
override val qrCodeContent = background
|
||||
override val qrCodeBackground = text
|
||||
override val primaryButtonFill = primary
|
||||
override val primaryButtonFillText = Color.Black
|
||||
}
|
||||
|
||||
data class ClassicLight(override val primary: Color = primaryGreen): Colors {
|
||||
override val isLight = true
|
||||
override val danger = dangerLight
|
||||
override val disabled = disabledLight
|
||||
override val background = classicLight6
|
||||
override val backgroundSecondary = classicLight5
|
||||
override val text = classicLight0
|
||||
override val textSecondary = classicLight1
|
||||
override val borders = classicLight3
|
||||
override val textBubbleSent = Color.Black
|
||||
override val backgroundBubbleReceived = classicLight4
|
||||
override val textBubbleReceived = classicLight4
|
||||
override val qrCodeContent = text
|
||||
override val qrCodeBackground = backgroundSecondary
|
||||
override val primaryButtonFill = text
|
||||
override val primaryButtonFillText = Color.White
|
||||
}
|
||||
|
||||
data class OceanDark(override val primary: Color = primaryBlue): Colors {
|
||||
override val isLight = false
|
||||
override val danger = dangerDark
|
||||
override val disabled = disabledDark
|
||||
override val background = oceanDark2
|
||||
override val backgroundSecondary = oceanDark1
|
||||
override val text = oceanDark7
|
||||
override val textSecondary = oceanDark5
|
||||
override val borders = oceanDark4
|
||||
override val textBubbleSent = Color.Black
|
||||
override val backgroundBubbleReceived = oceanDark4
|
||||
override val textBubbleReceived = oceanDark4
|
||||
override val qrCodeContent = background
|
||||
override val qrCodeBackground = text
|
||||
override val primaryButtonFill = primary
|
||||
override val primaryButtonFillText = Color.Black
|
||||
}
|
||||
|
||||
data class OceanLight(override val primary: Color = primaryBlue): Colors {
|
||||
override val isLight = true
|
||||
override val danger = dangerLight
|
||||
override val disabled = disabledLight
|
||||
override val background = oceanLight7
|
||||
override val backgroundSecondary = oceanLight6
|
||||
override val text = oceanLight1
|
||||
override val textSecondary = oceanLight2
|
||||
override val borders = oceanLight3
|
||||
override val textBubbleSent = oceanLight1
|
||||
override val backgroundBubbleReceived = oceanLight4
|
||||
override val textBubbleReceived = oceanLight1
|
||||
override val qrCodeContent = text
|
||||
override val qrCodeBackground = backgroundSecondary
|
||||
override val primaryButtonFill = text
|
||||
override val primaryButtonFillText = Color.White
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Colors(name: String, colors: List<Color>) {
|
||||
Column {
|
||||
colors.forEachIndexed { i, it ->
|
||||
Box(Modifier.background(it)) {
|
||||
Text("$name: $i")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewThemeColors(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
) {
|
||||
PreviewTheme(colors) { ThemeColors() }
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ThemeColors() {
|
||||
Column {
|
||||
Box(Modifier.background(MaterialTheme.colors.primary)) {
|
||||
Text("primary", style = base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.primaryVariant)) {
|
||||
Text("primaryVariant", style = base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.secondary)) {
|
||||
Text("secondary", style = base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.secondaryVariant)) {
|
||||
Text("secondaryVariant", style = base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.surface)) {
|
||||
Text("surface", style = base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.primarySurface)) {
|
||||
Text("primarySurface", style = base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.background)) {
|
||||
Text("background", style = base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.error)) {
|
||||
Text("error", style = base)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Colors.outlinedTextFieldColors(
|
||||
isError: Boolean
|
||||
) = TextFieldDefaults.outlinedTextFieldColors(
|
||||
textColor = if (isError) danger else text,
|
||||
cursorColor = if (isError) danger else text,
|
||||
focusedBorderColor = borders,
|
||||
unfocusedBorderColor = borders,
|
||||
placeholderColor = if (isError) danger else textSecondary
|
||||
)
|
||||
|
||||
val Colors.divider get() = text.copy(alpha = TabRowDefaults.DividerOpacity)
|
||||
|
||||
@Composable
|
||||
fun Colors.radioButtonColors() = RadioButtonDefaults.colors(
|
||||
selectedColor = primary,
|
||||
unselectedColor = text,
|
||||
disabledColor = disabled
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun transparentButtonColors() = ButtonDefaults.buttonColors(backgroundColor = Color.Transparent)
|
||||
|
||||
@Composable
|
||||
fun destructiveButtonColors() = ButtonDefaults.buttonColors(backgroundColor = Color.Transparent, contentColor = LocalColors.current.danger)
|
||||
|
||||
|
||||
/**
|
||||
* This class holds two instances of [Colors], [light] representing the [Colors] to use when the system is in a
|
||||
* light theme, and [dark] representing the [Colors] to use when the system is in a dark theme.
|
||||
*
|
||||
* If the user has [followSystemSettings] turned on then [light] should be equal to [dark].
|
||||
*/
|
||||
data class LightDarkColors(
|
||||
val light: Colors,
|
||||
val dark: Colors
|
||||
) {
|
||||
@Composable
|
||||
fun colors() = if (light == dark || isSystemInDarkTheme()) dark else light
|
||||
}
|
||||
|
||||
/**
|
||||
* Courtesy constructor that sets [light] and [dark] based on properties.
|
||||
*/
|
||||
fun LightDarkColors(isClassic: Boolean, isLight: Boolean, followSystemSettings: Boolean, primaryOrUnspecified: Color): LightDarkColors {
|
||||
val primary = primaryOrUnspecified.takeOrElse { if (isClassic) primaryGreen else primaryBlue }
|
||||
val light = when {
|
||||
isLight || followSystemSettings -> if (isClassic) ClassicLight(primary) else OceanLight(primary)
|
||||
else -> if (isClassic) ClassicDark(primary) else OceanDark(primary)
|
||||
}
|
||||
val dark = when {
|
||||
isLight && !followSystemSettings -> if (isClassic) ClassicLight(primary) else OceanLight(primary)
|
||||
else -> if (isClassic) ClassicDark(primary) else OceanDark(primary)
|
||||
}
|
||||
return LightDarkColors(light, dark)
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package org.thoughtcrime.securesms.ui.color
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.BLUE_ACCENT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.CLASSIC_DARK
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.CLASSIC_LIGHT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.GREEN_ACCENT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.OCEAN_LIGHT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.ORANGE_ACCENT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.PINK_ACCENT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.PURPLE_ACCENT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.RED_ACCENT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.YELLOW_ACCENT
|
||||
|
||||
/**
|
||||
* Retrieve the current [Colors] from [TextSecurePreferences] and current system settings.
|
||||
*/
|
||||
@Composable
|
||||
fun TextSecurePreferences.colors(): Colors = lightDarkColors().colors()
|
||||
private fun TextSecurePreferences.lightDarkColors() = LightDarkColors(isClassic(), isLight(), getFollowSystemSettings(), primaryColor())
|
||||
private fun TextSecurePreferences.isLight(): Boolean = getThemeStyle() in setOf(CLASSIC_LIGHT, OCEAN_LIGHT)
|
||||
private fun TextSecurePreferences.isClassic(): Boolean = getThemeStyle() in setOf(CLASSIC_DARK, CLASSIC_LIGHT)
|
||||
private fun TextSecurePreferences.primaryColor(): Color = when(getSelectedAccentColor()) {
|
||||
GREEN_ACCENT -> primaryGreen
|
||||
BLUE_ACCENT -> primaryBlue
|
||||
PURPLE_ACCENT -> primaryPurple
|
||||
PINK_ACCENT -> primaryPink
|
||||
RED_ACCENT -> primaryRed
|
||||
ORANGE_ACCENT -> primaryOrange
|
||||
YELLOW_ACCENT -> primaryYellow
|
||||
else -> Color.Unspecified
|
||||
}
|
@ -5,9 +5,9 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -15,16 +15,16 @@ import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.color.Colors
|
||||
import org.thoughtcrime.securesms.ui.h4
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.ThemeColors
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun AppBarPreview(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
AppBar(title = "Title", {}, {})
|
||||
@ -42,7 +42,7 @@ fun AppBar(title: String, onClose: () -> Unit = {}, onBack: (() -> Unit)? = null
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Text(text = title, style = h4)
|
||||
Text(text = title, style = LocalType.current.h4)
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Box(contentAlignment = Alignment.Center, modifier = Modifier.size(LocalDimensions.current.appBarHeight)) {
|
||||
IconButton(onClick = onClose) {
|
||||
|
@ -1,12 +1,12 @@
|
||||
package org.thoughtcrime.securesms.ui.components
|
||||
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
|
||||
@Composable
|
||||
fun Modifier.border() = this.border(
|
||||
|
@ -16,8 +16,8 @@ import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.ButtonColors
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.ButtonColors
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
@ -37,13 +37,14 @@ import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.LaunchedEffectAsync
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.baseBold
|
||||
import org.thoughtcrime.securesms.ui.buttonShape
|
||||
import org.thoughtcrime.securesms.ui.color.Colors
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.ThemeColors
|
||||
import org.thoughtcrime.securesms.ui.theme.bold
|
||||
import org.thoughtcrime.securesms.ui.theme.buttonShape
|
||||
import kotlin.time.Duration
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
@ -65,16 +66,16 @@ fun Button(
|
||||
content: @Composable RowScope.() -> Unit
|
||||
) {
|
||||
style.applyButtonConstraints {
|
||||
androidx.compose.material.Button(
|
||||
onClick,
|
||||
modifier.heightIn(min = style.minHeight),
|
||||
enabled,
|
||||
interactionSource,
|
||||
androidx.compose.material3.Button(
|
||||
onClick = onClick,
|
||||
modifier = modifier.heightIn(min = style.minHeight),
|
||||
enabled = enabled,
|
||||
interactionSource = interactionSource,
|
||||
elevation = null,
|
||||
shape,
|
||||
border,
|
||||
colors,
|
||||
contentPadding
|
||||
shape = shape,
|
||||
border = border,
|
||||
colors = colors,
|
||||
contentPadding = contentPadding
|
||||
) {
|
||||
// Button sets LocalTextStyle, so text style is applied inside to override that.
|
||||
style.applyTextConstraints {
|
||||
@ -129,11 +130,11 @@ fun Button(
|
||||
Button(text, onClick, ButtonType.Outline(LocalColors.current.primaryButtonFill), modifier, enabled)
|
||||
}
|
||||
|
||||
@Composable fun PrimaryOutlineButton(onClick: () -> Unit, modifier: Modifier = Modifier, enabled: Boolean = true, content: @Composable RowScope.() -> Unit) {
|
||||
@Composable fun PrimaryOutlineButton(modifier: Modifier = Modifier, enabled: Boolean = true, onClick: () -> Unit, content: @Composable RowScope.() -> Unit) {
|
||||
Button(onClick, ButtonType.Outline(LocalColors.current.primaryButtonFill), modifier, enabled, content = content)
|
||||
}
|
||||
|
||||
@Composable fun SlimOutlineButton(onClick: () -> Unit, modifier: Modifier = Modifier, color: Color = LocalColors.current.text, enabled: Boolean = true, content: @Composable RowScope.() -> Unit) {
|
||||
@Composable fun SlimOutlineButton(modifier: Modifier = Modifier, color: Color = LocalColors.current.text, enabled: Boolean = true, onClick: () -> Unit, content: @Composable RowScope.() -> Unit) {
|
||||
Button(onClick, ButtonType.Outline(color), modifier, enabled, ButtonStyle.Slim, content = content)
|
||||
}
|
||||
|
||||
@ -257,7 +258,7 @@ fun BorderlessButtonWithIcon(
|
||||
text: String,
|
||||
@DrawableRes iconRes: Int,
|
||||
modifier: Modifier = Modifier,
|
||||
style: TextStyle = baseBold,
|
||||
style: TextStyle = LocalType.current.base.bold(),
|
||||
color: Color = LocalColors.current.text,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
@ -292,7 +293,7 @@ val MutableInteractionSource.releases
|
||||
@Preview
|
||||
@Composable
|
||||
private fun VariousButtons(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
FlowRow(
|
||||
|
@ -1,21 +1,20 @@
|
||||
package org.thoughtcrime.securesms.ui.components
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.LocalMinimumInteractiveComponentEnforcement
|
||||
import androidx.compose.material.LocalTextStyle
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.LocalMinimumInteractiveComponentEnforcement
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.thoughtcrime.securesms.ui.baseBold
|
||||
import org.thoughtcrime.securesms.ui.extraSmall
|
||||
import org.thoughtcrime.securesms.ui.extraSmallBold
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.ui.theme.bold
|
||||
|
||||
interface ButtonStyle {
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@SuppressLint("ComposableNaming")
|
||||
@Composable fun applyButtonConstraints(content: @Composable () -> Unit) {
|
||||
CompositionLocalProvider(
|
||||
@ -27,26 +26,34 @@ interface ButtonStyle {
|
||||
@SuppressLint("ComposableNaming")
|
||||
@Composable fun applyTextConstraints(content: @Composable () -> Unit) {
|
||||
CompositionLocalProvider(
|
||||
LocalTextStyle provides textStyle,
|
||||
LocalTextStyle provides textStyle(),
|
||||
content = content
|
||||
)
|
||||
}
|
||||
|
||||
val textStyle: TextStyle
|
||||
@Composable
|
||||
fun textStyle() : TextStyle
|
||||
|
||||
val minHeight: Dp
|
||||
|
||||
object Large: ButtonStyle {
|
||||
override val textStyle = baseBold.copy(textAlign = TextAlign.Center)
|
||||
@Composable
|
||||
override fun textStyle() = LocalType.current.base.bold()
|
||||
.copy(textAlign = TextAlign.Center)
|
||||
override val minHeight = 41.dp
|
||||
}
|
||||
|
||||
object Slim: ButtonStyle {
|
||||
override val textStyle = extraSmallBold.copy(textAlign = TextAlign.Center)
|
||||
@Composable
|
||||
override fun textStyle() = LocalType.current.extraSmall.bold()
|
||||
.copy(textAlign = TextAlign.Center)
|
||||
override val minHeight = 29.dp
|
||||
}
|
||||
|
||||
object Borderless: ButtonStyle {
|
||||
override val textStyle = extraSmall.copy(textAlign = TextAlign.Center)
|
||||
@Composable
|
||||
override fun textStyle() = LocalType.current.extraSmall
|
||||
.copy(textAlign = TextAlign.Center)
|
||||
override val minHeight = 37.dp
|
||||
}
|
||||
}
|
||||
|
@ -2,13 +2,13 @@ package org.thoughtcrime.securesms.ui.components
|
||||
|
||||
import androidx.compose.foundation.BorderStroke
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.material.ButtonColors
|
||||
import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.material3.ButtonColors
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
|
||||
private val disabledBorder @Composable get() = BorderStroke(
|
||||
width = LocalDimensions.current.borderStroke,
|
||||
@ -35,9 +35,9 @@ interface ButtonType {
|
||||
@Composable
|
||||
override fun buttonColors() = ButtonDefaults.buttonColors(
|
||||
contentColor = contentColor,
|
||||
backgroundColor = Color.Unspecified,
|
||||
containerColor = Color.Transparent,
|
||||
disabledContentColor = LocalColors.current.disabled,
|
||||
disabledBackgroundColor = Color.Unspecified
|
||||
disabledContainerColor = Color.Transparent
|
||||
)
|
||||
}
|
||||
|
||||
@ -47,9 +47,9 @@ interface ButtonType {
|
||||
@Composable
|
||||
override fun buttonColors() = ButtonDefaults.buttonColors(
|
||||
contentColor = LocalColors.current.background,
|
||||
backgroundColor = LocalColors.current.text,
|
||||
containerColor = LocalColors.current.text,
|
||||
disabledContentColor = LocalColors.current.disabled,
|
||||
disabledBackgroundColor = Color.Unspecified
|
||||
disabledContainerColor = Color.Transparent
|
||||
)
|
||||
}
|
||||
|
||||
@ -59,9 +59,9 @@ interface ButtonType {
|
||||
@Composable
|
||||
override fun buttonColors() = ButtonDefaults.buttonColors(
|
||||
contentColor = LocalColors.current.primaryButtonFillText,
|
||||
backgroundColor = LocalColors.current.primaryButtonFill,
|
||||
containerColor = LocalColors.current.primaryButtonFill,
|
||||
disabledContentColor = LocalColors.current.disabled,
|
||||
disabledBackgroundColor = Color.Unspecified
|
||||
disabledContainerColor = Color.Transparent
|
||||
)
|
||||
}
|
||||
|
||||
@ -73,8 +73,9 @@ interface ButtonType {
|
||||
@Composable
|
||||
override fun buttonColors() = ButtonDefaults.outlinedButtonColors(
|
||||
contentColor = color,
|
||||
backgroundColor = Color.Transparent,
|
||||
disabledContentColor = LocalColors.current.disabled
|
||||
containerColor = Color.Transparent,
|
||||
disabledContentColor = LocalColors.current.disabled,
|
||||
disabledContainerColor = Color.Transparent
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
package org.thoughtcrime.securesms.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.LocalContentColor
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@ -9,7 +9,7 @@ import androidx.compose.ui.unit.dp
|
||||
|
||||
@Composable
|
||||
fun CircularProgressIndicator(color: Color = LocalContentColor.current) {
|
||||
androidx.compose.material.CircularProgressIndicator(
|
||||
androidx.compose.material3.CircularProgressIndicator(
|
||||
modifier = Modifier.size(40.dp),
|
||||
color = color,
|
||||
strokeWidth = 2.dp
|
||||
@ -18,7 +18,7 @@ fun CircularProgressIndicator(color: Color = LocalContentColor.current) {
|
||||
|
||||
@Composable
|
||||
fun SmallCircularProgressIndicator(color: Color = LocalContentColor.current) {
|
||||
androidx.compose.material.CircularProgressIndicator(
|
||||
androidx.compose.material3.CircularProgressIndicator(
|
||||
modifier = Modifier.size(20.dp),
|
||||
color = color,
|
||||
strokeWidth = 2.dp
|
||||
|
@ -22,11 +22,11 @@ import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.material.Snackbar
|
||||
import androidx.compose.material.SnackbarHost
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.rememberScaffoldState
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Snackbar
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
@ -56,10 +56,9 @@ import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.launch
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsignal.utilities.Log
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.base
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.xl
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
private const val TAG = "NewMessageFragment"
|
||||
@ -78,7 +77,6 @@ fun MaybeScanQrCode(
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(LocalColors.current.background)
|
||||
) {
|
||||
LocalSoftwareKeyboardController.current?.hide()
|
||||
|
||||
@ -94,10 +92,10 @@ fun MaybeScanQrCode(
|
||||
) {
|
||||
Text(
|
||||
stringResource(R.string.activity_link_camera_permission_permanently_denied_configure_in_settings),
|
||||
style = base,
|
||||
style = LocalType.current.base,
|
||||
textAlign = TextAlign.Center
|
||||
)
|
||||
Spacer(modifier = Modifier.size(LocalDimensions.current.itemSpacing))
|
||||
Spacer(modifier = Modifier.size(LocalDimensions.current.spacing))
|
||||
OutlineButton(
|
||||
stringResource(R.string.sessionSettings),
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally),
|
||||
@ -107,14 +105,14 @@ fun MaybeScanQrCode(
|
||||
} else {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.background(color = LocalColors.current.backgroundSecondary)
|
||||
.fillMaxSize()
|
||||
.padding(LocalDimensions.current.largeMargin),
|
||||
.padding(LocalDimensions.current.xlargeSpacing),
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Spacer(modifier = Modifier.weight(1f))
|
||||
Text(stringResource(R.string.fragment_scan_qr_code_camera_access_explanation), style = xl, textAlign = TextAlign.Center)
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.itemSpacing))
|
||||
Text(stringResource(R.string.fragment_scan_qr_code_camera_access_explanation),
|
||||
style = LocalType.current.xl, textAlign = TextAlign.Center)
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.spacing))
|
||||
PrimaryOutlineButton(
|
||||
stringResource(R.string.cameraGrantAccess),
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
@ -158,13 +156,12 @@ fun ScanQrCode(errors: Flow<String>, onScan: (String) -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
val scaffoldState = rememberScaffoldState()
|
||||
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
errors.collect { error ->
|
||||
scaffoldState.snackbarHostState
|
||||
snackbarHostState
|
||||
.takeIf { it.currentSnackbarData == null }
|
||||
?.run {
|
||||
scope.launch {
|
||||
@ -175,22 +172,21 @@ fun ScanQrCode(errors: Flow<String>, onScan: (String) -> Unit) {
|
||||
// Don't use debounce() because many QR scans can come through each second,
|
||||
// and each scan could restart the timer which could mean no scan gets
|
||||
// through until the user stops scanning; quite perplexing.
|
||||
showSnackbar(message = error)
|
||||
snackbarHostState.showSnackbar(message = error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
scaffoldState = scaffoldState,
|
||||
snackbarHost = {
|
||||
SnackbarHost(
|
||||
hostState = scaffoldState.snackbarHostState,
|
||||
modifier = Modifier.padding(LocalDimensions.current.smallItemSpacing)
|
||||
hostState = snackbarHostState,
|
||||
modifier = Modifier.padding(LocalDimensions.current.smallSpacing)
|
||||
) { data ->
|
||||
Snackbar(
|
||||
snackbarData = data,
|
||||
modifier = Modifier.padding(LocalDimensions.current.smallItemSpacing)
|
||||
modifier = Modifier.padding(LocalDimensions.current.smallSpacing)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -204,7 +200,7 @@ fun ScanQrCode(errors: Flow<String>, onScan: (String) -> Unit) {
|
||||
Box(
|
||||
Modifier
|
||||
.aspectRatio(1f)
|
||||
.padding(LocalDimensions.current.itemSpacing)
|
||||
.padding(LocalDimensions.current.spacing)
|
||||
.clip(shape = RoundedCornerShape(26.dp))
|
||||
.background(Color(0x33ffffff))
|
||||
.align(Alignment.Center)
|
||||
|
@ -10,8 +10,8 @@ import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.Card
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
@ -32,15 +32,15 @@ import androidx.compose.ui.unit.dp
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.util.QRCodeUtilities
|
||||
|
||||
@Composable
|
||||
fun QrImage(
|
||||
string: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
contentPadding: Dp = LocalDimensions.current.smallItemSpacing,
|
||||
contentPadding: Dp = LocalDimensions.current.smallSpacing,
|
||||
icon: Int = R.drawable.session_shield
|
||||
) {
|
||||
var bitmap: Bitmap? by remember {
|
||||
@ -56,10 +56,9 @@ fun QrImage(
|
||||
}
|
||||
}
|
||||
|
||||
Card(
|
||||
backgroundColor = LocalColors.current.qrCodeBackground,
|
||||
elevation = 0.dp,
|
||||
modifier = modifier
|
||||
Box(
|
||||
modifier = modifier.background(color = LocalColors.current.qrCodeBackground,
|
||||
shape = MaterialTheme.shapes.small)
|
||||
) { Content(bitmap, icon, Modifier.padding(contentPadding), backgroundColor = LocalColors.current.qrCodeBackground) }
|
||||
}
|
||||
|
||||
|
@ -1,40 +1,58 @@
|
||||
package org.thoughtcrime.securesms.ui.components
|
||||
|
||||
import android.content.ContentProvider
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.scaleIn
|
||||
import androidx.compose.animation.scaleOut
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.selection.selectable
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.TextButton
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.color.transparentButtonColors
|
||||
import network.loki.messenger.libsession_util.util.ExpiryMode
|
||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.ExpiryType
|
||||
import org.thoughtcrime.securesms.ui.GetString
|
||||
import org.thoughtcrime.securesms.ui.RadioOption
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.sessionTypography
|
||||
import org.thoughtcrime.securesms.ui.theme.textEnabled
|
||||
import org.thoughtcrime.securesms.ui.theme.transparentButtonColors
|
||||
import kotlin.time.Duration.Companion.days
|
||||
|
||||
@Composable
|
||||
fun RadioButton(
|
||||
onClick: () -> Unit = {},
|
||||
modifier: Modifier = Modifier,
|
||||
checked: Boolean = false,
|
||||
selected: Boolean = false,
|
||||
enabled: Boolean = true,
|
||||
contentPadding: PaddingValues = PaddingValues(),
|
||||
content: @Composable RowScope.() -> Unit = {}
|
||||
) {
|
||||
@ -42,20 +60,22 @@ fun RadioButton(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.selectable(
|
||||
selected = checked,
|
||||
selected = selected,
|
||||
enabled = true,
|
||||
role = Role.RadioButton,
|
||||
onClick = onClick
|
||||
),
|
||||
enabled = enabled,
|
||||
colors = transparentButtonColors(),
|
||||
onClick = onClick,
|
||||
shape = RectangleShape,
|
||||
contentPadding = contentPadding
|
||||
) {
|
||||
content()
|
||||
|
||||
Spacer(modifier = Modifier.width(20.dp))
|
||||
RadioButtonIndicator(
|
||||
checked = checked,
|
||||
selected = selected && enabled, // disabled radio shouldn't be selected
|
||||
modifier = Modifier
|
||||
.size(22.dp)
|
||||
.align(Alignment.CenterVertically)
|
||||
@ -65,12 +85,12 @@ fun RadioButton(
|
||||
|
||||
@Composable
|
||||
private fun RadioButtonIndicator(
|
||||
checked: Boolean,
|
||||
selected: Boolean,
|
||||
modifier: Modifier
|
||||
) {
|
||||
Box(modifier = modifier) {
|
||||
AnimatedVisibility(
|
||||
checked,
|
||||
selected,
|
||||
modifier = Modifier
|
||||
.padding(2.5.dp)
|
||||
.clip(CircleShape),
|
||||
@ -91,9 +111,93 @@ private fun RadioButtonIndicator(
|
||||
.aspectRatio(1f)
|
||||
.border(
|
||||
width = LocalDimensions.current.borderStroke,
|
||||
color = LocalColors.current.text,
|
||||
color = LocalContentColor.current,
|
||||
shape = CircleShape
|
||||
)
|
||||
) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun <T> TitledRadioButton(
|
||||
modifier: Modifier = Modifier,
|
||||
option: RadioOption<T>,
|
||||
onClick: () -> Unit
|
||||
) {
|
||||
RadioButton(
|
||||
modifier = modifier.heightIn(min = 60.dp)
|
||||
.contentDescription(option.contentDescription),
|
||||
onClick = onClick,
|
||||
selected = option.selected,
|
||||
enabled = option.enabled,
|
||||
contentPadding = PaddingValues(horizontal = LocalDimensions.current.spacing),
|
||||
content = {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.align(Alignment.CenterVertically)
|
||||
) {
|
||||
Column {
|
||||
Text(
|
||||
text = option.title(),
|
||||
style = LocalType.current.large
|
||||
)
|
||||
option.subtitle?.let {
|
||||
Text(
|
||||
text = it(),
|
||||
style = LocalType.current.extraSmall
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewTextRadioButton() {
|
||||
PreviewTheme {
|
||||
TitledRadioButton(
|
||||
option = RadioOption<ExpiryMode>(
|
||||
value = ExpiryType.AFTER_SEND.mode(7.days),
|
||||
title = GetString(7.days),
|
||||
subtitle = GetString("This is a subtitle"),
|
||||
enabled = true,
|
||||
selected = true
|
||||
)
|
||||
) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewDisabledTextRadioButton() {
|
||||
PreviewTheme {
|
||||
TitledRadioButton(
|
||||
option = RadioOption<ExpiryMode>(
|
||||
value = ExpiryType.AFTER_SEND.mode(7.days),
|
||||
title = GetString(7.days),
|
||||
subtitle = GetString("This is a subtitle"),
|
||||
enabled = false,
|
||||
selected = true
|
||||
)
|
||||
) {}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewDeselectedTextRadioButton() {
|
||||
PreviewTheme {
|
||||
TitledRadioButton(
|
||||
option = RadioOption<ExpiryMode>(
|
||||
value = ExpiryType.AFTER_SEND.mode(7.days),
|
||||
title = GetString(7.days),
|
||||
subtitle = GetString("This is a subtitle"),
|
||||
enabled = true,
|
||||
selected = false
|
||||
)
|
||||
) {}
|
||||
}
|
||||
}
|
@ -1,15 +1,15 @@
|
||||
package org.thoughtcrime.securesms.ui.components
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.pager.PagerState
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material.Tab
|
||||
import androidx.compose.material.TabRow
|
||||
import androidx.compose.material.TabRowDefaults
|
||||
import androidx.compose.material.TabRowDefaults.tabIndicatorOffset
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.TabRow
|
||||
import androidx.compose.material3.TabRowDefaults
|
||||
import androidx.compose.material3.TabRowDefaults.tabIndicatorOffset
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -19,13 +19,12 @@ 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.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.color.Colors
|
||||
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.color.divider
|
||||
import org.thoughtcrime.securesms.ui.h8
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.SessionColorsParameterProvider
|
||||
import org.thoughtcrime.securesms.ui.theme.ThemeColors
|
||||
|
||||
private val TITLES = listOf(R.string.sessionRecoveryPassword, R.string.qrScan)
|
||||
|
||||
@ -33,32 +32,30 @@ private val TITLES = listOf(R.string.sessionRecoveryPassword, R.string.qrScan)
|
||||
@Composable
|
||||
fun SessionTabRow(pagerState: PagerState, titles: List<Int>) {
|
||||
TabRow(
|
||||
backgroundColor = Color.Unspecified,
|
||||
containerColor = Color.Unspecified,
|
||||
selectedTabIndex = pagerState.currentPage,
|
||||
contentColor = LocalColors.current.text,
|
||||
indicator = { tabPositions ->
|
||||
TabRowDefaults.Indicator(
|
||||
TabRowDefaults.SecondaryIndicator(
|
||||
Modifier.tabIndicatorOffset(tabPositions[pagerState.currentPage]),
|
||||
color = LocalColors.current.primary,
|
||||
height = LocalDimensions.current.indicatorHeight
|
||||
)
|
||||
},
|
||||
divider = { TabRowDefaults.Divider(color = LocalColors.current.divider) },
|
||||
modifier = Modifier
|
||||
.height(48.dp)
|
||||
.background(color = Color.Unspecified)
|
||||
divider = { HorizontalDivider(color = LocalColors.current.borders) }
|
||||
) {
|
||||
val animationScope = rememberCoroutineScope()
|
||||
titles.forEachIndexed { i, it ->
|
||||
Tab(
|
||||
i == pagerState.currentPage,
|
||||
modifier = Modifier.heightIn(min = 48.dp),
|
||||
selected = i == pagerState.currentPage,
|
||||
onClick = { animationScope.launch { pagerState.animateScrollToPage(i) } },
|
||||
selectedContentColor = LocalColors.current.text,
|
||||
unselectedContentColor = LocalColors.current.text,
|
||||
) {
|
||||
Text(
|
||||
stringResource(id = it),
|
||||
style = h8
|
||||
text = stringResource(id = it),
|
||||
style = LocalType.current.h8
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -69,7 +66,7 @@ fun SessionTabRow(pagerState: PagerState, titles: List<Int>) {
|
||||
@androidx.compose.ui.tooling.preview.Preview
|
||||
@Composable
|
||||
fun PreviewSessionTabRow(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: Colors
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) {
|
||||
val pagerState = rememberPagerState { TITLES.size }
|
||||
|
@ -17,9 +17,9 @@ import androidx.compose.foundation.text.InlineTextContent
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.text.appendInlineContent
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
@ -37,15 +37,15 @@ import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import network.loki.messenger.R
|
||||
import org.thoughtcrime.securesms.ui.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.base
|
||||
import org.thoughtcrime.securesms.ui.baseBold
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.color.borders
|
||||
import org.thoughtcrime.securesms.ui.color.text
|
||||
import org.thoughtcrime.securesms.ui.color.textSecondary
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalDimensions
|
||||
import org.thoughtcrime.securesms.ui.theme.PreviewTheme
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.theme.borders
|
||||
import org.thoughtcrime.securesms.ui.theme.text
|
||||
import org.thoughtcrime.securesms.ui.theme.textSecondary
|
||||
import org.thoughtcrime.securesms.ui.contentDescription
|
||||
import org.thoughtcrime.securesms.ui.theme.LocalType
|
||||
import org.thoughtcrime.securesms.ui.theme.bold
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
@ -85,7 +85,7 @@ fun SessionOutlinedTextField(
|
||||
modifier: Modifier = Modifier,
|
||||
contentDescription: String? = null,
|
||||
onChange: (String) -> Unit = {},
|
||||
textStyle: TextStyle = base,
|
||||
textStyle: TextStyle = LocalType.current.base,
|
||||
placeholder: String = "",
|
||||
onContinue: () -> Unit = {},
|
||||
error: String? = null,
|
||||
@ -106,7 +106,7 @@ fun SessionOutlinedTextField(
|
||||
if (text.isEmpty()) {
|
||||
Text(
|
||||
text = placeholder,
|
||||
style = base,
|
||||
style = LocalType.current.base,
|
||||
color = LocalColors.current.textSecondary(isTextErrorColor),
|
||||
modifier = Modifier.wrapContentSize()
|
||||
.align(Alignment.CenterStart)
|
||||
@ -130,13 +130,13 @@ fun SessionOutlinedTextField(
|
||||
)
|
||||
}
|
||||
error?.let {
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xsItemSpacing))
|
||||
Spacer(modifier = Modifier.height(LocalDimensions.current.xsSpacing))
|
||||
Text(
|
||||
it,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
.contentDescription(R.string.AccessibilityId_error_message),
|
||||
textAlign = TextAlign.Center,
|
||||
style = baseBold,
|
||||
style = LocalType.current.base.bold(),
|
||||
color = LocalColors.current.danger
|
||||
)
|
||||
}
|
||||
@ -148,7 +148,7 @@ fun AnnotatedTextWithIcon(
|
||||
text: String,
|
||||
@DrawableRes iconRes: Int,
|
||||
modifier: Modifier = Modifier,
|
||||
style: TextStyle = base,
|
||||
style: TextStyle = LocalType.current.base,
|
||||
color: Color = Color.Unspecified,
|
||||
iconSize: TextUnit = 12.sp
|
||||
) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package org.thoughtcrime.securesms.ui.color
|
||||
package org.thoughtcrime.securesms.ui.theme
|
||||
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
@ -0,0 +1,24 @@
|
||||
package org.thoughtcrime.securesms.ui.theme
|
||||
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
|
||||
val LocalDimensions = staticCompositionLocalOf { Dimensions() }
|
||||
|
||||
data class Dimensions(
|
||||
val xxxsSpacing: Dp = 4.dp,
|
||||
val xxsSpacing: Dp = 8.dp,
|
||||
val xsSpacing: Dp = 12.dp,
|
||||
val smallSpacing: Dp = 16.dp,
|
||||
val spacing: Dp = 24.dp,
|
||||
val mediumSpacing: Dp = 36.dp,
|
||||
val xlargeSpacing: Dp = 64.dp,
|
||||
|
||||
val dividerIndent: Dp = 60.dp,
|
||||
val appBarHeight: Dp = 64.dp,
|
||||
val minLargeItemButtonHeight: Dp = 60.dp,
|
||||
|
||||
val indicatorHeight: Dp = 4.dp,
|
||||
val borderStroke: Dp = 1.dp
|
||||
)
|
@ -0,0 +1,145 @@
|
||||
package org.thoughtcrime.securesms.ui.theme
|
||||
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.sp
|
||||
|
||||
|
||||
fun TextStyle.bold() = TextStyle.Default.copy(
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
|
||||
fun TextStyle.monospace() = TextStyle.Default.copy(
|
||||
fontFamily = FontFamily.Monospace
|
||||
)
|
||||
|
||||
val sessionTypography = SessionTypography()
|
||||
|
||||
data class SessionTypography(
|
||||
// Body
|
||||
val xl: TextStyle = TextStyle(
|
||||
fontSize = 18.sp,
|
||||
lineHeight = 21.6.sp,
|
||||
fontWeight = FontWeight.Normal
|
||||
),
|
||||
|
||||
val large: TextStyle = TextStyle(
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 19.2.sp,
|
||||
fontWeight = FontWeight.Normal
|
||||
),
|
||||
|
||||
val base: TextStyle = TextStyle(
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 16.8.sp,
|
||||
fontWeight = FontWeight.Normal
|
||||
),
|
||||
|
||||
val small: TextStyle = TextStyle(
|
||||
fontSize = 12.sp,
|
||||
lineHeight = 14.4.sp,
|
||||
fontWeight = FontWeight.Normal
|
||||
),
|
||||
|
||||
val extraSmall: TextStyle = TextStyle(
|
||||
fontSize = 11.sp,
|
||||
lineHeight = 13.2.sp,
|
||||
fontWeight = FontWeight.Normal
|
||||
),
|
||||
|
||||
val fine: TextStyle = TextStyle(
|
||||
fontSize = 9.sp,
|
||||
lineHeight = 10.8.sp,
|
||||
fontWeight = FontWeight.Normal
|
||||
),
|
||||
|
||||
// Headings
|
||||
val h1: TextStyle = TextStyle(
|
||||
fontSize = 36.sp,
|
||||
lineHeight = 43.2.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
),
|
||||
|
||||
val h2: TextStyle = TextStyle(
|
||||
fontSize = 32.sp,
|
||||
lineHeight = 38.4.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
),
|
||||
|
||||
val h3: TextStyle = TextStyle(
|
||||
fontSize = 29.sp,
|
||||
lineHeight = 34.8.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
),
|
||||
|
||||
val h4: TextStyle = TextStyle(
|
||||
fontSize = 26.sp,
|
||||
lineHeight = 31.2.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
),
|
||||
|
||||
val h5: TextStyle = TextStyle(
|
||||
fontSize = 23.sp,
|
||||
lineHeight = 27.6.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
),
|
||||
|
||||
val h6: TextStyle = TextStyle(
|
||||
fontSize = 20.sp,
|
||||
lineHeight = 24.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
),
|
||||
|
||||
val h7: TextStyle = TextStyle(
|
||||
fontSize = 18.sp,
|
||||
lineHeight = 21.6.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
),
|
||||
|
||||
val h8: TextStyle = TextStyle(
|
||||
fontSize = 16.sp,
|
||||
lineHeight = 19.2.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
),
|
||||
|
||||
val h9: TextStyle = TextStyle(
|
||||
fontSize = 14.sp,
|
||||
lineHeight = 16.8.sp,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
) {
|
||||
|
||||
// An opinionated override of Material's defaults
|
||||
@Composable
|
||||
fun asMaterialTypography() = Typography(
|
||||
// Display
|
||||
displayLarge = h1,
|
||||
displayMedium = h1,
|
||||
displaySmall = h1,
|
||||
|
||||
// Headline
|
||||
headlineLarge = h2,
|
||||
headlineMedium = h3,
|
||||
headlineSmall = h4,
|
||||
|
||||
// Title
|
||||
titleLarge = h5,
|
||||
titleMedium = h6,
|
||||
titleSmall = h7,
|
||||
|
||||
// Body
|
||||
bodyLarge = large,
|
||||
bodyMedium = base,
|
||||
bodySmall = small,
|
||||
|
||||
// Label
|
||||
labelLarge = extraSmall,
|
||||
labelMedium = fine,
|
||||
labelSmall = fine
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,10 @@
|
||||
package org.thoughtcrime.securesms.ui.theme
|
||||
|
||||
/**
|
||||
* This class holds two instances of [ThemeColors], [light] representing the [ThemeColors] to use when the system is in a
|
||||
* light theme, and [dark] representing the [ThemeColors] to use when the system is in a dark theme.
|
||||
*/
|
||||
data class ThemeColorSet(
|
||||
val light: ThemeColors,
|
||||
val dark: ThemeColors
|
||||
)
|
@ -0,0 +1,206 @@
|
||||
package org.thoughtcrime.securesms.ui.theme
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.text.selection.TextSelectionColors
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.darkColorScheme
|
||||
import androidx.compose.material3.lightColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
|
||||
interface ThemeColors {
|
||||
// properties to override for each theme
|
||||
val isLight: Boolean
|
||||
val primary: Color
|
||||
val danger: Color
|
||||
val disabled: Color
|
||||
val background: Color
|
||||
val backgroundSecondary: Color
|
||||
val text: Color
|
||||
val textSecondary: Color
|
||||
val borders: Color
|
||||
val textBubbleSent: Color
|
||||
val backgroundBubbleReceived: Color
|
||||
val textBubbleReceived: Color
|
||||
val qrCodeContent: Color
|
||||
val qrCodeBackground: Color
|
||||
val primaryButtonFill: Color
|
||||
val primaryButtonFillText: Color
|
||||
}
|
||||
|
||||
// extra functions and properties that work for all themes
|
||||
val ThemeColors.textSelectionColors
|
||||
get() = TextSelectionColors(
|
||||
handleColor = primary,
|
||||
backgroundColor = primary.copy(alpha = 0.5f)
|
||||
)
|
||||
|
||||
fun ThemeColors.text(isError: Boolean): Color = if (isError) danger else text
|
||||
fun ThemeColors.textSecondary(isError: Boolean): Color = if (isError) danger else textSecondary
|
||||
fun ThemeColors.textEnabled(enabled: Boolean) = if (enabled) text else disabled
|
||||
fun ThemeColors.borders(isError: Boolean): Color = if (isError) danger else borders
|
||||
|
||||
fun ThemeColors.toMaterialColors() = if (isLight) {
|
||||
lightColorScheme(
|
||||
primary = background,
|
||||
secondary = backgroundSecondary,
|
||||
tertiary = backgroundSecondary,
|
||||
onPrimary = text,
|
||||
onSecondary = text,
|
||||
onTertiary = text,
|
||||
background = background,
|
||||
surface = background,
|
||||
surfaceVariant = background,
|
||||
onBackground = text,
|
||||
onSurface = text,
|
||||
scrim = blackAlpha40,
|
||||
outline = text,
|
||||
outlineVariant = text
|
||||
)
|
||||
} else {
|
||||
darkColorScheme(
|
||||
primary = background,
|
||||
secondary = backgroundSecondary,
|
||||
tertiary = backgroundSecondary,
|
||||
onPrimary = text,
|
||||
onSecondary = text,
|
||||
onTertiary = text,
|
||||
background = background,
|
||||
surface = background,
|
||||
surfaceVariant = background,
|
||||
onBackground = text,
|
||||
onSurface = text,
|
||||
scrim = blackAlpha40,
|
||||
outline = text,
|
||||
outlineVariant = text
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun transparentButtonColors() = ButtonDefaults.buttonColors(
|
||||
containerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent,
|
||||
disabledContentColor = LocalColors.current.disabled
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun dangerButtonColors() = ButtonDefaults.buttonColors(
|
||||
containerColor = Color.Transparent,
|
||||
contentColor = LocalColors.current.danger
|
||||
)
|
||||
|
||||
|
||||
// Our themes
|
||||
data class ClassicDark(override val primary: Color = primaryGreen) : ThemeColors {
|
||||
override val isLight = false
|
||||
override val danger = dangerDark
|
||||
override val disabled = disabledDark
|
||||
override val background = classicDark0
|
||||
override val backgroundSecondary = classicDark1
|
||||
override val text = classicDark6
|
||||
override val textSecondary = classicDark5
|
||||
override val borders = classicDark3
|
||||
override val textBubbleSent = Color.Black
|
||||
override val backgroundBubbleReceived = classicDark2
|
||||
override val textBubbleReceived = Color.White
|
||||
override val qrCodeContent = background
|
||||
override val qrCodeBackground = text
|
||||
override val primaryButtonFill = primary
|
||||
override val primaryButtonFillText = Color.Black
|
||||
}
|
||||
|
||||
data class ClassicLight(override val primary: Color = primaryGreen) : ThemeColors {
|
||||
override val isLight = true
|
||||
override val danger = dangerLight
|
||||
override val disabled = disabledLight
|
||||
override val background = classicLight6
|
||||
override val backgroundSecondary = classicLight5
|
||||
override val text = classicLight0
|
||||
override val textSecondary = classicLight1
|
||||
override val borders = classicLight3
|
||||
override val textBubbleSent = text
|
||||
override val backgroundBubbleReceived = classicLight4
|
||||
override val textBubbleReceived = classicLight4
|
||||
override val qrCodeContent = text
|
||||
override val qrCodeBackground = backgroundSecondary
|
||||
override val primaryButtonFill = text
|
||||
override val primaryButtonFillText = Color.White
|
||||
}
|
||||
|
||||
data class OceanDark(override val primary: Color = primaryBlue) : ThemeColors {
|
||||
override val isLight = false
|
||||
override val danger = dangerDark
|
||||
override val disabled = disabledDark
|
||||
override val background = oceanDark2
|
||||
override val backgroundSecondary = oceanDark1
|
||||
override val text = oceanDark7
|
||||
override val textSecondary = oceanDark5
|
||||
override val borders = oceanDark4
|
||||
override val textBubbleSent = Color.Black
|
||||
override val backgroundBubbleReceived = oceanDark4
|
||||
override val textBubbleReceived = oceanDark4
|
||||
override val qrCodeContent = background
|
||||
override val qrCodeBackground = text
|
||||
override val primaryButtonFill = primary
|
||||
override val primaryButtonFillText = Color.Black
|
||||
}
|
||||
|
||||
data class OceanLight(override val primary: Color = primaryBlue) : ThemeColors {
|
||||
override val isLight = true
|
||||
override val danger = dangerLight
|
||||
override val disabled = disabledLight
|
||||
override val background = oceanLight7
|
||||
override val backgroundSecondary = oceanLight6
|
||||
override val text = oceanLight1
|
||||
override val textSecondary = oceanLight2
|
||||
override val borders = oceanLight3
|
||||
override val textBubbleSent = text
|
||||
override val backgroundBubbleReceived = oceanLight4
|
||||
override val textBubbleReceived = oceanLight1
|
||||
override val qrCodeContent = text
|
||||
override val qrCodeBackground = backgroundSecondary
|
||||
override val primaryButtonFill = text
|
||||
override val primaryButtonFillText = Color.White
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewThemeColors(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors
|
||||
) {
|
||||
PreviewTheme(colors) { ThemeColors() }
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ThemeColors() {
|
||||
Column {
|
||||
Box(Modifier.background(LocalColors.current.primary)) {
|
||||
Text("primary", style = LocalType.current.base)
|
||||
}
|
||||
Box(Modifier.background(LocalColors.current.background)) {
|
||||
Text("background", style = LocalType.current.base)
|
||||
}
|
||||
Box(Modifier.background(LocalColors.current.backgroundSecondary)) {
|
||||
Text("backgroundSecondary", style = LocalType.current.base)
|
||||
}
|
||||
Box(Modifier.background(LocalColors.current.text)) {
|
||||
Text("text", style = LocalType.current.base)
|
||||
}
|
||||
Box(Modifier.background(LocalColors.current.textSecondary)) {
|
||||
Text("textSecondary", style = LocalType.current.base)
|
||||
}
|
||||
Box(Modifier.background(LocalColors.current.danger)) {
|
||||
Text("danger", style = LocalType.current.base)
|
||||
}
|
||||
Box(Modifier.background(LocalColors.current.borders)) {
|
||||
Text("border", style = LocalType.current.base)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package org.thoughtcrime.securesms.ui.theme
|
||||
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.BLUE_ACCENT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.ORANGE_ACCENT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.PINK_ACCENT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.PURPLE_ACCENT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.RED_ACCENT
|
||||
import org.session.libsession.utilities.TextSecurePreferences.Companion.YELLOW_ACCENT
|
||||
|
||||
|
||||
/**
|
||||
* Returns the compose theme based on saved preferences
|
||||
* Some behaviour is hardcoded to cater for legacy usage of people with themes already set
|
||||
* But future themes will be picked and set directly from the "Appearance" screen
|
||||
*/
|
||||
@Composable
|
||||
fun TextSecurePreferences.getComposeTheme(): ThemeColors {
|
||||
val selectedTheme = getThemeStyle()
|
||||
|
||||
// get the chosen primary color from the preferences
|
||||
val selectedPrimary = primaryColor()
|
||||
|
||||
// create a theme set with the appropriate primary
|
||||
val colorSet = when(selectedTheme){
|
||||
TextSecurePreferences.OCEAN_DARK,
|
||||
TextSecurePreferences.OCEAN_LIGHT -> ThemeColorSet(
|
||||
light = OceanLight(selectedPrimary),
|
||||
dark = OceanDark(selectedPrimary)
|
||||
)
|
||||
|
||||
else -> ThemeColorSet(
|
||||
light = ClassicLight(selectedPrimary),
|
||||
dark = ClassicDark(selectedPrimary)
|
||||
)
|
||||
}
|
||||
|
||||
// deliver the right set from the light/dark mode chosen
|
||||
val theme = when{
|
||||
getFollowSystemSettings() -> if(isSystemInDarkTheme()) colorSet.dark else colorSet.light
|
||||
|
||||
selectedTheme == TextSecurePreferences.CLASSIC_LIGHT ||
|
||||
selectedTheme == TextSecurePreferences.OCEAN_LIGHT -> colorSet.light
|
||||
|
||||
else -> colorSet.dark
|
||||
}
|
||||
|
||||
return theme
|
||||
}
|
||||
|
||||
fun TextSecurePreferences.primaryColor(): Color = when(getSelectedAccentColor()) {
|
||||
BLUE_ACCENT -> primaryBlue
|
||||
PURPLE_ACCENT -> primaryPurple
|
||||
PINK_ACCENT -> primaryPink
|
||||
RED_ACCENT -> primaryRed
|
||||
ORANGE_ACCENT -> primaryOrange
|
||||
YELLOW_ACCENT -> primaryYellow
|
||||
else -> primaryGreen
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,28 +1,26 @@
|
||||
package org.thoughtcrime.securesms.ui
|
||||
package org.thoughtcrime.securesms.ui.theme
|
||||
|
||||
import android.content.Context
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.selection.LocalTextSelectionColors
|
||||
import androidx.compose.material.LocalContentColor
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Shapes
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Shapes
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.session.libsession.utilities.AppTextSecurePreferences
|
||||
import org.thoughtcrime.securesms.ui.color.ClassicDark
|
||||
import org.thoughtcrime.securesms.ui.color.ClassicLight
|
||||
import org.thoughtcrime.securesms.ui.color.Colors
|
||||
import org.thoughtcrime.securesms.ui.color.LocalColors
|
||||
import org.thoughtcrime.securesms.ui.color.OceanDark
|
||||
import org.thoughtcrime.securesms.ui.color.OceanLight
|
||||
import org.thoughtcrime.securesms.ui.color.colors
|
||||
import org.thoughtcrime.securesms.ui.color.textSelectionColors
|
||||
|
||||
// Globally accessible composition local objects
|
||||
val LocalColors = compositionLocalOf <ThemeColors> { ClassicDark() }
|
||||
val LocalType = compositionLocalOf { sessionTypography }
|
||||
|
||||
var selectedTheme: ThemeColors? = null
|
||||
|
||||
/**
|
||||
* Apply a Material2 compose theme based on user selections in SharedPreferences.
|
||||
@ -31,24 +29,33 @@ import org.thoughtcrime.securesms.ui.color.textSelectionColors
|
||||
fun SessionMaterialTheme(
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
SessionMaterialTheme(LocalContext.current.colors()) { content() }
|
||||
// set the theme data if it hasn't been done yet
|
||||
if(selectedTheme == null) {
|
||||
// Some values can be set from the preferences, and if not should fallback to a default value
|
||||
val context = LocalContext.current
|
||||
val preferences = AppTextSecurePreferences(context)
|
||||
selectedTheme = preferences.getComposeTheme()
|
||||
}
|
||||
|
||||
SessionMaterialTheme(colors = selectedTheme ?: ClassicDark()) { content() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply a given [Colors], and our typography and shapes as a Material 2 Compose Theme.
|
||||
* Apply a given [ThemeColors], and our typography and shapes as a Material 2 Compose Theme.
|
||||
**/
|
||||
@Composable
|
||||
fun SessionMaterialTheme(
|
||||
colors: Colors,
|
||||
colors: ThemeColors,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
MaterialTheme(
|
||||
colors = colors.toMaterialColors(),
|
||||
typography = sessionTypography,
|
||||
colorScheme = colors.toMaterialColors(),
|
||||
typography = sessionTypography.asMaterialTypography(),
|
||||
shapes = sessionShapes,
|
||||
) {
|
||||
CompositionLocalProvider(
|
||||
LocalColors provides colors,
|
||||
LocalType provides sessionTypography,
|
||||
LocalContentColor provides colors.text,
|
||||
LocalTextSelectionColors provides colors.textSelectionColors,
|
||||
) {
|
||||
@ -57,24 +64,6 @@ fun SessionMaterialTheme(
|
||||
}
|
||||
}
|
||||
|
||||
private fun Colors.toMaterialColors() = androidx.compose.material.Colors(
|
||||
primary = background,
|
||||
primaryVariant = backgroundSecondary,
|
||||
secondary = background,
|
||||
secondaryVariant = background,
|
||||
background = background,
|
||||
surface = background,
|
||||
error = danger,
|
||||
onPrimary = text,
|
||||
onSecondary = text,
|
||||
onBackground = text,
|
||||
onSurface = text,
|
||||
onError = text,
|
||||
isLight = isLight
|
||||
)
|
||||
|
||||
@Composable private fun Context.colors() = AppTextSecurePreferences(this).colors()
|
||||
|
||||
val pillShape = RoundedCornerShape(percent = 50)
|
||||
val buttonShape = pillShape
|
||||
|
||||
@ -88,7 +77,7 @@ val sessionShapes = Shapes(
|
||||
*/
|
||||
@Composable
|
||||
fun PreviewTheme(
|
||||
colors: Colors = LocalColors.current,
|
||||
colors: ThemeColors = LocalColors.current,
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
SessionMaterialTheme(colors) {
|
||||
@ -98,6 +87,7 @@ fun PreviewTheme(
|
||||
}
|
||||
}
|
||||
|
||||
class SessionColorsParameterProvider : PreviewParameterProvider<Colors> {
|
||||
// used for previews
|
||||
class SessionColorsParameterProvider : PreviewParameterProvider<ThemeColors> {
|
||||
override val values = sequenceOf(ClassicDark(), ClassicLight(), OceanDark(), OceanLight())
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_enabled="false" android:color="?android:textColorTertiary"/>
|
||||
<item android:color="@color/destructive"/>
|
||||
<item android:color="?danger"/>
|
||||
</selector>
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:color="@color/destructive" android:state_selected="true"/>
|
||||
<item android:color="?danger" android:state_selected="true"/>
|
||||
<item android:color="@color/call_action_button" android:state_selected="false"/>
|
||||
</selector>
|
@ -3,9 +3,9 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid android:color="@color/destructive" />
|
||||
<solid android:color="?danger" />
|
||||
|
||||
<corners android:radius="@dimen/dialog_button_corner_radius" />
|
||||
|
||||
<stroke android:width="@dimen/border_thickness" android:color="@color/destructive" />
|
||||
<stroke android:width="@dimen/border_thickness" android:color="?danger" />
|
||||
</shape>
|
@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/button_destructive">
|
||||
android:color="@color/button_danger">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="?colorPrimary"/>
|
||||
<corners android:radius="@dimen/medium_button_corner_radius" />
|
||||
<stroke
|
||||
android:color="@color/button_destructive"
|
||||
android:color="@color/button_danger"
|
||||
android:width="@dimen/border_thickness" />
|
||||
</shape>
|
||||
</item>
|
@ -1,11 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="25dp"
|
||||
android:height="26dp"
|
||||
android:viewportWidth="25"
|
||||
android:viewportHeight="26">
|
||||
<path
|
||||
android:pathData="M19.907,7.674H19.907H4.54H4.54C4.317,7.674 4.095,7.719 3.888,7.806L3.888,7.806C3.681,7.893 3.491,8.023 3.334,8.189C3.176,8.355 3.054,8.554 2.978,8.775L3.922,9.097L2.978,8.775C2.903,8.996 2.877,9.231 2.904,9.465L2.904,9.465L2.904,9.469L4.555,23.412C4.555,23.413 4.555,23.413 4.555,23.414C4.603,23.823 4.807,24.189 5.111,24.447C5.415,24.705 5.798,24.84 6.187,24.84H6.188H18.26H18.26C18.649,24.84 19.032,24.705 19.336,24.447C19.64,24.189 19.844,23.823 19.892,23.414C19.892,23.413 19.892,23.413 19.892,23.412L21.543,9.469L21.544,9.465C21.57,9.231 21.544,8.996 21.469,8.775L21.469,8.775C21.393,8.554 21.271,8.355 21.113,8.189C20.956,8.023 20.766,7.893 20.559,7.806L20.17,8.728L20.559,7.806C20.352,7.719 20.13,7.674 19.907,7.674ZM21.412,1.84H3.031C2.045,1.84 1.149,2.609 1.149,3.674V5.828C1.149,6.893 2.045,7.662 3.031,7.662H21.412C22.398,7.662 23.294,6.893 23.294,5.828V3.674C23.294,2.609 22.398,1.84 21.412,1.84Z"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#FF3A3A"
|
||||
android:strokeColor="?backgroundSecondary"/>
|
||||
</vector>
|
@ -3,7 +3,7 @@
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="@color/destructive">
|
||||
android:tint="?danger">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M6,19c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2V7H6v12zM19,4h-3.5l-1,-1h-5l-1,1H5v2h14V4z"/>
|
||||
|
5
app/src/main/res/drawable/sheet_rounded_bg.xml
Normal file
5
app/src/main/res/drawable/sheet_rounded_bg.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape android:shape="rectangle" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="?conversation_menu_background_color" />
|
||||
<corners android:radius="12dp" />
|
||||
</shape>
|
@ -39,7 +39,7 @@
|
||||
/>
|
||||
|
||||
<TextView
|
||||
style="@style/Widget.Session.Button.Common.DestructiveOutline"
|
||||
style="@style/Widget.Session.Button.Common.DangerOutline"
|
||||
android:paddingHorizontal="@dimen/large_spacing"
|
||||
android:paddingVertical="@dimen/small_spacing"
|
||||
android:text="@string/ConversationActivity_unblock"
|
||||
|
@ -228,7 +228,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@+id/toolbar"
|
||||
android:background="@color/destructive"
|
||||
android:background="?danger"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
@ -300,7 +300,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:contentDescription="@string/AccessibilityId_block_message_request_button"
|
||||
android:textColor="@color/destructive"
|
||||
android:textColor="?danger"
|
||||
android:paddingHorizontal="@dimen/massive_spacing"
|
||||
android:paddingVertical="@dimen/small_spacing"
|
||||
android:textSize="@dimen/text_size"
|
||||
@ -334,7 +334,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/declineMessageRequestButton"
|
||||
style="@style/Widget.Session.Button.Common.DestructiveOutline"
|
||||
style="@style/Widget.Session.Button.Common.DangerOutline"
|
||||
android:contentDescription="@string/AccessibilityId_decline_message_request_button"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/medium_button_height"
|
||||
|
@ -51,7 +51,7 @@
|
||||
<Button
|
||||
android:contentDescription="@string/AccessibilityId_clear_all_message_requests"
|
||||
android:id="@+id/clearAllMessageRequestsButton"
|
||||
style="@style/Widget.Session.Button.Common.DestructiveOutline"
|
||||
style="@style/Widget.Session.Button.Common.DangerOutline"
|
||||
android:layout_width="196dp"
|
||||
android:layout_height="@dimen/medium_button_height"
|
||||
android:layout_alignParentBottom="true"
|
||||
|
@ -175,7 +175,7 @@
|
||||
android:src="@drawable/ic_baseline_call_end_24"
|
||||
android:padding="@dimen/medium_spacing"
|
||||
android:foregroundTint="@color/call_action_foreground"
|
||||
android:backgroundTint="@color/destructive"
|
||||
android:backgroundTint="?danger"
|
||||
android:layout_width="@dimen/large_button_height"
|
||||
android:layout_height="@dimen/large_button_height"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
@ -265,7 +265,7 @@
|
||||
android:src="@drawable/ic_baseline_call_end_24"
|
||||
android:padding="@dimen/medium_spacing"
|
||||
android:foregroundTint="@color/call_action_foreground"
|
||||
android:backgroundTint="@color/destructive"
|
||||
android:backgroundTint="?danger"
|
||||
android:layout_width="@dimen/large_button_height"
|
||||
android:layout_height="@dimen/large_button_height"
|
||||
android:layout_marginBottom="@dimen/very_large_spacing"
|
||||
|
@ -9,7 +9,7 @@
|
||||
android:layout_marginHorizontal="@dimen/large_spacing"
|
||||
android:layout_marginVertical="@dimen/medium_spacing"
|
||||
android:text="@string/blocked_contacts_title"
|
||||
android:textColor="@color/destructive"
|
||||
android:textColor="?danger"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
/>
|
||||
|
@ -44,7 +44,7 @@
|
||||
android:orientation="horizontal">
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.DestructiveText"
|
||||
style="@style/Widget.Session.Button.Dialog.DangerText"
|
||||
android:id="@+id/clearAllDataButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dialog_button_height"
|
||||
|
@ -43,7 +43,7 @@
|
||||
android:text="@string/cancel" />
|
||||
|
||||
<Button
|
||||
style="@style/Widget.Session.Button.Dialog.DestructiveText"
|
||||
style="@style/Widget.Session.Button.Dialog.DangerText"
|
||||
android:id="@+id/sendSeedButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="@dimen/dialog_button_height"
|
||||
|
@ -62,7 +62,7 @@
|
||||
|
||||
<TextView
|
||||
style="@style/Widget.Session.Button.Common.ProminentFilled"
|
||||
android:backgroundTint="@color/destructive"
|
||||
android:backgroundTint="?danger"
|
||||
android:layout_marginHorizontal="@dimen/small_spacing"
|
||||
android:id="@+id/declineButton"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -5,7 +5,7 @@
|
||||
android:id="@+id/rootLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?conversation_menu_background_color">
|
||||
android:background="@drawable/sheet_rounded_bg">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleText"
|
||||
|
@ -14,14 +14,14 @@
|
||||
android:contentDescription="@string/AccessibilityId_delete_just_for_me"
|
||||
style="@style/BottomSheetActionItem"
|
||||
android:text="@string/delete_message_for_me"
|
||||
android:textColor="@color/destructive"/>
|
||||
android:textColor="?danger"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/deleteForEveryoneTextView"
|
||||
android:contentDescription="@string/delete_message_for_everyone"
|
||||
style="@style/BottomSheetActionItem"
|
||||
android:text="@string/delete_message_for_everyone"
|
||||
android:textColor="@color/destructive"/>
|
||||
android:textColor="?danger"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/cancelTextView"
|
||||
|
@ -3,7 +3,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?conversation_menu_background_color">
|
||||
android:background="@drawable/sheet_rounded_bg">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleText"
|
||||
|
@ -46,7 +46,7 @@
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:textColor="@color/destructive"
|
||||
android:textColor="?danger"
|
||||
android:id="@+id/cancelButton"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -4,7 +4,7 @@
|
||||
android:id="@+id/rootLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?conversation_menu_background_color">
|
||||
android:background="@drawable/sheet_rounded_bg">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleText"
|
||||
|
@ -13,13 +13,13 @@
|
||||
android:layout_width="13dp"
|
||||
android:layout_height="13dp"
|
||||
android:src="@drawable/ic_baseline_block_24"
|
||||
app:tint="@color/destructive" />
|
||||
app:tint="?danger" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/destructive"
|
||||
android:textColor="?danger"
|
||||
android:textSize="16sp"
|
||||
android:text="@string/recipient_preferences__block"
|
||||
/>
|
||||
|
@ -31,7 +31,7 @@
|
||||
android:layout_height="wrap_content"/>
|
||||
<TextView
|
||||
android:text="@string/message_requests_clear_all"
|
||||
android:textColor="@color/destructive"
|
||||
android:textColor="?danger"
|
||||
android:visibility="gone"
|
||||
android:id="@+id/header_view_clear_all"
|
||||
android:layout_width="wrap_content"
|
||||
|
@ -62,6 +62,7 @@
|
||||
android:textColor="?message_received_text_color"
|
||||
android:textAlignment="center"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center"
|
||||
tools:text="You missed a call"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
@ -35,7 +35,7 @@
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:background="@drawable/circle_tintable"
|
||||
android:backgroundTint="@color/destructive" />
|
||||
android:backgroundTint="?danger" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/recordingViewDurationTextView"
|
||||
@ -121,7 +121,7 @@
|
||||
android:alpha="0.5"
|
||||
android:layout_centerInParent="true"
|
||||
android:background="@drawable/circle_tintable"
|
||||
android:backgroundTint="@color/destructive" />
|
||||
android:backgroundTint="?danger" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
@ -136,7 +136,7 @@
|
||||
android:layout_marginEnd="-8dp"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:background="@drawable/circle_tintable"
|
||||
android:backgroundTint="@color/destructive" >
|
||||
android:backgroundTint="?danger" >
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/recordButtonOverlayImageView"
|
||||
|
@ -32,6 +32,7 @@
|
||||
<attr name="onLightCell" format="reference|color"/>
|
||||
|
||||
<attr name="accentColor" format="reference|color"/>
|
||||
<attr name="danger" format="reference|color"/>
|
||||
<attr name="backgroundSecondary" format="reference|color"/>
|
||||
<attr name="prominentButtonColor" format="reference|color"/>
|
||||
<attr name="elementBorderColor" format="reference|color"/>
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<color name="destructive">#FF453A</color>
|
||||
<color name="unimportant">#D8D8D8</color>
|
||||
<color name="profile_picture_background">#353535</color>
|
||||
<color name="action_bar_background">#161616</color>
|
||||
|
@ -108,9 +108,9 @@
|
||||
<item name="android:textColor">?android:textColorPrimary</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Session.Button.Common.DestructiveOutline">
|
||||
<item name="android:background">@drawable/destructive_outline_button_medium_background</item>
|
||||
<item name="android:textColor">@color/button_destructive</item>
|
||||
<style name="Widget.Session.Button.Common.DangerOutline">
|
||||
<item name="android:background">@drawable/danger_outline_button_medium_background</item>
|
||||
<item name="android:textColor">@color/button_danger</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Session.Button.Dialog" parent="">
|
||||
@ -125,9 +125,9 @@
|
||||
<item name="android:background">@drawable/unimportant_dialog_text_button_background</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Session.Button.Dialog.DestructiveText">
|
||||
<item name="android:background">@drawable/destructive_dialog_text_button_background</item>
|
||||
<item name="android:textColor">@color/destructive</item>
|
||||
<style name="Widget.Session.Button.Dialog.DangerText">
|
||||
<item name="android:background">@drawable/danger_dialog_text_button_background</item>
|
||||
<item name="android:textColor">?danger</item>
|
||||
</style>
|
||||
|
||||
<style name="Widget.Session.EditText.Compose" parent="@style/Signal.Text.Body">
|
||||
|
@ -58,7 +58,7 @@
|
||||
<item name="prominentButtonColor">?colorAccent</item>
|
||||
<item name="attachment_document_icon_small">@drawable/ic_document_small_dark</item>
|
||||
<item name="attachment_document_icon_large">@drawable/ic_document_large_dark</item>
|
||||
<item name="colorError">@color/destructive</item>
|
||||
<item name="colorError">?danger</item>
|
||||
</style>
|
||||
|
||||
<!-- This should be the default theme for the application. -->
|
||||
@ -318,6 +318,7 @@
|
||||
<item name="backgroundSecondary">@color/classic_dark_1</item>
|
||||
<item name="colorControlNormal">?android:textColorPrimary</item>
|
||||
<item name="colorControlActivated">?colorAccent</item>
|
||||
<item name="danger">@color/danger_dark</item>
|
||||
<item name="android:textColorPrimary">@color/classic_dark_6</item>
|
||||
<item name="android:textColorSecondary">?android:textColorPrimary</item>
|
||||
<item name="android:textColorTertiary">@color/classic_dark_5</item>
|
||||
@ -399,6 +400,7 @@
|
||||
<item name="colorPrimaryDark">@color/classic_light_6</item>
|
||||
<item name="colorControlNormal">?android:textColorPrimary</item>
|
||||
<item name="colorControlActivated">?colorAccent</item>
|
||||
<item name="danger">@color/danger_light</item>
|
||||
<item name="android:textColorPrimary">@color/classic_light_0</item>
|
||||
<item name="android:textColorSecondary">@color/classic_light_1</item>
|
||||
<item name="android:textColorTertiary">@color/classic_light_1</item>
|
||||
@ -488,6 +490,7 @@
|
||||
<item name="backgroundSecondary">@color/ocean_dark_1</item>
|
||||
<item name="colorControlNormal">@color/ocean_dark_7</item>
|
||||
<item name="colorControlActivated">?colorAccent</item>
|
||||
<item name="danger">@color/danger_dark</item>
|
||||
<item name="android:textColorPrimary">@color/ocean_dark_7</item>
|
||||
<item name="android:textColorSecondary">@color/ocean_dark_5</item>
|
||||
<item name="android:textColorTertiary">@color/ocean_dark_5</item>
|
||||
@ -574,6 +577,7 @@
|
||||
<item name="backgroundSecondary">@color/ocean_light_6</item>
|
||||
<item name="colorControlNormal">@color/ocean_light_1</item>
|
||||
<item name="colorControlActivated">?colorAccent</item>
|
||||
<item name="danger">@color/danger_light</item>
|
||||
<item name="android:textColorPrimary">@color/ocean_light_1</item>
|
||||
<item name="android:textColorSecondary">@color/ocean_light_2</item>
|
||||
<item name="android:textColorTertiary">@color/ocean_light_2</item>
|
||||
@ -686,6 +690,7 @@
|
||||
<item name="actionBarStyle">@style/Widget.Session.ActionBar</item>
|
||||
<item name="prominentButtonColor">?colorAccent</item>
|
||||
<item name="elementBorderColor">@color/classic_dark_3</item>
|
||||
<item name="danger">@color/danger_dark</item>
|
||||
|
||||
<!-- Home screen -->
|
||||
<item name="searchBackgroundColor">#1B1B1B</item>
|
||||
|
@ -25,7 +25,7 @@ import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsignal.utilities.guava.Optional
|
||||
import org.thoughtcrime.securesms.MainCoroutineRule
|
||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.ExpiryRadioOption
|
||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.OptionsCard
|
||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.OptionsCardData
|
||||
import org.thoughtcrime.securesms.conversation.disappearingmessages.ui.UiState
|
||||
import org.thoughtcrime.securesms.database.GroupDatabase
|
||||
import org.thoughtcrime.securesms.database.Storage
|
||||
@ -87,7 +87,7 @@ class DisappearingMessagesViewModelTest {
|
||||
viewModel.uiState.value
|
||||
).isEqualTo(
|
||||
UiState(
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_timer,
|
||||
typeOption(ExpiryMode.NONE, selected = true),
|
||||
timeOption(ExpiryType.AFTER_SEND, 12.hours),
|
||||
@ -126,7 +126,7 @@ class DisappearingMessagesViewModelTest {
|
||||
viewModel.uiState.value
|
||||
).isEqualTo(
|
||||
UiState(
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_timer,
|
||||
typeOption(ExpiryMode.NONE, selected = false),
|
||||
timeOption(ExpiryType.LEGACY, 12.hours),
|
||||
@ -165,7 +165,7 @@ class DisappearingMessagesViewModelTest {
|
||||
viewModel.uiState.value
|
||||
).isEqualTo(
|
||||
UiState(
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_timer,
|
||||
typeOption(ExpiryMode.NONE, selected = true),
|
||||
timeOption(ExpiryType.AFTER_SEND, 12.hours),
|
||||
@ -205,7 +205,7 @@ class DisappearingMessagesViewModelTest {
|
||||
viewModel.uiState.value
|
||||
).isEqualTo(
|
||||
UiState(
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_timer,
|
||||
typeOption(ExpiryMode.NONE, enabled = false, selected = true),
|
||||
timeOption(ExpiryType.AFTER_SEND, 12.hours, enabled = false),
|
||||
@ -247,7 +247,7 @@ class DisappearingMessagesViewModelTest {
|
||||
viewModel.uiState.value
|
||||
).isEqualTo(
|
||||
UiState(
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_delete_type,
|
||||
typeOption(ExpiryMode.NONE, selected = true),
|
||||
typeOption(12.hours, ExpiryType.AFTER_READ),
|
||||
@ -286,13 +286,13 @@ class DisappearingMessagesViewModelTest {
|
||||
viewModel.uiState.value
|
||||
).isEqualTo(
|
||||
UiState(
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_delete_type,
|
||||
typeOption(ExpiryMode.NONE),
|
||||
typeOption(time, ExpiryType.AFTER_READ),
|
||||
typeOption(time, ExpiryType.AFTER_SEND, selected = true)
|
||||
),
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_timer,
|
||||
timeOption(ExpiryType.AFTER_SEND, 12.hours, selected = true),
|
||||
timeOption(ExpiryType.AFTER_SEND, 1.days),
|
||||
@ -332,14 +332,14 @@ class DisappearingMessagesViewModelTest {
|
||||
viewModel.uiState.value
|
||||
).isEqualTo(
|
||||
UiState(
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_delete_type,
|
||||
typeOption(ExpiryMode.NONE),
|
||||
typeOption(time, ExpiryType.LEGACY, selected = true),
|
||||
typeOption(12.hours, ExpiryType.AFTER_READ, enabled = false),
|
||||
typeOption(1.days, ExpiryType.AFTER_SEND, enabled = false)
|
||||
),
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_timer,
|
||||
timeOption(ExpiryType.LEGACY, 12.hours, selected = true),
|
||||
timeOption(ExpiryType.LEGACY, 1.days),
|
||||
@ -379,13 +379,13 @@ class DisappearingMessagesViewModelTest {
|
||||
viewModel.uiState.value
|
||||
).isEqualTo(
|
||||
UiState(
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_delete_type,
|
||||
typeOption(ExpiryMode.NONE),
|
||||
typeOption(12.hours, ExpiryType.AFTER_READ),
|
||||
typeOption(time, ExpiryType.AFTER_SEND, selected = true)
|
||||
),
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_timer,
|
||||
timeOption(ExpiryType.AFTER_SEND, 12.hours),
|
||||
timeOption(ExpiryType.AFTER_SEND, 1.days, selected = true),
|
||||
@ -426,13 +426,13 @@ class DisappearingMessagesViewModelTest {
|
||||
viewModel.uiState.value
|
||||
).isEqualTo(
|
||||
UiState(
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_delete_type,
|
||||
typeOption(ExpiryMode.NONE),
|
||||
typeOption(1.days, ExpiryType.AFTER_READ, selected = true),
|
||||
typeOption(time, ExpiryType.AFTER_SEND)
|
||||
),
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_timer,
|
||||
timeOption(ExpiryType.AFTER_READ, 5.minutes),
|
||||
timeOption(ExpiryType.AFTER_READ, 1.hours),
|
||||
@ -479,13 +479,13 @@ class DisappearingMessagesViewModelTest {
|
||||
viewModel.uiState.value
|
||||
).isEqualTo(
|
||||
UiState(
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_delete_type,
|
||||
typeOption(ExpiryMode.NONE),
|
||||
typeOption(12.hours, ExpiryType.AFTER_READ),
|
||||
typeOption(1.days, ExpiryType.AFTER_SEND, selected = true)
|
||||
),
|
||||
OptionsCard(
|
||||
OptionsCardData(
|
||||
R.string.activity_disappearing_messages_timer,
|
||||
timeOption(ExpiryType.AFTER_SEND, 12.hours),
|
||||
timeOption(ExpiryType.AFTER_SEND, 1.days, selected = true),
|
||||
|
@ -1,6 +1,5 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<resources>
|
||||
<color name="destructive">#FF453A</color>
|
||||
<color name="unimportant">#D8D8D8</color>
|
||||
<color name="profile_picture_background">#353535</color>
|
||||
<color name="cell_background">#1B1B1B</color>
|
||||
|
Loading…
x
Reference in New Issue
Block a user