Added filter range component. Added age filter.

This commit is contained in:
DebaucheryLibrarian 2021-03-03 21:53:10 +01:00
parent fc6de64311
commit 5c6b5a0668
8 changed files with 309 additions and 4 deletions

View File

@ -60,6 +60,32 @@
<nav class="filter">
<ul class="nolist">
<li>
<Tooltip class="filter boobs">
<span
class="filter-trigger"
:class="{ enabled: ageRequired }"
><Icon icon="cake" />Age</span>
<template v-slot:tooltip>
<RangeFilter
label="age"
:min="18"
:max="100"
:value="age"
:disabled="!ageRequired"
:allow-enable="true"
@enable="(checked) => updateValue('ageRequired', checked, true)"
@input="(range) => updateValue('age', range, false)"
@change="(range) => updateValue('age', range, true)"
>
<template v-slot:start><Icon icon="flower" /></template>
<template v-slot:end><Icon icon="pipe" /></template>
</RangeFilter>
</template>
</Tooltip>
</li>
<li>
<Tooltip class="filter boobs">
<span
@ -241,6 +267,7 @@ import Actor from './tile.vue';
import Gender from './gender.vue';
import Checkbox from '../form/checkbox.vue';
import Range from '../form/range.vue';
import RangeFilter from './filter-range.vue';
import Pagination from '../pagination/pagination.vue';
const toggleValues = [true, null, false];
@ -255,6 +282,7 @@ function updateFilters() {
bs: this.boobSizeRequired ? this.boobSize.join(',') : undefined,
h: this.heightRequired ? this.height.join(',') : undefined,
w: this.weightRequired ? this.weight.join(',') : undefined,
age: this.ageRequired ? this.age.join(',') : undefined,
},
});
}
@ -275,6 +303,7 @@ async function fetchActors(scroll) {
pageNumber: Number(this.$route.params.pageNumber) || 1,
letter: this.letter.replace('all', ''),
gender: curatedGender === 'other' ? null : curatedGender,
age: this.ageRequired && this.age,
boobSize: this.boobSizeRequired && this.boobSize,
naturalBoobs: toggleValues[this.naturalBoobs] ?? null,
height: this.heightRequired && this.height,
@ -317,6 +346,7 @@ export default {
Checkbox,
Gender,
Range,
RangeFilter,
Pagination,
},
data() {
@ -326,6 +356,8 @@ export default {
totalCount: 0,
limit: 50,
letters: ['all'].concat(Array.from({ length: 26 }, (value, index) => String.fromCharCode(index + 97).toUpperCase())),
age: this.$route.query.age?.split(',') || [18, 100],
ageRequired: !!this.$route.query.age,
boobSizes,
boobSize: this.$route.query.bs?.split(',') || ['A', 'Z'],
boobSizeRequired: !!this.$route.query.bs,

View File

@ -0,0 +1,209 @@
<template>
<div class="filter-section">
<label class="filter-label noselect">
<span class="label">
<Checkbox
:checked="!disabled"
class="checkbox"
@change="(checked) => $emit('enable', checked)"
/>{{ label }}
</span>
<span
class="label-values"
>({{ value[0] }} - {{ value[1] }} {{ unit }})</span>
</label>
<span class="filter-split">
<Range
:min="min"
:max="max"
:value="value"
:disabled="disabled"
:allow-enable="true"
@enable="$emit('enable', true)"
@input="(range) => $emit('input', range)"
@change="(range) => $emit('change', range)"
>
<template v-slot:start><slot name="start" /></template>
<template v-slot:end><slot name="end" /></template>
</Range>
</span>
</div>
</template>
<script>
import Checkbox from '../form/checkbox.vue';
import Range from '../form/range.vue';
export default {
components: {
Checkbox,
Range,
},
props: {
label: {
type: String,
default: null,
},
value: {
type: Array,
default: () => [0, 10],
},
min: {
type: Number,
default: 0,
},
max: {
type: Number,
default: 10,
},
unit: {
type: String,
default: null,
},
disabled: {
type: Boolean,
default: false,
},
allowEnable: {
type: Boolean,
default: true,
},
},
emits: ['change', 'input', 'enable'],
};
</script>
<style lang="scss" scoped>
@import 'breakpoints';
.filter-section {
width: 15rem;
max-width: 100%;
border-bottom: solid 1px var(--darken-hint);
}
.filter-label {
display: flex;
justify-content: space-between;
padding: .75rem .5rem .5rem .5rem;
color: var(--darken);
font-weight: bold;
font-size: .9rem;
.label {
display: inline-flex;
align-items: center;
text-transform: capitalize;
}
.checkbox {
margin: 0 .75rem 0 0;
}
.icon {
margin: 0 .5rem 0 0;
}
}
.label-values {
font-weight: normal;
}
.filter-split {
display: flex;
align-items: center;
}
.toggle-container,
.range-container {
display: flex;
flex-grow: 1;
align-items: center;
padding: .5rem 0;
&.on {
.toggle-label.on {
color: var(--enabled);
.icon {
fill: var(--enabled);
}
}
.toggle {
background-color: var(--enabled-background);
&::-webkit-slider-thumb {
background: var(--enabled);
}
&::-moz-range-thumb {
background: var(--enabled);
}
}
}
&.off {
.toggle-label.off {
color: var(--disabled);
.icon {
fill: var(--disabled);
}
}
.toggle {
background-color: var(--disabled-background);
&::-webkit-slider-thumb {
background: var(--disabled);
}
&::-moz-range-thumb {
background: var(--disabled);
}
}
}
}
.toggle-label {
display: inline-flex;
justify-content: center;
min-width: 1.5rem;
flex-shrink: 0;
padding: 0 .5rem;
color: var(--darken);
font-weight: bold;
font-size: .9rem;
&.on {
text-align: right;
}
.icon {
fill: var(--darken);
}
&:hover {
cursor: pointer;
&.on {
color: var(--enabled);
.icon {
fill: var(--enabled);
}
}
&.off {
color: var(--disabled);
.icon {
fill: var(--disabled);
}
}
}
}
</style>

View File

@ -0,0 +1,6 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<title>accessibility</title>
<path d="M6.5 1.5c0-0.828 0.672-1.5 1.5-1.5s1.5 0.672 1.5 1.5c0 0.828-0.672 1.5-1.5 1.5s-1.5-0.672-1.5-1.5z"></path>
<path d="M10 5l5.15-2.221-0.371-0.929-6.279 2.15h-1l-6.279-2.15-0.371 0.929 5.15 2.221v4l-2.051 6.634 0.935 0.355 2.902-6.489h0.429l2.902 6.489 0.935-0.355-2.051-6.634z"></path>
</svg>

After

Width:  |  Height:  |  Size: 462 B

View File

@ -0,0 +1,7 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<title>accessibility2</title>
<path d="M16 10.985l-1.545 1.030-2.955-4.015h-4.5v-1h4v-2h-4v-1l-2-0.5v6.5h5.5l3.268 4.357 3.119-2.079z"></path>
<path d="M8 1.5c0 0.828-0.672 1.5-1.5 1.5s-1.5-0.672-1.5-1.5c0-0.828 0.672-1.5 1.5-1.5s1.5 0.672 1.5 1.5z"></path>
<path d="M10.609 12.349c-0.903 1.3-2.407 2.151-4.109 2.151-2.761 0-5-2.239-5-5 0-1.937 1.101-3.616 2.711-4.446l-0.978-1.174c-1.933 1.126-3.233 3.221-3.233 5.62 0 3.59 2.91 6.5 6.5 6.5 2.096 0 3.96-0.992 5.148-2.532l-1.039-1.119z"></path>
</svg>

After

Width:  |  Height:  |  Size: 634 B

5
assets/img/icons/hat.svg Normal file
View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<title>hat</title>
<path d="M13 7.768v-3.268c0-0.828-2.239-1.5-5-1.5s-5 0.672-5 1.5v3.268c-1.829 0.641-3 1.627-3 2.732 0 1.933 3.582 3.5 8 3.5s8-1.567 8-3.5c0-1.105-1.171-2.091-3-2.732zM13 10.5c0 0.828-2.239 1.5-5 1.5s-5-0.672-5-1.5v-2c0 0.828 2.239 1.5 5 1.5s5-0.672 5-1.5v2z"></path>
</svg>

After

Width:  |  Height:  |  Size: 424 B

View File

@ -0,0 +1,5 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<title>mustache</title>
<path d="M14.645 8.021c-0.211-0.064-0.439 0.018-0.561 0.201-0.327 0.491-0.734 0.761-1.146 0.761-0.408 0-0.793-0.271-0.982-0.689l-0.007-0.015c-0.229-0.509-0.466-1.035-0.815-1.462-0.442-0.542-0.992-0.817-1.634-0.817-0.817 0-1.544 0.394-2 1.002-0.456-0.608-1.183-1.002-2-1.002-0.642 0-1.192 0.275-1.634 0.817-0.348 0.427-0.586 0.953-0.815 1.462l-0.007 0.015c-0.189 0.419-0.574 0.689-0.982 0.689-0.412 0-0.819-0.27-1.146-0.761-0.122-0.183-0.35-0.265-0.561-0.201s-0.355 0.258-0.355 0.479c0 1.074 0.419 1.978 1.212 2.615 0.711 0.571 1.701 0.885 2.788 0.885 1.038 0 2.035-0.378 2.807-1.064 0.276-0.245 0.508-0.518 0.693-0.809 0.185 0.291 0.417 0.564 0.693 0.809 0.772 0.686 1.769 1.064 2.807 1.064 1.087 0 2.077-0.314 2.788-0.885 0.793-0.636 1.212-1.541 1.212-2.615 0-0.22-0.144-0.415-0.355-0.479z"></path>
</svg>

After

Width:  |  Height:  |  Size: 962 B

View File

@ -0,0 +1,17 @@
<!-- Generated by IcoMoon.io -->
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<title>radio</title>
<path d="M15 5h-10.249l9.928-4.033c0.247-0.101 0.374-0.381 0.282-0.634-0.094-0.26-0.381-0.394-0.641-0.299l-13.59 5.004c-0.42 0.119-0.73 0.506-0.73 0.963v9c0 0.55 0.45 1 1 1h14c0.55 0 1-0.45 1-1v-9c0-0.55-0.45-1-1-1zM2 15c-0.552 0-1-0.448-1-1s0.448-1 1-1 1 0.448 1 1-0.448 1-1 1zM2 12c-0.552 0-1-0.448-1-1s0.448-1 1-1 1 0.448 1 1-0.448 1-1 1zM3 7v1h-2v-2h7v2h-4v-1h-1zM11.5 15c-1.933 0-3.5-1.567-3.5-3.5s1.567-3.5 3.5-3.5 3.5 1.567 3.5 3.5-1.567 3.5-3.5 3.5z"></path>
<path d="M11 9.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
<path d="M13 9.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
<path d="M11 11.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
<path d="M10 10.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
<path d="M12 10.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
<path d="M13 11.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
<path d="M11 13.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
<path d="M13 13.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
<path d="M14 10.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
<path d="M10 12.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
<path d="M12 12.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
<path d="M14 12.5c0 0.276-0.224 0.5-0.5 0.5s-0.5-0.224-0.5-0.5c0-0.276 0.224-0.5 0.5-0.5s0.5 0.224 0.5 0.5z"></path>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -2,6 +2,7 @@ import config from 'config';
import { graphql, get } from '../api';
import { releaseFields, getIncludedEntities, getIncludedActors } from '../fragments';
import { curateActor, curateRelease } from '../curate';
import dayjs from 'dayjs';
import getDateRange from '../get-date-range';
function initActorActions(store, router) {
@ -266,18 +267,40 @@ function initActorActions(store, router) {
pageNumber = 1,
letter,
gender,
age,
naturalBoobs,
boobSize,
height,
weight,
}) {
const now = dayjs();
const genderFilter = (gender === null && 'gender: { isNull: true }')
|| (gender === 'all' && ' ')
|| `gender: { equalTo: "${gender}" }`;
const cupFilter = boobSize ? `cup: { greaterThanOrEqualTo: "${boobSize[0]}", lessThanOrEqualTo: "${boobSize[1]}" }` : '';
const ageFilter = age ? `
or: [
{
dateOfBirth: {
greaterThanOrEqualTo: "${now.subtract(age[1], 'year').format('YYYY-MM-DD')}",
lessThanOrEqualTo: "${now.subtract(age[0], 'year').format('YYYY-MM-DD')}"
}
},
{
age: {
greaterThanOrEqualTo: ${age[0]}
lessThanOrEqualTo: ${age[1]}
}
}
]
` : '';
const heightFilter = height ? `height: { greaterThanOrEqualTo: ${height[0]}, lessThanOrEqualTo: ${height[1]} }` : '';
const weightFilter = weight ? `weight: { greaterThanOrEqualTo: ${weight[0]}, lessThanOrEqualTo: ${weight[1]} }` : '';
const cupFilter = boobSize ? `cup: { greaterThanOrEqualTo: "${boobSize[0]}", lessThanOrEqualTo: "${boobSize[1]}" }` : '';
console.log(ageFilter);
const { connection: { actors, totalCount } } = await graphql(`
query Actors(
@ -298,12 +321,13 @@ function initActorActions(store, router) {
startsWith: $letter
}
${genderFilter}
${ageFilter}
${heightFilter}
${weightFilter}
${cupFilter}
naturalBoobs: {
equalTo: $naturalBoobs
}
${cupFilter}
${heightFilter}
${weightFilter}
}
) {
totalCount