From 9309cd489145c8af7c5fd37ed6c2e49fb830d8f8 Mon Sep 17 00:00:00 2001
From: MM20 <15646950+MM2-0@users.noreply.github.com>
Date: Tue, 27 Sep 2022 20:45:34 +0200
Subject: [PATCH] Add a preference to hide the edit favorites button
---
i18n/src/main/res/values/strings.xml | 2 +
.../de/mm20/launcher2/preferences/Defaults.kt | 1 +
.../preferences/migrations/Migration_9_10.kt | 1 +
preferences/src/main/proto/settings.proto | 1 +
.../mm20/launcher2/ui/common/FavoritesVM.kt | 2 +
.../ui/launcher/search/SearchColumn.kt | 247 ++++++++++--------
.../widgets/favorites/FavoritesWidget.kt | 100 ++++---
.../favorites/FavoritesSettingsScreen.kt | 13 +
.../favorites/FavoritesSettingsScreenVM.kt | 14 +
9 files changed, 238 insertions(+), 143 deletions(-)
diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml
index 2d24f681..81990716 100644
--- a/i18n/src/main/res/values/strings.xml
+++ b/i18n/src/main/res/values/strings.xml
@@ -620,6 +620,8 @@
Change the order of pinned items
Frequently used
Show frequently used items in favorites
+ Edit button
+ Show a button to rearrange the favorites
You haven\'t connected a Nextcloud account yet
diff --git a/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt b/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt
index 4623665a..11e1d7a6 100644
--- a/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt
+++ b/preferences/src/main/java/de/mm20/launcher2/preferences/Defaults.kt
@@ -59,6 +59,7 @@ fun createFactorySettings(context: Context): Settings {
.setEnabled(true)
.setFrequentlyUsed(true)
.setFrequentlyUsedRows(1)
+ .setEditButton(true)
)
.setFileSearch(
Settings.FilesSearchSettings
diff --git a/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_9_10.kt b/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_9_10.kt
index 949fffa2..192fe122 100644
--- a/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_9_10.kt
+++ b/preferences/src/main/java/de/mm20/launcher2/preferences/migrations/Migration_9_10.kt
@@ -8,6 +8,7 @@ class Migration_9_10: VersionedMigration(9, 10) {
builder.favorites.toBuilder()
.setFrequentlyUsed(true)
.setFrequentlyUsedRows(1)
+ .setEditButton(true)
)
}
}
\ No newline at end of file
diff --git a/preferences/src/main/proto/settings.proto b/preferences/src/main/proto/settings.proto
index 21776fde..441656b0 100644
--- a/preferences/src/main/proto/settings.proto
+++ b/preferences/src/main/proto/settings.proto
@@ -128,6 +128,7 @@ message Settings {
bool enabled = 1;
bool frequently_used = 2;
int32 frequently_used_rows = 3;
+ bool edit_button = 4;
}
FavoritesSettings favorites = 8;
diff --git a/ui/src/main/java/de/mm20/launcher2/ui/common/FavoritesVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/common/FavoritesVM.kt
index 67453239..fb966556 100644
--- a/ui/src/main/java/de/mm20/launcher2/ui/common/FavoritesVM.kt
+++ b/ui/src/main/java/de/mm20/launcher2/ui/common/FavoritesVM.kt
@@ -22,6 +22,8 @@ open class FavoritesVM : ViewModel(), KoinComponent {
val selectedTag = MutableStateFlow(null)
+ val showEditButton = dataStore.data.map { it.favorites.editButton }
+
val pinnedTags = favoritesRepository.getFavorites(
includeTypes = listOf("tag"),
manuallySorted = true,
diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt
index 80e5b818..25e71ba9 100644
--- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt
+++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchColumn.kt
@@ -2,14 +2,39 @@ package de.mm20.launcher2.ui.launcher.search
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.horizontalScroll
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.lazy.*
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.lazy.LazyColumn
+import androidx.compose.foundation.lazy.LazyItemScope
+import androidx.compose.foundation.lazy.LazyListScope
+import androidx.compose.foundation.lazy.LazyListState
+import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.rounded.*
-import androidx.compose.material3.*
-import androidx.compose.runtime.*
+import androidx.compose.material.icons.rounded.Edit
+import androidx.compose.material.icons.rounded.Person
+import androidx.compose.material.icons.rounded.Star
+import androidx.compose.material.icons.rounded.Tag
+import androidx.compose.material.icons.rounded.Work
+import androidx.compose.material3.FilterChip
+import androidx.compose.material3.FloatingActionButtonDefaults
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.OutlinedButton
+import androidx.compose.material3.SmallFloatingActionButton
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
@@ -82,6 +107,7 @@ fun SearchColumn(
val pinnedTags by favoritesVM.pinnedTags.collectAsState(emptyList())
val selectedTag by favoritesVM.selectedTag.collectAsState(null)
val tagsScrollState = rememberScrollState()
+ val favoritesEditButton by favoritesVM.showEditButton.collectAsState(false)
LazyColumn(
state = state,
@@ -115,56 +141,62 @@ fun SearchColumn(
)
}
} else null,
- after = {
- Row(
- modifier = Modifier
- .fillMaxWidth()
- .padding(
- top = if (reverse) 8.dp else 4.dp,
- bottom = if (reverse) 4.dp else 8.dp,
- end = 8.dp
- ),
- horizontalArrangement = Arrangement.End,
- verticalAlignment = Alignment.CenterVertically,
- ) {
+ after = if (pinnedTags.isEmpty() && !favoritesEditButton) {
+ null
+ } else {
+ {
Row(
modifier = Modifier
- .weight(1f)
- .horizontalScroll(tagsScrollState)
- .padding(end = 12.dp),
+ .fillMaxWidth()
+ .padding(
+ top = if (reverse) 8.dp else 4.dp,
+ bottom = if (reverse) 4.dp else 8.dp,
+ end = if (favoritesEditButton) 8.dp else 0.dp
+ ),
+ horizontalArrangement = Arrangement.End,
+ verticalAlignment = Alignment.CenterVertically,
) {
- FilterChip(
- modifier = Modifier.padding(start = 16.dp),
- selected = selectedTag == null,
- onClick = { favoritesVM.selectTag(null) },
- leadingIcon = {
- Icon(
- imageVector = Icons.Rounded.Star,
- contentDescription = null
- )
- },
- label = { Text(stringResource(R.string.favorites)) }
- )
- for (tag in pinnedTags) {
+ Row(
+ modifier = Modifier
+ .weight(1f)
+ .horizontalScroll(tagsScrollState)
+ .padding(end = 12.dp),
+ ) {
FilterChip(
- modifier = Modifier.padding(start = 8.dp),
- selected = selectedTag == tag.tag,
- onClick = { favoritesVM.selectTag(tag.tag) },
+ modifier = Modifier.padding(start = 16.dp),
+ selected = selectedTag == null,
+ onClick = { favoritesVM.selectTag(null) },
leadingIcon = {
Icon(
- imageVector = Icons.Rounded.Tag,
+ imageVector = Icons.Rounded.Star,
contentDescription = null
)
},
- label = { Text(tag.label) }
+ label = { Text(stringResource(R.string.favorites)) }
)
+ for (tag in pinnedTags) {
+ FilterChip(
+ modifier = Modifier.padding(start = 8.dp),
+ selected = selectedTag == tag.tag,
+ onClick = { favoritesVM.selectTag(tag.tag) },
+ leadingIcon = {
+ Icon(
+ imageVector = Icons.Rounded.Tag,
+ contentDescription = null
+ )
+ },
+ label = { Text(tag.label) }
+ )
+ }
+ }
+ if (favoritesEditButton) {
+ SmallFloatingActionButton(
+ elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation(),
+ onClick = { showEditFavoritesDialog = true }
+ ) {
+ Icon(imageVector = Icons.Rounded.Edit, contentDescription = null)
+ }
}
- }
- SmallFloatingActionButton(
- elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation(),
- onClick = { showEditFavoritesDialog = true }
- ) {
- Icon(imageVector = Icons.Rounded.Edit, contentDescription = null)
}
}
}
@@ -221,22 +253,24 @@ fun SearchColumn(
} else null
)
ListResults(
- before = if (missingShortcutsPermission && !isSearchEmpty){{
- MissingPermissionBanner(
- modifier = Modifier.padding(8.dp),
- text = stringResource(R.string.missing_permission_appshortcuts_search),
- onClick = { viewModel.requestAppShortcutPermission(context as AppCompatActivity) },
- secondaryAction = {
- OutlinedButton(onClick = {
- viewModel.disableAppShortcutSearch()
- }) {
- Text(
- stringResource(R.string.turn_off),
- )
+ before = if (missingShortcutsPermission && !isSearchEmpty) {
+ {
+ MissingPermissionBanner(
+ modifier = Modifier.padding(8.dp),
+ text = stringResource(R.string.missing_permission_appshortcuts_search),
+ onClick = { viewModel.requestAppShortcutPermission(context as AppCompatActivity) },
+ secondaryAction = {
+ OutlinedButton(onClick = {
+ viewModel.disableAppShortcutSearch()
+ }) {
+ Text(
+ stringResource(R.string.turn_off),
+ )
+ }
}
- }
- )
- }} else null,
+ )
+ }
+ } else null,
items = appShortcuts.toImmutableList(),
reverse = reverse,
key = "shortcuts"
@@ -254,42 +288,47 @@ fun SearchColumn(
}
}
ListResults(
- before = if (missingCalendarPermission && !isSearchEmpty){{
- MissingPermissionBanner(
- modifier = Modifier.padding(8.dp),
- text = stringResource(R.string.missing_permission_calendar_search),
- onClick = { viewModel.requestCalendarPermission(context as AppCompatActivity) },secondaryAction = {
- OutlinedButton(onClick = {
- viewModel.disableCalendarSearch()
- }) {
- Text(
- stringResource(R.string.turn_off),
- )
+ before = if (missingCalendarPermission && !isSearchEmpty) {
+ {
+ MissingPermissionBanner(
+ modifier = Modifier.padding(8.dp),
+ text = stringResource(R.string.missing_permission_calendar_search),
+ onClick = { viewModel.requestCalendarPermission(context as AppCompatActivity) },
+ secondaryAction = {
+ OutlinedButton(onClick = {
+ viewModel.disableCalendarSearch()
+ }) {
+ Text(
+ stringResource(R.string.turn_off),
+ )
+ }
}
- }
- )
- }} else null,
+ )
+ }
+ } else null,
items = events.toImmutableList(),
reverse = reverse,
key = "events"
)
ListResults(
- before = if (missingContactsPermission && !isSearchEmpty){{
- MissingPermissionBanner(
- modifier = Modifier.padding(8.dp),
- text = stringResource(R.string.missing_permission_contact_search),
- onClick = { viewModel.requestContactsPermission(context as AppCompatActivity) },
- secondaryAction = {
- OutlinedButton(onClick = {
- viewModel.disableContactsSearch()
- }) {
- Text(
- stringResource(R.string.turn_off),
- )
+ before = if (missingContactsPermission && !isSearchEmpty) {
+ {
+ MissingPermissionBanner(
+ modifier = Modifier.padding(8.dp),
+ text = stringResource(R.string.missing_permission_contact_search),
+ onClick = { viewModel.requestContactsPermission(context as AppCompatActivity) },
+ secondaryAction = {
+ OutlinedButton(onClick = {
+ viewModel.disableContactsSearch()
+ }) {
+ Text(
+ stringResource(R.string.turn_off),
+ )
+ }
}
- }
- )
- }} else null,
+ )
+ }
+ } else null,
items = contacts.toImmutableList(),
reverse = reverse,
key = "contacts"
@@ -307,22 +346,24 @@ fun SearchColumn(
}
}
ListResults(
- before = if (missingFilesPermission && !isSearchEmpty){{
- MissingPermissionBanner(
- modifier = Modifier.padding(8.dp),
- text = stringResource(R.string.missing_permission_files_search),
- onClick = { viewModel.requestFilesPermission(context as AppCompatActivity) },
- secondaryAction = {
- OutlinedButton(onClick = {
- viewModel.disableFilesSearch()
- }) {
- Text(
- stringResource(R.string.turn_off),
- )
+ before = if (missingFilesPermission && !isSearchEmpty) {
+ {
+ MissingPermissionBanner(
+ modifier = Modifier.padding(8.dp),
+ text = stringResource(R.string.missing_permission_files_search),
+ onClick = { viewModel.requestFilesPermission(context as AppCompatActivity) },
+ secondaryAction = {
+ OutlinedButton(onClick = {
+ viewModel.disableFilesSearch()
+ }) {
+ Text(
+ stringResource(R.string.turn_off),
+ )
+ }
}
- }
- )
- }} else null,
+ )
+ }
+ } else null,
items = files.toImmutableList(),
reverse = reverse,
key = "files"
diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/favorites/FavoritesWidget.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/favorites/FavoritesWidget.kt
index b444cf32..9c492ff8 100644
--- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/favorites/FavoritesWidget.kt
+++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/favorites/FavoritesWidget.kt
@@ -1,14 +1,28 @@
package de.mm20.launcher2.ui.launcher.widgets.favorites
import androidx.compose.foundation.horizontalScroll
-import androidx.compose.foundation.layout.*
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Edit
import androidx.compose.material.icons.rounded.Star
import androidx.compose.material.icons.rounded.Tag
-import androidx.compose.material3.*
-import androidx.compose.runtime.*
+import androidx.compose.material3.FilterChip
+import androidx.compose.material3.FloatingActionButtonDefaults
+import androidx.compose.material3.Icon
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.SmallFloatingActionButton
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
@@ -25,6 +39,7 @@ fun FavoritesWidget() {
val pinnedTags by viewModel.pinnedTags.collectAsState(emptyList())
val selectedTag by viewModel.selectedTag.collectAsState(null)
var showEditFavoritesDialog by remember { mutableStateOf(false) }
+ val favoritesEditButton by viewModel.showEditButton.collectAsState(false)
Column {
if (favorites.isNotEmpty()) {
@@ -41,54 +56,59 @@ fun FavoritesWidget() {
color = MaterialTheme.colorScheme.outline
)
}
- Row(
- modifier = Modifier
- .fillMaxWidth()
- .padding(
- top = 4.dp,
- bottom = 8.dp,
- end = 8.dp
- ),
- horizontalArrangement = Arrangement.End,
- verticalAlignment = Alignment.CenterVertically,
- ) {
+ if (pinnedTags.isNotEmpty() || favoritesEditButton) {
Row(
modifier = Modifier
- .weight(1f)
- .horizontalScroll(rememberScrollState()),
+ .fillMaxWidth()
+ .padding(
+ top = 4.dp,
+ bottom = 8.dp,
+ end = if (favoritesEditButton) 8.dp else 0.dp
+ ),
+ horizontalArrangement = Arrangement.End,
+ verticalAlignment = Alignment.CenterVertically,
) {
- FilterChip(
- modifier = Modifier.padding(start = 16.dp),
- selected = selectedTag == null,
- onClick = { viewModel.selectTag(null) },
- leadingIcon = {
- Icon(
- imageVector = Icons.Rounded.Star,
- contentDescription = null
- )
- },
- label = { Text(stringResource(R.string.favorites)) }
- )
- for (tag in pinnedTags) {
+ Row(
+ modifier = Modifier
+ .weight(1f)
+ .horizontalScroll(rememberScrollState())
+ .padding(end = 12.dp),
+ ) {
FilterChip(
- modifier = Modifier.padding(start = 8.dp),
- selected = selectedTag == tag.tag,
- onClick = { viewModel.selectTag(tag.tag) },
+ modifier = Modifier.padding(start = 16.dp),
+ selected = selectedTag == null,
+ onClick = { viewModel.selectTag(null) },
leadingIcon = {
Icon(
- imageVector = Icons.Rounded.Tag,
+ imageVector = Icons.Rounded.Star,
contentDescription = null
)
},
- label = { Text(tag.label) }
+ label = { Text(stringResource(R.string.favorites)) }
)
+ for (tag in pinnedTags) {
+ FilterChip(
+ modifier = Modifier.padding(start = 8.dp),
+ selected = selectedTag == tag.tag,
+ onClick = { viewModel.selectTag(tag.tag) },
+ leadingIcon = {
+ Icon(
+ imageVector = Icons.Rounded.Tag,
+ contentDescription = null
+ )
+ },
+ label = { Text(tag.label) }
+ )
+ }
+ }
+ if (favoritesEditButton) {
+ SmallFloatingActionButton(
+ elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation(),
+ onClick = { showEditFavoritesDialog = true }
+ ) {
+ Icon(imageVector = Icons.Rounded.Edit, contentDescription = null)
+ }
}
- }
- SmallFloatingActionButton(
- elevation = FloatingActionButtonDefaults.bottomAppBarFabElevation(),
- onClick = { showEditFavoritesDialog = true }
- ) {
- Icon(imageVector = Icons.Rounded.Edit, contentDescription = null)
}
}
}
diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreen.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreen.kt
index be71e1f7..f6f0f852 100644
--- a/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreen.kt
+++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreen.kt
@@ -58,6 +58,19 @@ fun FavoritesSettingsScreen() {
)
}
}
+ item {
+ val editButton by viewModel.editButton.observeAsState()
+ PreferenceCategory {
+ SwitchPreference(
+ title = stringResource(R.string.preference_edit_button),
+ summary = stringResource(R.string.preference_favorites_edit_button_summary),
+ value = editButton == true,
+ onValueChanged = {
+ viewModel.setEditButton(it)
+ }
+ )
+ }
+ }
}
if (showEditSheet) {
diff --git a/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreenVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreenVM.kt
index daa95021..6800ca1f 100644
--- a/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreenVM.kt
+++ b/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreenVM.kt
@@ -39,4 +39,18 @@ class FavoritesSettingsScreenVM: ViewModel(), KoinComponent {
}
}
}
+
+ val editButton = dataStore.data.map { it.favorites.editButton }.asLiveData()
+ fun setEditButton(editButton: Boolean) {
+ viewModelScope.launch {
+ dataStore.updateData {
+ it.toBuilder()
+ .setFavorites(
+ it.favorites.toBuilder()
+ .setEditButton(editButton)
+ )
+ .build()
+ }
+ }
+ }
}
\ No newline at end of file