Added actors pagination.
This commit is contained in:
parent
424546029d
commit
aad43e865a
|
@ -182,7 +182,7 @@
|
||||||
.filter-label {
|
.filter-label {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: .5rem 0 .25rem .5rem;
|
padding: .5rem 0 .25rem .25rem;
|
||||||
color: var(--shadow);
|
color: var(--shadow);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
|
@ -209,7 +209,7 @@
|
||||||
height: 1.25rem;
|
height: 1.25rem;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
background-color: var(--shadow-weak-30);
|
background-color: var(--shadow-weak-40);
|
||||||
background-image: radial-gradient(circle, var(--shadow-weak-10) .3rem, transparent calc(.3rem + 1px));
|
background-image: radial-gradient(circle, var(--shadow-weak-10) .3rem, transparent calc(.3rem + 1px));
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
|
|
|
@ -57,5 +57,5 @@
|
||||||
--enabled-background: rgba(0, 255, 0, .1);
|
--enabled-background: rgba(0, 255, 0, .1);
|
||||||
--disabled: #c20;
|
--disabled: #c20;
|
||||||
--disabled-background: rgba(255, 0, 0, .1);
|
--disabled-background: rgba(255, 0, 0, .1);
|
||||||
--disabled-handle: #aaa;
|
--disabled-handle: var(--grey-light-10);
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,12 +62,13 @@ defineProps({
|
||||||
.actor {
|
.actor {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
width: 10rem;
|
width: 100%;
|
||||||
height: 15rem;
|
aspect-ratio: 2/3;
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: .25rem;
|
border-radius: .25rem;
|
||||||
margin: .25rem;
|
margin: .25rem;
|
||||||
box-shadow: 0 0 3px var(--shadow-weak-30);
|
box-shadow: 0 0 3px var(--shadow-weak-30);
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: 0 0 3px var(--shadow-weak-20);
|
box-shadow: 0 0 3px var(--shadow-weak-20);
|
||||||
|
@ -82,6 +83,9 @@ defineProps({
|
||||||
padding: .25rem .5rem;
|
padding: .25rem .5rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
font-size: .9rem;
|
font-size: .9rem;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
user-select: all;
|
user-select: all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -161,8 +161,8 @@ async function setRange(prop, value) {
|
||||||
border-radius: .625rem;
|
border-radius: .625rem;
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
--slider-range: var(--shadow-weak-30);
|
--slider-range: var(--shadow-weak-40);
|
||||||
--slider-thumb: var(--grey-dark-10);
|
--slider-thumb: var(--disabled-handle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,19 @@
|
||||||
<ul class="pages nolist">
|
<ul class="pages nolist">
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
:href="`/updates/${routeParams?.scope}/1`"
|
:href="getPath(1)"
|
||||||
:class="{ disabled: !hasPrevPage }"
|
:class="{ disabled: !hasPrevPage }"
|
||||||
class="page first nolink"
|
class="page first nolink"
|
||||||
|
@click="(event) => go(1, event)"
|
||||||
><Icon icon="first2" /></Link>
|
><Icon icon="first2" /></Link>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
:href="hasPrevPage ? `/updates/${routeParams?.scope}/${currentPage - 1}` : null"
|
:href="hasPrevPage ? getPath(currentPage - 1) : null"
|
||||||
:class="{ disabled: !hasPrevPage }"
|
:class="{ disabled: !hasPrevPage }"
|
||||||
class="page prev nolink"
|
class="page prev nolink"
|
||||||
|
@click="(event) => hasPrevPage && go(currentPage - 1, event)"
|
||||||
><Icon icon="arrow-left" /></Link>
|
><Icon icon="arrow-left" /></Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -21,14 +23,15 @@
|
||||||
<div class="index">
|
<div class="index">
|
||||||
<ul class="pages before wrap nolist">
|
<ul class="pages before wrap nolist">
|
||||||
<li
|
<li
|
||||||
v-for="page in prevPages"
|
v-for="prevPage in prevPages"
|
||||||
:key="`page-${page}`"
|
:key="`page-${prevPage}`"
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
:href="`/updates/${routeParams?.scope}/${page}`"
|
:href="getPath(prevPage)"
|
||||||
|
:class="{ active: prevPage === currentPage }"
|
||||||
class="page nolink"
|
class="page nolink"
|
||||||
:class="{ active: page === currentPage }"
|
@click="(event) => go(prevPage, event)"
|
||||||
>{{ page }}</Link>
|
>{{ prevPage }}</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@ -40,14 +43,15 @@
|
||||||
|
|
||||||
<ul class="pages after wrap nolist">
|
<ul class="pages after wrap nolist">
|
||||||
<li
|
<li
|
||||||
v-for="page in nextPages"
|
v-for="nextPage in nextPages"
|
||||||
:key="`page-${page}`"
|
:key="`page-${nextPage}`"
|
||||||
>
|
>
|
||||||
<Link
|
<Link
|
||||||
:href="`/updates/${routeParams?.scope}/${page}`"
|
:href="getPath(nextPage)"
|
||||||
|
:class="{ active: nextPage === currentPage }"
|
||||||
class="page nolink"
|
class="page nolink"
|
||||||
:class="{ active: page === currentPage }"
|
@click="(event) => go(nextPage, event)"
|
||||||
>{{ page }}</Link>
|
>{{ nextPage }}</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@ -55,17 +59,19 @@
|
||||||
<ul class="pages nolist">
|
<ul class="pages nolist">
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
:href="hasNextPage ? `/updates/${routeParams?.scope}/${currentPage + 1}` : null"
|
:href="hasNextPage ? getPath(currentPage + 1) : null"
|
||||||
:class="{ disabled: !hasNextPage }"
|
:class="{ disabled: !hasNextPage }"
|
||||||
class="page next nolink"
|
class="page next nolink"
|
||||||
|
@click="(event) => hasNextPage && go(currentPage + 1, event)"
|
||||||
><Icon icon="arrow-right" /></Link>
|
><Icon icon="arrow-right" /></Link>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
:href="`/updates/${routeParams?.scope}/${pageTotal}`"
|
:href="getPath(pageTotal)"
|
||||||
:class="{ disabled: !hasNextPage }"
|
:class="{ disabled: !hasNextPage }"
|
||||||
class="page last nolink"
|
class="page last nolink"
|
||||||
|
@click="(event) => go(pageTotal, event)"
|
||||||
><Icon icon="last2" /></Link>
|
><Icon icon="last2" /></Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -73,41 +79,87 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { inject } from 'vue';
|
import { computed, inject } from 'vue';
|
||||||
|
import { parse } from 'path-to-regexp';
|
||||||
|
|
||||||
const { routeParams, pageProps } = inject('pageContext');
|
const props = defineProps({
|
||||||
const currentPage = Number(routeParams?.page);
|
page: {
|
||||||
const limit = Number(pageProps.limit) || 30;
|
type: Number,
|
||||||
const total = Number(pageProps.total);
|
default: null,
|
||||||
const pageTotal = Math.ceil(total / limit);
|
},
|
||||||
const hasNextPage = currentPage + 1 <= pageTotal;
|
total: {
|
||||||
const hasPrevPage = currentPage - 1 >= 1;
|
type: Number,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
redirect: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
includeQuery: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
console.log(routeParams);
|
const emit = defineEmits(['navigation']);
|
||||||
|
|
||||||
const prevPages = Array.from({ length: 4 }, (value, index) => {
|
const pageContext = inject('pageContext');
|
||||||
const page = currentPage - index - 1;
|
const { routeParams, urlParsed, pageProps } = pageContext;
|
||||||
|
|
||||||
|
const currentPage = computed(() => props.page || Number(routeParams?.page));
|
||||||
|
|
||||||
|
const limit = computed(() => props.limit || Number(pageProps.limit) || 30);
|
||||||
|
const total = computed(() => props.total || Number(pageProps.total));
|
||||||
|
const pageTotal = computed(() => Math.ceil(total.value / limit.value));
|
||||||
|
|
||||||
|
const hasNextPage = computed(() => currentPage.value + 1 <= pageTotal.value);
|
||||||
|
const hasPrevPage = computed(() => currentPage.value - 1 >= 1);
|
||||||
|
|
||||||
|
const prevPages = computed(() => Array.from({ length: 4 }, (value, index) => {
|
||||||
|
const page = currentPage.value - index - 1;
|
||||||
|
|
||||||
if (page < 1) {
|
if (page < 1) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
}).filter(Boolean);
|
}).filter(Boolean));
|
||||||
|
|
||||||
const nextPages = Array.from({ length: 4 }, (value, index) => {
|
const nextPages = computed(() => Array.from({ length: 4 }, (value, index) => {
|
||||||
const page = currentPage + index + 1;
|
const page = currentPage.value + index + 1;
|
||||||
|
|
||||||
if (page > pageTotal) {
|
if (page > pageTotal.value) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
}).filter(Boolean);
|
}).filter(Boolean));
|
||||||
|
|
||||||
console.log(total, limit, currentPage);
|
function go(page, event) {
|
||||||
console.log(prevPages);
|
if (!props.redirect) {
|
||||||
console.log(nextPages);
|
event.preventDefault();
|
||||||
|
|
||||||
|
history.pushState({}, '', event.target.href); // eslint-disable-line no-restricted-globals
|
||||||
|
currentPage.value = page;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('navigation', {
|
||||||
|
href: event.target.href,
|
||||||
|
page,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPath(page) {
|
||||||
|
const path = parse(routeParams.path)
|
||||||
|
.map((segment) => (segment.name === 'page' ? String(page) : routeParams[segment.name] || segment))
|
||||||
|
.join('/');
|
||||||
|
|
||||||
|
if (props.includeQuery && urlParsed.searchOriginal) {
|
||||||
|
return `${path}${urlParsed.searchOriginal}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return path;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
@ -115,6 +167,7 @@ console.log(nextPages);
|
||||||
height: 5rem;
|
height: 5rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
box-sizing: border-box;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineProps, inject } from 'vue';
|
import { inject } from 'vue';
|
||||||
|
|
||||||
import Scene from './tile.vue';
|
import Scene from './tile.vue';
|
||||||
import Pagination from '../pagination/pagination.vue';
|
import Pagination from '../pagination/pagination.vue';
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
"manticoresearch": "^4.0.0",
|
"manticoresearch": "^4.0.0",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"nanoid": "^5.0.4",
|
"nanoid": "^5.0.4",
|
||||||
|
"path-to-regexp": "^6.2.1",
|
||||||
"pg": "^8.11.3",
|
"pg": "^8.11.3",
|
||||||
"sirv": "^2.0.3",
|
"sirv": "^2.0.3",
|
||||||
"vike": "^0.4.150",
|
"vike": "^0.4.150",
|
||||||
|
@ -4381,6 +4382,11 @@
|
||||||
"resolved": "https://registry.npmjs.org/express-query-boolean/-/express-query-boolean-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/express-query-boolean/-/express-query-boolean-2.0.0.tgz",
|
||||||
"integrity": "sha512-4dU/1HPm8lkTPR12+HFUXqCarcsC19OKOkb4otLOuADfPYrQMaugPJkSmxNsqwmWYjozvT6vdTiqkgeBHkzOow=="
|
"integrity": "sha512-4dU/1HPm8lkTPR12+HFUXqCarcsC19OKOkb4otLOuADfPYrQMaugPJkSmxNsqwmWYjozvT6vdTiqkgeBHkzOow=="
|
||||||
},
|
},
|
||||||
|
"node_modules/express/node_modules/path-to-regexp": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||||
|
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
||||||
|
},
|
||||||
"node_modules/express/node_modules/safe-buffer": {
|
"node_modules/express/node_modules/safe-buffer": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
@ -5840,9 +5846,9 @@
|
||||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||||
},
|
},
|
||||||
"node_modules/path-to-regexp": {
|
"node_modules/path-to-regexp": {
|
||||||
"version": "0.1.7",
|
"version": "6.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
|
||||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
"integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw=="
|
||||||
},
|
},
|
||||||
"node_modules/pg": {
|
"node_modules/pg": {
|
||||||
"version": "8.11.3",
|
"version": "8.11.3",
|
||||||
|
@ -10758,6 +10764,11 @@
|
||||||
"vary": "~1.1.2"
|
"vary": "~1.1.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"path-to-regexp": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||||
|
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
||||||
|
},
|
||||||
"safe-buffer": {
|
"safe-buffer": {
|
||||||
"version": "5.2.1",
|
"version": "5.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||||
|
@ -11806,9 +11817,9 @@
|
||||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||||
},
|
},
|
||||||
"path-to-regexp": {
|
"path-to-regexp": {
|
||||||
"version": "0.1.7",
|
"version": "6.2.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.1.tgz",
|
||||||
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
|
"integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw=="
|
||||||
},
|
},
|
||||||
"pg": {
|
"pg": {
|
||||||
"version": "8.11.3",
|
"version": "8.11.3",
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
"manticoresearch": "^4.0.0",
|
"manticoresearch": "^4.0.0",
|
||||||
"mitt": "^3.0.1",
|
"mitt": "^3.0.1",
|
||||||
"nanoid": "^5.0.4",
|
"nanoid": "^5.0.4",
|
||||||
|
"path-to-regexp": "^6.2.1",
|
||||||
"pg": "^8.11.3",
|
"pg": "^8.11.3",
|
||||||
"sirv": "^2.0.3",
|
"sirv": "^2.0.3",
|
||||||
"vike": "^0.4.150",
|
"vike": "^0.4.150",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="page">
|
<div class="page">
|
||||||
<form
|
<form
|
||||||
|
v-show="showFilters"
|
||||||
class="filters"
|
class="filters"
|
||||||
@submit.prevent
|
@submit.prevent
|
||||||
>
|
>
|
||||||
|
@ -192,7 +193,7 @@
|
||||||
v-if="!filters.country"
|
v-if="!filters.country"
|
||||||
v-model="countryQuery"
|
v-model="countryQuery"
|
||||||
type="search"
|
type="search"
|
||||||
placeholder="Search country"
|
placeholder="Filter country"
|
||||||
class="input input-inline countries-search"
|
class="input input-inline countries-search"
|
||||||
>
|
>
|
||||||
|
|
||||||
|
@ -221,16 +222,45 @@
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ul class="actors nolist">
|
<div class="actors-anchor">
|
||||||
<li
|
<div
|
||||||
v-for="actor in actors"
|
class="sidebar-toggle"
|
||||||
:key="`actor-${actor.id}`"
|
@click="toggleFilters"
|
||||||
>
|
>
|
||||||
<ActorTile
|
<Icon
|
||||||
:actor="actor"
|
v-show="showFilters"
|
||||||
|
icon="arrow-left3"
|
||||||
/>
|
/>
|
||||||
</li>
|
|
||||||
</ul>
|
<Icon
|
||||||
|
v-show="!showFilters"
|
||||||
|
icon="arrow-right3"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
ref="container"
|
||||||
|
class="actors-container"
|
||||||
|
>
|
||||||
|
<ul class="actors nolist">
|
||||||
|
<li
|
||||||
|
v-for="actor in actors"
|
||||||
|
:key="`actor-${actor.id}`"
|
||||||
|
>
|
||||||
|
<ActorTile
|
||||||
|
:actor="actor"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<Pagination
|
||||||
|
:page="currentPage"
|
||||||
|
:total="total"
|
||||||
|
:redirect="false"
|
||||||
|
@navigation="paginate"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -242,16 +272,21 @@ import navigate from '#/src/navigate.js';
|
||||||
import { get } from '#/src/api.js';
|
import { get } from '#/src/api.js';
|
||||||
|
|
||||||
import ActorTile from '#/components/actors/tile.vue';
|
import ActorTile from '#/components/actors/tile.vue';
|
||||||
|
import Pagination from '#/components/pagination/pagination.vue';
|
||||||
import Gender from '#/components/actors/gender.vue';
|
import Gender from '#/components/actors/gender.vue';
|
||||||
import Checkbox from '#/components/form/checkbox.vue';
|
import Checkbox from '#/components/form/checkbox.vue';
|
||||||
import RangeFilter from '#/components/filters/range.vue';
|
import RangeFilter from '#/components/filters/range.vue';
|
||||||
import Countries from '#/components/filters/countries.vue';
|
import Countries from '#/components/filters/countries.vue';
|
||||||
|
|
||||||
const { pageProps, urlParsed } = inject('pageContext');
|
const pageContext = inject('pageContext');
|
||||||
|
const { pageProps, urlParsed, routeParams } = pageContext;
|
||||||
|
|
||||||
const q = ref(urlParsed.search.q);
|
const q = ref(urlParsed.search.q);
|
||||||
const actors = ref([]);
|
const actors = ref([]);
|
||||||
|
|
||||||
|
const container = ref(null);
|
||||||
|
const showFilters = ref(true);
|
||||||
|
|
||||||
const countries = ref(pageProps.countries);
|
const countries = ref(pageProps.countries);
|
||||||
const countryQuery = ref('');
|
const countryQuery = ref('');
|
||||||
|
|
||||||
|
@ -266,6 +301,9 @@ actors.value = pageProps.actors;
|
||||||
const braSizes = 'ABCDEFGHIJKZ'.split('');
|
const braSizes = 'ABCDEFGHIJKZ'.split('');
|
||||||
const naturalBoobsValues = [true, undefined, false];
|
const naturalBoobsValues = [true, undefined, false];
|
||||||
|
|
||||||
|
const currentPage = ref(Number(routeParams.page));
|
||||||
|
const total = ref(Number(pageProps.total));
|
||||||
|
|
||||||
const filters = ref({
|
const filters = ref({
|
||||||
gender: urlParsed.search.gender,
|
gender: urlParsed.search.gender,
|
||||||
ageRequired: !!urlParsed.search.age,
|
ageRequired: !!urlParsed.search.age,
|
||||||
|
@ -284,9 +322,11 @@ const filters = ref({
|
||||||
avatarRequired: !!urlParsed.search.avatar,
|
avatarRequired: !!urlParsed.search.avatar,
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(filters.value.dobType);
|
async function search(resetPage = true) {
|
||||||
|
if (resetPage) {
|
||||||
|
currentPage.value = 1;
|
||||||
|
}
|
||||||
|
|
||||||
async function search() {
|
|
||||||
const query = {
|
const query = {
|
||||||
q: q.value || undefined,
|
q: q.value || undefined,
|
||||||
gender: filters.value.gender || undefined,
|
gender: filters.value.gender || undefined,
|
||||||
|
@ -301,12 +341,21 @@ async function search() {
|
||||||
avatar: filters.value.avatarRequired || undefined,
|
avatar: filters.value.avatarRequired || undefined,
|
||||||
};
|
};
|
||||||
|
|
||||||
navigate('/actors', query, { redirect: false });
|
const res = await get('/actors', { ...query, page: currentPage.value }); // client uses param rather than query pagination
|
||||||
|
|
||||||
const res = await get('/actors', query);
|
|
||||||
|
|
||||||
actors.value = res.actors;
|
actors.value = res.actors;
|
||||||
|
total.value = res.total;
|
||||||
|
|
||||||
countries.value = res.countries;
|
countries.value = res.countries;
|
||||||
|
|
||||||
|
container.value.scrollTop = 0;
|
||||||
|
|
||||||
|
navigate(`/actors/${currentPage.value}`, query, { redirect: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
function paginate({ page }) {
|
||||||
|
currentPage.value = page;
|
||||||
|
search(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateFilter(prop, value, reload = true) {
|
function updateFilter(prop, value, reload = true) {
|
||||||
|
@ -316,6 +365,10 @@ function updateFilter(prop, value, reload = true) {
|
||||||
search();
|
search();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleFilters() {
|
||||||
|
showFilters.value = !showFilters.value;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
@ -355,6 +408,7 @@ function updateFilter(prop, value, reload = true) {
|
||||||
|
|
||||||
.filters {
|
.filters {
|
||||||
width: 17rem;
|
width: 17rem;
|
||||||
|
position: relative;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
border-right: solid 1px var(--shadow-weak-30);
|
border-right: solid 1px var(--shadow-weak-30);
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
@ -365,17 +419,57 @@ function updateFilter(prop, value, reload = true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
.filter {
|
.filter {
|
||||||
padding: .5rem .25rem;
|
padding: .5rem;
|
||||||
border-bottom: solid 1px var(--shadow-weak-30);
|
|
||||||
|
&:not(:last-child) {
|
||||||
|
border-bottom: solid 1px var(--shadow-weak-30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.actors-anchor {
|
||||||
|
flex-grow: 1;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sidebar-toggle {
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 2rem;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
bottom: .5rem;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10;
|
||||||
|
border-radius: 0 .25rem .25rem 0;
|
||||||
|
background: var(--background);
|
||||||
|
box-shadow: 0 0 3px var(--shadow-weak-30);
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
fill: var(--shadow);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
fill: var(--primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.actors-container {
|
||||||
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 1rem;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.actors {
|
.actors {
|
||||||
display: grid;
|
display: grid;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
grid-template-columns: repeat(auto-fill, 10rem);
|
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
|
||||||
gap: .25rem;
|
gap: .25rem;
|
||||||
padding: 1rem;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.genders {
|
.genders {
|
||||||
|
@ -430,10 +524,17 @@ function updateFilter(prop, value, reload = true) {
|
||||||
|
|
||||||
.select {
|
.select {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
color: var(--shadow-strong-10);
|
||||||
|
|
||||||
|
option {
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.countries-container {
|
.countries-container {
|
||||||
border-bottom: solid 1px var(--shadow-weak-30);
|
border-bottom: solid 1px var(--shadow-weak-30);
|
||||||
|
padding: .25rem 0;
|
||||||
|
margin-bottom: .5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.countries-search {
|
.countries-search {
|
||||||
|
|
|
@ -9,7 +9,7 @@ export async function onBeforeRender(pageContext) {
|
||||||
total,
|
total,
|
||||||
} = await fetchActors(curateActorsQuery(pageContext.urlQuery), {
|
} = await fetchActors(curateActorsQuery(pageContext.urlQuery), {
|
||||||
page: Number(pageContext.routeParams.page) || 1,
|
page: Number(pageContext.routeParams.page) || 1,
|
||||||
limit: Number(pageContext.urlParsed.search.limit) || 50,
|
limit: Number(pageContext.urlParsed.search.limit) || 120,
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { match } from 'path-to-regexp';
|
||||||
|
// import { resolveRoute } from 'vike/routing'; // eslint-disable-line import/extensions
|
||||||
|
|
||||||
|
const path = '/actors/:page?';
|
||||||
|
const urlMatch = match(path, { decode: decodeURIComponent });
|
||||||
|
|
||||||
|
export default (pageContext) => {
|
||||||
|
const matched = urlMatch(pageContext.urlPathname);
|
||||||
|
|
||||||
|
if (matched) {
|
||||||
|
return {
|
||||||
|
routeParams: {
|
||||||
|
page: matched.params.page || '1',
|
||||||
|
path,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
|
@ -1 +1 @@
|
||||||
export default '/actors/@actorId/*';
|
export default '/actor/@actorId/*';
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { fetchLatest, fetchUpcoming, fetchNew } from '../../src/scenes';
|
import { fetchLatest, fetchUpcoming, fetchNew } from '#/src/scenes.js';
|
||||||
|
|
||||||
async function fetchScenes(scope, page, limit) {
|
async function fetchScenes(scope, page, limit) {
|
||||||
if (scope === 'new') {
|
if (scope === 'new') {
|
||||||
|
|
|
@ -1,33 +1,20 @@
|
||||||
import { resolveRoute } from 'vike/routing';
|
import { match } from 'path-to-regexp';
|
||||||
|
// import { resolveRoute } from 'vike/routing'; // eslint-disable-line import/extensions
|
||||||
|
|
||||||
|
const path = '/updates/:scope?/:page?';
|
||||||
|
const urlMatch = match(path, { decode: decodeURIComponent });
|
||||||
|
|
||||||
export default (pageContext) => {
|
export default (pageContext) => {
|
||||||
{
|
const matched = urlMatch(pageContext.urlPathname);
|
||||||
const result = resolveRoute('/updates/@scope/@page', pageContext.urlPathname);
|
|
||||||
|
|
||||||
if (result.match) {
|
if (matched) {
|
||||||
return result;
|
return {
|
||||||
}
|
routeParams: {
|
||||||
}
|
scope: matched.params.scope || 'latest',
|
||||||
|
page: matched.params.page || '1',
|
||||||
{
|
path,
|
||||||
const result = resolveRoute('/updates/@scope', pageContext.urlPathname);
|
},
|
||||||
|
};
|
||||||
if (result.match) {
|
|
||||||
result.routeParams.page = '1';
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const result = resolveRoute('/updates', pageContext.urlPathname);
|
|
||||||
|
|
||||||
if (result.match) {
|
|
||||||
result.routeParams.scope = 'latest';
|
|
||||||
result.routeParams.page = '1';
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -62,20 +62,23 @@ export async function fetchActorsById(actorIds) {
|
||||||
.groupBy('actors.id', 'avatars.id'),
|
.groupBy('actors.id', 'avatars.id'),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return actorIds.map((actorId) => {
|
const curatedActors = actorIds.map((actorId) => {
|
||||||
const actor = actors.find((actorEntry) => actorEntry.id === actorId);
|
const actor = actors.find((actorEntry) => actorEntry.id === actorId);
|
||||||
|
|
||||||
if (!actor) {
|
if (!actor) {
|
||||||
|
console.warn(`Can't find ${actorId}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return curateActor(actor);
|
return curateActor(actor);
|
||||||
}).filter(Boolean);
|
}).filter(Boolean);
|
||||||
|
|
||||||
|
return curatedActors;
|
||||||
}
|
}
|
||||||
|
|
||||||
function curateOptions(options) {
|
function curateOptions(options) {
|
||||||
if (options?.limit > 100) {
|
if (options?.limit > 120) {
|
||||||
throw new HttpError('Limit must be <= 100', 400);
|
throw new HttpError('Limit must be <= 120', 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -108,8 +111,6 @@ function buildQuery(filters) {
|
||||||
|
|
||||||
['gender', 'country'].forEach((attribute) => {
|
['gender', 'country'].forEach((attribute) => {
|
||||||
if (filters[attribute]) {
|
if (filters[attribute]) {
|
||||||
console.log(attribute, filters[attribute]);
|
|
||||||
|
|
||||||
query.bool.must.push({
|
query.bool.must.push({
|
||||||
equals: {
|
equals: {
|
||||||
[attribute]: filters[attribute],
|
[attribute]: filters[attribute],
|
||||||
|
@ -197,6 +198,9 @@ export async function fetchActors(filters, rawOptions) {
|
||||||
const options = curateOptions(rawOptions);
|
const options = curateOptions(rawOptions);
|
||||||
const { query, expressions } = buildQuery(filters);
|
const { query, expressions } = buildQuery(filters);
|
||||||
|
|
||||||
|
console.log(options);
|
||||||
|
console.log('offset', (options.page - 1) * options.limit);
|
||||||
|
|
||||||
const result = await searchApi.search({
|
const result = await searchApi.search({
|
||||||
index: 'actors',
|
index: 'actors',
|
||||||
query,
|
query,
|
||||||
|
|
|
@ -24,8 +24,6 @@ function curateScene(rawScene, assets) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(assets.channel);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: rawScene.id,
|
id: rawScene.id,
|
||||||
title: rawScene.title,
|
title: rawScene.title,
|
||||||
|
|
|
@ -26,7 +26,7 @@ export async function fetchActorsApi(req, res) {
|
||||||
total,
|
total,
|
||||||
} = await fetchActors(curateActorsQuery(req.query), {
|
} = await fetchActors(curateActorsQuery(req.query), {
|
||||||
page: Number(req.query.page) || 1,
|
page: Number(req.query.page) || 1,
|
||||||
limit: Number(req.query.limit) || 50,
|
limit: Number(req.query.limit) || 120,
|
||||||
});
|
});
|
||||||
|
|
||||||
res.send({
|
res.send({
|
||||||
|
|
Loading…
Reference in New Issue