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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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