diff --git a/assets/img/icons/user-tags.svg b/assets/img/icons/user-tags.svg
new file mode 100644
index 0000000..4a1c65e
--- /dev/null
+++ b/assets/img/icons/user-tags.svg
@@ -0,0 +1,27 @@
+
+
+
+
diff --git a/components/filters/tags.vue b/components/filters/tags.vue
index 19d8a38..4f41249 100644
--- a/components/filters/tags.vue
+++ b/components/filters/tags.vue
@@ -12,14 +12,30 @@
+
+
+
+
+
+
+
+
-
+
[],
},
+ 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));
diff --git a/components/scenes/scenes.vue b/components/scenes/scenes.vue
index 643a0e9..bf1b341 100644
--- a/components/scenes/scenes.vue
+++ b/components/scenes/scenes.vue
@@ -34,6 +34,7 @@
@@ -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;
diff --git a/src/scenes.js b/src/scenes.js
index f3e5d1b..01856ed 100644
--- a/src/scenes.js
+++ b/src/scenes.js
@@ -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,
diff --git a/src/web/scenes.js b/src/web/scenes.js
index 5c80e2c..e3fe2d3 100644
--- a/src/web/scenes.js
+++ b/src/web/scenes.js
@@ -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,