mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-24 03:35:58 +00:00
Convert ChatsSettings screen to compose.
This commit is contained in:
@@ -30,7 +30,6 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalInspectionMode
|
||||
import androidx.compose.ui.res.colorResource
|
||||
@@ -72,7 +71,7 @@ import org.thoughtcrime.securesms.components.settings.app.subscription.BadgeImag
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.InAppPaymentsRepository
|
||||
import org.thoughtcrime.securesms.components.settings.app.subscription.completed.InAppPaymentsBottomSheetDelegate
|
||||
import org.thoughtcrime.securesms.compose.ComposeFragment
|
||||
import org.thoughtcrime.securesms.compose.StatusBarColorNestedScrollConnection
|
||||
import org.thoughtcrime.securesms.compose.rememberStatusBarColorNestedScrollModifier
|
||||
import org.thoughtcrime.securesms.database.model.InAppPaymentSubscriberRecord
|
||||
import org.thoughtcrime.securesms.profiles.ProfileName
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
@@ -107,16 +106,11 @@ class AppSettingsFragment : ComposeFragment(), Callbacks {
|
||||
)
|
||||
}
|
||||
|
||||
val nestedScrollConnection = remember {
|
||||
StatusBarColorNestedScrollConnection(requireActivity())
|
||||
}
|
||||
|
||||
AppSettingsContent(
|
||||
self = self!!,
|
||||
state = state!!,
|
||||
bannerManager = bannerManager,
|
||||
callbacks = this,
|
||||
lazyColumnModifier = Modifier.nestedScroll(nestedScrollConnection)
|
||||
callbacks = this
|
||||
)
|
||||
}
|
||||
|
||||
@@ -176,8 +170,7 @@ private fun AppSettingsContent(
|
||||
self: BioRecipientState,
|
||||
state: AppSettingsState,
|
||||
bannerManager: BannerManager,
|
||||
callbacks: Callbacks,
|
||||
lazyColumnModifier: Modifier = Modifier
|
||||
callbacks: Callbacks
|
||||
) {
|
||||
val isRegisteredAndUpToDate by rememberUpdatedState(state.isRegisteredAndUpToDate())
|
||||
|
||||
@@ -193,7 +186,7 @@ private fun AppSettingsContent(
|
||||
bannerManager.Banner()
|
||||
|
||||
LazyColumn(
|
||||
modifier = lazyColumnModifier
|
||||
modifier = rememberStatusBarColorNestedScrollModifier()
|
||||
) {
|
||||
item {
|
||||
BioRow(
|
||||
|
||||
@@ -47,6 +47,7 @@ import org.signal.core.ui.compose.SignalPreview
|
||||
import org.signal.core.ui.compose.Texts
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.compose.ComposeFragment
|
||||
import org.thoughtcrime.securesms.compose.rememberStatusBarColorNestedScrollModifier
|
||||
import org.thoughtcrime.securesms.contactshare.SimpleTextWatcher
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
@@ -278,7 +279,10 @@ fun AccountSettingsScreen(
|
||||
navigationIcon = ImageVector.vectorResource(R.drawable.ic_arrow_left_24)
|
||||
) { contentPadding ->
|
||||
LazyColumn(
|
||||
modifier = Modifier.padding(contentPadding).testTag(AccountSettingsTestTags.SCROLLER)
|
||||
modifier = Modifier
|
||||
.padding(contentPadding)
|
||||
.then(rememberStatusBarColorNestedScrollModifier())
|
||||
.testTag(AccountSettingsTestTags.SCROLLER)
|
||||
) {
|
||||
item {
|
||||
Texts.SectionHeader(
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.signal.core.ui.compose.SignalPreview
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.settings.app.appearance.navbar.ChooseNavigationBarStyleFragment
|
||||
import org.thoughtcrime.securesms.compose.ComposeFragment
|
||||
import org.thoughtcrime.securesms.compose.rememberStatusBarColorNestedScrollModifier
|
||||
import org.thoughtcrime.securesms.keyvalue.SettingsValues
|
||||
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
||||
|
||||
@@ -107,7 +108,9 @@ private fun AppearanceSettingsScreen(
|
||||
navigationIcon = ImageVector.vectorResource(R.drawable.symbol_arrow_start_24)
|
||||
) { paddingValues ->
|
||||
LazyColumn(
|
||||
modifier = Modifier.padding(paddingValues)
|
||||
modifier = Modifier
|
||||
.padding(paddingValues)
|
||||
.then(rememberStatusBarColorNestedScrollModifier())
|
||||
) {
|
||||
item {
|
||||
Rows.RadioListRow(
|
||||
|
||||
@@ -1,125 +1,247 @@
|
||||
package org.thoughtcrime.securesms.components.settings.app.chats
|
||||
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.navigation.Navigation
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.pluralStringResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import org.signal.core.ui.compose.Dividers
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.Rows
|
||||
import org.signal.core.ui.compose.Scaffolds
|
||||
import org.signal.core.ui.compose.SignalPreview
|
||||
import org.signal.core.ui.compose.Texts
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.settings.DSLConfiguration
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsFragment
|
||||
import org.thoughtcrime.securesms.components.settings.DSLSettingsText
|
||||
import org.thoughtcrime.securesms.components.settings.configure
|
||||
import org.thoughtcrime.securesms.compose.ComposeFragment
|
||||
import org.thoughtcrime.securesms.compose.rememberStatusBarColorNestedScrollModifier
|
||||
import org.thoughtcrime.securesms.util.RemoteConfig
|
||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||
import org.thoughtcrime.securesms.util.navigation.safeNavigate
|
||||
|
||||
class ChatsSettingsFragment : DSLSettingsFragment(R.string.preferences_chats__chats) {
|
||||
/**
|
||||
* Displays a list of chats settings options to the user, including
|
||||
* generating link previews and keeping muted chats archived.
|
||||
*/
|
||||
class ChatsSettingsFragment : ComposeFragment() {
|
||||
|
||||
private lateinit var viewModel: ChatsSettingsViewModel
|
||||
private val viewModel: ChatsSettingsViewModel by viewModels()
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
viewModel.refresh()
|
||||
}
|
||||
|
||||
@Suppress("ReplaceGetOrSet")
|
||||
override fun bindAdapter(adapter: MappingAdapter) {
|
||||
viewModel = ViewModelProvider(this).get(ChatsSettingsViewModel::class.java)
|
||||
@Composable
|
||||
override fun FragmentContent() {
|
||||
val state by viewModel.state.collectAsStateWithLifecycle()
|
||||
val callbacks = remember { Callbacks() }
|
||||
|
||||
viewModel.state.observe(viewLifecycleOwner) {
|
||||
adapter.submitList(getConfiguration(it).toMappingModelList())
|
||||
}
|
||||
ChatsSettingsScreen(
|
||||
state = state,
|
||||
callbacks = callbacks,
|
||||
isRemoteBackupsAvailable = RemoteConfig.messageBackups
|
||||
)
|
||||
}
|
||||
|
||||
private fun getConfiguration(state: ChatsSettingsState): DSLConfiguration {
|
||||
return configure {
|
||||
switchPref(
|
||||
title = DSLSettingsText.from(R.string.preferences__generate_link_previews),
|
||||
summary = DSLSettingsText.from(R.string.preferences__retrieve_link_previews_from_websites_for_messages),
|
||||
isEnabled = state.isRegisteredAndUpToDate(),
|
||||
isChecked = state.generateLinkPreviews,
|
||||
onClick = {
|
||||
viewModel.setGenerateLinkPreviewsEnabled(!state.generateLinkPreviews)
|
||||
}
|
||||
)
|
||||
private inner class Callbacks : ChatsSettingsCallbacks {
|
||||
override fun onNavigationClick() {
|
||||
requireActivity().onBackPressedDispatcher.onBackPressed()
|
||||
}
|
||||
|
||||
switchPref(
|
||||
title = DSLSettingsText.from(R.string.preferences__pref_use_address_book_photos),
|
||||
summary = DSLSettingsText.from(R.string.preferences__display_contact_photos_from_your_address_book_if_available),
|
||||
isEnabled = state.isRegisteredAndUpToDate(),
|
||||
isChecked = state.useAddressBook,
|
||||
onClick = {
|
||||
viewModel.setUseAddressBook(!state.useAddressBook)
|
||||
}
|
||||
)
|
||||
override fun onGenerateLinkPreviewsChanged(enabled: Boolean) {
|
||||
viewModel.setGenerateLinkPreviewsEnabled(enabled)
|
||||
}
|
||||
|
||||
switchPref(
|
||||
title = DSLSettingsText.from(R.string.preferences__pref_keep_muted_chats_archived),
|
||||
summary = DSLSettingsText.from(R.string.preferences__muted_chats_that_are_archived_will_remain_archived),
|
||||
isEnabled = state.isRegisteredAndUpToDate(),
|
||||
isChecked = state.keepMutedChatsArchived,
|
||||
onClick = {
|
||||
viewModel.setKeepMutedChatsArchived(!state.keepMutedChatsArchived)
|
||||
}
|
||||
)
|
||||
override fun onUseAddressBookChanged(enabled: Boolean) {
|
||||
viewModel.setUseAddressBook(enabled)
|
||||
}
|
||||
|
||||
dividerPref()
|
||||
override fun onKeepMutedChatsArchivedChanged(enabled: Boolean) {
|
||||
viewModel.setKeepMutedChatsArchived(enabled)
|
||||
}
|
||||
|
||||
sectionHeaderPref(R.string.ChatsSettingsFragment__chat_folders)
|
||||
override fun onAddAChatFolderClick() {
|
||||
findNavController().safeNavigate(R.id.action_chatsSettingsFragment_to_chatFoldersFragment)
|
||||
}
|
||||
|
||||
if (state.folderCount == 1) {
|
||||
clickPref(
|
||||
title = DSLSettingsText.from(R.string.ChatsSettingsFragment__add_chat_folder),
|
||||
isEnabled = state.isRegisteredAndUpToDate(),
|
||||
onClick = {
|
||||
Navigation.findNavController(requireView()).safeNavigate(R.id.action_chatsSettingsFragment_to_chatFoldersFragment)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
clickPref(
|
||||
title = DSLSettingsText.from(R.string.ChatsSettingsFragment__add_edit_chat_folder),
|
||||
summary = DSLSettingsText.from(resources.getQuantityString(R.plurals.ChatsSettingsFragment__d_folder, state.folderCount, state.folderCount)),
|
||||
isEnabled = state.isRegisteredAndUpToDate(),
|
||||
onClick = {
|
||||
Navigation.findNavController(requireView()).safeNavigate(R.id.action_chatsSettingsFragment_to_chatFoldersFragment)
|
||||
}
|
||||
override fun onAddOrEditFoldersClick() {
|
||||
findNavController().safeNavigate(R.id.action_chatsSettingsFragment_to_chatFoldersFragment)
|
||||
}
|
||||
|
||||
override fun onUseSystemEmojiChanged(enabled: Boolean) {
|
||||
viewModel.setUseSystemEmoji(enabled)
|
||||
}
|
||||
|
||||
override fun onEnterKeySendsChanged(enabled: Boolean) {
|
||||
viewModel.setEnterKeySends(enabled)
|
||||
}
|
||||
|
||||
override fun onChatBackupsClick() {
|
||||
findNavController().safeNavigate(R.id.action_chatsSettingsFragment_to_backupsPreferenceFragment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private interface ChatsSettingsCallbacks {
|
||||
fun onNavigationClick() = Unit
|
||||
fun onGenerateLinkPreviewsChanged(enabled: Boolean) = Unit
|
||||
fun onUseAddressBookChanged(enabled: Boolean) = Unit
|
||||
fun onKeepMutedChatsArchivedChanged(enabled: Boolean) = Unit
|
||||
fun onAddAChatFolderClick() = Unit
|
||||
fun onAddOrEditFoldersClick() = Unit
|
||||
fun onUseSystemEmojiChanged(enabled: Boolean) = Unit
|
||||
fun onEnterKeySendsChanged(enabled: Boolean) = Unit
|
||||
fun onChatBackupsClick() = Unit
|
||||
|
||||
object Empty : ChatsSettingsCallbacks
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ChatsSettingsScreen(
|
||||
isRemoteBackupsAvailable: Boolean,
|
||||
state: ChatsSettingsState,
|
||||
callbacks: ChatsSettingsCallbacks
|
||||
) {
|
||||
Scaffolds.Settings(
|
||||
title = stringResource(R.string.preferences_chats__chats),
|
||||
onNavigationClick = callbacks::onNavigationClick,
|
||||
navigationIcon = ImageVector.vectorResource(R.drawable.symbol_arrow_start_24)
|
||||
) { paddingValues ->
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.padding(paddingValues)
|
||||
.then(rememberStatusBarColorNestedScrollModifier())
|
||||
) {
|
||||
item {
|
||||
Rows.ToggleRow(
|
||||
text = stringResource(R.string.preferences__generate_link_previews),
|
||||
label = stringResource(R.string.preferences__retrieve_link_previews_from_websites_for_messages),
|
||||
enabled = state.isRegisteredAndUpToDate(),
|
||||
checked = state.generateLinkPreviews,
|
||||
onCheckChanged = callbacks::onGenerateLinkPreviewsChanged
|
||||
)
|
||||
}
|
||||
|
||||
dividerPref()
|
||||
|
||||
sectionHeaderPref(R.string.ChatsSettingsFragment__keyboard)
|
||||
|
||||
switchPref(
|
||||
title = DSLSettingsText.from(R.string.preferences_advanced__use_system_emoji),
|
||||
isEnabled = state.isRegisteredAndUpToDate(),
|
||||
isChecked = state.useSystemEmoji,
|
||||
onClick = {
|
||||
viewModel.setUseSystemEmoji(!state.useSystemEmoji)
|
||||
}
|
||||
)
|
||||
|
||||
switchPref(
|
||||
title = DSLSettingsText.from(R.string.ChatsSettingsFragment__send_with_enter),
|
||||
isEnabled = state.isRegisteredAndUpToDate(),
|
||||
isChecked = state.enterKeySends,
|
||||
onClick = {
|
||||
viewModel.setEnterKeySends(!state.enterKeySends)
|
||||
}
|
||||
)
|
||||
|
||||
if (!RemoteConfig.messageBackups) {
|
||||
dividerPref()
|
||||
|
||||
sectionHeaderPref(R.string.preferences_chats__backups)
|
||||
|
||||
clickPref(
|
||||
title = DSLSettingsText.from(R.string.preferences_chats__chat_backups),
|
||||
summary = DSLSettingsText.from(if (state.localBackupsEnabled) R.string.arrays__enabled else R.string.arrays__disabled),
|
||||
isEnabled = state.localBackupsEnabled || state.isRegisteredAndUpToDate(),
|
||||
onClick = {
|
||||
Navigation.findNavController(requireView()).safeNavigate(R.id.action_chatsSettingsFragment_to_backupsPreferenceFragment)
|
||||
}
|
||||
item {
|
||||
Rows.ToggleRow(
|
||||
text = stringResource(R.string.preferences__pref_use_address_book_photos),
|
||||
label = stringResource(R.string.preferences__display_contact_photos_from_your_address_book_if_available),
|
||||
enabled = state.isRegisteredAndUpToDate(),
|
||||
checked = state.useAddressBook,
|
||||
onCheckChanged = callbacks::onUseAddressBookChanged
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
Rows.ToggleRow(
|
||||
text = stringResource(R.string.preferences__pref_keep_muted_chats_archived),
|
||||
label = stringResource(R.string.preferences__muted_chats_that_are_archived_will_remain_archived),
|
||||
enabled = state.isRegisteredAndUpToDate(),
|
||||
checked = state.keepMutedChatsArchived,
|
||||
onCheckChanged = callbacks::onKeepMutedChatsArchivedChanged
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
Dividers.Default()
|
||||
}
|
||||
|
||||
item {
|
||||
Texts.SectionHeader(stringResource(R.string.ChatsSettingsFragment__chat_folders))
|
||||
}
|
||||
|
||||
if (state.folderCount == 1) {
|
||||
item {
|
||||
Rows.TextRow(
|
||||
text = stringResource(R.string.ChatsSettingsFragment__add_chat_folder),
|
||||
enabled = state.isRegisteredAndUpToDate(),
|
||||
onClick = callbacks::onAddAChatFolderClick
|
||||
)
|
||||
}
|
||||
} else {
|
||||
item {
|
||||
Rows.TextRow(
|
||||
text = stringResource(R.string.ChatsSettingsFragment__add_edit_chat_folder),
|
||||
label = pluralStringResource(R.plurals.ChatsSettingsFragment__d_folder, state.folderCount, state.folderCount),
|
||||
enabled = state.isRegisteredAndUpToDate(),
|
||||
onClick = callbacks::onAddOrEditFoldersClick
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
item {
|
||||
Dividers.Default()
|
||||
}
|
||||
|
||||
item {
|
||||
Texts.SectionHeader(stringResource(R.string.ChatsSettingsFragment__keyboard))
|
||||
}
|
||||
|
||||
item {
|
||||
Rows.ToggleRow(
|
||||
text = stringResource(R.string.preferences_advanced__use_system_emoji),
|
||||
enabled = state.isRegisteredAndUpToDate(),
|
||||
checked = state.useSystemEmoji,
|
||||
onCheckChanged = callbacks::onUseSystemEmojiChanged
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
Rows.ToggleRow(
|
||||
text = stringResource(R.string.ChatsSettingsFragment__send_with_enter),
|
||||
enabled = state.isRegisteredAndUpToDate(),
|
||||
checked = state.enterKeySends,
|
||||
onCheckChanged = callbacks::onEnterKeySendsChanged
|
||||
)
|
||||
}
|
||||
|
||||
if (!isRemoteBackupsAvailable) {
|
||||
item {
|
||||
Dividers.Default()
|
||||
}
|
||||
|
||||
item {
|
||||
Texts.SectionHeader(stringResource(R.string.preferences_chats__backups))
|
||||
}
|
||||
|
||||
item {
|
||||
Rows.TextRow(
|
||||
text = stringResource(R.string.preferences_chats__chat_backups),
|
||||
label = stringResource(if (state.localBackupsEnabled) R.string.arrays__enabled else R.string.arrays__disabled),
|
||||
enabled = state.localBackupsEnabled || state.isRegisteredAndUpToDate(),
|
||||
onClick = callbacks::onChatBackupsClick
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SignalPreview
|
||||
@Composable
|
||||
private fun ChatsSettingsScreenPreview() {
|
||||
Previews.Preview {
|
||||
ChatsSettingsScreen(
|
||||
state = ChatsSettingsState(
|
||||
generateLinkPreviews = true,
|
||||
useAddressBook = true,
|
||||
keepMutedChatsArchived = true,
|
||||
useSystemEmoji = false,
|
||||
enterKeySends = false,
|
||||
localBackupsEnabled = true,
|
||||
folderCount = 1,
|
||||
userUnregistered = false,
|
||||
clientDeprecated = false
|
||||
),
|
||||
callbacks = ChatsSettingsCallbacks.Empty,
|
||||
isRemoteBackupsAvailable = false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package org.thoughtcrime.securesms.components.settings.app.chats
|
||||
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import org.thoughtcrime.securesms.components.settings.app.chats.folders.ChatFoldersRepository
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
@@ -12,7 +14,6 @@ import org.thoughtcrime.securesms.util.BackupUtil
|
||||
import org.thoughtcrime.securesms.util.ConversationUtil
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.util.ThrottledDebouncer
|
||||
import org.thoughtcrime.securesms.util.livedata.Store
|
||||
|
||||
class ChatsSettingsViewModel @JvmOverloads constructor(
|
||||
private val repository: ChatsSettingsRepository = ChatsSettingsRepository()
|
||||
@@ -20,7 +21,7 @@ class ChatsSettingsViewModel @JvmOverloads constructor(
|
||||
|
||||
private val refreshDebouncer = ThrottledDebouncer(500L)
|
||||
|
||||
private val store: Store<ChatsSettingsState> = Store(
|
||||
private val store = MutableStateFlow(
|
||||
ChatsSettingsState(
|
||||
generateLinkPreviews = SignalStore.settings.isLinkPreviewsEnabled,
|
||||
useAddressBook = SignalStore.settings.isPreferSystemContactPhotos,
|
||||
@@ -34,7 +35,7 @@ class ChatsSettingsViewModel @JvmOverloads constructor(
|
||||
)
|
||||
)
|
||||
|
||||
val state: LiveData<ChatsSettingsState> = store.stateLiveData
|
||||
val state: StateFlow<ChatsSettingsState> = store
|
||||
|
||||
fun setGenerateLinkPreviewsEnabled(enabled: Boolean) {
|
||||
store.update { it.copy(generateLinkPreviews = enabled) }
|
||||
@@ -70,7 +71,7 @@ class ChatsSettingsViewModel @JvmOverloads constructor(
|
||||
val count = ChatFoldersRepository.getFolderCount()
|
||||
val backupsEnabled = SignalStore.settings.isBackupEnabled && BackupUtil.canUserAccessBackupDirectory(AppDependencies.application)
|
||||
|
||||
if (store.state.localBackupsEnabled != backupsEnabled) {
|
||||
if (store.value.localBackupsEnabled != backupsEnabled) {
|
||||
store.update {
|
||||
it.copy(
|
||||
folderCount = count,
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiStrings
|
||||
import org.thoughtcrime.securesms.components.settings.app.notifications.profiles.AddAllowedMembersViewModel.NotificationProfileAndRecipients
|
||||
import org.thoughtcrime.securesms.compose.ComposeFragment
|
||||
import org.thoughtcrime.securesms.compose.rememberStatusBarColorNestedScrollModifier
|
||||
import org.thoughtcrime.securesms.database.RecipientTable
|
||||
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfile
|
||||
import org.thoughtcrime.securesms.notifications.profiles.NotificationProfileId
|
||||
@@ -166,7 +167,9 @@ private fun AddAllowedMembersContent(
|
||||
modifier = Modifier.padding(contentPadding)
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier.weight(1f)
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.then(rememberStatusBarColorNestedScrollModifier())
|
||||
) {
|
||||
item {
|
||||
Text(
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.signal.core.ui.compose.SignalPreview
|
||||
import org.signal.core.ui.compose.Texts
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.compose.ComposeFragment
|
||||
import org.thoughtcrime.securesms.compose.rememberStatusBarColorNestedScrollModifier
|
||||
import org.thoughtcrime.securesms.util.CommunicationActions
|
||||
import org.thoughtcrime.securesms.util.viewModel
|
||||
|
||||
@@ -176,7 +177,9 @@ private fun AdvancedPrivacySettingsScreen(
|
||||
navigationIcon = ImageVector.vectorResource(R.drawable.symbol_arrow_start_24)
|
||||
) { paddingValues ->
|
||||
LazyColumn(
|
||||
modifier = Modifier.padding(paddingValues)
|
||||
modifier = Modifier
|
||||
.padding(paddingValues)
|
||||
.then(rememberStatusBarColorNestedScrollModifier())
|
||||
) {
|
||||
item {
|
||||
Rows.ToggleRow(
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.signal.core.ui.compose.Scaffolds
|
||||
import org.signal.core.ui.compose.SignalPreview
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.compose.ComposeFragment
|
||||
import org.thoughtcrime.securesms.compose.rememberStatusBarColorNestedScrollModifier
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.jobs.ApkUpdateJob
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
@@ -90,7 +91,9 @@ private fun AppUpdatesSettingsScreen(
|
||||
) { paddingValues ->
|
||||
|
||||
LazyColumn(
|
||||
modifier = Modifier.padding(paddingValues)
|
||||
modifier = Modifier
|
||||
.padding(paddingValues)
|
||||
.then(rememberStatusBarColorNestedScrollModifier())
|
||||
) {
|
||||
if (Build.VERSION.SDK_INT >= 31) {
|
||||
item {
|
||||
|
||||
@@ -2,9 +2,15 @@ package org.thoughtcrime.securesms.compose
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.app.Activity
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.Velocity
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.google.android.material.animation.ArgbEvaluatorCompat
|
||||
@@ -14,10 +20,14 @@ import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* Controls status-bar color based off a nested scroll
|
||||
*
|
||||
* Recommended to use this with [rememberStatusBarColorNestedScrollModifier] since it'll prevent you from having to wire through
|
||||
* an activity or the connection to subcomponents.
|
||||
*/
|
||||
class StatusBarColorNestedScrollConnection(
|
||||
private val activity: Activity
|
||||
) : NestedScrollConnection {
|
||||
|
||||
private var animator: ValueAnimator? = null
|
||||
|
||||
private val normalColor = ContextCompat.getColor(activity, R.color.signal_colorBackground)
|
||||
@@ -78,3 +88,21 @@ class StatusBarColorNestedScrollConnection(
|
||||
|
||||
private fun Float.isNearZero(): Boolean = abs(this) < 0.001
|
||||
}
|
||||
|
||||
/**
|
||||
* Remembers the nested scroll modifier to ensure the proper status bar coloring behavior.
|
||||
*
|
||||
* This is only required if the screen you are modifying does not utilize edgeToEdge.
|
||||
*/
|
||||
@Composable
|
||||
fun rememberStatusBarColorNestedScrollModifier(): Modifier {
|
||||
val activity = LocalContext.current as? AppCompatActivity
|
||||
|
||||
return remember {
|
||||
if (activity != null) {
|
||||
Modifier.nestedScroll(StatusBarColorNestedScrollConnection(activity))
|
||||
} else {
|
||||
Modifier
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user