From d1482ad112608d3ec97e70865bdd464f212fe3e9 Mon Sep 17 00:00:00 2001
From: MM20 <15646950+MM2-0@users.noreply.github.com>
Date: Thu, 20 Apr 2023 21:40:29 +0200
Subject: [PATCH] Get rid of LiveData
---
app/ui/build.gradle.kts | 1 -
app/ui/src/main/AndroidManifest.xml | 13 --
.../ui/assistant/AssistantScaffold.kt | 5 +-
.../mm20/launcher2/ui/base/BaseActivityVM.kt | 27 ---
.../launcher2/ui/common/RestoreBackupSheet.kt | 13 +-
.../ui/common/RestoreBackupSheetVM.kt | 12 +-
.../ui/common/WeatherLocationSearchDialog.kt | 5 +-
.../common/WeatherLocationSearchDialogVM.kt | 8 +-
.../ui/launcher/LauncherScaffoldVM.kt | 46 +++--
.../launcher2/ui/launcher/PagerScaffold.kt | 29 +--
.../launcher2/ui/launcher/PullDownScaffold.kt | 15 +-
.../ui/launcher/SharedLauncherActivity.kt | 23 ++-
.../launcher/searchbar/LauncherSearchBar.kt | 1 -
.../sheets/CustomizeSearchableSheet.kt | 5 +-
.../sheets/CustomizeSearchableSheetVM.kt | 6 +-
.../ui/launcher/sheets/EditFavoritesSheet.kt | 13 +-
.../launcher/sheets/EditFavoritesSheetVM.kt | 16 +-
.../ui/launcher/sheets/WidgetPickerSheet.kt | 5 +-
.../ui/launcher/widgets/WidgetColumn.kt | 6 +-
.../ui/launcher/widgets/WidgetsVM.kt | 16 +-
.../widgets/calendar/CalendarWidget.kt | 14 +-
.../widgets/calendar/CalendarWidgetVM.kt | 30 ++--
.../ui/launcher/widgets/clock/ClockWidget.kt | 8 +-
.../launcher/widgets/clock/ClockWidgetVM.kt | 10 +-
.../widgets/clock/parts/AlarmPartProvider.kt | 7 +-
.../launcher/widgets/music/MusicWidgetVM.kt | 4 -
.../launcher/widgets/picker/AppWidgetList.kt | 118 ------------
.../widgets/picker/PickAppWidgetActivity.kt | 168 ------------------
.../widgets/picker/PickAppWidgetVM.kt | 45 -----
.../launcher/widgets/weather/WeatherWidget.kt | 13 +-
.../widgets/weather/WeatherWidgetVM.kt | 31 ++--
.../appearance/AppearanceSettingsScreen.kt | 64 +------
.../appearance/AppearanceSettingsScreenVM.kt | 23 +--
.../settings/backup/BackupSettingsScreen.kt | 7 +-
.../settings/backup/BackupSettingsScreenVM.kt | 6 +-
.../ui/settings/backup/CreateBackupSheet.kt | 5 +-
.../ui/settings/backup/CreateBackupSheetVM.kt | 6 +-
.../ui/settings/cards/CardsSettingsScreen.kt | 10 +-
.../settings/cards/CardsSettingsScreenVM.kt | 17 +-
.../clockwidget/ClockWidgetSettingsScreen.kt | 21 +--
.../ClockWidgetSettingsScreenVM.kt | 32 ++--
.../colorscheme/ColorSchemeSettingsScreen.kt | 4 +-
.../ColorSchemeSettingsScreenVM.kt | 9 +-
.../CustomColorSchemeSettingsScreen.kt | 9 +-
.../CustomColorSchemeSettingsScreenVM.kt | 16 +-
.../crashreporter/CrashReportScreen.kt | 5 +-
.../crashreporter/CrashReportScreenVM.kt | 4 +-
.../crashreporter/CrashReporterScreen.kt | 7 +-
.../crashreporter/CrashReporterScreenVM.kt | 8 +-
.../easteregg/EasterEggSettingsScreen.kt | 4 +-
.../easteregg/EasterEggSettingsScreenVM.kt | 6 +-
.../favorites/FavoritesSettingsScreen.kt | 10 +-
.../favorites/FavoritesSettingsScreenVM.kt | 15 +-
.../filesearch/FileSearchSettingsScreen.kt | 24 +--
.../filesearch/FileSearchSettingsScreenVM.kt | 34 ++--
.../gestures/GestureSettingsScreen.kt | 1 -
.../gestures/GestureSettingsScreenVM.kt | 8 +-
.../hiddenitems/HiddenItemsSettingsScreen.kt | 5 +-
.../HiddenItemsSettingsScreenVM.kt | 14 +-
.../homescreen/HomescreenSettingsScreen.kt | 4 +-
.../homescreen/HomescreenSettingsScreenVM.kt | 17 +-
.../IntegrationsSettingsScreenVM.kt | 1 -
.../ui/settings/license/LicenseScreen.kt | 4 +-
.../ui/settings/license/LicenseScreenVM.kt | 4 +-
.../media/MediaIntegrationSettingsScreen.kt | 1 -
.../settings/search/SearchSettingsScreen.kt | 1 -
.../settings/search/SearchSettingsScreenVM.kt | 32 ++--
.../SearchActionsSettingsScreen.kt | 10 +-
.../SearchActionsSettingsScreenVM.kt | 13 +-
.../UnitConverterSettingsScreen.kt | 11 +-
.../UnitConverterSettingsScreenVM.kt | 9 +-
.../WeatherIntegrationSettingsScreen.kt | 9 +-
.../WeatherIntegrationSettingsScreenVM.kt | 18 +-
.../wikipedia/WikipediaSettingsScreen.kt | 8 +-
.../wikipedia/WikipediaSettingsScreenVM.kt | 12 +-
.../de/mm20/launcher2/database/IconDao.kt | 3 -
settings.gradle.kts | 5 -
77 files changed, 433 insertions(+), 816 deletions(-)
delete mode 100644 app/ui/src/main/java/de/mm20/launcher2/ui/base/BaseActivityVM.kt
delete mode 100644 app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/AppWidgetList.kt
delete mode 100644 app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/PickAppWidgetActivity.kt
delete mode 100644 app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/PickAppWidgetVM.kt
diff --git a/app/ui/build.gradle.kts b/app/ui/build.gradle.kts
index c88c7893..c3d26e1f 100644
--- a/app/ui/build.gradle.kts
+++ b/app/ui/build.gradle.kts
@@ -68,7 +68,6 @@ dependencies {
implementation(libs.bundles.kotlin)
implementation(libs.androidx.compose.runtime)
- implementation(libs.androidx.compose.livedata)
implementation(libs.androidx.compose.foundation)
implementation(libs.androidx.compose.foundationlayout)
implementation(libs.androidx.compose.ui)
diff --git a/app/ui/src/main/AndroidManifest.xml b/app/ui/src/main/AndroidManifest.xml
index 58823eef..5d532173 100644
--- a/app/ui/src/main/AndroidManifest.xml
+++ b/app/ui/src/main/AndroidManifest.xml
@@ -58,19 +58,6 @@
android:value="de.mm20.launcher2.ui.launcher.SharedLauncherActivity" />
-
-
-
-
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/assistant/AssistantScaffold.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/assistant/AssistantScaffold.kt
index da485779..8770169a 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/assistant/AssistantScaffold.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/assistant/AssistantScaffold.kt
@@ -5,7 +5,6 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.*
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
@@ -178,8 +177,8 @@ fun AssistantScaffold(
val value by searchVM.searchQuery
- val searchBarColor by viewModel.searchBarColor.observeAsState(Settings.SearchBarSettings.SearchBarColors.Auto)
- val searchBarStyle by viewModel.searchBarStyle.observeAsState(Settings.SearchBarSettings.SearchBarStyle.Transparent)
+ val searchBarColor by viewModel.searchBarColor.collectAsState()
+ val searchBarStyle by viewModel.searchBarStyle.collectAsState()
val launchOnEnter by searchVM.launchOnEnter.collectAsState(false)
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/base/BaseActivityVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/base/BaseActivityVM.kt
deleted file mode 100644
index 794e0d2e..00000000
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/base/BaseActivityVM.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package de.mm20.launcher2.ui.base
-
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
-import de.mm20.launcher2.preferences.LauncherDataStore
-import de.mm20.launcher2.preferences.Settings
-import kotlinx.coroutines.flow.first
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.runBlocking
-import org.koin.core.component.KoinComponent
-import org.koin.core.component.inject
-
-class BaseActivityVM : ViewModel(), KoinComponent {
- private val dataStore: LauncherDataStore by inject()
-
- val theme = dataStore.data.map { it.appearance.theme }.asLiveData()
-
- fun getTheme(): Settings.AppearanceSettings.Theme = runBlocking {
- dataStore.data.map { it.appearance.theme }.first()
- }
-
- val colorScheme = dataStore.data.map { it.appearance.colorScheme }.asLiveData()
-
- fun getColorScheme(): Settings.AppearanceSettings.ColorScheme = runBlocking {
- dataStore.data.map { it.appearance.colorScheme }.first()
- }
-}
\ No newline at end of file
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/common/RestoreBackupSheet.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/common/RestoreBackupSheet.kt
index 579aa638..403a7095 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/common/RestoreBackupSheet.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/common/RestoreBackupSheet.kt
@@ -12,7 +12,6 @@ import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
@@ -38,9 +37,9 @@ fun RestoreBackupSheet(
viewModel.setInputUri(uri)
}
- val state by viewModel.state.observeAsState(RestoreBackupState.Parsing)
- val selectedComponents by viewModel.selectedComponents.observeAsState(emptySet())
- val compatibility by viewModel.compatibility.observeAsState(null)
+ val state by viewModel.state
+ val selectedComponents by viewModel.selectedComponents
+ val compatibility by viewModel.compatibility
BottomSheetDialog(
onDismissRequest = onDismissRequest,
@@ -103,7 +102,7 @@ fun RestoreBackupSheet(
)
}
RestoreBackupState.Ready -> {
- val metadata by viewModel.metadata.observeAsState(null)
+ val metadata by viewModel.metadata
if (metadata != null) {
Column {
@@ -153,9 +152,7 @@ fun RestoreBackupSheet(
style = MaterialTheme.typography.titleSmall,
modifier = Modifier.padding(top = 8.dp, bottom = 4.dp)
)
- val components by viewModel.availableComponents.observeAsState(
- emptyList()
- )
+ val components by viewModel.availableComponents
for (component in components) {
Row(
modifier = Modifier
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/common/RestoreBackupSheetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/common/RestoreBackupSheetVM.kt
index a029904c..f85b04ba 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/common/RestoreBackupSheetVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/common/RestoreBackupSheetVM.kt
@@ -1,7 +1,7 @@
package de.mm20.launcher2.ui.common
import android.net.Uri
-import androidx.lifecycle.MutableLiveData
+import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.backup.BackupCompatibility
@@ -18,12 +18,12 @@ class RestoreBackupSheetVM : ViewModel(), KoinComponent {
private var restoreUri: Uri? = null
- val state = MutableLiveData(RestoreBackupState.Parsing)
- val metadata = MutableLiveData(null)
- val compatibility = MutableLiveData(null)
- val selectedComponents = MutableLiveData(setOf())
+ val state = mutableStateOf(RestoreBackupState.Parsing)
+ val metadata = mutableStateOf(null)
+ val compatibility = mutableStateOf(null)
+ val selectedComponents = mutableStateOf(setOf())
- val availableComponents = MutableLiveData(emptyList())
+ val availableComponents = mutableStateOf(emptyList())
fun setInputUri(uri: Uri) {
restoreUri = uri
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/common/WeatherLocationSearchDialog.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/common/WeatherLocationSearchDialog.kt
index 6c94088f..d28902dc 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/common/WeatherLocationSearchDialog.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/common/WeatherLocationSearchDialog.kt
@@ -12,7 +12,6 @@ import androidx.compose.material.icons.rounded.Error
import androidx.compose.material.icons.rounded.Search
import androidx.compose.material3.*
import androidx.compose.runtime.*
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
@@ -29,8 +28,8 @@ fun WeatherLocationSearchDialog(
) {
val scope = rememberCoroutineScope()
val viewModel: WeatherLocationSearchDialogVM = viewModel()
- val isSearching by viewModel.isSearchingLocation.observeAsState(initial = false)
- val locations by viewModel.locationResults.observeAsState(emptyList())
+ val isSearching by viewModel.isSearchingLocation
+ val locations by viewModel.locationResults
BottomSheetDialog(
onDismissRequest = onDismissRequest,
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/common/WeatherLocationSearchDialogVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/common/WeatherLocationSearchDialogVM.kt
index 9a3bb5a3..01231557 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/common/WeatherLocationSearchDialogVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/common/WeatherLocationSearchDialogVM.kt
@@ -1,6 +1,6 @@
package de.mm20.launcher2.ui.common
-import androidx.lifecycle.MutableLiveData
+import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import de.mm20.launcher2.weather.WeatherLocation
import de.mm20.launcher2.weather.WeatherRepository
@@ -12,8 +12,8 @@ import kotlin.coroutines.coroutineContext
class WeatherLocationSearchDialogVM: ViewModel(), KoinComponent {
private val repository: WeatherRepository by inject()
- val isSearchingLocation = MutableLiveData(false)
- val locationResults = MutableLiveData>(emptyList())
+ val isSearchingLocation = mutableStateOf(false)
+ val locationResults = mutableStateOf>(emptyList())
private var debounceSearchJob: Job? = null
suspend fun searchLocation(query: String) {
@@ -34,7 +34,7 @@ class WeatherLocationSearchDialogVM: ViewModel(), KoinComponent {
}
fun setLocation(location: WeatherLocation) {
- locationResults.postValue(emptyList())
+ locationResults.value = emptyList()
repository.setAutoLocation(false)
repository.setLocation(location)
}
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt
index f7264756..cb4d68a7 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldVM.kt
@@ -6,9 +6,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.core.app.ActivityOptionsCompat
-import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.searchable.SearchableRepository
import de.mm20.launcher2.globalactions.GlobalActionsService
@@ -48,13 +46,17 @@ class LauncherScaffoldVM : ViewModel(), KoinComponent {
) { dim, theme, systemDarkMode ->
dim && (theme == Settings.AppearanceSettings.Theme.Dark || theme == Settings.AppearanceSettings.Theme.System && systemDarkMode)
}
- val dimBackground = dimBackgroundState.asLiveData()
+ val dimBackground = dimBackgroundState.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
- val statusBarColor = dataStore.data.map { it.systemBars.statusBarColor }.asLiveData()
- val navBarColor = dataStore.data.map { it.systemBars.statusBarColor }.asLiveData()
+ val statusBarColor = dataStore.data.map { it.systemBars.statusBarColor }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
+ val navBarColor = dataStore.data.map { it.systemBars.statusBarColor }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
- val hideNavBar = dataStore.data.map { it.systemBars.hideNavBar }.asLiveData()
- val hideStatusBar = dataStore.data.map { it.systemBars.hideStatusBar }.asLiveData()
+ val hideNavBar = dataStore.data.map { it.systemBars.hideNavBar }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
+ val hideStatusBar = dataStore.data.map { it.systemBars.hideStatusBar }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
fun setSystemInDarkMode(darkMode: Boolean) {
isSystemInDarkMode.value = darkMode
@@ -62,15 +64,19 @@ class LauncherScaffoldVM : ViewModel(), KoinComponent {
val baseLayout = dataStore.data.map { it.layout.baseLayout }
.stateIn(viewModelScope, SharingStarted.Eagerly, null)
- val bottomSearchBar = dataStore.data.map { it.layout.bottomSearchBar }.asLiveData()
- val reverseSearchResults = dataStore.data.map { it.layout.reverseSearchResults }.asLiveData()
- val fixedSearchBar = dataStore.data.map { it.layout.fixedSearchBar }.asLiveData()
- val fixedRotation = dataStore.data.map { it.layout.fixedRotation }.asLiveData()
+ val bottomSearchBar = dataStore.data.map { it.layout.bottomSearchBar }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
+ val reverseSearchResults = dataStore.data.map { it.layout.reverseSearchResults }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
+ val fixedSearchBar = dataStore.data.map { it.layout.fixedSearchBar }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
+ val fixedRotation = dataStore.data.map { it.layout.fixedRotation }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
- val isSearchOpen = MutableLiveData(false)
- val isWidgetEditMode = MutableLiveData(false)
+ val isSearchOpen = mutableStateOf(false)
+ val isWidgetEditMode = mutableStateOf(false)
- val searchBarFocused = MutableLiveData(false)
+ val searchBarFocused = mutableStateOf(false)
val autoFocusSearch = dataStore.data.map { it.searchBar.autoFocus }
@@ -103,10 +109,14 @@ class LauncherScaffoldVM : ViewModel(), KoinComponent {
isWidgetEditMode.value = editMode
}
- val wallpaperBlur = dataStore.data.map { it.appearance.blurWallpaper }.asLiveData()
- val fillClockHeight = dataStore.data.map { it.clockWidget.fillHeight }.asLiveData()
- val searchBarColor = dataStore.data.map { it.searchBar.color }.asLiveData()
- val searchBarStyle = dataStore.data.map { it.searchBar.searchBarStyle }.asLiveData()
+ val wallpaperBlur = dataStore.data.map { it.appearance.blurWallpaper }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), true)
+ val fillClockHeight = dataStore.data.map { it.clockWidget.fillHeight }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), true)
+ val searchBarColor = dataStore.data.map { it.searchBar.color }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), Settings.SearchBarSettings.SearchBarColors.Auto)
+ val searchBarStyle = dataStore.data.map { it.searchBar.searchBarStyle }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), Settings.SearchBarSettings.SearchBarStyle.Transparent)
val gestureState: StateFlow = dataStore
.data.map { it.gestures }
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt
index 17731b4e..c631cc75 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PagerScaffold.kt
@@ -46,7 +46,6 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
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.rememberCoroutineScope
@@ -101,8 +100,8 @@ fun PagerScaffold(
val context = LocalContext.current
- val isSearchOpen by viewModel.isSearchOpen.observeAsState(false)
- val isWidgetEditMode by viewModel.isWidgetEditMode.observeAsState(false)
+ val isSearchOpen by viewModel.isSearchOpen
+ val isWidgetEditMode by viewModel.isWidgetEditMode
val actions by searchVM.searchActionResults
@@ -147,7 +146,7 @@ fun PagerScaffold(
}
}
- val fillClockHeight by viewModel.fillClockHeight.observeAsState(true)
+ val fillClockHeight by viewModel.fillClockHeight.collectAsState()
val showNavBarScrim by remember {
derivedStateOf {
@@ -199,7 +198,7 @@ fun PagerScaffold(
}
}
- val blurEnabled by viewModel.wallpaperBlur.observeAsState(false)
+ val blurEnabled by viewModel.wallpaperBlur.collectAsState()
val blurWallpaper by remember {
derivedStateOf {
@@ -369,11 +368,17 @@ fun PagerScaffold(
.fillMaxHeight()
.pointerInput(gestureManager.shouldDetectDoubleTaps) {
detectTapGestures(
- onDoubleTap = if (gestureManager.shouldDetectDoubleTaps) {{
- if (!isWidgetEditMode) gestureManager.dispatchDoubleTap(it)
- }} else null,
+ onDoubleTap = if (gestureManager.shouldDetectDoubleTaps) {
+ {
+ if (!isWidgetEditMode) gestureManager.dispatchDoubleTap(
+ it
+ )
+ }
+ } else null,
onLongPress = {
- if (!isWidgetEditMode) gestureManager.dispatchLongPress(it)
+ if (!isWidgetEditMode) gestureManager.dispatchLongPress(
+ it
+ )
},
onTap = {
if (!isWidgetEditMode) gestureManager.dispatchTap(it)
@@ -491,7 +496,7 @@ fun PagerScaffold(
}
}
- val focusSearchBar by viewModel.searchBarFocused.observeAsState(false)
+ val focusSearchBar by viewModel.searchBarFocused
val widgetEditModeOffset by animateDpAsState(
(if (isWidgetEditMode) 128.dp else 0.dp) * (if (bottomSearchBar) 1 else -1)
@@ -499,8 +504,8 @@ fun PagerScaffold(
val value by searchVM.searchQuery
- val searchBarColor by viewModel.searchBarColor.observeAsState(SearchBarColors.Auto)
- val searchBarStyle by viewModel.searchBarStyle.observeAsState(SearchBarStyle.Transparent)
+ val searchBarColor by viewModel.searchBarColor.collectAsState()
+ val searchBarStyle by viewModel.searchBarStyle.collectAsState()
val launchOnEnter by searchVM.launchOnEnter.collectAsState(false)
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt
index c68e7778..57251740 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/PullDownScaffold.kt
@@ -43,7 +43,6 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
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.rememberCoroutineScope
@@ -100,8 +99,8 @@ fun PullDownScaffold(
val actions by searchVM.searchActionResults
- val isSearchOpen by viewModel.isSearchOpen.observeAsState(false)
- val isWidgetEditMode by viewModel.isWidgetEditMode.observeAsState(false)
+ val isSearchOpen by viewModel.isSearchOpen
+ val isWidgetEditMode by viewModel.isWidgetEditMode
val widgetsScrollState = rememberScrollState()
val searchState = rememberLazyListState()
@@ -148,7 +147,7 @@ fun PullDownScaffold(
}
}
- val fillClockHeight by viewModel.fillClockHeight.observeAsState(true)
+ val fillClockHeight by viewModel.fillClockHeight.collectAsState()
val showStatusBarScrim by remember {
derivedStateOf {
@@ -210,7 +209,7 @@ fun PullDownScaffold(
val maxSearchBarOffset = with(density) { 128.dp.toPx() }
- val blurEnabled by viewModel.wallpaperBlur.observeAsState(false)
+ val blurEnabled by viewModel.wallpaperBlur.collectAsState()
val blurWallpaper by remember {
derivedStateOf {
@@ -516,15 +515,15 @@ fun PullDownScaffold(
}
}
}
- val searchBarFocused by viewModel.searchBarFocused.observeAsState(false)
+ val searchBarFocused by viewModel.searchBarFocused
val editModeSearchBarOffset by animateDpAsState(
(if (isWidgetEditMode) 128.dp else 0.dp) * (if (bottomSearchBar) 1 else -1)
)
val value by searchVM.searchQuery
- val searchBarColor by viewModel.searchBarColor.observeAsState(Settings.SearchBarSettings.SearchBarColors.Auto)
- val searchBarStyle by viewModel.searchBarStyle.observeAsState(Settings.SearchBarSettings.SearchBarStyle.Transparent)
+ val searchBarColor by viewModel.searchBarColor.collectAsState()
+ val searchBarStyle by viewModel.searchBarStyle.collectAsState()
val context = LocalContext.current
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt
index 05bbeff3..0163936c 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/SharedLauncherActivity.kt
@@ -19,7 +19,6 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
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.setValue
@@ -90,7 +89,7 @@ abstract class SharedLauncherActivity(
setContent {
val snackbarHostState = remember { SnackbarHostState() }
val wallpaperColors by wallpaperColorsAsState()
- val dimBackground by viewModel.dimBackground.observeAsState(false)
+ val dimBackground by viewModel.dimBackground.collectAsState()
CompositionLocalProvider(
LocalEnterHomeTransitionManager provides enterHomeTransitionManager,
LocalWindowSize provides windowSize,
@@ -103,24 +102,24 @@ abstract class SharedLauncherActivity(
LauncherTheme {
ProvideCurrentTime {
ProvideSettings {
- val statusBarColor by viewModel.statusBarColor.observeAsState(
- SystemBarColors.Auto
- )
- val navBarColor by viewModel.navBarColor.observeAsState(SystemBarColors.Auto)
+ val statusBarColor by viewModel.statusBarColor.collectAsState()
+ val navBarColor by viewModel.navBarColor.collectAsState()
val lightStatus =
!dimBackground && (statusBarColor == SystemBarColors.Dark || statusBarColor == SystemBarColors.Auto && wallpaperColors.supportsDarkText)
val lightNav =
!dimBackground && (navBarColor == SystemBarColors.Dark || navBarColor == SystemBarColors.Auto && wallpaperColors.supportsDarkText)
- val hideStatus by viewModel.hideStatusBar.observeAsState(false)
- val hideNav by viewModel.hideNavBar.observeAsState(false)
+ val hideStatus by viewModel.hideStatusBar.collectAsState()
+ val hideNav by viewModel.hideNavBar.collectAsState()
val layout by viewModel.baseLayout.collectAsState(null)
- val bottomSearchBar by viewModel.bottomSearchBar.observeAsState(false)
- val reverseSearchResults by viewModel.reverseSearchResults.observeAsState(false)
- val fixedSearchBar by viewModel.fixedSearchBar.observeAsState(false)
+ val bottomSearchBar by viewModel.bottomSearchBar.collectAsState()
+ val reverseSearchResults by viewModel.reverseSearchResults.collectAsState()
+ val fixedSearchBar by viewModel.fixedSearchBar.collectAsState()
- viewModel.fixedRotation.observe(this) { fixedRotation ->
+ val fixedRotation by viewModel.fixedRotation.collectAsState()
+
+ LaunchedEffect(fixedRotation) {
requestedOrientation = if (fixedRotation) {
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
} else {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/LauncherSearchBar.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/LauncherSearchBar.kt
index ecc3a729..2337a325 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/LauncherSearchBar.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/searchbar/LauncherSearchBar.kt
@@ -13,7 +13,6 @@ import androidx.compose.material3.IconButtonDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheet.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheet.kt
index 150c4873..585ed6ec 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheet.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheet.kt
@@ -31,7 +31,6 @@ import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
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.rememberCoroutineScope
@@ -180,11 +179,11 @@ fun CustomizeSearchableSheet(
val scope = rememberCoroutineScope()
val suggestions by remember { viewModel.getIconSuggestions(iconSizePx.toInt()) }
- .observeAsState(emptyList())
+ .collectAsState(emptyList())
val defaultIcon by remember {
viewModel.getDefaultIcon(iconSizePx.toInt())
- }.observeAsState()
+ }.collectAsState(null)
var query by remember { mutableStateOf("") }
var filterIconPack by remember { mutableStateOf(null) }
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheetVM.kt
index 0895cf6f..2e9d0c52 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheetVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/CustomizeSearchableSheetVM.kt
@@ -1,7 +1,6 @@
package de.mm20.launcher2.ui.launcher.sheets
import androidx.compose.runtime.mutableStateOf
-import androidx.lifecycle.liveData
import de.mm20.launcher2.data.customattrs.CustomAttributesRepository
import de.mm20.launcher2.data.customattrs.CustomIcon
import de.mm20.launcher2.icons.CustomIconWithPreview
@@ -14,6 +13,7 @@ import kotlinx.coroutines.cancelAndJoin
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.koin.core.component.KoinComponent
@@ -32,7 +32,7 @@ class CustomizeSearchableSheetVM(
return iconService.getIcon(searchable, size)
}
- fun getIconSuggestions(size: Int) = liveData {
+ fun getIconSuggestions(size: Int) = flow {
emit(iconService.getCustomIconSuggestions(searchable, size))
}
@@ -49,7 +49,7 @@ class CustomizeSearchableSheetVM(
closeIconPicker()
}
- fun getDefaultIcon(size: Int) = liveData {
+ fun getDefaultIcon(size: Int) = flow {
emit(iconService.getUncustomizedDefaultIcon(searchable, size))
}
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/EditFavoritesSheet.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/EditFavoritesSheet.kt
index 75ef65c5..871ceb5b 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/EditFavoritesSheet.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/EditFavoritesSheet.kt
@@ -51,7 +51,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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
@@ -102,8 +101,8 @@ fun EditFavoritesSheet(
viewModel.reload()
}
- val loading by viewModel.loading.observeAsState(true)
- val createShortcutTarget by viewModel.createShortcutTarget.observeAsState(null)
+ val loading by viewModel.loading
+ val createShortcutTarget by viewModel.createShortcutTarget
BottomSheetDialog(
onDismissRequest = onDismiss,
@@ -157,7 +156,7 @@ fun EditFavoritesSheet(
@Composable
fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM, paddingValues: PaddingValues) {
- val items by viewModel.gridItems.observeAsState(emptyList())
+ val items by viewModel.gridItems
val columns = LocalGridSettings.current.columnCount
val availableTags by viewModel.availableTags
@@ -336,10 +335,8 @@ fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM, paddingValues: Padding
}
}
}
- val enableFrequentlyUsed by viewModel.enableFrequentlyUsed.observeAsState(
- null
- )
- val frequentlyUsedRows by viewModel.frequentlyUsedRows.observeAsState(1)
+ val enableFrequentlyUsed by viewModel.enableFrequentlyUsed.collectAsState()
+ val frequentlyUsedRows by viewModel.frequentlyUsedRows.collectAsState()
AnimatedVisibility(showSettings) {
Surface(
modifier = Modifier
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/EditFavoritesSheetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/EditFavoritesSheetVM.kt
index bffda3fc..0a9f4182 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/EditFavoritesSheetVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/EditFavoritesSheetVM.kt
@@ -6,9 +6,7 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.lazy.LazyListItemInfo
import androidx.compose.foundation.lazy.grid.LazyGridItemInfo
import androidx.compose.runtime.mutableStateOf
-import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.appshortcuts.AppShortcutRepository
import de.mm20.launcher2.badges.Badge
@@ -26,9 +24,11 @@ import de.mm20.launcher2.search.Searchable
import de.mm20.launcher2.search.data.Tag
import de.mm20.launcher2.services.favorites.FavoritesService
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -43,11 +43,11 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent {
private val permissionsManager: PermissionsManager by inject()
private val dataStore: LauncherDataStore by inject()
- val gridItems = MutableLiveData>(emptyList())
+ val gridItems = mutableStateOf>(emptyList())
- val loading = MutableLiveData(false)
+ val loading = mutableStateOf(false)
- val createShortcutTarget = MutableLiveData(null)
+ val createShortcutTarget = mutableStateOf(null)
private var manuallySorted: MutableList = mutableListOf()
private var automaticallySorted: MutableList = mutableListOf()
@@ -245,7 +245,8 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent {
}
}
- val enableFrequentlyUsed = dataStore.data.map { it.favorites.frequentlyUsed }.asLiveData()
+ val enableFrequentlyUsed = dataStore.data.map { it.favorites.frequentlyUsed }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setFrequentlyUsed(frequentlyUsed: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -260,7 +261,8 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent {
}
}
- val frequentlyUsedRows = dataStore.data.map { it.favorites.frequentlyUsedRows }.asLiveData()
+ val frequentlyUsedRows = dataStore.data.map { it.favorites.frequentlyUsedRows }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), 0)
fun setFrequentlyUsedRows(frequentlyUsedRows: Int) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/WidgetPickerSheet.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/WidgetPickerSheet.kt
index 91eb8068..aaf82423 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/WidgetPickerSheet.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/sheets/WidgetPickerSheet.kt
@@ -59,7 +59,6 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.AsyncImage
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.BottomSheetDialog
-import de.mm20.launcher2.ui.launcher.widgets.picker.PickAppWidgetActivity
import de.mm20.launcher2.widgets.CalendarWidget
import de.mm20.launcher2.widgets.AppWidget
import de.mm20.launcher2.widgets.AppWidgetConfig
@@ -111,7 +110,7 @@ class BindAndConfigureAppWidgetActivity : Activity() {
AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE,
appWidgetProviderInfo.profile
)
- }, PickAppWidgetActivity.RequestCodeBind
+ }, RequestCodeBind
)
}
}
@@ -122,7 +121,7 @@ class BindAndConfigureAppWidgetActivity : Activity() {
this,
appWidgetId,
0,
- PickAppWidgetActivity.RequestCodeConfigure,
+ RequestCodeConfigure,
null
)
} else {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt
index 29442760..995107a8 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt
@@ -18,9 +18,9 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
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
@@ -77,7 +77,7 @@ fun WidgetColumn(
) {
val scope = rememberCoroutineScope()
Column {
- val widgets by viewModel.widgets.observeAsState(emptyList())
+ val widgets by viewModel.widgets.collectAsState()
val swapThresholds = remember(widgets) {
Array(widgets.size) { floatArrayOf(0f, 0f) }
}
@@ -144,7 +144,7 @@ fun WidgetColumn(
}
}
- val editButton by viewModel.editButton.observeAsState()
+ val editButton by viewModel.editButton.collectAsState()
if (editButton == true) {
val icon =
AnimatedImageVector.animatedVectorResource(R.drawable.anim_ic_edit_add)
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetsVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetsVM.kt
index 31d21061..06ef81e5 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetsVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetsVM.kt
@@ -2,11 +2,13 @@ package de.mm20.launcher2.ui.launcher.widgets
import android.util.Log
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
+import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.widgets.Widget
import de.mm20.launcher2.widgets.WidgetRepository
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -15,12 +17,14 @@ class WidgetsVM : ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject()
- val editButton = dataStore.data.map { it.widgets.editButton }.asLiveData()
+ val editButton = dataStore.data.map { it.widgets.editButton }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
- val widgets = widgetRepository.get().asLiveData()
+ val widgets = widgetRepository.get()
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
fun addWidget(widget: Widget) {
- val widgets = widgets.value?.toMutableList() ?: return
+ val widgets = widgets.value.toMutableList()
widgets.add(widget)
widgetRepository.set(widgets)
}
@@ -34,14 +38,14 @@ class WidgetsVM : ViewModel(), KoinComponent {
}
fun moveUp(index: Int) {
- val widgets = widgets.value?.toMutableList() ?: return
+ val widgets = widgets.value.toMutableList()
val widget = widgets.removeAt(index)
widgets.add(index - 1, widget)
widgetRepository.set(widgets)
}
fun moveDown(index: Int) {
- val widgets = widgets.value?.toMutableList() ?: return
+ val widgets = widgets.value.toMutableList()
val widget = widgets.removeAt(index)
widgets.add(index + 1, widget)
widgetRepository.set(widgets)
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/calendar/CalendarWidget.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/calendar/CalendarWidget.kt
index 7b62fb06..e0ae7b81 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/calendar/CalendarWidget.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/calendar/CalendarWidget.kt
@@ -10,9 +10,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
-import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
@@ -61,7 +59,7 @@ fun CalendarWidget(
modifier = Modifier.weight(1f),
contentAlignment = Alignment.Center
) {
- val selectedDate by viewModel.selectedDate.observeAsState(LocalDate.now())
+ val selectedDate by viewModel.selectedDate
var showDropdown by remember { mutableStateOf(false) }
TextButton(onClick = { showDropdown = true }) {
Text(
@@ -99,8 +97,8 @@ fun CalendarWidget(
Icon(imageVector = Icons.Rounded.OpenInNew, contentDescription = null)
}
}
- val events by viewModel.calendarEvents.observeAsState(emptyList())
- val hasPermission by viewModel.hasPermission.observeAsState()
+ val events by viewModel.calendarEvents
+ val hasPermission by viewModel.hasPermission.collectAsState()
Column(
modifier = Modifier
.animateContentSize()
@@ -124,7 +122,7 @@ fun CalendarWidget(
modifier = Modifier
.fillMaxWidth()
)
- val runningEvents by viewModel.hiddenPastEvents.observeAsState(0)
+ val runningEvents by viewModel.hiddenPastEvents
if (runningEvents > 0) {
Info(
text = pluralStringResource(
@@ -137,7 +135,7 @@ fun CalendarWidget(
}
)
}
- val nextEvents by viewModel.nextEvents.observeAsState(emptyList())
+ val nextEvents by viewModel.nextEvents
if (nextEvents.isNotEmpty()) {
Text(
stringResource(R.string.calendar_widget_next_events),
@@ -150,7 +148,7 @@ fun CalendarWidget(
.fillMaxWidth()
)
}
- val pinnedEvents by viewModel.pinnedCalendarEvents.observeAsState(emptyList())
+ val pinnedEvents by viewModel.pinnedCalendarEvents.collectAsState()
if (pinnedEvents.isNotEmpty()) {
Text(
stringResource(R.string.calendar_widget_pinned_events),
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/calendar/CalendarWidgetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/calendar/CalendarWidgetVM.kt
index 496255ae..7d786273 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/calendar/CalendarWidgetVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/calendar/CalendarWidgetVM.kt
@@ -5,23 +5,22 @@ import android.content.Context
import android.content.Intent
import android.provider.CalendarContract
import androidx.appcompat.app.AppCompatActivity
-import androidx.lifecycle.MutableLiveData
+import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.calendar.CalendarRepository
import de.mm20.launcher2.searchable.SearchableRepository
import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager
-import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.search.data.CalendarEvent
import de.mm20.launcher2.services.favorites.FavoritesService
import de.mm20.launcher2.widgets.CalendarWidget
import de.mm20.launcher2.widgets.CalendarWidgetConfig
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.collectLatest
-import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
import java.lang.Integer.min
@@ -39,23 +38,24 @@ class CalendarWidgetVM : ViewModel(), KoinComponent {
private val widgetConfig = MutableStateFlow(CalendarWidgetConfig())
- val calendarEvents = MutableLiveData>(emptyList())
+ val calendarEvents = mutableStateOf>(emptyList())
val pinnedCalendarEvents =
favoritesService.getFavorites(
includeTypes = listOf(CalendarEvent.Domain),
automaticallySorted = true,
manuallySorted = true,
- ).asLiveData(viewModelScope.coroutineContext)
- val nextEvents = MutableLiveData>(emptyList())
+ ).stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
+ val nextEvents = mutableStateOf>(emptyList())
var availableDates = listOf(LocalDate.now())
private val permissionsManager: PermissionsManager by inject()
- val hasPermission = permissionsManager.hasPermission(PermissionGroup.Calendar).asLiveData()
+ val hasPermission = permissionsManager.hasPermission(PermissionGroup.Calendar)
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
private var showRunningPastDayEvents = false
- val hiddenPastEvents = MutableLiveData(0)
+ val hiddenPastEvents = mutableStateOf(0)
- val selectedDate = MutableLiveData(LocalDate.now())
+ val selectedDate = mutableStateOf(LocalDate.now())
fun updateWidget(widget: CalendarWidget) {
widgetConfig.value = widget.config
@@ -147,17 +147,17 @@ class CalendarWidgetVM : ViewModel(), KoinComponent {
}
val hiddenCount = totalCount - events.size
- hiddenPastEvents.postValue(hiddenCount)
+ hiddenPastEvents.value = hiddenCount
} else {
- hiddenPastEvents.postValue(0)
+ hiddenPastEvents.value = 0
}
- calendarEvents.postValue(events)
+ calendarEvents.value = events
val e = this.upcomingEvents
if (events.isEmpty() && e.isNotEmpty()) {
- nextEvents.postValue(listOf(e[0]))
+ nextEvents.value = listOf(e[0])
} else {
- nextEvents.postValue(emptyList())
+ nextEvents.value = emptyList()
}
}
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt
index 495d966c..f0fde621 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidget.kt
@@ -16,8 +16,8 @@ import androidx.compose.material3.LocalContentColor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -44,9 +44,9 @@ fun ClockWidget(
) {
val viewModel: ClockWidgetVM = viewModel()
val context = LocalContext.current
- val layout by viewModel.layout.observeAsState()
- val clockStyle by viewModel.clockStyle.observeAsState()
- val color by viewModel.color.observeAsState()
+ val layout by viewModel.layout.collectAsState()
+ val clockStyle by viewModel.clockStyle.collectAsState()
+ val color by viewModel.color.collectAsState()
val time = LocalTime.current
LaunchedEffect(time) {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt
index 5b2babc7..8aeb394d 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/ClockWidgetVM.kt
@@ -4,7 +4,6 @@ import android.content.Context
import android.content.Intent
import android.provider.AlarmClock
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.preferences.LauncherDataStore
@@ -55,10 +54,13 @@ class ClockWidgetVM : ViewModel(), KoinComponent {
}
}
- val layout = dataStore.data.map { it.clockWidget.layout }.asLiveData()
- val clockStyle = dataStore.data.map { it.clockWidget.clockStyle }.asLiveData()
+ val layout = dataStore.data.map { it.clockWidget.layout }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
+ val clockStyle = dataStore.data.map { it.clockWidget.clockStyle }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
- val color = dataStore.data.map { it.clockWidget.color }.asLiveData()
+ val color = dataStore.data.map { it.clockWidget.color }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun updateTime(time: Long) {
partProviders.value.forEach { it.setTime(time) }
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/AlarmPartProvider.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/AlarmPartProvider.kt
index 6df1addd..e224d55c 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/AlarmPartProvider.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/clock/parts/AlarmPartProvider.kt
@@ -15,12 +15,11 @@ import androidx.compose.material3.*
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.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.core.content.getSystemService
-import androidx.lifecycle.MutableLiveData
import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout
import kotlinx.coroutines.channels.awaitClose
@@ -29,7 +28,7 @@ import kotlinx.coroutines.flow.*
class AlarmPartProvider : PartProvider {
- private val nextAlarmTime = MutableLiveData(null)
+ private val nextAlarmTime = mutableStateOf(null)
private val time = MutableStateFlow(System.currentTimeMillis())
@@ -75,7 +74,7 @@ class AlarmPartProvider : PartProvider {
override fun Component(layout: ClockWidgetLayout) {
val context = LocalContext.current
- val alarmTime by nextAlarmTime.observeAsState(null)
+ val alarmTime by nextAlarmTime
val time by this.time.collectAsState(System.currentTimeMillis())
alarmTime?.let {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidgetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidgetVM.kt
index f13b6c0d..3c5f7572 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidgetVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/music/MusicWidgetVM.kt
@@ -5,10 +5,7 @@ import android.content.Context
import android.graphics.Bitmap
import android.media.session.PlaybackState.CustomAction
import androidx.appcompat.app.AppCompatActivity
-import androidx.compose.ui.graphics.Color
-import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import de.mm20.launcher2.crashreporter.CrashReporter
import de.mm20.launcher2.music.MusicService
import de.mm20.launcher2.music.PlaybackState
@@ -16,7 +13,6 @@ import de.mm20.launcher2.music.SupportedActions
import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.map
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/AppWidgetList.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/AppWidgetList.kt
deleted file mode 100644
index 0b5969a8..00000000
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/AppWidgetList.kt
+++ /dev/null
@@ -1,118 +0,0 @@
-package de.mm20.launcher2.ui.launcher.widgets.picker
-
-import android.appwidget.AppWidgetProviderInfo
-import android.graphics.drawable.Drawable
-import androidx.compose.foundation.Canvas
-import androidx.compose.foundation.clickable
-import androidx.compose.foundation.layout.*
-import androidx.compose.foundation.lazy.LazyColumn
-import androidx.compose.foundation.lazy.items
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.Text
-import androidx.compose.runtime.Composable
-import androidx.compose.runtime.remember
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
-import androidx.compose.ui.graphics.nativeCanvas
-import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalDensity
-import androidx.compose.ui.unit.dp
-import de.mm20.launcher2.ktx.isAtLeastApiLevel
-import de.mm20.launcher2.ui.component.LauncherCard
-import de.mm20.launcher2.ui.ktx.toDp
-
-@Composable
-fun AppWidgetList(
- modifier: Modifier = Modifier,
- widgets: List,
- onWidgetSelected: (AppWidgetProviderInfo) -> Unit = {}
-) {
- val context = LocalContext.current
- val density = (LocalDensity.current.density * 160).toInt()
- LazyColumn(
- modifier = modifier
- ) {
- for (group in widgets) {
- item {
- Text(
- modifier = Modifier.padding(
- top = 16.dp,
- start = 8.dp,
- end = 8.dp,
- bottom = 8.dp
- ),
- text = group.appName,
- style = MaterialTheme.typography.titleLarge
- )
- }
- items(group.widgets) {
- LauncherCard(
- modifier = Modifier
- .padding(8.dp)
- .fillMaxWidth()
- ) {
- Column(
- modifier = Modifier
- .clickable {
- onWidgetSelected(it)
- }
- .padding(16.dp),
- ) {
- val label = remember { it.loadLabel(context.packageManager) }
- Text(text = label, style = MaterialTheme.typography.titleMedium)
- Box(
- modifier = Modifier
- .fillMaxWidth()
- .padding(vertical = 16.dp)
- ) {
-
- val image: Drawable? = remember {
- it.loadPreviewImage(context, density) ?: it.loadIcon(
- context,
- density
- )
- }
-
- if (image != null) {
-
- val mod =
- if (image.intrinsicWidth > 0 && image.intrinsicHeight > 0) {
- Modifier
- .heightIn(max = image.intrinsicHeight.toDp())
- .widthIn(max = image.intrinsicWidth.toDp())
- .aspectRatio(
- image.intrinsicWidth.toFloat() / image.intrinsicHeight.toFloat(),
- matchHeightConstraintsFirst = true
- )
- } else {
- Modifier.size(64.dp)
- }
-
- Canvas(
- modifier = mod
- ) {
- drawIntoCanvas {
- image.setBounds(
- 0,
- 0,
- size.width.toInt(),
- size.height.toInt(),
- )
- image.draw(it.nativeCanvas)
- }
- }
- }
- }
- if (isAtLeastApiLevel(31)) {
- val description = remember { it.loadDescription(context)?.toString() }
- if (description != null) {
- Text(text = description, style = MaterialTheme.typography.bodySmall)
- }
- }
- }
- }
- }
- }
-
- }
-}
\ No newline at end of file
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/PickAppWidgetActivity.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/PickAppWidgetActivity.kt
deleted file mode 100644
index 2e25e8f1..00000000
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/PickAppWidgetActivity.kt
+++ /dev/null
@@ -1,168 +0,0 @@
-package de.mm20.launcher2.ui.launcher.widgets.picker
-
-import android.appwidget.AppWidgetHost
-import android.appwidget.AppWidgetManager
-import android.appwidget.AppWidgetProviderInfo
-import android.content.Intent
-import android.os.Bundle
-import android.util.Log
-import androidx.activity.compose.setContent
-import androidx.activity.viewModels
-import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.fillMaxSize
-import androidx.compose.foundation.layout.padding
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.rounded.ArrowBack
-import androidx.compose.material3.*
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
-import androidx.compose.ui.Alignment
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
-import de.mm20.launcher2.ui.R
-import de.mm20.launcher2.ui.base.BaseActivity
-import de.mm20.launcher2.ui.base.ProvideSettings
-import de.mm20.launcher2.ui.theme.LauncherTheme
-
-class PickAppWidgetActivity : BaseActivity() {
-
- private val viewModel by viewModels()
-
- private lateinit var widgetHost: AppWidgetHost
- private lateinit var appWidgetManager: AppWidgetManager
-
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- widgetHost = AppWidgetHost(this, 44203)
- appWidgetManager = AppWidgetManager.getInstance(this)
-
- val availableWidgets = viewModel.getAvailableWidgets(this)
- setContent {
- LauncherTheme {
- ProvideSettings {
- Scaffold(
- topBar = {
- CenterAlignedTopAppBar(
- title = {
- Text(stringResource(R.string.widget_add_widget))
- },
- navigationIcon = {
- IconButton(onClick = { finish() }) {
- Icon(
- imageVector = Icons.Rounded.ArrowBack,
- contentDescription = stringResource(
- id = R.string.menu_back
- )
- )
- }
- }
- )
- }
- ) {
- val available by availableWidgets.observeAsState()
- val widgets = available
- if (widgets != null) {
- AppWidgetList(
- modifier = Modifier
- .fillMaxSize()
- .padding(it),
- widgets = widgets,
- onWidgetSelected = {
- selectAppWidget(it)
- }
- )
- } else {
- Box(
- modifier = Modifier
- .fillMaxSize()
- .padding(it),
- contentAlignment = Alignment.Center
- ) {
- CircularProgressIndicator()
- }
- }
- }
- }
- }
- }
- }
-
- private fun selectAppWidget(widget: AppWidgetProviderInfo) {
- val appWidgetId = widgetHost.allocateAppWidgetId()
- bindAppWidget(widget, appWidgetId)
- }
-
- private fun bindAppWidget(widget: AppWidgetProviderInfo, appWidgetId: Int) {
- val canBind = appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, widget.provider)
- Log.d("MM20", "Can bind: $canBind")
- if (canBind) {
- configureAppWidget(widget, appWidgetId)
- } else {
- startActivityForResult(
- Intent(AppWidgetManager.ACTION_APPWIDGET_BIND).apply {
- putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
- putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, widget.provider)
- }, RequestCodeBind
- )
- }
- }
-
- private fun configureAppWidget(widget: AppWidgetProviderInfo, appWidgetId: Int) {
- if (widget.configure != null) {
- widgetHost.startAppWidgetConfigureActivityForResult(
- this,
- appWidgetId,
- 0,
- RequestCodeConfigure,
- null
- )
- } else {
- finishWithResult(appWidgetId)
- }
- }
-
- @Deprecated("Deprecated in super class")
- override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- super.onActivityResult(requestCode, resultCode, data)
- when (requestCode) {
- RequestCodeBind -> {
- val appWidgetId =
- data?.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: return
- if (resultCode == RESULT_OK) {
- val widget = appWidgetManager.getAppWidgetInfo(appWidgetId)
- configureAppWidget(widget, appWidgetId)
- } else {
- widgetHost.deleteAppWidgetId(appWidgetId)
- cancel()
- }
- }
- RequestCodeConfigure -> {
- val appWidgetId =
- data?.extras?.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID) ?: return cancel()
- if (resultCode == RESULT_OK) {
- finishWithResult(appWidgetId)
- } else {
- widgetHost.deleteAppWidgetId(appWidgetId)
- cancel()
- }
- }
- }
- }
-
- private fun finishWithResult(widgetId: Int) {
- val data = Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId)
- setResult(RESULT_OK, data)
- finish()
- }
-
- private fun cancel() {
- setResult(RESULT_CANCELED)
- finish()
- }
-
- companion object {
- const val RequestCodeConfigure = 1
- const val RequestCodeBind = 2
- }
-}
\ No newline at end of file
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/PickAppWidgetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/PickAppWidgetVM.kt
deleted file mode 100644
index 5bb72549..00000000
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/picker/PickAppWidgetVM.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package de.mm20.launcher2.ui.launcher.widgets.picker
-
-import android.appwidget.AppWidgetManager
-import android.appwidget.AppWidgetProviderInfo
-import android.content.Context
-import android.content.pm.PackageManager
-import androidx.compose.ui.text.toLowerCase
-import androidx.lifecycle.LiveData
-import androidx.lifecycle.MutableLiveData
-import androidx.lifecycle.ViewModel
-import androidx.lifecycle.liveData
-import de.mm20.launcher2.crashreporter.CrashReporter
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.withContext
-
-typealias AppWidgetGroup = Pair>
-
-inline val AppWidgetGroup.appName: String
- get() = this.first
-inline val AppWidgetGroup.widgets: List
- get() = this.second
-
-class PickAppWidgetVM : ViewModel() {
- fun getAvailableWidgets(context: Context): LiveData?> = liveData {
- emit(null)
- val appWidgetManager = AppWidgetManager.getInstance(context)
- val widgets = withContext(Dispatchers.IO) {
- appWidgetManager.installedProviders
- .sortedBy { it.loadLabel(context.packageManager).lowercase() }
- .groupBy {
- val pkg = it.provider.packageName
- val appInfo = try {
- context.packageManager.getApplicationInfo(pkg, 0)
- } catch (e: PackageManager.NameNotFoundException) {
- CrashReporter.logException(e)
- return@groupBy ""
- }
- appInfo.loadLabel(context.packageManager).toString()
- }
- .toList()
- .sortedBy { it.first.lowercase() }
- }
- emit(widgets)
- }
-}
\ No newline at end of file
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt
index b2ce8e5c..2701fae4 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidget.kt
@@ -34,7 +34,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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
@@ -81,7 +80,7 @@ fun WeatherWidget(widget: WeatherWidget) {
}
}
- val selectedForecast by viewModel.currentForecast.observeAsState()
+ val selectedForecast by viewModel.currentForecast
val imperialUnits by viewModel.imperialUnits.collectAsState(false)
val compactMode = !widget.config.showForecast
@@ -93,8 +92,8 @@ fun WeatherWidget(widget: WeatherWidget) {
}
val forecast = selectedForecast ?: run {
- val hasPermission by viewModel.hasLocationPermission.observeAsState()
- val autoLocation by viewModel.autoLocation.observeAsState()
+ val hasPermission by viewModel.hasLocationPermission.collectAsState()
+ val autoLocation by viewModel.autoLocation.collectAsState()
Column {
AnimatedVisibility(hasPermission == false && autoLocation == true) {
MissingPermissionBanner(
@@ -126,9 +125,9 @@ fun WeatherWidget(widget: WeatherWidget) {
if (!compactMode) {
- val dailyForecasts by viewModel.dailyForecasts.observeAsState(emptyList())
- val selectedDayForecast by viewModel.currentDailyForecast.observeAsState()
- val currentDayForecasts by viewModel.currentDayForecasts.observeAsState(emptyList())
+ val dailyForecasts by viewModel.dailyForecasts
+ val selectedDayForecast by viewModel.currentDailyForecast
+ val currentDayForecasts by viewModel.currentDayForecasts
Surface(
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = LocalCardStyle.current.opacity),
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidgetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidgetVM.kt
index 9a8049e6..f64048cb 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidgetVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/weather/WeatherWidgetVM.kt
@@ -1,6 +1,7 @@
package de.mm20.launcher2.ui.launcher.widgets.weather
import androidx.appcompat.app.AppCompatActivity
+import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.*
import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager
@@ -8,8 +9,10 @@ import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.weather.DailyForecast
import de.mm20.launcher2.weather.Forecast
import de.mm20.launcher2.weather.WeatherRepository
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -30,16 +33,16 @@ class WeatherWidgetVM : ViewModel(), KoinComponent {
set(value) {
field = min(value, forecasts.lastIndex)
if (field < 0) {
- currentForecast.postValue(null)
+ currentForecast.value = null
return
}
selectedForecastIndex = min(
selectedForecastIndex,
forecasts[value].hourlyForecasts.lastIndex
)
- currentDayForecasts.postValue(forecasts[value].hourlyForecasts)
- currentDailyForecast.postValue(forecasts[value])
- currentForecast.postValue(getCurrentlySelectedForecast())
+ currentDayForecasts.value = forecasts[value].hourlyForecasts
+ currentDailyForecast.value = forecasts[value]
+ currentForecast.value = getCurrentlySelectedForecast()
}
/**
@@ -48,11 +51,11 @@ class WeatherWidgetVM : ViewModel(), KoinComponent {
private var selectedForecastIndex = 0
set(value) {
if (selectedDayIndex < 0) {
- currentForecast.postValue(null)
+ currentForecast.value = null
return
}
field = min(value, forecasts[selectedDayIndex].hourlyForecasts.lastIndex)
- currentForecast.postValue(getCurrentlySelectedForecast())
+ currentForecast.value = getCurrentlySelectedForecast()
}
private val forecastsFlow = weatherRepository.forecasts
@@ -65,29 +68,29 @@ class WeatherWidgetVM : ViewModel(), KoinComponent {
field = value
selectedDayIndex = 0
selectedForecastIndex = 0
- dailyForecasts.postValue(value)
+ dailyForecasts.value = value
}
/**
* Currently selected forecast, one of [currentDayForecasts]
*/
- val currentForecast = MutableLiveData(getCurrentlySelectedForecast())
+ val currentForecast = mutableStateOf(getCurrentlySelectedForecast())
/**
* List of forecast summaries for each day
*/
- val dailyForecasts = MutableLiveData>(emptyList())
+ val dailyForecasts = mutableStateOf>(emptyList())
/**
* Forecasts of the currently selected day (hourly in most cases).
* This is [DailyForecast.hourlyForecasts] of [currentDailyForecast]
*/
- val currentDayForecasts = MutableLiveData>(emptyList())
+ val currentDayForecasts = mutableStateOf>(emptyList())
/**
* Daily forecast summary for the currently selected day, one of [dailyForecasts] or null
*/
- val currentDailyForecast = MutableLiveData(null)
+ val currentDailyForecast = mutableStateOf(null)
init {
viewModelScope.launch {
@@ -98,11 +101,13 @@ class WeatherWidgetVM : ViewModel(), KoinComponent {
}
}
- val hasLocationPermission = permissionsManager.hasPermission(PermissionGroup.Location).asLiveData()
+ val hasLocationPermission = permissionsManager.hasPermission(PermissionGroup.Location)
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun requestLocationPermission(context: AppCompatActivity) {
permissionsManager.requestPermission(context, PermissionGroup.Location)
}
- val autoLocation = weatherRepository.autoLocation.asLiveData()
+ val autoLocation = weatherRepository.autoLocation
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
val imperialUnits = dataStore.data.map { it.weather.imperialUnits }
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt
index 7a06b4ff..8ab66178 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreen.kt
@@ -1,82 +1,24 @@
package de.mm20.launcher2.ui.settings.appearance
-import android.graphics.drawable.ColorDrawable
-import androidx.appcompat.app.AppCompatActivity
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.foundation.background
-import androidx.compose.foundation.layout.Arrangement
-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.padding
-import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.width
-import androidx.compose.foundation.lazy.grid.GridCells
-import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
-import androidx.compose.foundation.lazy.grid.items
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.rounded.FormatPaint
-import androidx.compose.material3.AlertDialog
-import androidx.compose.material3.FilledIconToggleButton
-import androidx.compose.material3.Icon
-import androidx.compose.material3.LocalContentColor
-import androidx.compose.material3.MaterialTheme
-import androidx.compose.material3.PlainTooltipBox
-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.collectAsState
-import androidx.compose.runtime.derivedStateOf
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.alpha
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
-import androidx.compose.ui.text.style.TextAlign
-import androidx.compose.ui.text.style.TextOverflow
-import androidx.compose.ui.unit.dp
-import androidx.compose.ui.window.Dialog
-import androidx.core.content.ContextCompat
import androidx.lifecycle.viewmodel.compose.viewModel
-import com.google.accompanist.pager.HorizontalPager
-import com.google.accompanist.pager.HorizontalPagerIndicator
-import com.google.accompanist.pager.rememberPagerState
-import de.mm20.launcher2.icons.StaticIconLayer
-import de.mm20.launcher2.icons.StaticLauncherIcon
import de.mm20.launcher2.preferences.Settings.AppearanceSettings
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
-import de.mm20.launcher2.preferences.Settings.IconSettings
-import de.mm20.launcher2.preferences.Settings.SearchBarSettings
-import de.mm20.launcher2.preferences.Settings.SearchBarSettings.SearchBarColors
-import de.mm20.launcher2.preferences.Settings.SearchBarSettings.SearchBarStyle
-import de.mm20.launcher2.preferences.Settings.SystemBarsSettings.SystemBarColors
import de.mm20.launcher2.ui.R
-import de.mm20.launcher2.ui.component.SearchBar
-import de.mm20.launcher2.ui.component.SearchBarLevel
-import de.mm20.launcher2.ui.component.ShapedLauncherIcon
-import de.mm20.launcher2.ui.component.getShape
import de.mm20.launcher2.ui.component.preferences.ListPreference
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.SliderPreference
-import de.mm20.launcher2.ui.component.preferences.SwitchPreference
-import de.mm20.launcher2.ui.component.preferences.label
import de.mm20.launcher2.ui.component.preferences.value
import de.mm20.launcher2.ui.locals.LocalNavController
import de.mm20.launcher2.ui.theme.getTypography
-import kotlinx.coroutines.delay
-import kotlinx.coroutines.isActive
@Composable
fun AppearanceSettingsScreen() {
@@ -86,7 +28,7 @@ fun AppearanceSettingsScreen() {
PreferenceScreen(title = stringResource(id = R.string.preference_screen_appearance)) {
item {
PreferenceCategory {
- val theme by viewModel.theme.observeAsState()
+ val theme by viewModel.theme.collectAsState()
ListPreference(
title = stringResource(id = R.string.preference_theme),
items = listOf(
@@ -100,7 +42,7 @@ fun AppearanceSettingsScreen() {
viewModel.setTheme(newValue)
}
)
- val colorScheme by viewModel.colorScheme.observeAsState()
+ val colorScheme by viewModel.colorScheme.collectAsState()
Preference(
title = stringResource(id = R.string.preference_screen_colors),
summary = when (colorScheme) {
@@ -113,7 +55,7 @@ fun AppearanceSettingsScreen() {
navController?.navigate("settings/appearance/colorscheme")
}
)
- val font by viewModel.font.observeAsState()
+ val font by viewModel.font.collectAsState()
ListPreference(
title = stringResource(R.string.preference_font),
items = listOf(
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt
index 856bf1a8..4befa06f 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/appearance/AppearanceSettingsScreenVM.kt
@@ -1,26 +1,16 @@
package de.mm20.launcher2.ui.settings.appearance
-import android.content.Context
-import android.content.Intent
-import android.view.WindowManager
-import androidx.appcompat.app.AppCompatActivity
-import androidx.core.content.getSystemService
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
-import de.mm20.launcher2.icons.IconPack
import de.mm20.launcher2.icons.IconService
-import de.mm20.launcher2.ktx.isAtLeastApiLevel
import de.mm20.launcher2.preferences.LauncherDataStore
-import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.ColorScheme
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Font
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.Theme
-import de.mm20.launcher2.preferences.Settings.SearchBarSettings
-import de.mm20.launcher2.preferences.Settings.SearchBarSettings.SearchBarColors
-import de.mm20.launcher2.preferences.Settings.SystemBarsSettings
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -30,7 +20,8 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent {
private val iconService: IconService by inject()
- val theme = dataStore.data.map { it.appearance.theme }.asLiveData()
+ val theme = dataStore.data.map { it.appearance.theme }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setTheme(theme: Theme) {
viewModelScope.launch {
dataStore.updateData {
@@ -41,7 +32,8 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val colorScheme = dataStore.data.map { it.appearance.colorScheme }.asLiveData()
+ val colorScheme = dataStore.data.map { it.appearance.colorScheme }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setColorScheme(colorScheme: ColorScheme) {
viewModelScope.launch {
dataStore.updateData {
@@ -52,7 +44,8 @@ class AppearanceSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val font = dataStore.data.map { it.appearance.font }.asLiveData()
+ val font = dataStore.data.map { it.appearance.font }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setFont(font: Font) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/BackupSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/BackupSettingsScreen.kt
index 981231ae..6021051f 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/BackupSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/BackupSettingsScreen.kt
@@ -3,7 +3,6 @@ package de.mm20.launcher2.ui.settings.backup
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.runtime.*
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
@@ -19,11 +18,9 @@ import java.time.format.DateTimeFormatter
fun BackupSettingsScreen() {
val viewModel: BackupSettingsScreenVM = viewModel()
- val restoreUri by viewModel.restoreUri.observeAsState()
+ val restoreUri by viewModel.restoreUri
- val showBackupSheet by viewModel.showBackupSheet.observeAsState(false)
-
- val context = LocalContext.current
+ val showBackupSheet by viewModel.showBackupSheet
val restoreLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.OpenDocument(),
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/BackupSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/BackupSettingsScreenVM.kt
index 21d55ca4..3a7df897 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/BackupSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/BackupSettingsScreenVM.kt
@@ -1,15 +1,15 @@
package de.mm20.launcher2.ui.settings.backup
import android.net.Uri
-import androidx.lifecycle.MutableLiveData
+import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import org.koin.core.component.KoinComponent
class BackupSettingsScreenVM : ViewModel(), KoinComponent {
- val showBackupSheet = MutableLiveData(false)
+ val showBackupSheet = mutableStateOf(false)
- val restoreUri = MutableLiveData(null)
+ val restoreUri = mutableStateOf(null)
fun setShowBackupSheet(show: Boolean) {
showBackupSheet.value = show
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/CreateBackupSheet.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/CreateBackupSheet.kt
index 06f271b6..eec262eb 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/CreateBackupSheet.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/CreateBackupSheet.kt
@@ -12,7 +12,6 @@ import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
@@ -38,8 +37,8 @@ fun CreateBackupSheet(
viewModel.reset()
}
- val components by viewModel.selectedComponents.observeAsState(emptySet())
- val state by viewModel.state.observeAsState(CreateBackupState.Ready)
+ val components by viewModel.selectedComponents
+ val state by viewModel.state
val backupLauncher = rememberLauncherForActivityResult(
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/CreateBackupSheetVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/CreateBackupSheetVM.kt
index ae1b0cf0..a17a4317 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/CreateBackupSheetVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/backup/CreateBackupSheetVM.kt
@@ -1,7 +1,7 @@
package de.mm20.launcher2.ui.settings.backup
import android.net.Uri
-import androidx.lifecycle.MutableLiveData
+import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.backup.BackupComponent
@@ -14,9 +14,9 @@ class CreateBackupSheetVM : ViewModel(), KoinComponent {
private val backupManager: BackupManager by inject()
- val state = MutableLiveData(CreateBackupState.Ready)
+ val state = mutableStateOf(CreateBackupState.Ready)
- val selectedComponents = MutableLiveData(BackupComponent.values().toSet())
+ val selectedComponents = mutableStateOf(BackupComponent.values().toSet())
fun reset() {
state.value = CreateBackupState.Ready
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/cards/CardsSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/cards/CardsSettingsScreen.kt
index 97a8373b..015656bf 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/cards/CardsSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/cards/CardsSettingsScreen.kt
@@ -9,8 +9,8 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
@@ -43,7 +43,7 @@ fun CardsSettingsScreen() {
}
item {
PreferenceCategory {
- val shape by viewModel.shape.observeAsState()
+ val shape by viewModel.shape.collectAsState()
ListPreference(
icon = Icons.Rounded.Rectangle,
title = stringResource(R.string.preference_cards_shape),
@@ -55,7 +55,7 @@ fun CardsSettingsScreen() {
onValueChanged = {
if (it != null) viewModel.setShape(it)
})
- val radius by viewModel.radius.observeAsState(0)
+ val radius by viewModel.radius.collectAsState()
SliderPreference(
title = stringResource(R.string.preference_cards_corner_radius),
icon = Icons.Rounded.RoundedCorner,
@@ -67,7 +67,7 @@ fun CardsSettingsScreen() {
viewModel.setRadius(it)
}
)
- val opacity by viewModel.opacity.observeAsState(0f)
+ val opacity by viewModel.opacity.collectAsState()
SliderPreference(
title = stringResource(R.string.preference_cards_opacity),
icon = Icons.Rounded.Opacity,
@@ -78,7 +78,7 @@ fun CardsSettingsScreen() {
viewModel.setOpacity(it)
}
)
- val borderWidth by viewModel.borderWidth.observeAsState(0)
+ val borderWidth by viewModel.borderWidth.collectAsState()
SliderPreference(
title = stringResource(R.string.preference_cards_stroke_width),
icon = Icons.Rounded.LineWeight,
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/cards/CardsSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/cards/CardsSettingsScreenVM.kt
index 9c5e46d1..1d20cacf 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/cards/CardsSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/cards/CardsSettingsScreenVM.kt
@@ -1,11 +1,12 @@
package de.mm20.launcher2.ui.settings.cards
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -13,7 +14,8 @@ import org.koin.core.component.inject
class CardsSettingsScreenVM: ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject()
- val opacity = dataStore.data.map { it.cards.opacity }.asLiveData()
+ val opacity = dataStore.data.map { it.cards.opacity }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), 0f)
fun setOpacity(opacity: Float) {
viewModelScope.launch {
dataStore.updateData {
@@ -25,7 +27,9 @@ class CardsSettingsScreenVM: ViewModel(), KoinComponent {
}
}
- val radius = dataStore.data.map { it.cards.radius }.asLiveData()
+ val radius = dataStore.data.map { it.cards.radius }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), 0)
+
fun setRadius(radius: Int) {
viewModelScope.launch {
dataStore.updateData {
@@ -37,7 +41,8 @@ class CardsSettingsScreenVM: ViewModel(), KoinComponent {
}
}
- val borderWidth = dataStore.data.map { it.cards.borderWidth }.asLiveData()
+ val borderWidth = dataStore.data.map { it.cards.borderWidth }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), 0)
fun setBorderWidth(borderWidth: Int) {
viewModelScope.launch {
dataStore.updateData {
@@ -49,7 +54,9 @@ class CardsSettingsScreenVM: ViewModel(), KoinComponent {
}
}
- val shape = dataStore.data.map { it.cards.shape }.asLiveData()
+ val shape = dataStore.data.map { it.cards.shape }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
+
fun setShape(shape: Settings.CardSettings.Shape) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt
index 257af212..eb4644db 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreen.kt
@@ -8,17 +8,14 @@ import androidx.compose.material3.AlertDialog
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.*
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
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
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockStyle
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetColors
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout
@@ -35,7 +32,7 @@ fun ClockWidgetSettingsScreen() {
) {
item {
PreferenceCategory {
- val layout by viewModel.layout.observeAsState()
+ val layout by viewModel.layout.collectAsState()
ListPreference(
title = stringResource(R.string.preference_clockwidget_layout),
value = layout,
@@ -47,7 +44,7 @@ fun ClockWidgetSettingsScreen() {
if (it != null) viewModel.setLayout(it)
}
)
- val clockStyle by viewModel.clockStyle.observeAsState()
+ val clockStyle by viewModel.clockStyle.collectAsState()
ClockStylePreference(
layout = layout ?: ClockWidgetLayout.Vertical,
value = clockStyle,
@@ -55,7 +52,7 @@ fun ClockWidgetSettingsScreen() {
viewModel.setClockStyle(it)
}
)
- val color by viewModel.color.observeAsState()
+ val color by viewModel.color.collectAsState()
ListPreference(
title = stringResource(R.string.preference_clock_widget_color),
value = color,
@@ -68,7 +65,7 @@ fun ClockWidgetSettingsScreen() {
if (it != null) viewModel.setColor(it)
}
)
- val fillHeight by viewModel.fillHeight.observeAsState()
+ val fillHeight by viewModel.fillHeight.collectAsState()
SwitchPreference(
title = stringResource(R.string.preference_clock_widget_fill_height),
summary = stringResource(R.string.preference_clock_widget_fill_height_summary),
@@ -79,7 +76,7 @@ fun ClockWidgetSettingsScreen() {
}
item {
PreferenceCategory {
- val datePart by viewModel.datePart.observeAsState()
+ val datePart by viewModel.datePart.collectAsState()
SwitchPreference(
title = stringResource(R.string.preference_clockwidget_date_part),
summary = stringResource(R.string.preference_clockwidget_date_part_summary),
@@ -89,7 +86,7 @@ fun ClockWidgetSettingsScreen() {
viewModel.setDatePart(it)
},
)
- val favoritesPart by viewModel.favoritesPart.observeAsState()
+ val favoritesPart by viewModel.favoritesPart.collectAsState()
SwitchPreference(
title = stringResource(R.string.preference_clockwidget_favorites_part),
summary = stringResource(R.string.preference_clockwidget_favorites_part_summary),
@@ -103,7 +100,7 @@ fun ClockWidgetSettingsScreen() {
}
item {
PreferenceCategory {
- val musicPart by viewModel.musicPart.observeAsState()
+ val musicPart by viewModel.musicPart.collectAsState()
SwitchPreference(
title = stringResource(R.string.preference_clockwidget_music_part),
summary = stringResource(R.string.preference_clockwidget_music_part_summary),
@@ -113,7 +110,7 @@ fun ClockWidgetSettingsScreen() {
viewModel.setMusicPart(it)
}
)
- val alarmPart by viewModel.alarmPart.observeAsState()
+ val alarmPart by viewModel.alarmPart.collectAsState()
SwitchPreference(
title = stringResource(R.string.preference_clockwidget_alarm_part),
summary = stringResource(R.string.preference_clockwidget_alarm_part_summary),
@@ -123,7 +120,7 @@ fun ClockWidgetSettingsScreen() {
viewModel.setAlarmPart(it)
}
)
- val batteryPart by viewModel.batteryPart.observeAsState()
+ val batteryPart by viewModel.batteryPart.collectAsState()
SwitchPreference(
title = stringResource(R.string.preference_clockwidget_battery_part),
summary = stringResource(R.string.preference_clockwidget_battery_part_summary),
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt
index b83a77c8..159df54d 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/clockwidget/ClockWidgetSettingsScreenVM.kt
@@ -1,20 +1,21 @@
package de.mm20.launcher2.ui.settings.clockwidget
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings
import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetColors
-import de.mm20.launcher2.preferences.Settings.ClockWidgetSettings.ClockWidgetLayout
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject()
- val layout = dataStore.data.map { it.clockWidget.layout }.asLiveData()
+ val layout = dataStore.data.map { it.clockWidget.layout }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setLayout(layout: ClockWidgetSettings.ClockWidgetLayout) {
viewModelScope.launch {
dataStore.updateData {
@@ -27,7 +28,9 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val clockStyle = dataStore.data.map { it.clockWidget.clockStyle }.asLiveData()
+ val clockStyle = dataStore.data.map { it.clockWidget.clockStyle }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
+
fun setClockStyle(clockStyle: ClockWidgetSettings.ClockStyle) {
viewModelScope.launch {
dataStore.updateData {
@@ -40,7 +43,8 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val color = dataStore.data.map { it.clockWidget.color }.asLiveData()
+ val color = dataStore.data.map { it.clockWidget.color }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setColor(color: ClockWidgetColors) {
viewModelScope.launch {
dataStore.updateData {
@@ -53,7 +57,8 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val fillHeight = dataStore.data.map { it.clockWidget.fillHeight }.asLiveData()
+ val fillHeight = dataStore.data.map { it.clockWidget.fillHeight }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setFillHeight(fillHeight: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -66,7 +71,8 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val datePart = dataStore.data.map { it.clockWidget.datePart }.asLiveData()
+ val datePart = dataStore.data.map { it.clockWidget.datePart }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setDatePart(datePart: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -79,7 +85,8 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val favoritesPart = dataStore.data.map { it.clockWidget.favoritesPart }.asLiveData()
+ val favoritesPart = dataStore.data.map { it.clockWidget.favoritesPart }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setFavoritesPart(favoritesPart: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -92,7 +99,8 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val batteryPart = dataStore.data.map { it.clockWidget.batteryPart }.asLiveData()
+ val batteryPart = dataStore.data.map { it.clockWidget.batteryPart }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setBatteryPart(batteryPart: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -105,7 +113,8 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val musicPart = dataStore.data.map { it.clockWidget.musicPart }.asLiveData()
+ val musicPart = dataStore.data.map { it.clockWidget.musicPart }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setMusicPart(musicPart: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -118,7 +127,8 @@ class ClockWidgetSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val alarmPart = dataStore.data.map { it.clockWidget.alarmPart }.asLiveData()
+ val alarmPart = dataStore.data.map { it.clockWidget.alarmPart }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setAlarmPart(alarmPart: Boolean) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ColorSchemeSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ColorSchemeSettingsScreen.kt
index 9a3e18d8..f35d82f2 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ColorSchemeSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ColorSchemeSettingsScreen.kt
@@ -8,8 +8,8 @@ import androidx.compose.material3.ColorScheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
@@ -34,7 +34,7 @@ fun ColorSchemeSettingsScreen() {
PreferenceScreen(title = stringResource(R.string.preference_screen_colors)) {
item {
PreferenceCategory {
- val colorScheme by viewModel.colorScheme.observeAsState()
+ val colorScheme by viewModel.colorScheme.collectAsState()
val items = mutableListOf(
AppearanceSettings.ColorScheme.Default to stringResource(R.string.preference_colors_default),
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ColorSchemeSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ColorSchemeSettingsScreenVM.kt
index f48b1329..c33d169a 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ColorSchemeSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/ColorSchemeSettingsScreenVM.kt
@@ -1,11 +1,12 @@
package de.mm20.launcher2.ui.settings.colorscheme
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings.AppearanceSettings
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -13,9 +14,11 @@ import org.koin.core.component.inject
class ColorSchemeSettingsScreenVM : ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject()
- val theme = dataStore.data.map { it.appearance.theme }.asLiveData()
+ val theme = dataStore.data.map { it.appearance.theme }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
- val colorScheme = dataStore.data.map { it.appearance.colorScheme }.asLiveData()
+ val colorScheme = dataStore.data.map { it.appearance.colorScheme }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setColorScheme(colorScheme: AppearanceSettings.ColorScheme) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CustomColorSchemeSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CustomColorSchemeSettingsScreen.kt
index fbec6e7b..1b5e356c 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CustomColorSchemeSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CustomColorSchemeSettingsScreen.kt
@@ -4,7 +4,6 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.MoreVert
import androidx.compose.material3.*
import androidx.compose.runtime.*
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.res.stringResource
@@ -18,7 +17,7 @@ import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
fun CustomColorSchemeSettingsScreen() {
val viewModel: CustomColorSchemeSettingsScreenVM = viewModel()
- val advancedMode by viewModel.advancedMode.observeAsState()
+ val advancedMode by viewModel.advancedMode.collectAsState()
PreferenceScreen(
title = stringResource(R.string.preference_screen_colors),
@@ -64,7 +63,7 @@ fun CustomColorSchemeSettingsScreen() {
if (advancedMode == false) {
item {
PreferenceCategory {
- val baseColors by viewModel.baseColors.observeAsState()
+ val baseColors by viewModel.baseColors.collectAsState()
ColorPreference(
title = stringResource(R.string.preference_custom_colors_a1),
value = baseColors?.let { Color(it.accent1) },
@@ -149,7 +148,7 @@ fun CustomColorSchemeSettingsScreen() {
if (advancedMode == true) {
item {
PreferenceCategory(stringResource(R.string.preference_category_custom_colors_light)) {
- val lightScheme by viewModel.lightScheme.observeAsState()
+ val lightScheme by viewModel.lightScheme.collectAsState()
ColorPreference(
title = "Primary",
value = lightScheme?.let { Color(it.primary) },
@@ -513,7 +512,7 @@ fun CustomColorSchemeSettingsScreen() {
}
PreferenceCategory(stringResource(R.string.preference_category_custom_colors_dark)) {
- val darkScheme by viewModel.darkScheme.observeAsState()
+ val darkScheme by viewModel.darkScheme.collectAsState()
ColorPreference(
title = "Primary",
value = darkScheme?.let { Color(it.primary) },
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CustomColorSchemeSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CustomColorSchemeSettingsScreenVM.kt
index fd084ab6..3fa1d43a 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CustomColorSchemeSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/colorscheme/CustomColorSchemeSettingsScreenVM.kt
@@ -1,13 +1,13 @@
package de.mm20.launcher2.ui.settings.colorscheme
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.preferences.LauncherDataStore
-import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.preferences.Settings.AppearanceSettings.CustomColors
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -17,7 +17,8 @@ import scheme.Scheme
class CustomColorSchemeSettingsScreenVM : ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject()
- val advancedMode = dataStore.data.map { it.appearance.customColors.advancedMode }.asLiveData()
+ val advancedMode = dataStore.data.map { it.appearance.customColors.advancedMode }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setAdvancedMode(advancedMode: Boolean) {
viewModelScope.launch {
val lightScheme = dataStore.updateData {
@@ -63,7 +64,8 @@ class CustomColorSchemeSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val baseColors = dataStore.data.map { it.appearance.customColors.baseColors }.asLiveData()
+ val baseColors = dataStore.data.map { it.appearance.customColors.baseColors }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setBaseColors(baseColors: CustomColors.BaseColors) {
viewModelScope.launch {
dataStore.updateData {
@@ -82,7 +84,8 @@ class CustomColorSchemeSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val darkScheme = dataStore.data.map { it.appearance.customColors.darkScheme }.asLiveData()
+ val darkScheme = dataStore.data.map { it.appearance.customColors.darkScheme }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setDarkScheme(darkScheme: CustomColors.Scheme) {
viewModelScope.launch {
dataStore.updateData {
@@ -99,7 +102,8 @@ class CustomColorSchemeSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val lightScheme = dataStore.data.map { it.appearance.customColors.lightScheme }.asLiveData()
+ val lightScheme = dataStore.data.map { it.appearance.customColors.lightScheme }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setLightScheme(lightScheme: CustomColors.Scheme) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReportScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReportScreen.kt
index 7fcfd77a..a9adc327 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReportScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReportScreen.kt
@@ -6,14 +6,13 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
-import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.BugReport
import androidx.compose.material.icons.rounded.Share
import androidx.compose.material3.*
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.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
@@ -26,7 +25,7 @@ import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
fun CrashReportScreen(fileName: String) {
val viewModel: CrashReportScreenVM = viewModel()
val context = LocalContext.current
- val crashReport by remember(fileName) { viewModel.getCrashReport(fileName) }.observeAsState()
+ val crashReport by remember(fileName) { viewModel.getCrashReport(fileName) }.collectAsState(null)
PreferenceScreen(
title = when (crashReport?.type) {
CrashReportType.Exception -> "Exception"
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReportScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReportScreenVM.kt
index 183c3f5a..633dc2ee 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReportScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReportScreenVM.kt
@@ -5,14 +5,14 @@ import android.content.Intent
import android.net.Uri
import androidx.core.content.FileProvider
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.liveData
import de.mm20.launcher2.crashreporter.CrashReport
import de.mm20.launcher2.crashreporter.CrashReporter
+import kotlinx.coroutines.flow.flow
import java.io.File
import java.net.URLEncoder
class CrashReportScreenVM : ViewModel() {
- fun getCrashReport(fileName: String) = liveData {
+ fun getCrashReport(fileName: String) = flow {
emit(CrashReporter.getCrashReport(fileName))
}
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReporterScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReporterScreen.kt
index 97fc9634..35570447 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReporterScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReporterScreen.kt
@@ -13,7 +13,6 @@ import androidx.compose.material3.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
@@ -32,9 +31,9 @@ import java.net.URLEncoder
fun CrashReporterScreen() {
val viewModel: CrashReporterScreenVM = viewModel()
val navController = LocalNavController.current
- val reports by viewModel.reports.observeAsState()
- val showExceptions by viewModel.showExceptions.observeAsState(true)
- val showCrashes by viewModel.showCrashes.observeAsState(true)
+ val reports by viewModel.reports
+ val showExceptions by viewModel.showExceptions
+ val showCrashes by viewModel.showCrashes
PreferenceScreen(
title = stringResource(R.string.preference_crash_reporter),
helpUrl = "https://kvaesitso.mm20.de/docs/user-guide/troubleshooting/crashreporter"
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReporterScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReporterScreenVM.kt
index 247f7ade..cabd27b4 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReporterScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/crashreporter/CrashReporterScreenVM.kt
@@ -1,6 +1,6 @@
package de.mm20.launcher2.ui.settings.crashreporter
-import androidx.lifecycle.MutableLiveData
+import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.crashreporter.BuildConfig
@@ -29,10 +29,10 @@ class CrashReporterScreenVM: ViewModel() {
}
}
- val showExceptions = MutableLiveData(false)
- val showCrashes = MutableLiveData(true)
+ val showExceptions = mutableStateOf(false)
+ val showCrashes = mutableStateOf(true)
- val reports = MutableLiveData?>(null)
+ val reports = mutableStateOf?>(null)
private var _reports: List? = null
init {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreen.kt
index 277d46c7..b83811b0 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreen.kt
@@ -12,8 +12,8 @@ import androidx.compose.foundation.layout.*
import androidx.compose.material3.MaterialTheme
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.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -30,7 +30,7 @@ fun EasterEggSettingsScreen() {
val viewModel: EasterEggSettingsScreenVM = viewModel()
PreferenceScreen(title = stringResource(R.string.preference_screen_about)) {
item {
- val easterEgg by viewModel.easterEgg.observeAsState(false)
+ val easterEgg by viewModel.easterEgg.collectAsState()
val bgAlpha by animateFloatAsState(if (easterEgg) 1f else 0f)
val textColor by animateColorAsState(if (easterEgg) MaterialTheme.colorScheme.onSecondaryContainer else MaterialTheme.colorScheme.onBackground)
Column(
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreenVM.kt
index 3ad48569..2602208c 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/easteregg/EasterEggSettingsScreenVM.kt
@@ -1,10 +1,11 @@
package de.mm20.launcher2.ui.settings.easteregg
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.preferences.LauncherDataStore
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -12,7 +13,8 @@ import org.koin.core.component.inject
class EasterEggSettingsScreenVM: ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject()
- val easterEgg = dataStore.data.map { it.easterEgg }.asLiveData()
+ val easterEgg = dataStore.data.map { it.easterEgg }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
fun setEasterEgg(easterEgg: Boolean) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreen.kt
index 89821bd4..f9b20153 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreen.kt
@@ -7,8 +7,8 @@ import androidx.compose.material.icons.rounded.Sort
import androidx.compose.material.icons.rounded.SwapVert
import androidx.compose.material.icons.rounded.TableRows
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
@@ -45,7 +45,7 @@ fun FavoritesSettingsScreen() {
}
item {
PreferenceCategory(stringResource(R.string.preference_category_favorites_frequently_used)) {
- val frequentlyUsed by viewModel.frequentlyUsed.observeAsState()
+ val frequentlyUsed by viewModel.frequentlyUsed.collectAsState()
SwitchPreference(
title = stringResource(R.string.frequently_used_show_in_favorites),
summary = stringResource(R.string.preference_favorites_frequently_used_summary),
@@ -55,7 +55,7 @@ fun FavoritesSettingsScreen() {
},
icon = Icons.Rounded.Insights
)
- val frequentlyUsedRows by viewModel.frequentlyUsedRows.observeAsState(1)
+ val frequentlyUsedRows by viewModel.frequentlyUsedRows.collectAsState()
SliderPreference(
title = stringResource(R.string.frequently_used_rows),
value = frequentlyUsedRows,
@@ -67,7 +67,7 @@ fun FavoritesSettingsScreen() {
},
icon = Icons.Rounded.TableRows
)
- val searchResultWeightFactor by viewModel.searchResultWeightFactor.observeAsState(WeightFactor.Default)
+ val searchResultWeightFactor by viewModel.searchResultWeightFactor.collectAsState()
ListPreference(
title = stringResource(R.string.preference_search_result_ordering_weight_factor),
icon = Icons.Rounded.SwapVert,
@@ -82,7 +82,7 @@ fun FavoritesSettingsScreen() {
}
}
item {
- val editButton by viewModel.editButton.observeAsState()
+ val editButton by viewModel.editButton.collectAsState()
PreferenceCategory {
SwitchPreference(
title = stringResource(R.string.preference_edit_button),
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreenVM.kt
index 6ee460d8..dd7c0280 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/favorites/FavoritesSettingsScreenVM.kt
@@ -1,11 +1,12 @@
package de.mm20.launcher2.ui.settings.favorites
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings.SearchResultOrderingSettings.WeightFactor
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -13,7 +14,8 @@ import org.koin.core.component.inject
class FavoritesSettingsScreenVM: ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject()
- val frequentlyUsed = dataStore.data.map { it.favorites.frequentlyUsed }.asLiveData()
+ val frequentlyUsed = dataStore.data.map { it.favorites.frequentlyUsed }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setFrequentlyUsed(frequentlyUsed: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -27,7 +29,8 @@ class FavoritesSettingsScreenVM: ViewModel(), KoinComponent {
}
}
- val frequentlyUsedRows = dataStore.data.map { it.favorites.frequentlyUsedRows }.asLiveData()
+ val frequentlyUsedRows = dataStore.data.map { it.favorites.frequentlyUsedRows }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), 1)
fun setFrequentlyUsedRows(frequentlyUsedRows: Int) {
viewModelScope.launch {
dataStore.updateData {
@@ -41,7 +44,8 @@ class FavoritesSettingsScreenVM: ViewModel(), KoinComponent {
}
}
- val editButton = dataStore.data.map { it.favorites.editButton }.asLiveData()
+ val editButton = dataStore.data.map { it.favorites.editButton }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setEditButton(editButton: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -55,7 +59,8 @@ class FavoritesSettingsScreenVM: ViewModel(), KoinComponent {
}
}
- val searchResultWeightFactor = dataStore.data.map { it.resultOrdering.weightFactor }.asLiveData()
+ val searchResultWeightFactor = dataStore.data.map { it.resultOrdering.weightFactor }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), WeightFactor.Default)
fun setSearchResultWeightFactor(searchResultWeightFactor: WeightFactor) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/filesearch/FileSearchSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/filesearch/FileSearchSettingsScreen.kt
index 3efe7ab9..b014ac30 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/filesearch/FileSearchSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/filesearch/FileSearchSettingsScreen.kt
@@ -11,8 +11,8 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.collectAsState
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.platform.LocalLifecycleOwner
@@ -40,7 +40,7 @@ fun FileSearchSettingsScreen() {
viewModel.onResume()
}
}
- val loading by viewModel.loading.observeAsState()
+ val loading by viewModel.loading
PreferenceScreen(title = stringResource(R.string.preference_search_files)) {
if (loading == true) {
item {
@@ -52,8 +52,8 @@ fun FileSearchSettingsScreen() {
}
item {
PreferenceCategory {
- val localFiles by viewModel.localFiles.observeAsState()
- val hasFilePermission by viewModel.hasFilePermission.observeAsState()
+ val localFiles by viewModel.localFiles.collectAsState()
+ val hasFilePermission by viewModel.hasFilePermission.collectAsState()
AnimatedVisibility(hasFilePermission == false) {
MissingPermissionBanner(
text = stringResource(
@@ -74,8 +74,8 @@ fun FileSearchSettingsScreen() {
enabled = hasFilePermission == true
)
- val nextcloud by viewModel.nextcloud.observeAsState()
- val nextcloudAccount by viewModel.nextcloudAccount.observeAsState()
+ val nextcloud by viewModel.nextcloud.collectAsState()
+ val nextcloudAccount by viewModel.nextcloudAccount
AnimatedVisibility(nextcloudAccount == null) {
Banner(
text = stringResource(R.string.no_account_nextcloud),
@@ -107,8 +107,8 @@ fun FileSearchSettingsScreen() {
enabled = nextcloudAccount != null
)
- val owncloud by viewModel.owncloud.observeAsState()
- val owncloudAccount by viewModel.owncloudAccount.observeAsState()
+ val owncloud by viewModel.owncloud.collectAsState()
+ val owncloudAccount by viewModel.owncloudAccount
AnimatedVisibility(owncloudAccount == null) {
Banner(
text = stringResource(R.string.no_account_owncloud),
@@ -141,8 +141,8 @@ fun FileSearchSettingsScreen() {
)
if (viewModel.microsoftAvailable) {
- val onedrive by viewModel.onedrive.observeAsState()
- val microsoftAccount by viewModel.microsoftAccount.observeAsState()
+ val onedrive by viewModel.onedrive.collectAsState()
+ val microsoftAccount by viewModel.microsoftAccount
AnimatedVisibility(microsoftAccount == null) {
Banner(
text = stringResource(R.string.no_account_microsoft),
@@ -176,8 +176,8 @@ fun FileSearchSettingsScreen() {
}
if (viewModel.googleAvailable) {
- val gdrive by viewModel.gdrive.observeAsState()
- val googleAccount by viewModel.googleAccount.observeAsState()
+ val gdrive by viewModel.gdrive.collectAsState()
+ val googleAccount by viewModel.googleAccount
AnimatedVisibility(googleAccount == null) {
Banner(
text = stringResource(R.string.no_account_google),
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/filesearch/FileSearchSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/filesearch/FileSearchSettingsScreenVM.kt
index 078c1846..aa4fc8c5 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/filesearch/FileSearchSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/filesearch/FileSearchSettingsScreenVM.kt
@@ -1,9 +1,8 @@
package de.mm20.launcher2.ui.settings.filesearch
import androidx.appcompat.app.AppCompatActivity
-import androidx.lifecycle.MutableLiveData
+import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.accounts.Account
import de.mm20.launcher2.accounts.AccountType
@@ -11,7 +10,9 @@ import de.mm20.launcher2.accounts.AccountsRepository
import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.preferences.LauncherDataStore
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -21,14 +22,14 @@ class FileSearchSettingsScreenVM : ViewModel(), KoinComponent {
private val accountsRepository: AccountsRepository by inject()
private val permissionsManager: PermissionsManager by inject()
- val hasFilePermission =
- permissionsManager.hasPermission(PermissionGroup.ExternalStorage).asLiveData()
+ val hasFilePermission = permissionsManager.hasPermission(PermissionGroup.ExternalStorage)
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
- val loading = MutableLiveData(true)
- val nextcloudAccount = MutableLiveData(null)
- val owncloudAccount = MutableLiveData(null)
- val microsoftAccount = MutableLiveData(null)
- val googleAccount = MutableLiveData(null)
+ val loading = mutableStateOf(true)
+ val nextcloudAccount = mutableStateOf(null)
+ val owncloudAccount = mutableStateOf(null)
+ val microsoftAccount = mutableStateOf(null)
+ val googleAccount = mutableStateOf(null)
val microsoftAvailable = accountsRepository.isSupported(AccountType.Microsoft)
val googleAvailable = accountsRepository.isSupported(AccountType.Google)
@@ -46,7 +47,8 @@ class FileSearchSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val localFiles = dataStore.data.map { it.fileSearch.localFiles }.asLiveData()
+ val localFiles = dataStore.data.map { it.fileSearch.localFiles }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setLocalFiles(localFiles: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -61,7 +63,8 @@ class FileSearchSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val nextcloud = dataStore.data.map { it.fileSearch.nextcloud }.asLiveData()
+ val nextcloud = dataStore.data.map { it.fileSearch.nextcloud }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setNextcloud(nextcloud: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -76,7 +79,8 @@ class FileSearchSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val gdrive = dataStore.data.map { it.fileSearch.gdrive }.asLiveData()
+ val gdrive = dataStore.data.map { it.fileSearch.gdrive }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setGdrive(gdrive: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -91,7 +95,8 @@ class FileSearchSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val onedrive = dataStore.data.map { it.fileSearch.onedrive }.asLiveData()
+ val onedrive = dataStore.data.map { it.fileSearch.onedrive }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setOneDrive(onedrive: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -106,7 +111,8 @@ class FileSearchSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val owncloud = dataStore.data.map { it.fileSearch.owncloud }.asLiveData()
+ val owncloud = dataStore.data.map { it.fileSearch.owncloud }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setOwncloud(owncloud: Boolean) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreen.kt
index d44c75eb..d37e7971 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreen.kt
@@ -14,7 +14,6 @@ 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
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreenVM.kt
index f99731c0..44b0d517 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/gestures/GestureSettingsScreenVM.kt
@@ -2,7 +2,6 @@ package de.mm20.launcher2.ui.settings.gestures
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.searchable.SearchableRepository
import de.mm20.launcher2.icons.IconService
@@ -29,8 +28,10 @@ class GestureSettingsScreenVM : ViewModel(), KoinComponent {
private val iconService: IconService by inject()
val hasPermission = permissionsManager.hasPermission(PermissionGroup.Accessibility)
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
val baseLayout = dataStore.data.map { it.layout.baseLayout }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setBaseLayout(baseLayout: Settings.LayoutSettings.Layout) {
viewModelScope.launch {
@@ -43,10 +44,15 @@ class GestureSettingsScreenVM : ViewModel(), KoinComponent {
}
val swipeDown = dataStore.data.map { it.gestures.swipeDown }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
val swipeLeft = dataStore.data.map { it.gestures.swipeLeft }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
val swipeRight = dataStore.data.map { it.gestures.swipeRight }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
val doubleTap = dataStore.data.map { it.gestures.doubleTap }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
val longPress = dataStore.data.map { it.gestures.longPress }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setSwipeDown(action: GestureAction) {
viewModelScope.launch {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/hiddenitems/HiddenItemsSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/hiddenitems/HiddenItemsSettingsScreen.kt
index 186738fa..4b0bb166 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/hiddenitems/HiddenItemsSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/hiddenitems/HiddenItemsSettingsScreen.kt
@@ -9,7 +9,6 @@ import androidx.compose.material.icons.rounded.Visibility
import androidx.compose.material.icons.rounded.VisibilityOff
import androidx.compose.material3.*
import androidx.compose.runtime.*
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
@@ -31,8 +30,8 @@ fun HiddenItemsSettingsScreen() {
val context = LocalContext.current
val density = LocalDensity.current
- val apps by viewModel.allApps.observeAsState(emptyList())
- val other by viewModel.hiddenItems.observeAsState(emptyList())
+ val apps by viewModel.allApps.collectAsState()
+ val other by viewModel.hiddenItems.collectAsState()
PreferenceScreen(title = stringResource(R.string.preference_hidden_items)) {
items(apps, key = { it.key }) { searchable ->
val icon by remember(searchable.key) {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/hiddenitems/HiddenItemsSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/hiddenitems/HiddenItemsSettingsScreenVM.kt
index a13a32bf..8d58bfff 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/hiddenitems/HiddenItemsSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/hiddenitems/HiddenItemsSettingsScreenVM.kt
@@ -5,10 +5,8 @@ import android.content.Context
import android.content.pm.LauncherApps
import android.os.Bundle
import androidx.core.content.getSystemService
-import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
-import androidx.lifecycle.liveData
+import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.applications.AppRepository
import de.mm20.launcher2.searchable.SearchableRepository
import de.mm20.launcher2.icons.IconService
@@ -18,8 +16,12 @@ import de.mm20.launcher2.search.SavableSearchable
import de.mm20.launcher2.search.data.LauncherApp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.first
+import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.withContext
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -31,11 +33,11 @@ class HiddenItemsSettingsScreenVM : ViewModel(), KoinComponent {
val allApps = appRepository.getAllInstalledApps().map {
withContext(Dispatchers.Default) { it.sorted() }
- }.asLiveData()
- val hiddenItems: LiveData> = liveData {
+ }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
+ val hiddenItems: StateFlow> = flow {
val hidden = searchableRepository.get(hidden = true).first().filter { it !is LauncherApp }.sorted()
emit(hidden)
- }
+ }.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
fun isHidden(searchable: SavableSearchable): Flow {
return searchableRepository.isHidden(searchable)
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreen.kt
index a4a83451..02a3e47c 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreen.kt
@@ -55,8 +55,8 @@ fun HomescreenSettingsScreen() {
val bottomSearchBar by viewModel.bottomSearchBar.collectAsStateWithLifecycle(null)
val fixedSearchBar by viewModel.fixedSearchBar.collectAsStateWithLifecycle(null)
val lightStatusBar by viewModel.statusBarIcons.collectAsStateWithLifecycle(null)
- val dimWallpaper by viewModel.dimWallpaper.collectAsStateWithLifecycle(false)
- val blurWallpaper by viewModel.blurWallpaper.collectAsStateWithLifecycle(false)
+ val dimWallpaper by viewModel.dimWallpaper.collectAsStateWithLifecycle()
+ val blurWallpaper by viewModel.blurWallpaper.collectAsStateWithLifecycle()
val lightNavBar by viewModel.navBarIcons.collectAsStateWithLifecycle(null)
val hideStatusBar by viewModel.hideStatusBar.collectAsStateWithLifecycle(null)
val hideNavBar by viewModel.hideNavBar.collectAsStateWithLifecycle(null)
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreenVM.kt
index 0baf3c1b..19b1113e 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/homescreen/HomescreenSettingsScreenVM.kt
@@ -6,14 +6,15 @@ import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.getSystemService
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.initializer
import androidx.lifecycle.viewmodel.viewModelFactory
import de.mm20.launcher2.ktx.isAtLeastApiLevel
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.get
@@ -24,6 +25,7 @@ class HomescreenSettingsScreenVM(
val dimWallpaper = dataStore.data.map { it.appearance.dimWallpaper }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
fun setDimWallpaper(dimWallpaper: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -37,6 +39,7 @@ class HomescreenSettingsScreenVM(
}
val blurWallpaper = dataStore.data.map { it.appearance.blurWallpaper }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
fun setBlurWallpaper(blurWallpaper: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -59,6 +62,7 @@ class HomescreenSettingsScreenVM(
}
val statusBarIcons = dataStore.data.map { it.systemBars.statusBarColor }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setLightStatusBar(statusBarColor: Settings.SystemBarsSettings.SystemBarColors) {
viewModelScope.launch {
dataStore.updateData {
@@ -73,6 +77,7 @@ class HomescreenSettingsScreenVM(
}
val navBarIcons = dataStore.data.map { it.systemBars.navBarColor }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setLightNavBar(navBarColors: Settings.SystemBarsSettings.SystemBarColors) {
viewModelScope.launch {
dataStore.updateData {
@@ -87,6 +92,7 @@ class HomescreenSettingsScreenVM(
}
val hideStatusBar = dataStore.data.map { it.systemBars.hideStatusBar }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setHideStatusBar(hideStatusBar: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -101,6 +107,7 @@ class HomescreenSettingsScreenVM(
}
val hideNavBar = dataStore.data.map { it.systemBars.hideNavBar }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setHideNavBar(hideNavBar: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -115,6 +122,7 @@ class HomescreenSettingsScreenVM(
}
val searchBarColor = dataStore.data.map { it.searchBar.color }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setSearchBarColor(color: Settings.SearchBarSettings.SearchBarColors) {
viewModelScope.launch {
dataStore.updateData {
@@ -128,9 +136,8 @@ class HomescreenSettingsScreenVM(
}
}
-
-
val searchBarStyle = dataStore.data.map { it.searchBar.searchBarStyle }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setSearchBarStyle(searchBarStyle: Settings.SearchBarSettings.SearchBarStyle) {
viewModelScope.launch {
dataStore.updateData {
@@ -145,6 +152,7 @@ class HomescreenSettingsScreenVM(
}
val fixedSearchBar = dataStore.data.map { it.layout.fixedSearchBar }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setFixedSearchBar(fixedSearchBar: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -156,6 +164,7 @@ class HomescreenSettingsScreenVM(
}
val bottomSearchBar = dataStore.data.map { it.layout.bottomSearchBar }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setBottomSearchBar(bottomSearchBar: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -167,6 +176,7 @@ class HomescreenSettingsScreenVM(
}
val fixedRotation = dataStore.data.map { it.layout.fixedRotation }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setFixedRotation(fixedRotation: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -178,6 +188,7 @@ class HomescreenSettingsScreenVM(
}
val widgetEditButton = dataStore.data.map { it.widgets.editButton }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setWidgetEditButton(editButton: Boolean) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/integrations/IntegrationsSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/integrations/IntegrationsSettingsScreenVM.kt
index 67e510e2..4520e570 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/integrations/IntegrationsSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/integrations/IntegrationsSettingsScreenVM.kt
@@ -2,7 +2,6 @@ package de.mm20.launcher2.ui.settings.integrations
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.mutableStateOf
-import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.accounts.Account
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/license/LicenseScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/license/LicenseScreen.kt
index 037e186b..ef3448bf 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/license/LicenseScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/license/LicenseScreen.kt
@@ -11,8 +11,8 @@ import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material.icons.rounded.OpenInBrowser
import androidx.compose.material3.*
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.input.nestedscroll.nestedScroll
@@ -102,7 +102,7 @@ fun LicenseScreen(library: OpenSourceLibrary) {
style = MaterialTheme.typography.bodySmall
)
}
- val licenseText by viewModel.getLicenseText(library).observeAsState()
+ val licenseText by viewModel.getLicenseText(library).collectAsState(null)
licenseText?.let {
Text(
text = it,
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/license/LicenseScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/license/LicenseScreenVM.kt
index cf6118cf..68be7d16 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/license/LicenseScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/license/LicenseScreenVM.kt
@@ -2,13 +2,13 @@ package de.mm20.launcher2.ui.settings.license
import android.app.Application
import androidx.lifecycle.AndroidViewModel
-import androidx.lifecycle.liveData
import de.mm20.launcher2.licenses.OpenSourceLibrary
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.withContext
class LicenseScreenVM(private val context: Application) : AndroidViewModel(context) {
- fun getLicenseText(library: OpenSourceLibrary) = liveData {
+ fun getLicenseText(library: OpenSourceLibrary) = flow {
val text = withContext(Dispatchers.IO) {
context.resources.openRawResource(library.licenseText).reader()
.readText()
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/media/MediaIntegrationSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/media/MediaIntegrationSettingsScreen.kt
index d767142c..38146981 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/media/MediaIntegrationSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/media/MediaIntegrationSettingsScreen.kt
@@ -9,7 +9,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
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.platform.LocalDensity
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt
index 67023279..871e7e7b 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreen.kt
@@ -7,7 +7,6 @@ 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
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreenVM.kt
index ee69276e..5715c138 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/search/SearchSettingsScreenVM.kt
@@ -2,14 +2,15 @@ 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 de.mm20.launcher2.preferences.Settings
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -19,6 +20,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
private val permissionsManager: PermissionsManager by inject()
val favorites = dataStore.data.map { it.favorites.enabled }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setFavorites(favorites: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -31,7 +33,10 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
val hasContactsPermission = permissionsManager.hasPermission(PermissionGroup.Contacts)
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
val contacts = dataStore.data.map { it.contactsSearch.enabled }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
+
fun setContacts(contacts: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -47,7 +52,9 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
}
val hasCalendarPermission = permissionsManager.hasPermission(PermissionGroup.Calendar)
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
val calendar = dataStore.data.map { it.calendarSearch.enabled }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setCalendar(calendar: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -63,6 +70,8 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
}
val calculator = dataStore.data.map { it.calculatorSearch.enabled }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
+
fun setCalculator(calculator: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -74,6 +83,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
}
val unitConverter = dataStore.data.map { it.unitConverterSearch.enabled }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setUnitConverter(unitConverter: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -85,6 +95,8 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
}
val wikipedia = dataStore.data.map { it.wikipediaSearch.enabled }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
+
fun setWikipedia(wikipedia: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -96,6 +108,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
}
val websites = dataStore.data.map { it.websiteSearch.enabled }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setWebsites(websites: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -106,18 +119,8 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val webSearch = dataStore.data.map { it.webSearch.enabled }
- fun setWebSearch(webSearch: Boolean) {
- viewModelScope.launch {
- dataStore.updateData {
- it.toBuilder().setWebSearch(
- it.webSearch.toBuilder().setEnabled(webSearch)
- ).build()
- }
- }
- }
-
val autoFocus = dataStore.data.map { it.searchBar.autoFocus }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setAutoFocus(autoFocus: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -129,6 +132,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
}
val launchOnEnter = dataStore.data.map { it.searchBar.launchOnEnter }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setLaunchOnEnter(launchOnEnter: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -140,7 +144,9 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
}
val hasAppShortcutPermission = permissionsManager.hasPermission(PermissionGroup.AppShortcuts)
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
val appShortcuts = dataStore.data.map { it.appShortcutSearch.enabled }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setAppShortcuts(appShortcuts: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -152,6 +158,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
}
val searchResultOrdering = dataStore.data.map { it.resultOrdering.ordering }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setSearchResultOrdering(searchResultOrdering: Settings.SearchResultOrderingSettings.Ordering) {
viewModelScope.launch {
dataStore.updateData {
@@ -164,6 +171,7 @@ class SearchSettingsScreenVM : ViewModel(), KoinComponent {
val reverseSearchResults = dataStore.data.map { it.layout.reverseSearchResults }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setReverseSearchResults(reverseSearchResults: Boolean) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/searchactions/SearchActionsSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/searchactions/SearchActionsSettingsScreen.kt
index c7190cd7..9c2087df 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/searchactions/SearchActionsSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/searchactions/SearchActionsSettingsScreen.kt
@@ -25,8 +25,8 @@ import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
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.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
@@ -69,8 +69,8 @@ fun SearchActionsSettingsScreen() {
onItemMove = { from, to -> viewModel.moveItem(from.index, to.index) }
)
- val searchActions by viewModel.searchActions.observeAsState(emptyList())
- val disabledActions by viewModel.disabledActions.observeAsState(emptyList())
+ val searchActions by viewModel.searchActions.collectAsState()
+ val disabledActions by viewModel.disabledActions.collectAsState()
Scaffold(
floatingActionButton = {
@@ -187,8 +187,8 @@ fun SearchActionsSettingsScreen() {
}
}
- val editAction by viewModel.showEditDialogFor.observeAsState(null)
- val createAction by viewModel.showCreateDialog.observeAsState(false)
+ val editAction by viewModel.showEditDialogFor
+ val createAction by viewModel.showCreateDialog
if (createAction) {
EditSearchActionSheet(
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/searchactions/SearchActionsSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/searchactions/SearchActionsSettingsScreenVM.kt
index f68e2d69..5619813f 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/searchactions/SearchActionsSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/searchactions/SearchActionsSettingsScreenVM.kt
@@ -1,13 +1,14 @@
package de.mm20.launcher2.ui.settings.searchactions
-import androidx.lifecycle.MutableLiveData
+import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.searchactions.SearchActionService
import de.mm20.launcher2.searchactions.builders.CustomizableSearchActionBuilder
import de.mm20.launcher2.searchactions.builders.SearchActionBuilder
import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -18,11 +19,11 @@ class SearchActionsSettingsScreenVM : ViewModel(), KoinComponent {
val searchActions = searchActionService
.getSearchActionBuilders()
- .asLiveData()
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
val disabledActions = searchActionService
.getDisabledActionBuilders()
- .asLiveData()
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), emptyList())
fun addAction(searchAction: SearchActionBuilder) {
val actions =
@@ -60,8 +61,8 @@ class SearchActionsSettingsScreenVM : ViewModel(), KoinComponent {
searchActionService.saveSearchActionBuilders(actions)
}
- val showEditDialogFor = MutableLiveData(null)
- val showCreateDialog = MutableLiveData(false)
+ val showEditDialogFor = mutableStateOf(null)
+ val showCreateDialog = mutableStateOf(false)
fun editAction(action: CustomizableSearchActionBuilder) {
showEditDialogFor.value = action
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/unitconverter/UnitConverterSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/unitconverter/UnitConverterSettingsScreen.kt
index c9f9b8da..ed090fd6 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/unitconverter/UnitConverterSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/unitconverter/UnitConverterSettingsScreen.kt
@@ -1,19 +1,14 @@
package de.mm20.launcher2.ui.settings.unitconverter
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.rounded.Loop
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
-import androidx.compose.ui.platform.LocalContext
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.PreferenceCategory
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
-import de.mm20.launcher2.ui.component.preferences.PreferenceWithSwitch
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
-import de.mm20.launcher2.ui.settings.search.SearchSettingsScreenVM
@Composable
fun UnitConverterSettingsScreen() {
@@ -21,7 +16,7 @@ fun UnitConverterSettingsScreen() {
PreferenceScreen(title = stringResource(R.string.preference_search_unitconverter)) {
item {
PreferenceCategory {
- val unitConverter by viewModel.unitConverter.observeAsState()
+ val unitConverter by viewModel.unitConverter.collectAsState()
SwitchPreference(
title = stringResource(R.string.preference_search_unitconverter),
summary = stringResource(R.string.preference_search_unitconverter_summary),
@@ -30,7 +25,7 @@ fun UnitConverterSettingsScreen() {
viewModel.setUnitConverter(it)
}
)
- val currencyConverter by viewModel.currencyConverter.observeAsState()
+ val currencyConverter by viewModel.currencyConverter.collectAsState()
SwitchPreference(
title = stringResource(R.string.preference_search_currencyconverter),
summary = stringResource(R.string.preference_search_currencyconverter_summary),
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/unitconverter/UnitConverterSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/unitconverter/UnitConverterSettingsScreenVM.kt
index 4cec43a5..16ec997b 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/unitconverter/UnitConverterSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/unitconverter/UnitConverterSettingsScreenVM.kt
@@ -1,10 +1,11 @@
package de.mm20.launcher2.ui.settings.unitconverter
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.preferences.LauncherDataStore
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -13,7 +14,8 @@ class UnitConverterSettingsScreenVM: ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject()
- val unitConverter = dataStore.data.map { it.unitConverterSearch.enabled }.asLiveData()
+ val unitConverter = dataStore.data.map { it.unitConverterSearch.enabled }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setUnitConverter(unitConverter: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -27,7 +29,8 @@ class UnitConverterSettingsScreenVM: ViewModel(), KoinComponent {
}
}
- val currencyConverter = dataStore.data.map { it.unitConverterSearch.currencies }.asLiveData()
+ val currencyConverter = dataStore.data.map { it.unitConverterSearch.currencies }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setCurrencyConverter(currencyConverter: Boolean) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherIntegrationSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherIntegrationSettingsScreen.kt
index b292788c..2292f9cd 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherIntegrationSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherIntegrationSettingsScreen.kt
@@ -4,7 +4,6 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.*
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
@@ -29,7 +28,7 @@ fun WeatherIntegrationSettingsScreen() {
) {
item {
PreferenceCategory {
- val weatherProvider by viewModel.weatherProvider.observeAsState()
+ val weatherProvider by viewModel.weatherProvider.collectAsState()
ListPreference(
title = stringResource(R.string.preference_weather_provider),
items = viewModel.availableProviders.map {
@@ -60,7 +59,7 @@ fun WeatherIntegrationSettingsScreen() {
}
item {
PreferenceCategory(title = stringResource(R.string.preference_category_location)) {
- val hasPermission by viewModel.hasLocationPermission.observeAsState()
+ val hasPermission by viewModel.hasLocationPermission.collectAsState()
AnimatedVisibility(hasPermission == false) {
MissingPermissionBanner(
text = stringResource(R.string.missing_permission_auto_location),
@@ -70,7 +69,7 @@ fun WeatherIntegrationSettingsScreen() {
modifier = Modifier.padding(16.dp)
)
}
- val autoLocation by viewModel.autoLocation.observeAsState(false)
+ val autoLocation by viewModel.autoLocation.collectAsState()
SwitchPreference(
title = stringResource(R.string.preference_automatic_location),
summary = stringResource(R.string.preference_automatic_location_summary),
@@ -79,7 +78,7 @@ fun WeatherIntegrationSettingsScreen() {
viewModel.setAutoLocation(it)
}
)
- val location by viewModel.location.observeAsState()
+ val location by viewModel.location
LocationPreference(
title = stringResource(R.string.preference_location),
value = location,
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherIntegrationSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherIntegrationSettingsScreenVM.kt
index 4455c45f..fadecea1 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherIntegrationSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/weather/WeatherIntegrationSettingsScreenVM.kt
@@ -1,9 +1,8 @@
package de.mm20.launcher2.ui.settings.weather
import androidx.appcompat.app.AppCompatActivity
-import androidx.lifecycle.MutableLiveData
+import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager
@@ -12,9 +11,11 @@ import de.mm20.launcher2.preferences.Settings.WeatherSettings
import de.mm20.launcher2.weather.WeatherLocation
import de.mm20.launcher2.weather.WeatherRepository
import kotlinx.coroutines.*
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -25,7 +26,8 @@ class WeatherIntegrationSettingsScreenVM : ViewModel(), KoinComponent {
val availableProviders = repository.getAvailableProviders()
- val weatherProvider = repository.selectedProvider.asLiveData()
+ val weatherProvider = repository.selectedProvider
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setWeatherProvider(provider: WeatherSettings.WeatherProvider) {
repository.selectProvider(provider)
}
@@ -41,14 +43,16 @@ class WeatherIntegrationSettingsScreenVM : ViewModel(), KoinComponent {
}
}
- val autoLocation = repository.autoLocation.asLiveData()
+ val autoLocation = repository.autoLocation
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), false)
fun setAutoLocation(autoLocation: Boolean) {
repository.setAutoLocation(autoLocation)
}
- val location = MutableLiveData(null)
+ val location = mutableStateOf(null)
- val hasLocationPermission = permissionsManager.hasPermission(PermissionGroup.Location).asLiveData()
+ val hasLocationPermission = permissionsManager.hasPermission(PermissionGroup.Location)
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun requestLocationPermission(activity: AppCompatActivity) {
permissionsManager.requestPermission(activity, PermissionGroup.Location)
@@ -64,7 +68,7 @@ class WeatherIntegrationSettingsScreenVM : ViewModel(), KoinComponent {
if (autoLoc) lastLoc
else loc
}.collectLatest {
- this@WeatherIntegrationSettingsScreenVM.location.postValue(it)
+ this@WeatherIntegrationSettingsScreenVM.location.value = it
}
}
}
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/wikipedia/WikipediaSettingsScreen.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/wikipedia/WikipediaSettingsScreen.kt
index 11a17c06..e78119a0 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/wikipedia/WikipediaSettingsScreen.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/wikipedia/WikipediaSettingsScreen.kt
@@ -1,8 +1,8 @@
package de.mm20.launcher2.ui.settings.wikipedia
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
-import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ui.R
@@ -15,7 +15,7 @@ fun WikipediaSettingsScreen() {
val viewModel: WikipediaSettingsScreenVM = viewModel()
PreferenceScreen(title = stringResource(R.string.preference_search_wikipedia)) {
item {
- val wikipedia by viewModel.wikipedia.observeAsState()
+ val wikipedia by viewModel.wikipedia.collectAsState()
SwitchPreference(
title = stringResource(R.string.preference_search_wikipedia),
summary = stringResource(R.string.preference_search_wikipedia_summary),
@@ -24,7 +24,7 @@ fun WikipediaSettingsScreen() {
viewModel.setWikipedia(it)
}
)
- val images by viewModel.images.observeAsState()
+ val images by viewModel.images.collectAsState()
SwitchPreference(
title = stringResource(R.string.preference_search_wikipedia_pictures),
summary = stringResource(R.string.preference_search_wikipedia_pictures_summary),
@@ -34,7 +34,7 @@ fun WikipediaSettingsScreen() {
viewModel.setImages(it)
}
)
- val customUrl by viewModel.customUrl.observeAsState("")
+ val customUrl by viewModel.customUrl.collectAsState()
TextPreference(
title = stringResource(R.string.preference_wikipedia_customurl),
value = customUrl,
diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/wikipedia/WikipediaSettingsScreenVM.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/wikipedia/WikipediaSettingsScreenVM.kt
index f93997ce..89c32577 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/settings/wikipedia/WikipediaSettingsScreenVM.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/settings/wikipedia/WikipediaSettingsScreenVM.kt
@@ -1,10 +1,11 @@
package de.mm20.launcher2.ui.settings.wikipedia
import androidx.lifecycle.ViewModel
-import androidx.lifecycle.asLiveData
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.preferences.LauncherDataStore
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -12,7 +13,8 @@ import org.koin.core.component.inject
class WikipediaSettingsScreenVM: ViewModel(), KoinComponent {
private val dataStore: LauncherDataStore by inject()
- val wikipedia = dataStore.data.map { it.wikipediaSearch.enabled }.asLiveData()
+ val wikipedia = dataStore.data.map { it.wikipediaSearch.enabled }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setWikipedia(wikipedia: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -26,7 +28,8 @@ class WikipediaSettingsScreenVM: ViewModel(), KoinComponent {
}
}
- val images = dataStore.data.map { it.wikipediaSearch.images }.asLiveData()
+ val images = dataStore.data.map { it.wikipediaSearch.images }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), null)
fun setImages(images: Boolean) {
viewModelScope.launch {
dataStore.updateData {
@@ -40,7 +43,8 @@ class WikipediaSettingsScreenVM: ViewModel(), KoinComponent {
}
}
- val customUrl = dataStore.data.map { it.wikipediaSearch.customUrl }.asLiveData()
+ val customUrl = dataStore.data.map { it.wikipediaSearch.customUrl }
+ .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), "")
fun setCustomUrl(customUrl: String) {
viewModelScope.launch {
dataStore.updateData {
diff --git a/core/database/src/main/java/de/mm20/launcher2/database/IconDao.kt b/core/database/src/main/java/de/mm20/launcher2/database/IconDao.kt
index 38feca44..f45ab415 100644
--- a/core/database/src/main/java/de/mm20/launcher2/database/IconDao.kt
+++ b/core/database/src/main/java/de/mm20/launcher2/database/IconDao.kt
@@ -1,13 +1,10 @@
package de.mm20.launcher2.database
-import androidx.lifecycle.LiveData
import androidx.room.*
import de.mm20.launcher2.database.entities.IconEntity
import de.mm20.launcher2.database.entities.IconPackEntity
import kotlinx.coroutines.flow.Flow
-internal val AppTypes = listOf("app", "calendar", "clock")
-
@Dao
interface IconDao {
@Insert
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 21c7a4e1..0694ddeb 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -37,8 +37,6 @@ dependencyResolutionManagement {
version("androidx.compose.compiler", "1.4.5")
library("androidx.compose.runtime", "androidx.compose.runtime", "runtime")
.version("1.5.0-alpha03")
- library("androidx.compose.livedata", "androidx.compose.runtime", "runtime-livedata")
- .version("1.5.0-alpha03")
library("androidx.compose.foundation", "androidx.compose.foundation", "foundation")
.version("1.5.0-alpha03")
library("androidx.compose.foundationlayout", "androidx.compose.foundation", "foundation-layout")
@@ -61,8 +59,6 @@ dependencyResolutionManagement {
version("androidx.lifecycle", "2.6.1")
library("androidx.lifecycle.viewmodel", "androidx.lifecycle", "lifecycle-viewmodel-ktx")
.versionRef("androidx.lifecycle")
- library("androidx.lifecycle.livedata", "androidx.lifecycle", "lifecycle-livedata-ktx")
- .versionRef("androidx.lifecycle")
library("androidx.lifecycle.common", "androidx.lifecycle", "lifecycle-common-java8")
.versionRef("androidx.lifecycle")
library("androidx.lifecycle.runtime", "androidx.lifecycle", "lifecycle-runtime-ktx")
@@ -75,7 +71,6 @@ dependencyResolutionManagement {
"androidx.lifecycle",
listOf(
"androidx.lifecycle.viewmodel",
- "androidx.lifecycle.livedata",
"androidx.lifecycle.common",
"androidx.lifecycle.runtime"
)