Bringup notes widget
This commit is contained in:
parent
e17c8d0f63
commit
d98dcdf286
@ -74,6 +74,7 @@ import de.mm20.launcher2.widgets.AppWidget
|
|||||||
import de.mm20.launcher2.widgets.CalendarWidget
|
import de.mm20.launcher2.widgets.CalendarWidget
|
||||||
import de.mm20.launcher2.widgets.FavoritesWidget
|
import de.mm20.launcher2.widgets.FavoritesWidget
|
||||||
import de.mm20.launcher2.widgets.MusicWidget
|
import de.mm20.launcher2.widgets.MusicWidget
|
||||||
|
import de.mm20.launcher2.widgets.NotesWidget
|
||||||
import de.mm20.launcher2.widgets.WeatherWidget
|
import de.mm20.launcher2.widgets.WeatherWidget
|
||||||
import de.mm20.launcher2.widgets.Widget
|
import de.mm20.launcher2.widgets.Widget
|
||||||
import org.koin.androidx.compose.get
|
import org.koin.androidx.compose.get
|
||||||
@ -110,6 +111,7 @@ fun ConfigureWidgetSheet(
|
|||||||
is CalendarWidget -> ConfigureCalendarWidget(widget, onWidgetUpdated)
|
is CalendarWidget -> ConfigureCalendarWidget(widget, onWidgetUpdated)
|
||||||
is FavoritesWidget -> ConfigureFavoritesWidget(widget, onWidgetUpdated)
|
is FavoritesWidget -> ConfigureFavoritesWidget(widget, onWidgetUpdated)
|
||||||
is MusicWidget -> ConfigureMusicWidget()
|
is MusicWidget -> ConfigureMusicWidget()
|
||||||
|
is NotesWidget -> ConfigureNotesWidget(widget, onWidgetUpdated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,6 +306,7 @@ fun ColumnScope.ConfigureAppWidget(
|
|||||||
is MusicWidget -> it.copy(id = widget.id)
|
is MusicWidget -> it.copy(id = widget.id)
|
||||||
is CalendarWidget -> it.copy(id = widget.id)
|
is CalendarWidget -> it.copy(id = widget.id)
|
||||||
is FavoritesWidget -> it.copy(id = widget.id)
|
is FavoritesWidget -> it.copy(id = widget.id)
|
||||||
|
is NotesWidget -> it.copy(id = widget.id)
|
||||||
}
|
}
|
||||||
onWidgetUpdated(updatedWidget)
|
onWidgetUpdated(updatedWidget)
|
||||||
replaceWidget = false
|
replaceWidget = false
|
||||||
@ -537,4 +540,12 @@ fun ColumnScope.ConfigureCalendarWidget(
|
|||||||
text = stringResource(R.string.widget_config_calendar_no_calendars)
|
text = stringResource(R.string.widget_config_calendar_no_calendars)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun ConfigureNotesWidget(
|
||||||
|
widget: NotesWidget,
|
||||||
|
onWidgetUpdated: (NotesWidget) -> Unit
|
||||||
|
) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -30,6 +30,7 @@ import androidx.compose.material.icons.rounded.LightMode
|
|||||||
import androidx.compose.material.icons.rounded.MusicNote
|
import androidx.compose.material.icons.rounded.MusicNote
|
||||||
import androidx.compose.material.icons.rounded.Search
|
import androidx.compose.material.icons.rounded.Search
|
||||||
import androidx.compose.material.icons.rounded.Star
|
import androidx.compose.material.icons.rounded.Star
|
||||||
|
import androidx.compose.material.icons.rounded.StickyNote2
|
||||||
import androidx.compose.material.icons.rounded.Today
|
import androidx.compose.material.icons.rounded.Today
|
||||||
import androidx.compose.material.icons.rounded.Widgets
|
import androidx.compose.material.icons.rounded.Widgets
|
||||||
import androidx.compose.material.icons.rounded.Work
|
import androidx.compose.material.icons.rounded.Work
|
||||||
@ -64,6 +65,7 @@ import de.mm20.launcher2.widgets.AppWidget
|
|||||||
import de.mm20.launcher2.widgets.AppWidgetConfig
|
import de.mm20.launcher2.widgets.AppWidgetConfig
|
||||||
import de.mm20.launcher2.widgets.FavoritesWidget
|
import de.mm20.launcher2.widgets.FavoritesWidget
|
||||||
import de.mm20.launcher2.widgets.MusicWidget
|
import de.mm20.launcher2.widgets.MusicWidget
|
||||||
|
import de.mm20.launcher2.widgets.NotesWidget
|
||||||
import de.mm20.launcher2.widgets.WeatherWidget
|
import de.mm20.launcher2.widgets.WeatherWidget
|
||||||
import de.mm20.launcher2.widgets.Widget
|
import de.mm20.launcher2.widgets.Widget
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@ -287,6 +289,7 @@ fun WidgetPickerSheet(
|
|||||||
CalendarWidget.Type -> CalendarWidget(id)
|
CalendarWidget.Type -> CalendarWidget(id)
|
||||||
MusicWidget.Type -> MusicWidget(id)
|
MusicWidget.Type -> MusicWidget(id)
|
||||||
FavoritesWidget.Type -> FavoritesWidget(id)
|
FavoritesWidget.Type -> FavoritesWidget(id)
|
||||||
|
NotesWidget.Type -> NotesWidget(id)
|
||||||
else -> return@OutlinedCard
|
else -> return@OutlinedCard
|
||||||
}
|
}
|
||||||
onWidgetSelected(widget)
|
onWidgetSelected(widget)
|
||||||
@ -302,6 +305,7 @@ fun WidgetPickerSheet(
|
|||||||
CalendarWidget.Type -> Icons.Rounded.Today
|
CalendarWidget.Type -> Icons.Rounded.Today
|
||||||
MusicWidget.Type -> Icons.Rounded.MusicNote
|
MusicWidget.Type -> Icons.Rounded.MusicNote
|
||||||
FavoritesWidget.Type -> Icons.Rounded.Star
|
FavoritesWidget.Type -> Icons.Rounded.Star
|
||||||
|
NotesWidget.Type -> Icons.Rounded.StickyNote2
|
||||||
else -> Icons.Rounded.Widgets
|
else -> Icons.Rounded.Widgets
|
||||||
},
|
},
|
||||||
contentDescription = null,
|
contentDescription = null,
|
||||||
|
|||||||
@ -45,11 +45,13 @@ 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.external.ExternalWidget
|
||||||
import de.mm20.launcher2.ui.launcher.widgets.favorites.FavoritesWidget
|
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.music.MusicWidget
|
||||||
|
import de.mm20.launcher2.ui.launcher.widgets.notes.NotesWidget
|
||||||
import de.mm20.launcher2.ui.launcher.widgets.weather.WeatherWidget
|
import de.mm20.launcher2.ui.launcher.widgets.weather.WeatherWidget
|
||||||
import de.mm20.launcher2.widgets.AppWidget
|
import de.mm20.launcher2.widgets.AppWidget
|
||||||
import de.mm20.launcher2.widgets.CalendarWidget
|
import de.mm20.launcher2.widgets.CalendarWidget
|
||||||
import de.mm20.launcher2.widgets.FavoritesWidget
|
import de.mm20.launcher2.widgets.FavoritesWidget
|
||||||
import de.mm20.launcher2.widgets.MusicWidget
|
import de.mm20.launcher2.widgets.MusicWidget
|
||||||
|
import de.mm20.launcher2.widgets.NotesWidget
|
||||||
import de.mm20.launcher2.widgets.WeatherWidget
|
import de.mm20.launcher2.widgets.WeatherWidget
|
||||||
import de.mm20.launcher2.widgets.Widget
|
import de.mm20.launcher2.widgets.Widget
|
||||||
|
|
||||||
@ -107,6 +109,7 @@ fun WidgetItem(
|
|||||||
is MusicWidget -> stringResource(R.string.widget_name_music)
|
is MusicWidget -> stringResource(R.string.widget_name_music)
|
||||||
is CalendarWidget -> stringResource(R.string.widget_name_calendar)
|
is CalendarWidget -> stringResource(R.string.widget_name_calendar)
|
||||||
is FavoritesWidget -> stringResource(R.string.widget_name_favorites)
|
is FavoritesWidget -> stringResource(R.string.widget_name_favorites)
|
||||||
|
is NotesWidget -> stringResource(R.string.widget_name_notes)
|
||||||
is AppWidget -> remember(widget.config.widgetId) {
|
is AppWidget -> remember(widget.config.widgetId) {
|
||||||
appWidget?.loadLabel(
|
appWidget?.loadLabel(
|
||||||
context.packageManager
|
context.packageManager
|
||||||
@ -155,6 +158,10 @@ fun WidgetItem(
|
|||||||
FavoritesWidget(widget)
|
FavoritesWidget(widget)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is NotesWidget -> {
|
||||||
|
NotesWidget(widget)
|
||||||
|
}
|
||||||
|
|
||||||
is AppWidget -> {
|
is AppWidget -> {
|
||||||
val widgetInfo = remember(widget.config.widgetId) {
|
val widgetInfo = remember(widget.config.widgetId) {
|
||||||
AppWidgetManager.getInstance(context)
|
AppWidgetManager.getInstance(context)
|
||||||
@ -193,6 +200,7 @@ fun WidgetItem(
|
|||||||
is MusicWidget -> it.copy(id = widget.id)
|
is MusicWidget -> it.copy(id = widget.id)
|
||||||
is CalendarWidget -> it.copy(id = widget.id)
|
is CalendarWidget -> it.copy(id = widget.id)
|
||||||
is FavoritesWidget -> it.copy(id = widget.id)
|
is FavoritesWidget -> it.copy(id = widget.id)
|
||||||
|
is NotesWidget -> it.copy(id = widget.id)
|
||||||
}
|
}
|
||||||
onWidgetUpdate(updatedWidget)
|
onWidgetUpdate(updatedWidget)
|
||||||
replaceWidget = false
|
replaceWidget = false
|
||||||
|
|||||||
@ -0,0 +1,37 @@
|
|||||||
|
package de.mm20.launcher2.ui.launcher.widgets.notes
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.text.BasicTextField
|
||||||
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.graphics.SolidColor
|
||||||
|
import androidx.compose.ui.text.input.TextFieldValue
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
|
import de.mm20.launcher2.widgets.NotesWidget
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun NotesWidget(widget: NotesWidget) {
|
||||||
|
val viewModel: NotesWidgetVM = viewModel(key = "notes-widget-${widget.id}", factory = NotesWidgetVM.Factory)
|
||||||
|
|
||||||
|
LaunchedEffect(widget) {
|
||||||
|
viewModel.updateWidget(widget)
|
||||||
|
}
|
||||||
|
|
||||||
|
val text by viewModel.noteText
|
||||||
|
|
||||||
|
BasicTextField(
|
||||||
|
value = text,
|
||||||
|
onValueChange = { viewModel.setText(it) },
|
||||||
|
modifier = Modifier.fillMaxWidth().padding(16.dp),
|
||||||
|
textStyle = MaterialTheme.typography.bodyMedium.copy(
|
||||||
|
color = LocalContentColor.current,
|
||||||
|
),
|
||||||
|
cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
|
||||||
|
)
|
||||||
|
}
|
||||||
@ -0,0 +1,48 @@
|
|||||||
|
package de.mm20.launcher2.ui.launcher.widgets.notes
|
||||||
|
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import androidx.lifecycle.viewmodel.initializer
|
||||||
|
import androidx.lifecycle.viewmodel.viewModelFactory
|
||||||
|
import de.mm20.launcher2.services.widgets.WidgetsService
|
||||||
|
import de.mm20.launcher2.widgets.NotesWidget
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import org.koin.core.component.KoinComponent
|
||||||
|
import org.koin.core.component.get
|
||||||
|
|
||||||
|
class NotesWidgetVM(
|
||||||
|
private val widgetsService: WidgetsService,
|
||||||
|
) : ViewModel() {
|
||||||
|
private val widget = MutableStateFlow<NotesWidget?>(null)
|
||||||
|
|
||||||
|
val noteText = mutableStateOf(widget.value?.config?.storedText ?: "")
|
||||||
|
|
||||||
|
fun updateWidget(widget: NotesWidget) {
|
||||||
|
val oldId = this.widget.value?.id
|
||||||
|
this.widget.value = widget
|
||||||
|
if (widget.id != oldId) noteText.value = widget.config.storedText
|
||||||
|
}
|
||||||
|
|
||||||
|
private var updateJob: Job? = null
|
||||||
|
fun setText(text: String) {
|
||||||
|
noteText.value = text
|
||||||
|
updateJob?.cancel()
|
||||||
|
val widget = widget.value ?: return
|
||||||
|
updateJob = viewModelScope.launch {
|
||||||
|
delay(1000)
|
||||||
|
widgetsService.updateWidget(widget.copy(config = widget.config.copy(storedText = text)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object: KoinComponent {
|
||||||
|
val Factory = viewModelFactory {
|
||||||
|
initializer {
|
||||||
|
NotesWidgetVM(get())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -219,6 +219,7 @@
|
|||||||
<string name="widget_name_calendar">Calendar</string>
|
<string name="widget_name_calendar">Calendar</string>
|
||||||
<string name="widget_name_music">Music</string>
|
<string name="widget_name_music">Music</string>
|
||||||
<string name="widget_name_favorites">Favorites</string>
|
<string name="widget_name_favorites">Favorites</string>
|
||||||
|
<string name="widget_name_notes">Note</string>
|
||||||
<string name="widget_name_unknown">Unknown app widget</string>
|
<string name="widget_name_unknown">Unknown app widget</string>
|
||||||
<string name="widget_add_widget">Add widget</string>
|
<string name="widget_add_widget">Add widget</string>
|
||||||
<!-- Add a third party widget (=a standard Android app widget) -->
|
<!-- Add a third party widget (=a standard Android app widget) -->
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
package de.mm20.launcher2.widgets
|
||||||
|
|
||||||
|
import de.mm20.launcher2.database.entities.PartialWidgetEntity
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class NotesWidgetConfig(
|
||||||
|
val storedText: String = "",
|
||||||
|
val quickActions: Boolean = true,
|
||||||
|
)
|
||||||
|
|
||||||
|
data class NotesWidget(
|
||||||
|
override val id: UUID,
|
||||||
|
val config: NotesWidgetConfig = NotesWidgetConfig(),
|
||||||
|
) : Widget() {
|
||||||
|
|
||||||
|
override fun toDatabaseEntity(): PartialWidgetEntity {
|
||||||
|
return PartialWidgetEntity(
|
||||||
|
id = id,
|
||||||
|
type = Type,
|
||||||
|
config = Json.encodeToString(config),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val Type = "notes"
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -54,6 +54,12 @@ sealed class Widget {
|
|||||||
config,
|
config,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
NotesWidget.Type -> {
|
||||||
|
val config: NotesWidgetConfig =
|
||||||
|
Json.decodeFromStringOrNull(entity.config?.takeIf { it.isNotBlank() })
|
||||||
|
?: NotesWidgetConfig()
|
||||||
|
NotesWidget(entity.id, config)
|
||||||
|
}
|
||||||
|
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import androidx.core.content.getSystemService
|
|||||||
import de.mm20.launcher2.widgets.CalendarWidget
|
import de.mm20.launcher2.widgets.CalendarWidget
|
||||||
import de.mm20.launcher2.widgets.FavoritesWidget
|
import de.mm20.launcher2.widgets.FavoritesWidget
|
||||||
import de.mm20.launcher2.widgets.MusicWidget
|
import de.mm20.launcher2.widgets.MusicWidget
|
||||||
|
import de.mm20.launcher2.widgets.NotesWidget
|
||||||
import de.mm20.launcher2.widgets.WeatherWidget
|
import de.mm20.launcher2.widgets.WeatherWidget
|
||||||
import de.mm20.launcher2.widgets.Widget
|
import de.mm20.launcher2.widgets.Widget
|
||||||
import de.mm20.launcher2.widgets.WidgetRepository
|
import de.mm20.launcher2.widgets.WidgetRepository
|
||||||
@ -56,6 +57,10 @@ class WidgetsService(
|
|||||||
type = FavoritesWidget.Type,
|
type = FavoritesWidget.Type,
|
||||||
label = context.getString(R.string.widget_name_favorites),
|
label = context.getString(R.string.widget_name_favorites),
|
||||||
),
|
),
|
||||||
|
BuiltInWidgetInfo(
|
||||||
|
type = NotesWidget.Type,
|
||||||
|
label = context.getString(R.string.widget_name_notes),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,6 +68,10 @@ class WidgetsService(
|
|||||||
widgetRepository.create(widget, position, parentId)
|
widgetRepository.create(widget, position, parentId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun updateWidget(widget: Widget) {
|
||||||
|
widgetRepository.update(widget)
|
||||||
|
}
|
||||||
|
|
||||||
fun getWidgets() = widgetRepository.get()
|
fun getWidgets() = widgetRepository.get()
|
||||||
|
|
||||||
fun isFavoritesWidgetFirst(): Flow<Boolean> {
|
fun isFavoritesWidgetFirst(): Flow<Boolean> {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user