diff --git a/components/filters/tags.vue b/components/filters/tags.vue index 3e23078..c2564c0 100644 --- a/components/filters/tags.vue +++ b/components/filters/tags.vue @@ -224,6 +224,8 @@ const groupedTags = computed(() => { }); function toggleTag(tag, combine) { + emit('update', 'onlyActorTags', showActorTags.value, false); + if (props.filters.tags.includes(tag.slug)) { emit('update', 'tags', props.filters.tags.filter((tagId) => tagId !== tag.slug)); return; diff --git a/components/scenes/scenes.vue b/components/scenes/scenes.vue index bf1b341..6283fd0 100644 --- a/components/scenes/scenes.vue +++ b/components/scenes/scenes.vue @@ -287,6 +287,7 @@ const filters = ref({ search: urlParsed.search.q, years: urlParsed.search.years?.split(',').filter(Boolean).map(Number) || [], tags: urlParsed.search.tags?.split(',').filter(Boolean) || [], + onlyActorTags: Object.hasOwn(urlParsed.search, 'at'), entity: queryEntity, actors: queryActors, }); @@ -346,6 +347,7 @@ async function search(options = {}) { years: filters.value.years.join(',') || undefined, 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, + at: (filters.value.tags.length > 0 && filters.value.onlyActorTags) || undefined, // e: filters.value.entity?.type === 'network' ? `_${filters.value.entity.slug}` : (filters.value.entity?.slug || undefined), e: filters.value.entity ? `${entityPrefixes[filters.value.entity.type]}${filters.value.entity.slug}` : undefined, }, { redirect: false }); @@ -355,6 +357,7 @@ async function search(options = {}) { years: filters.value.years.filter(Boolean).join(','), // if we're on an actor page, that actor ID needs to be included 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 tags: [pageTag?.slug, ...filters.value.tags].filter(Boolean).join(','), + at: !!filters.value.onlyActorTags, stashId: pageStash?.id, e: entitySlug, scope: scope.value, diff --git a/src/scenes.js b/src/scenes.js index d9d01f7..dc45fba 100644 --- a/src/scenes.js +++ b/src/scenes.js @@ -498,7 +498,17 @@ async function queryManticoreSql(filters, options, _reqUser) { } filters.tagIds?.forEach((tagId) => { - builder.where('any(tag_ids)', tagId); + if (filters.onlyActorTags) { + builder.where((whereBuilder) => { + whereBuilder.where('any(assigned_tag_ids)', tagId); + + filters.actorIds?.forEach((actorId) => { + whereBuilder.orWhere('any(assigned_tag_ids)', actorId * 1_000_00 + tagId); + }); + }); + } else { + builder.where('any(tag_ids)', tagId); + } }); if (filters.notTagIds) { diff --git a/src/web/scenes.js b/src/web/scenes.js index e3fe2d3..7e600f6 100644 --- a/src/web/scenes.js +++ b/src/web/scenes.js @@ -44,6 +44,7 @@ export async function curateScenesQuery(query) { notActorIds: splitActors.filter((actor) => actor.charAt(0) === '!').map((identifier) => parseActorIdentifier(identifier.slice(1))?.id).filter(Boolean), tagIds, notTagIds: notTagIds.filter((tagId) => !tagIds.includes(tagId)), // included tags get priority over excluded tags + onlyActorTags: !!query.at, entityId, notEntityIds, movieId: Number(query.movieId) || null,