diff --git a/frontend/src/views/PublicBrowser.vue b/frontend/src/views/PublicBrowser.vue index b813abb..912a921 100644 --- a/frontend/src/views/PublicBrowser.vue +++ b/frontend/src/views/PublicBrowser.vue @@ -47,6 +47,58 @@ /> + +
+ + +
+
+ + +
+ +
+ + +
+ + +
+
+
Directory is empty. @@ -73,7 +125,7 @@ entries.value.filter(e => !e.is_dir)) +// --- Filters --- +const filtersOpen = ref(false) +const filterMap = ref('') +const filterPlayer = ref('') + +const hasMvdData = computed(() => entries.value.some(e => e.mvd_info)) + +const availableMaps = computed(() => { + const maps = new Set() + for (const e of entries.value) { + if (e.mvd_info?.map) maps.add(e.mvd_info.map) + } + return [...maps].sort() +}) + +const activeFiltersCount = computed(() => (filterMap.value ? 1 : 0) + (filterPlayer.value.trim() ? 1 : 0)) + +const filteredEntries = computed(() => { + const player = filterPlayer.value.trim().toLowerCase() + return entries.value.filter(e => { + if (e.is_dir) return true + if (filterMap.value && e.mvd_info?.map !== filterMap.value) return false + if (player) { + const a = (e.mvd_info?.players_a ?? '').toLowerCase() + const b = (e.mvd_info?.players_b ?? '').toLowerCase() + if (!a.includes(player) && !b.includes(player)) return false + } + return true + }) +}) + +function clearFilters() { + filterMap.value = '' + filterPlayer.value = '' + selected.value = new Set() +} + +watch([filterMap, filterPlayer], () => { selected.value = new Set() }) + +watch(currentPath, () => { + filterMap.value = '' + filterPlayer.value = '' + filtersOpen.value = false +}) + +const fileEntries = computed(() => filteredEntries.value.filter(e => !e.is_dir)) const showMultiselect = computed(() => fileEntries.value.length >= 3) const allFilesSelected = computed(() => fileEntries.value.length > 0 && fileEntries.value.every(e => selected.value.has(e.name))) const someFilesSelected = computed(() => !allFilesSelected.value && fileEntries.value.some(e => selected.value.has(e.name)))