:recycle!: Normalize UDN comparison and improve WebRenderer detection

- Fix renderer filtering logic to normalize `udn` and id by stripping 'uuid:' prefix
- Replace fragile model_name-based detection with reliable friendly-name check for WebRenderers ('Web Audio – ' prefix)
- Add `manufacturer` field to renderer types and registry
- Update badge count in UnifiedControlView.vue to use filtered renderers
This commit is contained in:
2026-04-05 23:42:25 +02:00
parent 813fc97fa1
commit 23b1ce7661
5 changed files with 17 additions and 10 deletions

View File

@@ -36,12 +36,14 @@ const myUdn = computed(() => webRenderer.rendererUdn.value);
const filteredRenderers = computed(() => { const filteredRenderers = computed(() => {
const udn = myUdn.value; const udn = myUdn.value;
const normalizedUdn = udn?.replace(/^uuid:/, '') ?? null;
return allRenderers.value.filter((r: RendererSummary) => { return allRenderers.value.filter((r: RendererSummary) => {
// Show only our own WebRenderer based on UDN match // WebRenderers have "Web Audio " as friendly_name prefix
const isWebRenderer = r.model_name?.includes("WebRenderer") ?? false; const isWebRenderer = r.friendly_name?.startsWith("Web Audio ") ?? false;
if (isWebRenderer) { if (isWebRenderer) {
if (udn === null) return false; if (normalizedUdn === null) return false;
return r.id === udn; const normalizedId = r.id.replace(/^uuid:/, '');
return normalizedId === normalizedUdn;
} }
return true; return true;
}); });

View File

@@ -63,6 +63,7 @@ function ensureSSEInitialized() {
id: rendererId, id: rendererId,
friendly_name: event.friendly_name, friendly_name: event.friendly_name,
model_name: event.model_name, model_name: event.model_name,
manufacturer: event.manufacturer,
protocol: "upnp", // Valeur par défaut, sera mise à jour par le fetch protocol: "upnp", // Valeur par défaut, sera mise à jour par le fetch
capabilities: { capabilities: {
has_avtransport: false, has_avtransport: false,

View File

@@ -29,6 +29,7 @@ export interface RendererSummary {
id: string; id: string;
friendly_name: string; friendly_name: string;
model_name: string; model_name: string;
manufacturer?: string;
protocol: RendererProtocolSummary; protocol: RendererProtocolSummary;
capabilities: RendererCapabilitiesSummary; capabilities: RendererCapabilitiesSummary;
online: boolean; online: boolean;

View File

@@ -77,9 +77,9 @@ const onlineServersCount = computed(
() => allServers.value.filter((s) => s.online).length, () => allServers.value.filter((s) => s.online).length,
); );
// Nombre de renderers online pour afficher dans le badge // Nombre de renderers online (filtrés) pour afficher dans le badge
const onlineRenderersCount = computed( const onlineRenderersCount = computed(
() => allRenderers.value.filter((r) => r.online).length, () => filterRenderers(allRenderers.value).filter((r) => r.online).length,
); );
// Gestion de l'ouverture du drawer depuis le bouton // Gestion de l'ouverture du drawer depuis le bouton
@@ -106,11 +106,14 @@ function handleRendererSelect(rendererId: string) {
// Filter to show only our own WebRenderer based on UDN match // Filter to show only our own WebRenderer based on UDN match
function filterRenderers(renderers: typeof allRenderers.value) { function filterRenderers(renderers: typeof allRenderers.value) {
const myUdn = webRenderer.rendererUdn.value; const myUdn = webRenderer.rendererUdn.value;
const normalizedUdn = myUdn?.replace(/^uuid:/, '') ?? null;
return renderers.filter((r) => { return renderers.filter((r) => {
const isWebRenderer = r.model_name?.includes("WebRenderer") ?? false; // WebRenderers have "Web Audio " as friendly_name prefix
const isWebRenderer = r.friendly_name?.startsWith("Web Audio ") ?? false;
if (isWebRenderer) { if (isWebRenderer) {
if (myUdn === null) return false; if (normalizedUdn === null) return false;
return r.id === myUdn; const normalizedId = r.id.replace(/^uuid:/, '');
return normalizedId === normalizedUdn;
} }
return true; return true;
}); });

View File

@@ -358,7 +358,7 @@ impl MediaRendererRegistry {
udn_with_prefix.clone(), udn_with_prefix.clone(),
model.friendly_name().to_string(), model.friendly_name().to_string(),
model.model_name().to_string(), model.model_name().to_string(),
"PMOMusic".to_string(), "PMOMusic-WebRenderer".to_string(),
RendererProtocol::UpnpAvOnly, RendererProtocol::UpnpAvOnly,
RendererCapabilities { RendererCapabilities {
has_avtransport: true, has_avtransport: true,