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>
 |