Add preference to hide widget edit button
This commit is contained in:
parent
9309cd4891
commit
fc6d1d382c
@ -622,6 +622,7 @@
|
||||
<string name="preference_favorites_frequently_used_summary">Show frequently used items in favorites</string>
|
||||
<string name="preference_edit_button">Edit button</string>
|
||||
<string name="preference_favorites_edit_button_summary">Show a button to rearrange the favorites</string>
|
||||
<string name="preference_widgets_edit_button_summary">Show a button to add, remove and rearrange widgets</string>
|
||||
<!-- Used in an info banner if a specific feature requires a Nextcloud account -->
|
||||
<string name="no_account_nextcloud">You haven\'t connected a Nextcloud account yet</string>
|
||||
<!-- Used in an info banner if a specific feature requires an Owncloud account -->
|
||||
|
||||
@ -155,6 +155,10 @@ fun createFactorySettings(context: Context): Settings {
|
||||
.setRadius(8)
|
||||
.setOpacity(1f)
|
||||
)
|
||||
.setWidgets(
|
||||
Settings.WidgetSettings.newBuilder()
|
||||
.setEditButton(true)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
|
||||
|
||||
@ -2,13 +2,18 @@ package de.mm20.launcher2.preferences.migrations
|
||||
|
||||
import de.mm20.launcher2.preferences.Settings
|
||||
|
||||
class Migration_9_10: VersionedMigration(9, 10) {
|
||||
class Migration_9_10 : VersionedMigration(9, 10) {
|
||||
override suspend fun applyMigrations(builder: Settings.Builder): Settings.Builder {
|
||||
return builder.setFavorites(
|
||||
builder.favorites.toBuilder()
|
||||
.setFrequentlyUsed(true)
|
||||
.setFrequentlyUsedRows(1)
|
||||
.setEditButton(true)
|
||||
)
|
||||
return builder
|
||||
.setFavorites(
|
||||
builder.favorites.toBuilder()
|
||||
.setFrequentlyUsed(true)
|
||||
.setFrequentlyUsedRows(1)
|
||||
.setEditButton(true)
|
||||
)
|
||||
.setWidgets(
|
||||
Settings.WidgetSettings.newBuilder()
|
||||
.setEditButton(true)
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -259,4 +259,9 @@ message Settings {
|
||||
bool enabled = 1;
|
||||
}
|
||||
AppShortcutSearchSettings app_shortcut_search = 25;
|
||||
|
||||
message WidgetSettings {
|
||||
bool edit_button = 1;
|
||||
}
|
||||
WidgetSettings widgets = 26;
|
||||
}
|
||||
@ -7,20 +7,37 @@ import android.content.Intent
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.graphics.ExperimentalAnimationGraphicsApi
|
||||
import androidx.compose.animation.graphics.res.animatedVectorResource
|
||||
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
|
||||
import androidx.compose.animation.graphics.vector.AnimatedImageVector
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.gestures.rememberDraggableState
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Add
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material3.ExtendedFloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.runtime.livedata.observeAsState
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.layout.onPlaced
|
||||
@ -35,10 +52,9 @@ import androidx.compose.ui.window.Dialog
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.ui.launcher.widgets.clock.ClockWidget
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.ktx.animateTo
|
||||
import de.mm20.launcher2.ui.ktx.conditional
|
||||
import de.mm20.launcher2.ui.launcher.widgets.clock.ClockWidget
|
||||
import de.mm20.launcher2.ui.launcher.widgets.picker.PickAppWidgetActivity
|
||||
import de.mm20.launcher2.widgets.ExternalWidget
|
||||
import kotlinx.coroutines.awaitCancellation
|
||||
@ -69,17 +85,18 @@ fun WidgetColumn(
|
||||
}
|
||||
}
|
||||
|
||||
val pickWidgetLauncher = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) {
|
||||
val data = it.data ?: return@rememberLauncherForActivityResult
|
||||
val widgetId = data.getIntExtra(
|
||||
AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID
|
||||
)
|
||||
if (widgetId == AppWidgetManager.INVALID_APPWIDGET_ID) return@rememberLauncherForActivityResult
|
||||
if (it.resultCode == Activity.RESULT_OK) {
|
||||
viewModel.addAppWidget(context, widgetId)
|
||||
val pickWidgetLauncher =
|
||||
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult()) {
|
||||
val data = it.data ?: return@rememberLauncherForActivityResult
|
||||
val widgetId = data.getIntExtra(
|
||||
AppWidgetManager.EXTRA_APPWIDGET_ID,
|
||||
AppWidgetManager.INVALID_APPWIDGET_ID
|
||||
)
|
||||
if (widgetId == AppWidgetManager.INVALID_APPWIDGET_ID) return@rememberLauncherForActivityResult
|
||||
if (it.resultCode == Activity.RESULT_OK) {
|
||||
viewModel.addAppWidget(context, widgetId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
@ -168,43 +185,47 @@ fun WidgetColumn(
|
||||
}
|
||||
}
|
||||
|
||||
val icon =
|
||||
AnimatedImageVector.animatedVectorResource(R.drawable.anim_ic_edit_add)
|
||||
ExtendedFloatingActionButton(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
.align(Alignment.CenterHorizontally),
|
||||
icon = {
|
||||
Icon(
|
||||
painter = rememberAnimatedVectorPainter(
|
||||
animatedImageVector = icon,
|
||||
atEnd = !editMode
|
||||
), contentDescription = null
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
stringResource(
|
||||
if (editMode) R.string.widget_add_widget
|
||||
else R.string.menu_edit_widgets
|
||||
val editButton by viewModel.editButton.observeAsState()
|
||||
if (editButton == true) {
|
||||
val icon =
|
||||
AnimatedImageVector.animatedVectorResource(R.drawable.anim_ic_edit_add)
|
||||
ExtendedFloatingActionButton(
|
||||
modifier = Modifier
|
||||
.padding(16.dp)
|
||||
.align(Alignment.CenterHorizontally),
|
||||
icon = {
|
||||
Icon(
|
||||
painter = rememberAnimatedVectorPainter(
|
||||
animatedImageVector = icon,
|
||||
atEnd = !editMode
|
||||
), contentDescription = null
|
||||
)
|
||||
)
|
||||
}, onClick = {
|
||||
if (!editMode) {
|
||||
onEditModeChange(true)
|
||||
} else {
|
||||
if (viewModel.getAvailableBuiltInWidgets().isEmpty()) {
|
||||
pickWidgetLauncher.launch(
|
||||
Intent(
|
||||
context,
|
||||
PickAppWidgetActivity::class.java
|
||||
)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
stringResource(
|
||||
if (editMode) R.string.widget_add_widget
|
||||
else R.string.menu_edit_widgets
|
||||
)
|
||||
)
|
||||
}, onClick = {
|
||||
if (!editMode) {
|
||||
onEditModeChange(true)
|
||||
} else {
|
||||
showAddDialog = true
|
||||
if (viewModel.getAvailableBuiltInWidgets().isEmpty()) {
|
||||
pickWidgetLauncher.launch(
|
||||
Intent(
|
||||
context,
|
||||
PickAppWidgetActivity::class.java
|
||||
)
|
||||
)
|
||||
} else {
|
||||
showAddDialog = true
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
if (showAddDialog) {
|
||||
val availableBuiltInWidgets =
|
||||
|
||||
@ -6,18 +6,24 @@ import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.liveData
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.widgets.ExternalWidget
|
||||
import de.mm20.launcher2.widgets.Widget
|
||||
import de.mm20.launcher2.widgets.WidgetRepository
|
||||
import de.mm20.launcher2.widgets.WidgetType
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class WidgetsVM : ViewModel(), KoinComponent {
|
||||
private val widgetRepository: WidgetRepository by inject()
|
||||
|
||||
private val dataStore: LauncherDataStore by inject()
|
||||
|
||||
val editButton = dataStore.data.map { it.widgets.editButton }.asLiveData()
|
||||
|
||||
val widgets = widgetRepository.getWidgets().asLiveData()
|
||||
|
||||
fun addWidget(widget: Widget) {
|
||||
|
||||
@ -2,16 +2,35 @@ package de.mm20.launcher2.ui.settings.widgets
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.widgets.WidgetRepository
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class WidgetSettingsScreenVM: ViewModel(), KoinComponent {
|
||||
class WidgetSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
|
||||
|
||||
private val widgetRepository: WidgetRepository by inject()
|
||||
private val dataStore: LauncherDataStore by inject()
|
||||
|
||||
val calendarWidget = widgetRepository.isCalendarWidgetEnabled().asLiveData()
|
||||
val musicWidget = widgetRepository.isMusicWidgetEnabled().asLiveData()
|
||||
val weatherWidget = widgetRepository.isWeatherWidgetEnabled().asLiveData()
|
||||
val favoritesWidget = widgetRepository.isFavoritesWidgetEnabled().asLiveData()
|
||||
val editButton = dataStore.data.map { it.widgets.editButton }.asLiveData()
|
||||
fun setEditButton(editButton: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setWidgets(
|
||||
it.widgets.toBuilder()
|
||||
.setEditButton(editButton)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -13,7 +13,9 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.preferences.Preference
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
|
||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
||||
|
||||
@Composable
|
||||
@ -22,56 +24,71 @@ fun WidgetsSettingsScreen() {
|
||||
val viewModel: WidgetSettingsScreenVM = viewModel()
|
||||
PreferenceScreen(title = stringResource(R.string.preference_screen_widgets)) {
|
||||
item {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_clockwidget),
|
||||
icon = Icons.Rounded.Schedule,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/clock")
|
||||
PreferenceCategory {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_clockwidget),
|
||||
icon = Icons.Rounded.Schedule,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/clock")
|
||||
}
|
||||
)
|
||||
|
||||
val weatherWidget by viewModel.weatherWidget.observeAsState()
|
||||
if (weatherWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_weatherwidget),
|
||||
icon = Icons.Rounded.LightMode,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/weather")
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
val weatherWidget by viewModel.weatherWidget.observeAsState()
|
||||
if (weatherWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_weatherwidget),
|
||||
icon = Icons.Rounded.LightMode,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/weather")
|
||||
}
|
||||
)
|
||||
val musicWidget by viewModel.musicWidget.observeAsState()
|
||||
if (musicWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_musicwidget),
|
||||
icon = Icons.Rounded.Audiotrack,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/music")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val calendarWidget by viewModel.calendarWidget.observeAsState()
|
||||
if (calendarWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_calendarwidget),
|
||||
icon = Icons.Rounded.Today,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/calendar")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val favoritesWidget by viewModel.favoritesWidget.observeAsState()
|
||||
if (favoritesWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.favorites),
|
||||
icon = Icons.Rounded.Star,
|
||||
onClick = {
|
||||
navController?.navigate("settings/favorites")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val musicWidget by viewModel.musicWidget.observeAsState()
|
||||
if (musicWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_musicwidget),
|
||||
icon = Icons.Rounded.Audiotrack,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/music")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val calendarWidget by viewModel.calendarWidget.observeAsState()
|
||||
if (calendarWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_calendarwidget),
|
||||
icon = Icons.Rounded.Today,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/calendar")
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
val favoritesWidget by viewModel.favoritesWidget.observeAsState()
|
||||
if (favoritesWidget == true) {
|
||||
Preference(
|
||||
title = stringResource(R.string.favorites),
|
||||
icon = Icons.Rounded.Star,
|
||||
onClick = {
|
||||
navController?.navigate("settings/favorites")
|
||||
}
|
||||
)
|
||||
item {
|
||||
PreferenceCategory {
|
||||
val editButton by viewModel.editButton.observeAsState()
|
||||
SwitchPreference(
|
||||
title = stringResource(id = R.string.preference_edit_button),
|
||||
summary = stringResource(id = R.string.preference_widgets_edit_button_summary),
|
||||
value = editButton == true,
|
||||
onValueChanged = {
|
||||
viewModel.setEditButton(it)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user