Aan/uit-schakelaar per wekker (blijvend); uitgezette wekkers worden niet gepland

This commit is contained in:
eddy 2026-10-14 20:42:08 +02:00
commit 7648aa6ce8
4 changed files with 83 additions and 27 deletions

View file

@ -9,6 +9,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.widget.LinearLayout import android.widget.LinearLayout
import android.widget.PopupMenu import android.widget.PopupMenu
import android.widget.Switch
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
@ -120,13 +121,20 @@ class MainActivity : AppCompatActivity() {
else -> "Gepland" else -> "Gepland"
} }
alarms.forEach { spec -> alarms.forEach { spec ->
container.addView( val disabled = prefs.isDisabled(spec.name)
inflater.inflate(R.layout.item_alarm_card, container, false).apply { val card = inflater.inflate(R.layout.item_alarm_card, container, false)
findViewById<TextView>(R.id.tv_day).text = dayLabel card.findViewById<TextView>(R.id.tv_day).text = dayLabel
findViewById<TextView>(R.id.tv_name).text = spec.name card.findViewById<TextView>(R.id.tv_name).text = spec.name
findViewById<TextView>(R.id.tv_time).text = TIME.format(spec.time) card.findViewById<TextView>(R.id.tv_time).text = TIME.format(spec.time)
}, val switch = card.findViewById<Switch>(R.id.switch_alarm)
) switch.setOnCheckedChangeListener(null)
switch.isChecked = !disabled
card.alpha = if (disabled) 0.5f else 1f
switch.setOnCheckedChangeListener { _, checked ->
toggleAlarm(spec, checked)
renderStatus()
}
container.addView(card)
} }
} }
@ -156,6 +164,19 @@ class MainActivity : AppCompatActivity() {
} }
} }
/** Zet een wekker aan/uit: plan/cancel het alarm morgen en onthoud de keuze. */
private fun toggleAlarm(spec: AlarmSpec, enabled: Boolean) {
if (enabled) {
prefs.enable(spec.name)
AlarmScheduler.scheduleAlarm(this, spec)
toast("${spec.name} ingeschakeld")
} else {
prefs.disable(spec.name)
AlarmScheduler.cancelAlarm(this, spec.name)
toast("${spec.name} uitgeschakeld")
}
}
private fun requestNotificationPermission() { private fun requestNotificationPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU &&
ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) != ContextCompat.checkSelfPermission(this, Manifest.permission.POST_NOTIFICATIONS) !=

View file

@ -94,6 +94,22 @@ class Prefs(context: Context) {
sp.edit().putString("ringtone_$name", uri?.toString()).apply() sp.edit().putString("ringtone_$name", uri?.toString()).apply()
} }
/** Wekkers die de gebruiker heeft uitgezet (blijvend, tot weer aangezet). */
var disabledAlarms: Set<String>
get() = sp.getString(KEY_DISABLED, "")?.split("|")?.filter { it.isNotEmpty() }?.toSet()
?: emptySet()
private set(value) = sp.edit().putString(KEY_DISABLED, value.joinToString("|")).apply()
fun isDisabled(name: String): Boolean = name in disabledAlarms
fun disable(name: String) {
disabledAlarms = disabledAlarms + name
}
fun enable(name: String) {
disabledAlarms = disabledAlarms - name
}
fun storePlan(day: LocalDate, alarms: List<AlarmSpec>) { fun storePlan(day: LocalDate, alarms: List<AlarmSpec>) {
val zone = ZoneId.systemDefault() val zone = ZoneId.systemDefault()
plannedDayIso = day.toString() plannedDayIso = day.toString()
@ -131,5 +147,6 @@ class Prefs(context: Context) {
const val KEY_PLAN_DAY = "plan_day" const val KEY_PLAN_DAY = "plan_day"
const val KEY_PLAN_ALARMS = "plan_alarms" const val KEY_PLAN_ALARMS = "plan_alarms"
const val KEY_SHIFT_START = "shift_start" const val KEY_SHIFT_START = "shift_start"
const val KEY_DISABLED = "disabled_alarms"
} }
} }

View file

@ -66,9 +66,13 @@ object ShiftCheck {
val shiftStart = starts.minOrNull()!! val shiftStart = starts.minOrNull()!!
prefs.lastShiftStartIso = shiftStart.toString() prefs.lastShiftStartIso = shiftStart.toString()
val plan = ShiftPlanner.plan(shiftStart) val plan = ShiftPlanner.plan(shiftStart)
plan.forEach { AlarmScheduler.scheduleAlarm(context, it) } // Volledig plan bewaren voor de weergave; alleen aangezette wekkers plannen.
prefs.storePlan(tomorrow, plan) prefs.storePlan(tomorrow, plan)
val times = plan.joinToString(" · ") { "${it.name} ${DISPLAY.format(it.time)}" } val disabled = prefs.disabledAlarms
plan.filter { it.name !in disabled }.forEach { AlarmScheduler.scheduleAlarm(context, it) }
plan.filter { it.name in disabled }.forEach { AlarmScheduler.cancelAlarm(context, it.name) }
val active = plan.filter { it.name !in disabled }
val times = active.joinToString(" · ") { "${it.name} ${DISPLAY.format(it.time)}" }
val msg = "Dienst morgen om ${DISPLAY.format(shiftStart)} → $times" val msg = "Dienst morgen om ${DISPLAY.format(shiftStart)} → $times"
prefs.lastStatusTxt = msg prefs.lastStatusTxt = msg
prefs.lastCheckedAtMillis = System.currentTimeMillis() prefs.lastCheckedAtMillis = System.currentTimeMillis()

View file

@ -13,38 +13,52 @@
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="20dp"> android:padding="20dp">
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal"> android:layout_weight="1"
android:orientation="vertical">
<TextView <LinearLayout
android:id="@+id/tv_day"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:id="@+id/tv_day"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_bright"
android:textSize="15sp"
android:textStyle="bold" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:textColor="@color/text_muted"
android:textSize="15sp" />
</LinearLayout>
<TextView
android:id="@+id/tv_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:textColor="@color/text_bright" android:textColor="@color/text_bright"
android:textSize="15sp" android:textSize="56sp"
android:textStyle="bold" /> android:textStyle="bold" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:textColor="@color/text_muted"
android:textSize="15sp" />
</LinearLayout> </LinearLayout>
<TextView <Switch
android:id="@+id/tv_time" android:id="@+id/switch_alarm"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="2dp" android:contentDescription="Wekker aan of uit" />
android:textColor="@color/text_bright"
android:textSize="56sp"
android:textStyle="bold" />
</LinearLayout> </LinearLayout>
</com.google.android.material.card.MaterialCardView> </com.google.android.material.card.MaterialCardView>