+31
-15
src/dashboard.zig
+31
-15
src/dashboard.zig
···
70
70
\\ border-bottom: 1px solid #1a1a1a;
71
71
\\ }
72
72
\\ .feed-item:last-child { border-bottom: none; }
73
+
\\ .feed-info { flex: 1; }
73
74
\\ .feed-name { color: #ccc; }
74
75
\\ .feed-desc { color: #555; font-size: 11px; }
76
+
\\ .feed-link { display: flex; align-items: center; padding: 0.4rem 0.6rem; background: #1a1a1a; border-radius: 4px; }
77
+
\\ .feed-link:hover { background: #252525; }
78
+
\\ .feed-link svg { width: 16px; height: 16px; fill: #1185fe; }
75
79
\\ .status-bar {
76
80
\\ display: flex;
77
81
\\ align-items: center;
···
126
130
\\
127
131
\\ <div class="feeds">
128
132
\\ <div class="feed-item">
129
-
\\ <div>
130
-
\\ <a href="https://bsky.app/profile/did:plc:vs3hnzq2daqbszxlysywzy54/feed/music-atmosphere" class="feed-name">music atmosphere</a>
133
+
\\ <div class="feed-info">
134
+
\\ <div class="feed-name">music atmosphere</div>
131
135
\\ <div class="feed-desc">all music posts</div>
132
136
\\ </div>
137
+
\\ <a href="https://bsky.app/profile/did:plc:vs3hnzq2daqbszxlysywzy54/feed/music-atmosphere" class="feed-link" title="open in bluesky"><svg viewBox="0 0 568 501"><path d="M123.121 33.664C188.241 82.553 258.281 181.68 284 234.873c25.719-53.192 95.759-152.32 160.879-201.21C491.866-1.611 568-28.906 568 57.947c0 17.346-9.945 145.713-15.778 166.555-20.275 72.453-94.155 90.933-159.875 79.748C507.222 323.8 536.444 388.56 473.333 453.32c-119.86 122.992-172.272-30.859-185.702-70.281-2.462-7.227-3.614-10.608-3.631-7.733-.017-2.875-1.169.506-3.631 7.733-13.43 39.422-65.842 193.273-185.702 70.281-63.111-64.76-33.89-129.52 80.986-149.07-65.72 11.185-139.6-7.295-159.875-79.748C9.945 203.659 0 75.291 0 57.946 0-28.906 76.135-1.612 123.121 33.664Z"/></svg></a>
133
138
\\ </div>
134
139
\\ <div class="feed-item">
135
-
\\ <div>
136
-
\\ <a href="https://bsky.app/profile/did:plc:vs3hnzq2daqbszxlysywzy54/feed/music-following" class="feed-name">music (following)</a>
140
+
\\ <div class="feed-info">
141
+
\\ <div class="feed-name">music (following)</div>
137
142
\\ <div class="feed-desc">only from people you follow</div>
138
143
\\ </div>
144
+
\\ <a href="https://bsky.app/profile/did:plc:vs3hnzq2daqbszxlysywzy54/feed/music-following" class="feed-link" title="open in bluesky"><svg viewBox="0 0 568 501"><path d="M123.121 33.664C188.241 82.553 258.281 181.68 284 234.873c25.719-53.192 95.759-152.32 160.879-201.21C491.866-1.611 568-28.906 568 57.947c0 17.346-9.945 145.713-15.778 166.555-20.275 72.453-94.155 90.933-159.875 79.748C507.222 323.8 536.444 388.56 473.333 453.32c-119.86 122.992-172.272-30.859-185.702-70.281-2.462-7.227-3.614-10.608-3.631-7.733-.017-2.875-1.169.506-3.631 7.733-13.43 39.422-65.842 193.273-185.702 70.281-63.111-64.76-33.89-129.52 80.986-149.07-65.72 11.185-139.6-7.295-159.875-79.748C9.945 203.659 0 75.291 0 57.946 0-28.906 76.135-1.612 123.121 33.664Z"/></svg></a>
139
145
\\ </div>
140
146
\\ </div>
141
147
\\
···
171
177
const total = platforms.soundcloud + platforms.bandcamp + platforms.spotify + platforms.plyr;
172
178
173
179
if (total > 0) {
174
-
// calculate percentages
175
-
const sc_pct = (platforms.soundcloud * 100) / total;
176
-
const bc_pct = (platforms.bandcamp * 100) / total;
177
-
const sp_pct = (platforms.spotify * 100) / total;
178
-
const pl_pct = (platforms.plyr * 100) / total;
180
+
// helper to format percentage - shows "<1%" for non-zero values that round to 0
181
+
const PlatformData = struct { name: []const u8, count: u64, color: []const u8 };
182
+
const platform_list = [_]PlatformData{
183
+
.{ .name = "soundcloud", .count = platforms.soundcloud, .color = "#ff5500" },
184
+
.{ .name = "bandcamp", .count = platforms.bandcamp, .color = "#1da0c3" },
185
+
.{ .name = "spotify", .count = platforms.spotify, .color = "#1db954" },
186
+
.{ .name = "plyr.fm", .count = platforms.plyr, .color = "#7c3aed" },
187
+
};
179
188
180
-
try w.print(
181
-
\\ <div class="platform-row"><span class="platform-name">soundcloud</span><div class="bar"><div class="bar-fill" style="width:{d}%;background:#ff5500"></div></div><span class="platform-pct">{d}%</span></div>
182
-
\\ <div class="platform-row"><span class="platform-name">bandcamp</span><div class="bar"><div class="bar-fill" style="width:{d}%;background:#1da0c3"></div></div><span class="platform-pct">{d}%</span></div>
183
-
\\ <div class="platform-row"><span class="platform-name">spotify</span><div class="bar"><div class="bar-fill" style="width:{d}%;background:#1db954"></div></div><span class="platform-pct">{d}%</span></div>
184
-
\\ <div class="platform-row"><span class="platform-name">plyr.fm</span><div class="bar"><div class="bar-fill" style="width:{d}%;background:#7c3aed"></div></div><span class="platform-pct">{d}%</span></div>
185
-
, .{ sc_pct, sc_pct, bc_pct, bc_pct, sp_pct, sp_pct, pl_pct, pl_pct });
189
+
for (platform_list) |p| {
190
+
const pct = (p.count * 100) / total;
191
+
const bar_width = if (p.count > 0 and pct == 0) @as(u64, 1) else pct; // min 1% width if non-zero
192
+
try w.print(
193
+
\\ <div class="platform-row"><span class="platform-name">{s}</span><div class="bar"><div class="bar-fill" style="width:{d}%;background:{s}"></div></div><span class="platform-pct">
194
+
, .{ p.name, bar_width, p.color });
195
+
if (p.count > 0 and pct == 0) {
196
+
try w.writeAll("<1%");
197
+
} else {
198
+
try w.print("{d}%", .{pct});
199
+
}
200
+
try w.writeAll("</span></div>\n");
201
+
}
186
202
} else {
187
203
try w.writeAll(
188
204
\\ <div class="platform-row"><span class="criteria-list">collecting data...</span></div>