✏️ amélioration des messages d'erreur avec nom du lecteur
- Ajout de `rendererName` computed property dans plusieurs composants pour afficher le nom convivial du lecteur (ou l'ID en fallback) - Mise à jour des messages d’erreur dans CurrentTrack, TransportControls et VolumeControl pour inclure le nom du lecteur (ex: « Sonos One » — impossible de…) - Amélioration du message d’erreur dans useRenderers.ts : « Impossible de rafraîchir la liste des lecteurs audio » + message plus spécifique pour les snapshots - Ajout de l’import `computed` manquant dans VolumeControl.vue
This commit is contained in:
@@ -13,6 +13,7 @@ const props = defineProps<{
|
||||
const { state } = useRenderer(toRef(props, "rendererId"));
|
||||
const uiStore = useUIStore();
|
||||
const metadata = computed(() => state.value?.current_track);
|
||||
const rendererName = computed(() => state.value?.friendly_name ?? props.rendererId);
|
||||
const isSeeking = ref(false);
|
||||
const isDragging = ref(false);
|
||||
const dragProgress = ref(0);
|
||||
@@ -149,7 +150,7 @@ function handleProgressBarMouseDown(event: MouseEvent) {
|
||||
await api.seekTo(props.rendererId, newPositionSeconds);
|
||||
} catch (error) {
|
||||
uiStore.notifyError(
|
||||
`Impossible de seek: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
`« ${rendererName.value} » — impossible de changer la position: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
);
|
||||
// En cas d'erreur, réinitialiser
|
||||
seekTargetMs.value = null;
|
||||
@@ -188,7 +189,7 @@ async function handleProgressBarClick(event: MouseEvent) {
|
||||
await api.seekTo(props.rendererId, newPositionSeconds);
|
||||
} catch (error) {
|
||||
uiStore.notifyError(
|
||||
`Impossible de seek: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
`« ${rendererName.value} » — impossible de changer la position: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
);
|
||||
// En cas d'erreur, réinitialiser
|
||||
seekTargetMs.value = null;
|
||||
@@ -251,7 +252,7 @@ function handleOverlayProgressBarTouchStart(event: TouchEvent) {
|
||||
await api.seekTo(props.rendererId, newPositionSeconds);
|
||||
} catch (error) {
|
||||
uiStore.notifyError(
|
||||
`Impossible de seek: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
`« ${rendererName.value} » — impossible de changer la position: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
);
|
||||
seekTargetMs.value = null;
|
||||
dragProgress.value = 0;
|
||||
|
||||
@@ -20,12 +20,14 @@ const isStopped = computed(
|
||||
state.value?.transport_state === "NO_MEDIA",
|
||||
);
|
||||
|
||||
const rendererName = computed(() => state.value?.friendly_name ?? props.rendererId);
|
||||
|
||||
async function handlePlay() {
|
||||
try {
|
||||
await resumeOrPlayFromQueue(props.rendererId);
|
||||
} catch (error) {
|
||||
uiStore.notifyError(
|
||||
`Impossible de démarrer la lecture: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
`« ${rendererName.value} » — impossible de démarrer la lecture: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -35,7 +37,7 @@ async function handlePause() {
|
||||
await pause(props.rendererId);
|
||||
} catch (error) {
|
||||
uiStore.notifyError(
|
||||
`Impossible de mettre en pause: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
`« ${rendererName.value} » — impossible de mettre en pause: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -45,7 +47,7 @@ async function handleStop() {
|
||||
await stop(props.rendererId);
|
||||
} catch (error) {
|
||||
uiStore.notifyError(
|
||||
`Impossible d'arrêter la lecture: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
`« ${rendererName.value} » — impossible d'arrêter la lecture: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -55,7 +57,7 @@ async function handleNext() {
|
||||
await next(props.rendererId);
|
||||
} catch (error) {
|
||||
uiStore.notifyError(
|
||||
`Impossible de passer au morceau suivant: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
`« ${rendererName.value} » — impossible de passer au morceau suivant: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, toRef } from "vue";
|
||||
import { ref, watch, computed, toRef } from "vue";
|
||||
import { useRenderer, useRenderers } from "@/composables/useRenderers";
|
||||
import { useUIStore } from "@/stores/ui";
|
||||
import { Volume2, VolumeX } from "lucide-vue-next";
|
||||
@@ -12,6 +12,7 @@ const { state } = useRenderer(toRef(props, "rendererId"));
|
||||
const { setVolume, toggleMute } = useRenderers();
|
||||
const uiStore = useUIStore();
|
||||
|
||||
const rendererName = computed(() => state.value?.friendly_name ?? props.rendererId);
|
||||
const localVolume = ref(state.value?.volume ?? 50);
|
||||
|
||||
// Synchroniser localVolume avec le state
|
||||
@@ -41,7 +42,7 @@ function handleVolumeChange(event: Event) {
|
||||
await setVolume(props.rendererId, localVolume.value);
|
||||
} catch (error) {
|
||||
uiStore.notifyError(
|
||||
`Impossible de régler le volume: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
`« ${rendererName.value} » — impossible de régler le volume: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
);
|
||||
}
|
||||
debounceTimer = null;
|
||||
@@ -53,7 +54,7 @@ async function handleToggleMute() {
|
||||
await toggleMute(props.rendererId);
|
||||
} catch (error) {
|
||||
uiStore.notifyError(
|
||||
`Impossible de basculer le mode muet: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
`« ${rendererName.value} » — impossible de couper/rétablir le son: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ const { renderer, state, queue, refresh } = useRenderer(
|
||||
toRef(props, "rendererId"),
|
||||
);
|
||||
const uiStore = useUIStore();
|
||||
const rendererName = computed(() => state.value?.friendly_name ?? props.rendererId);
|
||||
|
||||
// Détection mobile portrait pour afficher le drawer au lieu de la colonne
|
||||
const isMobilePortrait = useMediaQuery(
|
||||
@@ -59,7 +60,7 @@ async function handleQueueItemClick(item: QueueItem) {
|
||||
error,
|
||||
);
|
||||
uiStore.notifyError(
|
||||
`Erreur: ${error instanceof Error ? error.message : "Impossible de sauter à cet item"}`,
|
||||
`« ${rendererName.value} » — impossible de lire ce morceau: ${error instanceof Error ? error.message : "Erreur inconnue"}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,7 +342,7 @@ async function fetchRenderers(force = false, retries = 2) {
|
||||
error.value = lastError?.message ?? "Erreur fetch renderers";
|
||||
|
||||
// Notifier l'utilisateur en cas d'erreur finale
|
||||
uiStore.notifyError("Impossible de rafraîchir la liste des renderers");
|
||||
uiStore.notifyError("Impossible de rafraîchir la liste des lecteurs audio");
|
||||
}
|
||||
|
||||
async function fetchRendererSnapshot(
|
||||
@@ -383,7 +383,8 @@ async function fetchRendererSnapshot(
|
||||
snapshots.delete(rendererId);
|
||||
|
||||
// Notifier l'utilisateur
|
||||
uiStore.notifyError(`Impossible de récupérer l'état du renderer`);
|
||||
const name = renderersCache.value.get(rendererId)?.friendly_name ?? rendererId;
|
||||
uiStore.notifyError(`Impossible de récupérer l'état de « ${name} »`);
|
||||
} finally {
|
||||
// Toujours nettoyer le flag de chargement
|
||||
loadingIds.delete(rendererId);
|
||||
|
||||
Reference in New Issue
Block a user