diff --git a/PROJECT.org b/PROJECT.org
index 6493d67..3caa4f3 100644
--- a/PROJECT.org
+++ b/PROJECT.org
@@ -92,7 +92,7 @@ fetching and simple saving.
:LOGBOOK:
CLOCK: [2025-07-09 Wed 09:55]--[2025-07-09 Wed 10:15] => 0:20
:END:
-* Backlog [17/37]
+* Backlog [18/37]
** TODO [#C] Create small utility to clean up tracks scrobbled with wonky playback times :vrobbler:personal:bug:music:scrobbles:
** TODO [#C] Move to using more robust mopidy-webhooks pacakge form pypi :utility:improvement:
:PROPERTIES:
@@ -431,7 +431,7 @@ https://app.todoist.com/app/task/add-a-csv-endpoint-for-users-book-reads-that-li
** TODO [#A] When creating org-mode tasks, don't copy comments :vrobbler:bug:scrobbles:tasks:
** TODO Add sentiment parsing for Scrobbles with notes :vrobbler:project:scrobbles:sentiment:
-** STRT Fix display of notes so they look like stickies :vrobbler:project:personal:notes:scrobbles:
+** DONE Fix display of notes so they look like stickies :vrobbler:project:personal:notes:scrobbles:
:PROPERTIES:
:ID: 0ace8814-e96e-fa54-28d1-c57dcb508f1e
:END:
diff --git a/vrobbler/apps/scrobbles/dataclasses.py b/vrobbler/apps/scrobbles/dataclasses.py
index e3adc08..945c25e 100644
--- a/vrobbler/apps/scrobbles/dataclasses.py
+++ b/vrobbler/apps/scrobbles/dataclasses.py
@@ -65,6 +65,24 @@ class BaseLogData(JSONDataclass):
)
return note_str
+ def notes_as_html(self) -> str:
+ if not self.notes:
+ return ""
+
+ notes_list = []
+ if isinstance(self.notes, str):
+ notes_list = [self.notes]
+ elif isinstance(self.notes, list):
+ notes_list = self.notes
+
+ html_notes = []
+ for note in notes_list:
+ escaped_note = note.encode("utf-8").decode("unicode_escape")
+ for line in escaped_note.split("\n"):
+ if line.strip():
+ html_notes.append(f'
{line}
')
+ return "".join(html_notes)
+
@dataclass
class LongPlayLogData(JSONDataclass):
diff --git a/vrobbler/templates/base.html b/vrobbler/templates/base.html
index 96051c5..d1cbc05 100644
--- a/vrobbler/templates/base.html
+++ b/vrobbler/templates/base.html
@@ -167,6 +167,37 @@
box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
}
#scrobble-form { width: 100% }
+
+ .sticky-notes-container {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ }
+
+ .sticky-note {
+ padding: 8px;
+ border: 1px solid #ccc;
+ max-width: 200px;
+ font-size: 0.9em;
+ line-height: 1.3;
+ background: #fff9c4;
+ }
+
+ .sticky-note:nth-child(even) {
+ background: #ffccbc;
+ }
+
+ .sticky-note:nth-child(3n) {
+ background: #b3e5fc;
+ }
+
+ .sticky-note:nth-child(4n) {
+ background: #c8e6c9;
+ }
+
+ .sticky-note:nth-child(5n) {
+ background: #e1bee7;
+ }
{% block head_extra %}{% endblock %}
diff --git a/vrobbler/templates/lifeevents/lifeevent_detail.html b/vrobbler/templates/lifeevents/lifeevent_detail.html
index 0c0baa5..63dbbb4 100644
--- a/vrobbler/templates/lifeevents/lifeevent_detail.html
+++ b/vrobbler/templates/lifeevents/lifeevent_detail.html
@@ -37,7 +37,7 @@
| {{scrobble.local_timestamp}} |
{{scrobble.logdata.title}} |
- {{scrobble.logdata.notes_as_str|safe}} |
+ {{scrobble.logdata.notes_as_html|safe}} |
{{scrobble.source}} |
{% endfor %}
diff --git a/vrobbler/templates/scrobbles/scrobble_detail.html b/vrobbler/templates/scrobbles/scrobble_detail.html
index 667e32f..7ee90d5 100644
--- a/vrobbler/templates/scrobbles/scrobble_detail.html
+++ b/vrobbler/templates/scrobbles/scrobble_detail.html
@@ -12,11 +12,13 @@
{{ object.media_obj }} - {{object.media_type}}
-{% with notes_string=object.logdata.notes_as_str %}
-{% if notes_string %}
+{% with notes_html=object.logdata.notes_as_html %}
+{% if notes_html %}
Notes
-
{{ notes_string }}
+
+ {{ notes_html|safe }}
+
{% endif %}
{% endwith %}
diff --git a/vrobbler/templates/tasks/task_detail.html b/vrobbler/templates/tasks/task_detail.html
index fdc3333..a055b9f 100644
--- a/vrobbler/templates/tasks/task_detail.html
+++ b/vrobbler/templates/tasks/task_detail.html
@@ -64,7 +64,7 @@
| {{scrobble.local_timestamp}} |
{{scrobble.logdata.title}} |
- {{scrobble.logdata.notes_as_str|safe}} |
+ {{scrobble.logdata.notes_as_html|safe}} |
{{scrobble.source}} |
{% endfor %}