Skip to content

Commit

Permalink
Enable notifications (#470)
Browse files Browse the repository at this point in the history
  • Loading branch information
almarklein committed Apr 19, 2024
1 parent 2557637 commit ebe7f0e
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 1 deletion.
65 changes: 65 additions & 0 deletions timetagger/app/dialogs.py
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,15 @@ def __init__(self, canvas):
self._record = None
self._no_user_edit_yet = True

# Enable stopping a record via the notification
if window.navigator.serviceWorker:
try:
window.navigator.serviceWorker.addEventListener(
"message", self.on_notificationclick
)
except Exception:
pass

def open(self, mode, record, callback=None):
"""Show/open the dialog for the given record. On submit, the
record will be pushed to the store and callback (if given) will
Expand Down Expand Up @@ -1827,6 +1836,9 @@ def submit(self):
# Apply
window.store.records.put(self._record)
super().submit(self._record)
# Notify
if self._lmode == "start":
self.send_notification(self._record)
# Start pomo?
if window.simplesettings.get("pomodoro_enabled"):
if self._lmode == "start":
Expand Down Expand Up @@ -1855,10 +1867,43 @@ def resume_record(self):
if not (t1 < now < t2):
t1, t2 = self._canvas.range.get_today_range()
self._canvas.range.animate_range(t1, t2)
# Notify
self.send_notification(record)
# Start pomo?
if window.simplesettings.get("pomodoro_enabled"):
self._canvas.pomodoro_dialog.start_work()

def send_notification(self, record):
if not window.simplesettings.get("notifications"):
return
if window.Notification and Notification.permission != "granted":
return

title = "TimeTagger is tracking time"
actions = [
{"action": "stop", "title": "Stop"},
]
options = {
"icon": "timetagger192_sf.png",
"body": record.ds or "",
"requireInteraction": True,
"tag": "timetagger-running", # replace previous notifications
}
# If we show the notification via the service worker, we
# can show actions, making the flow easier for users.
if window.pwa and window.pwa.sw_reg:
options.actions = actions
window.pwa.sw_reg.showNotification(title, options)
else:
Notification(title, options)

def on_notificationclick(self, message_event):
event = message_event.data
if event.type != "notificationclick":
return
if event.action == "stop":
self._stop_all_running_records()


class TargetHelper:
"""A little class to help with targets. Because targets occur in two dialogs."""
Expand Down Expand Up @@ -3863,6 +3908,10 @@ def open(self, callback=None):
<option value='full'>Full width</option>
</select>
</div>
<h2><i class='fas'>\uf0e0</i>&nbsp;&nbsp;Notification</h2>
<label>
<input type='checkbox' checked='false'></input>
Show notification when starting a record.</label>
<h2><i class='fas'>\uf2f2</i>&nbsp;&nbsp;Pomodoro</h2>
<label>
<input type='checkbox' checked='false'></input>
Expand Down Expand Up @@ -3892,6 +3941,8 @@ def open(self, callback=None):
_, # Section: per device
_, # Appearance header
self._appearance_form,
_, # Notification header
self._notification_label,
_, # Pomodoro header
self._pomodoro_label,
_, # hr
Expand Down Expand Up @@ -3960,6 +4011,12 @@ def open(self, callback=None):
self._width_mode_select.value = width_mode
self._width_mode_select.onchange = self._on_width_mode_change

# Notifications
notifications_enabled = window.simplesettings.get("notifications")
self._notification_check = self._notification_label.children[0]
self._notification_check.checked = notifications_enabled
self._notification_check.onchange = self._on_notifications_check

# Pomodoro
pomo_enabled = window.simplesettings.get("pomodoro_enabled")
self._pomodoro_check = self._pomodoro_label.children[0]
Expand Down Expand Up @@ -4010,6 +4067,14 @@ def _on_width_mode_change(self):
window.front.set_width_mode(width_mode)
self._canvas._on_js_resize_event() # private method, but ah well

def _on_notifications_check(self):
notifications_enabled = bool(self._notification_check.checked)
window.simplesettings.set("notifications", notifications_enabled)
# Ask the user
if notifications_enabled:
if window.Notification and window.Notification.permission == "default":
Notification.requestPermission()

def _on_pomodoro_check(self):
pomo_enabled = bool(self._pomodoro_check.checked)
window.simplesettings.set("pomodoro_enabled", pomo_enabled)
Expand Down
3 changes: 2 additions & 1 deletion timetagger/app/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ class SimpleSettings:
Key-value pairs are stored in a cache for fast getters.
The actual storage can be:
* None / session only: unknown keys are not stored across sessions.
* Local storagee: a prefefined set of keys are stored in local storaged,
* Local storage: a prefefined set of keys are stored in local storaged,
which means that they are device-specific.
* Synced: synced to the server using the settings store.
"""
Expand All @@ -612,6 +612,7 @@ def __init__(self):
self._local_keys = {
"darkmode": 1,
"width_mode": "auto",
"notifications": False,
"pomodoro_enabled": False,
"report_grouping": "date",
"report_groupperiod": "none",
Expand Down

0 comments on commit ebe7f0e

Please sign in to comment.