@rmdes/indiekit-endpoint-funkwhale 1.0.3 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.js +6 -15
- package/lib/controllers/dashboard.js +18 -11
- package/lib/sync.js +19 -0
- package/locales/en.json +2 -2
- package/package.json +1 -2
- package/views/funkwhale.njk +25 -15
- package/assets/styles.css +0 -453
- package/views/favorites.njk +0 -124
- package/views/listenings.njk +0 -129
- package/views/partials/stats-summary.njk +0 -18
- package/views/partials/top-albums.njk +0 -20
- package/views/partials/top-artists.njk +0 -13
- package/views/stats.njk +0 -432
package/views/favorites.njk
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
{% extends "document.njk" %}
|
|
2
|
-
|
|
3
|
-
{% block content %}
|
|
4
|
-
<style>
|
|
5
|
-
.fw-section { margin-bottom: 2rem; }
|
|
6
|
-
.fw-list {
|
|
7
|
-
list-style: none;
|
|
8
|
-
padding: 0;
|
|
9
|
-
margin: 0 0 1rem 0;
|
|
10
|
-
}
|
|
11
|
-
.fw-list-item {
|
|
12
|
-
display: flex;
|
|
13
|
-
align-items: center;
|
|
14
|
-
gap: 0.75rem;
|
|
15
|
-
padding: 0.75rem 0;
|
|
16
|
-
border-bottom: 1px solid var(--color-border, #eee);
|
|
17
|
-
}
|
|
18
|
-
.fw-list-item:last-child { border-bottom: none; }
|
|
19
|
-
.fw-list-item img {
|
|
20
|
-
width: 48px;
|
|
21
|
-
height: 48px;
|
|
22
|
-
object-fit: cover;
|
|
23
|
-
border-radius: 0.25rem;
|
|
24
|
-
flex-shrink: 0;
|
|
25
|
-
}
|
|
26
|
-
.fw-list-item-placeholder {
|
|
27
|
-
width: 48px;
|
|
28
|
-
height: 48px;
|
|
29
|
-
background: var(--color-border, #ddd);
|
|
30
|
-
border-radius: 0.25rem;
|
|
31
|
-
flex-shrink: 0;
|
|
32
|
-
}
|
|
33
|
-
.fw-list-info {
|
|
34
|
-
flex: 1;
|
|
35
|
-
min-width: 0;
|
|
36
|
-
}
|
|
37
|
-
.fw-list-title {
|
|
38
|
-
display: block;
|
|
39
|
-
font-weight: 500;
|
|
40
|
-
text-decoration: none;
|
|
41
|
-
color: inherit;
|
|
42
|
-
white-space: nowrap;
|
|
43
|
-
overflow: hidden;
|
|
44
|
-
text-overflow: ellipsis;
|
|
45
|
-
}
|
|
46
|
-
.fw-list-title:hover { text-decoration: underline; }
|
|
47
|
-
.fw-list-album {
|
|
48
|
-
margin: 0.25rem 0;
|
|
49
|
-
color: var(--color-text-secondary, #666);
|
|
50
|
-
font-size: 0.875rem;
|
|
51
|
-
}
|
|
52
|
-
.fw-meta {
|
|
53
|
-
display: flex;
|
|
54
|
-
gap: 0.5rem;
|
|
55
|
-
color: var(--color-text-secondary, #666);
|
|
56
|
-
font-size: 0.75rem;
|
|
57
|
-
}
|
|
58
|
-
.fw-pagination {
|
|
59
|
-
display: flex;
|
|
60
|
-
align-items: center;
|
|
61
|
-
justify-content: center;
|
|
62
|
-
gap: 1rem;
|
|
63
|
-
margin-top: 1.5rem;
|
|
64
|
-
}
|
|
65
|
-
.fw-pagination-info {
|
|
66
|
-
color: var(--color-text-secondary, #666);
|
|
67
|
-
}
|
|
68
|
-
</style>
|
|
69
|
-
|
|
70
|
-
{% if error %}
|
|
71
|
-
{{ prose({ text: error.message }) }}
|
|
72
|
-
{% else %}
|
|
73
|
-
<section class="fw-section">
|
|
74
|
-
{% if favorites and favorites.length > 0 %}
|
|
75
|
-
<ul class="fw-list">
|
|
76
|
-
{% for favorite in favorites %}
|
|
77
|
-
<li class="fw-list-item">
|
|
78
|
-
{% if favorite.coverUrl %}
|
|
79
|
-
<img src="{{ favorite.coverUrl }}" alt="" loading="lazy">
|
|
80
|
-
{% else %}
|
|
81
|
-
<div class="fw-list-item-placeholder"></div>
|
|
82
|
-
{% endif %}
|
|
83
|
-
<div class="fw-list-info">
|
|
84
|
-
<a href="{{ favorite.trackUrl }}" class="fw-list-title" target="_blank" rel="noopener">
|
|
85
|
-
{{ favorite.artist }} - {{ favorite.track }}
|
|
86
|
-
</a>
|
|
87
|
-
{% if favorite.album %}
|
|
88
|
-
<p class="fw-list-album">{{ favorite.album }}</p>
|
|
89
|
-
{% endif %}
|
|
90
|
-
<small class="fw-meta">
|
|
91
|
-
<span>{{ favorite.duration }}</span>
|
|
92
|
-
<span>Favorited {{ favorite.relativeTime }}</span>
|
|
93
|
-
</small>
|
|
94
|
-
</div>
|
|
95
|
-
</li>
|
|
96
|
-
{% endfor %}
|
|
97
|
-
</ul>
|
|
98
|
-
|
|
99
|
-
{# Pagination #}
|
|
100
|
-
{% if pagination %}
|
|
101
|
-
<nav class="fw-pagination">
|
|
102
|
-
{% if pagination.hasPrev %}
|
|
103
|
-
<a href="?page={{ pagination.current - 1 }}" class="button button--secondary">Previous</a>
|
|
104
|
-
{% endif %}
|
|
105
|
-
<span class="fw-pagination-info">
|
|
106
|
-
Page {{ pagination.current }} of {{ pagination.total }}
|
|
107
|
-
</span>
|
|
108
|
-
{% if pagination.hasNext %}
|
|
109
|
-
<a href="?page={{ pagination.current + 1 }}" class="button button--secondary">Next</a>
|
|
110
|
-
{% endif %}
|
|
111
|
-
</nav>
|
|
112
|
-
{% endif %}
|
|
113
|
-
{% else %}
|
|
114
|
-
{{ prose({ text: __("funkwhale.noFavorites") }) }}
|
|
115
|
-
{% endif %}
|
|
116
|
-
</section>
|
|
117
|
-
|
|
118
|
-
{{ button({
|
|
119
|
-
classes: "button--secondary",
|
|
120
|
-
href: mountPath,
|
|
121
|
-
text: "Back to Dashboard"
|
|
122
|
-
}) }}
|
|
123
|
-
{% endif %}
|
|
124
|
-
{% endblock %}
|
package/views/listenings.njk
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
{% extends "document.njk" %}
|
|
2
|
-
|
|
3
|
-
{% block content %}
|
|
4
|
-
<style>
|
|
5
|
-
.fw-section { margin-bottom: 2rem; }
|
|
6
|
-
.fw-list {
|
|
7
|
-
list-style: none;
|
|
8
|
-
padding: 0;
|
|
9
|
-
margin: 0 0 1rem 0;
|
|
10
|
-
}
|
|
11
|
-
.fw-list-item {
|
|
12
|
-
display: flex;
|
|
13
|
-
align-items: center;
|
|
14
|
-
gap: 0.75rem;
|
|
15
|
-
padding: 0.75rem 0;
|
|
16
|
-
border-bottom: 1px solid var(--color-border, #eee);
|
|
17
|
-
}
|
|
18
|
-
.fw-list-item:last-child { border-bottom: none; }
|
|
19
|
-
.fw-list-item img {
|
|
20
|
-
width: 48px;
|
|
21
|
-
height: 48px;
|
|
22
|
-
object-fit: cover;
|
|
23
|
-
border-radius: 0.25rem;
|
|
24
|
-
flex-shrink: 0;
|
|
25
|
-
}
|
|
26
|
-
.fw-list-item-placeholder {
|
|
27
|
-
width: 48px;
|
|
28
|
-
height: 48px;
|
|
29
|
-
background: var(--color-border, #ddd);
|
|
30
|
-
border-radius: 0.25rem;
|
|
31
|
-
flex-shrink: 0;
|
|
32
|
-
}
|
|
33
|
-
.fw-list-info {
|
|
34
|
-
flex: 1;
|
|
35
|
-
min-width: 0;
|
|
36
|
-
}
|
|
37
|
-
.fw-list-title {
|
|
38
|
-
display: block;
|
|
39
|
-
font-weight: 500;
|
|
40
|
-
text-decoration: none;
|
|
41
|
-
color: inherit;
|
|
42
|
-
white-space: nowrap;
|
|
43
|
-
overflow: hidden;
|
|
44
|
-
text-overflow: ellipsis;
|
|
45
|
-
}
|
|
46
|
-
.fw-list-title:hover { text-decoration: underline; }
|
|
47
|
-
.fw-list-album {
|
|
48
|
-
margin: 0.25rem 0;
|
|
49
|
-
color: var(--color-text-secondary, #666);
|
|
50
|
-
font-size: 0.875rem;
|
|
51
|
-
}
|
|
52
|
-
.fw-meta {
|
|
53
|
-
display: flex;
|
|
54
|
-
gap: 0.5rem;
|
|
55
|
-
color: var(--color-text-secondary, #666);
|
|
56
|
-
font-size: 0.75rem;
|
|
57
|
-
}
|
|
58
|
-
.fw-pagination {
|
|
59
|
-
display: flex;
|
|
60
|
-
align-items: center;
|
|
61
|
-
justify-content: center;
|
|
62
|
-
gap: 1rem;
|
|
63
|
-
margin-top: 1.5rem;
|
|
64
|
-
}
|
|
65
|
-
.fw-pagination-info {
|
|
66
|
-
color: var(--color-text-secondary, #666);
|
|
67
|
-
}
|
|
68
|
-
</style>
|
|
69
|
-
|
|
70
|
-
{% if error %}
|
|
71
|
-
{{ prose({ text: error.message }) }}
|
|
72
|
-
{% else %}
|
|
73
|
-
<section class="fw-section">
|
|
74
|
-
{% if listenings and listenings.length > 0 %}
|
|
75
|
-
<ul class="fw-list">
|
|
76
|
-
{% for listening in listenings %}
|
|
77
|
-
<li class="fw-list-item">
|
|
78
|
-
{% if listening.coverUrl %}
|
|
79
|
-
<img src="{{ listening.coverUrl }}" alt="" loading="lazy">
|
|
80
|
-
{% else %}
|
|
81
|
-
<div class="fw-list-item-placeholder"></div>
|
|
82
|
-
{% endif %}
|
|
83
|
-
<div class="fw-list-info">
|
|
84
|
-
<a href="{{ listening.trackUrl }}" class="fw-list-title" target="_blank" rel="noopener">
|
|
85
|
-
{{ listening.artist }} - {{ listening.track }}
|
|
86
|
-
</a>
|
|
87
|
-
{% if listening.album %}
|
|
88
|
-
<p class="fw-list-album">{{ listening.album }}</p>
|
|
89
|
-
{% endif %}
|
|
90
|
-
<small class="fw-meta">
|
|
91
|
-
<span>{{ listening.duration }}</span>
|
|
92
|
-
<span>{{ listening.relativeTime }}</span>
|
|
93
|
-
</small>
|
|
94
|
-
</div>
|
|
95
|
-
{% if listening.status == "now-playing" %}
|
|
96
|
-
{{ badge({ color: "green", text: __("funkwhale.nowPlaying") }) }}
|
|
97
|
-
{% elif listening.status == "recently-played" %}
|
|
98
|
-
{{ badge({ color: "blue", text: __("funkwhale.recentlyPlayed") }) }}
|
|
99
|
-
{% endif %}
|
|
100
|
-
</li>
|
|
101
|
-
{% endfor %}
|
|
102
|
-
</ul>
|
|
103
|
-
|
|
104
|
-
{# Pagination #}
|
|
105
|
-
{% if pagination %}
|
|
106
|
-
<nav class="fw-pagination">
|
|
107
|
-
{% if pagination.hasPrev %}
|
|
108
|
-
<a href="?page={{ pagination.current - 1 }}" class="button button--secondary">Previous</a>
|
|
109
|
-
{% endif %}
|
|
110
|
-
<span class="fw-pagination-info">
|
|
111
|
-
Page {{ pagination.current }} of {{ pagination.total }}
|
|
112
|
-
</span>
|
|
113
|
-
{% if pagination.hasNext %}
|
|
114
|
-
<a href="?page={{ pagination.current + 1 }}" class="button button--secondary">Next</a>
|
|
115
|
-
{% endif %}
|
|
116
|
-
</nav>
|
|
117
|
-
{% endif %}
|
|
118
|
-
{% else %}
|
|
119
|
-
{{ prose({ text: __("funkwhale.noRecentPlays") }) }}
|
|
120
|
-
{% endif %}
|
|
121
|
-
</section>
|
|
122
|
-
|
|
123
|
-
{{ button({
|
|
124
|
-
classes: "button--secondary",
|
|
125
|
-
href: mountPath,
|
|
126
|
-
text: "Back to Dashboard"
|
|
127
|
-
}) }}
|
|
128
|
-
{% endif %}
|
|
129
|
-
{% endblock %}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
<div class="funkwhale-stats-grid">
|
|
2
|
-
<div class="funkwhale-stat">
|
|
3
|
-
<span class="funkwhale-stat__value">{{ summary.totalPlays }}</span>
|
|
4
|
-
<span class="funkwhale-stat__label">{{ __("funkwhale.plays") }}</span>
|
|
5
|
-
</div>
|
|
6
|
-
<div class="funkwhale-stat">
|
|
7
|
-
<span class="funkwhale-stat__value">{{ summary.uniqueTracks }}</span>
|
|
8
|
-
<span class="funkwhale-stat__label">{{ __("funkwhale.tracks") }}</span>
|
|
9
|
-
</div>
|
|
10
|
-
<div class="funkwhale-stat">
|
|
11
|
-
<span class="funkwhale-stat__value">{{ summary.uniqueArtists }}</span>
|
|
12
|
-
<span class="funkwhale-stat__label">{{ __("funkwhale.artists") }}</span>
|
|
13
|
-
</div>
|
|
14
|
-
<div class="funkwhale-stat">
|
|
15
|
-
<span class="funkwhale-stat__value">{{ summary.totalDurationFormatted }}</span>
|
|
16
|
-
<span class="funkwhale-stat__label">{{ __("funkwhale.listeningTime") }}</span>
|
|
17
|
-
</div>
|
|
18
|
-
</div>
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
{% if topAlbums and topAlbums.length > 0 %}
|
|
2
|
-
<ul class="funkwhale-album-grid">
|
|
3
|
-
{% for album in topAlbums %}
|
|
4
|
-
<li class="funkwhale-album">
|
|
5
|
-
{% if album.coverUrl %}
|
|
6
|
-
<img src="{{ album.coverUrl }}" alt="" class="funkwhale-album__cover" loading="lazy">
|
|
7
|
-
{% else %}
|
|
8
|
-
<div class="funkwhale-album__cover funkwhale-album__cover--placeholder"></div>
|
|
9
|
-
{% endif %}
|
|
10
|
-
<div class="funkwhale-album__info">
|
|
11
|
-
<span class="funkwhale-album__title">{{ album.title }}</span>
|
|
12
|
-
<span class="funkwhale-album__artist">{{ album.artist }}</span>
|
|
13
|
-
<small class="funkwhale-meta">{{ album.playCount }} {{ __("funkwhale.plays") }}</small>
|
|
14
|
-
</div>
|
|
15
|
-
</li>
|
|
16
|
-
{% endfor %}
|
|
17
|
-
</ul>
|
|
18
|
-
{% else %}
|
|
19
|
-
{{ prose({ text: "No data yet" }) }}
|
|
20
|
-
{% endif %}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{% if topArtists and topArtists.length > 0 %}
|
|
2
|
-
<ol class="funkwhale-top-list">
|
|
3
|
-
{% for artist in topArtists %}
|
|
4
|
-
<li class="funkwhale-top-list__item">
|
|
5
|
-
<span class="funkwhale-top-list__rank">{{ loop.index }}</span>
|
|
6
|
-
<span class="funkwhale-top-list__name">{{ artist.name }}</span>
|
|
7
|
-
<span class="funkwhale-top-list__count">{{ artist.playCount }} {{ __("funkwhale.plays") }}</span>
|
|
8
|
-
</li>
|
|
9
|
-
{% endfor %}
|
|
10
|
-
</ol>
|
|
11
|
-
{% else %}
|
|
12
|
-
{{ prose({ text: "No data yet" }) }}
|
|
13
|
-
{% endif %}
|