diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 20737d8..d91eb70 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -88,6 +88,20 @@ android:excludeFromRecents="true" android:launchMode="singleTask" /> + + + + + + + diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/qs/NewEventTileService.kt b/app/src/main/java/de/jeanlucmakiola/calendula/qs/NewEventTileService.kt new file mode 100644 index 0000000..4199341 --- /dev/null +++ b/app/src/main/java/de/jeanlucmakiola/calendula/qs/NewEventTileService.kt @@ -0,0 +1,41 @@ +package de.jeanlucmakiola.calendula.qs + +import android.app.PendingIntent +import android.os.Build +import android.service.quicksettings.TileService +import de.jeanlucmakiola.calendula.MainActivity +import kotlinx.datetime.TimeZone +import kotlinx.datetime.toLocalDateTime +import kotlin.time.Clock + +/** + * Quick Settings tile: tapping it opens the create-event form on today — the + * same action as the launcher "New event" shortcut and the agenda widget's "+". + * A stateless action tile, so there is no on/off state to keep in sync. + */ +class NewEventTileService : TileService() { + + override fun onClick() { + super.onClick() + val today = Clock.System.now() + .toLocalDateTime(TimeZone.currentSystemDefault()).date + val intent = MainActivity.openCreateIntent(this, today) + // Launch only once the device is unlocked: creating an event behind the + // keyguard makes no sense, and the shade can't start an activity over a + // locked screen anyway. + unlockAndRun { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { + val pending = PendingIntent.getActivity( + this, + 0, + intent, + PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT, + ) + startActivityAndCollapse(pending) + } else { + @Suppress("DEPRECATION") + startActivityAndCollapse(intent) + } + } + } +} diff --git a/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/SettingsScreen.kt b/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/SettingsScreen.kt index 604ac85..47e86ba 100644 --- a/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/SettingsScreen.kt +++ b/app/src/main/java/de/jeanlucmakiola/calendula/ui/settings/SettingsScreen.kt @@ -1,12 +1,16 @@ package de.jeanlucmakiola.calendula.ui.settings import android.Manifest +import android.app.StatusBarManager +import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.pm.PackageManager +import android.graphics.drawable.Icon import android.os.Build import android.os.PowerManager import android.provider.Settings +import androidx.annotation.RequiresApi import android.text.format.DateFormat import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts @@ -80,6 +84,7 @@ import de.jeanlucmakiola.calendula.data.prefs.CalendarReminderOverride import de.jeanlucmakiola.calendula.data.prefs.ThemeMode import de.jeanlucmakiola.calendula.data.prefs.WeekStartPref import de.jeanlucmakiola.calendula.domain.EventFormField +import de.jeanlucmakiola.calendula.qs.NewEventTileService import de.jeanlucmakiola.calendula.ui.crash.CrashReportDialog import de.jeanlucmakiola.calendula.ui.crash.openIssueTracker import de.jeanlucmakiola.calendula.ui.crash.submitCrashReport @@ -514,9 +519,39 @@ private fun EventFormScreen( ) }, ) + + // One-tap add of the "New event" Quick Settings tile. The system prompt + // is API 33+; on older versions the tile is still addable manually from + // the QS editor, so the row simply doesn't appear there. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + Spacer(Modifier.height(24.dp)) + val context = LocalContext.current + GroupedRow( + title = stringResource(R.string.settings_qs_tile), + summary = stringResource(R.string.settings_qs_tile_hint), + position = Position.Alone, + onClick = { requestAddQsTile(context) }, + ) + } } } +/** + * Ask the system to add the "New event" Quick Settings tile (API 33+). The OS + * shows its own confirmation dialog and handles the already-added case, so no + * result handling is needed here. + */ +@RequiresApi(Build.VERSION_CODES.TIRAMISU) +private fun requestAddQsTile(context: Context) { + val statusBar = context.getSystemService(StatusBarManager::class.java) ?: return + statusBar.requestAddTileService( + ComponentName(context, NewEventTileService::class.java), + context.getString(R.string.qs_tile_new_event_label), + Icon.createWithResource(context, R.drawable.ic_qs_new_event), + context.mainExecutor, + ) { /* result code unused — the system surfaces its own feedback */ } +} + /** * Reminder-notifications toggle (v1.4), mirroring the onboarding step. * Turning it on re-requests `POST_NOTIFICATIONS` when missing (API 33+) — diff --git a/app/src/main/res/drawable/ic_qs_new_event.xml b/app/src/main/res/drawable/ic_qs_new_event.xml new file mode 100644 index 0000000..df0f3fb --- /dev/null +++ b/app/src/main/res/drawable/ic_qs_new_event.xml @@ -0,0 +1,18 @@ + + + + + + diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 037c717..af81d6d 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -247,6 +247,11 @@ Neuer Termin Neuen Termin erstellen + + Neuer Termin + Schnelleinstellungen-Kachel hinzufügen + Eine Kachel „Neuer Termin“ zu den Schnelleinstellungen hinzufügen. + Kalender diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 21e31be..0a412c6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -361,6 +361,11 @@ New event Create a new event + + New event + Add Quick Settings tile + Add a “New event” tile to the Quick Settings panel. + https://gitea.jeanlucmakiola.de/makiolaj/calendula https://gitea.jeanlucmakiola.de/makiolaj/calendula/src/branch/main/LICENSE