Migrate search settings

This commit is contained in:
MM20
2022-01-10 21:48:29 +01:00
parent d91fc525f8
commit 5834e7e8c4
22 changed files with 964 additions and 371 deletions
@@ -0,0 +1,57 @@
package de.mm20.launcher2.ui.component.preferences
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.Switch
import androidx.compose.material.SwitchDefaults
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.unit.dp
@Composable
fun PreferenceWithSwitch(
title: String,
summary: String? = null,
icon: ImageVector? = null,
enabled: Boolean = true,
onClick: () -> Unit = {},
switchValue: Boolean,
onSwitchChanged: (Boolean) -> Unit
) {
Row(
verticalAlignment = (Alignment.CenterVertically)
) {
Box(
modifier = Modifier.weight(1f)
) {
Preference(
title = title,
summary = summary,
icon = icon,
enabled = enabled,
onClick = onClick
)
}
Box(
modifier = Modifier
.height(36.dp)
.width(1.dp)
.alpha(0.38f)
.background(LocalContentColor.current)
)
Switch(
modifier = Modifier.padding(horizontal = 16.dp),
checked = switchValue,
enabled = enabled,
onCheckedChange = onSwitchChanged,
colors = SwitchDefaults.colors(
uncheckedThumbColor = MaterialTheme.colorScheme.onSurface
)
)
}
}
@@ -763,4 +763,47 @@ val Icons.Rounded.Fdroid
lineTo(6.3535156f, 10.242188f)
close()
}
}
val Icons.Rounded.Wikipedia
get() = materialIcon("Icons.Rounded.Wikipedia") {
materialPath {
moveTo(14.97f, 18.95f)
lineTo(12.41f, 12.92f)
curveTo(11.39f, 14.91f, 10.27f, 17f, 9.31f, 18.95f)
curveTo(9.3f, 18.96f, 8.84f, 18.95f, 8.84f, 18.95f)
curveTo(7.37f, 15.5f, 5.85f, 12.1f, 4.37f, 8.68f)
curveTo(4.03f, 7.84f, 2.83f, 6.5f, 2f, 6.5f)
curveTo(2f, 6.4f, 2f, 6.18f, 2f, 6.05f)
horizontalLineTo(7.06f)
verticalLineTo(6.5f)
curveTo(6.46f, 6.5f, 5.44f, 6.9f, 5.7f, 7.55f)
curveTo(6.42f, 9.09f, 8.94f, 15.06f, 9.63f, 16.58f)
curveTo(10.1f, 15.64f, 11.43f, 13.16f, 12f, 12.11f)
curveTo(11.55f, 11.23f, 10.13f, 7.93f, 9.71f, 7.11f)
curveTo(9.39f, 6.57f, 8.58f, 6.5f, 7.96f, 6.5f)
curveTo(7.96f, 6.35f, 7.97f, 6.25f, 7.96f, 6.06f)
lineTo(12.42f, 6.07f)
verticalLineTo(6.47f)
curveTo(11.81f, 6.5f, 11.24f, 6.71f, 11.5f, 7.29f)
curveTo(12.1f, 8.53f, 12.45f, 9.42f, 13f, 10.57f)
curveTo(13.17f, 10.23f, 14.07f, 8.38f, 14.5f, 7.41f)
curveTo(14.76f, 6.76f, 14.37f, 6.5f, 13.29f, 6.5f)
curveTo(13.3f, 6.38f, 13.3f, 6.17f, 13.3f, 6.07f)
curveTo(14.69f, 6.06f, 16.78f, 6.06f, 17.15f, 6.05f)
verticalLineTo(6.47f)
curveTo(16.44f, 6.5f, 15.71f, 6.88f, 15.33f, 7.46f)
lineTo(13.5f, 11.3f)
curveTo(13.68f, 11.81f, 15.46f, 15.76f, 15.65f, 16.2f)
lineTo(19.5f, 7.37f)
curveTo(19.2f, 6.65f, 18.34f, 6.5f, 18f, 6.5f)
curveTo(18f, 6.37f, 18f, 6.2f, 18f, 6.05f)
lineTo(22f, 6.08f)
verticalLineTo(6.1f)
lineTo(22f, 6.5f)
curveTo(21.12f, 6.5f, 20.57f, 7f, 20.25f, 7.75f)
curveTo(19.45f, 9.54f, 17f, 15.24f, 15.4f, 18.95f)
curveTo(15.4f, 18.95f, 14.97f, 18.95f, 14.97f, 18.95f)
close()
}
}
@@ -28,6 +28,7 @@ import de.mm20.launcher2.ui.settings.debug.DebugSettingsScreen
import de.mm20.launcher2.ui.settings.license.LicenseScreen
import de.mm20.launcher2.ui.settings.main.MainSettingsScreen
import de.mm20.launcher2.ui.settings.musicwidget.MusicWidgetSettingsScreen
import de.mm20.launcher2.ui.settings.search.SearchSettingsScreen
import de.mm20.launcher2.ui.settings.weatherwidget.WeatherWidgetSettingsScreen
import de.mm20.launcher2.ui.settings.widgets.WidgetsSettingsScreen
@@ -85,6 +86,9 @@ class SettingsActivity : BaseActivity() {
composable("settings/appearance") {
AppearanceSettingsScreen()
}
composable("settings/search") {
SearchSettingsScreen()
}
composable("settings/widgets") {
WidgetsSettingsScreen()
}
@@ -33,7 +33,10 @@ fun MainSettingsScreen() {
Preference(
icon = Icons.Rounded.Search,
title = stringResource(id = R.string.preference_screen_search),
summary = stringResource(id = R.string.preference_screen_search_summary)
summary = stringResource(id = R.string.preference_screen_search_summary),
onClick = {
navController?.navigate("settings/search")
}
)
Preference(
icon = Icons.Rounded.Widgets,
@@ -0,0 +1,146 @@
package de.mm20.launcher2.ui.settings.search
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
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 de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.MissingPermissionBanner
import de.mm20.launcher2.ui.component.preferences.*
import de.mm20.launcher2.ui.icons.Wikipedia
@Composable
fun SearchSettingsScreen() {
val viewModel: SearchSettingsScreenVM = viewModel()
val context = LocalContext.current
PreferenceScreen(title = stringResource(R.string.preference_screen_search)) {
item {
PreferenceCategory {
val favorites by viewModel.favorites.observeAsState()
SwitchPreference(
title = stringResource(R.string.preference_search_favorites),
summary = stringResource(R.string.preference_search_favorites_summary),
icon = Icons.Rounded.Star,
value = favorites == true,
onValueChanged = {
viewModel.setFavorites(it)
}
)
Preference(
title = stringResource(R.string.preference_search_files),
summary = stringResource(R.string.preference_search_files_summary),
icon = Icons.Rounded.Description
)
val hasContactsPermission by viewModel.hasContactsPermission.observeAsState()
AnimatedVisibility(hasContactsPermission == false) {
MissingPermissionBanner(
text = stringResource(R.string.missing_permission_contact_search),
onClick = {
viewModel.requestContactsPermission(context as AppCompatActivity)
},
modifier = Modifier.padding(16.dp)
)
}
val contacts by viewModel.contacts.observeAsState()
SwitchPreference(
title = stringResource(R.string.preference_search_contacts),
summary = stringResource(R.string.preference_search_contacts_summary),
icon = Icons.Rounded.Person,
value = contacts == true,
onValueChanged = {
viewModel.setContacts(it)
}
)
val hasCalendarPermission by viewModel.hasCalendarPermission.observeAsState()
AnimatedVisibility(hasCalendarPermission == false) {
MissingPermissionBanner(
text = stringResource(R.string.missing_permission_calendar_search),
onClick = {
viewModel.requestCalendarPermission(context as AppCompatActivity)
},
modifier = Modifier.padding(16.dp)
)
}
val calendar by viewModel.calendar.observeAsState()
SwitchPreference(
title = stringResource(R.string.preference_search_calendar),
summary = stringResource(R.string.preference_search_calendar_summary),
icon = Icons.Rounded.Today,
value = calendar == true,
onValueChanged = {
viewModel.setCalendar(it)
}
)
val calculator by viewModel.calculator.observeAsState()
SwitchPreference(
title = stringResource(R.string.preference_search_calculator),
summary = stringResource(R.string.preference_search_calculator_summary),
icon = Icons.Rounded.Calculate,
value = calculator == true,
onValueChanged = {
viewModel.setCalculator(it)
}
)
val unitConverter by viewModel.unitConverter.observeAsState()
SwitchPreference(
title = stringResource(R.string.preference_search_unitconverter),
summary = stringResource(R.string.preference_search_unitconverter_summary),
icon = Icons.Rounded.Loop,
value = unitConverter == true,
onValueChanged = {
viewModel.setUnitConverter(it)
}
)
val wikipedia by viewModel.wikipedia.observeAsState()
PreferenceWithSwitch(
title = stringResource(R.string.preference_search_wikipedia),
summary = stringResource(R.string.preference_search_wikipedia_summary),
icon = Icons.Rounded.Wikipedia,
switchValue = wikipedia == true,
onSwitchChanged = {
viewModel.setWikipedia(it)
}
)
val websites by viewModel.websites.observeAsState()
SwitchPreference(
title = stringResource(R.string.preference_search_websites),
summary = stringResource(R.string.preference_search_websites_summary),
icon = Icons.Rounded.Language,
value = websites == true,
onValueChanged = {
viewModel.setWebsites(it)
}
)
val webSearch by viewModel.webSearch.observeAsState()
PreferenceWithSwitch(
title = stringResource(R.string.preference_search_websearch),
summary = stringResource(R.string.preference_search_websearch_summary),
icon = Icons.Rounded.TravelExplore,
switchValue = webSearch == true,
onSwitchChanged = {
viewModel.setWebSearch(it)
}
)
}
}
}
}
@@ -0,0 +1,139 @@
package de.mm20.launcher2.ui.settings.search
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.preferences.LauncherDataStore
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class SearchSettingsScreenVM : ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject()
private val permissionsManager: PermissionsManager by inject()
val favorites = dataStore.data.map { it.favorites.enabled }.asLiveData()
fun setFavorites(favorites: Boolean) {
viewModelScope.launch {
dataStore.updateData {
it.toBuilder()
.setFavorites(
it.favorites.toBuilder()
.setEnabled(favorites)
)
.build()
}
}
}
val hasContactsPermission = permissionsManager.hasPermission(PermissionGroup.Contacts).asLiveData()
val contacts = dataStore.data.map { it.contactsSearch.enabled }.asLiveData()
fun setContacts(contacts: Boolean) {
viewModelScope.launch {
dataStore.updateData {
it.toBuilder()
.setContactsSearch(
it.contactsSearch.toBuilder()
.setEnabled(contacts)
)
.build()
}
}
}
fun requestContactsPermission(activity: AppCompatActivity) {
permissionsManager.requestPermission(activity, PermissionGroup.Contacts)
}
val hasCalendarPermission = permissionsManager.hasPermission(PermissionGroup.Calendar).asLiveData()
val calendar = dataStore.data.map { it.calendarSearch.enabled }.asLiveData()
fun setCalendar(calendar: Boolean) {
viewModelScope.launch {
dataStore.updateData {
it.toBuilder()
.setCalendarSearch(
it.calendarSearch.toBuilder()
.setEnabled(calendar)
)
.build()
}
}
}
fun requestCalendarPermission(activity: AppCompatActivity) {
permissionsManager.requestPermission(activity, PermissionGroup.Calendar)
}
val calculator = dataStore.data.map { it.calculatorSearch.enabled }.asLiveData()
fun setCalculator(calculator: Boolean) {
viewModelScope.launch {
dataStore.updateData {
it.toBuilder()
.setCalculatorSearch(
it.calculatorSearch.toBuilder()
.setEnabled(calculator)
)
.build()
}
}
}
val unitConverter = dataStore.data.map { it.unitConverterSearch.enabled }.asLiveData()
fun setUnitConverter(unitConverter: Boolean) {
viewModelScope.launch {
dataStore.updateData {
it.toBuilder()
.setUnitConverterSearch(
it.unitConverterSearch.toBuilder()
.setEnabled(unitConverter)
)
.build()
}
}
}
val wikipedia = dataStore.data.map { it.wikipediaSearch.enabled }.asLiveData()
fun setWikipedia(wikipedia: Boolean) {
viewModelScope.launch {
dataStore.updateData {
it.toBuilder()
.setWikipediaSearch(
it.wikipediaSearch.toBuilder()
.setEnabled(wikipedia)
)
.build()
}
}
}
val websites = dataStore.data.map { it.websiteSearch.enabled }.asLiveData()
fun setWebsites(websites: Boolean) {
viewModelScope.launch {
dataStore.updateData {
it.toBuilder()
.setWebsiteSearch(
it.websiteSearch.toBuilder()
.setEnabled(websites)
)
.build()
}
}
}
val webSearch = dataStore.data.map { it.webSearch.enabled }.asLiveData()
fun setWebSearch(webSearch: Boolean) {
viewModelScope.launch {
dataStore.updateData {
it.toBuilder()
.setWebSearch(
it.webSearch.toBuilder()
.setEnabled(webSearch)
)
.build()
}
}
}
}