Reactive updating of related time
This commit is contained in:
@@ -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 %}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user