feat: unify search state and dynamic container routing

Refactor search handling across the frontend and backend to use a unified reactive state and dynamic container ID generation. The frontend now leverages a centralized `useMediaServers` composable for search queries and results, while the backend computes container IDs dynamically from source entries instead of using hardcoded values. Bumps version to 0.3.52.
This commit is contained in:
2026-06-11 21:50:10 +02:00
parent 8179c0e239
commit 0dab3077cf
8 changed files with 57 additions and 91 deletions

View File

@@ -22,17 +22,14 @@ const {
loading,
loadingMore,
error,
searchResults,
searchQuery,
searchServer,
clearSearch,
} = useMediaServers();
const searchInput = ref('');
async function handleSearch() {
if (searchInput.value.trim()) {
const virtualId = await searchServer(props.serverId, searchInput.value.trim(), props.containerId);
const virtualId = await searchServer(props.serverId, searchInput.value.trim());
if (virtualId) {
emit("navigate", virtualId);
}
@@ -41,11 +38,8 @@ async function handleSearch() {
function handleClearSearch() {
searchInput.value = '';
clearSearch();
}
const isSearchMode = computed(() => searchQuery.value !== '');
const { playContent, addToQueue, attachAndPlayPlaylist, attachPlaylist } =
useRenderers();
const uiStore = useUIStore();
@@ -55,9 +49,7 @@ const sentinelRef = ref<HTMLElement | null>(null);
let observer: IntersectionObserver | null = null;
const browseData = computed(() =>
isSearchMode.value
? searchResults.value
: getBrowseCached(props.serverId, props.containerId),
getBrowseCached(props.serverId, props.containerId),
);
const containers = computed(
@@ -68,7 +60,7 @@ const items = computed(
() => browseData.value?.entries.filter((e) => !e.is_container) || [],
);
const canLoadMore = computed(() => !isSearchMode.value && hasMore(props.serverId, props.containerId));
const canLoadMore = computed(() => hasMore(props.serverId, props.containerId));
function setupObserver() {
if (observer) observer.disconnect();
@@ -201,7 +193,7 @@ async function handleQueueItem(itemId: string, rendererId: string) {
@keyup.enter="handleSearch"
/>
<button
v-if="searchInput || isSearchMode"
v-if="searchInput"
class="search-clear"
@click="handleClearSearch"
title="Effacer"
@@ -269,7 +261,7 @@ async function handleQueueItem(itemId: string, rendererId: string) {
v-if="!containers.length && !items.length"
class="browser-empty"
>
<p>{{ isSearchMode ? 'Aucun résultat' : 'Ce dossier est vide' }}</p>
<p>{{ 'Ce dossier est vide' }}</p>
</div>
<!-- Sentinel infinite scroll -->