Migrate search bar style preferences

This commit is contained in:
MM20 2022-01-27 20:45:46 +01:00
parent 09bb040e9a
commit 237a0f2087
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
7 changed files with 175 additions and 6 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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()
}

View File

@ -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;
}

View File

@ -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

View File

@ -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)
}
}
)
}
}

View File

@ -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()
}
}
}
}