forked from DebaucheryLibrarian/traxxx
Added tag filter to releases query, enabled on homepage.
This commit is contained in:
parent
d1212725bb
commit
f9f9cc7977
|
@ -0,0 +1,172 @@
|
|||
<template>
|
||||
<div class="filters-bar noselect">
|
||||
<Icon icon="filter" />
|
||||
|
||||
<ul class="filters">
|
||||
<li
|
||||
v-tooltip.bottom="'Not yet available'"
|
||||
class="filter"
|
||||
>
|
||||
<label
|
||||
class="toggle"
|
||||
:class="{ active: !localFilter.includes('straight') }"
|
||||
>
|
||||
<input
|
||||
v-model="localFilter"
|
||||
value="straight"
|
||||
type="checkbox"
|
||||
class="check"
|
||||
disabled
|
||||
@change="$emit('set-filter', localFilter)"
|
||||
>straight
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<li class="filter">
|
||||
<label
|
||||
class="toggle"
|
||||
:class="{ active: !localFilter.includes('lesbian') }"
|
||||
>
|
||||
<input
|
||||
v-model="localFilter"
|
||||
value="lesbian"
|
||||
type="checkbox"
|
||||
class="check"
|
||||
@change="$emit('set-filter', localFilter)"
|
||||
>lesbian
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<li class="filter">
|
||||
<label
|
||||
class="toggle"
|
||||
:class="{ active: !localFilter.includes('gay') }"
|
||||
>
|
||||
<input
|
||||
v-model="localFilter"
|
||||
value="gay"
|
||||
type="checkbox"
|
||||
class="check"
|
||||
@change="$emit('set-filter', localFilter)"
|
||||
>gay
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<li class="filter">
|
||||
<label
|
||||
class="toggle"
|
||||
:class="{ active: !localFilter.includes('transsexual') }"
|
||||
>
|
||||
<input
|
||||
v-model="localFilter"
|
||||
value="transsexual"
|
||||
type="checkbox"
|
||||
class="check"
|
||||
@change="$emit('set-filter', localFilter)"
|
||||
>trans
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="filters">
|
||||
<li class="filter">
|
||||
<label
|
||||
class="toggle"
|
||||
:class="{ active: !localFilter.includes('anal') }"
|
||||
>
|
||||
<input
|
||||
v-model="localFilter"
|
||||
value="anal"
|
||||
type="checkbox"
|
||||
class="check"
|
||||
@change="$emit('set-filter', localFilter)"
|
||||
>anal
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<ul class="filters">
|
||||
<li class="filter">
|
||||
<label
|
||||
class="toggle"
|
||||
:class="{ active: !localFilter.includes('femdom') }"
|
||||
>
|
||||
<input
|
||||
v-model="localFilter"
|
||||
value="femdom"
|
||||
type="checkbox"
|
||||
class="check"
|
||||
@change="$emit('set-filter', localFilter)"
|
||||
>femdom
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
filter: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
localFilter: this.filter,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import 'theme';
|
||||
|
||||
.filters-bar {
|
||||
display: block;
|
||||
background: $shadow-hint;
|
||||
padding: .5rem 1rem;
|
||||
font-size: 0;
|
||||
|
||||
.icon {
|
||||
fill: $shadow;
|
||||
}
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
padding: .5rem;
|
||||
margin: 0;
|
||||
|
||||
&:not(:last-child) {
|
||||
border-right: solid 1px $shadow-weak;
|
||||
}
|
||||
}
|
||||
|
||||
.filter {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.toggle {
|
||||
color: $shadow;
|
||||
background: $shadow-hint;
|
||||
box-sizing: border-box;
|
||||
padding: .5rem;
|
||||
margin: 0 .25rem;
|
||||
border-radius: .5rem;
|
||||
font-size: .9rem;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
|
||||
.check {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $text-contrast;
|
||||
background: $primary;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,62 +1,9 @@
|
|||
<template>
|
||||
<div class="content">
|
||||
<div class="filters-bar noselect">
|
||||
<Icon icon="filter" />
|
||||
|
||||
<ul class="filters">
|
||||
<li class="filter">
|
||||
<label
|
||||
class="toggle"
|
||||
:class="{ active: showStraight }"
|
||||
>
|
||||
<input
|
||||
v-model="showStraight"
|
||||
type="checkbox"
|
||||
class="check"
|
||||
>straight
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<li class="filter">
|
||||
<label
|
||||
class="toggle"
|
||||
:class="{ active: showLesbian }"
|
||||
>
|
||||
<input
|
||||
v-model="showLesbian"
|
||||
type="checkbox"
|
||||
class="check"
|
||||
>lesbian
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<li class="filter">
|
||||
<label
|
||||
class="toggle"
|
||||
:class="{ active: showGay }"
|
||||
>
|
||||
<input
|
||||
v-model="showGay"
|
||||
type="checkbox"
|
||||
class="check"
|
||||
>gay
|
||||
</label>
|
||||
</li>
|
||||
|
||||
<li class="filter">
|
||||
<label
|
||||
class="toggle"
|
||||
:class="{ active: showTrans }"
|
||||
>
|
||||
<input
|
||||
v-model="showTrans"
|
||||
type="checkbox"
|
||||
class="check"
|
||||
>trans
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<FilterBar
|
||||
:filter="filter"
|
||||
@set-filter="setFilter"
|
||||
/>
|
||||
|
||||
<div class="content-inner">
|
||||
<ul class="scenes nolist">
|
||||
|
@ -73,75 +20,47 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import FilterBar from './filter.vue';
|
||||
import ReleaseTile from '../tile/release.vue';
|
||||
|
||||
async function mounted() {
|
||||
this.releases = await this.$store.dispatch('fetchReleases');
|
||||
this.networks = await this.$store.dispatch('fetchNetworks');
|
||||
async function fetchReleases() {
|
||||
this.releases = await this.$store.dispatch('fetchReleases', {
|
||||
filter: this.filter,
|
||||
});
|
||||
}
|
||||
|
||||
async function setFilter(filter) {
|
||||
this.filter = filter;
|
||||
localStorage.setItem('filter', this.filter);
|
||||
|
||||
await this.fetchReleases();
|
||||
}
|
||||
|
||||
async function mounted() {
|
||||
this.pageTitle = '';
|
||||
|
||||
await this.fetchReleases();
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FilterBar,
|
||||
ReleaseTile,
|
||||
},
|
||||
data() {
|
||||
const storedFilter = localStorage.getItem('filter');
|
||||
|
||||
return {
|
||||
showStraight: true,
|
||||
showLesbian: true,
|
||||
showGay: false,
|
||||
showTrans: false,
|
||||
filter: storedFilter ? storedFilter.split(',') : ['gay', 'transsexual'],
|
||||
releases: [],
|
||||
networks: [],
|
||||
pageTitle: null,
|
||||
};
|
||||
},
|
||||
mounted,
|
||||
methods: {
|
||||
fetchReleases,
|
||||
setFilter,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import 'theme';
|
||||
|
||||
.filters-bar {
|
||||
display: block;
|
||||
background: $shadow-hint;
|
||||
padding: .5rem 1rem;
|
||||
|
||||
.icon {
|
||||
fill: $shadow;
|
||||
}
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
padding: .5rem;
|
||||
margin: 0;
|
||||
|
||||
.toggle {
|
||||
color: $shadow;
|
||||
background: $shadow-hint;
|
||||
box-sizing: border-box;
|
||||
padding: .5rem;
|
||||
border-radius: .5rem;
|
||||
font-size: .9rem;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
|
||||
.check {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
color: $text-contrast;
|
||||
background: $primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filter {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -168,7 +168,7 @@ function photos() {
|
|||
}
|
||||
|
||||
async function mounted() {
|
||||
[this.release] = await this.$store.dispatch('fetchReleases', this.$route.params.releaseId);
|
||||
[this.release] = await this.$store.dispatch('fetchReleases', { id: this.$route.params.releaseId });
|
||||
}
|
||||
|
||||
export default {
|
||||
|
|
|
@ -116,7 +116,7 @@ export default {
|
|||
}
|
||||
|
||||
.logo {
|
||||
width: 15rem;
|
||||
width: 20rem;
|
||||
max-height: 8rem;
|
||||
object-fit: contain;
|
||||
margin: 0 .5rem 1rem 0;
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
.tooltip {
|
||||
display: block !important;
|
||||
z-index: 10000;
|
||||
|
||||
.tooltip-inner {
|
||||
background: #222;
|
||||
color: white;
|
||||
border-radius: 16px;
|
||||
padding: 5px 10px 4px;
|
||||
}
|
||||
|
||||
.tooltip-arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
margin: 5px;
|
||||
border-color: #222;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
&[x-placement^="top"] {
|
||||
margin-bottom: 5px;
|
||||
|
||||
.tooltip-arrow {
|
||||
border-width: 5px 5px 0 5px;
|
||||
border-left-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
bottom: -5px;
|
||||
left: calc(50% - 5px);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="bottom"] {
|
||||
margin-top: 5px;
|
||||
|
||||
.tooltip-arrow {
|
||||
border-width: 0 5px 5px 5px;
|
||||
border-left-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-top-color: transparent !important;
|
||||
top: -5px;
|
||||
left: calc(50% - 5px);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="right"] {
|
||||
margin-left: 5px;
|
||||
|
||||
.tooltip-arrow {
|
||||
border-width: 5px 5px 5px 0;
|
||||
border-left-color: transparent !important;
|
||||
border-top-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
left: -5px;
|
||||
top: calc(50% - 5px);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&[x-placement^="left"] {
|
||||
margin-right: 5px;
|
||||
|
||||
.tooltip-arrow {
|
||||
border-width: 5px 0 5px 5px;
|
||||
border-top-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
right: -5px;
|
||||
top: calc(50% - 5px);
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.popover {
|
||||
$color: #f9f9f9;
|
||||
|
||||
.popover-inner {
|
||||
background: $color;
|
||||
color: black;
|
||||
padding: 24px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 5px 30px rgba(black, .1);
|
||||
}
|
||||
|
||||
.popover-arrow {
|
||||
border-color: $color;
|
||||
}
|
||||
}
|
||||
|
||||
&[aria-hidden='true'] {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
/* transition: opacity .15s, visibility .15s; */
|
||||
}
|
||||
|
||||
&[aria-hidden='false'] {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
/* transition: opacity .15s; */
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
@import 'theme';
|
||||
@import 'states';
|
||||
@import 'tooltip';
|
||||
|
||||
html,
|
||||
body {
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import config from 'config';
|
||||
|
||||
async function get(endpoint, query = {}) {
|
||||
const queryString = Object.entries(query).reduce((acc, [key, value], index) => `${acc}${index > 0 ? '&' : ''}${key}=${value}`, '?');
|
||||
import queryString from 'query-string';
|
||||
|
||||
const res = await fetch(`${config.api.url}${endpoint}${queryString}`, {
|
||||
async function get(endpoint, query = {}) {
|
||||
const q = queryString.stringify(query);
|
||||
|
||||
const res = await fetch(`${config.api.url}${endpoint}?${q}`, {
|
||||
method: 'GET',
|
||||
mode: 'cors',
|
||||
credentials: 'same-origin',
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import Vue from 'vue';
|
||||
import dayjs from 'dayjs';
|
||||
import VTooltip from 'v-tooltip';
|
||||
|
||||
import router from './router';
|
||||
import initStore from './store';
|
||||
|
@ -31,6 +32,8 @@ function init() {
|
|||
},
|
||||
});
|
||||
|
||||
Vue.use(VTooltip);
|
||||
|
||||
new Vue({ // eslint-disable-line no-new
|
||||
el: '#container',
|
||||
store,
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { get } from '../api';
|
||||
|
||||
function initReleasesActions(_store, _router) {
|
||||
async function fetchReleases({ _commit }, releaseId) {
|
||||
const releases = await get(`/releases/${releaseId || ''}`);
|
||||
async function fetchReleases({ _commit }, { id, filter }) {
|
||||
const releases = await get(`/releases/${id || ''}`, { filter });
|
||||
|
||||
return releases;
|
||||
}
|
||||
|
|
|
@ -7700,6 +7700,24 @@
|
|||
"prepend-http": "^1.0.0",
|
||||
"query-string": "^4.1.0",
|
||||
"sort-keys": "^1.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"query-string": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
|
||||
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"object-assign": "^4.1.0",
|
||||
"strict-uri-encode": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"npm-run-path": {
|
||||
|
@ -8335,6 +8353,11 @@
|
|||
"resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
|
||||
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA=="
|
||||
},
|
||||
"popper.js": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.0.tgz",
|
||||
"integrity": "sha512-+G+EkOPoE5S/zChTpmBSSDYmhXJ5PsW8eMhH8cP/CQHMFPBG/kC9Y5IIw6qNYgdJ+/COf0ddY2li28iHaZRSjw=="
|
||||
},
|
||||
"posix-character-classes": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
|
||||
|
@ -8709,13 +8732,13 @@
|
|||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
|
||||
},
|
||||
"query-string": {
|
||||
"version": "4.3.4",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
|
||||
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
|
||||
"dev": true,
|
||||
"version": "6.8.3",
|
||||
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.8.3.tgz",
|
||||
"integrity": "sha512-llcxWccnyaWlODe7A9hRjkvdCKamEKTh+wH8ITdTc3OhchaqUZteiSCX/2ablWHVrkVIe04dntnaZJ7BdyW0lQ==",
|
||||
"requires": {
|
||||
"object-assign": "^4.1.0",
|
||||
"strict-uri-encode": "^1.0.0"
|
||||
"decode-uri-component": "^0.2.0",
|
||||
"split-on-first": "^1.0.0",
|
||||
"strict-uri-encode": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"querystring": {
|
||||
|
@ -10065,6 +10088,11 @@
|
|||
"through": "2"
|
||||
}
|
||||
},
|
||||
"split-on-first": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz",
|
||||
"integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw=="
|
||||
},
|
||||
"split-string": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
|
||||
|
@ -10210,10 +10238,9 @@
|
|||
"integrity": "sha512-1q+dL790Ps0NV33rISMq9OLtfDA9KMJZdo1PHZXE85orrWsM4FAh8CVyAOTHO0rhyeM138KNPngBPrx33bFsxw=="
|
||||
},
|
||||
"strict-uri-encode": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
|
||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
|
||||
"dev": true
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
|
||||
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
|
||||
},
|
||||
"string": {
|
||||
"version": "3.3.3",
|
||||
|
@ -10997,6 +11024,16 @@
|
|||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
|
||||
"integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho="
|
||||
},
|
||||
"v-tooltip": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/v-tooltip/-/v-tooltip-2.0.2.tgz",
|
||||
"integrity": "sha512-xQ+qzOFfywkLdjHknRPgMMupQNS8yJtf9Utd5Dxiu/0n4HtrxqsgDtN2MLZ0LKbburtSAQgyypuE/snM8bBZhw==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.11",
|
||||
"popper.js": "^1.15.0",
|
||||
"vue-resize": "^0.4.5"
|
||||
}
|
||||
},
|
||||
"v8-compile-cache": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz",
|
||||
|
@ -11121,6 +11158,11 @@
|
|||
"vue-style-loader": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"vue-resize": {
|
||||
"version": "0.4.5",
|
||||
"resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-0.4.5.tgz",
|
||||
"integrity": "sha512-bhP7MlgJQ8TIkZJXAfDf78uJO+mEI3CaLABLjv0WNzr4CcGRGPIAItyWYnP6LsPA4Oq0WE+suidNs6dgpO4RHg=="
|
||||
},
|
||||
"vue-router": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.0.6.tgz",
|
||||
|
|
|
@ -85,11 +85,13 @@
|
|||
"opn": "^5.4.0",
|
||||
"pg": "^7.9.0",
|
||||
"prop-types": "^15.7.2",
|
||||
"query-string": "^6.8.3",
|
||||
"react": "^16.8.6",
|
||||
"react-dom": "^16.8.6",
|
||||
"sharp": "^0.23.2",
|
||||
"tough-cookie": "^3.0.1",
|
||||
"tty-table": "^2.7.0",
|
||||
"v-tooltip": "^2.0.2",
|
||||
"vue": "^2.6.10",
|
||||
"vue-router": "^3.0.6",
|
||||
"vuex": "^3.1.1",
|
||||
|
|
|
@ -1,3 +1,44 @@
|
|||
/* $primary: #ff886c; */
|
||||
.filters-bar[data-v-7de6ddc6] {
|
||||
display: block;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
padding: .5rem 1rem;
|
||||
font-size: 0;
|
||||
}
|
||||
.filters-bar .icon[data-v-7de6ddc6] {
|
||||
fill: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.filters[data-v-7de6ddc6] {
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
padding: .5rem;
|
||||
margin: 0;
|
||||
}
|
||||
.filters[data-v-7de6ddc6]:not(:last-child) {
|
||||
border-right: solid 1px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.filter[data-v-7de6ddc6] {
|
||||
display: inline-block;
|
||||
}
|
||||
.toggle[data-v-7de6ddc6] {
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
padding: .5rem;
|
||||
margin: 0 .25rem;
|
||||
border-radius: .5rem;
|
||||
font-size: .9rem;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
.toggle .check[data-v-7de6ddc6] {
|
||||
display: none;
|
||||
}
|
||||
.toggle.active[data-v-7de6ddc6] {
|
||||
color: #fff;
|
||||
background: #ff6c88;
|
||||
}
|
||||
|
||||
/* $primary: #ff886c; */
|
||||
.tile[data-v-3abcf101] {
|
||||
display: flex;
|
||||
|
@ -118,42 +159,6 @@
|
|||
color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
/* $primary: #ff886c; */
|
||||
.filters-bar[data-v-5533e378] {
|
||||
display: block;
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
padding: .5rem 1rem;
|
||||
}
|
||||
.filters-bar .icon[data-v-5533e378] {
|
||||
fill: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.filters[data-v-5533e378] {
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
padding: .5rem;
|
||||
margin: 0;
|
||||
}
|
||||
.filters .toggle[data-v-5533e378] {
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
box-sizing: border-box;
|
||||
padding: .5rem;
|
||||
border-radius: .5rem;
|
||||
font-size: .9rem;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
.filters .toggle .check[data-v-5533e378] {
|
||||
display: none;
|
||||
}
|
||||
.filters .toggle.active[data-v-5533e378] {
|
||||
color: #fff;
|
||||
background: #ff6c88;
|
||||
}
|
||||
.filter[data-v-5533e378] {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* $primary: #ff886c; */
|
||||
.banner[data-v-2bc41e74] {
|
||||
background: #222;
|
||||
|
@ -246,7 +251,7 @@
|
|||
align-items: flex-end;
|
||||
}
|
||||
.logo[data-v-3e57cf44] {
|
||||
width: 15rem;
|
||||
width: 20rem;
|
||||
max-height: 8rem;
|
||||
-o-object-fit: contain;
|
||||
object-fit: contain;
|
||||
|
@ -423,6 +428,83 @@
|
|||
-ms-user-select: none;
|
||||
-webkit-tap-highlight-color: transparent; }
|
||||
|
||||
.tooltip {
|
||||
display: block !important;
|
||||
z-index: 10000; }
|
||||
.tooltip .tooltip-inner {
|
||||
background: #222;
|
||||
color: white;
|
||||
border-radius: 16px;
|
||||
padding: 5px 10px 4px; }
|
||||
.tooltip .tooltip-arrow {
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-style: solid;
|
||||
position: absolute;
|
||||
margin: 5px;
|
||||
border-color: #222;
|
||||
z-index: 1; }
|
||||
.tooltip[x-placement^="top"] {
|
||||
margin-bottom: 5px; }
|
||||
.tooltip[x-placement^="top"] .tooltip-arrow {
|
||||
border-width: 5px 5px 0 5px;
|
||||
border-left-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
bottom: -5px;
|
||||
left: calc(50% - 5px);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0; }
|
||||
.tooltip[x-placement^="bottom"] {
|
||||
margin-top: 5px; }
|
||||
.tooltip[x-placement^="bottom"] .tooltip-arrow {
|
||||
border-width: 0 5px 5px 5px;
|
||||
border-left-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-top-color: transparent !important;
|
||||
top: -5px;
|
||||
left: calc(50% - 5px);
|
||||
margin-top: 0;
|
||||
margin-bottom: 0; }
|
||||
.tooltip[x-placement^="right"] {
|
||||
margin-left: 5px; }
|
||||
.tooltip[x-placement^="right"] .tooltip-arrow {
|
||||
border-width: 5px 5px 5px 0;
|
||||
border-left-color: transparent !important;
|
||||
border-top-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
left: -5px;
|
||||
top: calc(50% - 5px);
|
||||
margin-left: 0;
|
||||
margin-right: 0; }
|
||||
.tooltip[x-placement^="left"] {
|
||||
margin-right: 5px; }
|
||||
.tooltip[x-placement^="left"] .tooltip-arrow {
|
||||
border-width: 5px 0 5px 5px;
|
||||
border-top-color: transparent !important;
|
||||
border-right-color: transparent !important;
|
||||
border-bottom-color: transparent !important;
|
||||
right: -5px;
|
||||
top: calc(50% - 5px);
|
||||
margin-left: 0;
|
||||
margin-right: 0; }
|
||||
.tooltip.popover .popover-inner {
|
||||
background: #f9f9f9;
|
||||
color: black;
|
||||
padding: 24px;
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 5px 30px rgba(0, 0, 0, 0.1); }
|
||||
.tooltip.popover .popover-arrow {
|
||||
border-color: #f9f9f9; }
|
||||
.tooltip[aria-hidden='true'] {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
/* transition: opacity .15s, visibility .15s; */ }
|
||||
.tooltip[aria-hidden='false'] {
|
||||
visibility: visible;
|
||||
opacity: 1;
|
||||
/* transition: opacity .15s; */ }
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%; }
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
|
@ -1399,6 +1399,10 @@ function getTagAliases(tagsMap) {
|
|||
name: 'tittyfuck',
|
||||
alias_for: tagsMap['titty-fuck'],
|
||||
},
|
||||
{
|
||||
name: 'tp',
|
||||
alias_for: tagsMap['triple-penetration'],
|
||||
},
|
||||
{
|
||||
name: 'trans',
|
||||
alias_for: tagsMap['transsexual'],
|
||||
|
@ -1408,8 +1412,8 @@ function getTagAliases(tagsMap) {
|
|||
alias_for: tagsMap['trimmed'],
|
||||
},
|
||||
{
|
||||
name: 'tp',
|
||||
alias_for: tagsMap['triple-penetration'],
|
||||
name: 'ts',
|
||||
alias_for: tagsMap['transsexual'],
|
||||
},
|
||||
{
|
||||
name: 'whipping',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const knex = require('./knex');
|
||||
const whereOr = require('./utils/where-or');
|
||||
|
||||
async function curateActor(actor) {
|
||||
const aliases = await knex('actors')
|
||||
|
@ -26,10 +27,9 @@ function curateActors(releases) {
|
|||
return Promise.all(releases.map(async release => curateActor(release)));
|
||||
}
|
||||
|
||||
async function fetchActors(actorId, actorSlug) {
|
||||
async function fetchActors(queryObject) {
|
||||
const releases = await knex('actors')
|
||||
.where({ id: actorId })
|
||||
.orWhere({ slug: actorSlug })
|
||||
.where(builder => whereOr(queryObject, 'actors', builder))
|
||||
.limit(100);
|
||||
|
||||
return curateActors(releases);
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const knex = require('./knex');
|
||||
const whereOr = require('./utils/where-or');
|
||||
|
||||
async function curateNetwork(network) {
|
||||
const [sites, studios] = await Promise.all([
|
||||
|
@ -44,10 +45,9 @@ function curateNetworks(releases) {
|
|||
return Promise.all(releases.map(async release => curateNetwork(release)));
|
||||
}
|
||||
|
||||
async function fetchNetworks(networkId, networkSlug) {
|
||||
async function fetchNetworks(queryObject) {
|
||||
const releases = await knex('networks')
|
||||
.where({ id: networkId })
|
||||
.orWhere({ slug: networkSlug })
|
||||
.where(builder => whereOr(queryObject, 'networks', builder))
|
||||
.limit(100);
|
||||
|
||||
return curateNetworks(releases);
|
||||
|
|
|
@ -66,18 +66,29 @@ function curateReleases(releases) {
|
|||
return Promise.all(releases.map(async release => curateRelease(release)));
|
||||
}
|
||||
|
||||
async function fetchReleases(releaseId) {
|
||||
async function fetchReleases(releaseId, filter = []) {
|
||||
// const straightFilter = filter.includes('straight') ? ['gay', 'lesbian'] : [];
|
||||
|
||||
const releases = await knex('releases')
|
||||
.where(releaseId ? { 'releases.id': releaseId } : {})
|
||||
.leftJoin('sites', 'releases.site_id', 'sites.id')
|
||||
.leftJoin('studios', 'releases.studio_id', 'studios.id')
|
||||
.leftJoin('networks', 'sites.network_id', 'networks.id')
|
||||
.select(
|
||||
'releases.*',
|
||||
'sites.name as site_name', 'sites.slug as site_slug', 'sites.url as site_url', 'sites.network_id',
|
||||
'studios.name as studio_name', 'sites.slug as site_slug', 'studios.url as studio_url',
|
||||
'networks.name as network_name', 'networks.slug as network_slug', 'networks.url as network_url',
|
||||
)
|
||||
.leftJoin('sites', 'releases.site_id', 'sites.id')
|
||||
.leftJoin('studios', 'releases.studio_id', 'studios.id')
|
||||
.leftJoin('networks', 'sites.network_id', 'networks.id')
|
||||
.whereNotExists((builder) => {
|
||||
// apply filters
|
||||
builder
|
||||
.select('*')
|
||||
.from('tags_associated')
|
||||
.leftJoin('tags', 'tags_associated.tag_id', 'tags.id')
|
||||
.whereIn('tags.slug', filter)
|
||||
.andWhereRaw('tags_associated.release_id = releases.id');
|
||||
})
|
||||
.andWhere(releaseId ? { 'releases.id': releaseId } : {})
|
||||
.orderBy([{ column: 'date', order: 'desc' }, { column: 'created_at', order: 'desc' }])
|
||||
.limit(100);
|
||||
|
||||
|
|
|
@ -8,6 +8,13 @@ const moment = require('moment');
|
|||
|
||||
const { matchTags } = require('../tags');
|
||||
|
||||
const defaultTags = {
|
||||
hardx: [],
|
||||
darkx: ['interracial'],
|
||||
eroticax: [],
|
||||
lesbianx: ['lesbian'],
|
||||
};
|
||||
|
||||
async function fetchPhotos(url) {
|
||||
const res = await bhttp.get(url);
|
||||
|
||||
|
@ -144,7 +151,7 @@ async function scrapeScene(html, url, site) {
|
|||
.orWhere({ slug: siteId })
|
||||
.first()
|
||||
: site,
|
||||
matchTags(rawTags),
|
||||
matchTags([...defaultTags[siteId], ...rawTags]),
|
||||
]);
|
||||
|
||||
return {
|
||||
|
|
|
@ -23,9 +23,9 @@ function curateSites(sites) {
|
|||
return Promise.all(sites.map(async site => curateSite(site)));
|
||||
}
|
||||
|
||||
async function fetchSites(query) {
|
||||
async function fetchSites(queryObject) {
|
||||
const sites = await knex('sites')
|
||||
.where(builder => whereOr(query, builder))
|
||||
.where(builder => whereOr(queryObject, 'sites', builder))
|
||||
.select(
|
||||
'sites.*',
|
||||
'networks.name as network_name', 'networks.slug as network_slug', 'networks.url as network_url',
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
const knex = require('./knex');
|
||||
const whereOr = require('./utils/where-or');
|
||||
|
||||
async function curateTag(tag) {
|
||||
const aliases = await knex('tags').where({ alias_for: tag.id });
|
||||
|
@ -30,10 +31,9 @@ async function storeTags(release, releaseEntry) {
|
|||
})));
|
||||
}
|
||||
|
||||
async function fetchTags(tagId, tagSlug) {
|
||||
async function fetchTags(queryObject) {
|
||||
const tags = await knex('tags')
|
||||
.where({ 'tags.id': tagId })
|
||||
.orWhere({ 'tags.slug': tagSlug })
|
||||
.where(builder => whereOr(queryObject, 'tags', builder))
|
||||
.andWhere({ 'tags.alias_for': null })
|
||||
.select(
|
||||
'tags.*',
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
'use strict';
|
||||
|
||||
function whereOr(query, builder) {
|
||||
function whereOr(query, table, builder) {
|
||||
Object.entries(query).forEach(([key, value]) => {
|
||||
if (value !== undefined) {
|
||||
builder.orWhere(`sites.${key}`, value);
|
||||
builder.orWhere(`${table}.${key}`, value);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -6,7 +6,10 @@ async function fetchActorsApi(req, res) {
|
|||
const actorId = typeof req.params.actorId === 'number' ? req.params.actorId : null;
|
||||
const actorSlug = typeof req.params.actorId === 'string' ? req.params.actorId : null;
|
||||
|
||||
const actors = await fetchActors(actorId, actorSlug);
|
||||
const actors = await fetchActors({
|
||||
id: actorId,
|
||||
slug: actorSlug,
|
||||
});
|
||||
|
||||
res.send(actors);
|
||||
}
|
||||
|
|
|
@ -3,10 +3,13 @@
|
|||
const { fetchNetworks, fetchNetworksFromReleases } = require('../networks');
|
||||
|
||||
async function fetchNetworksApi(req, res) {
|
||||
const networkId = typeof req.params.networkId === 'number' ? req.params.networkId : null;
|
||||
const networkSlug = typeof req.params.networkId === 'string' ? req.params.networkId : null;
|
||||
const networkId = typeof req.params.networkId === 'number' ? req.params.networkId : undefined; // null will literally include NULL results
|
||||
const networkSlug = typeof req.params.networkId === 'string' ? req.params.networkId : undefined;
|
||||
|
||||
const networks = await fetchNetworks(networkId, networkSlug);
|
||||
const networks = await fetchNetworks({
|
||||
id: networkId,
|
||||
slug: networkSlug,
|
||||
});
|
||||
|
||||
res.send(networks);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ const {
|
|||
} = require('../releases');
|
||||
|
||||
async function fetchReleasesApi(req, res) {
|
||||
const releases = await fetchReleases(req.params.releaseId);
|
||||
const releases = await fetchReleases(req.params.releaseId, req.query.filter ? [].concat(req.query.filter) : []);
|
||||
|
||||
res.send(releases);
|
||||
}
|
||||
|
|
|
@ -3,10 +3,13 @@
|
|||
const { fetchTags } = require('../tags');
|
||||
|
||||
async function fetchTagsApi(req, res) {
|
||||
const tagId = typeof req.params.tagId === 'number' ? req.params.tagId : null;
|
||||
const tagSlug = typeof req.params.tagId === 'string' ? req.params.tagId : null;
|
||||
const tagId = typeof req.params.tagId === 'number' ? req.params.tagId : undefined; // null will literally include NULL results
|
||||
const tagSlug = typeof req.params.tagId === 'string' ? req.params.tagId : undefined;
|
||||
|
||||
const tags = await fetchTags(tagId, tagSlug);
|
||||
const tags = await fetchTags({
|
||||
id: tagId,
|
||||
slug: tagSlug,
|
||||
});
|
||||
|
||||
res.send(tags);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue