Reactive updating of related time

This commit is contained in:
2026-02-07 16:53:40 +03:00
parent db11fabe1a
commit 0edf6e35d7
8 changed files with 101 additions and 4 deletions
+3 -1
View File
@@ -49,11 +49,13 @@ def parse_listens(json: dict) -> dict:
} }
for track in json["listens"]: for track in json["listens"]:
listened_at = track.get("listened_at", 0)
track = track["track_metadata"] track = track["track_metadata"]
new_track = { new_track = {
"artist_name": track["artist_name"], "artist_name": track["artist_name"],
"track_name": track["track_name"] "track_name": track["track_name"],
"listened_at": listened_at
} }
if mb := track.get("mbid_mapping"): if mb := track.get("mbid_mapping"):
@@ -0,0 +1,68 @@
document.addEventListener('alpine:init', () => {
Alpine.data('rtime', (unixTimestamp) => ({
targetDate: new Date(unixTimestamp * 1000),
timeString: '',
timer: null,
interval: 1000,
colorClasses: {
green: 't-green',
yellow: 't-yellow',
orange: 't-orange',
red: 't-red'
},
currentColor: 'green',
get textColorClass() {
return this.colorClasses[this.currentColor];
},
init() {
this.updateTime();
this.timer = setInterval(() => this.updateTime(), this.interval);
this.$el.addEventListener('alpine:removing', () => {
if (this.interval) clearInterval(this.interval);
});
},
updateTime() {
const now = new Date();
const diffInSeconds = Math.floor((now - this.targetDate) / 1000);
const diffInMinutes = Math.floor(diffInSeconds / 60);
const diffInHours = Math.floor(diffInSeconds / 3600);
const diffInDays = Math.floor(diffInSeconds / 86400);
let newInterval = this.interval;
if (diffInSeconds < 60) {
this.timeString = 'a moment ago';
} else if (diffInMinutes < 60) {
this.timeString = `${diffInMinutes} m ago`;
newInterval = 10000;
} else if (diffInHours < 24) {
this.timeString = `${diffInHours} h ago`;
newInterval = 60000;
} else {
this.timeString = `${diffInDays} d ago`;
clearInterval(this.timer);
}
if (diffInMinutes <= 15) {
this.currentColor = 'green';
} else if (diffInHours < 1) {
this.currentColor = 'yellow';
} else if (diffInDays < 1) {
this.currentColor = 'orange';
} else {
this.currentColor = 'red';
}
if (this.interval != newInterval) {
clearInterval(this.timer)
this.timer = setInterval(() => this.updateTime(), newInterval);
}
},
}));
});
@@ -3,9 +3,12 @@
<head> <head>
<title>Sweet Bread</title> <title>Sweet Bread</title>
<link rel="stylesheet" href="/static/style/tw.css">
<link rel="stylesheet" href="/static/style/main.css"> <link rel="stylesheet" href="/static/style/main.css">
<link rel="stylesheet" href="/static/style/risdeveau.css"> <link rel="stylesheet" href="/static/style/risdeveau.css">
<link rel="icon" type="image/webp" href="/static/icon/us/risdeveau.webp" /> <link rel="icon" type="image/webp" href="/static/icon/us/risdeveau.webp" />
<script src="/static/script/rtime.js"></script>
<script <script
src="https://track.lair.moe/api/script.js" src="https://track.lair.moe/api/script.js"
data-site-id="1" data-site-id="1"
@@ -16,6 +19,8 @@
integrity="sha384-/TgkGk7p307TH7EXJDuUlgG3Ce1UVolAOFopFekQkkXihi5u/6OCvVKyz1W+idaz" integrity="sha384-/TgkGk7p307TH7EXJDuUlgG3Ce1UVolAOFopFekQkkXihi5u/6OCvVKyz1W+idaz"
crossorigin="anonymous" crossorigin="anonymous"
></script> ></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta <meta
name="htmx-config" name="htmx-config"
@@ -6,6 +6,13 @@
<div> <div>
<p><b>{{ track.artist_name }}</b></p> <p><b>{{ track.artist_name }}</b></p>
<p>{{ track.track_name }}</p> <p>{{ track.track_name }}</p>
{% if not is_active %}
<p
x-data="rtime({{ track.listened_at }})"
x-text="`Listened ${timeString}`"
:class="textColorClass"
></p>
{% endif %}
</div> </div>
</div> </div>
{% endmacro %} {% endmacro %}
+8 -2
View File
@@ -31,7 +31,10 @@
</div> </div>
</a> </a>
{% endfor %} {% endfor %}
<p>Last updated: {{ rtmsmp(steam.caches.recent.last_updated) }} ago</p> <p
x-data="rtime({{steam.caches.recent.last_updated}})"
x-text="`Last updated: ${timeString}`"
></p>
{% endif %} {% endif %}
{% if steam.caches.owned.data.games %} {% if steam.caches.owned.data.games %}
@@ -58,6 +61,9 @@
</div> </div>
</a> </a>
{% endfor %} {% endfor %}
<p>Last updated: {{ rtmsmp(steam.caches.owned.last_updated) }} ago</p> <p
x-data="rtime({{steam.caches.owned.last_updated}})"
x-text="`Last updated: ${timeString}`"
></p>
{% endif %} {% endif %}
</div> </div>
+1 -1
View File
@@ -3,7 +3,7 @@ from os.path import join
def compile_styles(): def compile_styles():
dir = "blueprints/root/static/style" dir = "blueprints/root/static/style"
files = ("main",) files = ("main", "tw")
for file in files: for file in files:
console(f"sass {join(dir, file+'.scss')} {join(dir, file+'.css')}") console(f"sass {join(dir, file+'.scss')} {join(dir, file+'.css')}")
@@ -18,6 +18,7 @@ $subtext0: #a6adc8;
$subtext1: #bac2de; $subtext1: #bac2de;
$red: #f38ba8; $red: #f38ba8;
$yellow: #f9e2af;
$green: #a6e3a1; $green: #a6e3a1;
$peach: #fab387; $peach: #fab387;
$blue: #89b4fa; $blue: #89b4fa;
+8
View File
@@ -0,0 +1,8 @@
@use "catppuccin" as theme;
.t {
&-red { color: theme.$red; }
&-orange { color: theme.$peach; }
&-yellow { color: theme.$yellow; }
&-green { color: theme.$green; }
}