screen-locker/screen_locker/_ui_flows_sick.py
Krzysztof kuhy Rudnicki 9b39196671 Take gatelock 0.8.1: nested LockConfig
The grab axes are grab=GrabPolicy(kind=..., disable_vt=...,
preempt_weaker_holder=...) and every colour read goes through
config.palette; nothing about the lock's behaviour changed. Also carries
the pylint hook on 4.0.8 with the source-only scope config; the gate
stays at 8.0 until the remaining findings are cleared.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HHCbkJWXHjtTUaqvnHRAqA
2026-09-12 19:52:38 +02:00

95 lines
3.5 KiB
Python

"""Sick-day flow for the screen locker's locked screen.
Split out of :mod:`screen_locker._ui_flows` to keep every file under the
250-line cap. Composed back into ``UIFlowsMixin`` there, so the set of mixins
``ScreenLocker`` inherits is unchanged.
"""
from __future__ import annotations
from screen_locker import _sick_tracker
class SickDayFlowMixin:
"""Sick-day justification, countdown and debt bookkeeping."""
def ask_if_sick(self) -> None:
"""Display the structured sick-day justification dialog."""
self._show_sick_justification()
def _get_sick_day_status(self) -> tuple[str, str]:
"""Determine sick day status text and color."""
if self._sick_mode_used_today():
return "Shutdown time already adjusted today", self._colors.palette.warning
if self._adjust_shutdown_time_earlier():
return (
"Shutdown time moved 1.5 hours earlier ✓\n(Will revert tomorrow)"
), self._colors.palette.success
return (
"Could not adjust shutdown time (check permissions)",
self._colors.palette.danger,
)
def _proceed_to_sick_countdown(self) -> None:
"""Start the (escalated) sick day countdown after justification."""
history = getattr(
self,
"_sick_history_cache",
None,
)
if history is None:
history = _sick_tracker.load_history()
self._sick_history_cache = history
countdown = _sick_tracker.compute_lockout_seconds(history)
self.clear_container()
status_text, status_color = self._get_sick_day_status()
self._show_sick_day_ui(status_text, status_color, countdown)
self.sick_remaining_time = countdown
self._update_sick_countdown()
def _show_sick_day_ui(
self,
status_text: str,
status_color: str,
countdown: int,
) -> None:
"""Display sick day UI labels and countdown."""
self._label("Sick Day Mode", color=self._colors.palette.warning, pad="md")
self._text(status_text, color=status_color)
minutes = countdown // 60
self._text(
f"Please wait ~{minutes} min before unlocking...",
role="title",
pad="md",
)
self.sick_countdown_label = self._label(
str(countdown),
role="display",
scale=2.5,
pad="lg",
)
def _update_sick_countdown(self) -> None:
"""Update the sick day countdown timer."""
if self.sick_remaining_time > 0:
self.sick_countdown_label.config(text=str(self.sick_remaining_time))
self.sick_remaining_time -= 1
self.root.after(1000, self._update_sick_countdown)
else:
self._finalize_sick_day()
def _finalize_sick_day(self) -> None:
"""Persist sick-day history and unlock the screen."""
history = getattr(self, "_sick_history_cache", None)
if history is None:
history = _sick_tracker.load_history()
if _sick_tracker.had_commitment_for_today(history):
_sick_tracker.mark_commitment_broken(history)
self.workout_data["broke_commitment"] = "true"
new_debt = _sick_tracker.add_sick_day(history)
_sick_tracker.save_history(history)
self.workout_data["type"] = "sick_day"
self.workout_data["note"] = "Sick day - shutdown moved earlier"
self.workout_data["debt"] = str(new_debt)
self.unlock_screen()