Migrate calendar widget settings
This commit is contained in:
parent
5834e7e8c4
commit
a5cb2e3314
@ -5,7 +5,6 @@ import android.os.Bundle
|
||||
import android.view.MenuItem
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import de.mm20.launcher2.fragment.PreferencesCalendarFragment
|
||||
import de.mm20.launcher2.fragment.PreferencesMainFragment
|
||||
import de.mm20.launcher2.fragment.PreferencesServicesFragment
|
||||
import de.mm20.launcher2.fragment.PreferencesWeatherFragment
|
||||
@ -31,7 +30,6 @@ class SettingsActivity : AppCompatActivity() {
|
||||
|
||||
private fun getStartFragment(): Fragment {
|
||||
return when (intent.extras?.getString(FRAGMENT, "")) {
|
||||
FRAGMENT_CALENDAR -> PreferencesCalendarFragment()
|
||||
FRAGMENT_WEATHER -> PreferencesWeatherFragment()
|
||||
FRAGMENT_SERVICES -> PreferencesServicesFragment()
|
||||
else -> PreferencesMainFragment()
|
||||
|
||||
@ -1,121 +0,0 @@
|
||||
package de.mm20.launcher2.fragment
|
||||
|
||||
import android.Manifest
|
||||
import android.content.res.ColorStateList
|
||||
import android.os.Bundle
|
||||
import android.widget.CheckBox
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.ScrollView
|
||||
import android.widget.TextView
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.setPadding
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.afollestad.materialdialogs.bottomsheets.BottomSheet
|
||||
import com.afollestad.materialdialogs.customview.customView
|
||||
import de.mm20.launcher2.R
|
||||
import de.mm20.launcher2.ktx.checkPermission
|
||||
import de.mm20.launcher2.ktx.dp
|
||||
import de.mm20.launcher2.preferences.LauncherPreferences
|
||||
import de.mm20.launcher2.search.data.CalendarEvent
|
||||
import de.mm20.launcher2.search.data.UserCalendar
|
||||
|
||||
class PreferencesCalendarFragment : PreferenceFragmentCompat() {
|
||||
|
||||
private var hasCalendarPermission = false
|
||||
private val calendars = mutableListOf<UserCalendar>()
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
addPreferencesFromResource(R.xml.preferences_calendar)
|
||||
init()
|
||||
}
|
||||
|
||||
|
||||
fun init(requestPermission: Boolean = true) {
|
||||
val context = context ?: return
|
||||
hasCalendarPermission = context.checkPermission(Manifest.permission.READ_CALENDAR)
|
||||
if (hasCalendarPermission) {
|
||||
calendars.clear()
|
||||
calendars.addAll(CalendarEvent.getCalendars(context))
|
||||
val unselectedCalendars = LauncherPreferences.instance.unselectedCalendars.toMutableList()
|
||||
findPreference<Preference>("calendar_calendars")?.apply {
|
||||
var count = calendars.size - unselectedCalendars.size
|
||||
summary = resources.getQuantityString(R.plurals.preference_calendar_calendars_summary, count, count)
|
||||
isEnabled = true
|
||||
setOnPreferenceClickListener {
|
||||
val sheetView = LinearLayout(activity)
|
||||
sheetView.setPadding((8 * context.dp).toInt())
|
||||
sheetView.orientation = LinearLayout.VERTICAL
|
||||
sheetView.setBackgroundColor(ContextCompat.getColor(context, R.color.bottom_sheet))
|
||||
var owner = ""
|
||||
val padding = (8 * context.dp).toInt()
|
||||
for (c in calendars) {
|
||||
if (owner != c.owner) {
|
||||
owner = c.owner
|
||||
val text = TextView(activity)
|
||||
text.setTextColor(ContextCompat.getColor(context, R.color.text_color_secondary_normal))
|
||||
text.setPadding(padding, 2 * padding, padding, padding)
|
||||
text.text = owner
|
||||
sheetView.addView(text)
|
||||
}
|
||||
val checkbox = CheckBox(activity)
|
||||
checkbox.text = c.name
|
||||
checkbox.buttonTintList = ColorStateList.valueOf(CalendarEvent.getDisplayColor(context, c.color))
|
||||
checkbox.setPadding(padding)
|
||||
checkbox.isChecked = !unselectedCalendars.contains(c.id)
|
||||
checkbox.setOnCheckedChangeListener { _, checked ->
|
||||
if (checked) {
|
||||
unselectedCalendars.remove(c.id)
|
||||
} else {
|
||||
unselectedCalendars.add(c.id)
|
||||
}
|
||||
LauncherPreferences.instance.unselectedCalendars = unselectedCalendars
|
||||
count = calendars.size - unselectedCalendars.size
|
||||
summary = resources.getQuantityString(R.plurals.preference_calendar_calendars_summary, count, count)
|
||||
}
|
||||
sheetView.addView(checkbox)
|
||||
}
|
||||
val scrollView = ScrollView(context)
|
||||
scrollView.isNestedScrollingEnabled = true
|
||||
scrollView.addView(sheetView)
|
||||
MaterialDialog(context, BottomSheet()).show {
|
||||
customView(view = scrollView)
|
||||
title(R.string.preference_calendar_calendars)
|
||||
.negativeButton(R.string.close) {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (requestPermission) {
|
||||
ActivityCompat.requestPermissions(
|
||||
requireActivity(),
|
||||
arrayOf(Manifest.permission.READ_CALENDAR, Manifest.permission.WRITE_CALENDAR),
|
||||
0)
|
||||
}
|
||||
findPreference<Preference>("calendar_calendars")?.apply {
|
||||
isEnabled = false
|
||||
setSummary(R.string.preference_permission_denied)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
(activity as AppCompatActivity).supportActionBar?.setTitle(R.string.preference_screen_calendarwidget)
|
||||
hasCalendarPermission = requireActivity().checkPermission(Manifest.permission.READ_CALENDAR)
|
||||
&& requireActivity().checkPermission(Manifest.permission.WRITE_CALENDAR)
|
||||
}
|
||||
|
||||
|
||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
|
||||
init(false)
|
||||
}
|
||||
}
|
||||
@ -34,10 +34,6 @@ class PreferencesMainFragment : PreferenceFragmentCompat() {
|
||||
setSettingsScreen(PreferencesSearchFragment())
|
||||
true
|
||||
}
|
||||
findPreference<Preference>("screen_calendar")?.setOnPreferenceClickListener {
|
||||
setSettingsScreen(PreferencesCalendarFragment())
|
||||
true
|
||||
}
|
||||
findPreference<Preference>("screen_badges")?.setOnPreferenceClickListener {
|
||||
setSettingsScreen(PreferencesBadgesFragment())
|
||||
true
|
||||
|
||||
@ -1,22 +1,21 @@
|
||||
package de.mm20.launcher2.calendar
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ContentUris
|
||||
import android.content.Context
|
||||
import android.provider.CalendarContract
|
||||
import androidx.core.database.getStringOrNull
|
||||
import de.mm20.launcher2.hiddenitems.HiddenItemsRepository
|
||||
import de.mm20.launcher2.ktx.checkPermission
|
||||
import de.mm20.launcher2.permissions.PermissionGroup
|
||||
import de.mm20.launcher2.permissions.PermissionsManager
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import de.mm20.launcher2.preferences.LauncherPreferences
|
||||
import de.mm20.launcher2.search.data.CalendarEvent
|
||||
import de.mm20.launcher2.search.data.UserCalendar
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.channels.trySendBlocking
|
||||
import kotlinx.coroutines.flow.*
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.get
|
||||
import org.koin.core.component.inject
|
||||
import java.util.*
|
||||
|
||||
@ -24,6 +23,8 @@ interface CalendarRepository {
|
||||
fun search(query: String): Flow<List<CalendarEvent>>
|
||||
|
||||
fun getUpcomingEvents(): Flow<List<CalendarEvent>>
|
||||
|
||||
suspend fun getCalendars(): List<UserCalendar>
|
||||
}
|
||||
|
||||
class CalendarRepositoryImpl(
|
||||
@ -155,55 +156,59 @@ class CalendarRepositoryImpl(
|
||||
}
|
||||
|
||||
override fun getUpcomingEvents(): Flow<List<CalendarEvent>> = channelFlow {
|
||||
val unselectedCalendars = callbackFlow {
|
||||
val unregister =
|
||||
LauncherPreferences.instance.doOnPreferenceChange("unselected_calendars") {
|
||||
trySendBlocking(LauncherPreferences.instance.unselectedCalendars)
|
||||
}
|
||||
trySendBlocking(LauncherPreferences.instance.unselectedCalendars)
|
||||
awaitClose {
|
||||
unregister()
|
||||
}
|
||||
}
|
||||
|
||||
val hideAlldayEvents = callbackFlow {
|
||||
val unregister =
|
||||
LauncherPreferences.instance.doOnPreferenceChange("calendar_hide_allday") {
|
||||
trySendBlocking(LauncherPreferences.instance.calendarHideAllday)
|
||||
}
|
||||
trySendBlocking(LauncherPreferences.instance.calendarHideAllday)
|
||||
awaitClose {
|
||||
unregister()
|
||||
}
|
||||
}
|
||||
|
||||
hideAlldayEvents.collectLatest { hideAllday ->
|
||||
unselectedCalendars.collectLatest { unselected ->
|
||||
hiddenItems.collectLatest { hidden ->
|
||||
val now = System.currentTimeMillis()
|
||||
val end = now + 14 * 24 * 60 * 60 * 1000L
|
||||
val events = withContext(Dispatchers.IO) {
|
||||
queryCalendarEvents(
|
||||
query = "",
|
||||
intervalStart = now,
|
||||
intervalEnd = end,
|
||||
limit = 700,
|
||||
excludeAllDayEvents = hideAllday,
|
||||
excludeCalendars = unselected
|
||||
).filter {
|
||||
!hiddenItems.value.contains(it.key)
|
||||
}
|
||||
dataStore.data.map { it.calendarWidget }.collectLatest { settings ->
|
||||
hiddenItems.collectLatest { hidden ->
|
||||
val now = System.currentTimeMillis()
|
||||
val end = now + 14 * 24 * 60 * 60 * 1000L
|
||||
val events = withContext(Dispatchers.IO) {
|
||||
queryCalendarEvents(
|
||||
query = "",
|
||||
intervalStart = now,
|
||||
intervalEnd = end,
|
||||
limit = 700,
|
||||
excludeAllDayEvents = settings.hideAlldayEvents,
|
||||
excludeCalendars = settings.excludeCalendarsList
|
||||
).filter {
|
||||
!hiddenItems.value.contains(it.key)
|
||||
}
|
||||
send(events)
|
||||
}
|
||||
send(events)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var unselectedCalendars: List<Long>
|
||||
get() = LauncherPreferences.instance.unselectedCalendars
|
||||
set(value) {
|
||||
LauncherPreferences.instance.unselectedCalendars = value
|
||||
override suspend fun getCalendars(): List<UserCalendar> {
|
||||
if (!permissionsManager.checkPermissionOnce(PermissionGroup.Calendar)) return emptyList()
|
||||
return withContext(Dispatchers.IO) {
|
||||
val calendars = mutableListOf<UserCalendar>()
|
||||
val uri = CalendarContract.Calendars.CONTENT_URI
|
||||
val proj = arrayOf(
|
||||
CalendarContract.Calendars._ID,
|
||||
CalendarContract.Calendars.NAME,
|
||||
CalendarContract.Calendars.ACCOUNT_NAME,
|
||||
CalendarContract.Calendars.CALENDAR_COLOR,
|
||||
CalendarContract.Calendars.VISIBLE,
|
||||
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
|
||||
)
|
||||
val cursor = context.contentResolver.query(uri, proj, null, null, null)
|
||||
?: return@withContext emptyList()
|
||||
while (cursor.moveToNext()) {
|
||||
try {
|
||||
calendars.add(
|
||||
UserCalendar(
|
||||
id = cursor.getLong(0),
|
||||
name = cursor.getString(5) ?: cursor.getString(1) ?: "",
|
||||
owner = cursor.getString(2),
|
||||
color = cursor.getInt(3)
|
||||
)
|
||||
)
|
||||
} catch (e: NullPointerException) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
cursor.close()
|
||||
calendars.sortBy { it.owner }
|
||||
return@withContext calendars
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -79,41 +79,7 @@ class CalendarEvent(
|
||||
return null
|
||||
}
|
||||
|
||||
companion object: KoinComponent {
|
||||
|
||||
fun getCalendars(context: Context): List<UserCalendar> {
|
||||
val calendars = mutableListOf<UserCalendar>()
|
||||
val uri = CalendarContract.Calendars.CONTENT_URI
|
||||
val proj = arrayOf(
|
||||
CalendarContract.Calendars._ID,
|
||||
CalendarContract.Calendars.NAME,
|
||||
CalendarContract.Calendars.ACCOUNT_NAME,
|
||||
CalendarContract.Calendars.CALENDAR_COLOR,
|
||||
CalendarContract.Calendars.VISIBLE,
|
||||
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
|
||||
)
|
||||
if (!context.checkPermission(Manifest.permission.READ_CALENDAR)) return calendars
|
||||
val cursor = context.contentResolver.query(uri, proj, null, null, null)
|
||||
?: return emptyList()
|
||||
while (cursor.moveToNext()) {
|
||||
try {
|
||||
calendars.add(
|
||||
UserCalendar(
|
||||
id = cursor.getLong(0),
|
||||
name = cursor.getString(5) ?: cursor.getString(1) ?: "",
|
||||
owner = cursor.getString(2),
|
||||
color = cursor.getInt(3)
|
||||
)
|
||||
)
|
||||
} catch (e: NullPointerException) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
cursor.close()
|
||||
calendars.sortBy { it.owner }
|
||||
return calendars
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun getDisplayColor(context: Context, color: Int): Int {
|
||||
val hsl = FloatArray(3).let {
|
||||
ColorUtils.RGBToHSL(color.red, color.green, color.blue, it)
|
||||
|
||||
@ -148,15 +148,8 @@
|
||||
<string name="preference_dynamic_icon_bg">Dynamischer Hintergrund</string>
|
||||
<string name="preference_dynamic_icon_bg_summary">Hintergrundfarbe an Symbol anpassen</string>
|
||||
<string name="preference_category_widget">Widget</string>
|
||||
<string name="preference_screen_calendarwidget">Kalender</string>
|
||||
<string name="preference_screen_calendar_summary">Kalender, Widgets</string>
|
||||
<string name="preference_calendar_calendars">Kalender</string>
|
||||
<string name="preference_permission_denied">Berechtigung fehlt</string>
|
||||
<string name="preference_calendar_hide_allday">Ganztägige Termine ausblenden</string>
|
||||
<plurals name="preference_calendar_calendars_summary">
|
||||
<item quantity="one">%1$d Kalender ausgewählt</item>
|
||||
<item quantity="other">%1$d Kalender ausgewählt</item>
|
||||
</plurals>
|
||||
<string name="date_format_clock_widget">%1$s\n%2$s</string>
|
||||
<string name="menu_edit_widgets">Widgets bearbeiten</string>
|
||||
<string name="widget_name_weather">Wetter</string>
|
||||
@ -432,6 +425,14 @@
|
||||
<string name="preference_music_filter_sources">Auf Musik-Apps begrenzen</string>
|
||||
<string name="preference_music_filter_sources_summary">Mediensitzungen von Apps ignorieren, die keine Musik-Apps sind</string>
|
||||
|
||||
<string name="preference_screen_calendarwidget">Kalender</string>
|
||||
<string name="preference_calendar_calendars">Kalender</string>
|
||||
<string name="preference_calendar_hide_allday">Ganztägige Termine ausblenden</string>
|
||||
<plurals name="preference_calendar_calendars_summary">
|
||||
<item quantity="one">%1$d Kalender ausgewählt</item>
|
||||
<item quantity="other">%1$d Kalender ausgewählt</item>
|
||||
</plurals>
|
||||
|
||||
<string name="preference_screen_search">Suche</string>
|
||||
<string name="preference_screen_search_summary">Konfigurieren was durchsucht werden soll</string>
|
||||
<string name="preference_search_favorites">Favoriten</string>
|
||||
|
||||
@ -196,11 +196,8 @@
|
||||
<string name="preference_dynamic_icon_bg">Dynamic background</string>
|
||||
<string name="preference_dynamic_icon_bg_summary">Adjust background color to icon</string>
|
||||
<string name="preference_category_widget">Widget</string>
|
||||
<string name="preference_screen_calendarwidget">Calendar</string>
|
||||
<string name="preference_screen_calendar_summary">Calendars, Widget settings</string>
|
||||
<string name="preference_calendar_calendars">Calendars</string>
|
||||
<string name="preference_permission_denied">Permission denied</string>
|
||||
<string name="preference_calendar_hide_allday">Hide all-day events</string>
|
||||
<string name="menu_edit_widgets">Edit widgets</string>
|
||||
<string name="widget_name_weather">Weather</string>
|
||||
<string name="widget_name_calendar">Calendar</string>
|
||||
@ -237,10 +234,6 @@
|
||||
<string name="file_type_ebook">E-book</string>
|
||||
<string name="file_type_drawing">Drawing</string>
|
||||
<string name="file_type_form">Form</string>
|
||||
<plurals name="preference_calendar_calendars_summary">
|
||||
<item quantity="one">%1$d calendar selected</item>
|
||||
<item quantity="other">%1$d calendars selected</item>
|
||||
</plurals>
|
||||
<string name="menu_hide">Hide</string>
|
||||
<string name="menu_unhide">Don\'t hide</string>
|
||||
<string name="menu_hidden_items">Hidden items</string>
|
||||
@ -488,6 +481,14 @@
|
||||
<string name="preference_search_websearch">Web search</string>
|
||||
<string name="preference_search_websearch_summary">Show shortcuts to different search engines</string>
|
||||
|
||||
<string name="preference_screen_calendarwidget">Calendar</string>
|
||||
<string name="preference_calendar_calendars">Calendars</string>
|
||||
<string name="preference_calendar_hide_allday">Hide all-day events</string>
|
||||
<plurals name="preference_calendar_calendars_summary">
|
||||
<item quantity="one">%1$d calendar selected</item>
|
||||
<item quantity="other">%1$d calendars selected</item>
|
||||
</plurals>
|
||||
|
||||
<string name="preference_music_filter_sources">Restrict to music apps</string>
|
||||
<string name="preference_music_filter_sources_summary">Ignore media sessions of apps that are not music apps</string>
|
||||
|
||||
|
||||
@ -21,6 +21,10 @@ fun createFactorySettings(context: Context): Settings {
|
||||
.setFilterSources(true)
|
||||
.build()
|
||||
)
|
||||
.setCalendarWidget(Settings.CalendarWidgetSettings
|
||||
.newBuilder()
|
||||
.setHideAlldayEvents(false)
|
||||
)
|
||||
.setClockWidget(Settings.ClockWidgetSettings
|
||||
.newBuilder()
|
||||
.setLayout(Settings.ClockWidgetSettings.ClockWidgetLayout.Vertical)
|
||||
|
||||
@ -103,4 +103,10 @@ message Settings {
|
||||
}
|
||||
WebSearchSettings web_search = 16;
|
||||
|
||||
message CalendarWidgetSettings {
|
||||
bool hide_allday_events = 1;
|
||||
repeated int64 exclude_calendars = 2;
|
||||
}
|
||||
CalendarWidgetSettings calendar_widget = 17;
|
||||
|
||||
}
|
||||
@ -23,6 +23,7 @@ import de.mm20.launcher2.ui.base.BaseActivity
|
||||
import de.mm20.launcher2.ui.locals.LocalNavController
|
||||
import de.mm20.launcher2.ui.settings.about.AboutSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.appearance.AppearanceSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.calendarwidget.CalendarWidgetSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.clockwidget.ClockWidgetSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.debug.DebugSettingsScreen
|
||||
import de.mm20.launcher2.ui.settings.license.LicenseScreen
|
||||
@ -98,6 +99,9 @@ class SettingsActivity : BaseActivity() {
|
||||
composable("settings/widgets/music") {
|
||||
MusicWidgetSettingsScreen()
|
||||
}
|
||||
composable("settings/widgets/calendar") {
|
||||
CalendarWidgetSettingsScreen()
|
||||
}
|
||||
composable("settings/widgets/clock") {
|
||||
ClockWidgetSettingsScreen()
|
||||
}
|
||||
|
||||
@ -0,0 +1,155 @@
|
||||
package de.mm20.launcher2.ui.settings.calendarwidget
|
||||
|
||||
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.foundation.shape.RoundedCornerShape
|
||||
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.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import de.mm20.launcher2.search.data.UserCalendar
|
||||
import de.mm20.launcher2.ui.R
|
||||
import de.mm20.launcher2.ui.component.preferences.Preference
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceCategory
|
||||
import de.mm20.launcher2.ui.component.preferences.PreferenceScreen
|
||||
import de.mm20.launcher2.ui.component.preferences.SwitchPreference
|
||||
import de.mm20.launcher2.ui.pluralResource
|
||||
|
||||
@Composable
|
||||
fun CalendarWidgetSettingsScreen() {
|
||||
val viewModel: CalendarWidgetSettingsScreenVM = viewModel()
|
||||
PreferenceScreen(title = stringResource(R.string.preference_screen_calendarwidget)) {
|
||||
item {
|
||||
val excludeAllDayEvents by viewModel.excludeAllDayEvents.observeAsState()
|
||||
PreferenceCategory {
|
||||
SwitchPreference(
|
||||
title = stringResource(R.string.preference_calendar_hide_allday),
|
||||
value = excludeAllDayEvents == true,
|
||||
onValueChanged = {
|
||||
viewModel.setExcludeAllDayEvents(it)
|
||||
}
|
||||
)
|
||||
val calendars by viewModel.calendars.observeAsState(emptyList())
|
||||
val unselectedCalendars by viewModel.unselectedCalendars.observeAsState(emptyList())
|
||||
ExcludedCalendarsPreference(
|
||||
calendars = calendars,
|
||||
value = unselectedCalendars,
|
||||
onValueChanged = {
|
||||
viewModel.setUnselectedCalendars(it)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ExcludedCalendarsPreference(
|
||||
calendars: List<UserCalendar>,
|
||||
value: List<Long>,
|
||||
onValueChanged: (List<Long>) -> Unit
|
||||
) {
|
||||
var showDialog by remember { mutableStateOf(false) }
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_calendar_calendars),
|
||||
summary = pluralResource(
|
||||
R.plurals.preference_calendar_calendars_summary,
|
||||
quantity = calendars.size - value.size,
|
||||
calendars.size - value.size
|
||||
),
|
||||
onClick = {
|
||||
showDialog = true
|
||||
}
|
||||
)
|
||||
if (showDialog) {
|
||||
Dialog(
|
||||
onDismissRequest = { showDialog = false },
|
||||
) {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(max = 400.dp),
|
||||
shape = RoundedCornerShape(16.dp),
|
||||
tonalElevation = 16.dp,
|
||||
shadowElevation = 16.dp,
|
||||
) {
|
||||
Column {
|
||||
Text(
|
||||
text = stringResource(R.string.preference_calendar_calendars),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(
|
||||
start = 24.dp, end = 24.dp, top = 16.dp, bottom = 8.dp
|
||||
)
|
||||
)
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(horizontal = 16.dp)
|
||||
) {
|
||||
items(calendars) { c ->
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
if (value.contains(c.id)) {
|
||||
onValueChanged(
|
||||
value.filter { it != c.id }
|
||||
)
|
||||
} else {
|
||||
onValueChanged(
|
||||
value + c.id
|
||||
)
|
||||
}
|
||||
}
|
||||
) {
|
||||
Checkbox(
|
||||
checked = !value.contains(c.id),
|
||||
onCheckedChange = {
|
||||
if (it) {
|
||||
onValueChanged(
|
||||
value.filter { it != c.id }
|
||||
)
|
||||
} else {
|
||||
onValueChanged(
|
||||
value + c.id
|
||||
)
|
||||
}
|
||||
},
|
||||
colors = CheckboxDefaults.colors(
|
||||
checkedColor = Color(c.color)
|
||||
)
|
||||
)
|
||||
Text(text = c.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
TextButton(
|
||||
onClick = {
|
||||
onValueChanged(value.toList())
|
||||
showDialog = false
|
||||
},
|
||||
modifier = Modifier
|
||||
.align(Alignment.End)
|
||||
.padding(vertical = 12.dp, horizontal = 16.dp)
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(android.R.string.ok),
|
||||
style = MaterialTheme.typography.labelLarge
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
package de.mm20.launcher2.ui.settings.calendarwidget
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.asLiveData
|
||||
import androidx.lifecycle.liveData
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import de.mm20.launcher2.calendar.CalendarRepository
|
||||
import de.mm20.launcher2.preferences.LauncherDataStore
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.launch
|
||||
import org.koin.core.component.KoinComponent
|
||||
import org.koin.core.component.inject
|
||||
|
||||
class CalendarWidgetSettingsScreenVM : ViewModel(), KoinComponent {
|
||||
private val dataStore: LauncherDataStore by inject()
|
||||
private val calendarRepository: CalendarRepository by inject()
|
||||
|
||||
val excludeAllDayEvents = dataStore.data.map { it.calendarWidget.hideAlldayEvents }.asLiveData()
|
||||
fun setExcludeAllDayEvents(excludeAllDayEvents: Boolean) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setCalendarWidget(
|
||||
it.calendarWidget
|
||||
.toBuilder()
|
||||
.setHideAlldayEvents(excludeAllDayEvents)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val calendars = liveData {
|
||||
emit(calendarRepository.getCalendars())
|
||||
}
|
||||
val unselectedCalendars =
|
||||
dataStore.data.map { it.calendarWidget.excludeCalendarsList }.asLiveData()
|
||||
|
||||
fun setUnselectedCalendars(unselectedCalendars: List<Long>) {
|
||||
viewModelScope.launch {
|
||||
dataStore.updateData {
|
||||
it.toBuilder()
|
||||
.setCalendarWidget(
|
||||
it.calendarWidget.toBuilder()
|
||||
.clearExcludeCalendars()
|
||||
.addAllExcludeCalendars(unselectedCalendars)
|
||||
)
|
||||
.build()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -40,7 +40,10 @@ fun WidgetsSettingsScreen() {
|
||||
)
|
||||
Preference(
|
||||
title = stringResource(R.string.preference_screen_calendarwidget),
|
||||
icon = Icons.Rounded.Today
|
||||
icon = Icons.Rounded.Today,
|
||||
onClick = {
|
||||
navController?.navigate("settings/widgets/calendar")
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user