FEAT: side A/B
This commit is contained in:
@@ -1,83 +1,44 @@
|
||||
<template>
|
||||
<transition name="fade">
|
||||
<div
|
||||
v-if="ui.showSearch"
|
||||
class="fixed inset-0 z-50 flex items-center justify-center transition-all"
|
||||
>
|
||||
<div v-if="ui.showSearch" class="fixed inset-0 z-50 flex items-center justify-center transition-all">
|
||||
<div class="absolute inset-0 bg-black/60 backdrop-blur-md" @click="close"></div>
|
||||
<div
|
||||
class="relative w-full max-w-2xl rounded-xl bg-white shadow-xl ring-1 ring-slate-200 dark:bg-slate-900 dark:ring-slate-700"
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
@keydown.esc.prevent.stop="close"
|
||||
>
|
||||
role="dialog" aria-modal="true" @keydown.esc.prevent.stop="close">
|
||||
<div class="flex items-center gap-2 dark:border-slate-700">
|
||||
<svg
|
||||
class="ml-4 h-7 w-7 text-slate-500"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
stroke-width="2"
|
||||
stroke-linecap="round"
|
||||
stroke-linejoin="round"
|
||||
>
|
||||
<svg class="ml-4 h-7 w-7 text-slate-500" viewBox="0 0 24 24" fill="none" stroke="currentColor"
|
||||
stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||
<circle cx="11" cy="11" r="8" />
|
||||
<path d="m21 21-4.3-4.3" />
|
||||
</svg>
|
||||
<input
|
||||
ref="inputRef"
|
||||
v-model="ui.searchQuery"
|
||||
type="text"
|
||||
placeholder="Rechercher boxes, artistes, tracks..."
|
||||
<input ref="inputRef" v-model="ui.searchQuery" type="text" placeholder="Rechercher boxes, artistes, tracks..."
|
||||
class="flex-1 bg-transparent px-2 py-2 text-slate-900 text-3xl placeholder-slate-400 outline-none dark:text-slate-100"
|
||||
@keydown.down.prevent="move(1)"
|
||||
@keydown.up.prevent="move(-1)"
|
||||
@keydown.enter.prevent="confirm"
|
||||
/>
|
||||
@keydown.down.prevent="move(1)" @keydown.up.prevent="move(-1)" @keydown.enter.prevent="confirm" />
|
||||
</div>
|
||||
|
||||
<div class="max-h-72 overflow-auto results-scroll">
|
||||
<template v-if="results.length">
|
||||
<ul class="divide-y divide-slate-100 dark:divide-slate-800">
|
||||
<li
|
||||
v-for="(resultItem, idx) in results"
|
||||
:key="resultItem.key"
|
||||
:class="[
|
||||
'flex cursor-pointer items-center justify-between gap-3 px-2 py-3 hover:bg-slate-50 dark:hover:bg-slate-800',
|
||||
idx === activeIndex ? 'bg-slate-100 dark:bg-slate-800' : ''
|
||||
]"
|
||||
@mouseenter="activeIndex = idx"
|
||||
@click="selectResult(resultItem)"
|
||||
>
|
||||
<li v-for="(resultItem, idx) in results" :key="resultItem.key" :class="[
|
||||
'flex cursor-pointer items-center justify-between gap-3 px-2 py-3 hover:bg-slate-50 dark:hover:bg-slate-800',
|
||||
idx === activeIndex ? 'bg-slate-100 dark:bg-slate-800' : ''
|
||||
]" @mouseenter="activeIndex = idx" @click="selectResult(resultItem)">
|
||||
<div class="flex items-center gap-3">
|
||||
<img
|
||||
v-if="coverUrlFor(resultItem)"
|
||||
:src="coverUrlFor(resultItem)"
|
||||
alt=""
|
||||
loading="lazy"
|
||||
class="h-10 w-10 rounded object-cover ring-1 ring-slate-200 dark:ring-slate-700"
|
||||
/>
|
||||
<img v-if="coverUrlFor(resultItem)" :src="coverUrlFor(resultItem)" alt="" loading="lazy"
|
||||
class="h-10 w-10 rounded object-cover ring-1 ring-slate-200 dark:ring-slate-700" />
|
||||
<span
|
||||
class="inline-flex min-w-[68px] items-center justify-center rounded-md border px-2 py-0.5 text-xs font-semibold uppercase text-slate-600 dark:text-slate-300 dark:border-slate-600"
|
||||
>{{ resultItem.type }}</span
|
||||
>
|
||||
class="inline-flex min-w-[68px] items-center justify-center rounded-md border px-2 py-0.5 text-xs font-semibold uppercase text-slate-600 dark:text-slate-300 dark:border-slate-600">{{
|
||||
resultItem.type }}</span>
|
||||
<span class="text-slate-900 dark:text-slate-100">{{ resultItem.label }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-2">
|
||||
<span
|
||||
v-if="resultItem.sublabel"
|
||||
class="text-sm text-slate-500 dark:text-slate-400"
|
||||
>{{ resultItem.sublabel }}</span
|
||||
>
|
||||
<toggleFavorite v-if="resultItem.type === 'TRACK'" :track="resultItem.payload" />
|
||||
<span v-if="resultItem.sublabel" class="text-sm text-slate-500 dark:text-slate-400">{{
|
||||
resultItem.sublabel }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
<div
|
||||
v-else-if="ui.searchQuery"
|
||||
class="px-2 py-6 text-center text-slate-500 dark:text-slate-400"
|
||||
>
|
||||
<div v-else-if="ui.searchQuery" class="px-2 py-6 text-center text-slate-500 dark:text-slate-400">
|
||||
Aucun résultat
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,12 +52,10 @@ import { computed, nextTick, onMounted, ref, watch } from 'vue'
|
||||
import { useUiStore } from '~/store/ui'
|
||||
import { useDataStore } from '~/store/data'
|
||||
import { usePlayerStore } from '~/store/player'
|
||||
import { useFavoritesStore } from '~/store/favorites'
|
||||
|
||||
const ui = useUiStore()
|
||||
const data = useDataStore()
|
||||
const player = usePlayerStore()
|
||||
const fav = useFavoritesStore()
|
||||
const inputRef = ref<HTMLInputElement | null>(null)
|
||||
const activeIndex = ref(0)
|
||||
|
||||
@@ -195,15 +154,10 @@ const selectResult = (ResultItem: ResultItem) => {
|
||||
}
|
||||
} else if (ResultItem.type === 'TRACK') {
|
||||
const track = ResultItem.payload
|
||||
// If the selected track is a favorite, just play it without navigating/selecting its box
|
||||
if (fav.isFavorite(track.id)) {
|
||||
const box = data.getBoxById(track.boxId)
|
||||
if (box) {
|
||||
ui.selectBox(box.id)
|
||||
player.playTrack(track)
|
||||
} else {
|
||||
const box = data.getBoxById(track.boxId)
|
||||
if (box) {
|
||||
ui.selectBox(box.id)
|
||||
player.playTrack(track)
|
||||
}
|
||||
}
|
||||
}
|
||||
close()
|
||||
|
||||
Reference in New Issue
Block a user