fix timers
lint / ruff (push) Failing after 15s
tests / desktop (push) Successful in 21s
tests / web (push) Successful in 46s
docker / image (push) Failing after 1m31s
tests / android-core (push) Successful in 1m5s
tests / backend (push) Successful in 2m33s
android / apk (push) Successful in 4m34s
lint / ruff (push) Failing after 15s
tests / desktop (push) Successful in 21s
tests / web (push) Successful in 46s
docker / image (push) Failing after 1m31s
tests / android-core (push) Successful in 1m5s
tests / backend (push) Successful in 2m33s
android / apk (push) Successful in 4m34s
This commit is contained in:
30 files changed
+3331
-419
No files matched your search
@@ -78,7 +78,17 @@ class Controller(QObject):
|
||||
self._last_session_id: int | None = None
|
||||
self._last_kind = ""
|
||||
self._last_status = ""
|
||||
self._completing = False
|
||||
self._completed_id: int | None = None
|
||||
"""The interval we have already asked the server to finish.
|
||||
|
||||
An id rather than a bare "in flight" flag. A poll issued just before the
|
||||
countdown ran out answers with that interval still running at 00:00, and
|
||||
a flag cleared by that answer sends `complete` a second time — onto the
|
||||
break `auto_next` has since started, which is why a break could end the
|
||||
instant it began. Ids are never reused, so the second attempt is never
|
||||
made. Cleared only when the call itself fails, so a refused or dropped
|
||||
complete is still retried.
|
||||
"""
|
||||
self._paused_by_lock = False
|
||||
self._mini_visible = False
|
||||
self._mini_dismissed = False
|
||||
@@ -174,6 +184,13 @@ class Controller(QObject):
|
||||
current = self._state.get("current")
|
||||
return str(current["status"]) if current else "idle"
|
||||
|
||||
@property
|
||||
def _session_id(self) -> int | None:
|
||||
"""The running interval's id, or None when nothing is running."""
|
||||
current = self._state.get("current") or {}
|
||||
session_id = current.get("id")
|
||||
return int(session_id) if session_id is not None else None
|
||||
|
||||
@pyqtProperty(int, notify=stateChanged)
|
||||
def remainingSeconds(self) -> int:
|
||||
if self._state.get("current"):
|
||||
@@ -393,7 +410,7 @@ class Controller(QObject):
|
||||
|
||||
@pyqtSlot()
|
||||
def complete(self) -> None:
|
||||
self._send("complete", {"auto_next": True})
|
||||
self._send("complete", {"auto_next": True, "session_id": self._session_id})
|
||||
|
||||
@pyqtSlot()
|
||||
@pyqtSlot(str)
|
||||
@@ -567,7 +584,6 @@ class Controller(QObject):
|
||||
self._last_session_id = session_id
|
||||
self._last_kind = kind
|
||||
self._last_status = status
|
||||
self._completing = False
|
||||
self.stateChanged.emit()
|
||||
self._update_launcher()
|
||||
|
||||
@@ -610,12 +626,18 @@ class Controller(QObject):
|
||||
|
||||
def _on_command_failed(self, name: str, detail: str) -> None:
|
||||
log.warning("%s failed: %s", name, detail)
|
||||
if name == "complete":
|
||||
# It never landed, so the interval at 00:00 is still owed a complete.
|
||||
self._completed_id = None
|
||||
self.toast.emit(detail)
|
||||
|
||||
def _on_command_done(self, name: str, result: dict[str, Any]) -> None:
|
||||
if name == "complete":
|
||||
finished = result.get("finished") or {}
|
||||
self._announce_finished(str(finished.get("kind", "work")), result)
|
||||
finished = result.get("finished")
|
||||
# None means the server declined: something else was running by the
|
||||
# time the call arrived, so nothing finished and nothing is announced.
|
||||
if finished:
|
||||
self._announce_finished(str(finished.get("kind", "work")), result)
|
||||
elif name == "send_report":
|
||||
self.toast.emit("Daily report sent" if result.get("sent") else "Report not sent — check Telegram settings")
|
||||
elif name == "refresh_sources":
|
||||
@@ -706,10 +728,11 @@ class Controller(QObject):
|
||||
if self._remaining % 5 == 0:
|
||||
self._update_launcher()
|
||||
return
|
||||
if not self._completing:
|
||||
session_id = self._session_id
|
||||
if session_id is not None and self._completed_id != session_id:
|
||||
# The countdown reached zero: the server books the interval, and its
|
||||
# reply decides what happens next (auto-break, or nothing).
|
||||
self._completing = True
|
||||
self._completed_id = session_id
|
||||
self.complete()
|
||||
|
||||
def _check_idle(self) -> None:
|
||||
|
||||
Reference in new issue
Block a user