Added 'match all' tag filter for actors and toggle to 'match any'.

This commit is contained in:
DebaucheryLibrarian 2020-07-19 03:52:36 +02:00
parent f147d0f3b3
commit 2bb511cd99
45 changed files with 124 additions and 108 deletions

View File

@ -291,6 +291,7 @@
</Scroll> </Scroll>
<FilterBar <FilterBar
ref="filter"
:fetch-releases="fetchActor" :fetch-releases="fetchActor"
:items-total="totalCount" :items-total="totalCount"
:items-per-page="limit" :items-per-page="limit"
@ -322,7 +323,7 @@ import Social from './social.vue';
async function fetchActor() { async function fetchActor() {
const { actor, releases, totalCount } = await this.$store.dispatch('fetchActorById', { const { actor, releases, totalCount } = await this.$store.dispatch('fetchActorById', {
actorId: Number(this.$route.params.actorId), actorId: Number(this.$route.params.actorId),
limit: 10, limit: this.limit,
pageNumber: Number(this.$route.params.pageNumber), pageNumber: Number(this.$route.params.pageNumber),
range: this.$route.params.range, range: this.$route.params.range,
}); });
@ -330,6 +331,10 @@ async function fetchActor() {
this.actor = actor; this.actor = actor;
this.releases = releases; this.releases = releases;
this.totalCount = totalCount; this.totalCount = totalCount;
if (this.$refs.filter) {
this.$refs.filter.$el.scrollIntoView();
}
} }
function sfw() { function sfw() {
@ -364,7 +369,7 @@ export default {
actor: null, actor: null,
releases: null, releases: null,
totalCount: 0, totalCount: 0,
limit: 10, limit: 15,
pageTitle: null, pageTitle: null,
bioExpanded: false, bioExpanded: false,
photosExpanded: false, photosExpanded: false,

View File

@ -15,6 +15,21 @@
</div> </div>
<div slot="popover"> <div slot="popover">
<select
v-model="mode"
class="mode"
@change="$router.push({ query: { ...$route.query, mode } })"
>
<option
value="all"
class="option"
>match all selected</option>
<option
value="any"
class="option"
>match any selected</option>
</select>
<ul class="tags nolist"> <ul class="tags nolist">
<li <li
v-for="tag in availableTags" v-for="tag in availableTags"
@ -22,7 +37,7 @@
class="tag" class="tag"
:class="{ selected: selectedTags.includes(tag.slug) }" :class="{ selected: selectedTags.includes(tag.slug) }"
> >
<router-link :to="{ query: { ...getNewRange(tag.slug) } }"> <router-link :to="{ query: { ...getNewRange(tag.slug), mode } }">
<Icon <Icon
icon="checkmark" icon="checkmark"
class="include" class="include"
@ -30,7 +45,7 @@
</router-link> </router-link>
<router-link <router-link
:to="{ query: { ...(selectedTags.length === 1 && selectedTags.includes(tag.slug) ? null : { tags: tag.slug }) } }" :to="{ query: { ...(selectedTags.length === 1 && selectedTags.includes(tag.slug) ? null : { tags: tag.slug }), mode }, params: { pageNumber: 1 } }"
class="name" class="name"
>{{ tag.name }}</router-link> >{{ tag.name }}</router-link>
</li> </li>
@ -71,6 +86,11 @@ export default {
default: () => [], default: () => [],
}, },
}, },
data() {
return {
mode: 'all',
};
},
computed: { computed: {
selectedTags, selectedTags,
}, },
@ -119,6 +139,15 @@ export default {
} }
} }
.mode {
width: 100%;
background: none;
padding: .75rem;
font-size: 1rem;
border: none;
border-bottom: solid 1px var(--shadow-hint);
}
.tags { .tags {
padding: .5rem 0; padding: .5rem 0;
} }

View File

