Added dark theme. Fixed actor country aggregation.

This commit is contained in:
DebaucheryLibrarian 2024-06-10 03:24:48 +02:00
parent 255dd48af6
commit 69cefa57ff
38 changed files with 299 additions and 153 deletions

View File

@ -3,9 +3,10 @@
padding: .5rem .75rem;
font-size: 1rem;
flex-basis: 0;
border: solid 1px var(--grey-light-30);
color: inherit;
border: solid 1px var(--glass-weak-30);
border-radius: .25rem;
background: var(--grey-light-60);
background: var(--background-base-10);
font: inherit;
&:focus {
@ -31,14 +32,14 @@
border-radius: .25rem;
background: var(--background);
box-shadow: 0 0 3px var(--shadow-weak-30);
color: var(--shadow-strong-20);
color: var(--glass);
font-size: .9rem;
font-weight: bold;
.icon {
height: auto;
padding: 0 .75rem 0 .25rem;
fill: var(--shadow-strong-10);
fill: var(--glass);
}
&:hover {
@ -70,7 +71,7 @@
}
&:disabled {
background: var(--shadow-weak-10);
background: var(--glass);
}
}
@ -84,7 +85,7 @@
}
&:disabled {
background: var(--shadow-weak-10);
background: var(--glass);
}
}
@ -118,7 +119,7 @@
.button-cancel {
background: none;
color: var(--shadow-strong-10);
color: var(--glass);
font-weight: normal;
&:hover:not(:disabled) {
@ -127,7 +128,7 @@
}
&:disabled {
color: var(--shadow-weak-10);
color: var(--glass);
}
}
@ -137,7 +138,6 @@
.filter-section {
width: 100%;
border-bottom: solid 1px var(--shadow-hint);
margin-bottom: .25rem;
}
@ -209,7 +209,7 @@
min-width: 1.5rem;
flex-shrink: 0;
padding: 0 .5rem;
color: var(--shadow);
color: var(--glass);
font-weight: bold;
font-size: .9rem;
@ -218,7 +218,7 @@
}
.icon {
fill: var(--shadow);
fill: var(--glass);
}
&:hover {
@ -246,7 +246,7 @@
display: flex;
justify-content: space-between;
padding: .5rem 0 .25rem .25rem;
color: var(--shadow);
color: var(--glass);
font-weight: bold;
font-size: .9rem;
@ -272,8 +272,8 @@
height: 1.25rem;
appearance: none;
border-radius: 1rem;
background-color: var(--shadow-weak-40);
background-image: radial-gradient(circle, var(--shadow-weak-10) .3rem, transparent calc(.3rem + 1px));
background-color: var(--glass-weak-40);
background-image: radial-gradient(circle, var(--glass-weak-10) .3rem, transparent calc(.3rem + 1px));
cursor: pointer;
&::-webkit-slider-thumb {

View File

@ -49,6 +49,16 @@
--highlight-strong-20: rgba(255, 255, 255, .75);
--highlight-strong-30: rgba(255, 255, 255, .9);
--glass-weak-50: rgba(0, 0, 0, .02);
--glass-weak-40: rgba(0, 0, 0, .05);
--glass-weak-30: rgba(0, 0, 0, .1);
--glass-weak-20: rgba(0, 0, 0, .2);
--glass-weak-10: rgba(0, 0, 0, .35);
--glass: rgba(0, 0, 0, .5);
--glass-strong-10: rgba(0, 0, 0, .6);
--glass-strong-20: rgba(0, 0, 0, .75);
--glass-strong-30: rgba(0, 0, 0, .9);
--text: #222;
--text-light: #fff;
@ -71,3 +81,42 @@
--gold: #d5b522;
}
.dark {
--background-dark-20: #000;
--background-dark-10: #111;
--background: #222;
--background-base: #252525;
--background-base-10: #1a1a1a;
--background-base-20: #050505;
--background-level-10: #fff;
--background-level-20: #eee;
--background-level-30: #eee;
--background-dim: var(--shadow-weak-10);
--text: #fcfcfc;
--glass-weak-50: rgba(255, 255, 255, .02);
--glass-weak-40: rgba(255, 255, 255, .05);
--glass-weak-30: rgba(255, 255, 255, .1);
--glass-weak-20: rgba(255, 255, 255, .2);
--glass-weak-10: rgba(255, 255, 255, .35);
--glass: rgba(255, 255, 255, .5);
--glass-strong-10: rgba(255, 255, 255, .6);
--glass-strong-20: rgba(255, 255, 255, .75);
--glass-strong-30: rgba(255, 255, 255, .9);
--grey-dark-50: #101010;
--grey-dark-40: #1f1f1f;
--grey-dark-30: #3c3c3c;
--grey-dark-20: #606060;
--grey-dark-10: #808080;
--grey: #aaa;
--grey-light-10: #bbb;
--grey-light-20: #ccc;
--grey-light-30: #ddd;
--grey-light-40: #eee;
--grey-light-50: #fafafa;
--grey-light-60: #fcfcfc;
}

View File

@ -177,20 +177,20 @@
/* Dropdown */
.v-popper--theme-dropdown .v-popper__inner {
background: #fff;
color: black;
background: var(--background);
color: var(--text);
border-radius: 6px;
border: 1px solid #ddd;
border: solid 1px var(--glass-weak-40);
box-shadow: 0 6px 30px rgba(0, 0, 0, .1);
}
.v-popper--theme-dropdown .v-popper__arrow-inner {
visibility: visible;
border-color: #fff;
border-color: var(--background);
}
.v-popper--theme-dropdown .v-popper__arrow-outer {
border-color: #ddd;
border-color: var(--glass-weak-40);
}
.resize-observer {

View File

@ -266,6 +266,7 @@ function updateFilter(prop, value, reload = true) {
min-height: 100%;
display: flex;
align-items: stretch;
background: var(--background-base-10);
}
.actors-container {

View File

@ -568,14 +568,14 @@ function selectStash(selectedStash) {
flex-shrink: 0;
width: 3.5rem;
font-size: .9rem;
color: var(--shadow);
color: var(--glass);
&.item-logic {
width: 2.75rem;
}
.icon {
fill: var(--shadow);
fill: var(--glass);
}
}
@ -586,11 +586,11 @@ function selectStash(selectedStash) {
flex-grow: 1;
gap: .5rem 0;
padding: .5rem 0;
border-bottom: solid 1px var(--shadow-weak-40);
border-bottom: solid 1px var(--glass-weak-40);
&.or .field-item::before,
&.and .field-item::before {
color: var(--shadow);
color: var(--glass);
padding: 0 .5rem;
}
@ -621,7 +621,7 @@ function selectStash(selectedStash) {
right: -.5rem;
padding: .2rem;
border-radius: 1rem;
fill: var(--shadow);
fill: var(--glass);
background: var(--background);
box-shadow: 0 0 3px var(--shadow-weak-20);
@ -681,7 +681,7 @@ function selectStash(selectedStash) {
display: flex;
justify-content: space-between;
padding: .5rem 1rem;
border-bottom: solid 1px var(--shadow-weak-40);
border-bottom: solid 1px var(--glass-weak-40);
}
.field-items {

View File

@ -1,5 +1,5 @@
<template>
<Teleport to="body">
<Teleport to="#container">
<div
class="dialog-container"
@click="emit('close')"
@ -55,7 +55,7 @@ onMounted(() => emit('open'));
.dialog-description {
margin: 0 0 .5rem 0;
color: var(--shadow-strong-10);
color: var(--glass-strong-10);
font-size: .9rem;
line-height: 1.5;
}

View File

@ -33,7 +33,7 @@ defineProps({
box-sizing: border-box;
padding: 1rem;
border-radius: .5rem;
background: var(--grey-dark-40);
background: var(--shadow-strong-40);
color: var(--text-light);
font-size: 1.25rem;
font-weight: bold;

View File

@ -80,7 +80,7 @@ const emit = defineEmits(['update']);
.select {
flex-grow: 1;
color: var(--shadow-strong-10);
color: var(--glass-strong-10);
option {
color: var(--text);

View File

@ -171,7 +171,7 @@ const entities = computed(() => {
width: 2.25rem;
height: 1rem;
transform: rotate(-135deg);
fill: var(--shadow-weak-30);
fill: var(--glass-weak-30);
overflow: hidden; /* prevent parent jumping on load */
}
}

View File

@ -42,7 +42,7 @@ const emit = defineEmits(['country']);
<style scoped>
.countries:not(:last-child) {
border-bottom: solid 1px var(--shadow-weak-30);
border-bottom: solid 1px var(--glass-weak-30);
}
.country {
@ -57,7 +57,7 @@ const emit = defineEmits(['country']);
}
&:hover {
background: var(--shadow-weak-30);
background: var(--glass-weak-30);
cursor: pointer;
}
@ -78,7 +78,7 @@ const emit = defineEmits(['country']);
display: flex;
align-items: center;
padding: .5rem;
fill: var(--shadow);
fill: var(--glass);
&:hover {
fill: var(--error);

View File

@ -81,7 +81,7 @@ function toggleFilters(state) {
}
&:not(:last-child) {
border-bottom: solid 1px var(--shadow-weak-30);
border-bottom: solid 1px var(--glass-weak-30);
}
}
@ -98,7 +98,7 @@ function toggleFilters(state) {
display: flex;
align-items: center;
padding-left: .5rem;
fill: var(--shadow);
fill: var(--glass);
&:hover {
cursor: pointer;
@ -109,13 +109,13 @@ function toggleFilters(state) {
.filter-mode {
width: 100%;
color: var(--shadow);
color: var(--glass);
background: none;
padding: .75rem;
margin: 0 0 .5rem 0;
font-size: 1rem;
border: none;
border-bottom: solid 1px var(--shadow-hint);
border-bottom: solid 1px var(--glass-weak-40);
option {
color: var(--text-dark);
@ -124,7 +124,7 @@ function toggleFilters(state) {
.filters-sort {
display: flex;
border-bottom: solid 1px var(--shadow-weak-30);
border-bottom: solid 1px var(--glass-weak-30);
}
.filters-search {
@ -138,25 +138,25 @@ function toggleFilters(state) {
align-items: center;
justify-content: space-between;
padding: .5rem 1rem;
color: var(--shadow-weak-10);
color: var(--glass-weak-10);
text-decoration: none;
cursor: default;
.icon {
fill: var(--shadow-weak-30);
fill: var(--glass-weak-30);
margin: 0 0 0 1rem;
}
&.active {
color: var(--shadow);
color: var(--glass);
.icon {
fill: var(--shadow-weak-10);
fill: var(--glass-weak-10);
}
&:hover {
color: var(--text);
background: var(--shadow-hint);
background: var(--glass-weak-30);
cursor: pointer;
.icon {
@ -184,7 +184,7 @@ function toggleFilters(state) {
align-items: stretch;
&:hover {
background: var(--shadow-weak-30);
background: var(--glass-weak-30);
cursor: pointer;
}
@ -240,7 +240,7 @@ function toggleFilters(state) {
.icon {
width: 1rem;
padding: 0 .75rem;
fill: var(--shadow-weak-30);
fill: var(--glass-weak-30);
}
.filter-remove {
@ -255,7 +255,7 @@ function toggleFilters(state) {
.filter-include:hover,
.filter-name:hover {
background: var(--shadow-weak-30);
background: var(--glass-weak-30);
}
.filter-sort {
@ -267,14 +267,14 @@ function toggleFilters(state) {
padding: 0 .25rem;
cursor: pointer;
font-weight: bold;
color: var(--shadow);
color: var(--glass);
&.order {
padding: 0 .5rem 0 .25rem;
}
.icon {
fill: var(--shadow);
fill: var(--glass);
}
&:hover {
@ -293,7 +293,7 @@ function toggleFilters(state) {
.filter-remove.icon {
padding: .25rem .6rem;
fill: var(--shadow);
fill: var(--glass);
&:hover {
fill: var(--alert);
@ -308,13 +308,13 @@ function toggleFilters(state) {
justify-content: flex-end;
padding: 0 .25rem;
overflow: hidden;
color: var(--shadow-weak-10);
color: var(--glass-weak-10);
font-size: .9rem;
}
.filter-empty {
padding: .5rem;
color: var(--shadow);
color: var(--glass);
font-style: italic;
}
@ -329,7 +329,7 @@ function toggleFilters(state) {
@media (--compact) {
.filter {
border-right: solid 1px var(--shadow-weak-30);
border-right: solid 1px var(--glass-weak-30);
}
}
</style>
@ -377,7 +377,7 @@ function toggleFilters(state) {
right: -2.5rem;
border-radius: 0 .5rem .5rem 0;
background: var(--background);
color: var(--shadow);
color: var(--glass);
font-weight: bold;
box-shadow: inset 0 0 3px var(--shadow-weak-30);
@ -395,7 +395,7 @@ function toggleFilters(state) {
}
.icon {
fill: var(--shadow);
fill: var(--glass);
}
&:hover {

View File

@ -75,7 +75,8 @@ const emit = defineEmits(['update']);
justify-content: center;
box-sizing: border-box;
border: none;
color: var(--shadow);
border-radius: 100%;
color: var(--glass);
background: var(--background);
font-weight: bold;
text-decoration: none;
@ -89,7 +90,7 @@ const emit = defineEmits(['update']);
}
.icon {
fill: var(--shadow);
fill: var(--glass);
}
&:hover {

View File

@ -41,10 +41,10 @@ const { env } = pageContext;
display: inline-flex;
align-items: center;
padding: .5rem 1rem;
color: var(--shadow);
color: var(--glass);
&:not(:first-child) {
border-left: solid 1px var(--shadow-weak-30);
border-left: solid 1px var(--glass-weak-30);
}
}
@ -59,6 +59,6 @@ const { env } = pageContext;
.discord .icon {
height: 1.25rem;
width: 3.5rem;
fill: var(--shadow-strong-10);
fill: var(--glass-strong-10);
}
</style>

View File

@ -53,7 +53,7 @@ defineEmits(['change']);
justify-content: center;
flex-shrink: 0;
position: relative;
background-color: var(--shadow-weak-30);
background-color: var(--glass-weak-30);
border-radius: .25rem;
cursor: pointer;
transition: background .15s ease;

View File

@ -148,10 +148,11 @@ async function setRange(prop, value) {
.range-container {
display: flex;
justify-content: space-between;
font-size: 0;
}
.range {
--slider-track: var(--shadow-weak-30);
--slider-track: var(--glass-weak-30);
--slider-range: var(--primary-light-30);
--slider-thumb: var(--primary);
@ -161,7 +162,7 @@ async function setRange(prop, value) {
border-radius: .625rem;
&.disabled {
--slider-range: var(--shadow-weak-40);
--slider-range: var(--glass-weak-40);
--slider-thumb: var(--disabled-handle);
}
}
@ -221,6 +222,6 @@ async function setRange(prop, value) {
width: 1.25rem;
height: 1.25rem;
flex-shrink: 0;
fill: var(--shadow);
fill: var(--glass);
}
</style>

View File

@ -79,11 +79,11 @@
</form>
<div
v-if="user"
class="userpanel"
:class="{ searching: searchFocused }"
>
<VDropdown
v-if="user"
:triggers="['click']"
:prevent-overflow="true"
class="notifs-trigger"
@ -115,21 +115,35 @@
<VDropdown
:triggers="['click']"
:prevent-overflow="true"
class="menu-trigger"
>
<img
:src="user.avatar"
class="avatar"
>
<div class="avatar-container">
<img
v-if="user"
:src="user.avatar"
class="avatar"
>
<Icon
v-else
icon="user7"
class="avatar-placeholder"
/>
</div>
<template #popper>
<div class="menu">
<a
v-if="user"
:href="`/user/${user.username}`"
class="menu-header ellipsis"
>{{ user.username }}</a>
<ul class="menu-list nolist">
<li class="menu-item">
<li
v-if="user"
class="menu-item"
>
<a
:href="`/user/${user.username}`"
class="menu-button nolink"
@ -140,7 +154,21 @@
</li>
<li
v-if="user.primaryStash"
v-else-if="allowLogin"
v-close-popper
class="menu-item"
>
<a
:href="`/login?r=${encodeURIComponent(currentPath)}`"
class="menu-button nolink"
>
<Icon icon="enter" />
Log in
</a>
</li>
<li
v-if="user?.primaryStash"
class="menu-item"
>
<a
@ -161,6 +189,26 @@
Settings
</li>
<li
v-if="theme === 'dark'"
v-close-popper
class="menu-item menu-button"
@click="setTheme('light')"
>
<Icon icon="sun3" />
Light theme
</li>
<li
v-else
v-close-popper
class="menu-item menu-button"
@click="setTheme('dark')"
>
<Icon icon="moon" />
Dark theme
</li>
<li
class="menu-button menu-item logout"
@click="logout"
@ -170,20 +218,6 @@
</template>
</VDropdown>
</div>
<div
v-else-if="allowLogin"
class="userpanel"
:class="{ searching: searchFocused }"
>
<a
:href="`/login?r=${encodeURIComponent(currentPath)}`"
class="login button button-submit nolink"
>
<span class="login-text">Log in</span>
<Icon icon="enter" />
</a>
</div>
</div>
<Settings
@ -205,8 +239,11 @@ import {
inject,
} from 'vue';
import Cookies from 'js-cookie';
import navigate from '#/src/navigate.js';
import { del } from '#/src/api.js';
import events from '#/src/events.js';
// import getPath from '#/src/get-path.js';
import Notifications from '#/components/header/notifications.vue';
@ -216,6 +253,7 @@ import AlertDialog from '#/components/alerts/create.vue';
import logo from '../../assets/img/logo.svg?raw'; // eslint-disable-line import/no-unresolved
const pageContext = inject('pageContext');
const theme = ref(pageContext.env.theme);
const user = pageContext.user;
const unseen = ref(pageContext.meta.unseenNotifications);
@ -232,6 +270,13 @@ function search() {
navigate('/search', { q: query.value }, { redirect: true });
}
function setTheme(newTheme) {
theme.value = newTheme;
Cookies.set('theme', newTheme);
events.emit('theme', newTheme);
}
async function logout() {
await del('/session');
navigate('/login?consent', null, { redirect: true }); // pass consent variable to reinstate in new session
@ -275,7 +320,7 @@ function blurSearch(event) {
.nav-item .link {
font-size: .9rem;
color: var(--shadow-strong-10);
color: var(--glass-strong-10);
box-sizing: border-box;
padding: 1rem;
height: 100%;
@ -330,7 +375,7 @@ function blurSearch(event) {
.icon {
height: 100%;
padding: 0 .75rem 0 .5rem;
fill: var(--shadow-weak-10);
fill: var(--glass-weak-10);
}
&.focused {
@ -355,7 +400,6 @@ function blurSearch(event) {
height: 100%;
display: flex;
align-items: center;
padding: 0 1rem 0 0;
font-size: 0;
cursor: pointer;
@ -368,6 +412,21 @@ function blurSearch(event) {
}
}
.menu-trigger {
height: 100%;
}
.avatar-container {
display: flex;
align-items: center;
height: 100%;
padding: 0 1rem 0 0;
&:hover .icon {
fill: var(--primary);
}
}
.avatar {
width: 2rem;
height: 2rem;
@ -375,6 +434,13 @@ function blurSearch(event) {
object-fit: cover;
}
.avatar-placeholder {
width: 1.25rem;
padding-left: 1rem;
height: 100%;
fill: var(--glass-strong-20);
}
.notifs-trigger {
height: 100%;
}
@ -411,7 +477,7 @@ function blurSearch(event) {
}
.notifs-bell {
fill: var(--shadow);
fill: var(--glass);
}
.login {
@ -433,8 +499,8 @@ function blurSearch(event) {
.menu-header {
display: flex;
padding: .75rem 1rem;
border-bottom: solid 1px var(--shadow-weak-30);
color: var(--shadow-strong-30);
border-bottom: solid 1px var(--glass-weak-30);
color: var(--glass-strong-30);
text-decoration: none;
font-weight: bold;
}
@ -450,7 +516,7 @@ function blurSearch(event) {
font-size: 1.1rem;
.icon {
fill: var(--shadow);
fill: var(--glass);
margin-right: .75rem;
transform: translateY(-1px);
}

View File

@ -166,7 +166,7 @@ onMounted(async () => {
box-shadow: inset 0 0 3px var(--shadow-weak-30);
.icon {
fill: var(--shadow-strong-10);
fill: var(--glass-strong-10);
&:hover {
fill: var(--primary);
@ -202,14 +202,14 @@ onMounted(async () => {
overflow: hidden;
&:not(:last-child) {
border-bottom: solid 1px var(--shadow-weak-40);
border-bottom: solid 1px var(--glass-weak-40);
}
&:before {
width: 2.5rem;
flex-shrink: 0;
content: '•';
color: var(--shadow-weak-20);
color: var(--glass-weak-20);
text-align: center;
}
@ -236,7 +236,7 @@ onMounted(async () => {
justify-content: space-between;
padding: .5rem 0 .1rem 0;
box-sizing: border-box;
color: var(--shadow-strong);
color: var(--glass-strong);
font-weight: bold;
}
@ -255,12 +255,12 @@ onMounted(async () => {
.notif-date {
flex-shrink: 0;
color: var(--shadow-strong-10);
color: var(--glass-strong-10);
&:after {
content: '•';
padding: 0 .5rem;
color: var(--shadow-weak-20);
color: var(--glass-weak-20);
}
}
@ -272,7 +272,7 @@ onMounted(async () => {
.notif-id {
padding: 0 .5rem;
color: var(--shadow-weak-10);
color: var(--glass-weak-10);
font-size: .9rem;
font-weight: normal;
}

View File

@ -47,7 +47,7 @@ import(`../../assets/img/icons/${props.icon}.svg?raw`).then((raw) => {
}
&.active {
fill: var(--shadow);
fill: var(--glass);
&:hover {
fill: var(--text);

View File

@ -199,6 +199,10 @@ const favorited = ref(props.movie.stashes?.some((movieStash) => movieStash.id ==
opacity: .1;
}
.dark .nocover {
filter: invert();
}
.tile-info {
flex-shrink: 0;
font-size: 0;
@ -294,7 +298,7 @@ const favorited = ref(props.movie.stashes?.some((movieStash) => movieStash.id ==
overflow: hidden;
padding: 0 .5rem;
margin-bottom: .25rem;
color: var(--shadow-strong-10);
color: var(--glass-strong-10);
font-size: .75rem;
}

View File

@ -251,14 +251,14 @@ function getPath(page) {
margin-bottom: 1rem;
background: var(--background);
box-shadow: 0 0 3px var(--shadow-weak-30);
color: var(--shadow);
color: var(--glass);
font-weight: bold;
font-size: 1rem;
.icon {
width: .9rem;
height: .9rem;
fill: var(--shadow);
fill: var(--glass);
}
&.active {
@ -267,7 +267,7 @@ function getPath(page) {
}
&.disabled .icon {
fill: var(--shadow-weak-20);
fill: var(--glass-weak-20);
}
}
@ -282,7 +282,7 @@ function getPath(page) {
.more {
padding: 2rem;
text-align: center;
color: var(--shadow-strong-10);
color: var(--glass-strong-10);
font-size: 1.1rem;
}

View File

@ -321,7 +321,7 @@ function updateFilter(prop, value, reload = true) {
padding: .5rem 1rem;
background: var(--background-dark-20);
border-radius: 1rem;
color: var(--shadow);
color: var(--glass);
font-size: .9rem;
font-weight: bold;

View File

@ -179,7 +179,7 @@ const favorited = ref(props.scene.stashes.some((sceneStash) => sceneStash.id ===
.icon {
width: 3rem;
height: 3rem;
fill: var(--shadow-weak-40);
fill: var(--glass-weak-40);
}
}
@ -295,7 +295,7 @@ const favorited = ref(props.scene.stashes.some((sceneStash) => sceneStash.id ===
.tag {
margin: 0 .5rem .25rem 0;
padding: .1rem 0;
color: var(--shadow-strong-10);
color: var(--glass-strong-10);
font-size: .75rem;
}
</style>

View File

@ -148,7 +148,7 @@ const activePage = computed(() => pageContext.urlParsed.pathname.split('/')[1]);
padding: .75rem 1rem;
font-size: 1.1rem;
font-weight: bold;
color: var(--shadow-strong-10);
color: var(--glass-strong-10);
&:hover {
color: var(--primary);
@ -166,7 +166,7 @@ const activePage = computed(() => pageContext.urlParsed.pathname.split('/')[1]);
width: 1rem;
padding: 0 1rem;
height: auto;
fill: var(--shadow);
fill: var(--glass);
}
&:hover {

View File

@ -159,7 +159,7 @@ async function unstashItem(stash) {
width: 1.5rem;
height: 1.5rem;
padding: .5rem .5rem;
fill: var(--shadow);
fill: var(--glass);
}
&.light .icon {

View File

@ -211,7 +211,7 @@ async function rename() {
.stash {
width: 100%;
border-radius: .25rem;
background: var(--background);
background: var(--background-base);
box-shadow: 0 0 3px var(--shadow-weak-30);
&:hover {
@ -222,7 +222,7 @@ async function rename() {
.stash-header {
display: flex;
align-items: stretch;
border-bottom: solid 1px var(--shadow-weak-30);
border-bottom: solid 1px var(--glass-weak-30);
font-weight: bold;
}
@ -230,11 +230,11 @@ async function rename() {
display: flex;
height: 100%;
padding: 0 .75rem;
fill: var(--shadow);
fill: var(--glass);
&:hover {
cursor: pointer;
fill: var(--shadow-strong-30);
fill: var(--glass-strong-30);
}
}
@ -268,7 +268,7 @@ async function rename() {
.icon {
margin-right: .5rem;
fill: var(--shadow);
fill: var(--glass);
}
&:hover {
@ -283,7 +283,7 @@ async function rename() {
.icon.private {
display: flex;
height: auto;
fill: var(--shadow-weak-20);
fill: var(--glass-weak-20);
padding-left: .5rem;
}
@ -295,7 +295,7 @@ async function rename() {
.icon {
display: flex;
margin-right: .75rem;
fill: var(--shadow);
fill: var(--glass);
}
&.remove {

View File

@ -169,7 +169,7 @@ onMounted(() => {
padding: 0 1rem 0 .5rem;
.icon {
fill: var(--shadow);
fill: var(--glass);
}
&:hover {

View File

@ -217,7 +217,7 @@ onMounted(() => {
padding: 0 1rem 0 .5rem;
.icon {
fill: var(--shadow);
fill: var(--glass);
}
&:hover {

View File

@ -130,7 +130,7 @@ async function search() {
.icon {
padding: 0 1rem;
height: auto;
fill: var(--shadow);
fill: var(--glass);
&:hover {
cursor: pointer;
@ -153,7 +153,7 @@ async function search() {
.section-label {
padding: 0 1rem;
margin-bottom: .5rem;
color: var(--shadow);
color: var(--glass);
}
.network {
@ -164,7 +164,7 @@ async function search() {
position: relative;
padding: 1rem;
border-radius: .5rem;
background: var(--grey-dark-40);
background: var(--shadow-strong-30);
color: var(--text-light);
font-size: 1.25rem;
font-weight: bold;

View File

@ -432,7 +432,7 @@ const scenes = pageContext.pageProps.scenes;
.icon {
width: 1.5rem;
height: 1.5rem;
fill: var(--shadow);
fill: var(--glass);
}
.button {
@ -490,7 +490,7 @@ const scenes = pageContext.pageProps.scenes;
}
.added-batch {
color: var(--shadow-weak-10);
color: var(--glass-weak-10);
margin-left: .25rem;
}

View File

@ -154,7 +154,7 @@
<div class="info">
<ul
v-if="scene.actors.length > 0"
class="actors nolist"
class="actors nolist nobar"
>
<li
v-for="actor in scene.actors"
@ -632,10 +632,15 @@ function copySummary() {
}
.actors {
display: grid;
display: flex;
flex-grow: 1;
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
gap: .25rem;
overflow-x: auto;
.actor {
width: 8rem;
flex-shrink: 0;
}
}
.tag {
@ -696,7 +701,7 @@ function copySummary() {
}
.added-batch {
color: var(--shadow-weak-10);
color: var(--glass-weak-10);
margin-left: .25rem;
}
@ -713,7 +718,7 @@ function copySummary() {
.icon {
height: auto;
padding: 0 .5rem 0 .75rem;
fill: var(--shadow);
fill: var(--glass);
&:hover {
cursor: pointer;
@ -726,13 +731,13 @@ function copySummary() {
display: none;
}
@media(--small) {
@media(--compact) {
.content {
margin: 0;
}
.info {
margin: 0 .5rem;
margin: 0 .75rem;
}
.banner-container {
@ -756,7 +761,7 @@ function copySummary() {
.title {
width: 100%;
margin-left: .5rem;
margin-left: 1rem;
white-space: wrap;
}

View File

@ -151,7 +151,7 @@ const query = pageContext.urlParsed.search.q;
.results-meta {
box-sizing: border-box;
padding: 1rem 1rem 0 1rem;
color: var(--shadow);
color: var(--glass);
font-weight: bold;
.link {

View File

@ -447,7 +447,7 @@ const scenes = pageContext.pageProps.scenes;
.icon {
width: 1.5rem;
height: 1.5rem;
fill: var(--shadow);
fill: var(--glass);
}
.button {
@ -505,7 +505,7 @@ const scenes = pageContext.pageProps.scenes;
}
.added-batch {
color: var(--shadow-weak-10);
color: var(--glass-weak-10);
margin-left: .25rem;
}

View File

@ -258,7 +258,7 @@ onMounted(() => {
.icon {
padding: 0 1rem;
height: auto;
fill: var(--shadow);
fill: var(--glass);
&:hover {
cursor: pointer;
@ -282,7 +282,7 @@ onMounted(() => {
padding: 1rem 1rem 0 1.5rem;
margin: 0;
text-transform: capitalize;
color: var(--shadow);
color: var(--glass);
}
.tag {
@ -306,7 +306,7 @@ onMounted(() => {
text-transform: capitalize;
font-size: .9rem;
font-weight: bold;
color: var(--shadow-strong-10);
color: var(--glass-strong-10);
}
.thumb-container {

View File

@ -332,7 +332,7 @@ async function removeAlert(alert) {
align-items: center;
padding: .5rem 1rem;
color: var(--highlight-strong-30);
background: var(--grey-dark-40);
background: var(--shadow-strong-30);
border-radius: 0 0 .5rem .5rem;
}
@ -398,10 +398,10 @@ async function removeAlert(alert) {
padding: 0 0 0 .5rem;
display: flex;
align-items: stretch;
border-bottom: solid 1px var(--shadow-weak-40);
border-bottom: solid 1px var(--glass-weak-40);
&:hover {
border-color: var(--shadow-weak-30);
border-color: var(--glass-weak-30);
}
}
@ -412,11 +412,11 @@ async function removeAlert(alert) {
margin-right: .75rem;
.icon {
fill: var(--shadow-weak-40);
fill: var(--glass-weak-40);
}
.icon.trigger {
fill: var(--shadow-weak-10);
fill: var(--glass-weak-10);
}
}
@ -424,7 +424,7 @@ async function removeAlert(alert) {
padding: .25rem 0;
flex-grow: 1;
line-height: 2.5;
color: var(--shadow);
color: var(--glass);
&.and .alert-detail:not(:last-child):after {
content: ' and ';
@ -440,7 +440,7 @@ async function removeAlert(alert) {
.icon {
margin-right: .25rem;
fill: var(--shadow);
fill: var(--glass);
transform: translateY(2px);
}
}
@ -474,12 +474,12 @@ async function removeAlert(alert) {
display: flex;
align-items: center;
font-size: .9rem;
color: var(--shadow-weak-10);
color: var(--glass-weak-10);
.icon {
height: 100%;
padding: 0 .75rem;
fill: var(--shadow);
fill: var(--glass);
&:hover {
cursor: pointer;

View File

@ -32,7 +32,7 @@ function createApp(Page, pageProps, pageContext) {
app.provide('pageContext', pageContext);
app.use(FloatingVue);
app.use(FloatingVue, { container: '#container' });
app.use(VueVirtualScroller);
app.component('Link', Link);

View File

@ -1,6 +1,8 @@
<template>
<div
id="container"
class="container"
:class="{ [theme]: true }"
@click="blur"
>
<transition name="slide">
@ -65,6 +67,7 @@ import BottomNavigation from '#/components/footer/navigation.vue';
const pageContext = inject('pageContext');
const { psa } = pageContext.env;
const theme = ref(pageContext.env.theme);
const content = ref(null);
const feedback = ref(null);
@ -108,6 +111,10 @@ onMounted(() => {
easing: 'ease-in-out',
});
});
events.on('theme', (newTheme) => {
theme.value = newTheme;
});
});
</script>
@ -159,6 +166,8 @@ onMounted(() => {
display: flex;
flex-direction: column;
overflow: hidden;
background: var(--background);
color: var(--text);
}
.content {

View File

@ -167,6 +167,7 @@ function curateOptions(options) {
return {
page: options?.page || 1,
limit: options?.limit || 30,
aggregateCountries: true,
requireAvatar: options?.requireAvatar || false,
order: [escape(options.order?.[0]) || 'name', escape(options.order?.[1]) || 'asc'],
};
@ -312,7 +313,7 @@ async function queryManticoreSql(filters, options, _reqUser) {
.offset((options.page - 1) * options.limit)
.toString(),
// option threads=1 fixes actors, but drastically slows down performance, wait for fix
countriesFacet: options.aggregateActors ? knex.raw('facet actors.country order by count(*) desc limit 300', [aggSize]) : null,
countriesFacet: options.aggregateCountries ? knex.raw('facet actors.country order by count(*) desc limit :aggSize', { aggSize }) : null,
maxMatches: config.database.manticore.maxMatches,
maxQueryTime: config.database.manticore.maxQueryTime,
}).toString();
@ -328,11 +329,9 @@ async function queryManticoreSql(filters, options, _reqUser) {
const results = await utilsApi.sql(curatedSqlQuery);
// console.log(results[0]);
const countries = results
.find((result) => (result.columns[0].actor_ids || result.columns[0]['scenes.country']) && result.columns[1]['count(*)'])
?.data.map((row) => ({ key: row.actor_ids || row['scenes.country'], doc_count: row['count(*)'] }))
.find((result) => (result.columns[0].country || result.columns[0]['actors.country']) && result.columns[1]['count(*)'])
?.data.map((row) => ({ key: row.country || row['actors.country'], doc_count: row['count(*)'] })).filter((country) => !!country.key)
|| [];
const total = Number(results.at(-1).data.find((entry) => entry.Variable_name === 'total_found').Value);

View File

@ -175,6 +175,16 @@ export default async function initServer() {
// TAGS
router.get('/api/tags', fetchTagsApi);
router.use((req, res, next) => {
/* eslint-disable no-param-reassign */
res.set('Accept-CH', 'Sec-CH-Prefers-Color-Scheme');
res.set('Vary', 'Sec-CH-Prefers-Color-Scheme');
res.set('Critical-CH', 'Sec-CH-Prefers-Color-Scheme');
/* eslint-enable no-param-reassign */
next();
});
router.get('*', async (req, res, next) => {
const unseenNotifications = await fetchUnseenNotificationsCount(req.user);
@ -193,6 +203,7 @@ export default async function initServer() {
primaryStash: req.user.primaryStash,
},
env: {
theme: req.cookies.theme || req.headers['sec-ch-prefers-color-scheme'] || 'light',
allowLogin: config.auth.login,
allowSignup: config.auth.signup,
maxMatches: config.database.manticore.maxMatches,