From cf56832ff166fc51a551564c6dc313254cff2559 Mon Sep 17 00:00:00 2001
From: Ethan Vogelsang <38506314+evogelsa@users.noreply.github.com>
Date: Thu, 6 Mar 2025 19:50:45 -0600
Subject: [PATCH 1/3] feat: add option to randomize new tag colors
---
timetagger/app/dialogs.py | 24 ++++++++++++++++++++++--
timetagger/app/stores.py | 10 +++++++++-
timetagger/app/utils.py | 6 ++++++
3 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/timetagger/app/dialogs.py b/timetagger/app/dialogs.py
index 116e024..84c2499 100644
--- a/timetagger/app/dialogs.py
+++ b/timetagger/app/dialogs.py
@@ -2148,7 +2148,7 @@ def _set_default_color(self):
self._set_color(self._default_color)
def _set_random_color(self):
- clr = "#" + Math.floor(Math.random() * 16777215).toString(16)
+ clr = utils.color_random()
self._set_color(clr)
def _set_color(self, clr):
@@ -3920,9 +3920,18 @@ def open(self, callback=None):
\uf085 Misc
+
+ Show elapsed time below start-button
+
@@ -3971,6 +3980,7 @@ def open(self, callback=None):
_, # Time repr header
self._repr_form,
_, # Misc header
+ self._tag_form,
self._stopwatch_label,
_, # hr
_, # Section: per device
@@ -4032,6 +4042,12 @@ def open(self, callback=None):
self._today_end_offset.value = today_end_offset
self._today_end_offset.onchange = self._on_today_end_offset_change
+ # Tag color
+ tag_color = window.simplesettings.get("tag_color")
+ self._tag_color = self._tag_form.children[1]
+ self._tag_color.value = tag_color
+ self._tag_color.onchange = self._on_tag_color_change
+
# Stopwatch
show_stopwatch = window.simplesettings.get("show_stopwatch")
self._stopwatch_check = self._stopwatch_label.children[0]
@@ -4128,6 +4144,10 @@ def _on_stopwatch_check(self):
show_stopwatch = bool(self._stopwatch_check.checked)
window.simplesettings.set("show_stopwatch", show_stopwatch)
+ def _on_tag_color_change(self):
+ tag_color = self._tag_color.value
+ window.simplesettings.set("tag_color", tag_color)
+
class GuideDialog(BaseDialog):
"""Dialog to have quick access to the guide."""
diff --git a/timetagger/app/stores.py b/timetagger/app/stores.py
index fa3c37a..624ce4f 100644
--- a/timetagger/app/stores.py
+++ b/timetagger/app/stores.py
@@ -358,7 +358,15 @@ def get_tag_info(self, tagz):
def get_color_for_tag(self, tag):
info = self.get_tag_info(tag)
color = info.get("color", "")
- return color or window.front.COLORS.acc_clr
+ if not color:
+ if window.simplesettings.get("tag_color") == "tag_name":
+ color = utils.color_from_name(tag)
+ elif window.simplesettings.get("tag_color") == "random":
+ color = utils.color_random()
+ else:
+ color = window.front.COLORS.acc_clr
+ self.set_tag_info(tag, {"color": color})
+ return color
class RecordStore(BaseStore):
diff --git a/timetagger/app/utils.py b/timetagger/app/utils.py
index 4139d01..01d8031 100644
--- a/timetagger/app/utils.py
+++ b/timetagger/app/utils.py
@@ -104,6 +104,11 @@ def color_from_name(name):
_lasthashedcolors[name] = PALETTE1[color % len(PALETTE1)]
return _lasthashedcolors[name]
+def color_random():
+ """Generate a random color"""
+ clr = "#" + Math.floor(Math.random() * 16777215).toString(16)
+ return clr
+
def create_palettes():
# The Github color palette, consisting of 8 strong colors and 8 lighter variants.
@@ -629,6 +634,7 @@ def __init__(self):
"today_snap_offset": "",
"today_end_offset": "",
"show_stopwatch": True,
+ "tag_color": "default",
}
# The data store for synced source
self._store = None
From cace31dede45cfcfe86216881e817a0204055c90 Mon Sep 17 00:00:00 2001
From: Ethan Vogelsang <38506314+evogelsa@users.noreply.github.com>
Date: Tue, 25 Mar 2025 23:00:18 -0500
Subject: [PATCH 2/3] style: invoke format
---
timetagger/app/utils.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/timetagger/app/utils.py b/timetagger/app/utils.py
index 01d8031..61c4148 100644
--- a/timetagger/app/utils.py
+++ b/timetagger/app/utils.py
@@ -104,6 +104,7 @@ def color_from_name(name):
_lasthashedcolors[name] = PALETTE1[color % len(PALETTE1)]
return _lasthashedcolors[name]
+
def color_random():
"""Generate a random color"""
clr = "#" + Math.floor(Math.random() * 16777215).toString(16)
From e6e7e9260614007577456a244942eca75dc6f03c Mon Sep 17 00:00:00 2001
From: Ethan Vogelsang <38506314+evogelsa@users.noreply.github.com>
Date: Thu, 15 May 2025 21:38:36 -0500
Subject: [PATCH 3/3] feat: improve random color to generate on dialog open
also tidy up the settings dialog options per feedback
---
timetagger/app/dialogs.py | 8 ++++++--
timetagger/app/stores.py | 2 +-
timetagger/app/utils.py | 2 +-
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/timetagger/app/dialogs.py b/timetagger/app/dialogs.py
index 84c2499..2a70b85 100644
--- a/timetagger/app/dialogs.py
+++ b/timetagger/app/dialogs.py
@@ -1646,6 +1646,10 @@ def open(self, mode, record, callback=None):
self._delete_but2.onclick = self._delete2
self.maindiv.addEventListener("click", self._autocompleter.clear)
+ # Generate the next random tag color
+ color = utils.color_random()
+ window.simplesettings.set("next_random_color", color)
+
# Enable for some more info (e.g. during dev)
if False:
for x in [f"ID: {record.key}", f"Modified: {dt.time2localstr(record.mt)}"]:
@@ -3923,8 +3927,8 @@ def open(self, callback=None):
diff --git a/timetagger/app/stores.py b/timetagger/app/stores.py
index 624ce4f..5d43e58 100644
--- a/timetagger/app/stores.py
+++ b/timetagger/app/stores.py
@@ -362,7 +362,7 @@ def get_color_for_tag(self, tag):
if window.simplesettings.get("tag_color") == "tag_name":
color = utils.color_from_name(tag)
elif window.simplesettings.get("tag_color") == "random":
- color = utils.color_random()
+ color = window.simplesettings.get("next_random_color")
else:
color = window.front.COLORS.acc_clr
self.set_tag_info(tag, {"color": color})
diff --git a/timetagger/app/utils.py b/timetagger/app/utils.py
index 61c4148..7470314 100644
--- a/timetagger/app/utils.py
+++ b/timetagger/app/utils.py
@@ -107,7 +107,7 @@ def color_from_name(name):
def color_random():
"""Generate a random color"""
- clr = "#" + Math.floor(Math.random() * 16777215).toString(16)
+ clr = "#" + Math.floor(Math.random() * 16777215).toString(16).padStart(6, "0")
return clr