Add favorites widget

This commit is contained in:
MM20 2022-03-30 22:29:20 +02:00
parent a86d453f4e
commit 0b7704cdf2
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
7 changed files with 82 additions and 2 deletions

View File

@ -204,6 +204,7 @@
<string name="widget_name_weather">Weather</string>
<string name="widget_name_calendar">Calendar</string>
<string name="widget_name_music">Music</string>
<string name="widget_name_favorites">Favorites</string>
<string name="widget_add_widget">Add widget</string>
<!-- Add a third party widget (=a standard Android app widget) -->
<string name="widget_add_external">More</string>

View File

@ -7,6 +7,8 @@ import de.mm20.launcher2.ui.component.ProvideIconShape
import de.mm20.launcher2.ui.locals.LocalCardStyle
import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled
import de.mm20.launcher2.ui.locals.LocalGridColumns
import de.mm20.launcher2.widgets.WidgetRepository
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map
import org.koin.androidx.compose.inject
@ -16,6 +18,7 @@ fun ProvideSettings(
content: @Composable () -> Unit
) {
val dataStore: LauncherDataStore by inject()
val widgetRepository: WidgetRepository by inject()
val cardStyle by remember {
dataStore.data.map { it.cards }.distinctUntilChanged()
@ -30,7 +33,10 @@ fun ProvideSettings(
}.collectAsState(Settings.IconSettings.IconShape.Circle)
val favoritesEnabled by remember {
dataStore.data.map { it.favorites.enabled }.distinctUntilChanged()
combine(
widgetRepository.isFavoritesWidgetEnabled(),
dataStore.data.map { it.favorites.enabled }
) { a, b -> a || b }.distinctUntilChanged()
}.collectAsState(true)
val gridColumns by remember {

View File

@ -25,6 +25,7 @@ import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.LauncherCard
import de.mm20.launcher2.ui.launcher.widgets.calendar.CalendarWidget
import de.mm20.launcher2.ui.launcher.widgets.external.ExternalWidget
import de.mm20.launcher2.ui.launcher.widgets.favorites.FavoritesWidget
import de.mm20.launcher2.ui.launcher.widgets.music.MusicWidget
import de.mm20.launcher2.ui.launcher.widgets.weather.WeatherWidget
import de.mm20.launcher2.widgets.*
@ -120,6 +121,9 @@ fun WidgetItem(
is CalendarWidget -> {
CalendarWidget()
}
is FavoritesWidget -> {
FavoritesWidget()
}
is ExternalWidget -> {
var height by remember(widget) { mutableStateOf(widget.height) }
Column {

View File

@ -0,0 +1,15 @@
package de.mm20.launcher2.ui.launcher.widgets.favorites
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ui.launcher.search.common.grid.SearchResultGrid
@Composable
fun FavoritesWidget() {
val viewModel: FavoritesWidgetVM = viewModel()
val favorites by viewModel.favorites.observeAsState(emptyList())
SearchResultGrid(favorites)
}

View File

@ -0,0 +1,30 @@
package de.mm20.launcher2.ui.launcher.widgets.favorites
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.favorites.FavoritesRepository
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.widgets.WidgetRepository
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
class FavoritesWidgetVM: ViewModel(), KoinComponent {
private val favoritesRepository: FavoritesRepository by inject()
private val widgetRepository: WidgetRepository by inject()
val favorites = MutableLiveData<List<Searchable>>(emptyList())
init {
viewModelScope.launch {
widgetRepository.isCalendarWidgetEnabled().collectLatest { excludeCalendar ->
favoritesRepository.getFavorites(excludeCalendarEvents = excludeCalendar).collectLatest {
favorites.value = it
}
}
}
}
}

View File

@ -24,6 +24,7 @@ sealed class Widget {
"weather" -> WeatherWidget
"music" -> MusicWidget
"calendar" -> CalendarWidget
"favorites" -> FavoritesWidget
else -> null
}
} else {
@ -132,6 +133,24 @@ object CalendarWidget : Widget() {
}
}
object FavoritesWidget : Widget() {
override fun loadLabel(context: Context): String {
return context.getString(R.string.widget_name_favorites)
}
override fun toDatabaseEntity(position: Int): WidgetEntity {
return WidgetEntity(
type = WidgetType.INTERNAL.value,
data = "favorites",
height = -1,
position = position
)
}
override val isConfigurable: Boolean = false
}
class ExternalWidget(
var height: Int,
val widgetId: Int,

View File

@ -14,6 +14,7 @@ interface WidgetRepository {
fun removeWidget(widget: Widget)
fun setWidgetHeight(widget: Widget, newHeight: Int)
fun isCalendarWidgetEnabled(): Flow<Boolean>
fun isFavoritesWidgetEnabled(): Flow<Boolean>
}
internal class WidgetRepositoryImpl(
@ -30,7 +31,7 @@ internal class WidgetRepositoryImpl(
}
override fun getInternalWidgets(): List<Widget> {
return listOf(WeatherWidget, MusicWidget, CalendarWidget)
return listOf(WeatherWidget, MusicWidget, CalendarWidget, FavoritesWidget)
}
@ -81,4 +82,8 @@ internal class WidgetRepositoryImpl(
return database.widgetDao().exists("internal", "calendar")
}
override fun isFavoritesWidgetEnabled(): Flow<Boolean> {
return database.widgetDao().exists("internal", "favorites")
}
}