Migrate search bar style preferences
This commit is contained in:
parent
09bb040e9a
commit
237a0f2087
@ -459,6 +459,8 @@
|
||||
<string name="preference_search_gdrive">Google Drive</string>
|
||||
<string name="preference_summary_not_logged_in">Sie sind im Moment nicht angemeldet</string>
|
||||
<string name="preference_search_gdrive_summary">%1$ss Dateien auf Google Drive durchsuchen</string>
|
||||
<string name="preference_search_bar_style">Stil</string>
|
||||
<string name="preference_search_bar_style_summary">Erscheinungsbild der Suchleiste anpassen</string>
|
||||
|
||||
<string name="preference_wikipedia_customurl">Wikipedia-URL</string>
|
||||
|
||||
|
||||
@ -502,6 +502,9 @@
|
||||
<string name="preference_music_filter_sources">Restrict to music apps</string>
|
||||
<string name="preference_music_filter_sources_summary">Ignore media sessions of apps that are not music apps</string>
|
||||
|
||||
<string name="preference_search_bar_style">Style</string>
|
||||
<string name="preference_search_bar_style_summary">Customize search bar appearance</string>
|
||||
|
||||
<string name="preference_wikipedia_customurl">Wikipedia URL</string>
|
||||
|
||||
<string name="music_widget_default_title">%1$s is playing media</string>
|
||||
|
||||
@ -101,5 +101,10 @@ fun createFactorySettings(context: Context): Settings {
|
||||
.setColumnCount(context.resources.getInteger(R.integer.config_columnCount))
|
||||
.build()
|
||||
)
|
||||
.setSearchBar(
|
||||
Settings.SearchBarSettings.newBuilder()
|
||||
.setSearchBarStyle(Settings.SearchBarSettings.SearchBarStyle.Transparent)
|
||||
.build()
|
||||
)
|
||||
.build()
|
||||
}
|
||||
@ -123,4 +123,14 @@ message Settings {
|
||||
}
|
||||
GridSettings grid = 19;
|
||||
|
||||
message SearchBarSettings {
|
||||
enum SearchBarStyle {
|
||||
Transparent = 0;
|
||||
Solid = 1;
|
||||
Hidden = 2;
|
||||
}
|
||||
SearchBarStyle search_bar_style = 1;
|
||||
}
|
||||
SearchBarSettings search_bar = 20;
|
||||
|
||||
}
|
||||
@ -30,6 +30,7 @@ import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.focus.onFocusEvent
|
||||
@ -41,11 +42,16 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import coil.compose.rememberImagePainter
|
||||
import de.mm20.launcher2.ktx.tryStartActivity
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
import de.mm20.launcher2.preferences.Settings.SearchBarSettings
|
||||
import de.mm20.launcher2.search.data.Websearch
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.LauncherCard
|
||||
import de.mm20.launcher2.ui.launcher.LauncherActivityVM
|
||||
import de.mm20.launcher2.ui.settings.SettingsActivity
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.koin.androidx.compose.inject
|
||||
import java.io.File
|
||||
|
||||
@Composable
|
||||
@ -56,6 +62,11 @@ fun SearchBar(
|
||||
val searchViewModel: SearchVM = viewModel()
|
||||
val activityViewModel: LauncherActivityVM = viewModel()
|
||||
|
||||
val dataStore: LauncherDataStore by inject()
|
||||
|
||||
val style by remember { dataStore.data.map { it.searchBar.searchBarStyle } }
|
||||
.collectAsState(SearchBarSettings.SearchBarStyle.Hidden)
|
||||
|
||||
val context = LocalContext.current
|
||||
|
||||
val query by searchViewModel.searchQuery.observeAsState("")
|
||||
@ -69,6 +80,7 @@ fun SearchBar(
|
||||
onValueChange = {
|
||||
searchViewModel.search(it)
|
||||
},
|
||||
style = style,
|
||||
overflowMenu = { show, onDismissRequest ->
|
||||
DropdownMenu(expanded = show, onDismissRequest = onDismissRequest) {
|
||||
DropdownMenuItem(onClick = {
|
||||
@ -125,6 +137,7 @@ fun SearchBar(
|
||||
websearches: List<Websearch>,
|
||||
overflowMenu: @Composable (show: Boolean, onDismissRequest: () -> Unit) -> Unit = { _, _ -> },
|
||||
value: String,
|
||||
style: SearchBarSettings.SearchBarStyle,
|
||||
onValueChange: (String) -> Unit,
|
||||
onFocus: () -> Unit = {}
|
||||
) {
|
||||
@ -148,10 +161,10 @@ fun SearchBar(
|
||||
}
|
||||
}
|
||||
) {
|
||||
when (it) {
|
||||
SearchBarLevel.Resting -> 0.dp
|
||||
SearchBarLevel.Active -> 2.dp
|
||||
SearchBarLevel.Raised -> 8.dp
|
||||
when {
|
||||
it == SearchBarLevel.Resting && style != SearchBarSettings.SearchBarStyle.Solid -> 0.dp
|
||||
it == SearchBarLevel.Raised -> 8.dp
|
||||
else -> 2.dp
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,7 +179,11 @@ fun SearchBar(
|
||||
else -> tween(durationMillis = 500)
|
||||
}
|
||||
}) {
|
||||
if (it == SearchBarLevel.Resting) 0f else 1f
|
||||
when {
|
||||
style != SearchBarSettings.SearchBarStyle.Transparent -> 1f
|
||||
it == SearchBarLevel.Resting -> 0f
|
||||
else -> 1f
|
||||
}
|
||||
}
|
||||
|
||||
val contentColor by transition.animateColor(label = "textColor",
|
||||
@ -180,7 +197,16 @@ fun SearchBar(
|
||||
else -> tween(durationMillis = 500)
|
||||
}
|
||||
}) {
|
||||
if (it == SearchBarLevel.Resting) Color.White else LocalContentColor.current
|
||||
when {
|
||||
style != SearchBarSettings.SearchBarStyle.Transparent -> LocalContentColor.current
|
||||
it == SearchBarLevel.Resting -> Color.White
|
||||
else -> LocalContentColor.current
|
||||
}
|
||||
}
|
||||
|
||||
val opacity by transition.animateFloat(label = "opacity") {
|
||||
if (style == SearchBarSettings.SearchBarStyle.Hidden && it == SearchBarLevel.Resting) 0f
|
||||
else 1f
|
||||
}
|
||||
|
||||
val rightIcon = AnimatedImageVector.animatedVectorResource(R.drawable.anim_ic_menu_clear)
|
||||
@ -189,6 +215,7 @@ fun SearchBar(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.wrapContentHeight()
|
||||
.alpha(opacity)
|
||||
.padding(8.dp),
|
||||
backgroundOpacity = backgroundOpacity,
|
||||
elevation = elevation
|
||||
|
||||
@ -1,15 +1,33 @@
|
||||
package de.mm20.launcher2.ui.settings.appearance
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.AlertDialog
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import com.google.accompanist.pager.ExperimentalPagerApi
|
||||
import com.google.accompanist.pager.HorizontalPager
|
||||
import com.google.accompanist.pager.HorizontalPagerIndicator
|
||||
import com.google.accompanist.pager.rememberPagerState
|
||||
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme
|
||||
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
|
||||
import de.mm20.launcher2.preferences.Settings.SearchBarSettings
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.preferences.*
|
||||
import de.mm20.launcher2.ui.launcher.search.SearchBar
|
||||
import de.mm20.launcher2.ui.launcher.search.SearchBarLevel
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
|
||||
@Composable
|
||||
fun AppearanceSettingsScreen() {
|
||||
@ -78,6 +96,96 @@ fun AppearanceSettingsScreen() {
|
||||
}
|
||||
)
|
||||
}
|
||||
PreferenceCategory(stringResource(R.string.preference_category_searchbar)) {
|
||||
val searchBarStyle by viewModel.searchBarStyle.observeAsState()
|
||||
SearchBarStylePreference(
|
||||
title = stringResource(R.string.preference_search_bar_style),
|
||||
summary = stringResource(R.string.preference_search_bar_style_summary),
|
||||
value = searchBarStyle,
|
||||
onValueChanged = {
|
||||
viewModel.setSearchBarStyle(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalPagerApi::class)
|
||||
@Composable
|
||||
fun SearchBarStylePreference(
|
||||
title: String,
|
||||
summary: String? = null,
|
||||
value: SearchBarSettings.SearchBarStyle?,
|
||||
onValueChanged: (SearchBarSettings.SearchBarStyle) -> Unit
|
||||
) {
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
Preference(title = title, summary = summary, onClick = { showDialog = true })
|
||||
if (showDialog && value != null) {
|
||||
val styles = remember {
|
||||
SearchBarSettings.SearchBarStyle.values().filter { it != SearchBarSettings.SearchBarStyle.UNRECOGNIZED }
|
||||
}
|
||||
val pagerState = rememberPagerState(styles.indexOf(value))
|
||||
|
||||
var level by remember { mutableStateOf(SearchBarLevel.Resting) }
|
||||
var previewSearchValue by remember { mutableStateOf("") }
|
||||
LaunchedEffect(null) {
|
||||
while(isActive) {
|
||||
delay(2000)
|
||||
level = SearchBarLevel.Active
|
||||
delay(1000)
|
||||
previewSearchValue = "A"
|
||||
delay(100)
|
||||
previewSearchValue = "AB"
|
||||
delay(100)
|
||||
previewSearchValue = "ABC"
|
||||
delay(800)
|
||||
level = SearchBarLevel.Raised
|
||||
delay(2000)
|
||||
level = SearchBarLevel.Resting
|
||||
previewSearchValue = ""
|
||||
}
|
||||
}
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = { showDialog = false },
|
||||
confirmButton = {
|
||||
TextButton(onClick = {
|
||||
showDialog = false
|
||||
onValueChanged(styles[pagerState.currentPage])
|
||||
}) {
|
||||
Text(
|
||||
text = stringResource(android.R.string.ok),
|
||||
style = MaterialTheme.typography.labelLarge
|
||||
)
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
TextButton(onClick = { showDialog = false }) {
|
||||
Text(
|
||||
text = stringResource(android.R.string.cancel),
|
||||
style = MaterialTheme.typography.labelLarge
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
text = {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
HorizontalPager(
|
||||
count = styles.size,
|
||||
state = pagerState,
|
||||
modifier = Modifier
|
||||
.height(150.dp)
|
||||
.padding(bottom = 16.dp)
|
||||
.background(MaterialTheme.colorScheme.secondary)
|
||||
) {
|
||||
SearchBar(level = level, style = styles[it], websearches = emptyList(), value = previewSearchValue, onValueChange = {})
|
||||
}
|
||||
HorizontalPagerIndicator(pagerState = pagerState)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -8,6 +8,7 @@ import androidx.lifecycle.viewModelScope
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme
|
||||
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
|
||||
import de.mm20.launcher2.preferences.Settings.SearchBarSettings
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
@ -63,4 +64,17 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
fun openWallpaperChooser(context: AppCompatActivity) {
|
||||
context.startActivity(Intent.createChooser(Intent(Intent.ACTION_SET_WALLPAPER), null))
|
||||
}
|
||||
|
||||
val searchBarStyle = dataStore.data.map { it.searchBar.searchBarStyle }.asLiveData()
|
||||
fun setSearchBarStyle(searchBarStyle: SearchBarSettings.SearchBarStyle) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setSearchBar(it.searchBar.toBuilder()
|
||||
.setSearchBarStyle(searchBarStyle)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user