148 lines
2.3 KiB
Vue
Executable File
148 lines
2.3 KiB
Vue
Executable File
<template>
|
|
<div>
|
|
<input
|
|
ref="input"
|
|
v-model="query"
|
|
:placeholder="label || `Search ${content}`"
|
|
class="input"
|
|
@input="search"
|
|
>
|
|
|
|
<ul
|
|
v-if="results.length > 0"
|
|
class="nolist"
|
|
>
|
|
<li
|
|
v-for="result in results"
|
|
:key="`result-${result.id}`"
|
|
class="result"
|
|
@click="selectResult(result)"
|
|
>
|
|
<Icon
|
|
v-if="result.type === 'network'"
|
|
v-tooltip="'Network'"
|
|
icon="device_hub"
|
|
/>
|
|
|
|
<Icon
|
|
v-if="result.type === 'channel'"
|
|
v-tooltip="'Channel'"
|
|
icon="tv"
|
|
/>
|
|
|
|
<img
|
|
v-if="result.avatar"
|
|
:src="getPath(result.avatar)"
|
|
class="avatar"
|
|
>{{ result.name }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
async function search() {
|
|
if (this.content === 'actors') {
|
|
const { actors } = await this.$store.dispatch('fetchActors', {
|
|
query: this.query,
|
|
limit: 10,
|
|
});
|
|
|
|
this.results = actors;
|
|
}
|
|
|
|
if (this.content === 'entities') {
|
|
this.results = await this.$store.dispatch('searchEntities', {
|
|
query: this.query,
|
|
limit: 10,
|
|
});
|
|
}
|
|
|
|
if (this.content === 'tags') {
|
|
this.results = await this.$store.dispatch('searchTags', {
|
|
query: this.query,
|
|
minLength: 1,
|
|
limit: 10,
|
|
});
|
|
}
|
|
|
|
if (this.content === 'stashes') {
|
|
this.results = this.$store.state.auth.user.stashes.filter(stash => new RegExp(this.query).test(stash.name));
|
|
}
|
|
}
|
|
|
|
function selectResult(item) {
|
|
this.query = null;
|
|
this.results = [];
|
|
|
|
this.$emit('select', item);
|
|
}
|
|
|
|
async function mounted() {
|
|
this.$refs.input.focus();
|
|
|
|
if (this.defaults.length > 0 && this.content === 'tags') {
|
|
this.results = await this.$store.dispatch('fetchTags', {
|
|
slugs: this.defaults,
|
|
});
|
|
}
|
|
|
|
if (this.content === 'stashes') {
|
|
this.results = this.$store.state.auth.user.stashes;
|
|
}
|
|
}
|
|
|
|
export default {
|
|
props: {
|
|
content: {
|
|
type: String,
|
|
default: null,
|
|
},
|
|
defaults: {
|
|
type: Array,
|
|
default: () => [],
|
|
},
|
|
label: {
|
|
type: String,
|
|
default: null,
|
|
},
|
|
},
|
|
data() {
|
|
return {
|
|
query: null,
|
|
results: [],
|
|
};
|
|
},
|
|
emits: ['select'],
|
|
mounted,
|
|
methods: {
|
|
search,
|
|
selectResult,
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.result {
|
|
color: var(--text);
|
|
display: flex;
|
|
align-items: center;
|
|
padding: .5rem;
|
|
|
|
&:hover {
|
|
color: var(--primary);
|
|
cursor: pointer;
|
|
}
|
|
}
|
|
|
|
.avatar {
|
|
height: 2rem;
|
|
margin: 0 .5rem 0 0;
|
|
}
|
|
|
|
.icon {
|
|
fill: var(--shadow);
|
|
margin: -.1rem .75rem 0 0;
|
|
}
|
|
</style>
|