Applying tag filters to URL.

This commit is contained in:
ThePendulum 2020-05-27 01:40:10 +02:00
parent 86377fec5f
commit 88a88227c4
16 changed files with 210 additions and 96 deletions

View File

@ -288,8 +288,19 @@
:actor="actor"
/>
<FilterBar :fetch-releases="fetchActor" />
<Releases :releases="actor.releases" />
<FilterBar
:fetch-releases="fetchActor"
:items-total="totalCount"
:items-per-page="limit"
/>
<Releases :releases="releases" />
<Pagination
:items-total="totalCount"
:items-per-page="limit"
class="pagination-top"
/>
</div>
</div>
</div>
@ -297,16 +308,23 @@
<script>
import Photos from './photos.vue';
import Pagination from '../pagination/pagination.vue';
import FilterBar from '../header/filter-bar.vue';
import Releases from '../releases/releases.vue';
import Gender from './gender.vue';
import Social from './social.vue';
async function fetchActor() {
this.actor = await this.$store.dispatch('fetchActorById', {
const { actor, releases, totalCount } = await this.$store.dispatch('fetchActorById', {
actorId: Number(this.$route.params.actorId),
limit: 10,
pageNumber: Number(this.$route.params.pageNumber),
range: this.$route.params.range,
});
this.actor = actor;
this.releases = releases;
this.totalCount = totalCount;
}
function sfw() {
@ -328,6 +346,7 @@ async function mounted() {
export default {
components: {
FilterBar,
Pagination,
Photos,
Releases,
Gender,
@ -337,6 +356,8 @@ export default {
return {
actor: null,
releases: null,
totalCount: 0,
limit: 10,
pageTitle: null,
expanded: false,
};
@ -612,12 +633,9 @@ export default {
background: var(--background-dim);
}
.releases {
border-top: solid 1px var(--crease);
}
.releases {
flex-grow: 1;
border-top: solid 1px var(--crease);
padding: 1rem;
}

View File

@ -2,19 +2,19 @@
<div class="filter-bar noselect">
<span class="sort">
<router-link
:to="{ name: isHome ? 'latest' : $route.name, params: { ...$route.params, range: 'latest', pageNumber: 1 } }"
:to="{ params: { range: 'latest', pageNumber: 1 } }"
:class="{ active: $route.name === 'latest' || range === 'latest' }"
class="range range-button"
>Latest</router-link>
<router-link
:to="{ name: isHome ? 'upcoming' : $route.name, params: { ...$route.params, range: 'upcoming', pageNumber: 1 } }"
:to="{ params: { range: 'upcoming', pageNumber: 1 } }"
:class="{ active: $route.name === 'upcoming' || range === 'upcoming' }"
class="range-button"
>Upcoming</router-link>
<router-link
:to="{ name: isHome ? 'new' : $route.name, params: { ...$route.params, range: 'new', pageNumber: 1 } }"
:to="{ params: { range: 'new', pageNumber: 1 } }"
:class="{ active: $route.name === 'new' || range === 'new' }"
class="range-button"
>New</router-link>

View File

@ -8,19 +8,17 @@
v-for="tag in tags"
:key="`tag-${tag}`"
class="tag"
:class="{ selected: selectedTags.has(tag) }"
>
<Icon
icon="checkmark"
class="include"
/>
<Icon
icon="cross"
class="exclude"
/>
<router-link :to="{ params: { range: getNewRange(tag) } }">
<Icon
icon="checkmark"
class="include"
/>
</router-link>
<router-link
:to="{ name: 'tag', params: { tagSlug: tag } }"
:to="{ params: { range: tag } }"
class="name"
>{{ tag }}</router-link>
</li>
@ -31,11 +29,32 @@
<script>
const tags = [
'airtight',
'anal',
'blowjob',
'double-penetration',
'facial',
'gangbang',
'lesbian',
'mff',
'mfm',
'orgy',
];
function getNewRange(tag) {
const selected = new Set(this.selectedTags).add(tag);
if (this.selectedTags.has(tag)) {
selected.delete(tag);
}
return Array.from(selected).join('+');
}
function selectedTags() {
return new Set(this.$route.params.range.split('+'));
}
export default {
props: {
filter: {
@ -49,10 +68,15 @@ export default {
},
data() {
return {
localFilter: this.filter,
tags,
};
},
computed: {
selectedTags,
},
methods: {
getNewRange,
},
};
</script>
@ -82,7 +106,7 @@ export default {
width: 1rem;
height: 1rem;
padding: .5rem;
fill: var(--darken-weak);
fill: var(--darken-hint);
&:hover {
cursor: pointer;
@ -90,15 +114,10 @@ export default {
}
.include:hover,
.include.active {
&.selected .include {
fill: var(--success);
}
.exclude:hover,
.exclude.active {
fill: var(--alert);
}
.name {
flex-grow: 1;
padding: .5rem;

View File

@ -28,8 +28,8 @@ import Pagination from '../pagination/pagination.vue';
async function fetchReleases() {
const { releases, totalCount } = await this.$store.dispatch('fetchReleases', {
limit: this.limit,
range: this.$route.params.range,
pageNumber: Number(this.$route.params.pageNumber) || 1,
range: this.$route.name,
});
this.totalCount = totalCount;

View File

@ -212,10 +212,12 @@ export default {
.content-inner {
padding: 0;
overflow-y: auto;
}
.releases {
padding: 1rem 1rem 1rem .5rem;
border-top: solid 1px var(--crease);
}
.sidebar {

View File

@ -41,7 +41,11 @@
</router-link>
</div>
<FilterBar :fetch-releases="fetchSite" />
<FilterBar
:fetch-releases="fetchSite"
:items-total="totalCount"
:items-per-page="limit"
/>
<div class="content-inner">
<Releases :releases="releases" />
@ -54,12 +58,16 @@ import FilterBar from '../header/filter-bar.vue';
import Releases from '../releases/releases.vue';
async function fetchSite() {
this.site = await this.$store.dispatch('fetchSiteBySlug', {
const { site, releases, totalCount } = await this.$store.dispatch('fetchSiteBySlug', {
siteSlug: this.$route.params.siteSlug,
range: this.$route.params.range,
pageNumber: Number(this.$route.params.pageNumber) || 1,
limit: this.limit,
});
this.releases = this.site.releases;
this.site = site;
this.releases = releases;
this.totalCount = totalCount;
}
async function route() {
@ -81,6 +89,8 @@ export default {
return {
site: null,
releases: null,
totalCount: 0,
limit: 10,
pageTitle: null,
};
},

View File

@ -1,5 +1,6 @@
import { graphql, get } from '../api';
import {
releaseFields,
releasePosterFragment,
releaseActorsFragment,
releaseTagsFragment,
@ -8,13 +9,19 @@ import { curateActor, curateRelease } from '../curate';
import getDateRange from '../get-date-range';
function initActorActions(store, _router) {
async function fetchActorById({ _commit }, { actorId, limit = 100, range = 'latest' }) {
async function fetchActorById({ _commit }, {
actorId,
limit = 10,
pageNumber = 1,
range = 'latest',
}) {
const { before, after, orderBy } = getDateRange(range);
const { actor } = await graphql(`
const { actor, connection: { releases, totalCount } } = await graphql(`
query Actor(
$actorId: Int!
$limit:Int = 1000,
$limit:Int = 10,
$offset:Int = 0,
$after:Date = "1900-01-01",
$before:Date = "2100-01-01",
$orderBy:[ReleasesActorsOrderBy!]
@ -123,7 +130,7 @@ function initActorActions(store, _router) {
name
slug
}
releases: releasesActors(
releasesConnection: releasesActorsConnection(
filter: {
release: {
date: {
@ -140,45 +147,80 @@ function initActorActions(store, _router) {
}
}
}
},
first: $limit,
}
first: $limit
offset: $offset
orderBy: $orderBy
) {
release {
id
url
title
date
slug
${releaseActorsFragment}
${releaseTagsFragment}
${releasePosterFragment}
site {
id
name
slug
url
network {
id
name
slug
url
}
}
}
releases: nodes {
release {
id
url
title
date
slug
${releaseActorsFragment}
${releaseTagsFragment}
${releasePosterFragment}
site {
id
name
slug
url
network {
id
name
slug
url
}
}
}
}
}
}
connection: releasesActorsConnection(
first: $limit
offset: $offset
orderBy: $orderBy
filter: {
actorId: {
equalTo: $actorId
}
or: [
{
release: {
date: {
lessThan: $before,
greaterThan: $after
}
}
},
]
}
) {
releases: nodes {
release {
${releaseFields}
}
}
totalCount
}
}
`, {
actorId,
limit,
offset: Math.max(0, (pageNumber - 1)) * limit,
after,
before,
orderBy: orderBy === 'DATE_DESC' ? 'RELEASE_BY_RELEASE_ID__DATE_DESC' : 'RELEASE_BY_RELEASE_ID__DATE_ASC',
exclude: store.state.ui.filter,
});
return curateActor(actor, null, curateRelease);
return {
actor: curateActor(actor, null, curateRelease),
releases: releases.map(release => curateRelease(release.release)),
totalCount,
};
}
async function fetchActors({ _commit }, {

View File

@ -1,6 +1,6 @@
import dayjs from 'dayjs';
function curateActor(actor, release, curateActorRelease) {
function curateActor(actor, release) {
if (!actor) {
return null;
}
@ -53,10 +53,6 @@ function curateActor(actor, release, curateActorRelease) {
curatedActor.ageThen = dayjs(release.date).diff(actor.birthdate, 'year');
}
if (actor.releases) {
curatedActor.releases = actor.releases.map(actorRelease => curateActorRelease(actorRelease.release));
}
if (actor.aliasFor) {
curatedActor.aliasFor = curateActor(curatedActor.aliasFor);
}

View File

@ -24,7 +24,7 @@ const dateRanges = {
};
function getDateRange(range) {
return dateRanges[range]();
return (dateRanges[range] || dateRanges.all)();
}
export default getDateRange;

View File

@ -19,35 +19,17 @@ const routes = [
{
path: '/',
redirect: {
name: 'latest',
name: 'home',
params: {
range: 'latest',
pageNumber: 1,
},
},
},
{
path: '/home',
redirect: {
name: 'latest',
params: {
pageNumber: 1,
},
},
},
{
path: '/latest/:pageNumber?',
path: '/:range/:pageNumber?',
component: Home,
name: 'latest',
},
{
path: '/upcoming/:pageNumber?',
component: Home,
name: 'upcoming',
},
{
path: '/new/:pageNumber?',
component: Home,
name: 'new',
name: 'home',
},
{
path: '/scene/:releaseId/:releaseSlug?',
@ -67,11 +49,12 @@ const routes = [
params: {
...from.params,
range: 'latest',
pageNumber: 1,
},
}),
},
{
path: '/actor/:actorId/:actorSlug?/:range',
path: '/actor/:actorId/:actorSlug/:range/:pageNumber?',
component: Actor,
name: 'actorRange',
},
@ -84,11 +67,12 @@ const routes = [
params: {
...from.params,
range: 'latest',
pageNumber: 1,
},
}),
},
{
path: '/site/:siteSlug/:range',
path: '/site/:siteSlug/:range/:pageNumber?',
component: Site,
name: 'siteRange',
},

View File

@ -1,6 +1,6 @@
import { graphql } from '../api';
import { releaseFields } from '../fragments';
import { curateSite } from '../curate';
import { curateSite, curateRelease } from '../curate';
import getDateRange from '../get-date-range';
function initSitesActions(store, _router) {
@ -12,7 +12,7 @@ function initSitesActions(store, _router) {
}) {
const { before, after, orderBy } = getDateRange(range);
const { site } = await graphql(`
const { site, connection: { releases, totalCount } } = await graphql(`
query Site(
$siteSlug: String!,
$limit:Int = 100,
@ -39,7 +39,7 @@ function initSitesActions(store, _router) {
slug
url
}
releases(
releasesConnection(
filter: {
date: {
lessThan: $before,
@ -59,9 +59,42 @@ function initSitesActions(store, _router) {
offset: $offset
orderBy: $orderBy
) {
${releaseFields}
releases: nodes {
${releaseFields}
}
totalCount
}
}
connection: releasesConnection(
first: $limit
offset: $offset
orderBy: $orderBy
filter: {
site: {
slug: {
equalTo: $siteSlug
}
}
date: {
lessThan: $before,
greaterThan: $after
}
releasesTagsConnection: {
none: {
tag: {
slug: {
in: $exclude
}
}
}
}
}
) {
releases: nodes {
${releaseFields}
}
totalCount
}
}
`, {
siteSlug,
@ -74,7 +107,11 @@ function initSitesActions(store, _router) {
exclude: store.state.ui.filter,
});
return curateSite(site);
return {
site: curateSite(site),
releases: releases.map(release => curateRelease(release)),
totalCount,
};
}
async function fetchSites({ _commit }, { limit = 100 }) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 26 KiB

BIN
public/img/tags/atm/5.jpeg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@ -5,29 +5,35 @@ const substitutes = {
á: 'a',
ä: 'a',
å: 'a',
ã: 'a',
æ: 'ae',
ç: 'c',
è: 'e',
é: 'e',
ë: 'e',
: 'e',
ì: 'i',
í: 'i',
ï: 'i',
ĩ: 'i',
ǹ: 'n',
ń: 'n',
ñ: 'n',
ò: 'o',
ó: 'o',
ö: 'o',
õ: 'o',
ø: 'o',
œ: 'oe',
ß: 'ss',
ù: 'u',
ú: 'u',
ü: 'u',
ũ: 'u',
: 'y',
ý: 'y',
ÿ: 'y',
: 'y',
};
function slugify(string, delimiter = '-', {