Bump protocols. Added proto status
Build and Publish / Build and Publish Docker Image (push) Successful in 5m25s

This commit is contained in:
Ultradesu
2026-07-28 22:46:43 +01:00
parent d61d7a6bac
commit 4efcfdc539
4 changed files with 79 additions and 7 deletions
Generated
+1 -1
View File
@@ -1836,7 +1836,7 @@ checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]] [[package]]
name = "furumusic" name = "furumusic"
version = "0.9.6" version = "0.9.7"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
+23 -3
View File
@@ -84,6 +84,7 @@ struct Identity {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct StoredDevice { struct StoredDevice {
device_id: String, device_id: String,
endpoint_id: String,
endpoint_ticket: String, endpoint_ticket: String,
} }
@@ -1573,8 +1574,7 @@ async fn sync_device(
user_id: i64, user_id: i64,
device: &StoredDevice, device: &StoredDevice,
) -> Result<()> { ) -> Result<()> {
let ticket: PeerTicket = device.endpoint_ticket.parse()?; let peer = resolve_device_peer(&service, device).await?;
let peer = service.connect(ticket).await?;
let own_ticket = service.ticket().await?.to_string(); let own_ticket = service.ticket().await?.to_string();
let identity = ensure_identity(pool, user_id, "").await?; let identity = ensure_identity(pool, user_id, "").await?;
let profile = own_profile(pool, user_id, "", &own_ticket).await?; let profile = own_profile(pool, user_id, "", &own_ticket).await?;
@@ -4118,7 +4118,7 @@ pub async fn playlist_content_ids_for_removal(
async fn active_remote_devices(pool: &sqlx::PgPool, user_id: i64) -> Result<Vec<StoredDevice>> { async fn active_remote_devices(pool: &sqlx::PgPool, user_id: i64) -> Result<Vec<StoredDevice>> {
let identity = ensure_identity(pool, user_id, "").await?; let identity = ensure_identity(pool, user_id, "").await?;
let rows = sqlx::query( let rows = sqlx::query(
"SELECT device_id, endpoint_ticket "SELECT device_id, endpoint_id, endpoint_ticket
FROM furumusic__fed_device FROM furumusic__fed_device
WHERE user_id = $1 WHERE user_id = $1
AND trusted_at_ms IS NOT NULL AND trusted_at_ms IS NOT NULL
@@ -4134,11 +4134,31 @@ async fn active_remote_devices(pool: &sqlx::PgPool, user_id: i64) -> Result<Vec<
.into_iter() .into_iter()
.map(|row| StoredDevice { .map(|row| StoredDevice {
device_id: row.get("device_id"), device_id: row.get("device_id"),
endpoint_id: row.get("endpoint_id"),
endpoint_ticket: row.get("endpoint_ticket"), endpoint_ticket: row.get("endpoint_ticket"),
}) })
.collect()) .collect())
} }
async fn resolve_device_peer(
service: &MusicDhtService,
device: &StoredDevice,
) -> Result<music_dht::EndpointId> {
if let Ok(peer) = device.endpoint_id.parse::<music_dht::EndpointId>()
&& (service.connected_peers().contains(&peer)
|| service
.known_peers()
.iter()
.any(|contact| contact.peer_id == peer))
{
// Prefer the live/current-schema DHT contact over a persisted ticket
// that may have been issued before a schema upgrade.
return Ok(peer);
}
let ticket: PeerTicket = device.endpoint_ticket.parse()?;
service.connect(ticket).await.map_err(Into::into)
}
async fn active_device_count(pool: &sqlx::PgPool, user_id: i64) -> Result<i64> { async fn active_device_count(pool: &sqlx::PgPool, user_id: i64) -> Result<i64> {
sqlx::query_scalar( sqlx::query_scalar(
"SELECT COUNT(*) FROM furumusic__fed_device "SELECT COUNT(*) FROM furumusic__fed_device
+19 -3
View File
@@ -757,8 +757,22 @@
</div> </div>
</div> </div>
<template x-if="$store.library.currentArtist.top_tracks && $store.library.currentArtist.top_tracks.length > 0"> <template x-if="$store.library.currentArtist.top_tracks && $store.library.currentArtist.top_tracks.length > 0">
<section class="artist-release-group"> <section class="artist-release-group" x-data="{ expanded: false }">
<h2 class="artist-release-group-title">{{ t.player_top_tracks }}</h2> <div class="artist-release-group-heading">
<h2 class="artist-release-group-title">{{ t.player_top_tracks }}</h2>
<button class="artist-top-tracks-toggle"
type="button"
x-show="$store.library.currentArtist.top_tracks.length > 5"
@click="expanded = !expanded"
:aria-expanded="expanded"
x-cloak>
<span x-text="expanded ? '{{ t.player_collapse }}' : '{{ t.player_expand_all }}'"></span>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
:class="{ expanded: expanded }">
<polyline points="6 9 12 15 18 9"/>
</svg>
</button>
</div>
<div class="track-list-header"> <div class="track-list-header">
<span>#</span> <span>#</span>
<span>{{ t.player_title }}</span> <span>{{ t.player_title }}</span>
@@ -766,7 +780,9 @@
<span></span> <span></span>
<span style="text-align:right">{{ t.player_duration }}</span> <span style="text-align:right">{{ t.player_duration }}</span>
</div> </div>
<template x-for="(track, idx) in $store.library.currentArtist.top_tracks" :key="track.id"> <template x-for="(track, idx) in (expanded
? $store.library.currentArtist.top_tracks
: $store.library.currentArtist.top_tracks.slice(0, 5))" :key="track.id">
<div class="track-row artist-appearance-row" <div class="track-row artist-appearance-row"
:class="{ playing: $store.player.currentTrack && $store.player.currentTrack.id === track.id }" :class="{ playing: $store.player.currentTrack && $store.player.currentTrack.id === track.id }"
@dblclick="$store.queue.playRelease($store.library.currentArtist.top_tracks, idx)"> @dblclick="$store.queue.playRelease($store.library.currentArtist.top_tracks, idx)">
+36
View File
@@ -676,6 +676,42 @@ button.user-stat:hover {
margin-bottom: 14px; margin-bottom: 14px;
text-transform: capitalize; text-transform: capitalize;
} }
.artist-release-group-heading {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-bottom: 14px;
}
.artist-release-group-heading .artist-release-group-title {
margin-bottom: 0;
}
.artist-top-tracks-toggle {
border: 0;
background: transparent;
color: var(--text-subdued);
display: inline-flex;
align-items: center;
gap: 6px;
padding: 5px 7px;
border-radius: 5px;
font: inherit;
font-size: 12px;
font-weight: 700;
cursor: pointer;
}
.artist-top-tracks-toggle:hover {
color: var(--text-primary);
background: var(--bg-hover);
}
.artist-top-tracks-toggle svg {
width: 15px;
height: 15px;
transition: transform 0.18s ease;
}
.artist-top-tracks-toggle svg.expanded {
transform: rotate(180deg);
}
/* Release detail header */ /* Release detail header */
.release-header { .release-header {