From 09df1345582d40df1a9b3d67a974f68d535f2202 Mon Sep 17 00:00:00 2001 From: DebaucheryLibrarian Date: Thu, 22 Feb 2024 05:08:06 +0100 Subject: [PATCH] Added global search. --- components/actors/bio.vue | 2 +- components/filters/actors.vue | 147 ++++++++++++----------- components/filters/channels.vue | 133 +++++++++++---------- components/filters/filters.vue | 6 + components/filters/tags.vue | 167 ++++++++++++++------------- components/header/header.vue | 70 +++++++++-- components/pagination/pagination.vue | 12 ++ components/scenes/scenes.vue | 57 ++++++--- pages/actors/+Page.vue | 24 ++-- pages/scene/+Page.vue | 38 +++--- pages/updates/+Page.vue | 6 - src/actors.js | 12 +- src/scenes.js | 56 ++++++++- src/web/actors.js | 2 - src/web/scenes.js | 1 + 15 files changed, 461 insertions(+), 272 deletions(-) diff --git a/components/actors/bio.vue b/components/actors/bio.vue index 3364a7a..eb1a943 100644 --- a/components/actors/bio.vue +++ b/components/actors/bio.vue @@ -391,7 +391,7 @@ defineProps({ .flag { height: 1rem; - margin: .25rem .25rem 0 0; + margin: .25rem .5rem 0 0; } .bio-name { diff --git a/components/filters/actors.vue b/components/filters/actors.vue index b05f06c..1763b01 100644 --- a/components/filters/actors.vue +++ b/components/filters/actors.vue @@ -1,82 +1,89 @@ @@ -124,13 +131,17 @@ const availableActors = computed(() => props.actors const genders = computed(() => [null, ...['female', 'male', 'transsexual', 'other'].filter((gender) => props.actors.some((actor) => actor.gender === gender))]); -function toggleActor(actor) { +function toggleActor(actor, combine) { if (props.filters.actors.some((filterActor) => filterActor.id === actor.id)) { emit('update', 'actors', props.filters.actors.filter((filterActor) => filterActor.id !== actor.id)); return; } - emit('update', 'actors', props.filters.actors.concat(actor)); + if (combine) { + emit('update', 'actors', props.filters.actors.concat(actor)); + } else { + emit('update', 'actors', [actor]); + } } function selectGender() { diff --git a/components/filters/channels.vue b/components/filters/channels.vue index bfd92e0..e4a368b 100644 --- a/components/filters/channels.vue +++ b/components/filters/channels.vue @@ -1,75 +1,82 @@ diff --git a/components/filters/filters.vue b/components/filters/filters.vue index 6ddffa1..1733284 100644 --- a/components/filters/filters.vue +++ b/components/filters/filters.vue @@ -284,6 +284,12 @@ function toggleFilters(state) { color: var(--shadow-weak-10); font-size: .9rem; } + +.filter-empty { + padding: .5rem; + color: var(--shadow); + font-style: italic; +} diff --git a/components/pagination/pagination.vue b/components/pagination/pagination.vue index 629c4a3..132c10a 100644 --- a/components/pagination/pagination.vue +++ b/components/pagination/pagination.vue @@ -95,6 +95,10 @@ const props = defineProps({ type: Boolean, default: true, }, + query: { + type: String, + default: null, + }, includeQuery: { type: Boolean, default: true, @@ -148,6 +152,14 @@ function go(page, event) { } function getPath(page) { + if (!routeParams.path && props.includeQuery) { + return `${pageContext.urlParsed.pathname}${page}${urlParsed.searchOriginal}`; + } + + if (!routeParams.path) { + return `${pageContext.urlParsed.pathname}${page}`; + } + const path = parse(routeParams.path) .map((segment) => { if (segment.name === 'page') { diff --git a/components/scenes/scenes.vue b/components/scenes/scenes.vue index 018039e..b77650d 100644 --- a/components/scenes/scenes.vue +++ b/components/scenes/scenes.vue @@ -6,6 +6,16 @@ v-if="showFilters" :class="{ loading }" > +
+ +
+ + @@ -108,7 +122,7 @@ import Scene from '#/components/scenes/tile.vue'; import Pagination from '#/components/pagination/pagination.vue'; import Ellipsis from '#/components/loading/ellipsis.vue'; -defineProps({ +const props = defineProps({ showFilters: { type: Boolean, default: true, @@ -121,6 +135,10 @@ defineProps({ type: Boolean, default: false, }, + defaultScope: { + type: String, + default: 'latest', + }, }); const { pageProps, routeParams, urlParsed } = inject('pageContext'); @@ -137,7 +155,7 @@ const aggTags = ref(pageProps.aggTags || []); const aggChannels = ref(pageProps.aggChannels || []); const currentPage = ref(Number(routeParams.page)); -const scope = ref(routeParams.scope); +const scope = ref(routeParams.scope || props.defaultScope); const total = ref(Number(pageProps.total)); const loading = ref(false); @@ -150,6 +168,7 @@ const channels = Object.fromEntries(aggChannels.value.filter((channel) => channe const queryEntity = networks[urlParsed.search.e] || channels[urlParsed.search.e]; const filters = ref({ + search: urlParsed.search.q, tags: urlParsed.search.tags?.split(',').filter(Boolean) || [], entity: queryEntity, actors: queryActors, @@ -175,18 +194,37 @@ function getPath(targetScope, preserveQuery) { return path; } -async function search(resetPage = true) { - if (resetPage) { +async function search(options = {}) { + if (options.resetPage !== false) { currentPage.value = 1; } - const query = {}; + if (options.autoScope !== false) { + if (filters.value.search) { + scope.value = 'results'; + } + + if (!filters.value.search && scope.value === 'results') { + scope.value = 'latest'; + } + } + + const query = { + q: filters.value.search || undefined, + }; const entity = filters.value.entity || pageEntity; const entitySlug = entity?.type === 'network' ? `_${entity.slug}` : entity?.slug; loading.value = true; + navigate(getPath(scope.value, false), { + ...query, + actors: filters.value.actors.map((filterActor) => getActorIdentifier(filterActor)).join(',') || undefined, // don't include page actor ID in query, already a parameter + tags: filters.value.tags.join(',') || undefined, + e: filters.value.entity?.type === 'network' ? `_${filters.value.entity.slug}` : (filters.value.entity?.slug || undefined), + }, { redirect: false }); + const res = await get('/scenes', { ...query, actors: [pageActor, ...filters.value.actors].filter(Boolean).map((filterActor) => getActorIdentifier(filterActor)).join(','), // if we're on an actor page, that actor ID needs to be included @@ -205,13 +243,6 @@ async function search(resetPage = true) { loading.value = false; events.emit('scrollUp'); - - navigate(getPath(scope.value, false), { - ...query, - actors: filters.value.actors.map((filterActor) => getActorIdentifier(filterActor)).join(',') || undefined, // don't include page actor ID in query, already a parameter - tags: filters.value.tags.join(',') || undefined, - e: filters.value.entity?.type === 'network' ? `_${filters.value.entity.slug}` : (filters.value.entity?.slug || undefined), - }, { redirect: false }); } function updateFilter(prop, value, reload = true) { diff --git a/pages/actors/+Page.vue b/pages/actors/+Page.vue index 2fd80ed..2a9bcba 100644 --- a/pages/actors/+Page.vue +++ b/pages/actors/+Page.vue @@ -55,7 +55,7 @@