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_search_gdrive">Google Drive</string>
|
||||||
<string name="preference_summary_not_logged_in">Sie sind im Moment nicht angemeldet</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_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>
|
<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">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_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="preference_wikipedia_customurl">Wikipedia URL</string>
|
||||||
|
|
||||||
<string name="music_widget_default_title">%1$s is playing media</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))
|
.setColumnCount(context.resources.getInteger(R.integer.config_columnCount))
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
|
.setSearchBar(
|
||||||
|
Settings.SearchBarSettings.newBuilder()
|
||||||
|
.setSearchBarStyle(Settings.SearchBarSettings.SearchBarStyle.Transparent)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
@ -123,4 +123,14 @@ message Settings {
|
|||||||
}
|
}
|
||||||
GridSettings grid = 19;
|
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.runtime.livedata.observeAsState
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.focus.focusRequester
|
import androidx.compose.ui.focus.focusRequester
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.focus.onFocusEvent
|
import androidx.compose.ui.focus.onFocusEvent
|
||||||
@ -41,11 +42,16 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import coil.compose.rememberImagePainter
|
import coil.compose.rememberImagePainter
|
||||||
import de.mm20.launcher2.ktx.tryStartActivity
|
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.search.data.Websearch
|
||||||
import de.mm20.launcher2.ui.R
|
import de.mm20.launcher2.ui.R
|
||||||
import de.mm20.launcher2.ui.component.LauncherCard
|
import de.mm20.launcher2.ui.component.LauncherCard
|
||||||
import de.mm20.launcher2.ui.launcher.LauncherActivityVM
|
import de.mm20.launcher2.ui.launcher.LauncherActivityVM
|
||||||
import de.mm20.launcher2.ui.settings.SettingsActivity
|
import de.mm20.launcher2.ui.settings.SettingsActivity
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
import org.koin.androidx.compose.inject
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@ -56,6 +62,11 @@ fun SearchBar(
|
|||||||
val searchViewModel: SearchVM = viewModel()
|
val searchViewModel: SearchVM = viewModel()
|
||||||
val activityViewModel: LauncherActivityVM = 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 context = LocalContext.current
|
||||||
|
|
||||||
val query by searchViewModel.searchQuery.observeAsState("")
|
val query by searchViewModel.searchQuery.observeAsState("")
|
||||||
@ -69,6 +80,7 @@ fun SearchBar(
|
|||||||
onValueChange = {
|
onValueChange = {
|
||||||
searchViewModel.search(it)
|
searchViewModel.search(it)
|
||||||
},
|
},
|
||||||
|
style = style,
|
||||||
overflowMenu = { show, onDismissRequest ->
|
overflowMenu = { show, onDismissRequest ->
|
||||||
DropdownMenu(expanded = show, onDismissRequest = onDismissRequest) {
|
DropdownMenu(expanded = show, onDismissRequest = onDismissRequest) {
|
||||||
DropdownMenuItem(onClick = {
|
DropdownMenuItem(onClick = {
|
||||||
@ -125,6 +137,7 @@ fun SearchBar(
|
|||||||
websearches: List<Websearch>,
|
websearches: List<Websearch>,
|
||||||
overflowMenu: @Composable (show: Boolean, onDismissRequest: () -> Unit) -> Unit = { _, _ -> },
|
overflowMenu: @Composable (show: Boolean, onDismissRequest: () -> Unit) -> Unit = { _, _ -> },
|
||||||
value: String,
|
value: String,
|
||||||
|
style: SearchBarSettings.SearchBarStyle,
|
||||||
onValueChange: (String) -> Unit,
|
onValueChange: (String) -> Unit,
|
||||||
onFocus: () -> Unit = {}
|
onFocus: () -> Unit = {}
|
||||||
) {
|
) {
|
||||||
@ -148,10 +161,10 @@ fun SearchBar(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
when (it) {
|
when {
|
||||||
SearchBarLevel.Resting -> 0.dp
|
it == SearchBarLevel.Resting && style != SearchBarSettings.SearchBarStyle.Solid -> 0.dp
|
||||||
SearchBarLevel.Active -> 2.dp
|
it == SearchBarLevel.Raised -> 8.dp
|
||||||
SearchBarLevel.Raised -> 8.dp
|
else -> 2.dp
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -166,7 +179,11 @@ fun SearchBar(
|
|||||||
else -> tween(durationMillis = 500)
|
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",
|
val contentColor by transition.animateColor(label = "textColor",
|
||||||
@ -180,7 +197,16 @@ fun SearchBar(
|
|||||||
else -> tween(durationMillis = 500)
|
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)
|
val rightIcon = AnimatedImageVector.animatedVectorResource(R.drawable.anim_ic_menu_clear)
|
||||||
@ -189,6 +215,7 @@ fun SearchBar(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.wrapContentHeight()
|
.wrapContentHeight()
|
||||||
|
.alpha(opacity)
|
||||||
.padding(8.dp),
|
.padding(8.dp),
|
||||||
backgroundOpacity = backgroundOpacity,
|
backgroundOpacity = backgroundOpacity,
|
||||||
elevation = elevation
|
elevation = elevation
|
||||||
|
|||||||
@ -1,15 +1,33 @@
|
|||||||
package de.mm20.launcher2.ui.settings.appearance
|
package de.mm20.launcher2.ui.settings.appearance
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
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.*
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
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.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
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.ColorScheme
|
||||||
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
|
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.R
|
||||||
import de.mm20.launcher2.ui.component.preferences.*
|
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
|
@Composable
|
||||||
fun AppearanceSettingsScreen() {
|
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.LauncherDataStore
|
||||||
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme
|
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme
|
||||||
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
|
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
|
||||||
|
import de.mm20.launcher2.preferences.Settings.SearchBarSettings
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.koin.core.component.KoinComponent
|
import org.koin.core.component.KoinComponent
|
||||||
@ -63,4 +64,17 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent {
|
|||||||
fun openWallpaperChooser(context: AppCompatActivity) {
|
fun openWallpaperChooser(context: AppCompatActivity) {
|
||||||
context.startActivity(Intent.createChooser(Intent(Intent.ACTION_SET_WALLPAPER), null))
|
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