traxxx-web/components/actors/search.vue

116 lines
1.9 KiB
Vue
Raw Normal View History

<template>
<VDropdown
:disabled="disabled"
class="trigger"
@show="focus"
>
<slot />
<template #popper>
<div>
<input
ref="queryInput"
v-model="query"
placeholder="Search actor"
class="input"
@input="search"
>
<ul class="actors nolist">
<li
v-for="actor in actors"
:key="`actor-${actor.slug}`"
v-close-popper
class="actor"
@click="emit('actor', actor)"
>{{ actor.name }} ({{ [actor.ageFromBirth, actor.origin?.country?.alpha2].join(', ') }})
<img
v-if="actor.avatar"
:src="getPath(actor.avatar, 'thumbnail')"
class="avatar"
>
</li>
</ul>
</div>
</template>
</VDropdown>
</template>
<script setup>
import { ref, inject } from 'vue';
import { get } from '#/src/api.js';
import getPath from '#/src/get-path.js';
const pageContext = inject('pageContext');
const actorNames = {
dp: 'double penetration',
};
const defaultActors = pageContext.pageProps.actorIds
? Object.entries(pageContext.pageProps.actorIds).map(([slug, id]) => ({
id,
slug,
name: actorNames[slug] || slug,
}))
: [];
const actors = ref(defaultActors);
const query = ref(null);
const queryInput = ref(null);
defineProps({
disabled: {
type: Boolean,
default: false,
},
});
const emit = defineEmits(['actor']);
async function search() {
const data = await get('/actors', { q: query.value });
actors.value = data.actors;
}
function focus() {
setTimeout(() => {
queryInput.value?.focus();
}, 100);
}
</script>
<style scoped>
.trigger {
height: 100%;
overflow: hidden;
}
.actor {
display: block;
padding: .25rem .5rem;
&:hover {
background: var(--glass-weak-50);
color: var(--primary);
cursor: pointer;
.avatar {
display: block;
}
}
}
.avatar {
position: fixed;
display: none;
left: 7rem;
width: 8rem;
border-radius: .25rem;
box-shadow: 0 0 3px var(--shadow-weak-10);
pointer-events: none;
}
</style>