Added studios to filters and scene page.
This commit is contained in:
		
							parent
							
								
									c3362e614e
								
							
						
					
					
						commit
						60c7e2a876
					
				|  | @ -63,7 +63,8 @@ | |||
|     --text: #222; | ||||
|     --text-light: #fff; | ||||
| 
 | ||||
|     --link: #48f; | ||||
|     /* --link: #48f; */ | ||||
|     --link: var(--primary); | ||||
| 
 | ||||
|     --male: #0af; | ||||
|     --female: #f0a; | ||||
|  |  | |||
|  | @ -131,14 +131,14 @@ const entities = computed(() => { | |||
| 			return acc; | ||||
| 		} | ||||
| 
 | ||||
| 		if (channel.parent && !acc[channel.parent.id] && channel.type === 'channel') { | ||||
| 		if (!acc[channel.id] && channel.parent && !acc[channel.parent.id] && (channel.type === 'channel' || channel.type === 'studio')) { | ||||
| 			acc[channel.parent.id] = { | ||||
| 				...channel.parent, | ||||
| 				children: [], | ||||
| 			}; | ||||
| 		} | ||||
| 
 | ||||
| 		if (channel.parent && channel.type === 'channel') { | ||||
| 		if (!acc[channel.id] && channel.parent && (channel.type === 'channel' || channel.type === 'studio')) { | ||||
| 			acc[channel.parent.id].children.push(channel); | ||||
| 		} | ||||
| 
 | ||||
|  |  | |||
|  | @ -160,6 +160,7 @@ import { parse } from 'path-to-regexp'; | |||
| import navigate from '#/src/navigate.js'; | ||||
| import { get } from '#/src/api.js'; | ||||
| import events from '#/src/events.js'; | ||||
| import entityPrefixes from '#/src/entities-prefixes.js'; | ||||
| import { getActorIdentifier, parseActorIdentifier } from '#/src/query.js'; | ||||
| 
 | ||||
| import Filters from '#/components/filters/filters.vue'; | ||||
|  | @ -211,6 +212,8 @@ const aggActors = ref(pageProps.aggActors || []); | |||
| const aggTags = ref(pageProps.aggTags || []); | ||||
| const aggChannels = ref(pageProps.aggChannels || []); | ||||
| 
 | ||||
| console.log(aggChannels.value); | ||||
| 
 | ||||
| const currentPage = ref(Number(routeParams.page)); | ||||
| const scope = ref(routeParams.scope || props.defaultScope); | ||||
| const total = ref(Number(pageProps.sceneTotal || pageProps.total)); | ||||
|  | @ -277,7 +280,8 @@ async function search(options = {}) { | |||
| 	}; | ||||
| 
 | ||||
| 	const entity = filters.value.entity || pageEntity; | ||||
| 	const entitySlug = entity?.type === 'network' ? `_${entity.slug}` : entity?.slug; | ||||
| 	// const entitySlug = entity?.type === 'network' ? `_${entity.slug}` : entity?.slug; | ||||
| 	const entitySlug = `${entityPrefixes[entity.type]}${entity.slug}`; | ||||
| 
 | ||||
| 	loading.value = true; | ||||
| 
 | ||||
|  | @ -286,7 +290,8 @@ 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, | ||||
| 		e: filters.value.entity?.type === 'network' ? `_${filters.value.entity.slug}` : (filters.value.entity?.slug || 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 }); | ||||
| 
 | ||||
| 	const res = await get('/scenes', { | ||||
|  |  | |||
|  | @ -109,6 +109,16 @@ | |||
| 			class="row tags nolist" | ||||
| 			:title="scene.tags.map((tag) => tag.name).join(', ')" | ||||
| 		> | ||||
| 			<li | ||||
| 				v-if="scene.shootId" | ||||
| 				class="tag shoot" | ||||
| 			> | ||||
| 				<Link | ||||
| 					:href="scene.studio ? `/studio/${scene.studio.slug}` : null" | ||||
| 					class="nolink" | ||||
| 				>{{ scene.shootId }}</Link> | ||||
| 			</li> | ||||
| 
 | ||||
| 			<li | ||||
| 				v-for="tag in scene.tags" | ||||
| 				:key="`tag-${scene.id}-${tag.id}`" | ||||
|  | @ -304,4 +314,10 @@ const favorited = ref(props.scene.stashes.some((sceneStash) => sceneStash.id === | |||
| 	color: var(--glass-strong-10); | ||||
| 	font-size: .75rem; | ||||
| } | ||||
| 
 | ||||
| .shoot { | ||||
| 	color: var(--primary); | ||||
| 	font-size: .75rem; | ||||
| 	font-weight: bold; | ||||
| } | ||||
| </style> | ||||
|  |  | |||
|  | @ -76,6 +76,19 @@ | |||
| 			/> | ||||
| 
 | ||||
| 			<div class="children-container"> | ||||
| 				<div | ||||
| 					v-show="expanded" | ||||
| 					class="expand-container expand-top" | ||||
| 				> | ||||
| 					<button | ||||
| 						class="expand" | ||||
| 						@click="expanded = !expanded" | ||||
| 					> | ||||
| 						<span class="expand-text">Collapse channels</span> | ||||
| 						<Icon icon="arrow-up3" /> | ||||
| 					</button> | ||||
| 				</div> | ||||
| 
 | ||||
| 				<ul | ||||
| 					v-if="entity.children.length > 0" | ||||
| 					ref="children" | ||||
|  | @ -252,7 +265,7 @@ const entityUrl = (() => { | |||
| 	align-items: center; | ||||
| 	padding: .5rem; | ||||
| 	border: none; | ||||
| 	background: var(--grey-dark-50); | ||||
| 	background: var(--grey-dark-40); | ||||
| 	color: var(--highlight-strong-30); | ||||
| 	font-size: .9rem; | ||||
| 	font-weight: bold; | ||||
|  | @ -274,6 +287,17 @@ const entityUrl = (() => { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| .expand-top { | ||||
| 	height: 0; | ||||
| 	top: 3.5rem; | ||||
| 	bottom: auto; | ||||
| 	position: sticky; | ||||
| 
 | ||||
| 	.expand { | ||||
| 		height: 2rem; | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| .domains-bar { | ||||
| 	display: none; | ||||
| } | ||||
|  |  | |||
|  | @ -1,6 +1,7 @@ | |||
| import { render } from 'vike/abort'; /* eslint-disable-line import/extensions */ | ||||
| 
 | ||||
| import { fetchEntitiesById } from '#/src/entities.js'; | ||||
| import entityPrefixes from '#/src/entities-prefixes.js'; | ||||
| import { fetchScenes } from '#/src/scenes.js'; | ||||
| import { fetchMovies } from '#/src/movies.js'; | ||||
| import { curateScenesQuery } from '#/src/web/scenes.js'; | ||||
|  | @ -35,7 +36,8 @@ async function fetchReleases(pageContext, entityId) { | |||
| } | ||||
| 
 | ||||
| export async function onBeforeRender(pageContext) { | ||||
| 	const entityId = await redis.hGet('traxxx:entities:id_by_slug', pageContext.routeParams.entityType === 'network' ? `_${pageContext.routeParams.entitySlug}` : pageContext.routeParams.entitySlug); | ||||
| 	// const entityId = await redis.hGet('traxxx:entities:id_by_slug', pageContext.routeParams.entityType === 'network' ? `_${pageContext.routeParams.entitySlug}` : pageContext.routeParams.entitySlug);
 | ||||
| 	const entityId = await redis.hGet('traxxx:entities:id_by_slug', `${entityPrefixes[pageContext.routeParams.entityType]}${pageContext.routeParams.entitySlug}`); | ||||
| 
 | ||||
| 	if (!entityId) { | ||||
| 		throw render(404, `Cannot find ${pageContext.routeParams.entityType} '${pageContext.routeParams.entitySlug}'.`); | ||||
|  |  | |||
|  | @ -1,7 +1,7 @@ | |||
| import { match } from 'path-to-regexp'; | ||||
| // import { resolveRoute } from 'vike/routing'; // eslint-disable-line import/extensions
 | ||||
| 
 | ||||
| const path = '/:entityType(channel|network)/:entitySlug/:domain(scenes|movies|series)?/:scope?/:page?'; | ||||
| const path = '/:entityType(channel|network|studio)/:entitySlug/:domain(scenes|movies|series)?/:scope?/:page?'; | ||||
| const urlMatch = match(path, { decode: decodeURIComponent }); | ||||
| 
 | ||||
| export default (pageContext) => { | ||||
|  |  | |||
|  | @ -205,6 +205,18 @@ | |||
| 						{{ scene.shootId }} | ||||
| 					</div> | ||||
| 
 | ||||
| 					<div | ||||
| 						v-if="scene.studio" | ||||
| 						class="detail" | ||||
| 					> | ||||
| 						<h3 class="heading">Studio</h3> | ||||
| 
 | ||||
| 						<a | ||||
| 							:href="`/studio/${scene.studio.slug}`" | ||||
| 							class="link" | ||||
| 						>{{ scene.studio.name }}</a> | ||||
| 					</div> | ||||
| 
 | ||||
| 					<div | ||||
| 						v-if="scene.qualities.length > 0" | ||||
| 						class="detail" | ||||
|  |  | |||
|  | @ -0,0 +1,6 @@ | |||
| export default { | ||||
| 	channel: '', | ||||
| 	network: '_', | ||||
| 	studio: '*', | ||||
| 	info: '@', | ||||
| }; | ||||
|  | @ -1,16 +1,10 @@ | |||
| import knex from './knex.js'; | ||||
| import redis from './redis.js'; | ||||
| import initLogger from './logger.js'; | ||||
| import entityPrefixes from './entities-prefixes.js'; | ||||
| 
 | ||||
| const logger = initLogger(); | ||||
| 
 | ||||
| const entityPrefixes = { | ||||
| 	channel: '', | ||||
| 	network: '_', | ||||
| 	studio: '*', | ||||
| 	info: '@', | ||||
| }; | ||||
| 
 | ||||
| export function curateEntity(entity, context) { | ||||
| 	if (!entity) { | ||||
| 		return null; | ||||
|  |  | |||
|  | @ -79,6 +79,13 @@ function curateScene(rawScene, assets) { | |||
| 			type: assets.channel.network_type, | ||||
| 			hasLogo: assets.channel.network_has_logo, | ||||
| 		} : null, | ||||
| 		studio: assets.studio ? { | ||||
| 			id: assets.studio.id, | ||||
| 			slug: assets.studio.slug, | ||||
| 			name: assets.studio.name, | ||||
| 			type: assets.studio.type, | ||||
| 			hasLogo: assets.studio.has_logo, | ||||
| 		} : null, | ||||
| 		affiliate: assets.channel.affiliate ? { | ||||
| 			id: assets.channel.affiliate.id, | ||||
| 			url: assets.channel.affiliate.url, | ||||
|  | @ -132,6 +139,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) { | |||
| 	const { | ||||
| 		scenes, | ||||
| 		channels, | ||||
| 		studios, | ||||
| 		actors, | ||||
| 		directors, | ||||
| 		tags, | ||||
|  | @ -161,6 +169,10 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) { | |||
| 			.leftJoin('entities as networks', 'networks.id', 'channels.parent_id') | ||||
| 			.leftJoin('affiliates', knex.raw('affiliates.entity_id in (channels.id, networks.id)')) | ||||
| 			.groupBy('channels.id', 'networks.id', 'affiliates.id'), | ||||
| 		studios: knex('releases') | ||||
| 			.whereIn('releases.id', sceneIds) | ||||
| 			.leftJoin('entities as studios', 'studios.id', 'releases.studio_id'), | ||||
| 		// .leftJoin('entities as networks', 'networks.id', 'studios.parent_id'),
 | ||||
| 		actors: knex('releases_actors') | ||||
| 			.select( | ||||
| 				'actors.*', | ||||
|  | @ -265,6 +277,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) { | |||
| 		} | ||||
| 
 | ||||
| 		const sceneChannel = channels.find((entity) => entity.id === scene.entity_id); | ||||
| 		const sceneStudio = studios.find((entity) => entity.id === scene.studio_id); | ||||
| 		const sceneActors = actors.filter((actor) => actor.release_id === sceneId); | ||||
| 		const sceneDirectors = directors.filter((director) => director.release_id === sceneId); | ||||
| 		const sceneTags = tags.filter((tag) => tag.release_id === sceneId); | ||||
|  | @ -280,6 +293,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) { | |||
| 
 | ||||
| 		return curateScene(scene, { | ||||
| 			channel: sceneChannel, | ||||
| 			studio: sceneStudio, | ||||
| 			actors: sceneActors, | ||||
| 			directors: sceneDirectors, | ||||
| 			tags: sceneTags, | ||||
|  | @ -339,7 +353,8 @@ async function queryManticoreSql(filters, options, _reqUser) { | |||
| 		:yearsFacet: | ||||
| 		:actorsFacet: | ||||
| 		:tagsFacet: | ||||
| 		:channelsFacet:; | ||||
| 		:channelsFacet: | ||||
| 		:studiosFacet:; | ||||
| 		show meta; | ||||
| 	`, {
 | ||||
| 		query: knexManticore(filters.stashId ? 'scenes_stashed' : 'scenes') | ||||
|  | @ -470,6 +485,7 @@ async function queryManticoreSql(filters, options, _reqUser) { | |||
| 		actorsFacet: options.aggregateActors ? knex.raw('facet scenes.actor_ids order by count(*) desc limit ?', [aggSize]) : null, | ||||
| 		tagsFacet: options.aggregateTags ? knex.raw('facet scenes.tag_ids order by count(*) desc limit ?', [aggSize]) : null, | ||||
| 		channelsFacet: options.aggregateChannels ? knex.raw('facet scenes.channel_id order by count(*) desc limit ?', [aggSize]) : null, | ||||
| 		studiosFacet: options.aggregateChannels ? knex.raw('facet scenes.studio_id order by count(*) desc limit ?', [aggSize]) : null, | ||||
| 		maxMatches: config.database.manticore.maxMatches, | ||||
| 		maxQueryTime: config.database.manticore.maxQueryTime, | ||||
| 	}).toString(); | ||||
|  | @ -507,6 +523,13 @@ async function queryManticoreSql(filters, options, _reqUser) { | |||
| 		?.data.map((row) => ({ key: row.channel_id || row['scenes.channel_id'], doc_count: row['count(*)'] })) | ||||
| 		|| []; | ||||
| 
 | ||||
| 	const studioIds = results | ||||
| 		.find((result) => (result.columns[0].studio_id || result.columns[0]['scenes.studio_id']) && result.columns[1]['count(*)']) | ||||
| 		?.data | ||||
| 		.map((row) => ({ key: row.studio_id || row['scenes.studio_id'], doc_count: row['count(*)'] })) | ||||
| 		.filter((row) => !!row.key) | ||||
| 		|| []; | ||||
| 
 | ||||
| 	const total = Number(results.at(-1).data.find((entry) => entry.Variable_name === 'total_found')?.Value) || 0; | ||||
| 
 | ||||
| 	return { | ||||
|  | @ -517,6 +540,7 @@ async function queryManticoreSql(filters, options, _reqUser) { | |||
| 			actorIds, | ||||
| 			tagIds, | ||||
| 			channelIds, | ||||
| 			studioIds, | ||||
| 		}, | ||||
| 	}; | ||||
| } | ||||
|  | @ -540,19 +564,24 @@ export async function fetchScenes(filters, rawOptions, reqUser) { | |||
| 	console.timeEnd('manticore sql'); | ||||
| 
 | ||||
| 	const aggYears = options.aggregateYears && result.aggregations.years.map((bucket) => ({ year: bucket.key, count: bucket.doc_count })); | ||||
| 	const entityIds = options.aggregateChannels && [...(result.aggregations.channelIds || []), ...(result.aggregations.studioIds || [])]; | ||||
| 
 | ||||
| 	const actorCounts = options.aggregateActors && countAggregations(result.aggregations?.actorIds); | ||||
| 	const tagCounts = options.aggregateTags && countAggregations(result.aggregations?.tagIds); | ||||
| 	const channelCounts = options.aggregateChannels && countAggregations(result.aggregations?.channelIds); | ||||
| 	const channelCounts = options.aggregateChannels && countAggregations(entityIds); | ||||
| 
 | ||||
| 	console.log('entity ids', entityIds); | ||||
| 
 | ||||
| 	console.time('fetch aggregations'); | ||||
| 
 | ||||
| 	const [aggActors, aggTags, aggChannels] = await Promise.all([ | ||||
| 		options.aggregateActors ? fetchActorsById(result.aggregations.actorIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: actorCounts }) : [], | ||||
| 		options.aggregateTags ? fetchTagsById(result.aggregations.tagIds.map((bucket) => bucket.key), { order: [knex.raw('lower(name)'), 'asc'], append: tagCounts }) : [], | ||||
| 		options.aggregateChannels ? fetchEntitiesById(result.aggregations.channelIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: channelCounts }) : [], | ||||
| 		options.aggregateChannels ? fetchEntitiesById(entityIds.map((bucket) => bucket.key), { order: ['slug', 'asc'], append: channelCounts }) : [], | ||||
| 	]); | ||||
| 
 | ||||
| 	console.log('studio ids', aggChannels.filter((studio) => studio.slug === 'wgcz')); | ||||
| 
 | ||||
| 	console.timeEnd('fetch aggregations'); | ||||
| 
 | ||||
| 	console.time('fetch full'); | ||||
|  |  | |||
							
								
								
									
										2
									
								
								static
								
								
								
								
							
							
								
								
								
								
								
								
							
						
						
									
										2
									
								
								static
								
								
								
								
							|  | @ -1 +1 @@ | |||
| Subproject commit 5e1b2190f0d580321a310c1c1fc95ede8f33473b | ||||
| Subproject commit 333d2604c8987548786434c78162118f50c94bc8 | ||||
		Loading…
	
		Reference in New Issue