Remove MaterialTheme usages

This commit is contained in:
Andrew 2024-06-14 00:51:23 +09:30
parent 96157d65a6
commit 4e4ffc02ec
29 changed files with 792 additions and 706 deletions

View File

@ -12,7 +12,6 @@ import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
@ -20,11 +19,11 @@ 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.LocalColors
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.NoOpCallbacks
import org.thoughtcrime.securesms.ui.OptionsCard
import org.thoughtcrime.securesms.ui.RadioOption
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedButton
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.extraSmall
import org.thoughtcrime.securesms.ui.fadingEdges
@ -55,16 +54,16 @@ fun DisappearingMessages(
if (state.showGroupFooter) Text(
text = stringResource(R.string.activity_disappearing_messages_group_footer),
style = MaterialTheme.typography.extraSmall,
style = extraSmall,
fontWeight = FontWeight(400),
color = LocalColors.current.textSecondary,
color = LocalPalette.current.textSecondary,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth())
}
}
if (state.showSetButton) OutlineButton(
textId = R.string.disappearing_messages_set_button_title,
if (state.showSetButton) SessionOutlinedButton(
stringResource(R.string.disappearing_messages_set_button_title),
modifier = Modifier
.contentDescription(R.string.AccessibilityId_set_button)
.align(Alignment.CenterHorizontally)

View File

@ -11,7 +11,7 @@ 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.SessionColors
import org.thoughtcrime.securesms.ui.Palette
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
@Preview(widthDp = 450, heightDp = 700)
@ -51,9 +51,9 @@ class StatePreviewParameterProvider : PreviewParameterProvider<State> {
@Preview
@Composable
fun PreviewThemes(
@PreviewParameter(SessionColorsParameterProvider::class) sessionColors: SessionColors
@PreviewParameter(SessionColorsParameterProvider::class) palette: Palette
) {
PreviewTheme(sessionColors) {
PreviewTheme(palette) {
DisappearingMessages(
State(expiryMode = ExpiryMode.AfterSend(43200)).toUiState(),
modifier = Modifier.size(400.dp, 600.dp)

View File

@ -42,16 +42,17 @@ import org.thoughtcrime.securesms.conversation.v2.ConversationActivityV2
import org.thoughtcrime.securesms.dependencies.DatabaseComponent
import org.thoughtcrime.securesms.showOpenUrlDialog
import org.thoughtcrime.securesms.ui.LoadingArcOr
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionColors
import org.thoughtcrime.securesms.ui.Palette
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
import org.thoughtcrime.securesms.ui.components.AppBar
import org.thoughtcrime.securesms.ui.components.BorderlessButtonWithIcon
import org.thoughtcrime.securesms.ui.components.MaybeScanQrCode
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.MediumButtonSize
import org.thoughtcrime.securesms.ui.components.SessionButtonText
import org.thoughtcrime.securesms.ui.components.SessionOutlinedButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedTextField
import org.thoughtcrime.securesms.ui.components.SessionTabRow
import org.thoughtcrime.securesms.ui.contentDescription
@ -102,9 +103,9 @@ class NewMessageFragment : Fragment() {
@Preview
@Composable
private fun PreviewNewMessage(
@PreviewParameter(SessionColorsParameterProvider::class) sessionColors: SessionColors
@PreviewParameter(SessionColorsParameterProvider::class) palette: Palette
) {
PreviewTheme(sessionColors) {
PreviewTheme(palette) {
NewMessage(State())
}
}
@ -123,7 +124,7 @@ private fun NewMessage(
) {
val pagerState = rememberPagerState { TITLES.size }
Column(modifier = Modifier.background(LocalColors.current.backgroundSecondary)) {
Column(modifier = Modifier.background(LocalPalette.current.backgroundSecondary)) {
AppBar(stringResource(R.string.messageNew), onClose = onClose, onBack = onBack)
SessionTabRow(pagerState, TITLES)
HorizontalPager(pagerState) {
@ -162,7 +163,7 @@ fun EnterAccountId(
BorderlessButtonWithIcon(
text = stringResource(R.string.messageNewDescription),
iconRes = R.drawable.ic_circle_question_mark,
contentColor = LocalColors.current.textSecondary,
contentColor = LocalPalette.current.textSecondary,
modifier = Modifier
.contentDescription(R.string.AccessibilityId_help_desk_link)
.fillMaxWidth()
@ -170,12 +171,13 @@ fun EnterAccountId(
) { onHelp() }
}
OutlineButton(
SessionOutlinedButton(
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(horizontal = LocalDimensions.current.marginLarge)
.fillMaxWidth()
.contentDescription(R.string.next),
size = MediumButtonSize,
enabled = state.isNextButtonEnabled,
onClick = { callbacks.onContinue() }
) {

View File

@ -14,9 +14,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.primarySurface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -31,12 +29,14 @@ import network.loki.messenger.R
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.preferences.copyPublicKey
import org.thoughtcrime.securesms.preferences.sendInvitationToUseSession
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.components.AppBar
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.OutlineCopyButton
import org.thoughtcrime.securesms.ui.components.SmallButtons
import org.thoughtcrime.securesms.ui.components.MediumButtonSize
import org.thoughtcrime.securesms.ui.components.SessionOutlinedCopyButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedButton
import org.thoughtcrime.securesms.ui.components.SmallButtonSize
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.onCreateView
import org.thoughtcrime.securesms.ui.small
@ -62,7 +62,9 @@ class InviteFriendFragment : Fragment() {
@Preview
@Composable
private fun PreviewInviteFriend() {
InviteFriend("050000000")
PreviewTheme {
InviteFriend("050000000")
}
}
@Composable
@ -73,7 +75,7 @@ private fun InviteFriend(
copyPublicKey: () -> Unit = {},
sendInvitation: () -> Unit = {},
) {
Column(modifier = Modifier.background(MaterialTheme.colors.primarySurface)) {
Column(modifier = Modifier.background(LocalPalette.current.backgroundSecondary)) {
AppBar(stringResource(R.string.invite_a_friend), onBack = onBack, onClose = onClose)
Column(
modifier = Modifier.padding(horizontal = 24.dp),
@ -83,7 +85,7 @@ private fun InviteFriend(
modifier = Modifier
.border(
width = 1.dp,
color = LocalColors.current.textSecondary,
color = LocalPalette.current.textSecondary,
shape = RoundedCornerShape(size = 13.dp)
)
.fillMaxWidth()
@ -96,32 +98,34 @@ private fun InviteFriend(
.align(Alignment.Center)
.padding(22.dp),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.base
style = base
)
}
Text(
stringResource(R.string.invite_your_friend_to_chat_with_you_on_session_by_sharing_your_account_id_with_them),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.small,
color = LocalColors.current.textSecondary,
style = small,
color = LocalPalette.current.textSecondary,
modifier = Modifier.padding(horizontal = 8.dp)
)
SmallButtons {
Row(horizontalArrangement = spacedBy(20.dp)) {
OutlineButton(
modifier = Modifier
.weight(1f)
.contentDescription("Share button"),
text = stringResource(R.string.share),
onClick = sendInvitation
)
Row(horizontalArrangement = spacedBy(20.dp)) {
SessionOutlinedButton(
stringResource(R.string.share),
modifier = Modifier
.weight(1f)
.contentDescription("Share button"),
size = MediumButtonSize,
color = LocalPalette.current.text,
onClick = sendInvitation
)
OutlineCopyButton(
modifier = Modifier.weight(1f),
onClick = copyPublicKey
)
}
SessionOutlinedCopyButton(
modifier = Modifier.weight(1f),
size = MediumButtonSize,
color = LocalPalette.current.text,
onClick = copyPublicKey
)
}
}
}

View File

@ -11,7 +11,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.material.primarySurface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
@ -21,7 +20,7 @@ import network.loki.messenger.R
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.ui.Divider
import org.thoughtcrime.securesms.ui.ItemButton
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.components.AppBar
import org.thoughtcrime.securesms.ui.components.QrImage
@ -47,7 +46,7 @@ class NewConversationHomeFragment : Fragment() {
@Composable
fun NewConversationScreen() {
Column(modifier = Modifier.background(MaterialTheme.colors.primarySurface)) {
Column(modifier = Modifier.background(LocalPalette.current.backgroundSecondary)) {
AppBar(stringResource(R.string.dialog_new_conversation_title), onClose = { delegate.onDialogClosePressed() })
ItemButton(textId = R.string.messageNew, icon = R.drawable.ic_message) { delegate.onNewMessageSelected() }
Divider(startIndent = LocalDimensions.current.dividerIndent)
@ -63,13 +62,13 @@ class NewConversationHomeFragment : Fragment() {
) {
Text(
text = stringResource(R.string.accountIdYours),
style = MaterialTheme.typography.xl
style = xl
)
Spacer(modifier = Modifier.height(LocalDimensions.current.itemSpacingTiny))
Text(
text = stringResource(R.string.qrYoursDescription),
color = LocalColors.current.textSecondary,
style = MaterialTheme.typography.small
color = LocalPalette.current.textSecondary,
style = small
)
Spacer(modifier = Modifier.height(LocalDimensions.current.itemSpacingSmall))
QrImage(string = TextSecurePreferences.getLocalNumber(requireContext())!!, Modifier.contentDescription(R.string.AccessibilityId_qr_code))

View File

@ -38,7 +38,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
@ -66,11 +65,10 @@ 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.LocalColors
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionColors
import org.thoughtcrime.securesms.ui.Palette
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
import org.thoughtcrime.securesms.ui.SessionMaterialTheme
import org.thoughtcrime.securesms.ui.TitledText
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.baseMonospace
@ -314,9 +312,9 @@ fun ExpandButton(modifier: Modifier = Modifier, onClick: () -> Unit) {
@Preview
@Composable
fun PreviewMessageDetails(
@PreviewParameter(SessionColorsParameterProvider::class) sessionColors: SessionColors
@PreviewParameter(SessionColorsParameterProvider::class) palette: Palette
) {
PreviewTheme(sessionColors) {
PreviewTheme(palette) {
MessageDetails(
state = MessageDetailsState(
nonImageAttachmentFileDetails = listOf(
@ -363,7 +361,7 @@ fun FileDetails(fileDetails: List<TitledText>) {
fun TitledErrorText(titledText: TitledText?) {
TitledText(
titledText,
style = MaterialTheme.typography.base.copy(color = LocalColors.current.danger)
style = base.copy(color = LocalPalette.current.danger)
)
}
@ -371,7 +369,7 @@ fun TitledErrorText(titledText: TitledText?) {
fun TitledMonospaceText(titledText: TitledText?) {
TitledText(
titledText,
style = MaterialTheme.typography.baseMonospace
style = baseMonospace
)
}
@ -379,7 +377,7 @@ fun TitledMonospaceText(titledText: TitledText?) {
fun TitledText(
titledText: TitledText?,
modifier: Modifier = Modifier,
style: TextStyle = MaterialTheme.typography.base,
style: TextStyle = base,
) {
titledText?.apply {
TitledView(title, modifier) {

View File

@ -16,9 +16,11 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.requiredWidth
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
@ -26,7 +28,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
@ -95,16 +96,16 @@ import org.thoughtcrime.securesms.preferences.SettingsActivity
import org.thoughtcrime.securesms.showMuteDialog
import org.thoughtcrime.securesms.showSessionDialog
import org.thoughtcrime.securesms.ui.Divider
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionColors
import org.thoughtcrime.securesms.ui.Palette
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
import org.thoughtcrime.securesms.ui.SessionMaterialTheme
import org.thoughtcrime.securesms.ui.SessionShieldIcon
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedButton
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.h4
import org.thoughtcrime.securesms.ui.h8
import org.thoughtcrime.securesms.ui.setContentWithTheme
import org.thoughtcrime.securesms.ui.small
@ -366,9 +367,9 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
@Preview
@Composable
fun PreviewMessageDetails(
@PreviewParameter(SessionColorsParameterProvider::class) sessionColors: SessionColors
@PreviewParameter(SessionColorsParameterProvider::class) palette: Palette
) {
PreviewTheme(sessionColors) {
PreviewTheme(palette) {
SeedReminder()
}
}
@ -381,11 +382,11 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
Modifier
.fillMaxWidth()
.height(4.dp)
.background(LocalColors.current.primary)
.background(LocalPalette.current.primary)
)
Row(
Modifier
.background(LocalColors.current.backgroundSecondary)
.background(LocalPalette.current.backgroundSecondary)
.padding(
horizontal = LocalDimensions.current.marginSmall,
vertical = LocalDimensions.current.marginExtraSmall
@ -395,19 +396,19 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
Row {
Text(
stringResource(R.string.save_your_recovery_password),
style = MaterialTheme.typography.h8
style = h8
)
Spacer(Modifier.requiredWidth(LocalDimensions.current.itemSpacingExtraSmall))
SessionShieldIcon()
}
Text(
stringResource(R.string.save_your_recovery_password_to_make_sure_you_don_t_lose_access_to_your_account),
style = MaterialTheme.typography.small
style = small
)
}
Spacer(Modifier.width(LocalDimensions.current.marginExtraExtraSmall))
OutlineButton(
textId = R.string.continue_2,
SessionOutlinedButton(
text = stringResource(R.string.continue_2),
modifier = Modifier
.align(Alignment.CenterVertically)
.contentDescription(R.string.AccessibilityId_reveal_recovery_phrase_button),
@ -434,13 +435,13 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
if (newAccount) {
Text(
stringResource(R.string.onboardingAccountCreated),
style = MaterialTheme.typography.h4,
style = h4,
textAlign = TextAlign.Center
)
Text(
stringResource(R.string.welcome_to_session),
style = MaterialTheme.typography.base,
color = LocalColors.current.primary,
style = base,
color = LocalPalette.current.primary,
textAlign = TextAlign.Center
)
}
@ -449,12 +450,12 @@ class HomeActivity : PassphraseRequiredActionBarActivity(),
Text(
stringResource(R.string.conversationsNone),
style = MaterialTheme.typography.h8,
style = h8,
textAlign = TextAlign.Center,
modifier = Modifier.padding(bottom = 12.dp))
Text(
stringResource(R.string.onboardingHitThePlusButton),
style = MaterialTheme.typography.small,
style = small,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.weight(2f))

View File

@ -33,7 +33,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@ -47,15 +46,16 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
import org.thoughtcrime.securesms.onboarding.pickname.startPickDisplayNameActivity
import org.thoughtcrime.securesms.service.KeyCachingService
import org.thoughtcrime.securesms.showOpenUrlDialog
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionColors
import org.thoughtcrime.securesms.ui.Palette
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
import org.thoughtcrime.securesms.ui.components.BorderlessHtmlButton
import org.thoughtcrime.securesms.ui.components.FilledButton
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedButton
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.h4
import org.thoughtcrime.securesms.ui.large
import org.thoughtcrime.securesms.ui.setComposeContent
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo
@ -96,9 +96,9 @@ class LandingActivity : BaseActionBarActivity() {
@Preview
@Composable
private fun LandingScreen(
@PreviewParameter(SessionColorsParameterProvider::class) sessionColors: SessionColors
@PreviewParameter(SessionColorsParameterProvider::class) palette: Palette
) {
PreviewTheme(sessionColors) {
PreviewTheme(palette) {
LandingScreen()
}
}
@ -125,7 +125,7 @@ class LandingActivity : BaseActionBarActivity() {
Text(
stringResource(R.string.onboardingBubblePrivacyInYourPocket),
modifier = Modifier.align(Alignment.CenterHorizontally),
style = MaterialTheme.typography.h4,
style = h4,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.height(LocalDimensions.current.itemSpacingMedium))
@ -162,7 +162,7 @@ class LandingActivity : BaseActionBarActivity() {
onClick = ::startPickDisplayNameActivity
)
Spacer(modifier = Modifier.height(LocalDimensions.current.itemSpacingSmall))
OutlineButton(
SessionOutlinedButton(
text = stringResource(R.string.onboardingAccountExists),
modifier = Modifier
.fillMaxWidth()
@ -224,8 +224,8 @@ 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,
textColor = if (isOutgoing) LocalColors.current.textBubbleSent else LocalColors.current.textBubbleReceived,
color = if (isOutgoing) LocalPalette.current.backgroundBubbleSent else LocalPalette.current.backgroundBubbleReceived,
textColor = if (isOutgoing) LocalPalette.current.textBubbleSent else LocalPalette.current.textBubbleReceived,
modifier = Modifier.align(if (isOutgoing) Alignment.TopEnd else Alignment.TopStart)
)
}
@ -246,7 +246,7 @@ private fun MessageText(
) {
Text(
text,
style = MaterialTheme.typography.large,
style = large,
color = textColor,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp)
)

View File

@ -39,10 +39,11 @@ import org.thoughtcrime.securesms.ui.SessionMaterialTheme
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.baseBold
import org.thoughtcrime.securesms.ui.components.MaybeScanQrCode
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedButton
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.h4
import org.thoughtcrime.securesms.ui.setComposeContent
import org.thoughtcrime.securesms.util.start
import javax.inject.Inject
@ -126,7 +127,7 @@ fun RecoveryPassword(state: LinkDeviceState, onChange: (String) -> Unit = {}, on
Row {
Text(
stringResource(R.string.sessionRecoveryPassword),
style = MaterialTheme.typography.h4
style = h4
)
Spacer(Modifier.width(6.dp))
Icon(
@ -137,7 +138,7 @@ fun RecoveryPassword(state: LinkDeviceState, onChange: (String) -> Unit = {}, on
Spacer(Modifier.size(28.dp))
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 = MaterialTheme.typography.base
style = base
)
Spacer(Modifier.size(24.dp))
SessionOutlinedTextField(
@ -151,8 +152,8 @@ fun RecoveryPassword(state: LinkDeviceState, onChange: (String) -> Unit = {}, on
error = state.error
)
Spacer(Modifier.weight(2f))
OutlineButton(
textId = R.string.continue_2,
SessionOutlinedButton(
stringResource(R.string.continue_2),
modifier = Modifier
.align(Alignment.CenterHorizontally)
.padding(vertical = 20.dp)

View File

@ -110,11 +110,11 @@ class LoadingActivity: BaseActionBarActivity() {
)
Text(
stringResource(R.string.waitOneMoment),
style = MaterialTheme.typography.h7
style = h7
)
Text(
stringResource(R.string.loadAccountProgressMessage),
style = MaterialTheme.typography.base
style = base
)
Spacer(modifier = Modifier.weight(2f))
}

View File

@ -4,31 +4,21 @@ import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.viewModels
import androidx.annotation.StringRes
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedButton
import androidx.compose.material.RadioButton
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import dagger.hilt.android.AndroidEntryPoint
import network.loki.messenger.R
import org.session.libsession.utilities.TextSecurePreferences
@ -36,19 +26,16 @@ import org.thoughtcrime.securesms.ApplicationContext
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.home.HomeActivity
import org.thoughtcrime.securesms.notifications.PushRegistry
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.Palette
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionColors
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
import org.thoughtcrime.securesms.ui.SessionMaterialTheme
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.NotificationRadioButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedButton
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.h8
import org.thoughtcrime.securesms.ui.h9
import org.thoughtcrime.securesms.ui.h4
import org.thoughtcrime.securesms.ui.setComposeContent
import org.thoughtcrime.securesms.ui.small
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo
import javax.inject.Inject
@ -87,9 +74,9 @@ class MessageNotificationsActivity : BaseActionBarActivity() {
@Preview
@Composable
fun MessageNotificationsScreenPreview(
@PreviewParameter(SessionColorsParameterProvider::class) sessionColors: SessionColors
@PreviewParameter(SessionColorsParameterProvider::class) palette: Palette
) {
PreviewTheme(sessionColors) {
PreviewTheme(palette) {
MessageNotificationsScreen()
}
}
@ -103,9 +90,9 @@ fun MessageNotificationsScreen(
Column {
Spacer(Modifier.weight(1f))
Column(modifier = Modifier.padding(horizontal = LocalDimensions.current.marginMedium)) {
Text(stringResource(R.string.notificationsMessage), style = MaterialTheme.typography.h4)
Text(stringResource(R.string.notificationsMessage), style = h4)
Spacer(Modifier.height(LocalDimensions.current.marginExtraSmall))
Text(stringResource(R.string.onboardingMessageNotificationExplaination), style = MaterialTheme.typography.base)
Text(stringResource(R.string.onboardingMessageNotificationExplaination), style = base)
Spacer(Modifier.height(LocalDimensions.current.marginExtraSmall))
NotificationRadioButton(
R.string.activity_pn_mode_fast_mode,
@ -125,8 +112,8 @@ fun MessageNotificationsScreen(
)
}
Spacer(Modifier.weight(1f))
OutlineButton(
textId = R.string.continue_2,
SessionOutlinedButton(
stringResource(R.string.continue_2),
modifier = Modifier
.padding(horizontal = LocalDimensions.current.marginLarge)
.contentDescription(R.string.AccessibilityId_continue)
@ -138,37 +125,6 @@ fun MessageNotificationsScreen(
}
}
@Composable
fun NotificationRadioButton(
@StringRes title: Int,
@StringRes explanation: Int,
@StringRes tag: Int? = null,
@StringRes contentDescription: Int? = null,
selected: Boolean = false,
onClick: () -> Unit = {}
) {
Row {
OutlinedButton(
onClick = onClick,
modifier = Modifier
.weight(1f)
.contentDescription(contentDescription),
colors = ButtonDefaults.outlinedButtonColors(backgroundColor = LocalColors.current.background, contentColor = LocalColors.current.text),
border = if (selected) BorderStroke(ButtonDefaults.OutlinedBorderSize, LocalColors.current.primary) else ButtonDefaults.outlinedBorder,
shape = RoundedCornerShape(8.dp)
) {
Column(
verticalArrangement = Arrangement.spacedBy(6.dp)
) {
Text(stringResource(title), style = MaterialTheme.typography.h8)
Text(stringResource(explanation), style = MaterialTheme.typography.small)
tag?.let { Text(stringResource(it), color = LocalColors.current.primary, style = MaterialTheme.typography.h9) }
}
}
RadioButton(selected = selected, modifier = Modifier.align(Alignment.CenterVertically), onClick = onClick, colors = LocalColors.current.radioButtonColors())
}
}
fun Context.startMessageNotificationsActivity(flags: Int = 0) {
Intent(this, MessageNotificationsActivity::class.java)
.also { it.flags = flags }

View File

@ -30,9 +30,10 @@ import org.thoughtcrime.securesms.onboarding.messagenotifications.startMessageNo
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionMaterialTheme
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedTextField
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.h4
import org.thoughtcrime.securesms.ui.setComposeContent
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo
import javax.inject.Inject
@ -86,10 +87,10 @@ class PickDisplayNameActivity : BaseActionBarActivity() {
.padding(bottom = 12.dp)
) {
Spacer(modifier = Modifier.weight(1f))
Text(stringResource(state.title), style = MaterialTheme.typography.h4)
Text(stringResource(state.title), style = h4)
Text(
stringResource(state.description),
style = MaterialTheme.typography.base,
style = base,
modifier = Modifier.padding(bottom = 12.dp))
SessionOutlinedTextField(
@ -105,8 +106,8 @@ class PickDisplayNameActivity : BaseActionBarActivity() {
Spacer(modifier = Modifier.weight(2f))
OutlineButton(
textId = R.string.continue_2,
SessionOutlinedButton(
stringResource(R.string.continue_2),
modifier = Modifier
.contentDescription(R.string.AccessibilityId_continue)
.align(Alignment.CenterHorizontally)

View File

@ -15,7 +15,6 @@ import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@ -24,7 +23,6 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
@ -34,18 +32,17 @@ import network.loki.messenger.R
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.showSessionDialog
import org.thoughtcrime.securesms.ui.CellWithPaddingAndMargin
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.Palette
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionColors
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
import org.thoughtcrime.securesms.ui.SessionMaterialTheme
import org.thoughtcrime.securesms.ui.SessionShieldIcon
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.OutlineCopyButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedCopyButton
import org.thoughtcrime.securesms.ui.components.QrImage
import org.thoughtcrime.securesms.ui.components.SmallButtons
import org.thoughtcrime.securesms.ui.components.SessionOutlinedButton
import org.thoughtcrime.securesms.ui.components.SmallButtonSize
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.extraSmallMonospace
import org.thoughtcrime.securesms.ui.h8
@ -95,9 +92,9 @@ class RecoveryPasswordActivity : BaseActionBarActivity() {
@Preview
@Composable
fun PreviewRecoveryPasswordScreen(
@PreviewParameter(SessionColorsParameterProvider::class) sessionColors: SessionColors
@PreviewParameter(SessionColorsParameterProvider::class) palette: Palette
) {
PreviewTheme(sessionColors) {
PreviewTheme(palette) {
RecoveryPasswordScreen(seed = "Voyage urban toyed maverick peculiar tuxedo penguin tree grass building listen speak withdraw terminal plane")
}
}
@ -115,10 +112,8 @@ fun RecoveryPasswordScreen(
.verticalScroll(rememberScrollState())
.padding(bottom = LocalDimensions.current.marginExtraSmall)
) {
SmallButtons {
RecoveryPasswordCell(seed, copySeed)
HideRecoveryPasswordCell(onHide)
}
RecoveryPasswordCell(seed, copySeed)
HideRecoveryPasswordCell(onHide)
}
}
@ -133,7 +128,7 @@ fun RecoveryPasswordCell(seed: String, copySeed:() -> Unit = {}) {
Row {
Text(
stringResource(R.string.sessionRecoveryPassword),
style = MaterialTheme.typography.h8
style = h8
)
Spacer(Modifier.width(LocalDimensions.current.itemSpacingExtraSmall))
SessionShieldIcon()
@ -143,7 +138,7 @@ fun RecoveryPasswordCell(seed: String, copySeed:() -> Unit = {}) {
Text(
stringResource(R.string.recoveryPasswordDescription),
style = MaterialTheme.typography.base
style = base
)
AnimatedVisibility(!showQr) {
@ -165,25 +160,26 @@ fun RecoveryPasswordCell(seed: String, copySeed:() -> Unit = {}) {
AnimatedVisibility(!showQr) {
Row(horizontalArrangement = Arrangement.spacedBy(LocalDimensions.current.marginMedium)) {
OutlineCopyButton(
Modifier
.weight(1f)
.contentDescription(R.string.AccessibilityId_copy_button),
color = LocalColors.current.text,
SessionOutlinedCopyButton(
Modifier.weight(1f),
color = LocalPalette.current.text,
size = SmallButtonSize,
onClick = copySeed
)
OutlineButton(
textId = R.string.qrView,
SessionOutlinedButton(
text = stringResource(R.string.qrView),
modifier = Modifier.weight(1f),
color = LocalColors.current.text,
color = LocalPalette.current.text,
size = SmallButtonSize,
onClick = { showQr = !showQr }
)
}
}
AnimatedVisibility(showQr, modifier = Modifier.align(Alignment.CenterHorizontally)) {
OutlineButton(
textId = R.string.recoveryPasswordView,
SessionOutlinedButton(
text = stringResource(R.string.recoveryPasswordView),
color = LocalPalette.current.text,
onClick = { showQr = !showQr }
)
}
@ -200,13 +196,13 @@ private fun RecoveryPassword(seed: String) {
.padding(vertical = LocalDimensions.current.marginSmall)
.border(
width = 1.dp,
color = LocalColors.current.borders,
color = LocalPalette.current.borders,
shape = RoundedCornerShape(11.dp)
)
.padding(LocalDimensions.current.marginSmall),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.extraSmallMonospace,
color = LocalColors.current.run { if (isLight) text else primary },
style = extraSmallMonospace,
color = LocalPalette.current.run { if (isLight) text else primary },
)
}
@ -219,21 +215,21 @@ private fun HideRecoveryPasswordCell(onHide: () -> Unit = {}) {
) {
Text(
stringResource(R.string.recoveryPasswordHideRecoveryPassword),
style = MaterialTheme.typography.h8
style = h8
)
Text(
stringResource(R.string.recoveryPasswordHideRecoveryPasswordDescription),
style = MaterialTheme.typography.base
style = base
)
}
Spacer(modifier = Modifier.width(LocalDimensions.current.marginExtraExtraSmall))
OutlineButton(
textId = R.string.hide,
SessionOutlinedButton(
text = stringResource(R.string.hide),
modifier = Modifier
.wrapContentWidth()
.align(Alignment.CenterVertically)
.contentDescription(R.string.AccessibilityId_hide_recovery_password_button),
color = LocalColors.current.danger,
color = LocalPalette.current.danger,
onClick = onHide
)
}

View File

@ -26,6 +26,8 @@ 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.LocalPalette
import org.thoughtcrime.securesms.ui.components.MaybeScanQrCode
import org.thoughtcrime.securesms.ui.components.QrImage
import org.thoughtcrime.securesms.ui.components.SessionTabRow
@ -92,14 +94,14 @@ private fun Tabs(sessionId: String, errors: Flow<String>, onScan: (String) -> Un
fun QrPage(string: String) {
Column(
modifier = Modifier
.background(MaterialTheme.colors.surface)
.padding(horizontal = 32.dp)
.background(LocalPalette.current.backgroundSecondary)
.padding(horizontal = LocalDimensions.current.marginMedium)
.fillMaxSize()
) {
QrImage(
string = string,
modifier = Modifier
.padding(top = 32.dp, bottom = 12.dp)
.padding(top = LocalDimensions.current.marginMedium, bottom = LocalDimensions.current.marginExtraExtraSmall)
.contentDescription(R.string.AccessibilityId_qr_code),
icon = R.drawable.session
)
@ -107,7 +109,7 @@ fun QrPage(string: String) {
Text(
text = stringResource(R.string.this_is_your_account_id_other_users_can_scan_it_to_start_a_conversation_with_you),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.small
style = small
)
}
}

View File

@ -78,9 +78,8 @@ import org.thoughtcrime.securesms.ui.Divider
import org.thoughtcrime.securesms.ui.ItemButton
import org.thoughtcrime.securesms.ui.ItemButtonWithDrawable
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.SessionMaterialTheme
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.components.OutlineCopyButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedCopyButton
import org.thoughtcrime.securesms.ui.components.SessionOutlinedButton
import org.thoughtcrime.securesms.ui.destructiveButtonColors
import org.thoughtcrime.securesms.ui.setContentWithTheme
import org.thoughtcrime.securesms.util.BitmapDecodingException
@ -391,13 +390,13 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() {
.padding(top = LocalDimensions.current.marginTiny),
horizontalArrangement = Arrangement.spacedBy(LocalDimensions.current.itemSpacingSmall),
) {
OutlineButton(
SessionOutlinedButton(
stringResource(R.string.share),
modifier = Modifier.weight(1f),
onClick = { sendInvitationToUseSession() }
)
OutlineCopyButton(
SessionOutlinedCopyButton(
modifier = Modifier.weight(1f),
onClick = ::copyPublicKey,
)

View File

@ -56,7 +56,7 @@ fun BoxScope.HorizontalPagerIndicator(pagerState: PagerState) {
pagerState = pagerState,
pageCount = pagerState.pageCount,
activeColor = Color.White,
inactiveColor = LocalColors.current.textSecondary)
inactiveColor = LocalPalette.current.textSecondary)
}
}
}

View File

@ -1,246 +0,0 @@
package org.thoughtcrime.securesms.ui
import android.content.Context
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.Colors
import androidx.compose.material.ContentAlpha
import androidx.compose.material.LocalContentColor
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.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import org.session.libsession.utilities.TextSecurePreferences
val classicDark0 = Color(0xff111111)
val classicDark1 = Color(0xff1B1B1B)
val classicDark2 = Color(0xff2D2D2D)
val classicDark3 = Color(0xff414141)
val classicDark4 = Color(0xff767676)
val classicDark5 = Color(0xffA1A2A1)
val classicDark6 = Color(0xffFFFFFF)
val classicLight0 = Color(0xff000000)
val classicLight1 = Color(0xff6D6D6D)
val classicLight2 = Color(0xffA1A2A1)
val classicLight3 = Color(0xffDFDFDF)
val classicLight4 = Color(0xffF0F0F0)
val classicLight5 = Color(0xffF9F9F9)
val classicLight6 = Color(0xffFFFFFF)
val oceanDark0 = Color(0xff000000)
val oceanDark1 = Color(0xff1A1C28)
val oceanDark2 = Color(0xff252735)
val oceanDark3 = Color(0xff2B2D40)
val oceanDark4 = Color(0xff3D4A5D)
val oceanDark5 = Color(0xffA6A9CE)
val oceanDark6 = Color(0xff5CAACC)
val oceanDark7 = Color(0xffFFFFFF)
val oceanLight0 = Color(0xff000000)
val oceanLight1 = Color(0xff19345D)
val oceanLight2 = Color(0xff6A6E90)
val oceanLight3 = Color(0xff5CAACC)
val oceanLight4 = Color(0xffB3EDF2)
val oceanLight5 = Color(0xffE7F3F4)
val oceanLight6 = Color(0xffECFAFB)
val oceanLight7 = Color(0xffFCFFFF)
val Colors.disabled @Composable get() = onSurface.copy(alpha = ContentAlpha.disabled)
val blackAlpha40 = Color.Black.copy(alpha = 0.4f)
val LocalColors = staticCompositionLocalOf { sessionColors(isLight = false, isClassic = true) }
data class SessionColors(
val isLight: Boolean = false,
val primary: Color = Color.Unspecified,
val danger: Color = Color.Unspecified,
val disabled: Color = Color.Unspecified,
val background: Color = Color.Unspecified,
val backgroundSecondary: Color = Color.Unspecified,
val text: Color = Color.Unspecified,
val textSecondary: Color = Color.Unspecified,
val borders: Color = Color.Unspecified,
val textBubbleSent: Color = Color.Unspecified,
val backgroundBubbleReceived: Color = Color.Unspecified,
val textBubbleReceived: Color = Color.Unspecified,
) {
val backgroundLight get() = if (isLight) backgroundSecondary else Color.White
val onBackgroundLight get() = if (isLight) text else background
val button get() = if (isLight) text else primary
val divider get() = text.copy(alpha = TabRowDefaults.DividerOpacity)
val backgroundBubbleSent get() = primary
@Composable fun radioButtonColors() = RadioButtonDefaults.colors(selectedColor = primary, unselectedColor = text, disabledColor = disabled)
}
val primaryGreen = Color(0xFF31F196)
val primaryBlue = Color(0xFF57C9FA)
val primaryPurple = Color(0xFFC993FF)
val primaryPink = Color(0xFFFF95EF)
val primaryRed = Color(0xFFFF9C8E)
val primaryOrange = Color(0xFFFCB159)
val primaryYellow = Color(0xFFFAD657)
val dangerDark = Color(0xFFFF3A3A)
val dangerLight = Color(0xFFE12D19)
val disabledDark = Color(0xFFA1A2A1)
val disabledLight = Color(0xFF6D6D6D)
fun sessionColors(
isLight: Boolean,
isClassic: Boolean,
primary: Color = if (isClassic) primaryGreen else primaryBlue
): SessionColors = if (isClassic) {
if (isLight) classicLight else classicDark
} else {
if (isLight) oceanLight else oceanDark
}.copy(
primary = primary
)
val classicDark = SessionColors(
isLight = false,
primary = primaryGreen,
danger = dangerDark,
disabled = disabledDark,
background = Color.Black,
backgroundSecondary = classicDark1,
text = Color.White,
textSecondary = classicDark5,
borders = classicDark3,
textBubbleSent = Color.Black,
backgroundBubbleReceived = classicDark2,
textBubbleReceived = Color.White,
)
val classicLight = SessionColors(
isLight = true,
primary = primaryGreen,
danger = dangerLight,
disabled = disabledLight,
background = Color.White,
backgroundSecondary = classicLight5,
text = Color.Black,
textSecondary = classicLight1,
borders = classicLight3,
textBubbleSent = Color.Black,
backgroundBubbleReceived = classicLight4,
textBubbleReceived = classicLight4,
)
val oceanDark = SessionColors(
isLight = false,
primary = primaryBlue,
danger = dangerDark,
disabled = disabledDark,
background = oceanDark2,
backgroundSecondary = oceanDark1,
text = Color.White,
textSecondary = oceanDark5,
borders = oceanDark4,
textBubbleSent = Color.Black,
backgroundBubbleReceived = oceanDark4,
textBubbleReceived = oceanDark4,
)
val oceanLight = SessionColors(
isLight = true,
primary = primaryBlue,
danger = dangerLight,
disabled = disabledLight,
background = oceanLight7,
backgroundSecondary = oceanLight6,
text = oceanLight1,
textSecondary = oceanLight2,
borders = oceanLight3,
textBubbleSent = oceanLight1,
backgroundBubbleReceived = oceanLight4,
textBubbleReceived = oceanLight4
)
@Composable
fun transparentButtonColors() = ButtonDefaults.buttonColors(backgroundColor = Color.Transparent)
@Composable
fun destructiveButtonColors() = ButtonDefaults.buttonColors(backgroundColor = Color.Transparent, contentColor = LocalColors.current.danger)
@Composable
fun Colors(name: String, colors: List<Color>) {
Column {
colors.forEachIndexed { i, it ->
Box(Modifier.background(it)) {
Text("$name: $i")
}
}
}
}
@Preview
@Composable
fun PreviewThemeColors(
@PreviewParameter(SessionColorsParameterProvider::class) sessionColors: SessionColors
) {
PreviewTheme(sessionColors) { ThemeColors() }
}
@Composable
private fun ThemeColors() {
Column {
Box(Modifier.background(MaterialTheme.colors.primary)) {
Text("primary", style = MaterialTheme.typography.base)
}
Box(Modifier.background(MaterialTheme.colors.primaryVariant)) {
Text("primaryVariant", style = MaterialTheme.typography.base)
}
Box(Modifier.background(MaterialTheme.colors.secondary)) {
Text("secondary", style = MaterialTheme.typography.base)
}
Box(Modifier.background(MaterialTheme.colors.secondaryVariant)) {
Text("secondaryVariant", style = MaterialTheme.typography.base)
}
Box(Modifier.background(MaterialTheme.colors.surface)) {
Text("surface", style = MaterialTheme.typography.base)
}
Box(Modifier.background(MaterialTheme.colors.primarySurface)) {
Text("primarySurface", style = MaterialTheme.typography.base)
}
Box(Modifier.background(MaterialTheme.colors.background)) {
Text("background", style = MaterialTheme.typography.base)
}
Box(Modifier.background(MaterialTheme.colors.error)) {
Text("error", style = MaterialTheme.typography.base)
}
}
}
@Composable
fun outlinedTextFieldColors(
isError: Boolean
) = TextFieldDefaults.outlinedTextFieldColors(
textColor = if (isError) LocalColors.current.danger else LocalContentColor.current,
cursorColor = if (isError) LocalColors.current.danger else LocalContentColor.current,
focusedBorderColor = LocalColors.current.borders,
unfocusedBorderColor = LocalColors.current.borders,
placeholderColor = if (isError) LocalColors.current.danger else LocalColors.current.textSecondary
)
fun TextSecurePreferences.Companion.getAccentColor(context: Context): Color = when (getAccentColorName(context)) {
BLUE_ACCENT -> primaryBlue
PURPLE_ACCENT -> primaryPurple
PINK_ACCENT -> primaryPink
RED_ACCENT -> primaryRed
ORANGE_ACCENT -> primaryOrange
YELLOW_ACCENT -> primaryYellow
else -> primaryGreen
}

View File

@ -32,7 +32,6 @@ import androidx.compose.material.Icon
import androidx.compose.material.LocalContentColor
import androidx.compose.material.MaterialTheme
import androidx.compose.material.RadioButton
import androidx.compose.material.RadioButtonDefaults
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
@ -40,7 +39,6 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.draw.drawWithContent
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.BlendMode
@ -93,7 +91,7 @@ data class RadioOption<T>(
fun <T> OptionsCard(card: OptionsCard<T>, callbacks: Callbacks<T>) {
Text(
card.title(),
style = MaterialTheme.typography.base
style = base
)
CellNoMargin {
LazyColumn(
@ -190,7 +188,7 @@ fun ItemButton(
) {
icon()
}
Text(text, modifier = Modifier.fillMaxWidth(), style = MaterialTheme.typography.xl)
Text(text, modifier = Modifier.fillMaxWidth(), style = xl)
}
}
@ -210,7 +208,7 @@ fun CellWithPaddingAndMargin(
content: @Composable () -> Unit
) {
Card(
backgroundColor = LocalColors.current.backgroundSecondary,
backgroundColor = LocalPalette.current.backgroundSecondary,
shape = RoundedCornerShape(16.dp),
elevation = 0.dp,
modifier = Modifier
@ -224,7 +222,7 @@ fun CellWithPaddingAndMargin(
@Composable
fun <T> TitledRadioButton(option: RadioOption<T>, onClick: () -> Unit) {
val color = if (option.enabled) LocalColors.current.text else LocalColors.current.disabled
val color = if (option.enabled) LocalPalette.current.text else LocalPalette.current.disabled
Row(
horizontalArrangement = Arrangement.spacedBy(16.dp),
modifier = Modifier
@ -239,13 +237,13 @@ fun <T> TitledRadioButton(option: RadioOption<T>, onClick: () -> Unit) {
Column {
Text(
text = option.title(),
style = MaterialTheme.typography.large,
style = large,
color = color
)
option.subtitle?.let {
Text(
text = it(),
style = MaterialTheme.typography.extraSmall,
style = extraSmall,
color = color
)
}
@ -258,7 +256,7 @@ fun <T> TitledRadioButton(option: RadioOption<T>, onClick: () -> Unit) {
.height(26.dp)
.align(Alignment.CenterVertically),
enabled = option.enabled,
colors = LocalColors.current.radioButtonColors()
colors = LocalPalette.current.radioButtonColors()
)
}
}
@ -324,7 +322,7 @@ fun Modifier.fadingEdges(
fun Divider(modifier: Modifier = Modifier, startIndent: Dp = 0.dp) {
androidx.compose.material.Divider(
modifier = modifier.padding(horizontal = LocalDimensions.current.marginExtraSmall),
color = LocalColors.current.divider,
color = LocalPalette.current.divider,
startIndent = startIndent
)
}
@ -357,7 +355,7 @@ fun ProgressArc(progress: Float, modifier: Modifier = Modifier) {
"${text}%",
color = Color.White,
modifier = Modifier.align(Alignment.Center),
style = MaterialTheme.typography.h2
style = h2
)
}
}
@ -366,8 +364,8 @@ fun ProgressArc(progress: Float, modifier: Modifier = Modifier) {
fun Arc(
modifier: Modifier = Modifier,
percentage: Float = 0.25f,
fillColor: Color = LocalColors.current.primary,
backgroundColor: Color = LocalColors.current.borders,
fillColor: Color = LocalPalette.current.primary,
backgroundColor: Color = LocalPalette.current.borders,
strokeWidth: Dp = 18.dp,
sweepAngle: Float = 310f,
startAngle: Float = (360f - sweepAngle) / 2 + 90f

View File

@ -0,0 +1,273 @@
package org.thoughtcrime.securesms.ui
import android.content.Context
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
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.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import org.session.libsession.utilities.TextSecurePreferences
val classicDark0 = Color(0xff111111)
val classicDark1 = Color(0xff1B1B1B)
val classicDark2 = Color(0xff2D2D2D)
val classicDark3 = Color(0xff414141)
val classicDark4 = Color(0xff767676)
val classicDark5 = Color(0xffA1A2A1)
val classicDark6 = Color(0xffFFFFFF)
val classicLight0 = Color(0xff000000)
val classicLight1 = Color(0xff6D6D6D)
val classicLight2 = Color(0xffA1A2A1)
val classicLight3 = Color(0xffDFDFDF)
val classicLight4 = Color(0xffF0F0F0)
val classicLight5 = Color(0xffF9F9F9)
val classicLight6 = Color(0xffFFFFFF)
val oceanDark0 = Color(0xff000000)
val oceanDark1 = Color(0xff1A1C28)
val oceanDark2 = Color(0xff252735)
val oceanDark3 = Color(0xff2B2D40)
val oceanDark4 = Color(0xff3D4A5D)
val oceanDark5 = Color(0xffA6A9CE)
val oceanDark6 = Color(0xff5CAACC)
val oceanDark7 = Color(0xffFFFFFF)
val oceanLight0 = Color(0xff000000)
val oceanLight1 = Color(0xff19345D)
val oceanLight2 = Color(0xff6A6E90)
val oceanLight3 = Color(0xff5CAACC)
val oceanLight4 = Color(0xffB3EDF2)
val oceanLight5 = Color(0xffE7F3F4)
val oceanLight6 = Color(0xffECFAFB)
val oceanLight7 = Color(0xffFCFFFF)
val primaryGreen = Color(0xFF31F196)
val primaryBlue = Color(0xFF57C9FA)
val primaryPurple = Color(0xFFC993FF)
val primaryPink = Color(0xFFFF95EF)
val primaryRed = Color(0xFFFF9C8E)
val primaryOrange = Color(0xFFFCB159)
val primaryYellow = Color(0xFFFAD657)
val dangerDark = Color(0xFFFF3A3A)
val dangerLight = Color(0xFFE12D19)
val disabledDark = Color(0xFFA1A2A1)
val disabledLight = Color(0xFF6D6D6D)
val blackAlpha40 = Color.Black.copy(alpha = 0.4f)
val LocalPalette = staticCompositionLocalOf<Palette> { ClassicDark() }
interface Palette {
@Composable
fun outlinedButtonColors(color: Color) = ButtonDefaults.outlinedButtonColors(
contentColor = color,
backgroundColor = Color.Unspecified,
disabledContentColor = disabled
)
@Composable
fun filledButtonColors() = ButtonDefaults.outlinedButtonColors(
contentColor = background,
backgroundColor = primary,
disabledContentColor = disabled
)
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 buttonFilled: Color
val buttonOutline: Color
val qrCodeContent: Color
val qrCodeBackground: Color
}
fun sessionColors(
isLight: Boolean,
isClassic: Boolean,
primary: Color
): Palette = when {
isClassic && isLight -> ::ClassicLight
isLight -> ::OceanLight
isClassic -> ::ClassicDark
else -> ::OceanDark
}(primary)
data class ClassicDark(override val primary: Color = primaryGreen): Palette {
override val isLight = false
override val danger = dangerDark
override val disabled = disabledDark
override val background = Color.Black
override val backgroundSecondary = classicDark1
override val text = Color.White
override val textSecondary = classicDark5
override val borders = classicDark3
override val textBubbleSent = Color.Black
override val backgroundBubbleReceived = classicDark2
override val textBubbleReceived = Color.White
override val buttonFilled = primary
override val buttonOutline = primary
override val qrCodeContent = background
override val qrCodeBackground = text
}
data class ClassicLight(override val primary: Color = primaryGreen): Palette {
override val isLight = true
override val danger = dangerLight
override val disabled = disabledLight
override val background = Color.White
override val backgroundSecondary = classicLight5
override val text = Color.Black
override val textSecondary = classicLight1
override val borders = classicLight3
override val textBubbleSent = Color.Black
override val backgroundBubbleReceived = classicLight4
override val textBubbleReceived = classicLight4
override val buttonFilled = primary
override val buttonOutline = Color.Black
override val qrCodeContent = text
override val qrCodeBackground = backgroundSecondary
}
data class OceanDark(override val primary: Color = primaryBlue): Palette {
override val isLight = false
override val danger = dangerDark
override val disabled = disabledDark
override val background = oceanDark2
override val backgroundSecondary = oceanDark1
override val text = Color.White
override val textSecondary = oceanDark5
override val borders = oceanDark4
override val textBubbleSent = Color.Black
override val backgroundBubbleReceived = oceanDark4
override val textBubbleReceived = oceanDark4
override val buttonFilled = primary
override val buttonOutline = text
override val qrCodeContent = background
override val qrCodeBackground = text
}
data class OceanLight(override val primary: Color = primaryBlue): Palette {
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 buttonFilled = text
override val buttonOutline = oceanLight1
override val qrCodeContent = text
override val qrCodeBackground = backgroundSecondary
}
@Composable
fun transparentButtonColors() = ButtonDefaults.buttonColors(backgroundColor = Color.Transparent)
@Composable
fun destructiveButtonColors() = ButtonDefaults.buttonColors(backgroundColor = Color.Transparent, contentColor = LocalPalette.current.danger)
@Composable
fun Colors(name: String, colors: List<Color>) {
Column {
colors.forEachIndexed { i, it ->
Box(Modifier.background(it)) {
Text("$name: $i")
}
}
}
}
@Preview
@Composable
fun PreviewThemeColors(
@PreviewParameter(SessionColorsParameterProvider::class) palette: Palette
) {
PreviewTheme(palette) { 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 Palette.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 Palette.divider get() = text.copy(alpha = TabRowDefaults.DividerOpacity)
@Composable
fun Palette.radioButtonColors() = RadioButtonDefaults.colors(
selectedColor = primary,
unselectedColor = text,
disabledColor = disabled
)
fun TextSecurePreferences.Companion.getAccentColor(context: Context): Color = when (getAccentColorName(context)) {
BLUE_ACCENT -> primaryBlue
PURPLE_ACCENT -> primaryPurple
PINK_ACCENT -> primaryPink
RED_ACCENT -> primaryRed
ORANGE_ACCENT -> primaryOrange
YELLOW_ACCENT -> primaryYellow
else -> primaryGreen
}

View File

@ -3,6 +3,7 @@ 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
@ -12,31 +13,44 @@ fun boldStyle(size: TextUnit) = TextStyle.Default.copy(
fontSize = size
)
fun defaultStyle(size: TextUnit) = TextStyle.Default.copy(
fun defaultStyle(size: TextUnit, fontFamily: FontFamily? = TextStyle.Default.fontFamily) = TextStyle.Default.copy(
fontSize = size,
lineHeight = size * 1.2
lineHeight = size * 1.2,
fontFamily = fontFamily
)
val xl = defaultStyle(18.sp)
val large = defaultStyle(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 = boldStyle(36.sp),
h2 = boldStyle(32.sp),
h3 = boldStyle(29.sp),
h4 = boldStyle(26.sp),
h5 = boldStyle(23.sp),
h6 = boldStyle(20.sp),
h1 = h1,
h2 = h2,
h3 = h3,
h4 = h4,
h5 = h5,
h6 = h6,
)
val Typography.xl get() = defaultStyle(18.sp)
val Typography.large get() = defaultStyle(16.sp)
val Typography.base get() = defaultStyle(14.sp)
val Typography.baseBold get() = boldStyle(14.sp)
val Typography.baseMonospace get() = defaultStyle(14.sp).copy(fontFamily = FontFamily.Monospace)
val Typography.small get() = defaultStyle(12.sp)
val Typography.smallMonospace get() = defaultStyle(12.sp).copy(fontFamily = FontFamily.Monospace)
val Typography.extraSmall get() = defaultStyle(11.sp)
val Typography.extraSmallMonospace get() = defaultStyle(11.sp).copy(fontFamily = FontFamily.Monospace)
val Typography.fine get() = defaultStyle(9.sp)
val Typography.h7 get() = boldStyle(18.sp)
val Typography.h8 get() = boldStyle(16.sp)
val Typography.h9 get() = boldStyle(14.sp)

View File

@ -31,26 +31,26 @@ fun SessionMaterialTheme(
}
/**
* Apply a given [SessionColors], and our typography and shapes as a Material 2 Compose Theme.
* Apply a given [Palette], and our typography and shapes as a Material 2 Compose Theme.
**/
@Composable
fun SessionMaterialTheme(
sessionColors: SessionColors,
palette: Palette,
content: @Composable () -> Unit
) {
MaterialTheme(
colors = sessionColors.toMaterialColors(),
colors = palette.toMaterialColors(),
typography = sessionTypography,
shapes = sessionShapes,
) {
val textSelectionColors = TextSelectionColors(
handleColor = LocalColors.current.primary,
backgroundColor = LocalColors.current.primary.copy(alpha = 0.5f)
handleColor = LocalPalette.current.primary,
backgroundColor = LocalPalette.current.primary.copy(alpha = 0.5f)
)
CompositionLocalProvider(
LocalColors provides sessionColors,
LocalContentColor provides sessionColors.text,
LocalPalette provides palette,
LocalContentColor provides palette.text,
LocalTextSelectionColors provides textSelectionColors
) {
content()
@ -58,7 +58,7 @@ fun SessionMaterialTheme(
}
}
private fun SessionColors.toMaterialColors() = Colors(
private fun Palette.toMaterialColors() = Colors(
primary = background,
primaryVariant = backgroundSecondary,
secondary = background,
@ -86,21 +86,16 @@ val sessionShapes = Shapes(
*/
@Composable
fun PreviewTheme(
sessionColors: SessionColors = LocalColors.current,
palette: Palette = LocalPalette.current,
content: @Composable () -> Unit
) {
SessionMaterialTheme(sessionColors) {
Box(modifier = Modifier.background(color = LocalColors.current.background)) {
SessionMaterialTheme(palette) {
Box(modifier = Modifier.background(color = LocalPalette.current.background)) {
content()
}
}
}
class SessionColorsParameterProvider : PreviewParameterProvider<SessionColors> {
override val values = sequenceOf(
sessionColors(isLight = false, isClassic = true),
sessionColors(isLight = true, isClassic = true),
sessionColors(isLight = false, isClassic = false),
sessionColors(isLight = true, isClassic = false),
)
class SessionColorsParameterProvider : PreviewParameterProvider<Palette> {
override val values = sequenceOf(ClassicDark(), ClassicLight(), OceanDark(), OceanLight())
}

View File

@ -7,20 +7,28 @@ 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.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
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.Palette
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
import org.thoughtcrime.securesms.ui.h4
@Preview
@Composable
fun AppBarPreview() {
AppBar(title = "Title", {}, {})
fun AppBarPreview(
@PreviewParameter(SessionColorsParameterProvider::class) palette: Palette
) {
PreviewTheme(palette) {
AppBar(title = "Title", {}, {})
}
}
@Composable
@ -34,7 +42,7 @@ fun AppBar(title: String, onClose: () -> Unit = {}, onBack: (() -> Unit)? = null
}
}
Spacer(modifier = Modifier.weight(1f))
Text(text = title, style = MaterialTheme.typography.h4)
Text(text = title, style = h4)
Spacer(modifier = Modifier.weight(1f))
Box(contentAlignment = Alignment.Center, modifier = Modifier.size(64.dp)) {
IconButton(onClick = onClose) {

View File

@ -2,198 +2,65 @@ package org.thoughtcrime.securesms.ui.components
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ButtonDefaults
import androidx.compose.material.ContentAlpha
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedButton
import androidx.compose.material.RadioButton
import androidx.compose.material.Text
import androidx.compose.material.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.filter
import network.loki.messenger.R
import org.thoughtcrime.securesms.ui.GetString
import org.thoughtcrime.securesms.ui.LaunchedEffectAsync
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.baseBold
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.extraSmall
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
import org.thoughtcrime.securesms.ui.h8
import org.thoughtcrime.securesms.ui.h9
import org.thoughtcrime.securesms.ui.radioButtonColors
import org.thoughtcrime.securesms.ui.small
val LocalButtonSize = staticCompositionLocalOf { mediumButton }
@Composable
fun Modifier.applyButtonSize() = then(LocalButtonSize.current)
val mediumButton = Modifier.height(41.dp)
val smallButton = Modifier.wrapContentHeight()
val LocalButtonTextStyle = staticCompositionLocalOf { baseBold }
/**
* Text to be used in buttons.
*
* This text gets its style from [LocalButtonTextStyle] which may vary if button size is changed
* by passing in a [ButtonSize] to some Session Button.
*/
@Composable
fun SessionButtonText(
text: String,
modifier: Modifier = Modifier,
color: Color = LocalColors.current.button,
style: TextStyle = LocalButtonTextStyle.current,
color: Color = LocalPalette.current.buttonOutline,
enabled: Boolean = true
) {
Text(
modifier = modifier,
text = text,
style = MaterialTheme.typography.baseBold,
color = if (enabled) color else LocalColors.current.disabled
style = style,
color = if (enabled) color else LocalPalette.current.disabled
)
}
@Composable
fun OutlineButton(
@StringRes textId: Int,
modifier: Modifier = Modifier,
color: Color = LocalColors.current.button,
onClick: () -> Unit
) { OutlineButton(stringResource(textId), modifier, color, onClick) }
@Composable
fun OutlineButton(
text: String,
modifier: Modifier = Modifier,
color: Color = LocalColors.current.button,
onClick: () -> Unit
) {
OutlineButton(
modifier = modifier,
color = color,
onClick = onClick
) {
SessionButtonText(text = text, color = color)
}
}
@Composable
fun OutlineButton(
modifier: Modifier = Modifier,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
color: Color = LocalColors.current.button,
onClick: () -> Unit,
content: @Composable () -> Unit = {}
) {
OutlinedButton(
modifier = modifier.applyButtonSize(),
enabled = enabled,
interactionSource = interactionSource,
onClick = onClick,
border = BorderStroke(1.dp, if (enabled) color else LocalColors.current.disabled),
colors = ButtonDefaults.outlinedButtonColors(
contentColor = if (enabled) color else LocalColors.current.disabled,
backgroundColor = Color.Unspecified
)
) {
content()
}
}
@Composable
fun OutlineCopyButton(
modifier: Modifier = Modifier,
color: Color = LocalColors.current.button,
onClick: () -> Unit = {}
) {
val interactionSource = remember { MutableInteractionSource() }
OutlineButton(
modifier = modifier,
interactionSource = interactionSource,
color = color,
onClick = onClick
) {
TemporaryClickedContent(
interactionSource = interactionSource,
content = {
// using a centered box because the outline button uses rowscope internally and it shows the crossfade
Box(
modifier = Modifier.fillMaxWidth()
) {
SessionButtonText(
text = stringResource(R.string.copy),
modifier = Modifier.align(Alignment.Center),
color = color
)
}
},
temporaryContent = {
// using a centered box because the outline button uses rowscope internally and it shows the crossfade
Box(
modifier = Modifier.fillMaxWidth()
) {
SessionButtonText(
text = stringResource(R.string.copied),
modifier = Modifier.align(Alignment.Center),
color = color
)
}
}
)
}
}
@Composable
fun TemporaryClickedContent(
modifier: Modifier = Modifier,
interactionSource: MutableInteractionSource,
content: @Composable () -> Unit,
temporaryContent: @Composable () -> Unit,
temporaryDelay: Duration = 2.seconds
) {
var clicked by remember { mutableStateOf(false) }
LaunchedEffectAsync {
interactionSource.releases.collectLatest {
clicked = true
delay(temporaryDelay)
clicked = false
}
}
Crossfade(
modifier = modifier,
targetState = clicked
) {
when(it) {
false -> content()
true -> temporaryContent()
}
}
}
@Composable
fun FilledButton(
text: String,
@ -203,19 +70,16 @@ fun FilledButton(
OutlinedButton(
modifier = modifier,
onClick = onClick,
colors = ButtonDefaults.outlinedButtonColors(
contentColor = LocalColors.current.background,
backgroundColor = LocalColors.current.primary
)
colors = LocalPalette.current.filledButtonColors()
) {
SessionButtonText(text, color = LocalColors.current.background)
SessionButtonText(text, color = LocalPalette.current.background)
}
}
@Composable
fun BorderlessButton(
modifier: Modifier = Modifier,
contentColor: Color = LocalColors.current.text,
contentColor: Color = LocalPalette.current.text,
backgroundColor: Color = Color.Transparent,
onClick: () -> Unit,
content: @Composable () -> Unit
@ -235,7 +99,7 @@ fun BorderlessButton(
text: String,
modifier: Modifier = Modifier,
contentDescription: GetString = GetString(text),
contentColor: Color = LocalColors.current.text,
contentColor: Color = LocalPalette.current.text,
backgroundColor: Color = Color.Transparent,
onClick: () -> Unit
) {
@ -248,7 +112,7 @@ fun BorderlessButton(
Text(
text = text,
textAlign = TextAlign.Center,
style = MaterialTheme.typography.extraSmall,
style = extraSmall,
modifier = Modifier.padding(horizontal = 2.dp)
)
}
@ -259,8 +123,8 @@ fun BorderlessButtonWithIcon(
text: String,
@DrawableRes iconRes: Int,
modifier: Modifier = Modifier,
style: TextStyle = MaterialTheme.typography.baseBold,
contentColor: Color = LocalColors.current.text,
style: TextStyle = baseBold,
contentColor: Color = LocalPalette.current.text,
backgroundColor: Color = Color.Transparent,
onClick: () -> Unit
) {
@ -278,7 +142,7 @@ fun BorderlessButtonWithIcon(
fun BorderlessHtmlButton(
textId: Int,
modifier: Modifier = Modifier,
contentColor: Color = LocalColors.current.text,
contentColor: Color = LocalPalette.current.text,
backgroundColor: Color = Color.Transparent,
onClick: () -> Unit
) {
@ -291,16 +155,56 @@ fun BorderlessHtmlButton(
Text(
text = annotatedStringResource(textId),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.extraSmall,
style = extraSmall,
modifier = Modifier.padding(horizontal = 2.dp)
)
}
}
private val MutableInteractionSource.releases
get() = interactions.filter { it is PressInteraction.Release }
@Composable
fun SmallButtons(content: @Composable () -> Unit) {
CompositionLocalProvider(LocalButtonSize provides smallButton) { content() }
fun NotificationRadioButton(
@StringRes title: Int,
@StringRes explanation: Int,
@StringRes tag: Int? = null,
@StringRes contentDescription: Int? = null,
selected: Boolean = false,
onClick: () -> Unit = {}
) {
Row {
SessionOutlinedButton(
onClick = onClick,
modifier = Modifier
.weight(1f)
.contentDescription(contentDescription),
color = LocalPalette.current.text,
border = BorderStroke(
width = ButtonDefaults.OutlinedBorderSize,
color = if (selected) LocalPalette.current.primary else LocalPalette.current.borders
),
shape = RoundedCornerShape(8.dp)
) {
Column(
verticalArrangement = Arrangement.spacedBy(6.dp)
) {
Text(stringResource(title), style = h8)
Text(stringResource(explanation), style = small)
tag?.let {
Text(
stringResource(it),
color = LocalPalette.current.primary,
style = h9
)
}
}
}
RadioButton(
selected = selected,
modifier = Modifier.align(Alignment.CenterVertically),
onClick = onClick,
colors = LocalPalette.current.radioButtonColors()
)
}
}
val MutableInteractionSource.releases
get() = interactions.filter { it is PressInteraction.Release }

View File

@ -0,0 +1,40 @@
package org.thoughtcrime.securesms.ui.components
import android.annotation.SuppressLint
import androidx.compose.material.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.text.TextStyle
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.smallBold
interface ButtonSize {
@SuppressLint("ComposableNaming")
@Composable fun applyTextStyle(content: @Composable () -> Unit) {
CompositionLocalProvider(LocalButtonTextStyle provides textStyle) {
content()
}
}
val textStyle: TextStyle @Composable get
val minHeight: Dp
}
object LargeButtonSize: ButtonSize {
override val textStyle @Composable get() = baseBold
override val minHeight = 41.dp
}
object MediumButtonSize: ButtonSize {
override val textStyle @Composable get() = smallBold
override val minHeight = 34.dp
}
object SmallButtonSize: ButtonSize {
override val textStyle @Composable get() = extraSmallBold
override val minHeight = 29.dp
}

View File

@ -58,6 +58,7 @@ import kotlinx.coroutines.flow.filter
import network.loki.messenger.R
import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.base
import java.util.concurrent.Executors
@ -76,7 +77,7 @@ fun MaybeScanQrCode(
) {
Box(
modifier = Modifier.fillMaxSize()
.background(MaterialTheme.colors.surface)
.background(LocalPalette.current.background)
) {
LocalSoftwareKeyboardController.current?.hide()
@ -92,11 +93,11 @@ fun MaybeScanQrCode(
) {
Text(
stringResource(R.string.activity_link_camera_permission_permanently_denied_configure_in_settings),
style = MaterialTheme.typography.base,
style = base,
textAlign = TextAlign.Center
)
Spacer(modifier = Modifier.size(20.dp))
OutlineButton(
SessionOutlinedButton(
stringResource(R.string.sessionSettings),
modifier = Modifier.align(Alignment.CenterHorizontally),
onClick = onClickSettings
@ -104,7 +105,7 @@ fun MaybeScanQrCode(
}
} else {
Box(modifier = Modifier.fillMaxSize().padding(LocalDimensions.current.marginLarge)) {
OutlineButton(
SessionOutlinedButton(
stringResource(R.string.cameraGrantAccess),
modifier = Modifier
.align(Alignment.Center)

View File

@ -8,7 +8,6 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.Card
import androidx.compose.material.Icon
@ -31,7 +30,7 @@ import androidx.compose.ui.unit.dp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import network.loki.messenger.R
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.util.QRCodeUtilities
@Composable
@ -53,15 +52,11 @@ fun QrImage(
}
}
if (LocalColors.current.isLight) {
Content(bitmap, icon, modifier = modifier, backgroundColor = LocalColors.current.backgroundLight)
} else {
Card(
backgroundColor = LocalColors.current.backgroundLight,
elevation = 0.dp,
modifier = modifier
) { Content(bitmap, icon, modifier = Modifier.padding(16.dp), backgroundColor = LocalColors.current.backgroundLight) }
}
Card(
backgroundColor = LocalPalette.current.qrCodeBackground,
elevation = 0.dp,
modifier = modifier
) { Content(bitmap, icon, backgroundColor = LocalPalette.current.qrCodeBackground) }
}
@Composable
@ -69,7 +64,7 @@ private fun Content(
bitmap: Bitmap?,
icon: Int,
modifier: Modifier = Modifier,
qrColor: Color = LocalColors.current.onBackgroundLight,
qrColor: Color = LocalPalette.current.qrCodeContent,
backgroundColor: Color,
) {
Box(

View File

@ -0,0 +1,145 @@
package org.thoughtcrime.securesms.ui.components
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.Crossfade
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.BorderStroke
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material.MaterialTheme
import androidx.compose.material.OutlinedButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import network.loki.messenger.R
import org.thoughtcrime.securesms.ui.LaunchedEffectAsync
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.contentDescription
import kotlin.time.Duration
import kotlin.time.Duration.Companion.seconds
@Composable
fun SessionOutlinedButton(
text: String,
modifier: Modifier = Modifier,
size: ButtonSize = LargeButtonSize,
color: Color = LocalPalette.current.buttonOutline,
onClick: () -> Unit
) {
SessionOutlinedButton(
modifier = modifier,
size = size,
color = color,
onClick = onClick
) {
SessionButtonText(text = text, style = size.textStyle, color = color)
}
}
/**
* Base implementation of [SessionOutlinedButton]
*/
@Composable
fun SessionOutlinedButton(
modifier: Modifier = Modifier,
size: ButtonSize = LargeButtonSize,
enabled: Boolean = true,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
color: Color = LocalPalette.current.buttonOutline,
border: BorderStroke = BorderStroke(1.dp, if (enabled) color else LocalPalette.current.disabled),
shape: Shape = MaterialTheme.shapes.small,
onClick: () -> Unit,
content: @Composable () -> Unit = {}
) {
OutlinedButton(
modifier = modifier.heightIn(min = size.minHeight),
enabled = enabled,
interactionSource = interactionSource,
onClick = onClick,
border = border,
shape = shape,
colors = LocalPalette.current.outlinedButtonColors(color)
) {
size.applyTextStyle {
content()
}
}
}
@Composable
fun SessionOutlinedCopyButton(
modifier: Modifier = Modifier,
size: ButtonSize = LargeButtonSize,
color: Color = LocalPalette.current.buttonOutline,
onClick: () -> Unit
) {
val interactionSource = remember { MutableInteractionSource() }
SessionOutlinedButton(
modifier = modifier.contentDescription(R.string.AccessibilityId_copy_button),
size = size,
interactionSource = interactionSource,
color = color,
onClick = onClick
) {
TemporaryClickedContent(
interactionSource = interactionSource,
content = {
SessionButtonText(
text = stringResource(R.string.copy),
color = color
)
},
temporaryContent = {
SessionButtonText(
text = stringResource(R.string.copied),
color = color
)
}
)
}
}
@Composable
fun TemporaryClickedContent(
modifier: Modifier = Modifier,
interactionSource: MutableInteractionSource,
content: @Composable () -> Unit,
temporaryContent: @Composable () -> Unit,
temporaryDelay: Duration = 2.seconds
) {
var clicked by remember { mutableStateOf(false) }
LaunchedEffectAsync {
interactionSource.releases.collectLatest {
clicked = true
delay(temporaryDelay)
clicked = false
}
}
// Using a Box because the Buttons add children in a Row
// and they will jank as they are added and removed.
Box(contentAlignment = Alignment.Center) {
AnimatedVisibility(!clicked, enter = fadeIn(), exit = fadeOut()) {
content()
}
AnimatedVisibility(clicked, enter = fadeIn(), exit = fadeOut()) {
temporaryContent()
}
}
}

View File

@ -19,10 +19,11 @@ 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.LocalColors
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.SessionColors
import org.thoughtcrime.securesms.ui.Palette
import org.thoughtcrime.securesms.ui.SessionColorsParameterProvider
import org.thoughtcrime.securesms.ui.divider
import org.thoughtcrime.securesms.ui.h8
private val TITLES = listOf(R.string.sessionRecoveryPassword, R.string.qrScan)
@ -33,8 +34,8 @@ fun SessionTabRow(pagerState: PagerState, titles: List<Int>) {
TabRow(
backgroundColor = Color.Unspecified,
selectedTabIndex = pagerState.currentPage,
contentColor = LocalColors.current.text,
divider = { TabRowDefaults.Divider(color = LocalColors.current.divider) },
contentColor = LocalPalette.current.text,
divider = { TabRowDefaults.Divider(color = LocalPalette.current.divider) },
modifier = Modifier
.height(48.dp)
.background(color = Color.Unspecified)
@ -44,12 +45,12 @@ fun SessionTabRow(pagerState: PagerState, titles: List<Int>) {
Tab(
i == pagerState.currentPage,
onClick = { animationScope.launch { pagerState.animateScrollToPage(i) } },
selectedContentColor = LocalColors.current.text,
unselectedContentColor = LocalColors.current.text,
selectedContentColor = LocalPalette.current.text,
unselectedContentColor = LocalPalette.current.text,
) {
Text(
stringResource(id = it),
style = MaterialTheme.typography.h8
style = h8
)
}
}
@ -60,9 +61,9 @@ fun SessionTabRow(pagerState: PagerState, titles: List<Int>) {
@androidx.compose.ui.tooling.preview.Preview
@Composable
fun PreviewSessionTabRow(
@PreviewParameter(SessionColorsParameterProvider::class) sessionColors: SessionColors
@PreviewParameter(SessionColorsParameterProvider::class) palette: Palette
) {
PreviewTheme(sessionColors) {
PreviewTheme(palette) {
val pagerState = rememberPagerState { TITLES.size }
SessionTabRow(pagerState = pagerState, titles = TITLES)
}

View File

@ -24,7 +24,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalPalette
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.base
import org.thoughtcrime.securesms.ui.baseBold
@ -43,15 +43,15 @@ fun SessionOutlinedTextField(
OutlinedTextField(
value = text,
modifier = Modifier.fillMaxWidth(),
textStyle = MaterialTheme.typography.base,
textStyle = base,
onValueChange = { onChange(it) },
placeholder = {
Text(
placeholder,
style = MaterialTheme.typography.base
style = base
)
},
colors = outlinedTextFieldColors(error != null),
colors = LocalPalette.current.outlinedTextFieldColors(error != null),
singleLine = true,
keyboardActions = KeyboardActions(
onDone = { onContinue() },
@ -67,8 +67,8 @@ fun SessionOutlinedTextField(
it,
modifier = Modifier.padding(top = LocalDimensions.current.marginExtraExtraSmall),
textAlign = TextAlign.Center,
style = MaterialTheme.typography.baseBold,
color = LocalColors.current.danger
style = baseBold,
color = LocalPalette.current.danger
)
}
}
@ -79,7 +79,7 @@ fun AnnotatedTextWithIcon(
text: String,
@DrawableRes iconRes: Int,
modifier: Modifier = Modifier,
style: TextStyle = MaterialTheme.typography.base,
style: TextStyle = base,
iconTint: Color = Color.Unspecified,
iconSize: TextUnit = 12.sp
) {