forked from DebaucheryLibrarian/traxxx
Merged filters into new settings dialog, added experimental summary field.
This commit is contained in:
parent
637669e3d1
commit
b5e308562e
|
@ -8,17 +8,10 @@
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<transition name="slide">
|
<transition name="slide">
|
||||||
<Sidebar
|
<Sidebar v-if="showSidebar" />
|
||||||
v-if="showSidebar"
|
|
||||||
@toggle-sidebar="(state) => toggleSidebar(state)"
|
|
||||||
@show-filters="(state) => toggleFilters(state)"
|
|
||||||
/>
|
|
||||||
</transition>
|
</transition>
|
||||||
|
|
||||||
<Header
|
<Header />
|
||||||
@toggle-sidebar="(state) => toggleSidebar(state)"
|
|
||||||
@show-filters="(state) => toggleFilters(state)"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<p
|
<p
|
||||||
v-if="config.showDisclaimer"
|
v-if="config.showDisclaimer"
|
||||||
|
@ -30,13 +23,18 @@
|
||||||
class="content"
|
class="content"
|
||||||
@scroll="scroll"
|
@scroll="scroll"
|
||||||
>
|
>
|
||||||
<router-view @scroll="scrollToTop" />
|
<RouterView @scroll="scrollToTop" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Filters
|
<Filters
|
||||||
v-if="showFilters"
|
v-if="showFilters"
|
||||||
@close="toggleFilters(false)"
|
@close="toggleFilters(false)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Settings
|
||||||
|
v-if="showSettings"
|
||||||
|
@close="toggleSettings(false)"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -45,6 +43,7 @@ import Warning from './warning.vue';
|
||||||
import Header from '../header/header.vue';
|
import Header from '../header/header.vue';
|
||||||
import Sidebar from '../sidebar/sidebar.vue';
|
import Sidebar from '../sidebar/sidebar.vue';
|
||||||
import Filters from '../filters/filters.vue';
|
import Filters from '../filters/filters.vue';
|
||||||
|
import Settings from '../settings/settings.vue';
|
||||||
|
|
||||||
function toggleSidebar(state) {
|
function toggleSidebar(state) {
|
||||||
this.showSidebar = typeof state === 'boolean' ? state : !this.showSidebar;
|
this.showSidebar = typeof state === 'boolean' ? state : !this.showSidebar;
|
||||||
|
@ -55,6 +54,11 @@ function toggleFilters(state) {
|
||||||
this.showSidebar = false;
|
this.showSidebar = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function toggleSettings(state) {
|
||||||
|
this.showSettings = state;
|
||||||
|
this.showSidebar = false;
|
||||||
|
}
|
||||||
|
|
||||||
async function setConsent(consent, includeQueer) {
|
async function setConsent(consent, includeQueer) {
|
||||||
if (consent) {
|
if (consent) {
|
||||||
this.showWarning = false;
|
this.showWarning = false;
|
||||||
|
@ -88,6 +92,9 @@ function scrollToTop() {
|
||||||
function mounted() {
|
function mounted() {
|
||||||
document.addEventListener('click', this.blur);
|
document.addEventListener('click', this.blur);
|
||||||
window.addEventListener('resize', this.resize);
|
window.addEventListener('resize', this.resize);
|
||||||
|
|
||||||
|
this.events.on('toggleSettings', this.toggleSettings);
|
||||||
|
this.events.on('toggleSidebar', this.toggleSidebar);
|
||||||
}
|
}
|
||||||
|
|
||||||
function beforeUnmount() {
|
function beforeUnmount() {
|
||||||
|
@ -101,12 +108,14 @@ export default {
|
||||||
Sidebar,
|
Sidebar,
|
||||||
Warning,
|
Warning,
|
||||||
Filters,
|
Filters,
|
||||||
|
Settings,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
showSidebar: false,
|
showSidebar: false,
|
||||||
showWarning: localStorage.getItem('consent') !== window.env.sessionId,
|
showWarning: localStorage.getItem('consent') !== window.env.sessionId,
|
||||||
showFilters: false,
|
showFilters: false,
|
||||||
|
showSettings: false,
|
||||||
selected: null,
|
selected: null,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -115,6 +124,7 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
toggleSidebar,
|
toggleSidebar,
|
||||||
toggleFilters,
|
toggleFilters,
|
||||||
|
toggleSettings,
|
||||||
setConsent,
|
setConsent,
|
||||||
blur,
|
blur,
|
||||||
resize,
|
resize,
|
||||||
|
|
|
@ -114,13 +114,16 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep(.dialog-body) {
|
::v-deep(.dialog-body) {
|
||||||
padding: 1rem;
|
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 1rem;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
::v-deep(.dialog-section:not(:last-child)) {
|
::v-deep(.dialog-section:not(:last-child)) {
|
||||||
|
padding-bottom: 1rem;
|
||||||
border-bottom: solid 1px var(--shadow-hint);
|
border-bottom: solid 1px var(--shadow-hint);
|
||||||
|
margin-bottom: 1rem;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<header class="header">
|
<header class="header">
|
||||||
<div class="header-nav">
|
<div class="header-nav">
|
||||||
<router-link
|
<RouterLink
|
||||||
to="/"
|
to="/"
|
||||||
class="logo-link"
|
class="logo-link"
|
||||||
><h1 class="header-logo">
|
><h1 class="header-logo">
|
||||||
|
@ -9,12 +9,12 @@
|
||||||
class="logo"
|
class="logo"
|
||||||
v-html="logo"
|
v-html="logo"
|
||||||
/>
|
/>
|
||||||
</h1></router-link>
|
</h1></RouterLink>
|
||||||
|
|
||||||
<nav class="nav">
|
<nav class="nav">
|
||||||
<ul class="nav-list nolist">
|
<ul class="nav-list nolist">
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<router-link
|
<RouterLink
|
||||||
v-slot="{ href, isActive, navigate }"
|
v-slot="{ href, isActive, navigate }"
|
||||||
:to="{ name: 'actors', params: { pageNumber: 1 } }"
|
:to="{ name: 'actors', params: { pageNumber: 1 } }"
|
||||||
custom
|
custom
|
||||||
|
@ -25,11 +25,11 @@
|
||||||
:class="{ active: isActive }"
|
:class="{ active: isActive }"
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
>Actors</a>
|
>Actors</a>
|
||||||
</router-link>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<router-link
|
<RouterLink
|
||||||
v-slot="{ href, isActive, navigate }"
|
v-slot="{ href, isActive, navigate }"
|
||||||
:to="{ name: 'channels' }"
|
:to="{ name: 'channels' }"
|
||||||
custom
|
custom
|
||||||
|
@ -40,11 +40,11 @@
|
||||||
:class="{ active: isActive }"
|
:class="{ active: isActive }"
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
>Channels</a>
|
>Channels</a>
|
||||||
</router-link>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<router-link
|
<RouterLink
|
||||||
v-slot="{ href, isActive, navigate }"
|
v-slot="{ href, isActive, navigate }"
|
||||||
:to="{ name: 'tags' }"
|
:to="{ name: 'tags' }"
|
||||||
custom
|
custom
|
||||||
|
@ -55,11 +55,11 @@
|
||||||
:class="{ active: isActive }"
|
:class="{ active: isActive }"
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
>Tags</a>
|
>Tags</a>
|
||||||
</router-link>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<router-link
|
<RouterLink
|
||||||
v-slot="{ href, isActive, navigate }"
|
v-slot="{ href, isActive, navigate }"
|
||||||
:to="{ name: 'movies', params: { range: 'latest', pageNumber: 1 } }"
|
:to="{ name: 'movies', params: { range: 'latest', pageNumber: 1 } }"
|
||||||
custom
|
custom
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
:class="{ active: isActive }"
|
:class="{ active: isActive }"
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
>Movies</a>
|
>Movies</a>
|
||||||
</router-link>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
<div class="header-section">
|
<div class="header-section">
|
||||||
<div
|
<div
|
||||||
class="sidebar-toggle noselect"
|
class="sidebar-toggle noselect"
|
||||||
@click.stop="$emit('toggleSidebar')"
|
@click.stop="events.emit('toggleSidebar')"
|
||||||
><Icon icon="menu" /></div>
|
><Icon icon="menu" /></div>
|
||||||
|
|
||||||
<Tooltip v-if="me">
|
<Tooltip v-if="me">
|
||||||
|
@ -95,7 +95,7 @@
|
||||||
>{{ unseenNotificationsCount }}</span>
|
>{{ unseenNotificationsCount }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-slot:tooltip>
|
<template #tooltip>
|
||||||
<Notifications
|
<Notifications
|
||||||
:notifications="notifications"
|
:notifications="notifications"
|
||||||
:unseen-count="unseenNotificationsCount"
|
:unseen-count="unseenNotificationsCount"
|
||||||
|
@ -115,8 +115,8 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-slot:tooltip>
|
<template #tooltip>
|
||||||
<Menu @show-filters="state => $emit('showFilters', state)" />
|
<Menu />
|
||||||
</template>
|
</template>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@
|
||||||
icon="search"
|
icon="search"
|
||||||
/></button>
|
/></button>
|
||||||
|
|
||||||
<template v-slot:tooltip>
|
<template #tooltip>
|
||||||
<Search
|
<Search
|
||||||
:searching="searching"
|
:searching="searching"
|
||||||
class="compact"
|
class="compact"
|
||||||
|
|
|
@ -68,9 +68,9 @@
|
||||||
|
|
||||||
<li
|
<li
|
||||||
class="menu-item"
|
class="menu-item"
|
||||||
@click="$emit('showFilters', true)"
|
@click="events.emit('toggleSettings', true)"
|
||||||
>
|
>
|
||||||
<Icon icon="filter" />Filters
|
<Icon icon="cog" />Settings
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
|
@ -104,7 +104,7 @@ function signup(state) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function favorites() {
|
function favorites() {
|
||||||
return this.me?.stashes.find(stash => stash.primary);
|
return this.me?.stashes.find((stash) => stash.primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
function me(state) {
|
function me(state) {
|
||||||
|
@ -130,7 +130,6 @@ export default {
|
||||||
}),
|
}),
|
||||||
favorites,
|
favorites,
|
||||||
},
|
},
|
||||||
emits: ['showFilters'],
|
|
||||||
methods: {
|
methods: {
|
||||||
setSfw,
|
setSfw,
|
||||||
setTheme,
|
setTheme,
|
||||||
|
|
|
@ -85,7 +85,7 @@
|
||||||
<span class="row-label">Part of</span>
|
<span class="row-label">Part of</span>
|
||||||
|
|
||||||
<div class="movies">
|
<div class="movies">
|
||||||
<router-link
|
<RouterLink
|
||||||
v-for="movie in [...release.movies, ...release.series]"
|
v-for="movie in [...release.movies, ...release.series]"
|
||||||
:key="`movie-${movie.id}`"
|
:key="`movie-${movie.id}`"
|
||||||
:to="{ name: movie.type || 'movie', params: { releaseId: movie.id, releaseSlug: movie.slug } }"
|
:to="{ name: movie.type || 'movie', params: { releaseId: movie.id, releaseSlug: movie.slug } }"
|
||||||
|
@ -98,7 +98,7 @@
|
||||||
:src="getPath(movie.covers[0] || movie.poster, 'thumbnail')"
|
:src="getPath(movie.covers[0] || movie.poster, 'thumbnail')"
|
||||||
class="movie-cover"
|
class="movie-cover"
|
||||||
>
|
>
|
||||||
</router-link>
|
</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -113,12 +113,12 @@
|
||||||
>
|
>
|
||||||
<span class="row-label">Director</span>
|
<span class="row-label">Director</span>
|
||||||
|
|
||||||
<router-link
|
<RouterLink
|
||||||
v-for="director in release.directors"
|
v-for="director in release.directors"
|
||||||
:key="`director-${director.id}`"
|
:key="`director-${director.id}`"
|
||||||
class="link director"
|
class="link director"
|
||||||
:to="`/director/${director.id}/${director.slug}`"
|
:to="`/director/${director.id}/${director.slug}`"
|
||||||
>{{ director.name }}</router-link>
|
>{{ director.name }}</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -162,10 +162,10 @@
|
||||||
>
|
>
|
||||||
<span class="row-label">Studio</span>
|
<span class="row-label">Studio</span>
|
||||||
|
|
||||||
<router-link
|
<RouterLink
|
||||||
:to="`/studio/${release.studio.slug}`"
|
:to="`/studio/${release.studio.slug}`"
|
||||||
class="link studio"
|
class="link studio"
|
||||||
>{{ release.studio.name }}</router-link>
|
>{{ release.studio.name }}</RouterLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -227,17 +227,40 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<span class="row-label">Added</span>
|
<span class="row-label">Added</span>
|
||||||
|
|
||||||
<router-link
|
<RouterLink
|
||||||
:to="`/added/${formatDate(release.createdAt, 'YYYY/MM/DD')}`"
|
:to="`/added/${formatDate(release.createdAt, 'YYYY/MM/DD')}`"
|
||||||
:title="`Added on ${formatDate(release.createdAt, 'MMMM D, YYYY HH:mm')}`"
|
:title="`Added on ${formatDate(release.createdAt, 'MMMM D, YYYY HH:mm')}`"
|
||||||
class="link added"
|
class="link added"
|
||||||
>{{ release.createdBatchId }}: {{ formatDate(release.createdAt, 'MMMM D, YYYY HH:mm') }}</router-link>
|
>{{ release.createdBatchId }}: {{ formatDate(release.createdAt, 'MMMM D, YYYY HH:mm') }}</RouterLink>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<span class="row-label">Summary</span>
|
||||||
|
|
||||||
|
<div class="summary">
|
||||||
|
<input
|
||||||
|
ref="summary"
|
||||||
|
v-model="summary"
|
||||||
|
class="input"
|
||||||
|
@focus="selectSummary"
|
||||||
|
>
|
||||||
|
|
||||||
|
<button
|
||||||
|
v-if="hasClipboard"
|
||||||
|
type="button"
|
||||||
|
class="button button-secondary"
|
||||||
|
:disabled="summaryCopied"
|
||||||
|
@focus="copySummary"
|
||||||
|
>{{ summaryCopied ? 'Copied!' : 'Copy' }}</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import formatSummary from '../../js/utils/format-summary';
|
||||||
|
|
||||||
import Details from './details.vue';
|
import Details from './details.vue';
|
||||||
import Banner from './banner.vue';
|
import Banner from './banner.vue';
|
||||||
import StashButton from '../stashes/button.vue';
|
import StashButton from '../stashes/button.vue';
|
||||||
|
@ -266,6 +289,7 @@ async function fetchRelease(scroll = true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.stashedBy = this.release.stashes;
|
this.stashedBy = this.release.stashes;
|
||||||
|
this.setSummary();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stashScene(stashId) {
|
async function stashScene(stashId) {
|
||||||
|
@ -288,6 +312,37 @@ function me() {
|
||||||
return this.$store.state.auth.user;
|
return this.$store.state.auth.user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setSummary() {
|
||||||
|
// this.summary = `${this.release.entity.name} - ${this.release.title} (${this.release.actors.map((actor) => actor.name).join(', ')}, ${this.formatDate(this.release.date, 'DD-MM-YYYY')})`;
|
||||||
|
const simpleRelease = {
|
||||||
|
channel: this.release.entity.name,
|
||||||
|
network: this.release.entity.parent?.name || this.release.entity.name,
|
||||||
|
title: this.release.title,
|
||||||
|
movie: this.release.movies?.[0]?.title,
|
||||||
|
actors: this.release.actors.map((actor) => actor.name),
|
||||||
|
tags: this.release.tags.map((tag) => tag.name),
|
||||||
|
date: this.release.date,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.summary = formatSummary(simpleRelease, this.$store.state.ui.summaryFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function selectSummary() {
|
||||||
|
this.$refs.summary.select();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function copySummary() {
|
||||||
|
const { state } = await navigator.permissions.query({ name: 'clipboard-write' });
|
||||||
|
|
||||||
|
if (state === 'granted' || state === 'prompt') {
|
||||||
|
await navigator.clipboard.writeText(this.summary);
|
||||||
|
|
||||||
|
this.summaryCopied = true;
|
||||||
|
|
||||||
|
setTimeout(() => { this.summaryCopied = false; }, 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function bannerBackground() {
|
function bannerBackground() {
|
||||||
return (this.release.poster && this.getBgPath(this.release.poster, 'thumbnail'))
|
return (this.release.poster && this.getBgPath(this.release.poster, 'thumbnail'))
|
||||||
|| (this.release.covers.length > 0 && this.getBgPath(this.release.covers[0], 'thumbnail'));
|
|| (this.release.covers.length > 0 && this.getBgPath(this.release.covers[0], 'thumbnail'));
|
||||||
|
@ -318,7 +373,10 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
release: null,
|
release: null,
|
||||||
|
summary: null,
|
||||||
|
summaryCopied: false,
|
||||||
stashedBy: [],
|
stashedBy: [],
|
||||||
|
hasClipboard: !!navigator?.clipboard?.writeText,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -332,6 +390,9 @@ export default {
|
||||||
},
|
},
|
||||||
mounted: fetchRelease,
|
mounted: fetchRelease,
|
||||||
methods: {
|
methods: {
|
||||||
|
copySummary,
|
||||||
|
selectSummary,
|
||||||
|
setSummary,
|
||||||
fetchRelease,
|
fetchRelease,
|
||||||
stashScene,
|
stashScene,
|
||||||
unstashScene,
|
unstashScene,
|
||||||
|
@ -502,6 +563,18 @@ export default {
|
||||||
margin: 0 0 -.15rem .1rem;
|
margin: 0 0 -.15rem .1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.summary {
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.input {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
width: 4rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.link {
|
.link {
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
color: var(--link);
|
color: var(--link);
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
<template>
|
||||||
|
<div class="dialog-section">
|
||||||
|
<h3 class="form-heading">Show me</h3>
|
||||||
|
|
||||||
|
<ul class="tags nolist">
|
||||||
|
<li
|
||||||
|
v-for="tag in tags"
|
||||||
|
:key="tag"
|
||||||
|
class="tags-item"
|
||||||
|
>
|
||||||
|
<Checkbox
|
||||||
|
:checked="!tagFilter.includes(tag)"
|
||||||
|
:label="tag"
|
||||||
|
class="tag"
|
||||||
|
@change="(state) => filterTag(tag, state)"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<p class="disclaimer">You may still incidentally see filtered out content</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Checkbox from '../form/checkbox.vue';
|
||||||
|
|
||||||
|
function tagFilter() {
|
||||||
|
return this.$store.state.ui.tagFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
function filterTag(tag, isChecked) {
|
||||||
|
if (isChecked) {
|
||||||
|
this.$store.dispatch('setTagFilter', this.tagFilter.filter((filteredTag) => filteredTag !== tag));
|
||||||
|
} else {
|
||||||
|
this.$store.dispatch('setTagFilter', this.tagFilter.concat(tag));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Checkbox,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
tags: ['anal', 'gay', 'transsexual', 'bisexual', 'pissing', 'anal prolapse'],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
tagFilter,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
filterTag,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.dialog-body {
|
||||||
|
width: 40rem;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filters {
|
||||||
|
width: 20rem;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tags-item {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag {
|
||||||
|
padding: .5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.disclaimer {
|
||||||
|
margin: 1rem 0 0 0;
|
||||||
|
line-height: 1.5;
|
||||||
|
text-align: center;
|
||||||
|
font-size: .9rem;
|
||||||
|
color: var(--shadow);
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,81 @@
|
||||||
|
<template>
|
||||||
|
<Dialog
|
||||||
|
title="Settings"
|
||||||
|
@close="$emit('close')"
|
||||||
|
>
|
||||||
|
<nav class="tabs">
|
||||||
|
<button
|
||||||
|
class="tab"
|
||||||
|
:class="{ selected: section === 'filters' }"
|
||||||
|
@click="section = 'filters'"
|
||||||
|
>Filters</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="tab"
|
||||||
|
:class="{ selected: section === 'summary' }"
|
||||||
|
@click="section = 'summary'"
|
||||||
|
>Summary</button>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div class="dialog-body">
|
||||||
|
<component :is="sections[section]" />
|
||||||
|
</div>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { shallowRef } from 'vue';
|
||||||
|
|
||||||
|
import Filters from './filters.vue';
|
||||||
|
import Summary from './summary.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
emits: ['close'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
sections: {
|
||||||
|
filters: shallowRef(Filters),
|
||||||
|
summary: shallowRef(Summary),
|
||||||
|
},
|
||||||
|
section: 'filters',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.dialog-body {
|
||||||
|
width: 40rem;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tabs {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: .75rem 1rem;
|
||||||
|
background: var(--shadow-touch);
|
||||||
|
border: none;
|
||||||
|
border-bottom: solid 1px var(--shadow-hint);
|
||||||
|
color: var(--shadow);
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: bold;
|
||||||
|
|
||||||
|
&:not(:first-child) {
|
||||||
|
border-left: solid 1px var(--shadow-hint);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.selected {
|
||||||
|
background: none;
|
||||||
|
color: var(--primary);
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--shadow-strong);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,327 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="dialog-section">
|
||||||
|
<h3 class="form-heading">Summary format</h3>
|
||||||
|
|
||||||
|
<ul class="summary nolist">
|
||||||
|
<li
|
||||||
|
v-for="(group, groupIndex) in summaryFormat"
|
||||||
|
:key="groupIndex"
|
||||||
|
class="summary-group"
|
||||||
|
>
|
||||||
|
<div class="summary-options">
|
||||||
|
<label class="summary-option">Delimiter
|
||||||
|
<input
|
||||||
|
class="input summary-delimiter"
|
||||||
|
:value="group.delimiter"
|
||||||
|
@change="setSummaryGroupValue(groupIndex, 'delimiter', $event.target.value)"
|
||||||
|
>
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<label class="summary-option">Brackets
|
||||||
|
<select
|
||||||
|
class="select summary-delimiter"
|
||||||
|
:value="group.bracket"
|
||||||
|
@change="setSummaryGroupValue(groupIndex, 'bracket', $event.target.value)"
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="bracket in brackets"
|
||||||
|
:key="bracket"
|
||||||
|
>{{ bracket }}</option>
|
||||||
|
</select>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="summary-segments nolist">
|
||||||
|
<li
|
||||||
|
v-for="(segment, segmentIndex) in group.segments"
|
||||||
|
:key="segmentIndex"
|
||||||
|
class="summary-segment"
|
||||||
|
>
|
||||||
|
<select
|
||||||
|
class="select summary-prop"
|
||||||
|
:value="segment.prop"
|
||||||
|
@change="setSummarySegmentValue(groupIndex, segmentIndex, 'prop', $event.target.value)"
|
||||||
|
>
|
||||||
|
<option>channel</option>
|
||||||
|
<option>network</option>
|
||||||
|
<option>title</option>
|
||||||
|
<option>movie</option>
|
||||||
|
<option>tags</option>
|
||||||
|
<option>actors</option>
|
||||||
|
<option>date</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<input
|
||||||
|
v-if="delimitedProps.includes(segment.prop)"
|
||||||
|
class="input summary-delimiter"
|
||||||
|
:value="segment.delimiter"
|
||||||
|
@change="setSummarySegmentValue(groupIndex, segmentIndex, 'delimiter', $event.target.value)"
|
||||||
|
>
|
||||||
|
|
||||||
|
<select
|
||||||
|
v-if="segment.prop === 'date'"
|
||||||
|
class="select summary-format"
|
||||||
|
:value="segment.format"
|
||||||
|
@change="setSummarySegmentValue(groupIndex, segmentIndex, 'format', $event.target.value)"
|
||||||
|
>
|
||||||
|
<option>YYYY-MM-DD</option>
|
||||||
|
<option>DD-MM-YYYY</option>
|
||||||
|
<option>MM/DD/YYYY</option>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
icon="bin"
|
||||||
|
class="active"
|
||||||
|
@click="removeSummarySegment(groupIndex, segmentIndex)"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="summary-actions">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="button button-secondary"
|
||||||
|
@click="addSummarySegment(groupIndex)"
|
||||||
|
>Add segment</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="button button-secondary"
|
||||||
|
@click="removeSummaryGroup(groupIndex)"
|
||||||
|
>Remove group</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li class="summary summary-actions">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="button button-secondary"
|
||||||
|
@click="addSummaryGroup"
|
||||||
|
>Add group</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="button button-secondary"
|
||||||
|
@click="resetSummaryFormat"
|
||||||
|
>Reset to default</button>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dialog-section">
|
||||||
|
<h3 class="form-heading">Preview</h3>
|
||||||
|
|
||||||
|
<input
|
||||||
|
class="input summary-preview"
|
||||||
|
:value="summary"
|
||||||
|
:title="summary"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import formatSummary from '../../js/utils/format-summary';
|
||||||
|
|
||||||
|
function summary() {
|
||||||
|
return formatSummary(this.scene, this.summaryFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
function summaryFormat() {
|
||||||
|
return this.$store.state.ui.summaryFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSummaryGroupValue(targetGroupIndex, target, value) {
|
||||||
|
const newFormat = this.summaryFormat.map((group, groupIndex) => {
|
||||||
|
if (groupIndex === targetGroupIndex) {
|
||||||
|
return {
|
||||||
|
...group,
|
||||||
|
[target]: value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return group;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$store.dispatch('setSummaryFormat', newFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSummarySegmentValue(targetGroupIndex, targetSegmentIndex, target, value) {
|
||||||
|
const newFormat = this.summaryFormat.map((group, groupIndex) => {
|
||||||
|
if (groupIndex === targetGroupIndex) {
|
||||||
|
return {
|
||||||
|
...group,
|
||||||
|
segments: group.segments.map((segment, segmentIndex) => {
|
||||||
|
if (segmentIndex === targetSegmentIndex) {
|
||||||
|
return {
|
||||||
|
...segment,
|
||||||
|
[target]: value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return segment;
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return group;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$store.dispatch('setSummaryFormat', newFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSummarySegment(targetGroupIndex) {
|
||||||
|
const newFormat = this.summaryFormat.map((group, groupIndex) => {
|
||||||
|
if (groupIndex === targetGroupIndex) {
|
||||||
|
return {
|
||||||
|
...group,
|
||||||
|
segments: group.segments.concat({
|
||||||
|
prop: 'title',
|
||||||
|
delimiter: ',', // default delimiter for when prop is changed to iterabte like actors or tags
|
||||||
|
format: 'YYYY-MM-DD', // default format for when prop is changed to date
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return group;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$store.dispatch('setSummaryFormat', newFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
function addSummaryGroup() {
|
||||||
|
const newFormat = this.summaryFormat.concat({
|
||||||
|
delimiter: ' - ',
|
||||||
|
segments: [{ prop: 'title' }],
|
||||||
|
});
|
||||||
|
|
||||||
|
this.$store.dispatch('setSummaryFormat', newFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeSummaryGroup(groupIndex) {
|
||||||
|
const newFormat = this.summaryFormat.filter((group, index) => index !== groupIndex);
|
||||||
|
|
||||||
|
this.$store.dispatch('setSummaryFormat', newFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeSummarySegment(targetGroupIndex, targetSegmentIndex) {
|
||||||
|
const newFormat = this.summaryFormat.map((group, groupIndex) => ({
|
||||||
|
...group,
|
||||||
|
segments: groupIndex === targetGroupIndex
|
||||||
|
? group.segments.filter((segment, index) => index !== targetSegmentIndex)
|
||||||
|
: group.segments,
|
||||||
|
}));
|
||||||
|
|
||||||
|
this.$store.dispatch('setSummaryFormat', newFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resetSummaryFormat() {
|
||||||
|
this.$store.dispatch('setSummaryFormat', this.$store.state.ui.defaultSummaryFormat);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
delimiters: [null, '-', '_', ',', '.'],
|
||||||
|
brackets: [null, '()', '[]', '{}', '<>'],
|
||||||
|
delimitedProps: ['actors', 'tags'],
|
||||||
|
scene: {
|
||||||
|
channel: 'Channel',
|
||||||
|
network: 'Network',
|
||||||
|
title: 'Title',
|
||||||
|
movie: 'Movie',
|
||||||
|
scene: 1,
|
||||||
|
actors: ['Jane Doe', 'John Doe'],
|
||||||
|
date: new Date(),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
summary,
|
||||||
|
summaryFormat,
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addSummaryGroup,
|
||||||
|
setSummaryGroupValue,
|
||||||
|
addSummarySegment,
|
||||||
|
setSummarySegmentValue,
|
||||||
|
removeSummaryGroup,
|
||||||
|
removeSummarySegment,
|
||||||
|
resetSummaryFormat,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.summary {
|
||||||
|
.icon {
|
||||||
|
padding: .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-group,
|
||||||
|
.summary-segment {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-group {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-top: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:last-child) {
|
||||||
|
padding-bottom: .5rem;
|
||||||
|
border-bottom: solid 1px var(--shadow-hint);
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-segments {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-segment {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: .25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-delimiter {
|
||||||
|
width: 5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-format {
|
||||||
|
width: 9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-prop {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-options {
|
||||||
|
margin-bottom: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-option:not(:last-child) {
|
||||||
|
margin-right: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-preview {
|
||||||
|
width: 100%;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="sidebar-container"
|
class="sidebar-container"
|
||||||
@click="$emit('toggleSidebar', false)"
|
@click="events.emit('toggleSidebar', false)"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="sidebar"
|
class="sidebar"
|
||||||
|
@ -9,10 +9,10 @@
|
||||||
>
|
>
|
||||||
<div class="sidebar-section">
|
<div class="sidebar-section">
|
||||||
<div class="sidebar-header">
|
<div class="sidebar-header">
|
||||||
<router-link
|
<RouterLink
|
||||||
to="/updates"
|
to="/updates"
|
||||||
class="logo-link"
|
class="logo-link"
|
||||||
@click="$emit('toggleSidebar', false)"
|
@click="events.emit('toggleSidebar', false)"
|
||||||
>
|
>
|
||||||
<h1 class="sidebar-logo">
|
<h1 class="sidebar-logo">
|
||||||
<div
|
<div
|
||||||
|
@ -20,27 +20,27 @@
|
||||||
v-html="logo"
|
v-html="logo"
|
||||||
/>
|
/>
|
||||||
</h1>
|
</h1>
|
||||||
</router-link>
|
</RouterLink>
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
icon="cross2"
|
icon="cross2"
|
||||||
class="sidebar-close noselect"
|
class="sidebar-close noselect"
|
||||||
@click.native="$emit('toggleSidebar', false)"
|
@click.native="events.emit('toggleSidebar', false)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Search
|
<Search
|
||||||
class="search"
|
class="search"
|
||||||
@search="$emit('toggleSidebar', false)"
|
@search="events.emit('toggleSidebar', false)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<nav class="nav">
|
<nav class="nav">
|
||||||
<ul class="nolist">
|
<ul class="nolist">
|
||||||
<li
|
<li
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
@click="$emit('toggleSidebar', false)"
|
@click="events.emit('toggleSidebar', false)"
|
||||||
>
|
>
|
||||||
<router-link
|
<RouterLink
|
||||||
v-slot="{ href, isActive, navigate }"
|
v-slot="{ href, isActive, navigate }"
|
||||||
to="/updates"
|
to="/updates"
|
||||||
custom
|
custom
|
||||||
|
@ -51,14 +51,14 @@
|
||||||
:class="{ active: isActive }"
|
:class="{ active: isActive }"
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
>Home</a>
|
>Home</a>
|
||||||
</router-link>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
@click="$emit('toggleSidebar', false)"
|
@click="events.emit('toggleSidebar', false)"
|
||||||
>
|
>
|
||||||
<router-link
|
<RouterLink
|
||||||
v-slot="{ href, isActive, navigate }"
|
v-slot="{ href, isActive, navigate }"
|
||||||
to="/actors"
|
to="/actors"
|
||||||
custom
|
custom
|
||||||
|
@ -69,14 +69,14 @@
|
||||||
:class="{ active: isActive }"
|
:class="{ active: isActive }"
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
>Actors</a>
|
>Actors</a>
|
||||||
</router-link>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
@click="$emit('toggleSidebar', false)"
|
@click="events.emit('toggleSidebar', false)"
|
||||||
>
|
>
|
||||||
<router-link
|
<RouterLink
|
||||||
v-slot="{ href, isActive, navigate }"
|
v-slot="{ href, isActive, navigate }"
|
||||||
to="/channels"
|
to="/channels"
|
||||||
custom
|
custom
|
||||||
|
@ -87,14 +87,14 @@
|
||||||
:class="{ active: isActive }"
|
:class="{ active: isActive }"
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
>Channels</a>
|
>Channels</a>
|
||||||
</router-link>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
@click="$emit('toggleSidebar', false)"
|
@click="events.emit('toggleSidebar', false)"
|
||||||
>
|
>
|
||||||
<router-link
|
<RouterLink
|
||||||
v-slot="{ href, isActive, navigate }"
|
v-slot="{ href, isActive, navigate }"
|
||||||
to="/movies"
|
to="/movies"
|
||||||
custom
|
custom
|
||||||
|
@ -105,14 +105,14 @@
|
||||||
:class="{ active: isActive }"
|
:class="{ active: isActive }"
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
>Movies</a>
|
>Movies</a>
|
||||||
</router-link>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
class="nav-item"
|
class="nav-item"
|
||||||
@click="$emit('toggleSidebar', false)"
|
@click="events.emit('toggleSidebar', false)"
|
||||||
>
|
>
|
||||||
<router-link
|
<RouterLink
|
||||||
v-slot="{ href, isActive, navigate }"
|
v-slot="{ href, isActive, navigate }"
|
||||||
to="/tags"
|
to="/tags"
|
||||||
custom
|
custom
|
||||||
|
@ -123,7 +123,7 @@
|
||||||
:class="{ active: isActive }"
|
:class="{ active: isActive }"
|
||||||
@click="navigate"
|
@click="navigate"
|
||||||
>Tags</a>
|
>Tags</a>
|
||||||
</router-link>
|
</RouterLink>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -132,23 +132,23 @@
|
||||||
<div class="sidebar-section controls noselect">
|
<div class="sidebar-section controls noselect">
|
||||||
<label
|
<label
|
||||||
v-if="login && me"
|
v-if="login && me"
|
||||||
@click="$emit('toggleSidebar', false)"
|
@click="events.emit('toggleSidebar', false)"
|
||||||
>
|
>
|
||||||
<router-link
|
<RouterLink
|
||||||
:to="{ name: 'user', params: { username: me.username } }"
|
:to="{ name: 'user', params: { username: me.username } }"
|
||||||
class="toggle username nolink"
|
class="toggle username nolink"
|
||||||
>{{ me.username }}</router-link>
|
>{{ me.username }}</RouterLink>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<div class="toggles noselect">
|
<div class="toggles noselect">
|
||||||
<label
|
<label
|
||||||
v-if="login && !me"
|
v-if="login && !me"
|
||||||
@click="$emit('toggleSidebar', false)"
|
@click="events.emit('toggleSidebar', false)"
|
||||||
>
|
>
|
||||||
<router-link
|
<RouterLink
|
||||||
:to="{ name: 'login', query: { ref: $route.path } }"
|
:to="{ name: 'login', query: { ref: $route.path } }"
|
||||||
class="toggle nolink"
|
class="toggle nolink"
|
||||||
><Icon icon="enter2" />Log in</router-link>
|
><Icon icon="enter2" />Log in</RouterLink>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label
|
<label
|
||||||
|
@ -183,8 +183,8 @@
|
||||||
|
|
||||||
<label
|
<label
|
||||||
class="toggle"
|
class="toggle"
|
||||||
@click="$emit('showFilters', true)"
|
@click="events.emit('toggleSettings', true)"
|
||||||
><Icon icon="filter" />Filters</label>
|
><Icon icon="cog" />Settings</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -230,7 +230,6 @@ export default {
|
||||||
components: {
|
components: {
|
||||||
Search,
|
Search,
|
||||||
},
|
},
|
||||||
emits: ['toggleSidebar', 'showFilters'],
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
logo,
|
logo,
|
||||||
|
|
|
@ -54,10 +54,15 @@
|
||||||
.button-secondary {
|
.button-secondary {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
|
|
||||||
&:hover {
|
&:hover:not(:disabled) {
|
||||||
color: var(--highlight-strong);
|
color: var(--text-light);
|
||||||
background: var(--primary);
|
background: var(--primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
color: var(--shadow-strong);
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.album-toggle {
|
.album-toggle {
|
||||||
|
|
|
@ -10,6 +10,11 @@ function initUiActions(store, _router) {
|
||||||
localStorage.setItem('tagFilter', tagFilter);
|
localStorage.setItem('tagFilter', tagFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setSummaryFormat({ commit }, summaryFormat) {
|
||||||
|
commit('setSummaryFormat', summaryFormat);
|
||||||
|
localStorage.setItem('summaryFormat', JSON.stringify(summaryFormat));
|
||||||
|
}
|
||||||
|
|
||||||
function setRange({ commit }, range) {
|
function setRange({ commit }, range) {
|
||||||
commit('setRange', range);
|
commit('setRange', range);
|
||||||
}
|
}
|
||||||
|
@ -309,6 +314,7 @@ function initUiActions(store, _router) {
|
||||||
checkNotifications,
|
checkNotifications,
|
||||||
search,
|
search,
|
||||||
setTagFilter,
|
setTagFilter,
|
||||||
|
setSummaryFormat,
|
||||||
setRange,
|
setRange,
|
||||||
setBatch,
|
setBatch,
|
||||||
setSfw,
|
setSfw,
|
||||||
|
|
|
@ -2,6 +2,10 @@ function setTagFilter(state, tagFilter) {
|
||||||
state.tagFilter = tagFilter;
|
state.tagFilter = tagFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function setSummaryFormat(state, summaryFormat) {
|
||||||
|
state.summaryFormat = summaryFormat;
|
||||||
|
}
|
||||||
|
|
||||||
function setRange(state, range) {
|
function setRange(state, range) {
|
||||||
state.range = range;
|
state.range = range;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +24,7 @@ function setTheme(state, theme) {
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
setTagFilter,
|
setTagFilter,
|
||||||
|
setSummaryFormat,
|
||||||
setRange,
|
setRange,
|
||||||
setBatch,
|
setBatch,
|
||||||
setSfw,
|
setSfw,
|
||||||
|
|
|
@ -1,12 +1,43 @@
|
||||||
const storedTagFilter = localStorage.getItem('tagFilter');
|
const storedTagFilter = localStorage.getItem('tagFilter');
|
||||||
|
const storedSummaryFormat = localStorage.getItem('summaryFormat');
|
||||||
const storedBatch = localStorage.getItem('batch');
|
const storedBatch = localStorage.getItem('batch');
|
||||||
const storedSfw = localStorage.getItem('sfw');
|
const storedSfw = localStorage.getItem('sfw');
|
||||||
const storedTheme = localStorage.getItem('theme');
|
const storedTheme = localStorage.getItem('theme');
|
||||||
|
|
||||||
const deviceTheme = window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
const deviceTheme = window.matchMedia?.('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||||
|
|
||||||
|
const defaultSummaryFormat = [
|
||||||
|
{
|
||||||
|
delimiter: ' - ',
|
||||||
|
segments: [
|
||||||
|
{
|
||||||
|
prop: 'channel',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'title',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
delimiter: ', ',
|
||||||
|
bracket: '()',
|
||||||
|
segments: [
|
||||||
|
{
|
||||||
|
prop: 'actors',
|
||||||
|
delimiter: ', ',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'date',
|
||||||
|
format: 'DD-MM-YYYY',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
tagFilter: storedTagFilter ? storedTagFilter.split(',') : [],
|
tagFilter: storedTagFilter ? storedTagFilter.split(',') : [],
|
||||||
|
summaryFormat: storedSummaryFormat ? JSON.parse(storedSummaryFormat) : defaultSummaryFormat,
|
||||||
|
defaultSummaryFormat,
|
||||||
range: 'latest',
|
range: 'latest',
|
||||||
batch: storedBatch || 'all',
|
batch: storedBatch || 'all',
|
||||||
sfw: storedSfw === 'true' || false,
|
sfw: storedSfw === 'true' || false,
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
import { formatDate } from '../format';
|
||||||
|
|
||||||
|
function formatSummary(release, summaryFormat) {
|
||||||
|
return summaryFormat
|
||||||
|
.map((group) => ({
|
||||||
|
...group,
|
||||||
|
segments: group.segments
|
||||||
|
.filter((segment) => {
|
||||||
|
if (!release[segment.prop]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(release[segment.prop]) && release[segment.prop].length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.map((segment) => {
|
||||||
|
if (Array.isArray(release[segment.prop])) {
|
||||||
|
return release[segment.prop].join(segment.delimiter || ', ');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (segment.prop === 'date') {
|
||||||
|
return formatDate(release[segment.prop], segment.format || 'YYYY-MM-DD');
|
||||||
|
}
|
||||||
|
|
||||||
|
return release[segment.prop];
|
||||||
|
}),
|
||||||
|
}))
|
||||||
|
.filter((group) => group.segments.length > 0)
|
||||||
|
.map((group) => `${group.bracket?.[0] || ''}${group.segments.join(group.delimiter || ' - ')}${group.bracket?.[1] || ''}`)
|
||||||
|
.join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
export default formatSummary;
|
|
@ -419,7 +419,7 @@ async function scrapeScene({ query }, url, channel, baseRelease, mobileItem, opt
|
||||||
return release;
|
return release;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function scrapeReleaseApi(data, site, options) {
|
async function scrapeReleaseApi(data, site, options, movieScenes) {
|
||||||
const release = {};
|
const release = {};
|
||||||
|
|
||||||
release.entryId = data.clip_id || data.movie_id;
|
release.entryId = data.clip_id || data.movie_id;
|
||||||
|
@ -470,6 +470,10 @@ async function scrapeReleaseApi(data, site, options) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (movieScenes?.length > 0) {
|
||||||
|
release.scenes = await Promise.all(movieScenes.map((movieScene) => scrapeReleaseApi(movieScene, site, options)));
|
||||||
|
}
|
||||||
|
|
||||||
release.channel = data.sitename;
|
release.channel = data.sitename;
|
||||||
release.qualities = data.download_sizes;
|
release.qualities = data.download_sizes;
|
||||||
|
|
||||||
|
@ -706,10 +710,16 @@ async function fetchMovieApi(url, site, baseRelease, options) {
|
||||||
indexName: 'all_movies',
|
indexName: 'all_movies',
|
||||||
params: `query=&page=0&facets=[]&tagFilters=&facetFilters=[["movie_id:${entryId}"]]`,
|
params: `query=&page=0&facets=[]&tagFilters=&facetFilters=[["movie_id:${entryId}"]]`,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
indexName: 'all_scenes_latest_desc',
|
||||||
|
params: `query=&page=0&facets=[]&tagFilters=&facetFilters=[["movie_id:${entryId}"]]`,
|
||||||
|
},
|
||||||
|
/*
|
||||||
{
|
{
|
||||||
indexName: 'all_movies',
|
indexName: 'all_movies',
|
||||||
params: 'query=&page=0&hitsPerPage=1&attributesToRetrieve=[]&attributesToHighlight=[]&attributesToSnippet=[]&tagFilters=&analytics=false&clickAnalytics=false&facets=clip_id',
|
params: 'query=&page=0&hitsPerPage=1&attributesToRetrieve=[]&attributesToHighlight=[]&attributesToSnippet=[]&tagFilters=&analytics=false&clickAnalytics=false&facets=clip_id',
|
||||||
},
|
},
|
||||||
|
*/
|
||||||
],
|
],
|
||||||
}, {
|
}, {
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -720,7 +730,7 @@ async function fetchMovieApi(url, site, baseRelease, options) {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (res.status === 200 && res.body.results?.[0]?.hits.length > 0) {
|
if (res.status === 200 && res.body.results?.[0]?.hits.length > 0) {
|
||||||
return scrapeReleaseApi(res.body.results[0].hits[0], site, options);
|
return scrapeReleaseApi(res.body.results[0].hits[0], site, options, res.body.results[1]?.hits);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
|
|
Loading…
Reference in New Issue