@ -255,16 +255,16 @@ export default {
} }
.labels { .labels {
padding: .25rem .5rem 1rem .5rem; padding: 0 .5rem 1rem .25rem;
max-height: .5rem; max-height: .5rem;
overflow-y: hidden; overflow-y: hidden;
} }
.shoot { .shoot {
display: inline; display: inline;
padding: .25rem; padding: .25rem .5rem .25rem .25rem;
background: var(--shadow-hint); border-right: solid 1px var(--shadow-hint);
color: var(--shadow); color: var(--shadow-strong);
font-size: 0.8rem; font-size: 0.8rem;
font-weight: bold; font-weight: bold;
} }
@ -275,7 +275,7 @@ export default {
} }
.tag { .tag {
margin: 0 .25rem .25rem 0; margin: 0 0 .25rem 0;
} }
.tag-link { .tag-link {
@ -286,7 +286,6 @@ export default {
font-weight: bold; font-weight: bold;
text-decoration: none; text-decoration: none;
line-height: 1; line-height: 1;
border: solid 1px var(--shadow-hint);
&:hover { &:hover {
color: var(--primary); color: var(--primary);

View File

@ -3,6 +3,7 @@
<div <div
v-for="(tags, category) in categories" v-for="(tags, category) in categories"
:key="category" :key="category"
class="category"
> >
<h3 class="heading">{{ category }}</h3> <h3 class="heading">{{ category }}</h3>
@ -47,12 +48,13 @@ async function mounted() {
'creampie', 'creampie',
'squirting', 'squirting',
], ],
appearance: [ ethnicity: [
'asian', 'asian',
'ebony', 'ebony',
'latina', 'latina',
'caucasian', 'caucasian',
'indian', ],
appearance: [
'natural-boobs', 'natural-boobs',
'fake-boobs', 'fake-boobs',
'blonde', 'blonde',
@ -155,7 +157,11 @@ export default {
} }
.heading { .heading {
font-size: 1.3rem; display: inline-block;
background: var(--primary);
color: var(--text-light);
padding: .5rem;
font-size: 1rem;
text-transform: capitalize; text-transform: capitalize;
} }

View File

@ -1,11 +1,6 @@
import config from 'config'; import config from 'config';
import { graphql, get } from '../api'; import { graphql, get } from '../api';
import { import { releaseFields } from '../fragments';
releaseFields,
releasePosterFragment,
releaseActorsFragment,
releaseTagsFragment,
} from '../fragments';
import { curateActor, curateRelease } from '../curate'; import { curateActor, curateRelease } from '../curate';
import getDateRange from '../get-date-range'; import getDateRange from '../get-date-range';
@ -18,18 +13,18 @@ function initActorActions(store, router) {
}) { }) {
const { before, after, orderBy } = getDateRange(range); const { before, after, orderBy } = getDateRange(range);
const includeTags = router.currentRoute.query.tags ? router.currentRoute.query.tags.split(',') : []; const includeTags = router.currentRoute.query.tags ? router.currentRoute.query.tags.split(',') : [];
const mode = router.currentRoute.query.mode || 'all';
const { actor, connection: { releases, totalCount } } = await graphql(` const { actor } = await graphql(`
query Actor( query Actor(
$actorId: Int! $actorId: Int!
$limit:Int = 10, $limit:Int = 10,
$offset:Int = 0, $offset:Int = 0,
$after:Datetime = "1900-01-01", $after:Datetime = "1900-01-01",
$before:Datetime = "2100-01-01", $before:Datetime = "2100-01-01",
$orderBy:[ReleasesActorsOrderBy!] $orderBy:[ReleasesOrderBy!]
$selectableTags: [String], $selectableTags: [String],
$excludeTags: [String!] $includeTags: [String!],
${includeTags.length > 0 ? '$includeTags: [String!]' : ''}
) { ) {
actor(id: $actorId) { actor(id: $actorId) {
id id
@ -150,92 +145,35 @@ function initActorActions(store, router) {
slug slug
priority priority
} }
releasesConnection: releasesActorsConnection( scenesConnection(
filter: { filter: {
release: { date: {
date: { lessThan: $before,
lessThan: $before, greaterThan: $after,
greaterThan: $after, }
} ${mode === 'any' ? `
releasesTagsConnection: { releasesTagsConnection: {
none: { some: {
tag: { tag: {
slug: { slug: {
in: $excludeTags in: $includeTags
} }
} }
} }
} }
} ` : ''}
} }
${mode === 'all' ? 'selectedTags: $includeTags' : ''}
first: $limit first: $limit
offset: $offset offset: $offset
orderBy: $orderBy orderBy: $orderBy
) { ) {
releases: nodes { releases: nodes {
release {
id
url
title
date
slug
${releaseActorsFragment}
${releaseTagsFragment}
${releasePosterFragment}
entity {
id
name
slug
url
parent {
id
name
slug
url
}
}
}
}
}
}
connection: releasesActorsConnection(
first: $limit
offset: $offset
orderBy: $orderBy
condition: {
actorId: $actorId
}
filter: {
or: [
{
release: {
date: {
lessThan: $before,
greaterThan: $after
}
}
},
]
${includeTags.length > 0 ? `release: {
releasesTagsConnection: {
some: {
tag: {
slug: {
in: $includeTags
}
}
}
}
}` : ''}
}
) {
releases: nodes {
release {
${releaseFields} ${releaseFields}
} }
} totalCount
totalCount }
} }
} }
`, { `, {
actorId, actorId,
@ -244,15 +182,15 @@ function initActorActions(store, router) {
after, after,
before, before,
selectableTags: config.selectableTags, selectableTags: config.selectableTags,
orderBy: orderBy === 'DATE_DESC' ? 'RELEASE_BY_RELEASE_ID__DATE_DESC' : 'RELEASE_BY_RELEASE_ID__DATE_ASC', orderBy,
excludeTags: store.state.ui.filter, excludeTags: store.state.ui.filter,
includeTags, includeTags,
}); });
return { return {
actor: curateActor(actor, null, curateRelease), actor: curateActor(actor, null, curateRelease),
releases: releases.map(release => curateRelease(release.release)), releases: actor.scenesConnection.releases.map(release => curateRelease(release)),
totalCount, totalCount: actor.scenesConnection.totalCount,
}; };
} }

View File

@ -5,12 +5,13 @@ export default {
selectableTags: [ selectableTags: [
'airtight', 'airtight',
'anal', 'anal',
'blowbang',
'blowjob', 'blowjob',
'creampie', 'creampie',
'deepthroat', 'deepthroat',
'double-anal', 'dap',
'double-penetration', 'dp',
'double-vaginal', 'dvp',
'facefucking', 'facefucking',
'facial', 'facial',
'fisting', 'fisting',
@ -18,6 +19,7 @@ export default {
'gangbang', 'gangbang',
'interracial', 'interracial',
'lesbian', 'lesbian',
'threesome',
'mff', 'mff',
'mfm', 'mfm',
'orgy', 'orgy',

View File

@ -57,7 +57,11 @@ function init() {
}, },
}); });
Vue.use(VTooltip); Vue.use(VTooltip, {
popover: {
defaultContainer: '.container',
},
});
Vue.use(VueLazyLoad, { Vue.use(VueLazyLoad, {
throttleWait: 0, throttleWait: 0,
}); });

