Fixed search inputs not working in Firefox/Safari. Added Stashes and Alerts to header menu. Indexing compilation tags as assigned tags in Manticore.
This commit is contained in:
@@ -310,3 +310,23 @@
|
|||||||
box-shadow: 0 0 3px var(--shadow-weak-10);
|
box-shadow: 0 0 3px var(--shadow-weak-10);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-cancel {
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
padding: .5rem;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
width: 1rem;
|
||||||
|
height: 1rem;
|
||||||
|
fill: var(--glass);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
fill: var(--error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,12 +5,19 @@
|
|||||||
<!-- onsearch not compatible with FF and Safari -->
|
<!-- onsearch not compatible with FF and Safari -->
|
||||||
<input
|
<input
|
||||||
v-model="q"
|
v-model="q"
|
||||||
type="search"
|
type="input"
|
||||||
placeholder="Search actors"
|
placeholder="Search actors"
|
||||||
class="input search"
|
class="input search"
|
||||||
@search="search"
|
@keydown.enter="search"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
v-if="q"
|
||||||
|
icon="cross2"
|
||||||
|
class="search-button"
|
||||||
|
@click="q = ''; search()"
|
||||||
|
/>
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
icon="search"
|
icon="search"
|
||||||
class="search-button"
|
class="search-button"
|
||||||
|
|||||||
@@ -187,6 +187,26 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<li class="menu-item">
|
||||||
|
<a
|
||||||
|
:href="`/user/${user.username}/stashes`"
|
||||||
|
class="menu-button nolink stashes"
|
||||||
|
>
|
||||||
|
<Icon icon="folder-heart" />
|
||||||
|
Stashes
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="menu-item">
|
||||||
|
<a
|
||||||
|
:href="`/user/${user.username}/alerts`"
|
||||||
|
class="menu-button nolink alerts"
|
||||||
|
>
|
||||||
|
<Icon icon="alarm" />
|
||||||
|
Alerts
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
v-close-popper
|
v-close-popper
|
||||||
class="menu-item menu-button"
|
class="menu-item menu-button"
|
||||||
|
|||||||
@@ -4,14 +4,28 @@
|
|||||||
v-if="showFilters"
|
v-if="showFilters"
|
||||||
:class="{ loading }"
|
:class="{ loading }"
|
||||||
>
|
>
|
||||||
<div class="filter">
|
<div class="filter search-container">
|
||||||
|
<!-- onsearch not compatible with FF and Safari -->
|
||||||
<input
|
<input
|
||||||
v-model="filters.search"
|
v-model="filters.search"
|
||||||
type="search"
|
type="input"
|
||||||
placeholder="Search movies"
|
placeholder="Search movies"
|
||||||
class="search input"
|
class="search input"
|
||||||
@search="search"
|
@keydown.enter="search"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
v-if="filters.search"
|
||||||
|
icon="cross2"
|
||||||
|
class="search-button"
|
||||||
|
@click="filters.search = ''; search()"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
icon="search"
|
||||||
|
class="search-button"
|
||||||
|
@click="search"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<YearsFilter
|
<YearsFilter
|
||||||
|
|||||||
@@ -12,12 +12,19 @@
|
|||||||
<!-- onsearch not compatible with FF and Safari -->
|
<!-- onsearch not compatible with FF and Safari -->
|
||||||
<input
|
<input
|
||||||
v-model="filters.search"
|
v-model="filters.search"
|
||||||
type="search"
|
type="input"
|
||||||
placeholder="Search scenes"
|
placeholder="Search scenes"
|
||||||
class="search input"
|
class="search input"
|
||||||
@search="search"
|
@keydown.enter="search"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
v-if="filters.search"
|
||||||
|
icon="cross2"
|
||||||
|
class="search-button"
|
||||||
|
@click="filters.search = ''; search()"
|
||||||
|
/>
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
icon="search"
|
icon="search"
|
||||||
class="search-button"
|
class="search-button"
|
||||||
|
|||||||
@@ -1,13 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<Admin class="page">
|
<Admin class="page">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<input
|
<form
|
||||||
v-model="actorQuery"
|
class="search"
|
||||||
type="search"
|
@submit.prevent="searchActors"
|
||||||
placeholder="Search actors"
|
|
||||||
class="input search"
|
|
||||||
@search="searchActors"
|
|
||||||
>
|
>
|
||||||
|
<input
|
||||||
|
v-model="actorQuery"
|
||||||
|
type="input"
|
||||||
|
placeholder="Search actors"
|
||||||
|
class="input search-input"
|
||||||
|
>
|
||||||
|
|
||||||
|
<button
|
||||||
|
v-if="actorQuery?.length"
|
||||||
|
type="button"
|
||||||
|
class="search-cancel nobutton"
|
||||||
|
@click="actorQuery = ''; searchActors()"
|
||||||
|
>
|
||||||
|
<Icon icon="cross2" />
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
<div class="header-actions">
|
<div class="header-actions">
|
||||||
<button
|
<button
|
||||||
@@ -208,10 +221,16 @@ onMounted(() => {
|
|||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.search {
|
.search {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
max-width: 20rem;
|
max-width: 20rem;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
|
|||||||
@@ -6,16 +6,23 @@
|
|||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
v-model="query"
|
v-model="query"
|
||||||
type="search"
|
type="input"
|
||||||
placeholder="Search channels"
|
placeholder="Search channels"
|
||||||
class="search input"
|
class="search input"
|
||||||
@search="search"
|
@keydown.enter="search"
|
||||||
>
|
>
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
icon="search"
|
icon="search"
|
||||||
@click="search"
|
@click="search"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
v-if="query"
|
||||||
|
icon="cross2"
|
||||||
|
class="search-button"
|
||||||
|
@click="query = ''; search()"
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -35,19 +35,27 @@
|
|||||||
class="search-container"
|
class="search-container"
|
||||||
@submit.prevent="search"
|
@submit.prevent="search"
|
||||||
>
|
>
|
||||||
|
<!-- onsearch not compatible with FF and Safari -->
|
||||||
<input
|
<input
|
||||||
ref="searchInput"
|
ref="searchInput"
|
||||||
v-model="query"
|
v-model="query"
|
||||||
type="search"
|
type="input"
|
||||||
placeholder="Search tags"
|
placeholder="Search tags"
|
||||||
class="search input"
|
class="search input"
|
||||||
@search="search"
|
@keydown.enter="search"
|
||||||
>
|
>
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
icon="search"
|
icon="search"
|
||||||
@click="search"
|
@click="search"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
v-if="query"
|
||||||
|
icon="cross2"
|
||||||
|
class="search-button"
|
||||||
|
@click="query = ''; search()"
|
||||||
|
/>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -717,6 +717,12 @@ export async function mergeActors(targetActorId, sourceActorIds, reqUser) {
|
|||||||
.whereIn('actor_id', sourceActorIds)
|
.whereIn('actor_id', sourceActorIds)
|
||||||
.returning('stash_id');
|
.returning('stash_id');
|
||||||
|
|
||||||
|
/* TODO: add revision entries
|
||||||
|
console.log('SOURCES', targetActor, sourceActors);
|
||||||
|
|
||||||
|
throw new Error('ABORT');
|
||||||
|
*/
|
||||||
|
|
||||||
await trx.commit();
|
await trx.commit();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
await trx.rollback();
|
await trx.rollback();
|
||||||
|
|||||||
21
src/sync.js
21
src/sync.js
@@ -187,13 +187,28 @@ export async function syncManticoreScenes(sceneIds) {
|
|||||||
const flatTags = scene.tags.filter((tag) => tag.f3 > 6).flatMap((tag) => [tag.f2].concat(tag.f4)).filter(Boolean); // only make top tags searchable to minimize cluttered results
|
const flatTags = scene.tags.filter((tag) => tag.f3 > 6).flatMap((tag) => [tag.f2].concat(tag.f4)).filter(Boolean); // only make top tags searchable to minimize cluttered results
|
||||||
const filteredTitle = filterTitle(scene.title, [...flatActors, ...flatTags]);
|
const filteredTitle = filterTitle(scene.title, [...flatActors, ...flatTags]);
|
||||||
|
|
||||||
|
const isCompilation = scene.tags.some((tag) => tag.f2 === 'compilation');
|
||||||
|
|
||||||
// use decimal packing with 5-decimal pad to allow for actor-specific tags, i.e. actor 135 tag 5 = 13500005
|
// use decimal packing with 5-decimal pad to allow for actor-specific tags, i.e. actor 135 tag 5 = 13500005
|
||||||
// all global tags are necessarily < 10,000, all tags for actor 135 are >= 13500000 and <= 13599999
|
// all global tags are necessarily < 10,000, all tags for actor 135 are >= 13500000 and <= 13599999
|
||||||
// f1 = tag ID, f5 = actor ID
|
// f1 = tag ID, f5 = actor ID
|
||||||
const assignedTagIds = scene.tags.map((tag) => (tag.f5 === null ? tag.f1 : tag.f5 * 1_000_00 + tag.f1));
|
const assignedTagIds = scene.tags.map((tag) => {
|
||||||
|
if (tag.f5) {
|
||||||
|
// tag is assigned to actor, pack tag ID with actor ID
|
||||||
|
return tag.f5 * 1_000_00 + tag.f1;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
if (isCompilation && tag.f2 !== 'compilation') {
|
||||||
if (sceneId === '187734') {
|
// tag is part of a compilation, pack with arbitrary large number that will never be an actor ID (famous last words)
|
||||||
|
return 900_000_000 * 1_000_00 + tag.f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// plain tag ID
|
||||||
|
return tag.f1;
|
||||||
|
});
|
||||||
|
|
||||||
|
/* abort to inspect
|
||||||
|
if (sceneId === '554480') {
|
||||||
console.log(scene, assignedTagIds);
|
console.log(scene, assignedTagIds);
|
||||||
throw new Error('ABORT');
|
throw new Error('ABORT');
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user