Fixed add stash in notifications panel. Fixed iframe ads breaking page width. Improved actor and movie tile size in search results.

This commit is contained in:
DebaucheryLibrarian 2024-08-29 17:53:54 +02:00
parent 33e8fbea0b
commit 0909e8d74c
9 changed files with 152 additions and 29 deletions

View File

@ -329,7 +329,7 @@
/> />
</li> </li>
<template v-if="stashes.length < user.stashes.length"> <template v-if="stashes.length < assets.stashes.length">
<li class="field-add"> <li class="field-add">
<button <button
v-if="stashes.length === 0" v-if="stashes.length === 0"
@ -349,7 +349,7 @@
<template #popper> <template #popper>
<ul class="nolist"> <ul class="nolist">
<li <li
v-for="stash in user.stashes.filter((stash) => !stashes.some((selectedStash) => selectedStash.id === stash.id))" v-for="stash in assets.stashes.filter((stash) => !stashes.some((selectedStash) => selectedStash.id === stash.id))"
:key="`stash-result-${stash.id}`" :key="`stash-result-${stash.id}`"
v-close-popper v-close-popper
class="result-item result-stash result-label" class="result-item result-stash result-label"
@ -384,7 +384,7 @@ import getPath from '#/src/get-path.js';
import Dialog from '#/components/dialog/dialog.vue'; import Dialog from '#/components/dialog/dialog.vue';
import Checkbox from '#/components/form/checkbox.vue'; import Checkbox from '#/components/form/checkbox.vue';
const { user } = inject('pageContext'); const { user, assets } = inject('pageContext');
const emit = defineEmits(['close']); const emit = defineEmits(['close']);

View File

@ -212,6 +212,7 @@ function getPath(page) {
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
overflow: hidden;
} }
.pagination { .pagination {

View File

@ -339,6 +339,8 @@ function updateFilter(prop, value, reload = true) {
max-height: 6rem; max-height: 6rem;
justify-content: center; justify-content: center;
margin: .5rem 1rem 0 1rem; margin: .5rem 1rem 0 1rem;
width: 0;
flex-grow: 1;
} }
} }

View File

@ -715,6 +715,12 @@ function copySummary() {
} }
@media(--small-50) { @media(--small-50) {
.date {
font-size: .9rem;
}
}
@media(--small-60) {
.compact-show { .compact-show {
display: flex; display: flex;
} }
@ -722,9 +728,5 @@ function copySummary() {
.compact-hide { .compact-hide {
display: none; display: none;
} }
.date {
font-size: .9rem;
}
} }
</style> </style>

View File

@ -177,8 +177,8 @@ const query = pageContext.urlParsed.search.q;
.tile, .tile,
.movie-tile { .movie-tile {
width: 9rem; width: 8rem;
min-width: 9rem; min-width: 8rem;
} }
} }
} }

View File

@ -327,6 +327,7 @@ async function queryManticoreSql(filters, options, _reqUser) {
title_filtered=7, title_filtered=7,
actors=10, actors=10,
tags=9, tags=9,
movies=7,
meta=6, meta=6,
channel_name=2, channel_name=2,
channel_slug=3, channel_slug=3,

View File

@ -1,7 +1,50 @@
import { fetchEntities } from '../entities.js'; import {
fetchEntities,
fetchEntitiesById,
} from '../entities.js';
export async function fetchEntitiesApi(req, res) { export async function fetchEntitiesApi(req, res) {
const entities = await fetchEntities(req.query); const entities = await fetchEntities(req.query);
res.send(entities); res.send(entities);
} }
export const entitiesSchema = `
extend type Query {
entities(
query: String
limit: Int! = 30
page: Int! = 1
): EntitiesResult
entity(
id: Int!
): Entity
}
type EntitiesResult {
nodes: [Entity]
total: Int
}
type Entity {
id: Int!
name: String
slug: String
parent: Entity
}
`;
export async function fetchEntitiesGraphql(query, _req) {
const entities = await fetchEntities(query);
return {
nodes: entities,
};
}
export async function fetchEntitiesByIdGraphql(query, _req) {
const [entity] = await fetchEntitiesById([query.id]);
return entity;
}

View File

@ -4,18 +4,29 @@ import {
GraphQLScalarType, GraphQLScalarType,
} from 'graphql'; } from 'graphql';
import { scenesSchema, fetchScenesGraphql } from './scenes.js'; import {
scenesSchema,
fetchScenesGraphql,
fetchScenesByIdGraphql,
} from './scenes.js';
import {
entitiesSchema,
fetchEntitiesGraphql,
fetchEntitiesByIdGraphql,
} from './entities.js';
const schema = buildSchema(` const schema = buildSchema(`
type Query { type Query {
scenes( movies(
limit: Int = 30 limit: Int = 30
): Result ): ReleasesResult
} }
scalar Date scalar Date
${scenesSchema} ${scenesSchema}
${entitiesSchema}
`); `);
const DateTimeScalar = new GraphQLScalarType({ const DateTimeScalar = new GraphQLScalarType({
@ -39,6 +50,9 @@ export async function graphqlApi(req, res) {
}, },
rootValue: { rootValue: {
scenes: async (query) => fetchScenesGraphql(query, req), scenes: async (query) => fetchScenesGraphql(query, req),
scene: async (query) => fetchScenesByIdGraphql(query, req),
entities: async (query) => fetchEntitiesGraphql(query, req),
entity: async (query) => fetchEntitiesByIdGraphql(query, req),
}, },
}); });

View File