View File

@ -857,6 +857,30 @@ exports.up = knex => Promise.resolve()
ORDER BY tags.name; ORDER BY tags.name;
$$ LANGUAGE SQL STABLE; $$ LANGUAGE SQL STABLE;
CREATE FUNCTION actors_scenes(actor actors, selected_tags text[]) RETURNS SETOF releases AS $$
SELECT releases.*
FROM releases
LEFT JOIN
releases_actors ON releases_actors.release_id = releases.id
LEFT JOIN
actors ON actors.id = releases_actors.actor_id
LEFT JOIN
releases_tags ON releases_tags.release_id = releases.id
LEFT JOIN
tags ON tags.id = releases_tags.tag_id
WHERE actors.id = actor.id
GROUP BY releases.id
HAVING CASE
WHEN array_length(selected_tags, 1) > 0
THEN COUNT(
CASE WHEN tags.slug = ANY(selected_tags)
THEN true
END
) = array_length(selected_tags, 1)
ELSE true
END;
$$ LANGUAGE SQL STABLE;
CREATE FUNCTION releases_is_new(release releases) RETURNS boolean AS $$ CREATE FUNCTION releases_is_new(release releases) RETURNS boolean AS $$
SELECT EXISTS(SELECT true WHERE (SELECT id FROM batches ORDER BY created_at DESC LIMIT 1) = release.created_batch_id); SELECT EXISTS(SELECT true WHERE (SELECT id FROM batches ORDER BY created_at DESC LIMIT 1) = release.created_batch_id);
$$ LANGUAGE sql STABLE; $$ LANGUAGE sql STABLE;
@ -883,6 +907,8 @@ exports.up = knex => Promise.resolve()
COMMENT ON COLUMN actors.height IS E'@omit read,update,create,delete,all,many'; COMMENT ON COLUMN actors.height IS E'@omit read,update,create,delete,all,many';
COMMENT ON COLUMN actors.weight IS E'@omit read,update,create,delete,all,many'; COMMENT ON COLUMN actors.weight IS E'@omit read,update,create,delete,all,many';
COMMENT ON FUNCTION actors_scenes IS E'@sortable';
`); `);
}); });
@ -943,6 +969,7 @@ exports.down = (knex) => { // eslint-disable-line arrow-body-style
DROP FUNCTION IF EXISTS releases_is_new; DROP FUNCTION IF EXISTS releases_is_new;
DROP FUNCTION IF EXISTS actors_tags; DROP FUNCTION IF EXISTS actors_tags;
DROP FUNCTION IF EXISTS actors_scenes;
DROP TEXT SEARCH CONFIGURATION IF EXISTS traxxx; DROP TEXT SEARCH CONFIGURATION IF EXISTS traxxx;
DROP TEXT SEARCH DICTIONARY IF EXISTS traxxx_dict; DROP TEXT SEARCH DICTIONARY IF EXISTS traxxx_dict;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 612 KiB

After

Width:  |  Height:  |  Size: 608 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 645 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 709 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 965 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 413 KiB

After

Width:  |  Height:  |  Size: 591 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 759 KiB

After

Width:  |  Height:  |  Size: 819 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 446 KiB

After

Width:  |  Height:  |  Size: 508 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 MiB

After

Width:  |  Height:  |  Size: 6.2 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.9 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 373 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

View File

@ -1537,6 +1537,10 @@ const aliases = [
name: 'red head', name: 'red head',
for: 'redhead', for: 'redhead',
}, },
{
name: 'ginger',
for: 'redhead',
},
{ {
name: 'redhead babes', name: 'redhead babes',
for: 'redhead', for: 'redhead',

View File

@ -598,14 +598,14 @@ const tagPosters = [
['blonde', 1, 'Marsha May in "Once You Go Black 7" for Jules Jordan'], ['blonde', 1, 'Marsha May in "Once You Go Black 7" for Jules Jordan'],
['blowbang', 0, 'Lacy Lennon in "Lacy Lennon\'s First Blowbang" for HardX'], ['blowbang', 0, 'Lacy Lennon in "Lacy Lennon\'s First Blowbang" for HardX'],
['blowjob', 0, 'Adriana Chechik in "The Dinner Party" for Real Wife Stories (Brazzers)'], ['blowjob', 0, 'Adriana Chechik in "The Dinner Party" for Real Wife Stories (Brazzers)'],
['brunette', 0, 'Liv Wild in "Dirty Talk 9" for Manuel Ferrara'], ['brunette', 0, 'Darcie Dolce for Playboy'],
['bukkake', 0, 'Jaye Summers in "Facialized 5" for HardX'], ['bukkake', 0, 'Jaye Summers in "Facialized 5" for HardX'],
['caucasian', 0, 'Remy Lacroix for HardX'], ['caucasian', 0, 'Remy Lacroix for HardX'],
['creampie', 'poster', 'ALina Lopez in "Making Yourself Unforgettable" for Blacked'], ['creampie', 'poster', 'ALina Lopez in "Making Yourself Unforgettable" for Blacked'],
['cum-in-mouth', 1, 'Sarah Vandella in "Blow Bang Vandella" for HardX'], ['cum-in-mouth', 1, 'Sarah Vandella in "Blow Bang Vandella" for HardX'],
['cum-on-butt', 0, 'Jynx Maze in "Don\'t Make Me Beg 4" for Evil Angel'], ['cum-on-butt', 0, 'Jynx Maze in "Don\'t Make Me Beg 4" for Evil Angel'],
['da-tp', 5, 'Venera Maxima in LegalPorno GIO1287'], ['da-tp', 5, 'Venera Maxima in LegalPorno GIO1287'],
['deepthroat', 1, 'Jynx Maze in "Slutty and Sluttier 13" for Evil Angel'], ['deepthroat', 2, 'Sarah Vandella for Throated'],
['dap', 7, 'Adriana Chechik in "DP Masters 6" for Jules Jordan'], ['dap', 7, 'Adriana Chechik in "DP Masters 6" for Jules Jordan'],
['double-blowjob', 1, 'Veronica Rodriguez and Penny Pax in "Fucking Older Guys 5" for Penthouse'], ['double-blowjob', 1, 'Veronica Rodriguez and Penny Pax in "Fucking Older Guys 5" for Penthouse'],
['double-dildo', 0, 'Kali Roses in "Double Dildo Party" for KaliRoses.com'], ['double-dildo', 0, 'Kali Roses in "Double Dildo Party" for KaliRoses.com'],
@ -616,7 +616,7 @@ const tagPosters = [
['ebony', 2, 'Nia Nacci for Sweetheart Video'], ['ebony', 2, 'Nia Nacci for Sweetheart Video'],
['facefucking', 2, 'Jynx Maze for Throated'], ['facefucking', 2, 'Jynx Maze for Throated'],
['facial', 0, 'Brooklyn Gray in "All About Ass 4" for Evil Angel'], ['facial', 0, 'Brooklyn Gray in "All About Ass 4" for Evil Angel'],
['fake-boobs', 4, 'Capri Cavanni for Big Tits in Sports'], ['fake-boobs', 2, 'Gia Milana in "Hot Anal Latina" for HardX'],
['family', 0, 'Teanna Trump in "A Family Appear: Part One" for Brazzers'], ['family', 0, 'Teanna Trump in "A Family Appear: Part One" for Brazzers'],
['femdom', 0, 'Alina Li in "Asian Domination… She Holds Jules Jordan\'s Cock Hostage!" for Jules Jordan'], ['femdom', 0, 'Alina Li in "Asian Domination… She Holds Jules Jordan\'s Cock Hostage!" for Jules Jordan'],
['gangbang', 5, 'Carter Cruise\'s first gangbang in "Slut Puppies 9" for Jules Jordan'], ['gangbang', 5, 'Carter Cruise\'s first gangbang in "Slut Puppies 9" for Jules Jordan'],
@ -643,7 +643,7 @@ const tagPosters = [
['schoolgirl', 1, 'Eliza Ibarra for Brazzers'], ['schoolgirl', 1, 'Eliza Ibarra for Brazzers'],
['swallowing', 'poster'], ['swallowing', 'poster'],
['teen', 0, 'Alexa Flexy for Sensual Girl'], ['teen', 0, 'Alexa Flexy for Sensual Girl'],
['tattoos', 0, 'Tigerlilly in "Wrapped In Blue" for Suicide Girls'], ['tattoos', 1, 'Joanna Angel for Joanna Angel'],
['trainbang', 'poster', 'Kali Roses in "Passing Me Around" for Blacked'], ['trainbang', 'poster', 'Kali Roses in "Passing Me Around" for Blacked'],
['tap', 'poster', 'Kristy Black in SZ1986 for LegalPorno'], ['tap', 'poster', 'Kristy Black in SZ1986 for LegalPorno'],
] ]
@ -689,6 +689,7 @@ const tagPhotos = [
['dap', 'poster', 'Haley Reed in "Young Hot Ass" for Evil Angel'], ['dap', 'poster', 'Haley Reed in "Young Hot Ass" for Evil Angel'],
['dap', 0, 'Nicole Black doing double anal during a gangbang in GIO971 for LegalPorno'], ['dap', 0, 'Nicole Black doing double anal during a gangbang in GIO971 for LegalPorno'],
['dap', 1, 'Ria Sunn in SZ1801 for LegalPorno'], ['dap', 1, 'Ria Sunn in SZ1801 for LegalPorno'],
['deepthroat', 1, 'Jynx Maze in "Slutty and Sluttier 13" for Evil Angel'],
['deepthroat', 0, 'Chanel Grey in "Deepthroating Is Fun" for Throated'], ['deepthroat', 0, 'Chanel Grey in "Deepthroating Is Fun" for Throated'],
['double-blowjob', 0, 'Kira Noir and Kali Roses for Brazzers'], ['double-blowjob', 0, 'Kira Noir and Kali Roses for Brazzers'],
['double-dildo-blowjob', 1, 'Aidra Fox and Reena Sky in "Reena\'s Got A Staring Problem" for Brazzers'], ['double-dildo-blowjob', 1, 'Aidra Fox and Reena Sky in "Reena\'s Got A Staring Problem" for Brazzers'],
@ -703,7 +704,7 @@ const tagPhotos = [
['facial', 'poster', 'Jynx Maze'], ['facial', 'poster', 'Jynx Maze'],
['facefucking', 3, 'Adriana Chechik in "Performing Magic Butt Tricks With Jules Jordan. What Will Disappear In Her Ass?" for Jules Jordan'], ['facefucking', 3, 'Adriana Chechik in "Performing Magic Butt Tricks With Jules Jordan. What Will Disappear In Her Ass?" for Jules Jordan'],
['facefucking', 1, 'Carrie for Young Throats'], ['facefucking', 1, 'Carrie for Young Throats'],
['fake-boobs', 2, 'Gia Milana in "Hot Anal Latina" for HardX'], ['fake-boobs', 4, 'Capri Cavanni for Big Tits in Sports'],
['fake-boobs', 1, 'Lela Star in "Thick" for Jules Jordan'], ['fake-boobs', 1, 'Lela Star in "Thick" for Jules Jordan'],
['fake-boobs', 3, 'Ashly Anderson for Passion HD'], ['fake-boobs', 3, 'Ashly Anderson for Passion HD'],
['gangbang', 'poster', 'Kristen Scott in "Interracial Gangbang!" for Jules Jordan'], ['gangbang', 'poster', 'Kristen Scott in "Interracial Gangbang!" for Jules Jordan'],
@ -717,16 +718,17 @@ const tagPhotos = [
['mff', 0, 'Madison Ivy, Adriana Chechik and Keiran Lee in "Day With A Pornstar" for Brazzers'], ['mff', 0, 'Madison Ivy, Adriana Chechik and Keiran Lee in "Day With A Pornstar" for Brazzers'],
['mfm', 6, 'Honey Gold in "Slut Puppies 12" for Jules Jordan'], ['mfm', 6, 'Honey Gold in "Slut Puppies 12" for Jules Jordan'],
['natural-boobs', 0, 'Autumn Falls in "Manuel Ferrara\'s Ripe 7" for Jules Jordan'], ['natural-boobs', 0, 'Autumn Falls in "Manuel Ferrara\'s Ripe 7" for Jules Jordan'],
['oil', 3, 'Vienna Black for Passion HD'],
['oil', 0, 'Jada Stevens in "Jada Stevens Anal Ass Oiled Up For James Deen\'s Cock" for Jules Jordan'],
['oil', 1, 'Kissa Sins in "Oil Overload 14" for JulesJordan'], ['oil', 1, 'Kissa Sins in "Oil Overload 14" for JulesJordan'],
['oil', 3, 'Vina Sky for Lubed'],
['oil', 0, 'Jada Stevens in "Jada Stevens Anal Ass Oiled Up For James Deen\'s Cock" for Jules Jordan'],
['orgy', 'poster', 'Zoey Mornoe (DP), Jillian Janson (sex), Frida Sante, Katerina Kay and Natasha Starr in "Orgy Masters 6" for Jules Jordan'], ['orgy', 'poster', 'Zoey Mornoe (DP), Jillian Janson (sex), Frida Sante, Katerina Kay and Natasha Starr in "Orgy Masters 6" for Jules Jordan'],
['pussy-eating', 0, 'Kali Roses licking Emily Willis\' pussy in "Peeping On My Neighbor" for Girl Girl'], ['pussy-eating', 0, 'Kali Roses licking Emily Willis\' pussy in "Peeping On My Neighbor" for Girl Girl'],
['redhead', 0, 'Penny Pax in "The Submission of Emma Marx: Boundaries" for New Sensations'], ['redhead', 0, 'Penny Pax in "The Submission of Emma Marx: Boundaries" for New Sensations'],
['tattoos', 0, 'Tigerlilly in "Wrapped In Blue" for Suicide Girls'],
['trainbang', 0, 'Nicole Black in GIO971 for LegalPorno'], ['trainbang', 0, 'Nicole Black in GIO971 for LegalPorno'],
['tap', 1, 'Natasha Teen in SZ2098 for LegalPorno'], ['tap', 1, 'Natasha Teen in SZ2098 for LegalPorno'],
['tap', 2, 'Kira Thorn in GIO1018 for LegalPorno'], ['tap', 2, 'Kira Thorn in GIO1018 for LegalPorno'],
['cum-in-mouth', 'poster', 'Khloe Kapri'], ['cum-in-mouth', 0, 'Vina Sky and Avi Love for HardX'],
] ]
.map(([slug, fileIndex, comment], index) => ({ .map(([slug, fileIndex, comment], index) => ({
id: nanoid(), id: nanoid(),