Compare commits
219 Commits
8322d43b09
...
33a327a04b
Author | SHA1 | Date |
---|---|---|
|
33a327a04b | |
|
a46061e247 | |
|
94e07ff23d | |
|
4811befcf6 | |
|
c455f02c66 | |
|
efc5620a28 | |
|
61123fdb6a | |
|
3ec6911d46 | |
|
2021093645 | |
|
1c72dc202f | |
|
1ef946fa77 | |
|
3b6bbc39ff | |
|
481c9feada | |
|
953b3e9568 | |
|
bdd2e68f49 | |
|
e4cc349302 | |
|
6547b93e55 | |
|
bb9649d23b | |
|
9e2eaef9d1 | |
|
1c3ee75d3b | |
|
15c9af8057 | |
|
295573c1ef | |
|
e93e8ace5c | |
|
43af7ba777 | |
|
0dad5b0d68 | |
|
ae9b793318 | |
|
fd8170f223 | |
|
661b8b716b | |
|
5ff076cac3 | |
|
41c100ac4e | |
|
c6e977f842 | |
|
50b7f521b5 | |
|
f0d0ee3acc | |
|
7b3bdadd44 | |
|
5deba6b90f | |
|
a5afffc968 | |
|
a239a5c593 | |
|
e56e7333e3 | |
|
d55e3c37cd | |
|
97b78ea016 | |
|
3e290b74dc | |
|
65141207ae | |
|
17dfeac1af | |
|
4a9c428d69 | |
|
333f252099 | |
|
38232f258a | |
|
582269cfaa | |
|
0b646429fd | |
|
fecef6c1cf | |
|
73e5404c44 | |
|
690d2bb3ed | |
|
1dd935e1e9 | |
|
8386230f33 | |
|
5a68b06137 | |
|
5918364cf5 | |
|
df4d860d35 | |
|
d9f0db6e3c | |
|
7372b560b2 | |
|
9d638c685c | |
|
5da1acc38d | |
|
c7c62e220d | |
|
9edd652a2c | |
|
cde760c1ea | |
|
19c7f958e1 | |
|
c7710afdbf | |
|
ba18a3dadb | |
|
496c29e569 | |
|
98a72a4929 | |
|
c4f0b48932 | |
|
93abbab873 | |
|
f7bbab08bd | |
|
1e4ddf2bbf | |
|
9b7879bff7 | |
|
03d96d4dec | |
|
1dfa034332 | |
|
196a1d33e3 | |
|
3d349c413f | |
|
bd5babd37e | |
|
fffe9080f3 | |
|
5630b16e99 | |
|
4bcf7ef45b | |
|
9abc1d48ac | |
|
ceaf5a3217 | |
|
36d84fb98b | |
|
3d80e9d77b | |
|
1dc38ffacc | |
|
ee210b5c68 | |
|
3aae3cd3a1 | |
|
f1a7f2f905 | |
|
0b7e0319f1 | |
|
10b8abf706 | |
|
b163223ff1 | |
|
b9f3eb85f9 | |
|
285a65f018 | |
|
815d56d334 | |
|
27a9a233e2 | |
|
22864105ac | |
|
7cf47cbf8d | |
|
502c588958 | |
|
81792a7c2f | |
|
784d326584 | |
|
83dc7aa578 | |
|
5a3b27fbf7 | |
|
5ff83a9497 | |
|
07cb39c756 | |
|
fffd54995d | |
|
5302176f0b | |
|
efd7cf8acc | |
|
52218c30f8 | |
|
04c176fa8b | |
|
af320684b4 | |
|
b2ba14ce45 | |
|
d776cc2f71 | |
|
b4bed2f623 | |
|
5c5a11fdca | |
|
a22c62d893 | |
|
90bc2f3724 | |
|
8cdc794a3a | |
|
250618df8b | |
|
b62ae00c54 | |
|
67d0a9e0e0 | |
|
b4425bc3bb | |
|
d77c145de3 | |
|
6753f923d9 | |
|
452f725332 | |
|
7c1f45bcfb | |
|
11ea54f6e8 | |
|
5b623ee46f | |
|
7ceec1c739 | |
|
fc318536aa | |
|
cd8f690ac6 | |
|
240a8e86fd | |
|
c557f0f1f0 | |
|
86f56695e2 | |
|
20da2d1cf6 | |
|
372db86927 | |
|
4c503a3177 | |
|
57d46f5842 | |
|
7f11d0ca91 | |
|
bbd788699e | |
|
e24add98ea | |
|
506971b44b | |
|
43a0bc8a2c | |
|
baebdbc0bb | |
|
1c24cae3b1 | |
|
b9146aee5f | |
|
09bfcb01f5 | |
|
5d80b6dc21 | |
|
140a38c349 | |
|
6760c11881 | |
|
2dcdbf9c37 | |
|
3b958a02ef | |
|
605242b399 | |
|
299f257a01 | |
|
0ad64ef5f4 | |
|
3bfe1e8fdb | |
|
7d992f4129 | |
|
280032937f | |
|
d93670842b | |
|
dc187a9a3a | |
|
5f89c6e14c | |
|
9f10420eb9 | |
|
9568370132 | |
|
1c0c30be11 | |
|
cdb7dcd6e9 | |
|
8e4be06675 | |
|
de7a8c756a | |
|
65e2b72c6a | |
|
523c36ecd4 | |
|
5b5688438c | |
|
4ca07631c7 | |
|
ec4e7bc12a | |
|
26d15c0a6f | |
|
a484396db4 | |
|
681db02784 | |
|
e88554666c | |
|
9f37ec4cff | |
|
abd063a578 | |
|
883e57ce1f | |
|
ad04502a8c | |
|
f65ed16842 | |
|
1918dd4ad5 | |
|
3983d3464f | |
|
61daf5f037 | |
|
eafa144104 | |
|
60c151ff6a | |
|
c97d18fcf9 | |
|
e41f9fa937 | |
|
56a7fb0ad9 | |
|
e29cbc9fea | |
|
08f725a0b6 | |
|
b93a5715cb | |
|
2018d5c298 | |
|
87094a9498 | |
|
53a1c697d0 | |
|
f04eb72891 | |
|
dfeb0c08cf | |
|
9d7183ac69 | |
|
2539e88f47 | |
|
20d0d860d3 | |
|
6b4aa64d74 | |
|
c7b9ec7a4b | |
|
e81864ebde | |
|
0305a22a24 | |
|
a406eb584d | |
|
2be3ea9bbb | |
|
0a8a7ff9a5 | |
|
98c103c625 | |
|
e0908a5f5e | |
|
f0b7678444 | |
|
64e9efe095 | |
|
ab29ab053e | |
|
a5081bc7c9 | |
|
da9c628f9b | |
|
26539b74a5 | |
|
ccb99e278c | |
|
a867817dc1 | |
|
d1e05915b5 | |
|
b764fdec85 |
|
@ -2,7 +2,7 @@
|
||||||
"root": true,
|
"root": true,
|
||||||
"extends": ["airbnb-base", "plugin:vue/recommended"],
|
"extends": ["airbnb-base", "plugin:vue/recommended"],
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"parser": "babel-eslint",
|
"parser": "@babel/eslint-parser",
|
||||||
"ecmaVersion": 2019,
|
"ecmaVersion": 2019,
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
|
@ -17,10 +17,11 @@
|
||||||
"vue/html-indent": ["error", "tab"],
|
"vue/html-indent": ["error", "tab"],
|
||||||
"vue/multiline-html-element-content-newline": 0,
|
"vue/multiline-html-element-content-newline": 0,
|
||||||
"vue/singleline-html-element-content-newline": 0,
|
"vue/singleline-html-element-content-newline": 0,
|
||||||
|
"vue/multi-word-component-names": 0,
|
||||||
"no-param-reassign": ["error", {
|
"no-param-reassign": ["error", {
|
||||||
"props": true,
|
"props": true,
|
||||||
"ignorePropertyModificationsFor": ["state", "acc"]
|
"ignorePropertyModificationsFor": ["state", "acc"]
|
||||||
}],
|
}]
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"CONFIG": true
|
"CONFIG": true
|
||||||
|
|
|
@ -2,6 +2,7 @@ node_modules/
|
||||||
dist/
|
dist/
|
||||||
log/
|
log/
|
||||||
media/
|
media/
|
||||||
|
html/
|
||||||
public/js/*
|
public/js/*
|
||||||
public/css/*
|
public/css/*
|
||||||
config/*
|
config/*
|
||||||
|
@ -9,3 +10,4 @@ config/*
|
||||||
assets/js/config/
|
assets/js/config/
|
||||||
!assets/js/config/default.js
|
!assets/js/config/default.js
|
||||||
*.heapprofile
|
*.heapprofile
|
||||||
|
*.heapsnapshot
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<div class="actor-header">
|
<div class="actor-header">
|
||||||
<h2 class="header-name">
|
<h2 class="header-name">
|
||||||
<span v-if="actor.entity">{{ actor.name }} ({{ actor.entity.name }})</span>
|
<span v-if="actor.entity">{{ actor.name }} ({{ actor.entity.name }})</span>
|
||||||
<span v-else="">{{ actor.name }}</span>
|
<span v-else>{{ actor.name }}</span>
|
||||||
|
|
||||||
<Gender
|
<Gender
|
||||||
:gender="actor.gender"
|
:gender="actor.gender"
|
||||||
|
|
|
@ -272,7 +272,7 @@ import Pagination from '../pagination/pagination.vue';
|
||||||
|
|
||||||
const toggleValues = [true, null, false];
|
const toggleValues = [true, null, false];
|
||||||
const boobSizes = 'ABCDEFGHIJKZ'.split('');
|
const boobSizes = 'ABCDEFGHIJKZ'.split('');
|
||||||
const topCountries = ['AU', 'BR', 'DE', 'JP', 'RU', 'GB', 'US'];
|
const topCountries = ['AU', 'BR', 'CZ', 'DE', 'JP', 'RU', 'GB', 'US'];
|
||||||
|
|
||||||
function updateFilters() {
|
function updateFilters() {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
|
|
|
@ -214,7 +214,7 @@ export default {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
box-shadow: 0 0 3px var(--darken-weak);
|
box-shadow: 0 0 3px var(--darken-weak);
|
||||||
background: var(--background);
|
background: var(--info);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
|
@ -237,12 +237,8 @@ export default {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
color: var(--text);
|
color: var(--text-light);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: var(--primary);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.handle {
|
.handle {
|
||||||
|
@ -253,7 +249,8 @@ export default {
|
||||||
box-shadow: 0 0 3px var(--shadow);
|
box-shadow: 0 0 3px var(--shadow);
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
padding: .5rem;
|
padding: .25rem .5rem;
|
||||||
|
font-size: .9rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.alias {
|
.alias {
|
||||||
|
@ -316,8 +313,8 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash {
|
.stash {
|
||||||
width: 1.25rem;
|
width: 1.5rem;
|
||||||
height: 1.25rem;
|
height: 1.5rem;
|
||||||
padding: .25rem .25rem .5rem .5rem;
|
padding: .25rem .25rem .5rem .5rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<template v-slot:tooltip>
|
<template #tooltip>
|
||||||
<Search
|
<Search
|
||||||
content="actors"
|
content="actors"
|
||||||
@select="actor => addActor(actor)"
|
@select="actor => addActor(actor)"
|
||||||
|
@ -88,7 +88,7 @@
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<template v-slot:tooltip>
|
<template #tooltip>
|
||||||
<Search
|
<Search
|
||||||
content="tags"
|
content="tags"
|
||||||
:defaults="['anal', 'blowbang', 'mfm', 'dp', 'gangbang', 'airtight']"
|
:defaults="['anal', 'blowbang', 'mfm', 'dp', 'gangbang', 'airtight']"
|
||||||
|
@ -126,7 +126,7 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-slot:tooltip>
|
<template #tooltip>
|
||||||
<Search
|
<Search
|
||||||
label="Search channels"
|
label="Search channels"
|
||||||
content="entities"
|
content="entities"
|
||||||
|
@ -181,7 +181,7 @@
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<template v-slot:tooltip>
|
<template #tooltip>
|
||||||
<Search
|
<Search
|
||||||
content="stashes"
|
content="stashes"
|
||||||
@select="stash => addStash(stash)"
|
@select="stash => addStash(stash)"
|
||||||
|
@ -194,6 +194,7 @@
|
||||||
|
|
||||||
<div class="dialog-actions right">
|
<div class="dialog-actions right">
|
||||||
<button
|
<button
|
||||||
|
:disabled="actors.length === 0 && tags.length === 0 && !entity"
|
||||||
type="submit"
|
type="submit"
|
||||||
class="button button-primary"
|
class="button button-primary"
|
||||||
>Add alert</button>
|
>Add alert</button>
|
||||||
|
@ -210,19 +211,19 @@ import Search from './search.vue';
|
||||||
|
|
||||||
async function addAlert() {
|
async function addAlert() {
|
||||||
await this.$store.dispatch('addAlert', {
|
await this.$store.dispatch('addAlert', {
|
||||||
actors: this.actors.map(actor => actor.id),
|
actors: this.actors.map((actor) => actor.id),
|
||||||
tags: this.tags.map(tag => tag.id),
|
tags: this.tags.map((tag) => tag.id),
|
||||||
entity: this.entity?.id,
|
entity: this.entity?.id,
|
||||||
notify: this.notify,
|
notify: this.notify,
|
||||||
email: this.email,
|
email: this.email,
|
||||||
stashes: this.stashes.map(stash => stash.id),
|
stashes: this.stashes.map((stash) => stash.id),
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$emit('close', true);
|
this.$emit('close', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addActor(actor) {
|
function addActor(actor) {
|
||||||
if (!this.actors.some(selectedActor => selectedActor.id === actor.id)) {
|
if (!this.actors.some((selectedActor) => selectedActor.id === actor.id)) {
|
||||||
this.actors = this.actors.concat(actor);
|
this.actors = this.actors.concat(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +236,7 @@ function addEntity(entity) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTag(tag) {
|
function addTag(tag) {
|
||||||
if (!this.tags.some(selectedTag => selectedTag.id === tag.id)) {
|
if (!this.tags.some((selectedTag) => selectedTag.id === tag.id)) {
|
||||||
this.tags = this.tags.concat(tag);
|
this.tags = this.tags.concat(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +244,7 @@ function addTag(tag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeActor(actor) {
|
function removeActor(actor) {
|
||||||
this.actors = this.actors.filter(listedActor => listedActor.id !== actor.id);
|
this.actors = this.actors.filter((listedActor) => listedActor.id !== actor.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeEntity() {
|
function removeEntity() {
|
||||||
|
@ -251,11 +252,11 @@ function removeEntity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeTag(tag) {
|
function removeTag(tag) {
|
||||||
this.tags = this.tags.filter(listedTag => listedTag.id !== tag.id);
|
this.tags = this.tags.filter((listedTag) => listedTag.id !== tag.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addStash(stash) {
|
function addStash(stash) {
|
||||||
if (!this.stashes.some(selectedStash => selectedStash.id === stash.id)) {
|
if (!this.stashes.some((selectedStash) => selectedStash.id === stash.id)) {
|
||||||
this.stashes = this.stashes.concat(stash);
|
this.stashes = this.stashes.concat(stash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,7 +264,7 @@ function addStash(stash) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeStash(stash) {
|
function removeStash(stash) {
|
||||||
this.stashes = this.stashes.filter(listedStash => listedStash.id !== stash.id);
|
this.stashes = this.stashes.filter((listedStash) => listedStash.id !== stash.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -273,6 +274,7 @@ export default {
|
||||||
Entity,
|
Entity,
|
||||||
Search,
|
Search,
|
||||||
},
|
},
|
||||||
|
emits: ['close'],
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
actors: [],
|
actors: [],
|
||||||
|
@ -284,7 +286,6 @@ export default {
|
||||||
availableStashes: this.$store.state.auth.user.stashes,
|
availableStashes: this.$store.state.auth.user.stashes,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
emits: ['close'],
|
|
||||||
methods: {
|
methods: {
|
||||||
addActor,
|
addActor,
|
||||||
addAlert,
|
addAlert,
|
||||||
|
|
|
@ -62,7 +62,7 @@ async function setConsent(consent, includeQueer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (includeQueer) {
|
if (includeQueer) {
|
||||||
this.$store.dispatch('setTagFilter', this.$store.state.ui.tagFilter.filter(tag => !['gay', 'bisexual', 'transsexual'].includes(tag)));
|
this.$store.dispatch('setTagFilter', this.$store.state.ui.tagFilter.filter((tag) => !['gay', 'bisexual', 'transsexual'].includes(tag)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
>{{ tag.name }}</li>
|
>{{ tag.name }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<router-link
|
<RouterLink
|
||||||
v-if="entity.parent"
|
v-if="entity.parent"
|
||||||
:to="`/${entity.parent.type}/${entity.parent.slug}`"
|
:to="`/${entity.parent.type}/${entity.parent.slug}`"
|
||||||
class="link link-parent"
|
class="link link-parent"
|
||||||
|
@ -74,7 +74,7 @@
|
||||||
>{{ entity.parent.name }}</h3>
|
>{{ entity.parent.name }}</h3>
|
||||||
|
|
||||||
<Icon icon="device_hub" />
|
<Icon icon="device_hub" />
|
||||||
</router-link>
|
</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -108,6 +108,7 @@
|
||||||
:fetch-releases="fetchEntity"
|
:fetch-releases="fetchEntity"
|
||||||
:items-total="totalCount"
|
:items-total="totalCount"
|
||||||
:items-per-page="limit"
|
:items-per-page="limit"
|
||||||
|
:available-tags="entity.tags"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div class="releases">
|
<div class="releases">
|
||||||
|
@ -153,8 +154,8 @@ async function fetchEntity(scroll = true) {
|
||||||
|
|
||||||
this.pageTitle = entity.name;
|
this.pageTitle = entity.name;
|
||||||
|
|
||||||
const campaign = entity.campaigns.find(campaignX => !campaignX.banner)
|
const campaign = entity.campaigns.find((campaignX) => !campaignX.banner)
|
||||||
|| entity.parent?.campaigns.find(campaignX => !campaignX.banner);
|
|| entity.parent?.campaigns.find((campaignX) => !campaignX.banner);
|
||||||
|
|
||||||
const affiliateParams = new URLSearchParams({
|
const affiliateParams = new URLSearchParams({
|
||||||
...(entity.url && Object.fromEntries(new URL(entity.url).searchParams)), // preserve any query in entity URL, e.g. ?siteId=5
|
...(entity.url && Object.fromEntries(new URL(entity.url).searchParams)), // preserve any query in entity URL, e.g. ?siteId=5
|
||||||
|
|
|
@ -4,39 +4,49 @@
|
||||||
:title="entity.name"
|
:title="entity.name"
|
||||||
class="tile"
|
class="tile"
|
||||||
>
|
>
|
||||||
<template v-if="entity.hasLogo">
|
<div class="tile-logo">
|
||||||
<img
|
<template v-if="entity.hasLogo">
|
||||||
v-if="entity.type === 'network' || entity.independent"
|
<img
|
||||||
:src="`/img/logos/${entity.slug}/thumbs/network.png`"
|
v-if="entity.type === 'network' || entity.independent"
|
||||||
:alt="entity.name"
|
:src="`/img/logos/${entity.slug}/thumbs/network.png`"
|
||||||
loading="lazy"
|
:alt="entity.name"
|
||||||
class="logo"
|
loading="lazy"
|
||||||
@load="$emit('load', $event)"
|
class="logo"
|
||||||
>
|
@load="$emit('load', $event)"
|
||||||
|
>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
v-else-if="entity.parent"
|
v-else-if="entity.parent"
|
||||||
:src="`/img/logos/${entity.parent.slug}/thumbs/${entity.slug}.png`"
|
:src="`/img/logos/${entity.parent.slug}/thumbs/${entity.slug}.png`"
|
||||||
:alt="entity.name"
|
:alt="entity.name"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="logo"
|
class="logo"
|
||||||
@load="$emit('load', $event)"
|
@load="$emit('load', $event)"
|
||||||
>
|
>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
|
v-else
|
||||||
|
:src="`/img/logos/${entity.slug}/thumbs/${entity.slug}.png`"
|
||||||
|
:alt="entity.name"
|
||||||
|
loading="lazy"
|
||||||
|
class="logo"
|
||||||
|
@load="$emit('load', $event)"
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<span
|
||||||
v-else
|
v-else
|
||||||
:src="`/img/logos/${entity.slug}/thumbs/${entity.slug}.png`"
|
class="name"
|
||||||
:alt="entity.name"
|
>{{ entity.name }}</span>
|
||||||
loading="lazy"
|
</div>
|
||||||
class="logo"
|
|
||||||
@load="$emit('load', $event)"
|
|
||||||
>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<span
|
<span
|
||||||
v-else
|
v-if="entity.childrenTotal > 0 || typeof entity.sceneTotal !== 'undefined'"
|
||||||
class="name"
|
class="count"
|
||||||
>{{ entity.name }}</span>
|
>
|
||||||
|
<span v-if="typeof entity.sceneTotal !== 'undefined'">{{ entity.sceneTotal }} scenes</span>
|
||||||
|
<span v-if="entity.type === 'network'">{{ entity.childrenTotal }} channels</span>
|
||||||
|
</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -59,15 +69,28 @@ export default {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background: var(--tile);
|
background: var(--tile);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: .5rem 1rem;
|
|
||||||
border-radius: .25rem;
|
border-radius: .25rem;
|
||||||
|
position: relative;
|
||||||
box-shadow: 0 0 3px rgba(0, 0, 0, .25);
|
box-shadow: 0 0 3px rgba(0, 0, 0, .25);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&:hover .count {
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tile-logo {
|
||||||
|
display: flex;
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: .5rem 1rem;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
|
@ -75,11 +98,30 @@ export default {
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
align-self: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
color: var(--text-light);
|
color: var(--text-light);
|
||||||
font-size: 1.25rem;
|
font-size: 1.25rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.count {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
bottom: -1.75rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: .25rem .5rem;
|
||||||
|
background: var(--darken-strong);
|
||||||
|
box-shadow: 0 0 3px var(--darken);
|
||||||
|
color: var(--text-light);
|
||||||
|
text-align: center;
|
||||||
|
text-shadow: 1px 1px var(--darken);
|
||||||
|
transition: bottom .1s ease;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,31 +1,33 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="filter-bar noselect">
|
<div class="filter-bar noselect">
|
||||||
<div class="sort">
|
<div class="sort">
|
||||||
<router-link
|
<RouterLink
|
||||||
v-for="section in ranges"
|
v-for="section in ranges"
|
||||||
:key="section"
|
:key="section"
|
||||||
:to="{ params: { range: section, pageNumber: 1 }, query: $route.query }"
|
:to="{ params: { range: section, pageNumber: 1 }, query: $route.query }"
|
||||||
:class="{ active: $route.name === section || range === section }"
|
:class="{ active: $route.name === section || range === section }"
|
||||||
class="range range-button"
|
class="range range-button"
|
||||||
>{{ section }}</router-link>
|
>{{ section }}</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<span
|
||||||
|
v-if="itemsTotal && showTotal"
|
||||||
|
class="total"
|
||||||
|
>{{ itemsTotal }} <template v-if="itemsTotal === 1">scene</template><template v-else>scenes</template></span>
|
||||||
|
|
||||||
<div class="filters">
|
<div class="filters">
|
||||||
<ActorFilter
|
<ActorFilter
|
||||||
class="filters-filter"
|
class="filters-filter"
|
||||||
:filter="filter"
|
|
||||||
:available-actors="availableActors"
|
:available-actors="availableActors"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<ChannelFilter
|
<ChannelFilter
|
||||||
class="filters-filter"
|
class="filters-filter"
|
||||||
:filter="filter"
|
|
||||||
:available-channels="availableChannels"
|
:available-channels="availableChannels"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<TagFilter
|
<TagFilter
|
||||||
class="filters-filter"
|
class="filters-filter"
|
||||||
:filter="filter"
|
|
||||||
:available-tags="availableTags"
|
:available-tags="availableTags"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -39,10 +41,6 @@ import ActorFilter from './actor-filter.vue';
|
||||||
import ChannelFilter from './channel-filter.vue';
|
import ChannelFilter from './channel-filter.vue';
|
||||||
import TagFilter from './tag-filter.vue';
|
import TagFilter from './tag-filter.vue';
|
||||||
|
|
||||||
function filter(state) {
|
|
||||||
return state.ui.filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
function range() {
|
function range() {
|
||||||
return this.$route.params.range;
|
return this.$route.params.range;
|
||||||
}
|
}
|
||||||
|
@ -78,6 +76,10 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
showTotal: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
itemsTotal: {
|
itemsTotal: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 0,
|
default: 0,
|
||||||
|
@ -105,7 +107,6 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState({
|
...mapState({
|
||||||
filter,
|
|
||||||
range,
|
range,
|
||||||
batch,
|
batch,
|
||||||
}),
|
}),
|
||||||
|
@ -120,6 +121,43 @@ export default {
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'breakpoints';
|
@import 'breakpoints';
|
||||||
|
|
||||||
|
.filter {
|
||||||
|
color: var(--shadow);
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.filter-applied {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: .75rem .5rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
&.empty {
|
||||||
|
color: var(--shadow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
fill: var(--shadow);
|
||||||
|
margin: -.1rem 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.applied {
|
||||||
|
color: var(--shadow-strong);
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
fill: var(--shadow-strong);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.filter-mode {
|
.filter-mode {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
color: var(--shadow);
|
color: var(--shadow);
|
||||||
|
@ -240,6 +278,10 @@ export default {
|
||||||
.filters-filter:last-child .filter {
|
.filters-filter:last-child .filter {
|
||||||
padding: .5rem 0 .5rem .5rem;
|
padding: .5rem 0 .5rem .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.total {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
@ -261,43 +303,6 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep(.filter) {
|
|
||||||
color: var(--shadow);
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
.filter-applied {
|
|
||||||
flex-grow: 1;
|
|
||||||
padding: .75rem .5rem;
|
|
||||||
font-size: 1rem;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
text-align: right;
|
|
||||||
|
|
||||||
&.empty {
|
|
||||||
color: var(--shadow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
fill: var(--shadow);
|
|
||||||
margin: -.1rem 0 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
.applied {
|
|
||||||
color: var(--shadow-strong);
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
fill: var(--shadow-strong);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.filters {
|
.filters {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
@ -351,4 +356,11 @@ export default {
|
||||||
margin: 0 1rem 0 0;
|
margin: 0 1rem 0 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.total {
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 0 1rem;
|
||||||
|
color: var(--shadow);
|
||||||
|
font-size: .8rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
>Tags</div>
|
>Tags</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-slot:tooltip>
|
<template #tooltip>
|
||||||
<div
|
<div
|
||||||
class="filter-options"
|
class="filter-options"
|
||||||
@click.stop
|
@click.stop
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
<script>
|
<script>
|
||||||
function getNewRange(tag) {
|
function getNewRange(tag) {
|
||||||
if (this.selectedTags.includes(tag)) {
|
if (this.selectedTags.includes(tag)) {
|
||||||
return { tags: this.selectedTags.filter(selectedTag => selectedTag !== tag).join(',') || undefined };
|
return { tags: this.selectedTags.filter((selectedTag) => selectedTag !== tag).join(',') || undefined };
|
||||||
}
|
}
|
||||||
|
|
||||||
return { tags: this.selectedTags.concat(tag).join(',') };
|
return { tags: this.selectedTags.concat(tag).join(',') };
|
||||||
|
@ -82,10 +82,6 @@ function selectedTags() {
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
filter: {
|
|
||||||
type: Array,
|
|
||||||
default: () => [],
|
|
||||||
},
|
|
||||||
compact: {
|
compact: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
:items-total="totalCount"
|
:items-total="totalCount"
|
||||||
:items-per-page="limit"
|
:items-per-page="limit"
|
||||||
:content="$refs.content"
|
:content="$refs.content"
|
||||||
|
:show-total="false"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Releases
|
<Releases
|
||||||
|
|
|
@ -28,7 +28,7 @@ export default {
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
beforeMount() {
|
beforeMount() {
|
||||||
this.svg = require(`../../img/icons/${this.icon}.svg`).default;
|
this.svg = require(`../../img/icons/${this.icon}.svg`).default; // eslint-disable-line global-require, import/no-dynamic-require
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -11,16 +11,31 @@
|
||||||
class="empty"
|
class="empty"
|
||||||
>No results for "{{ $route.query.query }}"</span>
|
>No results for "{{ $route.query.query }}"</span>
|
||||||
|
|
||||||
<div
|
<template v-else>
|
||||||
v-else
|
<h2 class="heading">Popular</h2>
|
||||||
class="entity-tiles"
|
|
||||||
>
|
<div
|
||||||
<Entity
|
class="entity-tiles"
|
||||||
v-for="entity in entities"
|
>
|
||||||
:key="entity.parent ? `entity-tile-${entity.parent.slug}-${entity.slug}` : `entity-tile-${entity.slug}`"
|
<Entity
|
||||||
:entity="entity"
|
v-for="entity in popularEntities"
|
||||||
/>
|
:key="entity.parent ? `entity-tile-${entity.parent.slug}-${entity.slug}` : `entity-tile-${entity.slug}`"
|
||||||
</div>
|
:entity="entity"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h2 class="heading">All networks</h2>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="entity-tiles"
|
||||||
|
>
|
||||||
|
<Entity
|
||||||
|
v-for="entity in entities"
|
||||||
|
:key="entity.parent ? `entity-tile-${entity.parent.slug}-${entity.slug}` : `entity-tile-${entity.slug}`"
|
||||||
|
:entity="entity"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
|
@ -58,6 +73,45 @@ async function searchEntities() {
|
||||||
this.done = true;
|
this.done = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function popularEntities() {
|
||||||
|
const entitiesBySlug = Object.fromEntries(this.entities.map((entity) => [entity.slug, entity]));
|
||||||
|
|
||||||
|
return [
|
||||||
|
'21sextury',
|
||||||
|
'amateurallure',
|
||||||
|
'analvids',
|
||||||
|
'bamvisions',
|
||||||
|
'bang',
|
||||||
|
'bangbros',
|
||||||
|
'blowpass',
|
||||||
|
'brazzers',
|
||||||
|
'burningangel',
|
||||||
|
'digitalplayground',
|
||||||
|
'dogfartnetwork',
|
||||||
|
'dorcel',
|
||||||
|
'elegantangel',
|
||||||
|
'evilangel',
|
||||||
|
'fakehub',
|
||||||
|
'girlsway',
|
||||||
|
'hookuphotshot',
|
||||||
|
'hussiepass',
|
||||||
|
'insex',
|
||||||
|
'julesjordan',
|
||||||
|
'kellymadison',
|
||||||
|
'kink',
|
||||||
|
'mofos',
|
||||||
|
'naughtyamerica',
|
||||||
|
'newsensations',
|
||||||
|
'pervcity',
|
||||||
|
'pornpros',
|
||||||
|
'private',
|
||||||
|
'realitykings',
|
||||||
|
'twistys',
|
||||||
|
'vixen',
|
||||||
|
'xempire',
|
||||||
|
].map((slug) => entitiesBySlug[slug]).filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
async function mounted() {
|
async function mounted() {
|
||||||
this.pageTitle = 'Channels';
|
this.pageTitle = 'Channels';
|
||||||
|
|
||||||
|
@ -82,6 +136,7 @@ export default {
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
channelCount,
|
channelCount,
|
||||||
|
popularEntities,
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: fetchEntities,
|
$route: fetchEntities,
|
||||||
|
@ -130,6 +185,10 @@ export default {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.heading {
|
||||||
|
margin: 1rem 0 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
@media(max-width: $breakpoint2) {
|
@media(max-width: $breakpoint2) {
|
||||||
.entity-tiles {
|
.entity-tiles {
|
||||||
grid-gap: .5rem;
|
grid-gap: .5rem;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<div class="media-container">
|
<div class="media-container">
|
||||||
<div
|
<div
|
||||||
class="media"
|
class="media"
|
||||||
:class="{ center: release.photos.length < 2, preview: !me }"
|
:class="{ center: (release.photos?.length || 0) + (release.scenesPhotos?.length || 0) < 2, preview: !me }"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
v-if="release.trailer || release.teaser"
|
v-if="release.trailer || release.teaser"
|
||||||
|
@ -71,24 +71,28 @@
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="release.covers && release.covers.length > 0">
|
<template v-if="release.covers?.length > 0">
|
||||||
<a
|
<div
|
||||||
v-for="cover in release.covers"
|
v-for="cover in release.covers"
|
||||||
:key="`cover-${cover.id}`"
|
:key="`cover-${cover.id}`"
|
||||||
:href="getPath(cover)"
|
class="item-container"
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
>
|
||||||
<img
|
<a
|
||||||
:src="getPath(cover, 'thumbnail')"
|
:href="getPath(cover)"
|
||||||
:style="{ 'background-image': getBgPath(cover, 'lazy') }"
|
target="_blank"
|
||||||
:width="cover.thumbnailWidth"
|
rel="noopener noreferrer"
|
||||||
:height="cover.thumbnailHeight"
|
|
||||||
class="item cover"
|
|
||||||
loading="lazy"
|
|
||||||
@load="$emit('load', $event)"
|
|
||||||
>
|
>
|
||||||
</a>
|
<img
|
||||||
|
:src="getPath(cover, 'thumbnail')"
|
||||||
|
:style="{ 'background-image': getBgPath(cover, 'lazy') }"
|
||||||
|
:width="cover.thumbnailWidth"
|
||||||
|
:height="cover.thumbnailHeight"
|
||||||
|
class="item cover"
|
||||||
|
loading="lazy"
|
||||||
|
@load="$emit('load', $event)"
|
||||||
|
>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -164,8 +168,8 @@ function poster() {
|
||||||
function photos() {
|
function photos() {
|
||||||
const clips = this.release.clips || [];
|
const clips = this.release.clips || [];
|
||||||
const clipPostersById = clips.reduce((acc, clip) => ({ ...acc, [clip.poster.id]: clip.poster }), {});
|
const clipPostersById = clips.reduce((acc, clip) => ({ ...acc, [clip.poster.id]: clip.poster }), {});
|
||||||
const uniqueClipPosters = Array.from(new Set(clips.map(clip => clip.poster.id) || [])).map(posterId => clipPostersById[posterId]);
|
const uniqueClipPosters = Array.from(new Set(clips.map((clip) => clip.poster.id) || [])).map((posterId) => clipPostersById[posterId]);
|
||||||
const photosWithClipPosters = (this.release.photos || []).concat(uniqueClipPosters);
|
const photosWithClipPosters = (this.release.photos || []).concat(this.release.scenesPhotos || []).concat(uniqueClipPosters);
|
||||||
|
|
||||||
if (this.release.trailer || (this.release.teaser && this.release.teaser.mime !== 'image/gif')) {
|
if (this.release.trailer || (this.release.teaser && this.release.teaser.mime !== 'image/gif')) {
|
||||||
// poster will be on trailer video
|
// poster will be on trailer video
|
||||||
|
|
|
@ -14,6 +14,12 @@
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
:title="movie.title"
|
||||||
|
class="unavailable"
|
||||||
|
><Icon icon="blocked" /></div>
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
v-show="(!stash || stash.primary) && favorited"
|
v-show="(!stash || stash.primary) && favorited"
|
||||||
icon="heart7"
|
icon="heart7"
|
||||||
|
@ -161,7 +167,6 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.movie {
|
.movie {
|
||||||
height: 16rem;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,18 +176,30 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.cover {
|
.cover {
|
||||||
height: 100%;
|
height: 16rem;
|
||||||
|
width: 11.25rem;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-shrink: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
box-shadow: 0 0 3px var(--darken-weak);
|
box-shadow: 0 0 3px var(--darken-weak);
|
||||||
|
background-color: var(--shadow-hint);
|
||||||
|
|
||||||
img {
|
img {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
max-width: 12rem;
|
width: 100%;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
object-position: center;
|
object-position: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.unavailable .icon {
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
fill: var(--shadow-hint);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
|
@ -252,12 +269,12 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash {
|
.stash {
|
||||||
width: 1.25rem;
|
width: 1.5rem;
|
||||||
height: 1.25rem;
|
height: 1.5rem;
|
||||||
padding: .25rem .5rem .5rem .25rem;
|
padding: .25rem .5rem .5rem .5rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
left: 0;
|
||||||
fill: var(--lighten-weak);
|
fill: var(--lighten-weak);
|
||||||
filter: drop-shadow(0 0 2px var(--darken));
|
filter: drop-shadow(0 0 2px var(--darken));
|
||||||
|
|
||||||
|
@ -273,8 +290,9 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width: $breakpoint-kilo) {
|
@media(max-width: $breakpoint-kilo) {
|
||||||
.movie {
|
.cover {
|
||||||
height: 12rem;
|
height: 12rem;
|
||||||
|
width: 8.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ensure no half actor names show */
|
/* ensure no half actor names show */
|
||||||
|
|
|
@ -21,14 +21,14 @@
|
||||||
<Details :release="release" />
|
<Details :release="release" />
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="release.photos.length > 0"
|
v-if="release.photos?.length > 0 || release.scenesPhotos?.length > 0"
|
||||||
class="album-toggle"
|
class="album-toggle"
|
||||||
@click="$router.push({ hash: '#album' })"
|
@click="$router.push({ hash: '#album' })"
|
||||||
><Icon icon="grid3" />View album</button>
|
><Icon icon="grid3" />View album</button>
|
||||||
|
|
||||||
<Album
|
<Album
|
||||||
v-if="showAlbum"
|
v-if="showAlbum"
|
||||||
:items="[release.poster, ...release.photos]"
|
:items="[release.poster, ...(release.photos || []), ...(release.scenesPhotos || [])]"
|
||||||
:title="release.title"
|
:title="release.title"
|
||||||
:path="config.media.mediaPath"
|
:path="config.media.mediaPath"
|
||||||
@close="$router.replace({ hash: undefined })"
|
@close="$router.replace({ hash: undefined })"
|
||||||
|
@ -79,22 +79,23 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="release.movies && release.movies.length > 0"
|
v-if="release.movies?.length > 0 || release.series?.length > 0"
|
||||||
class="row"
|
class="row"
|
||||||
>
|
>
|
||||||
<span class="row-label">Part of</span>
|
<span class="row-label">Part of</span>
|
||||||
|
|
||||||
<div class="movies">
|
<div class="movies">
|
||||||
<router-link
|
<router-link
|
||||||
v-for="movie in release.movies"
|
v-for="movie in [...release.movies, ...release.series]"
|
||||||
:key="`movie-${movie.id}`"
|
:key="`movie-${movie.id}`"
|
||||||
:to="{ name: 'movie', params: { releaseId: movie.id, releaseSlug: movie.slug } }"
|
:to="{ name: movie.type || 'movie', params: { releaseId: movie.id, releaseSlug: movie.slug } }"
|
||||||
class="movie"
|
class="movie"
|
||||||
>
|
>
|
||||||
<span class="movie-title">{{ movie.title }}</span>
|
<span class="movie-title">{{ movie.title }}</span>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
v-if="movie.covers.length > 0"
|
v-if="movie.covers.length > 0 || movie.poster"
|
||||||
:src="getPath(movie.covers[0], 'thumbnail')"
|
:src="getPath(movie.covers[0] || movie.poster, 'thumbnail')"
|
||||||
class="movie-cover"
|
class="movie-cover"
|
||||||
>
|
>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -243,6 +244,10 @@ async function fetchRelease(scroll = true) {
|
||||||
this.release = await this.$store.dispatch('fetchMovieById', this.$route.params.releaseId);
|
this.release = await this.$store.dispatch('fetchMovieById', this.$route.params.releaseId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.$route.name === 'serie') {
|
||||||
|
this.release = await this.$store.dispatch('fetchSerieById', this.$route.params.releaseId);
|
||||||
|
}
|
||||||
|
|
||||||
if (scroll && this.$refs.content) {
|
if (scroll && this.$refs.content) {
|
||||||
this.$refs.content.scrollTop = 0;
|
this.$refs.content.scrollTop = 0;
|
||||||
}
|
}
|
||||||
|
@ -278,11 +283,11 @@ function bannerBackground() {
|
||||||
function pageTitle() {
|
function pageTitle() {
|
||||||
return this.release
|
return this.release
|
||||||
&& (this.release.title
|
&& (this.release.title
|
||||||
|| (this.release.actors.length > 0 ? `${this.release.actors.map(actor => actor.name).join(', ')} for ${this.release.entity.name}` : null));
|
|| (this.release.actors.length > 0 ? `${this.release.actors.map((actor) => actor.name).join(', ')} for ${this.release.entity.name}` : null));
|
||||||
}
|
}
|
||||||
|
|
||||||
function showAlbum() {
|
function showAlbum() {
|
||||||
return this.release.photos?.length > 0 && this.$route.hash === '#album';
|
return (this.release.photos?.length > 0 || this.release.scenesPhotos?.length > 0) && this.$route.hash === '#album';
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -126,10 +126,29 @@ export default {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media(max-width: $breakpoint-mega) {
|
||||||
|
.tiles {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(19rem, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media(max-width: $breakpoint-kilo) {
|
@media(max-width: $breakpoint-kilo) {
|
||||||
.tiles {
|
.tiles {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(18.5rem, 1fr));
|
||||||
grid-gap: .5rem;
|
grid-gap: .5rem;
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media(max-width: $breakpoint) {
|
||||||
|
.tiles {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(max-width: $breakpoint-micro) {
|
||||||
|
.tiles {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr));
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -113,21 +113,22 @@
|
||||||
:key="actor.id"
|
:key="actor.id"
|
||||||
class="actor"
|
class="actor"
|
||||||
>
|
>
|
||||||
<router-link
|
<RouterLink
|
||||||
:to="{ name: 'actor', params: { actorId: actor.id, actorSlug: actor.slug } }"
|
:to="{ name: 'actor', params: { actorId: actor.id, actorSlug: actor.slug } }"
|
||||||
|
:class="{ [actor.gender]: !!actor.gender }"
|
||||||
class="actor-link"
|
class="actor-link"
|
||||||
>{{ actor.name }}</router-link>
|
>{{ actor.name }}</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<div class="labels">
|
<div class="labels">
|
||||||
<router-link
|
<RouterLink
|
||||||
v-if="release.shootId && release.studio"
|
v-if="release.shootId && release.studio"
|
||||||
:to="`/studio/${release.studio.slug}`"
|
:to="`/studio/${release.studio.slug}`"
|
||||||
:title="release.studio && release.studio.name"
|
:title="release.studio && release.studio.name"
|
||||||
class="shoot nolink"
|
class="shoot nolink"
|
||||||
>{{ release.shootId }}</router-link>
|
>{{ release.shootId }}</RouterLink>
|
||||||
|
|
||||||
<span
|
<span
|
||||||
v-else-if="release.shootId"
|
v-else-if="release.shootId"
|
||||||
|
@ -145,10 +146,10 @@
|
||||||
:key="`tag-${tag.slug}`"
|
:key="`tag-${tag.slug}`"
|
||||||
class="tag"
|
class="tag"
|
||||||
>
|
>
|
||||||
<router-link
|
<RouterLink
|
||||||
:to="`/tag/${tag.slug}`"
|
:to="`/tag/${tag.slug}`"
|
||||||
class="tag-link"
|
class="tag-link"
|
||||||
>{{ tag.name }}</router-link>
|
>{{ tag.name }}</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -233,20 +234,23 @@ export default {
|
||||||
box-shadow: 0 0 3px var(--darken-weak);
|
box-shadow: 0 0 3px var(--darken-weak);
|
||||||
|
|
||||||
&.new .poster::after {
|
&.new .poster::after {
|
||||||
content: '★';
|
content: 'new';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
display: flex;
|
||||||
left: 0;
|
align-items: center;
|
||||||
width: 1rem;
|
justify-content: center;
|
||||||
height: 1rem;
|
bottom: 0;
|
||||||
|
right: .5rem;
|
||||||
|
width: 2rem;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: .25rem;
|
padding: .1rem 0 .05rem 0;
|
||||||
border-radius: 0 0 .5rem 0;
|
border-radius: .25rem .25rem 0 0;
|
||||||
color: var(--primary);
|
background: var(--info);
|
||||||
font-size: 1rem;
|
color: var(--text-light);
|
||||||
|
font-size: .7rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
text-shadow: 0 0 2px var(--darken-weak);
|
box-shadow: 0 0 3px var(--shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover .unstashed,
|
&:hover .unstashed,
|
||||||
|
@ -295,8 +299,8 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash {
|
.stash {
|
||||||
width: 1.25rem;
|
width: 1.5rem;
|
||||||
height: 1.25rem;
|
height: 1.5rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
|
@ -317,17 +321,18 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
|
max-width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 0 .5rem;
|
padding: 0 .5rem;
|
||||||
margin: 0 0 .1rem 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.info {
|
.info {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
@ -339,7 +344,7 @@ export default {
|
||||||
.title {
|
.title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: var(--text);
|
color: var(--text);
|
||||||
font-size: 1rem;
|
font-size: .9rem;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
@ -365,8 +370,9 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.actor-link {
|
.actor-link {
|
||||||
color: var(--link);
|
color: var(--text);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
font-size: .9rem;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
|
@ -374,7 +380,7 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.labels {
|
.labels {
|
||||||
padding: 0 .5rem 1.5rem .5rem;
|
padding: 0 .5rem 1.25rem .5rem;
|
||||||
max-height: .5rem;
|
max-height: .5rem;
|
||||||
overflow-y: hidden;
|
overflow-y: hidden;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
|
@ -405,11 +411,11 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.tag-link {
|
.tag-link {
|
||||||
background: var(--background);
|
background: var(--shadow-touch);
|
||||||
color: var(--shadow);
|
color: var(--shadow);
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: .25rem .5rem;
|
padding: .25rem .5rem;
|
||||||
border: solid 1px var(--shadow-hint);
|
margin: 0 1px 0 0;
|
||||||
font-size: .75rem;
|
font-size: .75rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
@ -421,14 +427,20 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.details-wide {
|
.details-wide {
|
||||||
margin: 0 0 .5rem 0;
|
margin: 0 0 .4rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.details-compact {
|
.details-compact {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width: $breakpoint-kilo) {
|
@media(max-width: $breakpoint) {
|
||||||
|
.thumbnail {
|
||||||
|
height: 11rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(max-width: $breakpoint-micro) {
|
||||||
.tile-body {
|
.tile-body {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
@ -474,14 +486,15 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
.tile.new .poster::after {
|
.tile.new .poster::after {
|
||||||
bottom: 0;
|
top: 0;
|
||||||
top: auto;
|
right: .25rem;
|
||||||
margin: .1rem .25rem;
|
bottom: auto;
|
||||||
|
border-radius: 0 0 .25rem .25rem;
|
||||||
|
padding: .05rem 0 .1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash {
|
.stash {
|
||||||
left: 0;
|
left: 0;
|
||||||
right: auto;
|
|
||||||
padding: .25rem .5rem .5rem .25rem;
|
padding: .25rem .5rem .5rem .25rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,10 +57,7 @@
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="date"
|
class="date"
|
||||||
><Icon
|
>{{ formatDate(release.date, 'MMMM D, YYYY', release.datePrecision) }}</a>
|
||||||
v-if="release.url"
|
|
||||||
icon="share2"
|
|
||||||
/>{{ formatDate(release.date, 'MMMM D, YYYY', release.datePrecision) }}</a>
|
|
||||||
|
|
||||||
<a
|
<a
|
||||||
v-else
|
v-else
|
||||||
|
@ -91,27 +88,17 @@ export default {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
z-index: 1;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
background: var(--profile);
|
background: var(--info);
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
.favicon {
|
.favicon {
|
||||||
width: 2rem;
|
width: 2rem;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: .5rem;
|
padding: .4rem .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
&.new .date::before {
|
|
||||||
content: '';
|
|
||||||
width: .5rem;
|
|
||||||
height: .5rem;
|
|
||||||
border-radius: 50%;
|
|
||||||
margin: 0 .25rem 0 0;
|
|
||||||
background: var(--primary);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.site,
|
.site,
|
||||||
|
@ -120,7 +107,7 @@ export default {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: .8rem;
|
font-size: .8rem;
|
||||||
padding: .5rem;
|
padding: .4rem .5rem;
|
||||||
color: var(--text-light);
|
color: var(--text-light);
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,8 @@ const tagSlugsByCategory = {
|
||||||
'teen',
|
'teen',
|
||||||
'milf',
|
'milf',
|
||||||
'blowjob',
|
'blowjob',
|
||||||
|
'gay',
|
||||||
|
'transsexual',
|
||||||
'dp',
|
'dp',
|
||||||
'gangbang',
|
'gangbang',
|
||||||
'facial',
|
'facial',
|
||||||
|
@ -64,6 +66,11 @@ const tagSlugsByCategory = {
|
||||||
'tattoos',
|
'tattoos',
|
||||||
'piercings',
|
'piercings',
|
||||||
],
|
],
|
||||||
|
sexuality: [
|
||||||
|
'gay',
|
||||||
|
'bisexual',
|
||||||
|
'transsexual',
|
||||||
|
],
|
||||||
oral: [
|
oral: [
|
||||||
'blowjob',
|
'blowjob',
|
||||||
'pussy-eating',
|
'pussy-eating',
|
||||||
|
@ -80,7 +87,6 @@ const tagSlugsByCategory = {
|
||||||
'titty-fucking',
|
'titty-fucking',
|
||||||
'fisting',
|
'fisting',
|
||||||
'anal-fisting',
|
'anal-fisting',
|
||||||
'fisting-dp',
|
|
||||||
],
|
],
|
||||||
group: [
|
group: [
|
||||||
'mfm',
|
'mfm',
|
||||||
|
@ -101,16 +107,6 @@ const tagSlugsByCategory = {
|
||||||
'bukkake',
|
'bukkake',
|
||||||
'fake-cum',
|
'fake-cum',
|
||||||
],
|
],
|
||||||
toys: [
|
|
||||||
'toys',
|
|
||||||
'toy-anal',
|
|
||||||
'toy-dp',
|
|
||||||
'double-dildo',
|
|
||||||
'double-dildo-blowjob',
|
|
||||||
'double-dildo-kiss',
|
|
||||||
'double-dildo-anal',
|
|
||||||
'double-dildo-dp',
|
|
||||||
],
|
|
||||||
roleplay: [
|
roleplay: [
|
||||||
'family',
|
'family',
|
||||||
'parody',
|
'parody',
|
||||||
|
@ -119,6 +115,15 @@ const tagSlugsByCategory = {
|
||||||
'maid',
|
'maid',
|
||||||
'nun',
|
'nun',
|
||||||
],
|
],
|
||||||
|
extreme: [
|
||||||
|
'dp',
|
||||||
|
'airtight',
|
||||||
|
'dap',
|
||||||
|
'dvp',
|
||||||
|
'triple-penetration',
|
||||||
|
'tap',
|
||||||
|
'tvp',
|
||||||
|
],
|
||||||
fetish: [
|
fetish: [
|
||||||
'bdsm',
|
'bdsm',
|
||||||
'femdom',
|
'femdom',
|
||||||
|
@ -127,15 +132,15 @@ const tagSlugsByCategory = {
|
||||||
'latex',
|
'latex',
|
||||||
'blindfold',
|
'blindfold',
|
||||||
],
|
],
|
||||||
extreme: [
|
toys: [
|
||||||
'dp',
|
'toys',
|
||||||
'airtight',
|
'toy-anal',
|
||||||
'dap',
|
'toy-dp',
|
||||||
'dvp',
|
'double-dildo',
|
||||||
'da-tp',
|
'double-dildo-blowjob',
|
||||||
'dv-tp',
|
'double-dildo-kiss',
|
||||||
'tap',
|
'double-dildo-anal',
|
||||||
'tvp',
|
'double-dildo-dp',
|
||||||
],
|
],
|
||||||
misc: [
|
misc: [
|
||||||
'gaping',
|
'gaping',
|
||||||
|
@ -162,10 +167,18 @@ async function fetchTags() {
|
||||||
|
|
||||||
const tagsBySlug = tags.reduce((acc, tag) => ({ ...acc, [tag.slug]: tag }), {});
|
const tagsBySlug = tags.reduce((acc, tag) => ({ ...acc, [tag.slug]: tag }), {});
|
||||||
|
|
||||||
this.categories = Object.entries(tagSlugsByCategory).reduce((acc, [category, tagSlugs]) => ({
|
this.categories = Object.entries(tagSlugsByCategory).reduce((acc, [category, tagSlugs]) => {
|
||||||
...acc,
|
const categoryTags = tagSlugs.map((tagSlug) => tagsBySlug[tagSlug]).filter(Boolean);
|
||||||
[category]: tagSlugs.map(tagSlug => tagsBySlug[tagSlug]),
|
|
||||||
}), {});
|
if (categoryTags.length === 0) {
|
||||||
|
return acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...acc,
|
||||||
|
[category]: categoryTags,
|
||||||
|
};
|
||||||
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function searchTags() {
|
async function searchTags() {
|
||||||
|
@ -202,6 +215,7 @@ export default {
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
$route: fetchTags,
|
$route: fetchTags,
|
||||||
|
'$store.state.ui.tagFilter': fetchTags,
|
||||||
},
|
},
|
||||||
mounted,
|
mounted,
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -212,7 +226,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import 'theme';
|
@import 'breakpoints';
|
||||||
|
|
||||||
.tags {
|
.tags {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -244,22 +258,81 @@ export default {
|
||||||
margin: 0 0 .25rem 0;
|
margin: 0 0 .25rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width: $breakpoint3) {
|
@media(max-width: $breakpoint-mega) {
|
||||||
.tiles {
|
.tiles {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(18rem, .5fr));
|
grid-template-columns: repeat(auto-fill, minmax(17.75rem, .5fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::v-deep(.poster),
|
||||||
|
::v-deep(.blank) {
|
||||||
|
height: 12rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(max-width: $breakpoint-kilo) {
|
||||||
|
.tiles {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(18rem, 1fr));
|
||||||
|
grid-gap: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep(.poster),
|
||||||
|
::v-deep(.blank) {
|
||||||
|
height: 14rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width: $breakpoint) {
|
@media(max-width: $breakpoint) {
|
||||||
.tiles {
|
.tiles {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(14.5rem, 1fr));
|
||||||
grid-gap: .5rem;
|
grid-gap: .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::v-deep(.poster),
|
||||||
|
::v-deep(.blank) {
|
||||||
|
height: 11rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(max-width: $breakpoint0) {
|
@media(max-width: $breakpoint-small) {
|
||||||
|
::v-deep(.poster),
|
||||||
|
::v-deep(.blank) {
|
||||||
|
height: 10rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(max-width: $breakpoint-micro) {
|
||||||
.tiles {
|
.tiles {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(12rem, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::v-deep(.poster),
|
||||||
|
::v-deep(.blank) {
|
||||||
|
height: 7.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(max-width: $breakpoint-mini) {
|
||||||
|
.tiles {
|
||||||
|
grid-template-columns: repeat(auto-fill, minmax(11.5rem, 1fr));
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep(.poster),
|
||||||
|
::v-deep(.blank) {
|
||||||
|
height: 12rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(max-width: $breakpoint-nano) {
|
||||||
|
::v-deep(.poster),
|
||||||
|
::v-deep(.blank) {
|
||||||
|
height: 10rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(max-width: $breakpoint-pico) {
|
||||||
|
::v-deep(.poster),
|
||||||
|
::v-deep(.blank) {
|
||||||
|
height: 8rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -44,6 +44,11 @@
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--primary-strong);
|
background: var(--primary-strong);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
background: var(--shadow-weak);
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-secondary {
|
.button-secondary {
|
||||||
|
|
|
@ -5,10 +5,17 @@ $breakpoint3: 1200px;
|
||||||
$breakpoint4: 1500px;
|
$breakpoint4: 1500px;
|
||||||
|
|
||||||
:root {
|
:root {
|
||||||
|
--primary: #f65596;
|
||||||
|
--primary-strong: #f90071;
|
||||||
|
--primary-faded: #ffcce4;
|
||||||
|
|
||||||
|
/*
|
||||||
|
--primary: #f04288;
|
||||||
|
|
||||||
--primary: #ff6c88;
|
--primary: #ff6c88;
|
||||||
--primary-strong: #ff4166;
|
--primary-strong: #ff4166;
|
||||||
--primary-faded: #ffdfee;
|
--primary-faded: #ffdfee;
|
||||||
/*
|
|
||||||
--primary: #f28;
|
--primary: #f28;
|
||||||
--primary-strong: #f90071;
|
--primary-strong: #f90071;
|
||||||
--primary-faded: #ffcce4;
|
--primary-faded: #ffcce4;
|
||||||
|
@ -39,6 +46,8 @@ $breakpoint4: 1500px;
|
||||||
--logo-shadow: drop-shadow(1px 0 0 $shadow-weak) drop-shadow(-1px 0 0 $shadow-weak) drop-shadow(0 1px 0 $shadow-weak) drop-shadow(0 -1px 0 $shadow-weak);
|
--logo-shadow: drop-shadow(1px 0 0 $shadow-weak) drop-shadow(-1px 0 0 $shadow-weak) drop-shadow(0 1px 0 $shadow-weak) drop-shadow(0 -1px 0 $shadow-weak);
|
||||||
--logo-highlight: drop-shadow(0 0 1px $highlight);
|
--logo-highlight: drop-shadow(0 0 1px $highlight);
|
||||||
|
|
||||||
|
--info: #321b24;
|
||||||
|
|
||||||
--male: #0af;
|
--male: #0af;
|
||||||
--female: #f0a;
|
--female: #f0a;
|
||||||
|
|
||||||
|
|
|
@ -281,7 +281,7 @@ function initActorActions(store, router) {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
actor: curateActor(actor, null, curateRelease),
|
actor: curateActor(actor, null, curateRelease),
|
||||||
releases: actor.scenesConnection.releases.map(release => curateRelease(release)),
|
releases: actor.scenesConnection.releases.map((release) => curateRelease(release)),
|
||||||
totalCount: actor.scenesConnection.totalCount,
|
totalCount: actor.scenesConnection.totalCount,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -429,7 +429,7 @@ function initActorActions(store, router) {
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
actors: actors.map(actor => curateActor(actor)),
|
actors: actors.map((actor) => curateActor(actor)),
|
||||||
totalCount,
|
totalCount,
|
||||||
countries,
|
countries,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
function favoritesStash(state) {
|
function favoritesStash(state) {
|
||||||
return state.user.stashes.find(stash => stash.slug === 'favorites');
|
return state.user.stashes.find((stash) => stash.slug === 'favorites');
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
|
|
@ -31,8 +31,8 @@ function curateActor(actor, release) {
|
||||||
|
|
||||||
if (actor.profiles) {
|
if (actor.profiles) {
|
||||||
const photos = actor.profiles
|
const photos = actor.profiles
|
||||||
.map(profile => ({ entity: profile.entity, ...profile.avatar }))
|
.map((profile) => ({ entity: profile.entity, ...profile.avatar }))
|
||||||
.filter(avatar => avatar.id && (!curatedActor.avatar || avatar.hash !== curatedActor.avatar.hash));
|
.filter((avatar) => avatar.id && (!curatedActor.avatar || avatar.hash !== curatedActor.avatar.hash));
|
||||||
|
|
||||||
const descriptions = actor.profiles.reduce((acc, profile) => ({
|
const descriptions = actor.profiles.reduce((acc, profile) => ({
|
||||||
...acc,
|
...acc,
|
||||||
|
@ -57,34 +57,38 @@ function curateActor(actor, release) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (actor.stashes) {
|
if (actor.stashes) {
|
||||||
curatedActor.stashes = actor.stashes.filter(Boolean).map(stash => curateStash(stash.stash || stash)); // eslint-disable-line no-use-before-define
|
curatedActor.stashes = actor.stashes.filter(Boolean).map((stash) => curateStash(stash.stash || stash)); // eslint-disable-line no-use-before-define
|
||||||
}
|
}
|
||||||
|
|
||||||
curatedActor.stashes = actor.stashes?.map(stash => stash.stash || stash) || [];
|
curatedActor.stashes = actor.stashes?.map((stash) => stash.stash || stash) || [];
|
||||||
|
|
||||||
return curatedActor;
|
return curatedActor;
|
||||||
}
|
}
|
||||||
|
|
||||||
function curateRelease(release) {
|
function curateRelease(release, type = 'scene') {
|
||||||
const curatedRelease = {
|
const curatedRelease = {
|
||||||
...release,
|
...release,
|
||||||
|
type: release.type || type,
|
||||||
actors: [],
|
actors: [],
|
||||||
poster: release.poster && release.poster.media,
|
poster: release.poster && release.poster.media,
|
||||||
tags: release.tags ? release.tags.map(tag => tag.tag || tag) : [],
|
tags: release.tags ? release.tags.map((tag) => tag.tag || tag) : [],
|
||||||
};
|
};
|
||||||
|
|
||||||
if (release.scenes) curatedRelease.scenes = release.scenes.filter(Boolean).map(({ scene }) => curateRelease(scene));
|
curatedRelease.scenes = release.scenes?.filter(Boolean).map(({ scene }) => curateRelease(scene, 'scene')) || [];
|
||||||
if (release.movies) curatedRelease.movies = release.movies.filter(Boolean).map(({ movie }) => curateRelease(movie));
|
curatedRelease.movies = release.movies?.filter(Boolean).map(({ movie }) => curateRelease(movie, 'movie')) || [];
|
||||||
if (release.chapters) curatedRelease.chapters = release.chapters.filter(Boolean).map(chapter => curateRelease(chapter));
|
curatedRelease.series = release.series?.filter(Boolean).map(({ serie }) => curateRelease(serie, 'serie')) || [];
|
||||||
if (release.photos) curatedRelease.photos = release.photos.filter(Boolean).map(photo => photo.media || photo);
|
curatedRelease.chapters = release.chapters?.filter(Boolean).map((chapter) => curateRelease(chapter)) || [];
|
||||||
if (release.covers) curatedRelease.covers = release.covers.filter(Boolean).map(({ media }) => media);
|
curatedRelease.photos = release.photos?.filter(Boolean).map((photo) => photo.media || photo) || [];
|
||||||
|
curatedRelease.scenesPhotos = release.scenesPhotos?.filter(Boolean).map((photo) => photo.media || photo) || [];
|
||||||
|
curatedRelease.covers = release.covers?.filter(Boolean).map(({ media }) => media) || [];
|
||||||
|
|
||||||
if (release.trailer) curatedRelease.trailer = release.trailer.media;
|
if (release.trailer) curatedRelease.trailer = release.trailer.media;
|
||||||
if (release.teaser) curatedRelease.teaser = release.teaser.media;
|
if (release.teaser) curatedRelease.teaser = release.teaser.media;
|
||||||
if (release.actors) curatedRelease.actors = release.actors.filter(Boolean).map(actor => curateActor(actor.actor || actor, curatedRelease));
|
if (release.actors) curatedRelease.actors = release.actors.filter(Boolean).map((actor) => curateActor(actor.actor || actor, curatedRelease));
|
||||||
if (release.directors) curatedRelease.directors = release.directors.filter(Boolean).map(director => curateActor(director.director || director, curatedRelease));
|
if (release.directors) curatedRelease.directors = release.directors.filter(Boolean).map((director) => curateActor(director.director || director, curatedRelease));
|
||||||
if (release.movieTags && release.movieTags.length > 0) curatedRelease.tags = release.movieTags.filter(Boolean).map(({ tag }) => tag);
|
if (release.movieTags && release.movieTags.length > 0) curatedRelease.tags = release.movieTags.filter(Boolean).map(({ tag }) => tag);
|
||||||
if (release.movieActors && release.movieActors.length > 0) curatedRelease.actors = release.movieActors.filter(Boolean).map(({ actor }) => curateActor(actor, curatedRelease));
|
if (release.movieActors && release.movieActors.length > 0) curatedRelease.actors = release.movieActors.filter(Boolean).map(({ actor }) => curateActor(actor, curatedRelease));
|
||||||
if (release.stashes) curatedRelease.stashes = release.stashes.filter(Boolean).map(stash => curateStash(stash.stash || stash)); // eslint-disable-line no-use-before-define
|
if (release.stashes) curatedRelease.stashes = release.stashes.filter(Boolean).map((stash) => curateStash(stash.stash || stash)); // eslint-disable-line no-use-before-define
|
||||||
|
|
||||||
if (release.productionLocation) {
|
if (release.productionLocation) {
|
||||||
curatedRelease.productionLocation = {
|
curatedRelease.productionLocation = {
|
||||||
|
@ -105,17 +109,20 @@ function curateEntity(entity, parent, releases) {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (entity.tags) curatedEntity.tags = entity.tags.map(({ tag }) => tag);
|
if (entity.tags) curatedEntity.tags = entity.tags.map(({ tag }) => tag);
|
||||||
|
if (entity.sceneTags) curatedEntity.sceneTags = entity.sceneTags;
|
||||||
|
|
||||||
if (entity.children) {
|
if (entity.children) {
|
||||||
if (entity.children.nodes) {
|
if (entity.children.nodes) {
|
||||||
curatedEntity.children = entity.children.nodes.map(childEntity => curateEntity(childEntity, curatedEntity));
|
curatedEntity.children = entity.children.nodes.map((childEntity) => curateEntity(childEntity, curatedEntity));
|
||||||
}
|
}
|
||||||
|
|
||||||
curatedEntity.childrenTotal = entity.children.totalCount;
|
curatedEntity.childrenTotal = entity.children.totalCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (entity.parent || parent) curatedEntity.parent = curateEntity(entity.parent || parent);
|
if (entity.parent || parent) curatedEntity.parent = curateEntity(entity.parent || parent);
|
||||||
if (releases) curatedEntity.releases = releases.map(release => curateRelease(release));
|
if (releases) curatedEntity.releases = releases.map((release) => curateRelease(release));
|
||||||
|
|
||||||
|
curatedEntity.sceneTotal = entity.sceneTotal;
|
||||||
|
|
||||||
return curatedEntity;
|
return curatedEntity;
|
||||||
}
|
}
|
||||||
|
@ -138,7 +145,7 @@ function curateStash(stash) {
|
||||||
|
|
||||||
if (stash.scenes || stash.scenesConnection?.scenes) {
|
if (stash.scenes || stash.scenesConnection?.scenes) {
|
||||||
curatedStash.sceneTotal = stash.scenesConnection?.totalCount || null;
|
curatedStash.sceneTotal = stash.scenesConnection?.totalCount || null;
|
||||||
curatedStash.scenes = (stash.scenesConnection?.scenes || stash.scenes).map(item => ({
|
curatedStash.scenes = (stash.scenesConnection?.scenes || stash.scenes).map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
scene: curateRelease(item.scene),
|
scene: curateRelease(item.scene),
|
||||||
}));
|
}));
|
||||||
|
@ -146,7 +153,7 @@ function curateStash(stash) {
|
||||||
|
|
||||||
if (stash.actors || stash.actorsConnection?.actors) {
|
if (stash.actors || stash.actorsConnection?.actors) {
|
||||||
curatedStash.actorTotal = stash.actorsConnection?.totalCount || null;
|
curatedStash.actorTotal = stash.actorsConnection?.totalCount || null;
|
||||||
curatedStash.actors = (stash.actorsConnection?.actors || stash.actors).map(item => ({
|
curatedStash.actors = (stash.actorsConnection?.actors || stash.actors).map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
actor: curateActor(item.actor),
|
actor: curateActor(item.actor),
|
||||||
}));
|
}));
|
||||||
|
@ -154,7 +161,7 @@ function curateStash(stash) {
|
||||||
|
|
||||||
if (stash.movies || stash.moviesConnection?.movies) {
|
if (stash.movies || stash.moviesConnection?.movies) {
|
||||||
curatedStash.movieTotal = stash.moviesConnection?.totalCount || null;
|
curatedStash.movieTotal = stash.moviesConnection?.totalCount || null;
|
||||||
curatedStash.movies = (stash.moviesConnection?.movies || stash.movies).map(item => ({
|
curatedStash.movies = (stash.moviesConnection?.movies || stash.movies).map((item) => ({
|
||||||
...item,
|
...item,
|
||||||
movie: curateRelease(item.movie),
|
movie: curateRelease(item.movie),
|
||||||
}));
|
}));
|
||||||
|
@ -171,11 +178,11 @@ function curateAlert(alert) {
|
||||||
const curatedAlert = alert;
|
const curatedAlert = alert;
|
||||||
|
|
||||||
if (alert.actors) {
|
if (alert.actors) {
|
||||||
curatedAlert.actors = alert.actors.map(actor => curateActor(actor.actor || actor));
|
curatedAlert.actors = alert.actors.map((actor) => curateActor(actor.actor || actor));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alert.tags) {
|
if (alert.tags) {
|
||||||
curatedAlert.tags = alert.tags.map(tag => curateTag(tag.tag || tag));
|
curatedAlert.tags = alert.tags.map((tag) => curateTag(tag.tag || tag));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alert.entity) {
|
if (alert.entity) {
|
||||||
|
@ -183,7 +190,7 @@ function curateAlert(alert) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (alert.stashes) {
|
if (alert.stashes) {
|
||||||
curatedAlert.stashes = alert.stashes.map(stash => curateStash(stash.stash || stash));
|
curatedAlert.stashes = alert.stashes.map((stash) => curateStash(stash.stash || stash));
|
||||||
}
|
}
|
||||||
|
|
||||||
return curatedAlert;
|
return curatedAlert;
|
||||||
|
@ -197,11 +204,11 @@ function curateUser(user) {
|
||||||
const curatedUser = user;
|
const curatedUser = user;
|
||||||
|
|
||||||
if (user.stashes) {
|
if (user.stashes) {
|
||||||
curatedUser.stashes = user.stashes.map(stash => curateStash(stash.stash || stash));
|
curatedUser.stashes = user.stashes.map((stash) => curateStash(stash.stash || stash));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.alerts) {
|
if (user.alerts) {
|
||||||
curatedUser.alerts = user.alerts.map(alert => curateAlert(alert.alert || alert));
|
curatedUser.alerts = user.alerts.map((alert) => curateAlert(alert.alert || alert));
|
||||||
}
|
}
|
||||||
|
|
||||||
return curatedUser;
|
return curatedUser;
|
||||||
|
|
|
@ -14,7 +14,7 @@ function initEntitiesActions(store, router) {
|
||||||
}) {
|
}) {
|
||||||
const { before, after, orderBy } = getDateRange(range);
|
const { before, after, orderBy } = getDateRange(range);
|
||||||
|
|
||||||
const { entity, connection: { releases, totalCount } } = await graphql(`
|
const { entity } = await graphql(`
|
||||||
query Entity(
|
query Entity(
|
||||||
$entitySlug: String!
|
$entitySlug: String!
|
||||||
$entityType: String! = "channel"
|
$entityType: String! = "channel"
|
||||||
|
@ -22,8 +22,6 @@ function initEntitiesActions(store, router) {
|
||||||
$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",
|
||||||
$afterTime: Datetime = "1900-01-01",
|
|
||||||
$beforeTime: Datetime = "2100-01-01",
|
|
||||||
$orderBy: [ReleasesOrderBy!]
|
$orderBy: [ReleasesOrderBy!]
|
||||||
$exclude: [String!]
|
$exclude: [String!]
|
||||||
$hasAuth: Boolean!
|
$hasAuth: Boolean!
|
||||||
|
@ -43,6 +41,11 @@ function initEntitiesActions(store, router) {
|
||||||
slug
|
slug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sceneTags {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
slug
|
||||||
|
}
|
||||||
children: childEntitiesConnection(
|
children: childEntitiesConnection(
|
||||||
orderBy: [PRIORITY_DESC, NAME_ASC],
|
orderBy: [PRIORITY_DESC, NAME_ASC],
|
||||||
filter: {
|
filter: {
|
||||||
|
@ -64,6 +67,10 @@ function initEntitiesActions(store, router) {
|
||||||
independent
|
independent
|
||||||
hasLogo
|
hasLogo
|
||||||
${campaignsFragment}
|
${campaignsFragment}
|
||||||
|
sceneTotal
|
||||||
|
children: childEntitiesConnection {
|
||||||
|
totalCount
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
${campaignsFragment}
|
${campaignsFragment}
|
||||||
|
@ -77,82 +84,44 @@ function initEntitiesActions(store, router) {
|
||||||
hasLogo
|
hasLogo
|
||||||
${campaignsFragment}
|
${campaignsFragment}
|
||||||
}
|
}
|
||||||
}
|
connection: scenesConnection(
|
||||||
connection: releasesConnection(
|
first: $limit
|
||||||
first: $limit
|
offset: $offset
|
||||||
offset: $offset
|
orderBy: $orderBy
|
||||||
orderBy: $orderBy
|
filter: {
|
||||||
filter: {
|
or: [
|
||||||
and: [
|
{
|
||||||
{
|
date: {
|
||||||
entity: {
|
isNull: ${entityType !== 'network'}
|
||||||
or: [
|
|
||||||
{
|
|
||||||
slug: { equalTo: $entitySlug }
|
|
||||||
},
|
|
||||||
{
|
|
||||||
parent: {
|
|
||||||
slug: { equalTo: $entitySlug }
|
|
||||||
type: { equalTo: $entityType }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
parent: {
|
|
||||||
parent: {
|
|
||||||
slug: { equalTo: $entitySlug }
|
|
||||||
type: { equalTo: $entityType }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
parent: {
|
|
||||||
parent: {
|
|
||||||
parent: {
|
|
||||||
slug: { equalTo: $entitySlug }
|
|
||||||
type: { equalTo: $entityType }
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{
|
|
||||||
or: [
|
|
||||||
{
|
|
||||||
date: {
|
|
||||||
lessThan: $before,
|
|
||||||
greaterThan: $after
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
date: {
|
|
||||||
isNull: true
|
|
||||||
},
|
|
||||||
createdAt: {
|
|
||||||
lessThan: $beforeTime,
|
|
||||||
greaterThan: $afterTime,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
}
|
||||||
|
{
|
||||||
|
date: {
|
||||||
|
isNull: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
effectiveDate: {
|
||||||
|
lessThan: $before,
|
||||||
|
greaterThan: $after
|
||||||
}
|
}
|
||||||
]
|
releasesTagsConnection: {
|
||||||
releasesTagsConnection: {
|
none: {
|
||||||
none: {
|
tag: {
|
||||||
tag: {
|
slug: {
|
||||||
slug: {
|
in: $exclude
|
||||||
in: $exclude
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
) {
|
||||||
|
releases: nodes {
|
||||||
|
${releaseFields}
|
||||||
|
}
|
||||||
|
totalCount
|
||||||
}
|
}
|
||||||
) {
|
}
|
||||||
releases: nodes {
|
|
||||||
${releaseFields}
|
|
||||||
}
|
|
||||||
totalCount
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
`, {
|
`, {
|
||||||
entitySlug,
|
entitySlug,
|
||||||
|
@ -162,8 +131,6 @@ function initEntitiesActions(store, router) {
|
||||||
after,
|
after,
|
||||||
before,
|
before,
|
||||||
orderBy,
|
orderBy,
|
||||||
afterTime: store.getters.after,
|
|
||||||
beforeTime: store.getters.before,
|
|
||||||
exclude: store.state.ui.tagFilter,
|
exclude: store.state.ui.tagFilter,
|
||||||
hasAuth: !!store.state.auth.user,
|
hasAuth: !!store.state.auth.user,
|
||||||
userId: store.state.auth.user?.id,
|
userId: store.state.auth.user?.id,
|
||||||
|
@ -175,8 +142,8 @@ function initEntitiesActions(store, router) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
entity: curateEntity(entity, null, releases),
|
entity: curateEntity(entity, null, entity.connection.releases),
|
||||||
totalCount,
|
totalCount: entity.connection.totalCount,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +207,7 @@ function initEntitiesActions(store, router) {
|
||||||
entitySlugs,
|
entitySlugs,
|
||||||
});
|
});
|
||||||
|
|
||||||
return entities.map(entity => curateEntity(entity));
|
return entities.map((entity) => curateEntity(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function searchEntities({ _commit }, { query, limit = 20 }) {
|
async function searchEntities({ _commit }, { query, limit = 20 }) {
|
||||||
|
@ -274,7 +241,7 @@ function initEntitiesActions(store, router) {
|
||||||
limit,
|
limit,
|
||||||
});
|
});
|
||||||
|
|
||||||
return entities.map(entity => curateEntity(entity));
|
return entities.map((entity) => curateEntity(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -5,7 +5,7 @@ export function formatDuration(duration, forceHours) {
|
||||||
const minutes = Math.floor((duration % 3600) / 60);
|
const minutes = Math.floor((duration % 3600) / 60);
|
||||||
const seconds = Math.floor(duration % 60);
|
const seconds = Math.floor(duration % 60);
|
||||||
|
|
||||||
const [formattedHours, formattedMinutes, formattedSeconds] = [hours, minutes, seconds].map(segment => segment.toString().padStart(2, '0'));
|
const [formattedHours, formattedMinutes, formattedSeconds] = [hours, minutes, seconds].map((segment) => segment.toString().padStart(2, '0'));
|
||||||
|
|
||||||
if (duration >= 3600 || forceHours) {
|
if (duration >= 3600 || forceHours) {
|
||||||
return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
|
return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
|
||||||
|
|
|
@ -125,7 +125,7 @@ const movieFields = `
|
||||||
type
|
type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
covers: moviesCovers {
|
covers: moviesCovers(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
path
|
path
|
||||||
|
@ -260,7 +260,7 @@ const releaseTagsFragment = `
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const releasePosterFragment = `
|
const releasePosterFragment = `
|
||||||
poster: releasesPosterByReleaseId {
|
poster: releasesPoster {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
index
|
index
|
||||||
|
@ -335,7 +335,7 @@ const releasePhotosFragment = `
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const releaseTrailerFragment = `
|
const releaseTrailerFragment = `
|
||||||
trailer: releasesTrailerByReleaseId {
|
trailer: releasesTrailer {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
index
|
index
|
||||||
|
@ -349,7 +349,7 @@ const releaseTrailerFragment = `
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const releaseTeaserFragment = `
|
const releaseTeaserFragment = `
|
||||||
teaser: releasesTeaserByReleaseId {
|
teaser: releasesTeaser {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
index
|
index
|
||||||
|
@ -442,6 +442,29 @@ const releasesFragment = `
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const mediaFields = `
|
||||||
|
id
|
||||||
|
index
|
||||||
|
path
|
||||||
|
thumbnail
|
||||||
|
lazy
|
||||||
|
isS3
|
||||||
|
comment
|
||||||
|
sfw: sfwMedia {
|
||||||
|
id
|
||||||
|
thumbnail
|
||||||
|
lazy
|
||||||
|
path
|
||||||
|
comment
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const mediaFragment = `
|
||||||
|
media {
|
||||||
|
${mediaFields}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
const releaseFragment = `
|
const releaseFragment = `
|
||||||
release(id: $releaseId) {
|
release(id: $releaseId) {
|
||||||
id
|
id
|
||||||
|
@ -487,7 +510,7 @@ const releaseFragment = `
|
||||||
slug
|
slug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
poster: chaptersPosterByChapterId {
|
poster: chaptersPoster {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
index
|
index
|
||||||
|
@ -516,7 +539,7 @@ const releaseFragment = `
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
slug
|
slug
|
||||||
covers: moviesCovers {
|
covers: moviesCovers(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
index
|
index
|
||||||
|
@ -536,6 +559,19 @@ const releaseFragment = `
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
series: seriesScenesBySceneId {
|
||||||
|
serie {
|
||||||
|
id
|
||||||
|
title
|
||||||
|
slug
|
||||||
|
covers: seriesCoversBySerieId(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
|
||||||
|
${mediaFragment}
|
||||||
|
}
|
||||||
|
poster: seriesPosterBySerieId {
|
||||||
|
${mediaFragment}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
isFavorited
|
isFavorited
|
||||||
isStashed(includeFavorites: false)
|
isStashed(includeFavorites: false)
|
||||||
stashes: stashesScenesBySceneId(
|
stashes: stashesScenesBySceneId(
|
||||||
|
@ -624,6 +660,8 @@ export {
|
||||||
actorFields,
|
actorFields,
|
||||||
actorStashesFields,
|
actorStashesFields,
|
||||||
campaignsFragment,
|
campaignsFragment,
|
||||||
|
mediaFields,
|
||||||
|
mediaFragment,
|
||||||
movieFields,
|
movieFields,
|
||||||
releaseActorsFragment,
|
releaseActorsFragment,
|
||||||
releaseFields,
|
releaseFields,
|
||||||
|
|
|
@ -3,30 +3,6 @@ import dayjs from 'dayjs';
|
||||||
|
|
||||||
dayjs.extend(utc);
|
dayjs.extend(utc);
|
||||||
|
|
||||||
const dateRanges = {
|
|
||||||
latest: () => ({
|
|
||||||
after: '1900-01-01',
|
|
||||||
before: dayjs.utc().toDate(),
|
|
||||||
orderBy: ['DATE_DESC', 'CREATED_AT_DESC'],
|
|
||||||
}),
|
|
||||||
upcoming: () => ({
|
|
||||||
after: dayjs.utc().toDate(),
|
|
||||||
before: '2100-01-01',
|
|
||||||
orderBy: ['DATE_ASC', 'CREATED_AT_ASC'],
|
|
||||||
}),
|
|
||||||
new: () => ({
|
|
||||||
after: '1900-01-01 00:00:00',
|
|
||||||
before: '2100-01-01',
|
|
||||||
orderBy: ['CREATED_AT_DESC', 'DATE_ASC'],
|
|
||||||
}),
|
|
||||||
all: () => ({
|
|
||||||
after: '1900-01-01',
|
|
||||||
before: '2100-01-01',
|
|
||||||
orderBy: ['DATE_DESC', 'CREATED_AT_DESC'],
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
/* requires PostgreSQL 12.x> not available in production yet
|
|
||||||
const dateRanges = {
|
const dateRanges = {
|
||||||
latest: () => ({
|
latest: () => ({
|
||||||
after: '1900-01-01',
|
after: '1900-01-01',
|
||||||
|
@ -49,7 +25,6 @@ const dateRanges = {
|
||||||
orderBy: ['EFFECTIVE_DATE_DESC'],
|
orderBy: ['EFFECTIVE_DATE_DESC'],
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
*/
|
|
||||||
|
|
||||||
function getDateRange(range) {
|
function getDateRange(range) {
|
||||||
return (dateRanges[range] || dateRanges.all)();
|
return (dateRanges[range] || dateRanges.all)();
|
||||||
|
|
|
@ -109,6 +109,10 @@ async function init() {
|
||||||
document.title = 'traxxx';
|
document.title = 'traxxx';
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
beforeCreate() {
|
||||||
|
this.uid = uid;
|
||||||
|
uid += 1;
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
formatDate,
|
formatDate,
|
||||||
formatDuration,
|
formatDuration,
|
||||||
|
@ -117,10 +121,6 @@ async function init() {
|
||||||
getPath,
|
getPath,
|
||||||
getBgPath: (media, type) => `url(${getPath(media, type)})`,
|
getBgPath: (media, type) => `url(${getPath(media, type)})`,
|
||||||
},
|
},
|
||||||
beforeCreate() {
|
|
||||||
this.uid = uid;
|
|
||||||
uid += 1;
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
app.directive('tooltip', {
|
app.directive('tooltip', {
|
||||||
|
|
|
@ -4,6 +4,8 @@ import {
|
||||||
releaseFragment,
|
releaseFragment,
|
||||||
releaseFields,
|
releaseFields,
|
||||||
movieFields,
|
movieFields,
|
||||||
|
mediaFragment,
|
||||||
|
mediaFields,
|
||||||
} from '../fragments';
|
} from '../fragments';
|
||||||
import { curateRelease } from '../curate';
|
import { curateRelease } from '../curate';
|
||||||
import getDateRange from '../get-date-range';
|
import getDateRange from '../get-date-range';
|
||||||
|
@ -37,7 +39,7 @@ function initReleasesActions(store, router) {
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
releases: releases.map(release => curateRelease(release)),
|
releases: releases.map((release) => curateRelease(release)),
|
||||||
totalCount,
|
totalCount,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -99,7 +101,7 @@ function initReleasesActions(store, router) {
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
movies: movies.map(release => curateRelease(release)),
|
movies: movies.map((release) => curateRelease(release)),
|
||||||
totalCount,
|
totalCount,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -110,6 +112,8 @@ function initReleasesActions(store, router) {
|
||||||
$query: String!
|
$query: String!
|
||||||
$limit:Int = 20
|
$limit:Int = 20
|
||||||
$offset:Int = 0
|
$offset:Int = 0
|
||||||
|
$hasAuth: Boolean!
|
||||||
|
$userId: Int
|
||||||
) {
|
) {
|
||||||
connection: searchMoviesConnection(
|
connection: searchMoviesConnection(
|
||||||
query: $query
|
query: $query
|
||||||
|
@ -126,6 +130,8 @@ function initReleasesActions(store, router) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`, {
|
`, {
|
||||||
|
hasAuth: !!store.state.auth.user,
|
||||||
|
userId: store.state.auth.user?.id,
|
||||||
query,
|
query,
|
||||||
limit,
|
limit,
|
||||||
offset: Math.max(0, (pageNumber - 1)) * limit,
|
offset: Math.max(0, (pageNumber - 1)) * limit,
|
||||||
|
@ -137,16 +143,16 @@ function initReleasesActions(store, router) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchMovieById({ _commit }, movieId) {
|
async function fetchCollectionById({ _commit }, movieId, type = 'movie') {
|
||||||
// const release = await get(`/releases/${releaseId}`);
|
// const release = await get(`/releases/${releaseId}`);
|
||||||
|
|
||||||
const { movie } = await graphql(`
|
const result = await graphql(`
|
||||||
query Movie(
|
query Movie(
|
||||||
$movieId: Int!
|
$movieId: Int!
|
||||||
$hasAuth: Boolean!
|
$hasAuth: Boolean!
|
||||||
$userId: Int
|
$userId: Int
|
||||||
) {
|
) {
|
||||||
movie(id: $movieId) {
|
${type}(id: $movieId) {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
description
|
description
|
||||||
|
@ -178,7 +184,7 @@ function initReleasesActions(store, router) {
|
||||||
isS3
|
isS3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
poster: moviesPosterByMovieId {
|
poster: ${type === 'series' ? 'seriesPosterBySerieId' : 'moviesPoster'} {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
path
|
path
|
||||||
|
@ -191,7 +197,7 @@ function initReleasesActions(store, router) {
|
||||||
isS3
|
isS3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
covers: moviesCovers {
|
covers: ${type === 'series' ? 'seriesCoversBySerieId' : 'moviesCovers'}(orderBy: MEDIA_BY_MEDIA_ID__INDEX_ASC) {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
path
|
path
|
||||||
|
@ -204,14 +210,14 @@ function initReleasesActions(store, router) {
|
||||||
isS3
|
isS3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
trailer: moviesTrailerByMovieId {
|
trailer: ${type === 'series' ? 'seriesTrailerBySerieId' : 'moviesTrailer'} {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
path
|
path
|
||||||
isS3
|
isS3
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
scenes: moviesScenes {
|
scenes: ${type === 'series' ? 'seriesScenesBySerieId' : 'moviesScenes'} {
|
||||||
scene {
|
scene {
|
||||||
${releaseFields}
|
${releaseFields}
|
||||||
}
|
}
|
||||||
|
@ -221,25 +227,11 @@ function initReleasesActions(store, router) {
|
||||||
slug
|
slug
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
photos {
|
photos: ${type === 'series' ? 'seriesPhotosBySerieId' : 'moviesPhotos'} {
|
||||||
id
|
${mediaFragment}
|
||||||
index
|
}
|
||||||
path
|
scenesPhotos {
|
||||||
thumbnail
|
${mediaFields}
|
||||||
lazy
|
|
||||||
width
|
|
||||||
height
|
|
||||||
thumbnailWidth
|
|
||||||
thumbnailHeight
|
|
||||||
isS3
|
|
||||||
comment
|
|
||||||
sfw: sfwMedia {
|
|
||||||
id
|
|
||||||
thumbnail
|
|
||||||
lazy
|
|
||||||
path
|
|
||||||
comment
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
entity {
|
entity {
|
||||||
id
|
id
|
||||||
|
@ -255,7 +247,7 @@ function initReleasesActions(store, router) {
|
||||||
hasLogo
|
hasLogo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stashes: stashesMovies(
|
stashes: ${type === 'series' ? 'stashesSeriesBySerieId' : 'stashesMovies'}(
|
||||||
filter: {
|
filter: {
|
||||||
stash: {
|
stash: {
|
||||||
userId: {
|
userId: {
|
||||||
|
@ -279,12 +271,20 @@ function initReleasesActions(store, router) {
|
||||||
userId: store.state.auth.user?.id,
|
userId: store.state.auth.user?.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!movie) {
|
if (!result[type]) {
|
||||||
router.replace('/not-found');
|
router.replace('/not-found');
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return curateRelease(movie);
|
return curateRelease(result[type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchMovieById(context, movieId) {
|
||||||
|
return fetchCollectionById(context, movieId, 'movie');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchSerieById(context, serieId) {
|
||||||
|
return fetchCollectionById(context, serieId, 'series');
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -292,6 +292,7 @@ function initReleasesActions(store, router) {
|
||||||
fetchReleaseById,
|
fetchReleaseById,
|
||||||
fetchMovies,
|
fetchMovies,
|
||||||
fetchMovieById,
|
fetchMovieById,
|
||||||
|
fetchSerieById,
|
||||||
searchMovies,
|
searchMovies,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,10 +71,15 @@ const routes = [
|
||||||
component: Release,
|
component: Release,
|
||||||
name: 'movie',
|
name: 'movie',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/serie/:releaseId/:releaseSlug?',
|
||||||
|
component: Release,
|
||||||
|
name: 'serie',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/actor/:actorId/:actorSlug',
|
path: '/actor/:actorId/:actorSlug',
|
||||||
name: 'actor',
|
name: 'actor',
|
||||||
redirect: from => ({
|
redirect: (from) => ({
|
||||||
name: 'actorRange',
|
name: 'actorRange',
|
||||||
params: {
|
params: {
|
||||||
...from.params,
|
...from.params,
|
||||||
|
@ -91,7 +96,7 @@ const routes = [
|
||||||
{
|
{
|
||||||
path: '/director/:actorId/:actorSlug',
|
path: '/director/:actorId/:actorSlug',
|
||||||
name: 'director',
|
name: 'director',
|
||||||
redirect: from => ({
|
redirect: (from) => ({
|
||||||
name: 'directorRange',
|
name: 'directorRange',
|
||||||
params: {
|
params: {
|
||||||
...from.params,
|
...from.params,
|
||||||
|
@ -107,7 +112,7 @@ const routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/channel/:entitySlug',
|
path: '/channel/:entitySlug',
|
||||||
redirect: from => ({
|
redirect: (from) => ({
|
||||||
name: 'channel',
|
name: 'channel',
|
||||||
params: {
|
params: {
|
||||||
...from.params,
|
...from.params,
|
||||||
|
@ -123,7 +128,7 @@ const routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/network/:entitySlug',
|
path: '/network/:entitySlug',
|
||||||
redirect: from => ({
|
redirect: (from) => ({
|
||||||
name: 'network',
|
name: 'network',
|
||||||
params: {
|
params: {
|
||||||
...from.params,
|
...from.params,
|
||||||
|
@ -139,7 +144,7 @@ const routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/studio/:entitySlug',
|
path: '/studio/:entitySlug',
|
||||||
redirect: from => ({
|
redirect: (from) => ({
|
||||||
name: 'studio',
|
name: 'studio',
|
||||||
params: {
|
params: {
|
||||||
...from.params,
|
...from.params,
|
||||||
|
@ -155,7 +160,7 @@ const routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/tag/:tagSlug',
|
path: '/tag/:tagSlug',
|
||||||
redirect: from => ({
|
redirect: (from) => ({
|
||||||
name: 'tag',
|
name: 'tag',
|
||||||
params: {
|
params: {
|
||||||
...from.params,
|
...from.params,
|
||||||
|
@ -171,7 +176,7 @@ const routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/actors',
|
path: '/actors',
|
||||||
redirect: from => ({
|
redirect: (from) => ({
|
||||||
name: 'actors',
|
name: 'actors',
|
||||||
params: {
|
params: {
|
||||||
...from.params,
|
...from.params,
|
||||||
|
@ -229,7 +234,7 @@ const routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/stash/:stashId/:stashSlug',
|
path: '/stash/:stashId/:stashSlug',
|
||||||
redirect: from => ({
|
redirect: (from) => ({
|
||||||
name: 'stash',
|
name: 'stash',
|
||||||
params: {
|
params: {
|
||||||
...from.params,
|
...from.params,
|
||||||
|
|
|
@ -35,7 +35,7 @@ function initTagsActions(store, _router) {
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
}
|
}
|
||||||
poster: tagsPosterByTagId {
|
poster: tagsPoster {
|
||||||
media {
|
media {
|
||||||
id
|
id
|
||||||
thumbnail
|
thumbnail
|
||||||
|
@ -188,14 +188,14 @@ function initTagsActions(store, _router) {
|
||||||
before,
|
before,
|
||||||
orderBy,
|
orderBy,
|
||||||
offset: Math.max(0, (pageNumber - 1)) * limit,
|
offset: Math.max(0, (pageNumber - 1)) * limit,
|
||||||
exclude: store.state.ui.tagFilter.filter(tagFilter => tagFilter !== tagSlug),
|
exclude: store.state.ui.tagFilter.filter((tagFilter) => tagFilter !== tagSlug),
|
||||||
hasAuth: !!store.state.auth.user,
|
hasAuth: !!store.state.auth.user,
|
||||||
userId: store.state.auth.user?.id,
|
userId: store.state.auth.user?.id,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tag: curateTag(tagBySlug, null, curateRelease),
|
tag: curateTag(tagBySlug, null, curateRelease),
|
||||||
releases: tagBySlug.scenesConnection.releases.map(release => curateRelease(release)),
|
releases: tagBySlug.scenesConnection.releases.map((release) => curateRelease(release)),
|
||||||
totalCount: tagBySlug.scenesConnection.totalCount,
|
totalCount: tagBySlug.scenesConnection.totalCount,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -210,15 +210,21 @@ function initTagsActions(store, _router) {
|
||||||
query Tags(
|
query Tags(
|
||||||
$slugs: [String!] = [],
|
$slugs: [String!] = [],
|
||||||
$limit: Int = 100
|
$limit: Int = 100
|
||||||
|
$exclude: [String!]
|
||||||
) {
|
) {
|
||||||
tags(
|
tags(
|
||||||
filter: { slug: { in: $slugs } },
|
filter: {
|
||||||
|
slug: {
|
||||||
|
in: $slugs
|
||||||
|
notIn: $exclude
|
||||||
|
}
|
||||||
|
},
|
||||||
first: $limit
|
first: $limit
|
||||||
) {
|
) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
poster: tagsPosterByTagId {
|
poster: tagsPoster {
|
||||||
media {
|
media {
|
||||||
thumbnail
|
thumbnail
|
||||||
comment
|
comment
|
||||||
|
@ -257,9 +263,10 @@ function initTagsActions(store, _router) {
|
||||||
`, {
|
`, {
|
||||||
slugs,
|
slugs,
|
||||||
limit,
|
limit,
|
||||||
|
exclude: store.state.ui.tagFilter,
|
||||||
});
|
});
|
||||||
|
|
||||||
return tags.map(tag => curateTag(tag, store.state.ui.sfw));
|
return tags.map((tag) => curateTag(tag, store.state.ui.sfw));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function searchTags({ _commit }, {
|
async function searchTags({ _commit }, {
|
||||||
|
@ -283,7 +290,7 @@ function initTagsActions(store, _router) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
poster: tagsPosterByTagId {
|
poster: tagsPoster {
|
||||||
media {
|
media {
|
||||||
thumbnail
|
thumbnail
|
||||||
comment
|
comment
|
||||||
|
@ -325,7 +332,7 @@ function initTagsActions(store, _router) {
|
||||||
minLength,
|
minLength,
|
||||||
});
|
});
|
||||||
|
|
||||||
return tags.map(tag => curateTag(tag, store.state.ui.sfw));
|
return tags.map((tag) => curateTag(tag, store.state.ui.sfw));
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchTagReleases({ _commit }, tagId) {
|
async function fetchTagReleases({ _commit }, tagId) {
|
||||||
|
|
|
@ -70,7 +70,7 @@ function initUiActions(store, _router) {
|
||||||
slug
|
slug
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entity: alertsEntityByAlertId {
|
entity: alertsEntity {
|
||||||
entity {
|
entity {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
@ -103,7 +103,7 @@ function initUiActions(store, _router) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const curatedNotifications = notifications.nodes.map(notification => curateNotification(notification));
|
const curatedNotifications = notifications.nodes.map((notification) => curateNotification(notification));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
notifications: curatedNotifications,
|
notifications: curatedNotifications,
|
||||||
|
@ -222,8 +222,8 @@ function initUiActions(store, _router) {
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
releases: res?.results.map(result => curateRelease(result.release)) || [],
|
releases: res?.results.map((result) => curateRelease(result.release)) || [],
|
||||||
actors: res?.actors.map(actor => curateActor(actor)) || [],
|
actors: res?.actors.map((actor) => curateActor(actor)) || [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ async function initUiObservers(store, _router) {
|
||||||
|
|
||||||
body.classList.add(store.state.ui.theme);
|
body.classList.add(store.state.ui.theme);
|
||||||
|
|
||||||
store.watch(state => state.ui.theme, (newTheme, oldTheme) => {
|
store.watch((state) => state.ui.theme, (newTheme, oldTheme) => {
|
||||||
body.classList.add(newTheme);
|
body.classList.add(newTheme);
|
||||||
body.classList.remove(oldTheme);
|
body.classList.remove(oldTheme);
|
||||||
});
|
});
|
||||||
|
|
|
@ -90,7 +90,7 @@ function initUsersActions(store, _router) {
|
||||||
${actorFields}
|
${actorFields}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
entity: alertsEntityByAlertId {
|
entity: alertsEntity {
|
||||||
entity {
|
entity {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
|
|
|
@ -66,10 +66,7 @@ module.exports = {
|
||||||
// pornpros
|
// pornpros
|
||||||
'milfhumiliation',
|
'milfhumiliation',
|
||||||
'humiliated',
|
'humiliated',
|
||||||
'flexiblepositions',
|
|
||||||
'publicviolations',
|
|
||||||
'amateurviolations',
|
'amateurviolations',
|
||||||
'squirtdisgrace',
|
|
||||||
'cumdisgrace',
|
'cumdisgrace',
|
||||||
'webcamhackers',
|
'webcamhackers',
|
||||||
'collegeteens',
|
'collegeteens',
|
||||||
|
@ -301,10 +298,6 @@ module.exports = {
|
||||||
interval: 1000,
|
interval: 1000,
|
||||||
concurrency: 1,
|
concurrency: 1,
|
||||||
},
|
},
|
||||||
'www.realitykings.com': {
|
|
||||||
interval: 1000,
|
|
||||||
concurrency: 1,
|
|
||||||
},
|
|
||||||
'westcoastproductions.com': {
|
'westcoastproductions.com': {
|
||||||
interval: 100,
|
interval: 100,
|
||||||
concurrency: 1,
|
concurrency: 1,
|
||||||
|
@ -316,8 +309,15 @@ module.exports = {
|
||||||
},
|
},
|
||||||
fetchAfter: [1, 'week'],
|
fetchAfter: [1, 'week'],
|
||||||
missingDateLimit: 3,
|
missingDateLimit: 3,
|
||||||
|
memorySampling: {
|
||||||
|
enabled: false,
|
||||||
|
sampleDuration: 300000, // 5 minutes
|
||||||
|
snapshotIntervals: [],
|
||||||
|
},
|
||||||
media: {
|
media: {
|
||||||
path: './media',
|
path: './media',
|
||||||
|
maxSize: 1000,
|
||||||
|
quality: 80,
|
||||||
thumbnailSize: 320, // width for 16:9 will be exactly 576px
|
thumbnailSize: 320, // width for 16:9 will be exactly 576px
|
||||||
thumbnailQuality: 100,
|
thumbnailQuality: 100,
|
||||||
lazySize: 90,
|
lazySize: 90,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
const config = require('config');
|
const config = require('config');
|
||||||
|
|
||||||
exports.up = knex => Promise.resolve()
|
exports.up = (knex) => Promise.resolve()
|
||||||
.then(() => knex.schema.createTable('countries', (table) => {
|
.then(() => knex.schema.createTable('countries', (table) => {
|
||||||
table.text('alpha2', 2)
|
table.text('alpha2', 2)
|
||||||
.unique()
|
.unique()
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
exports.up = async (knex) => knex.raw(`
|
||||||
|
CREATE FUNCTION entities_scenes(entity entities) RETURNS SETOF releases AS $$
|
||||||
|
WITH RECURSIVE children AS (
|
||||||
|
SELECT entities.id
|
||||||
|
FROM entities
|
||||||
|
WHERE entities.id = entity.id
|
||||||
|
|
||||||
|
UNION ALL
|
||||||
|
|
||||||
|
SELECT entities.id
|
||||||
|
FROM entities
|
||||||
|
INNER JOIN children ON children.id = entities.parent_id
|
||||||
|
)
|
||||||
|
|
||||||
|
SELECT releases FROM releases
|
||||||
|
INNER JOIN children ON children.id = releases.entity_id
|
||||||
|
|
||||||
|
UNION
|
||||||
|
|
||||||
|
SELECT releases FROM releases
|
||||||
|
INNER JOIN children ON children.id = releases.studio_id;
|
||||||
|
$$ LANGUAGE SQL STABLE;
|
||||||
|
|
||||||
|
COMMENT ON FUNCTION entities_scenes IS E'@sortable';
|
||||||
|
`);
|
||||||
|
|
||||||
|
exports.down = async (knex) => knex.raw(`
|
||||||
|
DROP FUNCTION IF EXISTS entities_scenes;
|
||||||
|
`);
|
|
@ -0,0 +1,15 @@
|
||||||
|
exports.up = async (knex) => Promise.resolve()
|
||||||
|
.then(() => knex.schema.alterTable('releases_tags', (table) => {
|
||||||
|
table.index('release_id');
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.alterTable('movies_scenes', (table) => {
|
||||||
|
table.index('scene_id');
|
||||||
|
}));
|
||||||
|
|
||||||
|
exports.down = async (knex) => Promise.resolve()
|
||||||
|
.then(() => knex.schema.alterTable('releases_tags', (table) => {
|
||||||
|
table.dropIndex('release_id');
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.alterTable('movies_scenes', (table) => {
|
||||||
|
table.dropIndex('scene_id');
|
||||||
|
}));
|
|
@ -0,0 +1,11 @@
|
||||||
|
exports.up = async (knex) => knex.raw(`
|
||||||
|
CREATE OR REPLACE FUNCTION entities_scene_total(entity entities) RETURNS bigint AS $$
|
||||||
|
SELECT COUNT(id)
|
||||||
|
FROM releases
|
||||||
|
WHERE releases.entity_id = entity.id;
|
||||||
|
$$ LANGUAGE SQL STABLE;
|
||||||
|
`);
|
||||||
|
|
||||||
|
exports.down = async (knex) => knex.raw(`
|
||||||
|
DROP FUNCTION IF EXISTS entities_scene_total;
|
||||||
|
`);
|
|
@ -0,0 +1,23 @@
|
||||||
|
exports.up = async (knex) => knex.raw(`
|
||||||
|
CREATE FUNCTION entities_scene_tags(entity entities, selectable_tags text[]) RETURNS SETOF tags AS $$
|
||||||
|
SELECT tags.*
|
||||||
|
FROM releases
|
||||||
|
LEFT JOIN
|
||||||
|
releases_tags ON releases_tags.release_id = releases.id
|
||||||
|
LEFT JOIN
|
||||||
|
tags ON tags.id = releases_tags.tag_id
|
||||||
|
WHERE
|
||||||
|
releases.entity_id = entity.id
|
||||||
|
AND
|
||||||
|
CASE WHEN array_length(selectable_tags, 1) IS NOT NULL
|
||||||
|
THEN tags.slug = ANY(selectable_tags)
|
||||||
|
ELSE true
|
||||||
|
END
|
||||||
|
GROUP BY tags.id
|
||||||
|
ORDER BY tags.name;
|
||||||
|
$$ LANGUAGE SQL STABLE;
|
||||||
|
`);
|
||||||
|
|
||||||
|
exports.down = async (knex) => knex.raw(`
|
||||||
|
DROP FUNCTION IF EXISTS entities_scene_tags;
|
||||||
|
`);
|
|
@ -0,0 +1,215 @@
|
||||||
|
const config = require('config');
|
||||||
|
|
||||||
|
exports.up = async (knex) => Promise.resolve()
|
||||||
|
.then(() => knex.schema.createTable('series', (table) => {
|
||||||
|
table.increments('id', 16);
|
||||||
|
|
||||||
|
table.integer('entity_id', 12)
|
||||||
|
.references('id')
|
||||||
|
.inTable('entities')
|
||||||
|
.notNullable();
|
||||||
|
|
||||||
|
table.integer('studio_id', 12)
|
||||||
|
.references('id')
|
||||||
|
.inTable('entities');
|
||||||
|
|
||||||
|
table.text('entry_id');
|
||||||
|
table.unique(['entity_id', 'entry_id']);
|
||||||
|
|
||||||
|
table.text('url', 1000);
|
||||||
|
table.text('title');
|
||||||
|
table.text('slug');
|
||||||
|
|
||||||
|
table.timestamp('date');
|
||||||
|
table.index('date');
|
||||||
|
|
||||||
|
table.enum('date_precision', ['year', 'month', 'week', 'day', 'hour', 'minute', 'second'])
|
||||||
|
.defaultTo('day');
|
||||||
|
|
||||||
|
table.text('description');
|
||||||
|
|
||||||
|
table.boolean('deep');
|
||||||
|
table.text('deep_url', 1000);
|
||||||
|
|
||||||
|
table.text('comment');
|
||||||
|
|
||||||
|
table.integer('created_batch_id', 12)
|
||||||
|
.references('id')
|
||||||
|
.inTable('batches')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.integer('updated_batch_id', 12)
|
||||||
|
.references('id')
|
||||||
|
.inTable('batches')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.datetime('created_at')
|
||||||
|
.defaultTo(knex.fn.now());
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_scenes', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.integer('scene_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('releases')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.unique(['serie_id', 'scene_id']);
|
||||||
|
|
||||||
|
table.datetime('created_at')
|
||||||
|
.defaultTo(knex.fn.now());
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_trailers', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.unique()
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.text('media_id', 21)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('media');
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_posters', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.text('media_id', 21)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('media')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.unique('serie_id');
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_covers', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.text('media_id', 21)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('media');
|
||||||
|
|
||||||
|
table.unique(['serie_id', 'media_id']);
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_search', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('stashes_series', (table) => {
|
||||||
|
table.integer('stash_id')
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('stashes')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.integer('serie_id')
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.unique(['stash_id', 'serie_id']);
|
||||||
|
|
||||||
|
table.string('comment');
|
||||||
|
|
||||||
|
table.datetime('created_at')
|
||||||
|
.notNullable()
|
||||||
|
.defaultTo(knex.fn.now());
|
||||||
|
}))
|
||||||
|
.then(() => knex.raw(`
|
||||||
|
ALTER TABLE series_search ADD COLUMN document tsvector;
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX series_search_unique ON series_search (serie_id);
|
||||||
|
CREATE INDEX series_search_index ON series_search USING GIN (document);
|
||||||
|
|
||||||
|
CREATE FUNCTION series_actors(serie series) RETURNS SETOF actors AS $$
|
||||||
|
SELECT actors.*
|
||||||
|
FROM series_scenes
|
||||||
|
LEFT JOIN
|
||||||
|
releases ON releases.id = series_scenes.scene_id
|
||||||
|
LEFT JOIN
|
||||||
|
releases_actors ON releases_actors.release_id = releases.id
|
||||||
|
LEFT JOIN
|
||||||
|
actors ON actors.id = releases_actors.actor_id
|
||||||
|
WHERE series_scenes.serie_id = serie.id
|
||||||
|
AND actors.id IS NOT NULL
|
||||||
|
GROUP BY actors.id
|
||||||
|
ORDER BY actors.name, actors.gender
|
||||||
|
$$ LANGUAGE SQL STABLE;
|
||||||
|
|
||||||
|
CREATE FUNCTION series_tags(serie series) RETURNS SETOF tags AS $$
|
||||||
|
SELECT tags.*
|
||||||
|
FROM series_scenes
|
||||||
|
LEFT JOIN
|
||||||
|
releases ON releases.id = series_scenes.scene_id
|
||||||
|
LEFT JOIN
|
||||||
|
releases_tags ON releases_tags.release_id = releases.id
|
||||||
|
LEFT JOIN
|
||||||
|
tags ON tags.id = releases_tags.tag_id
|
||||||
|
WHERE series_scenes.serie_id = serie.id
|
||||||
|
AND tags.id IS NOT NULL
|
||||||
|
GROUP BY tags.id
|
||||||
|
ORDER BY tags.priority DESC
|
||||||
|
$$ LANGUAGE SQL STABLE;
|
||||||
|
|
||||||
|
CREATE FUNCTION series_photos(serie series) RETURNS SETOF media AS $$
|
||||||
|
SELECT media.*
|
||||||
|
FROM series_scenes
|
||||||
|
LEFT JOIN
|
||||||
|
releases ON releases.id = series_scenes.scene_id
|
||||||
|
INNER JOIN
|
||||||
|
releases_photos ON releases_photos.release_id = releases.id
|
||||||
|
LEFT JOIN
|
||||||
|
media ON media.id = releases_photos.media_id
|
||||||
|
WHERE series_scenes.serie_id = serie.id
|
||||||
|
GROUP BY media.id
|
||||||
|
ORDER BY media.index ASC
|
||||||
|
$$ LANGUAGE SQL STABLE;
|
||||||
|
|
||||||
|
GRANT ALL ON ALL TABLES IN SCHEMA public TO :visitor;
|
||||||
|
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO :visitor;
|
||||||
|
|
||||||
|
ALTER TABLE stashes_series ENABLE ROW LEVEL SECURITY;
|
||||||
|
|
||||||
|
CREATE POLICY stashes_policy ON stashes_series
|
||||||
|
USING (EXISTS (
|
||||||
|
SELECT *
|
||||||
|
FROM stashes
|
||||||
|
WHERE stashes.id = stashes_series.stash_id
|
||||||
|
AND (stashes.user_id = current_user_id() OR stashes.public)
|
||||||
|
));
|
||||||
|
`, {
|
||||||
|
visitor: knex.raw(config.database.query.user),
|
||||||
|
}));
|
||||||
|
|
||||||
|
exports.down = async (knex) => Promise.resolve()
|
||||||
|
.then(() => knex.raw(`
|
||||||
|
DROP FUNCTION IF EXISTS series_actors;
|
||||||
|
DROP FUNCTION IF EXISTS series_tags;
|
||||||
|
DROP FUNCTION IF EXISTS series_photos;
|
||||||
|
|
||||||
|
DROP TABLE IF EXISTS stashes_series CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_scenes CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_trailers CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_posters CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_covers CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_search CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series CASCADE;
|
||||||
|
`));
|
|
@ -0,0 +1,49 @@
|
||||||
|
const config = require('config');
|
||||||
|
|
||||||
|
exports.up = async (knex) => Promise.resolve()
|
||||||
|
.then(() => knex.raw(`
|
||||||
|
ALTER FUNCTION movies_photos(movie movies) RENAME TO movies_scenes_photos;
|
||||||
|
ALTER FUNCTION series_photos(serie series) RENAME TO series_scenes_photos;
|
||||||
|
`))
|
||||||
|
.then(() => knex.schema.createTable('movies_photos', (table) => {
|
||||||
|
table.integer('movie_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('movies')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.text('media_id', 21)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('media');
|
||||||
|
|
||||||
|
table.unique(['movie_id', 'media_id']);
|
||||||
|
}))
|
||||||
|
.then(() => knex.schema.createTable('series_photos', (table) => {
|
||||||
|
table.integer('serie_id', 16)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('series')
|
||||||
|
.onDelete('cascade');
|
||||||
|
|
||||||
|
table.text('media_id', 21)
|
||||||
|
.notNullable()
|
||||||
|
.references('id')
|
||||||
|
.inTable('media');
|
||||||
|
|
||||||
|
table.unique(['serie_id', 'media_id']);
|
||||||
|
}))
|
||||||
|
.then(() => knex.raw(`
|
||||||
|
GRANT ALL ON ALL TABLES IN SCHEMA public TO :visitor;
|
||||||
|
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO :visitor;
|
||||||
|
`, {
|
||||||
|
visitor: knex.raw(config.database.query.user),
|
||||||
|
}));
|
||||||
|
|
||||||
|
exports.down = async (knex) => knex.raw(`
|
||||||
|
DROP TABLE IF EXISTS movies_photos CASCADE;
|
||||||
|
DROP TABLE IF EXISTS series_photos CASCADE;
|
||||||
|
|
||||||
|
ALTER FUNCTION movies_scenes_photos(movie movies) RENAME TO movies_photos;
|
||||||
|
ALTER FUNCTION series_scenes_photos(serie series) RENAME TO series_photos;
|
||||||
|
`);
|
86
package.json
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"name": "traxxx",
|
"name": "traxxx",
|
||||||
"version": "1.200.2",
|
"version": "1.212.9",
|
||||||
"description": "All the latest porn releases in one place",
|
"description": "All the latest porn releases in one place",
|
||||||
"main": "src/app.js",
|
"main": "src/app.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node -r source-map-support/register src/init.js",
|
"start": "node -r source-map-support/register src/init.js",
|
||||||
"webpack": "webpack --env=production --mode=production",
|
"webpack": "webpack --env=production --mode=production",
|
||||||
"webpack-dev": "webpack --env=development --mode=development",
|
"webpack-dev": "webpack --env=development --mode=development",
|
||||||
"webpack-watch": "webpack --progress --colors --watch --env=development --mode=development",
|
"webpack-watch": "webpack --progress --color --watch --env=development --mode=development",
|
||||||
"babel": "babel src --source-maps -d dist",
|
"babel": "babel src --source-maps -d dist",
|
||||||
"babel-watch": "babel src -w --source-maps -d dist",
|
"babel-watch": "babel src -w --source-maps -d dist",
|
||||||
"build": "babel src --source-maps -d dist && webpack --env=production --mode=production",
|
"build": "babel src --source-maps -d dist && webpack --env=production --mode=production",
|
||||||
|
@ -40,38 +40,37 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/cli": "^7.12.10",
|
"@babel/cli": "^7.12.10",
|
||||||
"@babel/core": "^7.8.4",
|
"@babel/core": "^7.8.4",
|
||||||
|
"@babel/eslint-parser": "^7.16.0",
|
||||||
"@babel/plugin-proposal-optional-chaining": "^7.8.3",
|
"@babel/plugin-proposal-optional-chaining": "^7.8.3",
|
||||||
"@babel/preset-env": "^7.8.4",
|
"@babel/preset-env": "^7.8.4",
|
||||||
"@babel/register": "^7.8.3",
|
"@babel/register": "^7.8.3",
|
||||||
"@vue/compiler-sfc": "^3.0.4",
|
"autoprefixer": "^10.4.0",
|
||||||
"autoprefixer": "^9.7.4",
|
|
||||||
"babel-eslint": "^10.1.0",
|
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.0.6",
|
||||||
"babel-preset-airbnb": "^3.3.2",
|
"babel-preset-airbnb": "^5.0.0",
|
||||||
"css-loader": "^5.0.1",
|
"css-loader": "^6.5.0",
|
||||||
"eslint": "^7.20.0",
|
"eslint": "^8.1.0",
|
||||||
"eslint-config-airbnb": "^17.1.1",
|
"eslint-config-airbnb": "^18.2.1",
|
||||||
"eslint-config-airbnb-base": "^13.2.0",
|
"eslint-config-airbnb-base": "^14.2.1",
|
||||||
"eslint-plugin-import": "^2.20.1",
|
"eslint-plugin-import": "^2.20.1",
|
||||||
"eslint-plugin-jsx-a11y": "^6.2.3",
|
"eslint-plugin-jsx-a11y": "^6.2.3",
|
||||||
"eslint-plugin-react": "^7.18.3",
|
"eslint-plugin-react": "^7.18.3",
|
||||||
"eslint-plugin-vue": "^6.2.1",
|
"eslint-plugin-vue": "^8.0.3",
|
||||||
"eslint-watch": "^4.0.2",
|
"eslint-watch": "^7.0.0",
|
||||||
"eslint-webpack-plugin": "^2.5.2",
|
"eslint-webpack-plugin": "^3.1.0",
|
||||||
"mini-css-extract-plugin": "^1.3.3",
|
"mini-css-extract-plugin": "^2.4.3",
|
||||||
"node-sass": "^5.0.0",
|
"node-sass": "^6.0.1",
|
||||||
"postcss-loader": "^3.0.0",
|
"postcss-loader": "^6.2.0",
|
||||||
"raw-loader": "^4.0.2",
|
"raw-loader": "^4.0.2",
|
||||||
"sass-loader": "^11.0.1",
|
"sass-loader": "^12.3.0",
|
||||||
"style-loader": "^0.23.1",
|
"style-loader": "^3.3.1",
|
||||||
"vue-loader": "^16.1.2",
|
"vue-loader": "^16.8.2",
|
||||||
"webpack": "^5.11.0",
|
"webpack": "^5.11.0",
|
||||||
"webpack-cli": "^3.3.11"
|
"webpack-cli": "^4.9.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@casl/ability": "^5.2.2",
|
"@casl/ability": "^5.2.2",
|
||||||
"@graphile-contrib/pg-order-by-related": "^1.0.0-beta.6",
|
"@graphile-contrib/pg-order-by-related": "^1.0.0-beta.6",
|
||||||
"@graphile-contrib/pg-simplify-inflector": "^5.0.0-beta.1",
|
"@graphile-contrib/pg-simplify-inflector": "^6.1.0",
|
||||||
"acorn": "^8.0.4",
|
"acorn": "^8.0.4",
|
||||||
"array-equal": "^1.0.0",
|
"array-equal": "^1.0.0",
|
||||||
"aws-sdk": "^2.847.0",
|
"aws-sdk": "^2.847.0",
|
||||||
|
@ -88,63 +87,62 @@
|
||||||
"cloudscraper": "^4.6.0",
|
"cloudscraper": "^4.6.0",
|
||||||
"config": "^3.2.5",
|
"config": "^3.2.5",
|
||||||
"connect-session-knex": "^2.0.0",
|
"connect-session-knex": "^2.0.0",
|
||||||
"convert": "^1.6.2",
|
"convert": "^4.2.4",
|
||||||
"cookie": "^0.4.0",
|
"cookie": "^0.4.0",
|
||||||
"csv-stringify": "^5.3.6",
|
"csv-stringify": "^5.3.6",
|
||||||
"dayjs": "^1.8.21",
|
"dayjs": "^1.8.21",
|
||||||
"dompurify": "^2.0.11",
|
"dompurify": "^2.0.11",
|
||||||
"ejs": "^3.0.1",
|
"ejs": "^3.0.1",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
"express-promise-router": "^3.0.3",
|
"express-promise-router": "^4.1.0",
|
||||||
"express-react-views": "^0.11.0",
|
"express-react-views": "^0.11.0",
|
||||||
"express-session": "^1.17.1",
|
"express-session": "^1.17.1",
|
||||||
"face-api.js": "^0.22.2",
|
"face-api.js": "^0.22.2",
|
||||||
"faker": "^5.1.0",
|
"faker": "^5.1.0",
|
||||||
"file-type": "^14.1.4",
|
"file-type": "^16.5.3",
|
||||||
"fluent-ffmpeg": "^2.1.2",
|
"fluent-ffmpeg": "^2.1.2",
|
||||||
"fs-extra": "^7.0.1",
|
"fs-extra": "^10.0.0",
|
||||||
"graphile-utils": "^4.5.6",
|
"graphile-utils": "^4.12.2",
|
||||||
"graphql": "^14.6.0",
|
"graphql": "^15.4.0",
|
||||||
"html-entities": "^2.3.2",
|
"html-entities": "^2.3.2",
|
||||||
"iconv-lite": "^0.5.1",
|
"iconv-lite": "^0.6.3",
|
||||||
"inquirer": "^7.3.3",
|
"inquirer": "^8.2.0",
|
||||||
"inspector-api": "^1.4.2",
|
"inspector-api": "^1.4.2",
|
||||||
"jsdom": "^16.3.0",
|
"jsdom": "^18.0.0",
|
||||||
"knex": "^0.21.13",
|
"knex": "^0.95.12",
|
||||||
"knex-migrate": "^1.7.4",
|
"knex-migrate": "^1.7.4",
|
||||||
"longjohn": "^0.2.12",
|
"longjohn": "^0.2.12",
|
||||||
"mime": "^2.4.4",
|
"mime": "^2.4.4",
|
||||||
"mitt": "^2.1.0",
|
"mitt": "^3.0.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"nanoid": "^2.1.11",
|
"nanoid": "^3.1.30",
|
||||||
|
"node-fetch": "^2.6.7",
|
||||||
"object-merge-advanced": "^12.1.0",
|
"object-merge-advanced": "^12.1.0",
|
||||||
"object.omit": "^3.0.0",
|
"object.omit": "^3.0.0",
|
||||||
"opn": "^5.5.0",
|
"opn": "^6.0.0",
|
||||||
"pg": "^8.5.1",
|
"pg": "^8.5.1",
|
||||||
"postgraphile": "^4.10.0",
|
"postgraphile": "^4.10.0",
|
||||||
"postgraphile-plugin-connection-filter": "^1.1.3",
|
"postgraphile-plugin-connection-filter": "^2.2.2",
|
||||||
"promise-task-queue": "^1.2.0",
|
"promise-task-queue": "^1.2.0",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^16.13.0",
|
"sharp": "^0.29.2",
|
||||||
"react-dom": "^16.13.0",
|
|
||||||
"sharp": "^0.27.2",
|
|
||||||
"showdown": "^1.9.1",
|
"showdown": "^1.9.1",
|
||||||
"source-map-support": "^0.5.16",
|
"source-map-support": "^0.5.16",
|
||||||
"template-format": "^1.2.5",
|
"template-format": "^1.2.5",
|
||||||
"tippy.js": "^6.3.1",
|
"tippy.js": "^6.3.1",
|
||||||
"tough-cookie": "^3.0.1",
|
"tough-cookie": "^4.0.0",
|
||||||
"tty-table": "^2.8.12",
|
|
||||||
"tunnel": "0.0.6",
|
"tunnel": "0.0.6",
|
||||||
|
"undici": "^4.13.0",
|
||||||
"url-pattern": "^1.0.3",
|
"url-pattern": "^1.0.3",
|
||||||
"v-tooltip": "^2.0.3",
|
"v-tooltip": "^2.0.3",
|
||||||
"video.js": "^7.11.4",
|
"video.js": "^7.11.4",
|
||||||
"videojs-vr": "^1.7.1",
|
"videojs-vr": "^1.7.1",
|
||||||
"vue": "^3.0.4",
|
"vue": "^3.2.20",
|
||||||
"vue-router": "^4.0.1",
|
"vue-router": "^4.0.12",
|
||||||
"vuex": "^4.0.0-rc.2",
|
"vuex": "^4.0.2",
|
||||||
"why-is-node-running": "^2.2.0",
|
"why-is-node-running": "^2.2.0",
|
||||||
"winston": "^3.2.1",
|
"winston": "^3.2.1",
|
||||||
"winston-daily-rotate-file": "^4.4.2",
|
"winston-daily-rotate-file": "^4.4.2",
|
||||||
"yargs": "^13.3.0"
|
"yargs": "^17.2.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 7.4 KiB After Width: | Height: | Size: 7.4 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 6.8 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 6.6 KiB |
After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
After Width: | Height: | Size: 9.9 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 9.5 KiB After Width: | Height: | Size: 9.5 KiB |