Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable notifications #470

Merged
merged 1 commit into from
Apr 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading