forked from DebaucheryLibrarian/traxxx
Added search to tags.
This commit is contained in:
parent
959b5d9d0e
commit
eb1f8f86fd
|
@ -7,48 +7,9 @@
|
|||
ref="filters"
|
||||
class="filters"
|
||||
>
|
||||
<div class="filters-row">
|
||||
<ul class="genders nolist">
|
||||
<li class="gender">
|
||||
<router-link
|
||||
:to="{ name: 'actors', params: { gender: 'all', letter, pageNumber: 1 } }"
|
||||
:class="{ selected: gender === 'all' }"
|
||||
class="gender-link all"
|
||||
>all</router-link>
|
||||
</li>
|
||||
<li class="gender">
|
||||
<router-link
|
||||
:to="{ name: 'actors', params: { gender: 'female', letter, pageNumber: 1 } }"
|
||||
:class="{ selected: gender === 'female' }"
|
||||
class="gender-link female"
|
||||
><Gender gender="female" /></router-link>
|
||||
</li>
|
||||
<li class="gender">
|
||||
<router-link
|
||||
:to="{ name: 'actors', params: { gender: 'male', letter, pageNumber: 1 } }"
|
||||
:class="{ selected: gender === 'male' }"
|
||||
class="gender-link male"
|
||||
replace
|
||||
><Gender gender="male" /></router-link>
|
||||
</li>
|
||||
<li class="gender">
|
||||
<router-link
|
||||
:to="{ name: 'actors', params: { gender: 'trans', letter, pageNumber: 1 } }"
|
||||
:class="{ selected: gender === 'trans' }"
|
||||
class="gender-link transsexual"
|
||||
replace
|
||||
><Gender gender="transsexual" /></router-link>
|
||||
</li>
|
||||
<li class="gender">
|
||||
<router-link
|
||||
:to="{ name: 'actors', params: { gender: 'other', letter, pageNumber: 1 } }"
|
||||
:class="{ selected: gender === 'other' }"
|
||||
class="gender-link other"
|
||||
replace
|
||||
><Icon icon="question5" /></router-link>
|
||||
</li>
|
||||
</ul>
|
||||
<SearchBar :placeholder="`Search ${totalCount} actors`" />
|
||||
|
||||
<div class="filters-row">
|
||||
<ul class="nolist">
|
||||
<li>
|
||||
<Tooltip class="filter boobs">
|
||||
|
@ -195,9 +156,48 @@
|
|||
</Tooltip>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<SearchBar :placeholder="`Search ${totalCount} actors`" />
|
||||
<ul class="genders nolist">
|
||||
<li class="gender">
|
||||
<router-link
|
||||
:to="{ name: 'actors', params: { gender: 'all', letter, pageNumber: 1 } }"
|
||||
:class="{ selected: gender === 'all' }"
|
||||
class="gender-link all"
|
||||
>all</router-link>
|
||||
</li>
|
||||
<li class="gender">
|
||||
<router-link
|
||||
:to="{ name: 'actors', params: { gender: 'female', letter, pageNumber: 1 } }"
|
||||
:class="{ selected: gender === 'female' }"
|
||||
class="gender-link female"
|
||||
><Gender gender="female" /></router-link>
|
||||
</li>
|
||||
<li class="gender">
|
||||
<router-link
|
||||
:to="{ name: 'actors', params: { gender: 'male', letter, pageNumber: 1 } }"
|
||||
:class="{ selected: gender === 'male' }"
|
||||
class="gender-link male"
|
||||
replace
|
||||
><Gender gender="male" /></router-link>
|
||||
</li>
|
||||
<li class="gender">
|
||||
<router-link
|
||||
:to="{ name: 'actors', params: { gender: 'trans', letter, pageNumber: 1 } }"
|
||||
:class="{ selected: gender === 'trans' }"
|
||||
class="gender-link transsexual"
|
||||
replace
|
||||
><Gender gender="transsexual" /></router-link>
|
||||
</li>
|
||||
<li class="gender">
|
||||
<router-link
|
||||
:to="{ name: 'actors', params: { gender: 'other', letter, pageNumber: 1 } }"
|
||||
:class="{ selected: gender === 'other' }"
|
||||
class="gender-link other"
|
||||
replace
|
||||
><Icon icon="question5" /></router-link>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div class="tiles">
|
||||
|
@ -291,6 +291,7 @@ async function fetchActors(scroll) {
|
|||
|
||||
async function searchActors(scroll) {
|
||||
const actors = await this.$store.dispatch('searchActors', {
|
||||
minLength: 1,
|
||||
query: this.$route.query.query,
|
||||
limit: this.limit,
|
||||
});
|
||||
|
@ -419,7 +420,6 @@ export default {
|
|||
.search {
|
||||
width: 0;
|
||||
flex-grow: 1;
|
||||
justify-content: flex-end;
|
||||
box-sizing: border-box;
|
||||
padding: 0 1rem;
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ export default {
|
|||
.filters,
|
||||
.filters-row {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
justify-content: flex-end;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
|
@ -435,6 +435,10 @@ export default {
|
|||
margin: 1rem 0 .5rem 0;
|
||||
}
|
||||
|
||||
.filters-row {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.filters-row,
|
||||
.filter {
|
||||
padding: 0 1rem;
|
||||
|
@ -443,7 +447,7 @@ export default {
|
|||
.genders {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
padding: 0 .5rem 0 0;
|
||||
padding: 0 0 0 .5rem;
|
||||
}
|
||||
|
||||
.letter,
|
||||
|
@ -686,7 +690,7 @@ export default {
|
|||
|
||||
@media(max-width: $breakpoint-kilo) {
|
||||
.filters {
|
||||
flex-direction: column-reverse;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
::v-deep(.search) {
|
||||
|
@ -698,7 +702,7 @@ export default {
|
|||
|
||||
@media(max-width: $breakpoint) {
|
||||
.filters-row {
|
||||
flex-direction: column;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
.genders {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<li class="nav-item">
|
||||
<router-link
|
||||
v-slot="{ href, isActive, navigate }"
|
||||
to="/actors"
|
||||
:to="{ name: 'actors', params: { pageNumber: 1 } }"
|
||||
custom
|
||||
>
|
||||
<a
|
||||
|
@ -31,7 +31,7 @@
|
|||
<li class="nav-item">
|
||||
<router-link
|
||||
v-slot="{ href, isActive, navigate }"
|
||||
to="/channels"
|
||||
:to="{ name: 'channels' }"
|
||||
custom
|
||||
>
|
||||
<a
|
||||
|
@ -46,7 +46,7 @@
|
|||
<li class="nav-item">
|
||||
<router-link
|
||||
v-slot="{ href, isActive, navigate }"
|
||||
to="/tags"
|
||||
:to="{ name: 'tags' }"
|
||||
custom
|
||||
>
|
||||
<a
|
||||
|
@ -61,7 +61,7 @@
|
|||
<li class="nav-item">
|
||||
<router-link
|
||||
v-slot="{ href, isActive, navigate }"
|
||||
to="/movies"
|
||||
:to="{ name: 'movies', params: { range: 'latest', pageNumber: 1 } }"
|
||||
custom
|
||||
>
|
||||
<a
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
<template>
|
||||
<div class="tags">
|
||||
<div class="content-inner">
|
||||
<SearchBar :placeholder="'Search tags'" />
|
||||
|
||||
<div
|
||||
v-for="(tags, category) in categories"
|
||||
:key="category"
|
||||
|
@ -19,6 +22,7 @@
|
|||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Footer />
|
||||
</div>
|
||||
|
@ -26,13 +30,9 @@
|
|||
|
||||
<script>
|
||||
import Tag from './tile.vue';
|
||||
import SearchBar from '../search/bar.vue';
|
||||
|
||||
function sfw() {
|
||||
return this.$store.state.ui.sfw;
|
||||
}
|
||||
|
||||
async function mounted() {
|
||||
const tagSlugsByCategory = {
|
||||
const tagSlugsByCategory = {
|
||||
popular: [
|
||||
'anal',
|
||||
'lesbian',
|
||||
|
@ -141,7 +141,17 @@ async function mounted() {
|
|||
'vr',
|
||||
'bts',
|
||||
],
|
||||
};
|
||||
};
|
||||
|
||||
function sfw() {
|
||||
return this.$store.state.ui.sfw;
|
||||
}
|
||||
|
||||
async function fetchTags() {
|
||||
if (this.$route.query.query) {
|
||||
await this.searchTags();
|
||||
return;
|
||||
}
|
||||
|
||||
const tags = await this.$store.dispatch('fetchTags', {
|
||||
slugs: Object.values(tagSlugsByCategory).flat(),
|
||||
|
@ -153,13 +163,30 @@ async function mounted() {
|
|||
...acc,
|
||||
[category]: tagSlugs.map(tagSlug => tagsBySlug[tagSlug]),
|
||||
}), {});
|
||||
}
|
||||
|
||||
async function searchTags() {
|
||||
const tags = await this.$store.dispatch('searchTags', {
|
||||
minLength: 1,
|
||||
query: this.$route.query.query,
|
||||
limit: 20,
|
||||
});
|
||||
|
||||
this.categories = {
|
||||
results: tags,
|
||||
};
|
||||
}
|
||||
|
||||
async function mounted() {
|
||||
this.pageTitle = 'Tags';
|
||||
|
||||
await this.fetchTags();
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Tag,
|
||||
SearchBar,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -170,7 +197,14 @@ export default {
|
|||
computed: {
|
||||
sfw,
|
||||
},
|
||||
watch: {
|
||||
$route: fetchTags,
|
||||
},
|
||||
mounted,
|
||||
methods: {
|
||||
fetchTags,
|
||||
searchTags,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -178,6 +212,12 @@ export default {
|
|||
@import 'theme';
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.content-inner {
|
||||
padding: 1rem 1rem 0 1rem;
|
||||
}
|
||||
|
||||
|
@ -191,7 +231,7 @@ export default {
|
|||
.heading {
|
||||
text-transform: capitalize;
|
||||
padding: 0 0 0 .5rem;
|
||||
margin: 2rem 0 1rem 0;
|
||||
margin: 1.75rem 0 1rem 0;
|
||||
}
|
||||
|
||||
.category:first-child .heading {
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
<template>
|
||||
<div
|
||||
v-if="tag.poster"
|
||||
class="tile"
|
||||
>
|
||||
<router-link
|
||||
:to="`/tag/${tag.slug}`"
|
||||
:title="tag.name"
|
||||
:class="{ blank: !tag.poster }"
|
||||
class="poster-link"
|
||||
>
|
||||
<template v-if="tag.poster">
|
||||
<img
|
||||
v-if="!lazy && !sfw"
|
||||
:src="`/img/${tag.poster.thumbnail}`"
|
||||
|
@ -51,6 +52,12 @@
|
|||
:photo="tag.poster"
|
||||
favicon
|
||||
/>
|
||||
</template>
|
||||
|
||||
<Icon
|
||||
v-else
|
||||
icon="price-tag2"
|
||||
/>
|
||||
</router-link>
|
||||
|
||||
<router-link
|
||||
|
@ -59,11 +66,6 @@
|
|||
:title="tag.name"
|
||||
>{{ tag.name }}</router-link>
|
||||
</div>
|
||||
|
||||
<span
|
||||
v-else
|
||||
class="title"
|
||||
>{{ tag.name }}</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
@ -100,13 +102,16 @@ export default {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.tile {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
font-size: 0;
|
||||
|
||||
&:hover {
|
||||
.poster {
|
||||
.poster,
|
||||
.blank {
|
||||
box-shadow: 0 0 2px var(--darken);
|
||||
}
|
||||
|
||||
|
@ -119,15 +124,30 @@ export default {
|
|||
.poster {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 13.5rem;
|
||||
object-fit: cover;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
box-shadow: 0 0 3px var(--darken-weak);
|
||||
}
|
||||
|
||||
.poster,
|
||||
.blank {
|
||||
height: 13.5rem;
|
||||
}
|
||||
|
||||
.poster-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
flex-grow: 1;
|
||||
background: var(--shadow-hint);
|
||||
|
||||
.icon {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
fill: var(--shadow-weak);
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
|
|
|
@ -437,11 +437,13 @@ function initActorActions(store, router) {
|
|||
search: $query,
|
||||
minLength: $minLength
|
||||
first: $limit
|
||||
orderBy: NAME_ASC
|
||||
) {
|
||||
id
|
||||
name
|
||||
slug
|
||||
age
|
||||
dateOfBirth
|
||||
ageFromBirth
|
||||
ageAtDeath
|
||||
dateOfBirth
|
||||
dateOfDeath
|
||||
|
|
|
@ -276,7 +276,7 @@ function initTagsActions(store, _router) {
|
|||
$minLength: Int = 2
|
||||
) {
|
||||
tags: searchTags(
|
||||
search: $query,
|
||||
query: $query,
|
||||
first: $limit
|
||||
minLength: $minLength
|
||||
) {
|
||||
|
|
|
@ -1396,6 +1396,8 @@ exports.up = knex => Promise.resolve()
|
|||
.then(() => { // eslint-disable-line arrow-body-style
|
||||
// allow vim fold
|
||||
return knex.raw(`
|
||||
CREATE EXTENSION pg_trgm;
|
||||
|
||||
CREATE FUNCTION current_user_id() RETURNS INTEGER AS $$
|
||||
/* if the user ID is undefined, the adapter will pass it as a string, which cannot be cast as NULL by ::integer */
|
||||
SELECT NULLIF(current_setting('user.id', true), '')::integer;
|
||||
|
@ -1437,18 +1439,20 @@ exports.up = knex => Promise.resolve()
|
|||
CREATE FUNCTION search_actors(search text, min_length smallint DEFAULT 2) RETURNS SETOF actors AS $$
|
||||
SELECT * FROM actors
|
||||
WHERE length(search) >= min_length
|
||||
AND name ILIKE ('%' || TRIM(search) || '%')
|
||||
AND CASE
|
||||
WHEN length(search) > 1
|
||||
THEN name ILIKE ('%' || TRIM(search) || '%')
|
||||
ELSE name ILIKE (TRIM(search) || '%')
|
||||
END
|
||||
$$ LANGUAGE SQL STABLE;
|
||||
|
||||
CREATE FUNCTION search_tags(search text, min_length smallint DEFAULT 2, is_primary boolean DEFAULT true) RETURNS SETOF tags AS $$
|
||||
SELECT * FROM tags
|
||||
WHERE length(search) >= min_length
|
||||
AND name ILIKE ('%' || TRIM(search) || '%')
|
||||
AND CASE
|
||||
WHEN is_primary
|
||||
THEN tags.alias_for IS NULL
|
||||
ELSE true
|
||||
END
|
||||
CREATE FUNCTION search_tags(query text, min_length smallint DEFAULT 2) RETURNS SETOF tags AS $$
|
||||
SELECT aliases.* FROM tags
|
||||
LEFT JOIN tags AS aliases ON aliases.id = tags.alias_for OR (tags.alias_for IS NULL AND aliases.id = tags.id)
|
||||
WHERE length(query) >= min_length
|
||||
AND tags.name ILIKE ('%' || TRIM(query) || '%')
|
||||
GROUP BY aliases.id
|
||||
ORDER BY similarity(aliases.slug, query) DESC, slug ASC
|
||||
$$ LANGUAGE SQL STABLE;
|
||||
|
||||
CREATE FUNCTION actors_tags(actor actors, selectable_tags text[]) RETURNS SETOF tags AS $$
|
||||
|
@ -1822,6 +1826,7 @@ exports.down = (knex) => { // eslint-disable-line arrow-body-style
|
|||
DROP FUNCTION IF EXISTS search_sites;
|
||||
DROP FUNCTION IF EXISTS search_entities;
|
||||
DROP FUNCTION IF EXISTS search_actors;
|
||||
DROP FUNCTION IF EXISTS search_movies;
|
||||
DROP FUNCTION IF EXISTS search_tags;
|
||||
DROP FUNCTION IF EXISTS get_random_sfw_media_id;
|
||||
|
||||
|
|
|
@ -977,14 +977,14 @@ const tags = [
|
|||
name: 'DA triple penetration',
|
||||
slug: 'da-tp',
|
||||
priority: 7,
|
||||
description: 'Triple penetration with [two cocks in your ass](/tag/dap), and one in your pussy. Also see [double vaginal triple penetration](/tag/dv-tp).',
|
||||
description: '[Triple penetration](/tag/triple-penetration) with [two cocks in your ass](/tag/dap), and one in your pussy. Also see [double vaginal triple penetration](/tag/dv-tp).',
|
||||
group: 'penetration',
|
||||
},
|
||||
{
|
||||
name: 'DV triple penetration',
|
||||
slug: 'dv-tp',
|
||||
priority: 7,
|
||||
description: 'Triple penetration with [two cocks in your pussy](/tag/dvp), and one in [your ass](/tag/anal). Also see [double anal triple penetration](/tag/da-tp).',
|
||||
description: '[Triple penetration](/tag/triple-penetration) with [two cocks in your pussy](/tag/dvp), and one in [your ass](/tag/anal). Also see [double anal triple penetration](/tag/da-tp).',
|
||||
group: 'penetration',
|
||||
},
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue