From 9e2b24f7b9f0e8a0caf3aa6b0a6f3fe70a1073fd Mon Sep 17 00:00:00 2001 From: ThomasSession Date: Thu, 18 Jul 2024 16:32:03 +1000 Subject: [PATCH] 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 --- app/build.gradle | 2 +- .../securesms/SessionDialogBuilder.kt | 4 +- .../securesms/components/menu/ActionItem.kt | 4 +- .../components/menu/ContextMenuList.kt | 2 +- .../DisappearingMessages.kt | 3 +- .../disappearingmessages/ui/Adapter.kt | 4 +- .../ui/DisappearingMessages.kt | 32 ++- .../ui/DisappearingMessagesPreview.kt | 8 +- .../disappearingmessages/ui/UiState.kt | 8 +- .../start/home/StartConversation.kt | 39 +-- .../start/invitefriend/InviteFriend.kt | 34 +-- .../start/newmessage/NewMessage.kt | 65 ++--- .../start/newmessage/NewMessageViewModel.kt | 5 +- .../conversation/v2/ConversationActivityV2.kt | 4 +- .../v2/ConversationReactionOverlay.kt | 3 +- .../conversation/v2/MessageDetailActivity.kt | 59 +++-- .../v2/messages/VisibleMessageView.kt | 3 +- .../securesms/home/ConversationView.kt | 5 +- .../thoughtcrime/securesms/home/EmptyView.kt | 38 ++- .../securesms/home/SeedReminder.kt | 29 ++- .../messagerequests/MessageRequestsAdapter.kt | 6 +- .../OnboardingBackPressAlertDialog.kt | 2 +- .../securesms/onboarding/landing/Landing.kt | 55 ++--- .../onboarding/loadaccount/LoadAccount.kt | 27 +- .../securesms/onboarding/loading/Loading.kt | 13 +- .../MessageNotifications.kt | 50 ++-- .../onboarding/pickname/PickDisplayName.kt | 25 +- .../securesms/onboarding/ui/ContinueButton.kt | 6 +- .../securesms/preferences/QRCodeActivity.kt | 16 +- .../securesms/preferences/SettingsActivity.kt | 16 +- .../appearance/AppearanceSettingsViewModel.kt | 7 + .../recoverypassword/RecoveryPassword.kt | 47 ++-- .../RecoveryPasswordActivity.kt | 4 +- .../thoughtcrime/securesms/ui/AlertDialog.kt | 127 +++++++--- .../org/thoughtcrime/securesms/ui/Carousel.kt | 39 ++- .../thoughtcrime/securesms/ui/Components.kt | 170 ++++++------- .../thoughtcrime/securesms/ui/Dimensions.kt | 32 --- .../securesms/ui/SessionTypography.kt | 59 ----- .../org/thoughtcrime/securesms/ui/Util.kt | 1 + .../thoughtcrime/securesms/ui/color/Colors.kt | 233 ------------------ .../ui/color/ColorsFromPreferences.kt | 34 --- .../securesms/ui/components/AppBar.kt | 20 +- .../securesms/ui/components/Border.kt | 6 +- .../securesms/ui/components/Button.kt | 43 ++-- .../securesms/ui/components/ButtonStyle.kt | 31 ++- .../securesms/ui/components/ButtonType.kt | 25 +- .../components/CircularProgressIndicator.kt | 6 +- .../securesms/ui/components/QR.kt | 46 ++-- .../securesms/ui/components/QrImage.kt | 17 +- .../securesms/ui/components/RadioButton.kt | 126 +++++++++- .../securesms/ui/components/SessionTabRow.kt | 45 ++-- .../securesms/ui/components/Text.kt | 32 +-- .../{color/ColorDefs.kt => theme/Colors.kt} | 2 +- .../securesms/ui/theme/Dimensions.kt | 24 ++ .../securesms/ui/theme/SessionTypography.kt | 145 +++++++++++ .../securesms/ui/theme/ThemeColorSet.kt | 10 + .../securesms/ui/theme/ThemeColors.kt | 206 ++++++++++++++++ .../ui/theme/ThemeFromPreferences.kt | 65 +++++ .../securesms/ui/{ => theme}/Themes.kt | 66 +++-- ...tton_destructive.xml => button_danger.xml} | 2 +- .../state_list_call_action_mic_background.xml | 2 +- ...ml => danger_dialog_button_background.xml} | 4 +- ... danger_dialog_text_button_background.xml} | 0 ...nger_outline_button_medium_background.xml} | 4 +- app/src/main/res/drawable/ic_clear_data.xml | 11 - app/src/main/res/drawable/ic_delete_24.xml | 2 +- .../main/res/drawable/sheet_rounded_bg.xml | 5 + .../res/layout/activity_blocked_contacts.xml | 2 +- .../res/layout/activity_conversation_v2.xml | 6 +- .../res/layout/activity_message_requests.xml | 2 +- app/src/main/res/layout/activity_webrtc.xml | 4 +- .../layout/blocked_contacts_preference.xml | 2 +- .../main/res/layout/dialog_clear_all_data.xml | 2 +- app/src/main/res/layout/dialog_send_seed.xml | 2 +- .../res/layout/fragment_call_bottom_sheet.xml | 2 +- .../main/res/layout/fragment_create_group.xml | 2 +- .../fragment_delete_message_bottom_sheet.xml | 4 +- .../res/layout/fragment_join_community.xml | 2 +- .../fragment_modal_url_bottom_sheet.xml | 2 +- .../main/res/layout/fragment_new_message.xml | 2 +- .../layout/layout_conversation_block_icon.xml | 4 +- ..._sheet_dialog_fragment_recycler_header.xml | 2 +- .../main/res/layout/view_control_message.xml | 1 + .../res/layout/view_input_bar_recording.xml | 6 +- app/src/main/res/values/attrs.xml | 1 + app/src/main/res/values/colors.xml | 1 - app/src/main/res/values/styles.xml | 12 +- app/src/main/res/values/themes.xml | 7 +- .../DisappearingMessagesViewModelTest.kt | 32 +-- libsession/src/main/res/values/colors.xml | 1 - 90 files changed, 1308 insertions(+), 1058 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/ui/Dimensions.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/ui/SessionTypography.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/ui/color/Colors.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/ui/color/ColorsFromPreferences.kt rename app/src/main/java/org/thoughtcrime/securesms/ui/{color/ColorDefs.kt => theme/Colors.kt} (97%) create mode 100644 app/src/main/java/org/thoughtcrime/securesms/ui/theme/Dimensions.kt create mode 100644 app/src/main/java/org/thoughtcrime/securesms/ui/theme/SessionTypography.kt create mode 100644 app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColorSet.kt create mode 100644 app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColors.kt create mode 100644 app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeFromPreferences.kt rename app/src/main/java/org/thoughtcrime/securesms/ui/{ => theme}/Themes.kt (55%) rename app/src/main/res/color/{button_destructive.xml => button_danger.xml} (81%) rename app/src/main/res/drawable/{destructive_dialog_button_background.xml => danger_dialog_button_background.xml} (78%) rename app/src/main/res/drawable/{destructive_dialog_text_button_background.xml => danger_dialog_text_button_background.xml} (100%) rename app/src/main/res/drawable/{destructive_outline_button_medium_background.xml => danger_outline_button_medium_background.xml} (79%) delete mode 100644 app/src/main/res/drawable/ic_clear_data.xml create mode 100644 app/src/main/res/drawable/sheet_rounded_bg.xml diff --git a/app/build.gradle b/app/build.gradle index c56a2c8e3d9..4cd08255d67 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -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" diff --git a/app/src/main/java/org/thoughtcrime/securesms/SessionDialogBuilder.kt b/app/src/main/java/org/thoughtcrime/securesms/SessionDialogBuilder.kt index fa9cb2e4751..71e04230f2a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/SessionDialogBuilder.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/SessionDialogBuilder.kt @@ -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() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/menu/ActionItem.kt b/app/src/main/java/org/thoughtcrime/securesms/components/menu/ActionItem.kt index 700534fad18..af32b7f50f0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/menu/ActionItem.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/menu/ActionItem.kt @@ -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, ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/menu/ContextMenuList.kt b/app/src/main/java/org/thoughtcrime/securesms/components/menu/ContextMenuList.kt index 69dec0cdd69..7b92e505c6b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/menu/ContextMenuList.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/menu/ContextMenuList.kt @@ -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() diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessages.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessages.kt index d336c967cee..38da11ae24f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessages.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/DisappearingMessages.kt @@ -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 ) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/Adapter.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/Adapter.kt index 6ddc28c688b..d78d33a2f9f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/Adapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/Adapter.kt @@ -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 diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessages.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessages.kt index 51ac1d445e4..ae17e6a09ba 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessages.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessages.kt @@ -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 typealias ExpiryRadioOption = RadioOption @@ -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 ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessagesPreview.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessagesPreview.kt index 20f1821e4ca..d043cc314fd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessagesPreview.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/DisappearingMessagesPreview.kt @@ -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 { @Preview @Composable fun PreviewThemes( - @PreviewParameter(SessionColorsParameterProvider::class) colors: Colors + @PreviewParameter(SessionColorsParameterProvider::class) colors: ThemeColors ) { PreviewTheme(colors) { DisappearingMessages( diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/UiState.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/UiState.kt index 40f917427c6..47159571f84 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/UiState.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/disappearingmessages/ui/UiState.kt @@ -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 +typealias ExpiryOptionsCardData = OptionsCardData data class UiState( - val cards: List = emptyList(), + val cards: List = 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( +data class OptionsCardData( val title: GetString, val options: List> ) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/home/StartConversation.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/home/StartConversation.kt index 452968429e8..fcf13c9cf11 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/home/StartConversation.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/home/StartConversation.kt @@ -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( diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/invitefriend/InviteFriend.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/invitefriend/InviteFriend.kt index 256756521ef..54abf663037 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/invitefriend/InviteFriend.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/invitefriend/InviteFriend.kt @@ -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 diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt index 82f9d7ae1fe..97740b2a266 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessage.kt @@ -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")) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageViewModel.kt index a08282da744..65c8dd539aa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/start/newmessage/NewMessageViewModel.kt @@ -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) diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt index 4aeeb66fe8a..62ea2e52d48 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt @@ -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() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt index 56c6540ed5b..9f2046334b5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationReactionOverlay.kt @@ -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)) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt index d43225b5d71..9514552d280 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/MessageDetailActivity.kt @@ -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, 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, 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) { 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) { 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) { 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() } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt index 2019867f809..b2e3bba81b4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/v2/messages/VisibleMessageView.kt @@ -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 -> diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt index 4647156a01c..68aea844170 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/ConversationView.kt @@ -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) diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/EmptyView.kt b/app/src/main/java/org/thoughtcrime/securesms/home/EmptyView.kt index 9d078df4f7d..aa4e0d9017e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/EmptyView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/EmptyView.kt @@ -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) diff --git a/app/src/main/java/org/thoughtcrime/securesms/home/SeedReminder.kt b/app/src/main/java/org/thoughtcrime/securesms/home/SeedReminder.kt index 4dccc4224fd..33bdd2f2f60 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/home/SeedReminder.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/home/SeedReminder.kt @@ -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 {} diff --git a/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestsAdapter.kt b/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestsAdapter.kt index 10142cc8fca..3040bb774fd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestsAdapter.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/messagerequests/MessageRequestsAdapter.kt @@ -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) diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/OnboardingBackPressAlertDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/OnboardingBackPressAlertDialog.kt index c620f32b6a0..2820a64a66b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/OnboardingBackPressAlertDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/OnboardingBackPressAlertDialog.kt @@ -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( diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/Landing.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/Landing.kt index 55d0cb14e24..e40328b1d85 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/Landing.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/Landing.kt @@ -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 ) ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccount.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccount.kt index 5fe7b64fce5..cc1033ee964 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccount.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loadaccount/LoadAccount.kt @@ -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) diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/Loading.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/Loading.kt index 30d9a5acdbd..8c2e10e765f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/Loading.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/loading/Loading.kt @@ -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)) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/messagenotifications/MessageNotifications.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/messagenotifications/MessageNotifications.kt index c8cc30ce79e..e56b55aaab7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/messagenotifications/MessageNotifications.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/messagenotifications/MessageNotifications.kt @@ -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() diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayName.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayName.kt index f5e6e1a9a42..04124a5bfdf 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayName.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/pickname/PickDisplayName.kt @@ -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) diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/ui/ContinueButton.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/ui/ContinueButton.kt index d48b5f56ab1..0d31363d76a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/ui/ContinueButton.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/ui/ContinueButton.kt @@ -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, ) } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt index ccf7f9c178e..9778a1c8b8c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/QRCodeActivity.kt @@ -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, 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 ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt index ca69d37bc1f..fc98070ca40 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/SettingsActivity.kt @@ -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() } 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 = callbackFlow { registerReceiver(receiver, IntentFilter("pathsBuilt")) awaitClose { unregisterReceiver(receiver) } -}.onStart { emit(Unit) }.map { OnionRequestAPI.paths.isNotEmpty() } +}.onStart { emit(Unit) }.map { OnionRequestAPI.paths.isNotEmpty() } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/appearance/AppearanceSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/appearance/AppearanceSettingsViewModel.kt index c5694413824..afe33400ffa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/appearance/AppearanceSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/appearance/AppearanceSettingsViewModel.kt @@ -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 } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPassword.kt b/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPassword.kt index 2868bfbfd90..5f59943432b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPassword.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPassword.kt @@ -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") diff --git a/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordActivity.kt index 8d1a80fb0cd..a46b4a1d633 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/recoverypassword/RecoveryPasswordActivity.kt @@ -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 ) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/AlertDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/AlertDialog.kt index 121748809f1..df66cef4718 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/AlertDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/AlertDialog.kt @@ -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? = null + buttons: List? = 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 = {} + ) + } +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/Carousel.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/Carousel.kt index e3ffff66d0a..ea632d46e78 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/Carousel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/Carousel.kt @@ -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, diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/Components.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/Components.kt index 31ce715a8fa..daeb6b853db 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/Components.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/Components.kt @@ -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( ) @Composable -fun OptionsCard(card: OptionsCard, callbacks: Callbacks) { - 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 OptionsCard(card: OptionsCardData, callbacks: Callbacks) { + 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 TitledRadioButton(option: RadioOption, 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 ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/Dimensions.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/Dimensions.kt deleted file mode 100644 index 0a04880e8a9..00000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/Dimensions.kt +++ /dev/null @@ -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 -) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/SessionTypography.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/SessionTypography.kt deleted file mode 100644 index 426c6f8dc4a..00000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/SessionTypography.kt +++ /dev/null @@ -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, -) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/Util.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/Util.kt index d7aaf5430c1..b49f9c6d606 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/Util.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/Util.kt @@ -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) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/color/Colors.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/color/Colors.kt deleted file mode 100644 index 9aab573cee3..00000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/color/Colors.kt +++ /dev/null @@ -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 { 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) { - 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) -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/color/ColorsFromPreferences.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/color/ColorsFromPreferences.kt deleted file mode 100644 index a65c08cba05..00000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/color/ColorsFromPreferences.kt +++ /dev/null @@ -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 -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/AppBar.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/AppBar.kt index 10692750560..b64a482d8a1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/AppBar.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/AppBar.kt @@ -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) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Border.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Border.kt index 4039f84ec6e..4420e91e78a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Border.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Border.kt @@ -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( diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Button.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Button.kt index 23aee8c0110..5834f2f859b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Button.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Button.kt @@ -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( diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/ButtonStyle.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/ButtonStyle.kt index 3f566911db4..e8fcca06cf4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/ButtonStyle.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/ButtonStyle.kt @@ -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 } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/ButtonType.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/ButtonType.kt index e941ab4e83a..54478e69b5d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/ButtonType.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/ButtonType.kt @@ -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 ) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/CircularProgressIndicator.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/CircularProgressIndicator.kt index 259bbfe1700..bbad82d29e4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/CircularProgressIndicator.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/CircularProgressIndicator.kt @@ -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 diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/QR.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/QR.kt index 2d95a13d5ce..c58f7dc97ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/QR.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/QR.kt @@ -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, 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, 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, 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) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/QrImage.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/QrImage.kt index 48d81aa7231..c5f927b4abd 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/QrImage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/QrImage.kt @@ -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) } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/RadioButton.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/RadioButton.kt index 8058459a7cf..154c9ea3a1f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/RadioButton.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/RadioButton.kt @@ -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 TitledRadioButton( + modifier: Modifier = Modifier, + option: RadioOption, + 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( + 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( + 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( + value = ExpiryType.AFTER_SEND.mode(7.days), + title = GetString(7.days), + subtitle = GetString("This is a subtitle"), + enabled = true, + selected = false + ) + ) {} + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/SessionTabRow.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/SessionTabRow.kt index 5a3956922e7..5dae714380b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/SessionTabRow.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/SessionTabRow.kt @@ -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) { 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) { @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 } diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt index b6a12a792de..5e09f78b65b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/components/Text.kt @@ -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 ) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/color/ColorDefs.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Colors.kt similarity index 97% rename from app/src/main/java/org/thoughtcrime/securesms/ui/color/ColorDefs.kt rename to app/src/main/java/org/thoughtcrime/securesms/ui/theme/Colors.kt index 3e23985af3e..0b630ab233c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/color/ColorDefs.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Colors.kt @@ -1,4 +1,4 @@ -package org.thoughtcrime.securesms.ui.color +package org.thoughtcrime.securesms.ui.theme import androidx.compose.ui.graphics.Color diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Dimensions.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Dimensions.kt new file mode 100644 index 00000000000..66e5b74e8bc --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Dimensions.kt @@ -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 +) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/SessionTypography.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/SessionTypography.kt new file mode 100644 index 00000000000..602affa6afc --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/SessionTypography.kt @@ -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 + ) +} + + diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColorSet.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColorSet.kt new file mode 100644 index 00000000000..3ff4d55b610 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColorSet.kt @@ -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 +) \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColors.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColors.kt new file mode 100644 index 00000000000..8d080b65b74 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColors.kt @@ -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) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeFromPreferences.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeFromPreferences.kt new file mode 100644 index 00000000000..8988e84ca72 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeFromPreferences.kt @@ -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 +} + + + diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/Themes.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Themes.kt similarity index 55% rename from app/src/main/java/org/thoughtcrime/securesms/ui/Themes.kt rename to app/src/main/java/org/thoughtcrime/securesms/ui/theme/Themes.kt index 22050a27648..87e91e0ab0b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/Themes.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Themes.kt @@ -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 { 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 { +// used for previews +class SessionColorsParameterProvider : PreviewParameterProvider { override val values = sequenceOf(ClassicDark(), ClassicLight(), OceanDark(), OceanLight()) } diff --git a/app/src/main/res/color/button_destructive.xml b/app/src/main/res/color/button_danger.xml similarity index 81% rename from app/src/main/res/color/button_destructive.xml rename to app/src/main/res/color/button_danger.xml index cefbfed23a6..d1d41b95e5d 100644 --- a/app/src/main/res/color/button_destructive.xml +++ b/app/src/main/res/color/button_danger.xml @@ -1,5 +1,5 @@ - + diff --git a/app/src/main/res/color/state_list_call_action_mic_background.xml b/app/src/main/res/color/state_list_call_action_mic_background.xml index 1e40a3a054d..f8ec990e18b 100644 --- a/app/src/main/res/color/state_list_call_action_mic_background.xml +++ b/app/src/main/res/color/state_list_call_action_mic_background.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/app/src/main/res/drawable/destructive_dialog_button_background.xml b/app/src/main/res/drawable/danger_dialog_button_background.xml similarity index 78% rename from app/src/main/res/drawable/destructive_dialog_button_background.xml rename to app/src/main/res/drawable/danger_dialog_button_background.xml index 9d3ac00b075..0f72e98c740 100644 --- a/app/src/main/res/drawable/destructive_dialog_button_background.xml +++ b/app/src/main/res/drawable/danger_dialog_button_background.xml @@ -3,9 +3,9 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> - + - + \ No newline at end of file diff --git a/app/src/main/res/drawable/destructive_dialog_text_button_background.xml b/app/src/main/res/drawable/danger_dialog_text_button_background.xml similarity index 100% rename from app/src/main/res/drawable/destructive_dialog_text_button_background.xml rename to app/src/main/res/drawable/danger_dialog_text_button_background.xml diff --git a/app/src/main/res/drawable/destructive_outline_button_medium_background.xml b/app/src/main/res/drawable/danger_outline_button_medium_background.xml similarity index 79% rename from app/src/main/res/drawable/destructive_outline_button_medium_background.xml rename to app/src/main/res/drawable/danger_outline_button_medium_background.xml index c6e01ef98ed..7894c24be83 100644 --- a/app/src/main/res/drawable/destructive_outline_button_medium_background.xml +++ b/app/src/main/res/drawable/danger_outline_button_medium_background.xml @@ -1,12 +1,12 @@ + android:color="@color/button_danger"> diff --git a/app/src/main/res/drawable/ic_clear_data.xml b/app/src/main/res/drawable/ic_clear_data.xml deleted file mode 100644 index 84465dd4cb4..00000000000 --- a/app/src/main/res/drawable/ic_clear_data.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - diff --git a/app/src/main/res/drawable/ic_delete_24.xml b/app/src/main/res/drawable/ic_delete_24.xml index 178806738a3..48fa95783f2 100644 --- a/app/src/main/res/drawable/ic_delete_24.xml +++ b/app/src/main/res/drawable/ic_delete_24.xml @@ -3,7 +3,7 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24" - android:tint="@color/destructive"> + android:tint="?danger"> diff --git a/app/src/main/res/drawable/sheet_rounded_bg.xml b/app/src/main/res/drawable/sheet_rounded_bg.xml new file mode 100644 index 00000000000..848b177f4f8 --- /dev/null +++ b/app/src/main/res/drawable/sheet_rounded_bg.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_blocked_contacts.xml b/app/src/main/res/layout/activity_blocked_contacts.xml index 8d960ad231d..8bc458da028 100644 --- a/app/src/main/res/layout/activity_blocked_contacts.xml +++ b/app/src/main/res/layout/activity_blocked_contacts.xml @@ -39,7 +39,7 @@ /> @@ -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 @@