@ -1,6 +1,6 @@
import { stringify } from '@brillout/json-serializer/stringify'; /* eslint-disable-line import/extensions */ import { stringify } from '@brillout/json-serializer/stringify'; /* eslint-disable-line import/extensions */
import { fetchScenes } from '../scenes.js'; import { fetchScenes, fetchScenesById } from '../scenes.js';
import { parseActorIdentifier } from '../query.js'; import { parseActorIdentifier } from '../query.js';
import { getIdsBySlug } from '../cache.js'; import { getIdsBySlug } from '../cache.js';
import slugify from '../../utils/slugify.js'; import slugify from '../../utils/slugify.js';
@ -21,8 +21,8 @@ export async function curateScenesQuery(query) {
} = await promiseProps({ } = await promiseProps({
tagIds: getIdsBySlug([query.tagSlug, ...splitTags.filter((tag) => tag.charAt(0) !== '!')], 'tags'), tagIds: getIdsBySlug([query.tagSlug, ...splitTags.filter((tag) => tag.charAt(0) !== '!')], 'tags'),
notTagIds: getIdsBySlug([...(query.tagFilter || []), ...(splitTags.filter((tag) => tag.charAt(0) === '!').map((tag) => tag.slice(1)) || [])].map((tag) => slugify(tag)), 'tags'), notTagIds: getIdsBySlug([...(query.tagFilter || []), ...(splitTags.filter((tag) => tag.charAt(0) === '!').map((tag) => tag.slice(1)) || [])].map((tag) => slugify(tag)), 'tags'),
entityId: mainEntity ? await getIdsBySlug([mainEntity], 'entities').then(([id]) => id) : query.entityId, entityId: mainEntity ? getIdsBySlug([mainEntity], 'entities').then(([id]) => id) : query.entityId,
notEntityIds: await getIdsBySlug(splitEntities.filter((entity) => entity.charAt(0) === '!').map((entity) => entity.slice(1)), 'entities'), notEntityIds: getIdsBySlug(splitEntities.filter((entity) => entity.charAt(0) === '!').map((entity) => entity.slice(1)), 'entities'),
}); });
return { return {
@ -71,27 +71,48 @@ export async function fetchScenesApi(req, res) {
} }
export const scenesSchema = ` export const scenesSchema = `
type Aggregate { extend type Query {
scenes(
query: String
scope: String
entities: [String]
actorIds: [String]
tags: [String]
limit: Int! = 30
page: Int! = 1
): ReleasesResult
scene(
id: Int!
): Release
}
type ReleasesAggregate {
actors: [Actor] actors: [Actor]
} }
type Result { type ReleasesResult {
nodes: [Scene] nodes: [Release]
aggregates: Aggregate total: Int
aggregates: ReleasesAggregate
} }
type Scene { type Release {
id: Int! id: Int!
title: String title: String
effectiveDate: Date effectiveDate: Date
date: Date
createdAt: Date
shootId: Int shootId: Int
channel: Entity channel: Entity
network: Entity network: Entity
actors: [Actor] actors: [Actor]
tags: [Tag]
poster: Media poster: Media
trailer: Media trailer: Media
photos: [Media] photos: [Media]
covers: [Media] covers: [Media]
movies: [Release]
} }
type Actor { type Actor {
@ -100,11 +121,11 @@ export const scenesSchema = `
slug: String slug: String
} }
type Entity { type Tag {
id: Int! id: Int!
name: String name: String
slug: String slug: String
parent: Entity priority: Int
} }
type Media { type Media {
@ -123,28 +144,58 @@ export const scenesSchema = `
`; `;
export async function fetchScenesGraphql(query, req) { export async function fetchScenesGraphql(query, req) {
const mainEntity = query.entities?.find((entity) => entity.charAt(0) !== '!');
const {
tagIds,
notTagIds,
entityId,
notEntityIds,
} = await promiseProps({
tagIds: getIdsBySlug(query.tags?.filter((tag) => tag.charAt(0) !== '!'), 'tags'),
notTagIds: getIdsBySlug(query.tags?.filter((tag) => tag.charAt(0) === '!').map((tag) => tag.slice(1)).map((tag) => slugify(tag)), 'tags'),
entityId: getIdsBySlug([mainEntity], 'entities').then(([id]) => id),
notEntityIds: getIdsBySlug(query.entities?.filter((entity) => entity.charAt(0) === '!').map((entity) => entity.slice(1)), 'entities'),
});
const { const {
scenes, scenes,
aggActors, total,
/* /*
aggActors,
aggTags, aggTags,
aggChannels, aggChannels,
limit,
total,
*/ */
} = await fetchScenes({}, { } = await fetchScenes({
query: query.query, // query query query query
tagIds,
notTagIds,
entityId,
notEntityIds,
actorIds: query.actorIds?.filter((actorId) => actorId.charAt(0) !== '!').map((actorId) => Number(actorId)),
notActorIds: query.actorIds?.filter((actorId) => actorId.charAt(0) === '!').map((actorId) => Number(actorId.slice(1))),
scope: query.query && !query.scope
? 'results'
: query.scope,
isShowcased: null,
}, {
page: query.page || 1, page: query.page || 1,
limit: query.limit || 30, limit: query.limit || 30,
aggregate: false,
}, req.user); }, req.user);
// console.log('agg actors', aggActors); console.log(query);
console.log('query', query);
return { return {
nodes: scenes, nodes: scenes,
total,
/* restrict until deemed essential for 3rd party apps
aggregates: { aggregates: {
actors: aggActors, actors: aggActors,
tags: aggTags,
channels: aggChannels,
}, },
*/
}; };
/* /*
@ -158,3 +209,12 @@ export async function fetchScenesGraphql(query, req) {
}; };
*/ */
} }
export async function fetchScenesByIdGraphql(query, req) {
const [scene] = await fetchScenesById([query.id], {
reqUser: req.user,
includePartOf: true,
});
return scene;
}