Added toggle to select actor tags or all tags in filters.
This commit is contained in:
27
assets/img/icons/user-tags.svg
Normal file
27
assets/img/icons/user-tags.svg
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
|
||||
<svg
|
||||
version="1.1"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
id="svg2"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<path
|
||||
id="path2"
|
||||
d="M 7 0 C 4 0 4 2.015 4 4.5 C 4 6.048 4.898 7.5957969 6 8.2167969 L 6 9.0410156 C 2.608 9.3180156 0 10.985 0 13 L 4.9726562 13 C 4.6689986 12.449922 4.7486357 11.731833 5.2109375 11.269531 L 8 8.4804688 L 8 8.2167969 C 9.102 7.5957969 10 6.048 10 4.5 C 10 2.015 10 0 7 0 z M 9 11.509766 L 8.2167969 12.292969 L 8.9238281 13 L 9 13 L 9 11.509766 z " />
|
||||
<g
|
||||
id="g2"
|
||||
transform="matrix(0.51568847,0,0,0.51568847,5.8471254,8.4255678)">
|
||||
<path
|
||||
d="m 18.938,-1 h -6 c -0.412,0 -0.989,0.239 -1.28,0.53 L 4.219,6.969 c -0.292,0.292 -0.292,0.769 0,1.061 l 6.439,6.439 c 0.292,0.292 0.769,0.292 1.061,0 L 19.158,7.03 c 0.292,-0.292 0.53,-0.868 0.53,-1.28 v -6 c 0,-0.412 -0.337,-0.75 -0.75,-0.75 z m -3.75,6 c -0.828,0 -1.5,-0.672 -1.5,-1.5 0,-0.828 0.672,-1.5 1.5,-1.5 0.828,0 1.5,0.672 1.5,1.5 0,0.828 -0.672,1.5 -1.5,1.5 z"
|
||||
id="path1-5" />
|
||||
<path
|
||||
d="m 1.688,7.5 8.5,-8.5 h -1.25 c -0.412,0 -0.989,0.239 -1.28,0.53 L 0.219,6.969 c -0.292,0.292 -0.292,0.769 0,1.061 l 6.439,6.439 c 0.292,0.292 0.769,0.292 1.061,0 l 0.47,-0.47 -6.5,-6.5 z"
|
||||
id="path2-3" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -12,14 +12,30 @@
|
||||
<Icon icon="search" />
|
||||
</label>
|
||||
|
||||
<div
|
||||
v-show="showActorTags"
|
||||
v-tooltip="'Tags relevant to the selected actors'"
|
||||
class="filter-sort order noselect"
|
||||
@click="showActorTags = false"
|
||||
>
|
||||
<Icon icon="user-tags" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="!showActorTags"
|
||||
v-tooltip="'All tags'"
|
||||
class="filter-sort order noselect"
|
||||
@click="showActorTags = true"
|
||||
>
|
||||
<Icon icon="price-tags" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-show="order === 'priority'"
|
||||
class="filter-sort order noselect"
|
||||
@click="order = 'count'"
|
||||
>
|
||||
<Icon
|
||||
icon="star"
|
||||
/>
|
||||
<Icon icon="star" />
|
||||
</div>
|
||||
|
||||
<div
|
||||
@@ -115,16 +131,21 @@ const props = defineProps({
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
actorTags: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update']);
|
||||
|
||||
const { pageProps } = inject('pageContext');
|
||||
const { tag: pageTag, actor: pageActor } = pageProps;
|
||||
|
||||
const search = ref('');
|
||||
const searchRegexp = computed(() => new RegExp(search.value, 'i'));
|
||||
const order = ref('priority');
|
||||
|
||||
const { pageProps } = inject('pageContext');
|
||||
const { tag: pageTag } = pageProps;
|
||||
const showActorTags = ref(true);
|
||||
|
||||
const priorityTags = [
|
||||
'anal',
|
||||
@@ -148,8 +169,12 @@ const priorityTags = [
|
||||
];
|
||||
|
||||
const groupedTags = computed(() => {
|
||||
const selected = props.tags.filter((tag) => props.filters.tags.includes(tag.slug));
|
||||
const filtered = props.tags.filter((tag) => !props.filters.tags.includes(tag.slug)
|
||||
const tags = showActorTags.value && props.actorTags && (props.filters.actors.length > 0 || pageActor)
|
||||
? props.actorTags
|
||||
: props.tags;
|
||||
|
||||
const selected = tags.filter((tag) => props.filters.tags.includes(tag.slug));
|
||||
const filtered = tags.filter((tag) => !props.filters.tags.includes(tag.slug)
|
||||
&& tag.id !== pageTag?.id
|
||||
&& searchRegexp.value.test(tag.name));
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
<TagsFilter
|
||||
:filters="filters"
|
||||
:tags="aggTags"
|
||||
:actor-tags="aggActorTags"
|
||||
@update="updateFilter"
|
||||
/>
|
||||
|
||||
@@ -263,6 +264,7 @@ const scenes = ref(pageProps.scenes);
|
||||
const aggYears = ref(pageProps.aggYears || []);
|
||||
const aggActors = ref(pageProps.aggActors || []);
|
||||
const aggTags = ref(pageProps.aggTags || []);
|
||||
const aggActorTags = ref(pageProps.aggActorTags || []);
|
||||
const aggChannels = ref(pageProps.aggChannels || []);
|
||||
|
||||
const currentPage = ref(Number(routeParams.page));
|
||||
@@ -363,6 +365,7 @@ async function search(options = {}) {
|
||||
aggYears.value = res.aggYears;
|
||||
aggActors.value = res.aggActors;
|
||||
aggTags.value = res.aggTags;
|
||||
aggActorTags.value = res.aggActorTags;
|
||||
aggChannels.value = res.aggChannels;
|
||||
|
||||
total.value = res.total;
|
||||
|
||||
@@ -424,6 +424,7 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
||||
:yearsFacet:
|
||||
:actorsFacet:
|
||||
:tagsFacet:
|
||||
:actorTagsFacet:
|
||||
:channelsFacet:
|
||||
:studiosFacet:;
|
||||
show meta;
|
||||
@@ -566,10 +567,9 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
||||
yearsFacet: options.aggregateYears ? knex.raw('facet effective_year as years_facet order by effective_year desc limit ?', [aggSize]) : null,
|
||||
actorsFacet: options.aggregateActors ? knex.raw('facet scenes.actor_ids as actors_facet distinct id order by count(distinct id) desc limit ?', [aggSize]) : null,
|
||||
// don't facet tags associated to other actors, actor ID 0 means global
|
||||
tagsFacet: options.aggregateTags // eslint-disable-line no-nested-ternary
|
||||
? (filters.stashId || !filters?.actorIds || filters.actorIds.length === 0 // we can't join the tags table as well as the stashes table
|
||||
? knex.raw('facet scenes.tag_ids as tags_facet order by count(distinct id) desc limit ?', [aggSize])
|
||||
: knex.raw(`facet IF(IN(scenes_tags.actor_id, ${[0, ...filters?.actorIds || []]}), scenes_tags.tag_id, 0) tags_facet distinct id order by count(distinct id) desc limit ?`, [aggSize]))
|
||||
tagsFacet: options.aggregateTags ? knex.raw('facet scenes.tag_ids as tags_facet order by count(distinct id) desc limit ?', [aggSize]) : null,
|
||||
actorTagsFacet: options.aggregateTags && !filters.stashId // eslint-disable-line no-nested-ternary
|
||||
? knex.raw(`facet IF(IN(scenes_tags.actor_id, ${[0, ...filters?.actorIds || []]}), scenes_tags.tag_id, 0) actor_tags_facet distinct id order by count(distinct id) desc limit ?`, [aggSize])
|
||||
: null,
|
||||
channelsFacet: options.aggregateChannels ? knex.raw('facet scenes.channel_id as channels_facet distinct id order by count(distinct id) desc limit ?', [aggSize]) : null,
|
||||
studiosFacet: options.aggregateChannels ? knex.raw('facet scenes.studio_id as studios_facet distinct id order by count(distinct id) desc limit ?', [aggSize]) : null,
|
||||
@@ -607,6 +607,11 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
||||
?.data.map((row) => ({ key: row.tags_facet, doc_count: row['count(distinct id)'] || row['count(*)'] }))
|
||||
|| [];
|
||||
|
||||
const actorTagIds = results
|
||||
.find((result) => result.columns[0].actor_tags_facet && result.columns[1]['count(distinct id)'])
|
||||
?.data.map((row) => ({ key: row.actor_tags_facet, doc_count: row['count(distinct id)'] || row['count(*)'] }))
|
||||
|| [];
|
||||
|
||||
const channelIds = results
|
||||
.find((result) => result.columns[0].channels_facet && result.columns[1]['count(distinct id)'])
|
||||
?.data.map((row) => ({ key: row.channels_facet || row['scenes.channel_id'], doc_count: row['count(distinct id)'] }))
|
||||
@@ -626,6 +631,7 @@ async function queryManticoreSql(filters, options, _reqUser) {
|
||||
years,
|
||||
actorIds,
|
||||
tagIds,
|
||||
actorTagIds,
|
||||
channelIds,
|
||||
studioIds,
|
||||
},
|
||||
@@ -663,9 +669,10 @@ export async function fetchScenes(filters, rawOptions, reqUser, context) {
|
||||
|
||||
console.time('fetch aggregations');
|
||||
|
||||
const [aggActors, aggTags, aggChannels] = await Promise.all([
|
||||
const [aggActors, aggTags, aggActorTags, aggChannels] = await Promise.all([
|
||||
options.aggregateActors ? fetchActorsById(result.aggregations.actorIds.map((bucket) => bucket.key), { shallow: true, order: ['slug', 'asc'], append: actorCounts }, reqUser) : [],
|
||||
options.aggregateTags ? fetchTagsById(result.aggregations.tagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(name)'), 'asc'], append: tagCounts }, reqUser, context) : [],
|
||||
options.aggregateTags ? fetchTagsById(result.aggregations.actorTagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(name)'), 'asc'], append: tagCounts }, reqUser, context) : [],
|
||||
options.aggregateChannels ? fetchEntitiesById(entityIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: channelCounts }, reqUser, context) : [],
|
||||
]);
|
||||
|
||||
@@ -681,6 +688,7 @@ export async function fetchScenes(filters, rawOptions, reqUser, context) {
|
||||
aggYears,
|
||||
aggActors,
|
||||
aggTags,
|
||||
aggActorTags,
|
||||
aggChannels,
|
||||
total: result.total,
|
||||
limit: options.limit,
|
||||
|
||||
@@ -59,6 +59,7 @@ async function fetchScenesApi(req, res) {
|
||||
aggYears,
|
||||
aggActors,
|
||||
aggTags,
|
||||
aggActorTags,
|
||||
aggChannels,
|
||||
limit,
|
||||
total,
|
||||
@@ -77,6 +78,7 @@ async function fetchScenesApi(req, res) {
|
||||
aggYears,
|
||||
aggActors,
|
||||
aggTags,
|
||||
aggActorTags,
|
||||
aggChannels,
|
||||
limit,
|
||||
total,
|
||||
|
||||
Reference in New Issue
Block a user