Compare commits
12 Commits
d4919016b6
...
11e043ca2e
Author | SHA1 | Date |
---|---|---|
|
11e043ca2e | |
|
7ac64c57ae | |
|
9ff70e5578 | |
|
348aa91832 | |
|
de5d104e1e | |
|
565cf551f0 | |
|
819d53fc2b | |
|
67f22a6e08 | |
|
eee47111a6 | |
|
07643870cd | |
|
bb949e0a3b | |
|
a7cf3f689e |
|
@ -34,18 +34,11 @@
|
||||||
class="header-social"
|
class="header-social"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Icon
|
<StashButton
|
||||||
v-show="me && isStashed"
|
:stashed-by="stashedBy"
|
||||||
icon="heart7"
|
class="actor-stash light"
|
||||||
class="stash stashed noselect"
|
@stash="(stash) => stashActor(stash)"
|
||||||
@click="unstashActor"
|
@unstash="(stash) => unstashActor(stash)"
|
||||||
/>
|
|
||||||
|
|
||||||
<Icon
|
|
||||||
v-show="me && !isStashed"
|
|
||||||
icon="heart8"
|
|
||||||
class="stash unstashed noselect"
|
|
||||||
@click="stashActor"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -390,6 +383,7 @@ import Expand from '../expand/expand.vue';
|
||||||
import Scroll from '../scroll/scroll.vue';
|
import Scroll from '../scroll/scroll.vue';
|
||||||
import Gender from './gender.vue';
|
import Gender from './gender.vue';
|
||||||
import Social from './social.vue';
|
import Social from './social.vue';
|
||||||
|
import StashButton from '../stashes/button.vue';
|
||||||
|
|
||||||
async function fetchActor(scroll = true) {
|
async function fetchActor(scroll = true) {
|
||||||
const { actor, releases, totalCount } = await this.$store.dispatch('fetchActorById', {
|
const { actor, releases, totalCount } = await this.$store.dispatch('fetchActorById', {
|
||||||
|
@ -402,38 +396,31 @@ async function fetchActor(scroll = true) {
|
||||||
this.actor = actor;
|
this.actor = actor;
|
||||||
this.releases = releases;
|
this.releases = releases;
|
||||||
this.totalCount = totalCount;
|
this.totalCount = totalCount;
|
||||||
|
this.stashedBy = actor.stashes;
|
||||||
|
|
||||||
if (this.$refs.filter && scroll) {
|
if (this.$refs.filter && scroll) {
|
||||||
this.$refs.filter.$el.scrollIntoView();
|
this.$refs.filter.$el.scrollIntoView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stashActor() {
|
async function stashActor(stashId) {
|
||||||
this.$store.dispatch('stashActor', {
|
this.stashedBy = await this.$store.dispatch('stashActor', {
|
||||||
actorId: this.actor.id,
|
actorId: this.actor.id,
|
||||||
stashId: this.$store.getters.favorites.id,
|
stashId,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.fetchActor(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unstashActor() {
|
async function unstashActor(stashId) {
|
||||||
this.$store.dispatch('unstashActor', {
|
this.stashedBy = await this.$store.dispatch('unstashActor', {
|
||||||
actorId: this.actor.id,
|
actorId: this.actor.id,
|
||||||
stashId: this.$store.getters.favorites.id,
|
stashId,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.fetchActor(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function me() {
|
function me() {
|
||||||
return this.$store.state.auth.user;
|
return this.$store.state.auth.user;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isStashed() {
|
|
||||||
return this.actor.stashes?.length > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function sfw() {
|
function sfw() {
|
||||||
return this.$store.state.ui.sfw;
|
return this.$store.state.ui.sfw;
|
||||||
}
|
}
|
||||||
|
@ -467,6 +454,7 @@ export default {
|
||||||
Releases,
|
Releases,
|
||||||
Gender,
|
Gender,
|
||||||
Social,
|
Social,
|
||||||
|
StashButton,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
@ -477,10 +465,11 @@ export default {
|
||||||
pageTitle: null,
|
pageTitle: null,
|
||||||
bioExpanded: false,
|
bioExpanded: false,
|
||||||
photosExpanded: false,
|
photosExpanded: false,
|
||||||
|
stashed: false,
|
||||||
|
stashedBy: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
isStashed,
|
|
||||||
me,
|
me,
|
||||||
sfw,
|
sfw,
|
||||||
showAlbum,
|
showAlbum,
|
||||||
|
@ -516,6 +505,10 @@ export default {
|
||||||
background: var(--profile);
|
background: var(--profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.actor-stash {
|
||||||
|
margin: 0 1rem 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
.header-name {
|
.header-name {
|
||||||
padding: .5rem 1rem;
|
padding: .5rem 1rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
|
@ -113,6 +113,7 @@ export default {
|
||||||
|
|
||||||
.photo {
|
.photo {
|
||||||
height: 15rem;
|
height: 15rem;
|
||||||
|
width: auto;
|
||||||
box-shadow: 0 0 3px var(--darken-weak);
|
box-shadow: 0 0 3px var(--darken-weak);
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
import Warning from './warning.vue';
|
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.vue';
|
import Filters from '../filters/filters.vue';
|
||||||
|
|
||||||
function toggleSidebar(state) {
|
function toggleSidebar(state) {
|
||||||
this.showSidebar = typeof state === 'boolean' ? state : !this.showSidebar;
|
this.showSidebar = typeof state === 'boolean' ? state : !this.showSidebar;
|
||||||
|
@ -124,8 +124,6 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import 'theme';
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
@ -76,7 +76,6 @@ export default {
|
||||||
color: var(--text-light);
|
color: var(--text-light);
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-title {
|
.header-title {
|
||||||
|
@ -106,7 +105,11 @@ export default {
|
||||||
|
|
||||||
::v-deep(.dialog-actions) {
|
::v-deep(.dialog-actions) {
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: .5rem 0;
|
padding: 1rem 0 0 0;
|
||||||
|
|
||||||
|
&.center {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
&.right {
|
&.right {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<Dialog
|
<Dialog
|
||||||
title="filters"
|
title="Filters"
|
||||||
@close="$emit('close')"
|
@close="$emit('close')"
|
||||||
>
|
>
|
||||||
<div class="filters">
|
<div class="filters">
|
|
@ -1,5 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<label class="toggle-container noselect">
|
<label
|
||||||
|
class="toggle-container noselect"
|
||||||
|
:class="{ light: $store.state.ui.theme === 'dark' }"
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
:id="`toggle-${id}`"
|
:id="`toggle-${id}`"
|
||||||
:checked="checked"
|
:checked="checked"
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
v-if="release"
|
v-if="release"
|
||||||
ref="content"
|
ref="content"
|
||||||
class="content"
|
class="content"
|
||||||
|
@scroll="events.emit('scroll', $event)"
|
||||||
>
|
>
|
||||||
<Scroll
|
<Scroll
|
||||||
v-slot="slotProps"
|
v-slot="slotProps"
|
||||||
|
@ -51,18 +52,10 @@
|
||||||
/>
|
/>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<Icon
|
<StashButton
|
||||||
v-show="me && release.isStashed"
|
:stashed-by="stashedBy"
|
||||||
icon="heart7"
|
@stash="(stash) => stashScene(stash)"
|
||||||
class="stash stashed noselect"
|
@unstash="(stash) => unstashScene(stash)"
|
||||||
@click="unstashScene"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Icon
|
|
||||||
v-show="me && !release.isStashed"
|
|
||||||
icon="heart8"
|
|
||||||
class="stash unstashed noselect"
|
|
||||||
@click="stashScene"
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -230,6 +223,7 @@
|
||||||
<script>
|
<script>
|
||||||
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 Album from '../album/album.vue';
|
import Album from '../album/album.vue';
|
||||||
import Tags from './tags.vue';
|
import Tags from './tags.vue';
|
||||||
import Chapters from './chapters.vue';
|
import Chapters from './chapters.vue';
|
||||||
|
@ -249,26 +243,24 @@ async function fetchRelease(scroll = true) {
|
||||||
if (scroll && this.$refs.content) {
|
if (scroll && this.$refs.content) {
|
||||||
this.$refs.content.scrollTop = 0;
|
this.$refs.content.scrollTop = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.stashedBy = this.release.stashes;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stashScene() {
|
async function stashScene(stashId) {
|
||||||
this.$store.dispatch(this.$route.name === 'movie' ? 'stashMovie' : 'stashScene', {
|
this.stashedBy = await this.$store.dispatch(this.$route.name === 'movie' ? 'stashMovie' : 'stashScene', {
|
||||||
sceneId: this.release.id,
|
sceneId: this.release.id,
|
||||||
movieId: this.release.id,
|
movieId: this.release.id,
|
||||||
stashId: this.$store.getters.favorites.id,
|
stashId,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.fetchRelease(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unstashScene() {
|
async function unstashScene(stashId) {
|
||||||
this.$store.dispatch(this.$route.name === 'movie' ? 'unstashMovie' : 'unstashScene', {
|
this.stashedBy = await this.$store.dispatch(this.$route.name === 'movie' ? 'unstashMovie' : 'unstashScene', {
|
||||||
sceneId: this.release.id,
|
sceneId: this.release.id,
|
||||||
movieId: this.release.id,
|
movieId: this.release.id,
|
||||||
stashId: this.$store.getters.favorites.id,
|
stashId,
|
||||||
});
|
});
|
||||||
|
|
||||||
this.fetchRelease(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function me() {
|
function me() {
|
||||||
|
@ -294,16 +286,18 @@ export default {
|
||||||
components: {
|
components: {
|
||||||
Actor,
|
Actor,
|
||||||
Album,
|
Album,
|
||||||
Details,
|
|
||||||
Banner,
|
Banner,
|
||||||
Scroll,
|
|
||||||
Releases,
|
|
||||||
Chapters,
|
Chapters,
|
||||||
|
Details,
|
||||||
|
Releases,
|
||||||
|
Scroll,
|
||||||
|
StashButton,
|
||||||
Tags,
|
Tags,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
release: null,
|
release: null,
|
||||||
|
stashedBy: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -394,22 +388,6 @@ export default {
|
||||||
color: var(--shadow);
|
color: var(--shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash.icon {
|
|
||||||
width: 1.5rem;
|
|
||||||
height: 1.5rem;
|
|
||||||
padding: 0 1rem;
|
|
||||||
fill: var(--darken);
|
|
||||||
|
|
||||||
&.stashed {
|
|
||||||
fill: var(--primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
fill: var(--primary);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.album-toggle {
|
.album-toggle {
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
|
|
|
@ -451,7 +451,7 @@ export default {
|
||||||
.tile.new .poster::after {
|
.tile.new .poster::after {
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
top: auto;
|
top: auto;
|
||||||
margin: 0 .25rem;
|
margin: .1rem .25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash {
|
.stash {
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
<template>
|
||||||
|
<span class="stash-container">
|
||||||
|
<Tooltip class="stash-trigger">
|
||||||
|
<Icon
|
||||||
|
v-show="me"
|
||||||
|
icon="menu"
|
||||||
|
class="stash noselect"
|
||||||
|
:class="{ stashed }"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<template v-slot:tooltip>
|
||||||
|
<StashMenu
|
||||||
|
:stashed-by="stashedBy"
|
||||||
|
@stash="(stashId) => $emit('stash', stashId)"
|
||||||
|
@unstash="(stashId) => $emit('unstash', stashId)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</Tooltip>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
v-show="me && favorited"
|
||||||
|
icon="heart7"
|
||||||
|
class="stash stashed noselect"
|
||||||
|
@click.native="() => $emit('unstash', favorites.id)"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
v-show="me && !favorited"
|
||||||
|
icon="heart8"
|
||||||
|
class="stash unstashed noselect"
|
||||||
|
@click.native="() => $emit('stash', favorites.id)"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import StashMenu from './menu.vue';
|
||||||
|
|
||||||
|
function favorited() {
|
||||||
|
return this.stashedBy.some(stash => stash.primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stashed() {
|
||||||
|
return this.stashedBy.some(stash => !stash.primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
function favorites() {
|
||||||
|
return this.$store.getters.favorites;
|
||||||
|
}
|
||||||
|
|
||||||
|
function me() {
|
||||||
|
return this.$store.state.auth.user;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
StashMenu,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
stashedBy: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ['stash', 'unstash'],
|
||||||
|
computed: {
|
||||||
|
me,
|
||||||
|
favorites,
|
||||||
|
favorited,
|
||||||
|
stashed,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.stash-container.light .icon {
|
||||||
|
fill: var(--lighten);
|
||||||
|
}
|
||||||
|
|
||||||
|
.stash.icon {
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 1.5rem;
|
||||||
|
padding: 0 .5rem;
|
||||||
|
fill: var(--shadow);
|
||||||
|
|
||||||
|
&.stashed {
|
||||||
|
fill: var(--primary);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
fill: var(--primary);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.stash-trigger {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,70 @@
|
||||||
|
<template>
|
||||||
|
<ul class="menu nolist">
|
||||||
|
<li
|
||||||
|
v-for="stash in stashes"
|
||||||
|
:key="`stash-${stash.id}`"
|
||||||
|
class="menu-item"
|
||||||
|
>
|
||||||
|
<label class="menu-stash noselect">
|
||||||
|
<Checkbox
|
||||||
|
:checked="stashedByIds.has(stash.id)"
|
||||||
|
class="menu-check"
|
||||||
|
@change="(checked) => checked ? $emit('stash', stash.id) : $emit('unstash', stash.id)"
|
||||||
|
/>{{ stash.name }}
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Checkbox from '../form/checkbox.vue';
|
||||||
|
|
||||||
|
function stashes() {
|
||||||
|
return this.$store.state.auth.user?.stashes || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Checkbox,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
stashedBy: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ['stash', 'unstash'],
|
||||||
|
data() {
|
||||||
|
const stashedByIds = new Set(this.stashedBy.map(stash => stash.id));
|
||||||
|
|
||||||
|
return {
|
||||||
|
stashedByIds,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
stashes,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.menu-item {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-stash {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: .5rem 1rem .5rem .5rem;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--primary);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-check {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 .75rem 0 0;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,38 @@
|
||||||
|
<template>
|
||||||
|
<Dialog
|
||||||
|
title="Remove stash"
|
||||||
|
@close="$emit('close', false)"
|
||||||
|
>
|
||||||
|
<form @submit.prevent="removeStash">
|
||||||
|
Are you sure you want to remove stash "{{ stash.name }}"?
|
||||||
|
|
||||||
|
<div class="dialog-actions right">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="button button-primary"
|
||||||
|
>Remove</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
async function removeStash() {
|
||||||
|
await this.$store.dispatch('removeStash', this.stash.id);
|
||||||
|
|
||||||
|
this.$emit('close', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
stash: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ['close'],
|
||||||
|
methods: {
|
||||||
|
removeStash,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -4,9 +4,18 @@
|
||||||
class="stash content"
|
class="stash content"
|
||||||
>
|
>
|
||||||
<div class="stash-header">
|
<div class="stash-header">
|
||||||
<h2 class="stash-name">{{ stash.name }}</h2>
|
<h2
|
||||||
|
:title="stash.name"
|
||||||
|
class="stash-name"
|
||||||
|
>{{ stash.name }}</h2>
|
||||||
|
|
||||||
<span class="header-section">
|
<span class="header-section">
|
||||||
|
<router-link
|
||||||
|
v-if="stash.user"
|
||||||
|
:to="{ name: 'user', params: { username: stash.user.username } }"
|
||||||
|
class="header-item stash-username nolink"
|
||||||
|
><Icon icon="user3" /><span class="username-name">{{ stash.user.username }}</span></router-link>
|
||||||
|
|
||||||
<label
|
<label
|
||||||
v-if="isMine"
|
v-if="isMine"
|
||||||
v-tooltip="'Public'"
|
v-tooltip="'Public'"
|
||||||
|
@ -30,11 +39,18 @@
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<router-link
|
<Icon
|
||||||
v-if="stash.user"
|
v-if="isMine && !stash.primary"
|
||||||
:to="{ name: 'user', params: { username: stash.user.username } }"
|
icon="bin"
|
||||||
class="header-item stash-username nolink"
|
class="stash-remove"
|
||||||
><Icon icon="user3" />{{ stash.user.username }}</router-link>
|
@click.native="showRemoveStash = true"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<RemoveStash
|
||||||
|
v-if="showRemoveStash"
|
||||||
|
:stash="stash"
|
||||||
|
@close="removeStash"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -62,6 +78,7 @@
|
||||||
<script>
|
<script>
|
||||||
import Actor from '../actors/tile.vue';
|
import Actor from '../actors/tile.vue';
|
||||||
import Releases from '../releases/releases.vue';
|
import Releases from '../releases/releases.vue';
|
||||||
|
import RemoveStash from './remove-stash.vue';
|
||||||
import Toggle from '../form/toggle.vue';
|
import Toggle from '../form/toggle.vue';
|
||||||
|
|
||||||
async function fetchStash() {
|
async function fetchStash() {
|
||||||
|
@ -78,6 +95,19 @@ async function publishStash(isPublic) {
|
||||||
this.fetchStash();
|
this.fetchStash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function removeStash(removed) {
|
||||||
|
this.showRemoveStash = false;
|
||||||
|
|
||||||
|
if (removed && this.stash.user) {
|
||||||
|
this.$router.replace({ name: 'user', params: { username: this.stash.user.username } });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (removed) {
|
||||||
|
this.$router.replace({ name: 'home' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function mounted() {
|
async function mounted() {
|
||||||
this.fetchStash();
|
this.fetchStash();
|
||||||
}
|
}
|
||||||
|
@ -86,11 +116,13 @@ export default {
|
||||||
components: {
|
components: {
|
||||||
Actor,
|
Actor,
|
||||||
Releases,
|
Releases,
|
||||||
|
RemoveStash,
|
||||||
Toggle,
|
Toggle,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
stash: null,
|
stash: null,
|
||||||
|
showRemoveStash: false,
|
||||||
isMine: false,
|
isMine: false,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -98,11 +130,14 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
fetchStash,
|
fetchStash,
|
||||||
publishStash,
|
publishStash,
|
||||||
|
removeStash,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@import 'breakpoints';
|
||||||
|
|
||||||
.stash-header {
|
.stash-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
@ -123,12 +158,29 @@ export default {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-item:not(:last-child) {
|
.stash-name,
|
||||||
margin: 0 1rem 0 0;
|
.stash-username {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: .5rem 1rem;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stash-username {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 .5rem 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stash-name {
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash-public {
|
.stash-public {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
margin: 0 .5rem 0 0;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
margin: 0 .75rem 0 0;
|
margin: 0 .75rem 0 0;
|
||||||
|
@ -136,13 +188,15 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash-name,
|
.stash-remove.icon {
|
||||||
.stash-username {
|
height: 100%;
|
||||||
display: inline-flex;
|
padding: 0 1rem;
|
||||||
align-items: center;
|
fill: var(--lighten-strong);
|
||||||
padding: .5rem 1rem;
|
|
||||||
margin: 0;
|
&:hover {
|
||||||
font-weight: bold;
|
fill: var(--text-light);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash-section:not(:last-child) {
|
.stash-section:not(:last-child) {
|
||||||
|
@ -164,4 +218,18 @@ export default {
|
||||||
grid-template-columns: repeat(auto-fill, minmax(22rem, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(22rem, 1fr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media(max-width: $breakpoint-small) {
|
||||||
|
.stash-name {
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.username-name {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stash-username {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -63,7 +63,7 @@ export default {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
background: var(--shadow-weak);
|
background: var(--darken-weak);
|
||||||
color: var(--text-light);
|
color: var(--text-light);
|
||||||
font-size: .7rem;
|
font-size: .7rem;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
|
@ -6,29 +6,45 @@
|
||||||
class="stash-link nolink"
|
class="stash-link nolink"
|
||||||
>
|
>
|
||||||
<h4 class="stash-name">{{ stash.name }}</h4>
|
<h4 class="stash-name">{{ stash.name }}</h4>
|
||||||
|
<span class="stash-more">Browse</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
|
||||||
<label
|
<span class="header-actions noselect">
|
||||||
v-if="isMe"
|
<label
|
||||||
v-tooltip="'Public'"
|
v-if="isMe"
|
||||||
:class="{ public: stash.public }"
|
v-tooltip="'Public'"
|
||||||
class="stash-public"
|
:class="{ public: stash.public }"
|
||||||
>
|
class="stash-public"
|
||||||
<Icon
|
>
|
||||||
v-show="stash.public"
|
<Icon
|
||||||
icon="eye"
|
v-show="stash.public"
|
||||||
/>
|
icon="eye"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
v-show="!stash.public"
|
||||||
|
icon="eye-blocked"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Toggle
|
||||||
|
:checked="stash.public"
|
||||||
|
@change="checked => publishStash(checked)"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
v-show="!stash.public"
|
v-if="isMe && !stash.primary"
|
||||||
icon="eye-blocked"
|
icon="bin"
|
||||||
|
class="stash-remove"
|
||||||
|
@click.native="showRemoveStash = true"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Toggle
|
<RemoveStash
|
||||||
:checked="stash.public"
|
v-if="showRemoveStash"
|
||||||
@change="checked => publishStash(stash, checked)"
|
:stash="stash"
|
||||||
|
@close="removeStash"
|
||||||
/>
|
/>
|
||||||
</label>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul
|
<ul
|
||||||
|
@ -68,21 +84,31 @@
|
||||||
<script>
|
<script>
|
||||||
import ActorPreview from './actor-preview.vue';
|
import ActorPreview from './actor-preview.vue';
|
||||||
import ScenePreview from './scene-preview.vue';
|
import ScenePreview from './scene-preview.vue';
|
||||||
|
import RemoveStash from '../stashes/remove-stash.vue';
|
||||||
import Toggle from '../form/toggle.vue';
|
import Toggle from '../form/toggle.vue';
|
||||||
|
|
||||||
async function publishStash(stash, isPublic) {
|
async function publishStash(isPublic) {
|
||||||
await this.$store.dispatch('updateStash', {
|
await this.$store.dispatch('updateStash', {
|
||||||
stashId: stash.id,
|
stashId: this.stash.id,
|
||||||
stash: { public: isPublic },
|
stash: { public: isPublic },
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$emit('publish', isPublic);
|
this.$emit('publish', isPublic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function removeStash(removed) {
|
||||||
|
this.showRemoveStash = false;
|
||||||
|
|
||||||
|
if (removed) {
|
||||||
|
this.$emit('remove');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
ActorPreview,
|
ActorPreview,
|
||||||
ScenePreview,
|
ScenePreview,
|
||||||
|
RemoveStash,
|
||||||
Toggle,
|
Toggle,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
|
@ -95,9 +121,15 @@ export default {
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
emits: ['publish'],
|
emits: ['publish', 'remove'],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showRemoveStash: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
publishStash,
|
publishStash,
|
||||||
|
removeStash,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
@ -123,17 +155,46 @@ export default {
|
||||||
|
|
||||||
.stash-header {
|
.stash-header {
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
align-items: stretch;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash-link {
|
.stash-link {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
display: inline-block;
|
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&:hover .stash-more {
|
||||||
|
color: var(--primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.stash-name {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 .5rem;
|
||||||
|
margin: 0;
|
||||||
|
color: var(--shadow-strong);
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stash-more {
|
||||||
|
flex-shrink: 0;
|
||||||
|
margin: 0 0 0 .5rem;
|
||||||
|
color: var(--shadow);
|
||||||
|
font-size: .9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash-public {
|
.stash-public {
|
||||||
display: flex;
|
display: inline-flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: .5rem;
|
padding: .5rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -144,10 +205,15 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash-name {
|
.stash-remove {
|
||||||
padding: .5rem;
|
height: auto;
|
||||||
margin: 0;
|
padding: 0 .5rem 0 .75rem;
|
||||||
color: var(--shadow-strong);
|
fill: var(--shadow);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
fill: var(--shadow-strong);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.stash-actors,
|
.stash-actors,
|
||||||
|
|
|
@ -11,23 +11,33 @@
|
||||||
v-if="user.stashes?.length > 0"
|
v-if="user.stashes?.length > 0"
|
||||||
class="section"
|
class="section"
|
||||||
>
|
>
|
||||||
<h3 class="heading">Stashes</h3>
|
<div class="section-header">
|
||||||
|
<h3 class="section-heading">Stashes</h3>
|
||||||
|
|
||||||
<ul class="stashes nolist">
|
<Icon
|
||||||
|
icon="plus3"
|
||||||
|
class="header-add"
|
||||||
|
@click="showAddStash = true"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="section-body stashes nolist">
|
||||||
<li
|
<li
|
||||||
v-for="stash in user.stashes"
|
v-for="stash in user.stashes"
|
||||||
:key="stash.id"
|
:key="stash.id"
|
||||||
|
class="stashes-stash"
|
||||||
>
|
>
|
||||||
<Stash
|
<Stash
|
||||||
:stash="stash"
|
:stash="stash"
|
||||||
:is-me="isMe"
|
:is-me="isMe"
|
||||||
@publish="() => fetchUser()"
|
@publish="() => fetchUser()"
|
||||||
|
@remove="() => fetchUser()"
|
||||||
/>
|
/>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li
|
<li
|
||||||
v-if="isMe"
|
v-if="isMe"
|
||||||
class="stashes-add"
|
class="stashes-stash stashes-add"
|
||||||
@click="showAddStash = true"
|
@click="showAddStash = true"
|
||||||
>
|
>
|
||||||
<Icon icon="plus2" />
|
<Icon icon="plus2" />
|
||||||
|
@ -92,18 +102,23 @@ export default {
|
||||||
@import 'breakpoints';
|
@import 'breakpoints';
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
padding: .5rem 1rem;
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
background: var(--profile);
|
background: var(--profile);
|
||||||
}
|
}
|
||||||
|
|
||||||
.username {
|
.username {
|
||||||
|
padding: .5rem 1rem;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
color: var(--text-light);
|
color: var(--text-light);
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
.section {
|
.section {
|
||||||
padding: 1rem;
|
padding: 1rem 0;
|
||||||
margin: 0 0 1rem 0;
|
margin: 0 0 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -114,8 +129,37 @@ export default {
|
||||||
grid-gap: 1rem;
|
grid-gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heading {
|
.section-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 0 1rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-body {
|
||||||
|
padding: 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-heading {
|
||||||
color: var(--primary);
|
color: var(--primary);
|
||||||
|
padding: 0 1rem;
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-add {
|
||||||
|
height: auto;
|
||||||
|
padding: .5rem 1rem;
|
||||||
|
fill: var(--shadow);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
fill: var(--primary);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.stashes-stash {
|
||||||
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stashes-add {
|
.stashes-add {
|
||||||
|
@ -123,20 +167,20 @@ export default {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: var(--shadow-hint);
|
background: var(--shadow-touch);
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
fill: var(--shadow-weak);
|
fill: var(--shadow-hint);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: var(--shadow-weak);
|
background: var(--shadow-hint);
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
fill: var(--shadow);
|
fill: var(--shadow-weak);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,14 @@ $breakpoint4: 1500px;
|
||||||
--darken-censor: rgba(0, 0, 0, .95);
|
--darken-censor: rgba(0, 0, 0, .95);
|
||||||
--darken-weak: rgba(0, 0, 0, .2);
|
--darken-weak: rgba(0, 0, 0, .2);
|
||||||
--darken-hint: rgba(0, 0, 0, .1);
|
--darken-hint: rgba(0, 0, 0, .1);
|
||||||
|
--darken-touch: rgba(0, 0, 0, .05);
|
||||||
|
|
||||||
--lighten: rgba(255, 255, 255, .5);
|
--lighten: rgba(255, 255, 255, .5);
|
||||||
--lighten-strong: rgba(255, 255, 255, .7);
|
--lighten-strong: rgba(255, 255, 255, .7);
|
||||||
--lighten-extreme: rgba(255, 255, 255, .9);
|
--lighten-extreme: rgba(255, 255, 255, .9);
|
||||||
--lighten-weak: rgba(255, 255, 255, .2);
|
--lighten-weak: rgba(255, 255, 255, .2);
|
||||||
--lighten-hint: rgba(255, 255, 255, .05);
|
--lighten-hint: rgba(255, 255, 255, .05);
|
||||||
|
--lighten-touch: rgba(255, 255, 255, .03);
|
||||||
|
|
||||||
--logo-shadow: drop-shadow(1px 0 0 $shadow-weak) drop-shadow(-1px 0 0 $shadow-weak) drop-shadow(0 1px 0 $shadow-weak) drop-shadow(0 -1px 0 $shadow-weak);
|
--logo-shadow: drop-shadow(1px 0 0 $shadow-weak) drop-shadow(-1px 0 0 $shadow-weak) drop-shadow(0 1px 0 $shadow-weak) drop-shadow(0 -1px 0 $shadow-weak);
|
||||||
--logo-highlight: drop-shadow(0 0 1px $highlight);
|
--logo-highlight: drop-shadow(0 0 1px $highlight);
|
||||||
|
|
|
@ -246,6 +246,7 @@ function initActorActions(store, router) {
|
||||||
}
|
}
|
||||||
totalCount
|
totalCount
|
||||||
}
|
}
|
||||||
|
isStashed
|
||||||
stashes: stashesActors(
|
stashes: stashesActors(
|
||||||
filter: {
|
filter: {
|
||||||
stash: {
|
stash: {
|
||||||
|
@ -259,6 +260,7 @@ function initActorActions(store, router) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
|
primary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,12 @@ async function del(endpoint) {
|
||||||
credentials: 'same-origin',
|
credentials: 'same-origin',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const contentTypes = res.headers.get('content-type');
|
||||||
|
|
||||||
|
if (res.ok && contentTypes?.includes('application/json')) {
|
||||||
|
return res.json();
|
||||||
|
}
|
||||||
|
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,10 @@ function curateActor(actor, release) {
|
||||||
curatedActor.aliasFor = curateActor(curatedActor.aliasFor);
|
curatedActor.aliasFor = curateActor(curatedActor.aliasFor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actor.stashes) {
|
||||||
|
curatedActor.stashes = actor.stashes.filter(Boolean).map(stash => curateStash(stash.stash || stash)); // eslint-disable-line no-use-before-define
|
||||||
|
}
|
||||||
|
|
||||||
curatedActor.stashes = actor.stashes?.map(stash => stash.stash || stash) || [];
|
curatedActor.stashes = actor.stashes?.map(stash => stash.stash || stash) || [];
|
||||||
|
|
||||||
return curatedActor;
|
return curatedActor;
|
||||||
|
@ -80,6 +84,7 @@ function curateRelease(release) {
|
||||||
if (release.directors) curatedRelease.directors = release.directors.filter(Boolean).map(director => curateActor(director.director || director, curatedRelease));
|
if (release.directors) curatedRelease.directors = release.directors.filter(Boolean).map(director => curateActor(director.director || director, curatedRelease));
|
||||||
if (release.movieTags && release.movieTags.length > 0) curatedRelease.tags = release.movieTags.filter(Boolean).map(({ tag }) => tag);
|
if (release.movieTags && release.movieTags.length > 0) curatedRelease.tags = release.movieTags.filter(Boolean).map(({ tag }) => tag);
|
||||||
if (release.movieActors && release.movieActors.length > 0) curatedRelease.actors = release.movieActors.filter(Boolean).map(({ actor }) => curateActor(actor, curatedRelease));
|
if (release.movieActors && release.movieActors.length > 0) curatedRelease.actors = release.movieActors.filter(Boolean).map(({ actor }) => curateActor(actor, curatedRelease));
|
||||||
|
if (release.stashes) curatedRelease.stashes = release.stashes.filter(Boolean).map(stash => curateStash(stash.stash || stash)); // eslint-disable-line no-use-before-define
|
||||||
|
|
||||||
if (release.productionLocation) {
|
if (release.productionLocation) {
|
||||||
curatedRelease.productionLocation = {
|
curatedRelease.productionLocation = {
|
||||||
|
@ -155,7 +160,7 @@ function curateUser(user) {
|
||||||
const curatedUser = user;
|
const curatedUser = user;
|
||||||
|
|
||||||
if (user.stashes) {
|
if (user.stashes) {
|
||||||
curatedUser.stashes = user.stashes.map(stash => curateStash(stash));
|
curatedUser.stashes = user.stashes.map(stash => curateStash(stash.stash || stash));
|
||||||
}
|
}
|
||||||
|
|
||||||
return curatedUser;
|
return curatedUser;
|
||||||
|
|
|
@ -228,7 +228,8 @@ const releaseFields = `
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
isNew
|
isNew
|
||||||
isStashed
|
isFavorited
|
||||||
|
isStashed(includeFavorites: false)
|
||||||
stashes: stashesScenesBySceneId(
|
stashes: stashesScenesBySceneId(
|
||||||
filter: {
|
filter: {
|
||||||
stash: {
|
stash: {
|
||||||
|
@ -242,6 +243,7 @@ const releaseFields = `
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
|
primary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
@ -368,7 +370,8 @@ const releaseFragment = `
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isStashed
|
isFavorited
|
||||||
|
isStashed(includeFavorites: false)
|
||||||
stashes: stashesScenesBySceneId(
|
stashes: stashesScenesBySceneId(
|
||||||
filter: {
|
filter: {
|
||||||
stash: {
|
stash: {
|
||||||
|
@ -382,6 +385,7 @@ const releaseFragment = `
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
|
primary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -273,6 +273,7 @@ function initReleasesActions(store, router) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
|
primary
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ function initStashesActions(store, _router) {
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
public
|
public
|
||||||
|
primary
|
||||||
user {
|
user {
|
||||||
id
|
id
|
||||||
username
|
username
|
||||||
|
@ -68,44 +69,45 @@ function initStashesActions(store, _router) {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createStash(context, stash) {
|
async function createStash(context, stash) {
|
||||||
const newStash = await post('/stashes', stash);
|
return post('/stashes', stash);
|
||||||
|
|
||||||
return newStash;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateStash(context, { stashId, stash }) {
|
async function updateStash(context, { stashId, stash }) {
|
||||||
const newStash = await patch(`/stashes/${stashId}`, stash);
|
return patch(`/stashes/${stashId}`, stash);
|
||||||
|
}
|
||||||
|
|
||||||
return newStash;
|
async function removeStash(context, stashId) {
|
||||||
|
await del(`/stashes/${stashId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stashActor(context, { actorId, stashId }) {
|
async function stashActor(context, { actorId, stashId }) {
|
||||||
await post(`/stashes/${stashId}/actors`, { actorId });
|
return post(`/stashes/${stashId}/actors`, { actorId });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unstashActor(context, { actorId, stashId }) {
|
async function unstashActor(context, { actorId, stashId }) {
|
||||||
await del(`/stashes/${stashId}/actors/${actorId}`);
|
return del(`/stashes/${stashId}/actors/${actorId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stashScene(context, { sceneId, stashId }) {
|
async function stashScene(context, { sceneId, stashId }) {
|
||||||
await post(`/stashes/${stashId}/scenes`, { sceneId });
|
return post(`/stashes/${stashId}/scenes`, { sceneId });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unstashScene(context, { sceneId, stashId }) {
|
async function unstashScene(context, { sceneId, stashId }) {
|
||||||
await del(`/stashes/${stashId}/scenes/${sceneId}`);
|
return del(`/stashes/${stashId}/scenes/${sceneId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stashMovie(context, { movieId, stashId }) {
|
async function stashMovie(context, { movieId, stashId }) {
|
||||||
await post(`/stashes/${stashId}/movies`, { movieId });
|
return post(`/stashes/${stashId}/movies`, { movieId });
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unstashMovie(context, { movieId, stashId }) {
|
async function unstashMovie(context, { movieId, stashId }) {
|
||||||
await del(`/stashes/${stashId}/movies/${movieId}`);
|
return del(`/stashes/${stashId}/movies/${movieId}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
createStash,
|
createStash,
|
||||||
fetchStash,
|
fetchStash,
|
||||||
|
removeStash,
|
||||||
stashActor,
|
stashActor,
|
||||||
stashScene,
|
stashScene,
|
||||||
stashMovie,
|
stashMovie,
|
||||||
|
|
|
@ -19,6 +19,7 @@ function initUsersActions(store, _router) {
|
||||||
name
|
name
|
||||||
slug
|
slug
|
||||||
public
|
public
|
||||||
|
primary
|
||||||
actors: stashesActors {
|
actors: stashesActors {
|
||||||
comment
|
comment
|
||||||
actor {
|
actor {
|
||||||
|
|
|
@ -1067,6 +1067,10 @@ exports.up = knex => Promise.resolve()
|
||||||
.notNullable()
|
.notNullable()
|
||||||
.defaultTo(false);
|
.defaultTo(false);
|
||||||
|
|
||||||
|
table.boolean('primary')
|
||||||
|
.notNullable()
|
||||||
|
.defaultTo(false);
|
||||||
|
|
||||||
table.datetime('created_at')
|
table.datetime('created_at')
|
||||||
.notNullable()
|
.notNullable()
|
||||||
.defaultTo(knex.fn.now());
|
.defaultTo(knex.fn.now());
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
{
|
{
|
||||||
"name": "traxxx",
|
"name": "traxxx",
|
||||||
"version": "1.189.1",
|
"version": "1.190.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"version": "1.189.1",
|
"version": "1.190.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@casl/ability": "^5.2.2",
|
"@casl/ability": "^5.2.2",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "traxxx",
|
"name": "traxxx",
|
||||||
"version": "1.189.1",
|
"version": "1.190.0",
|
||||||
"description": "All the latest porn releases in one place",
|
"description": "All the latest porn releases in one place",
|
||||||
"main": "src/app.js",
|
"main": "src/app.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
@ -80,6 +80,7 @@ async function signup(credentials) {
|
||||||
name: 'Favorites',
|
name: 'Favorites',
|
||||||
slug: 'favorites',
|
slug: 'favorites',
|
||||||
public: false,
|
public: false,
|
||||||
|
primary: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
return fetchUser(userId);
|
return fetchUser(userId);
|
||||||
|
|
|
@ -13,6 +13,7 @@ function curateStash(stash) {
|
||||||
id: stash.id,
|
id: stash.id,
|
||||||
name: stash.name,
|
name: stash.name,
|
||||||
slug: stash.slug,
|
slug: stash.slug,
|
||||||
|
primary: stash.primary,
|
||||||
};
|
};
|
||||||
|
|
||||||
return curatedStash;
|
return curatedStash;
|
||||||
|
@ -48,6 +49,18 @@ async function fetchStash(stashId, sessionUser) {
|
||||||
return curateStash(stash);
|
return curateStash(stash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function fetchStashes(domain, itemId, sessionUser) {
|
||||||
|
const stashes = await knex(`stashes_${domain}s`)
|
||||||
|
.select('stashes.*')
|
||||||
|
.where({
|
||||||
|
[`${domain}_id`]: itemId,
|
||||||
|
user_id: sessionUser.id,
|
||||||
|
})
|
||||||
|
.leftJoin('stashes', 'stashes.id', `stashes_${domain}s.stash_id`);
|
||||||
|
|
||||||
|
return stashes.map(stash => curateStash(stash));
|
||||||
|
}
|
||||||
|
|
||||||
async function createStash(newStash, sessionUser) {
|
async function createStash(newStash, sessionUser) {
|
||||||
if (!sessionUser) {
|
if (!sessionUser) {
|
||||||
throw new HttpError('You are not authenthicated', 401);
|
throw new HttpError('You are not authenthicated', 401);
|
||||||
|
@ -80,6 +93,24 @@ async function updateStash(stashId, newStash, sessionUser) {
|
||||||
return curateStash(stash);
|
return curateStash(stash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function removeStash(stashId, sessionUser) {
|
||||||
|
if (!sessionUser) {
|
||||||
|
throw new HttpError('You are not authenthicated', 401);
|
||||||
|
}
|
||||||
|
|
||||||
|
const removed = await knex('stashes')
|
||||||
|
.where({
|
||||||
|
id: stashId,
|
||||||
|
user_id: sessionUser.id,
|
||||||
|
primary: false,
|
||||||
|
})
|
||||||
|
.delete();
|
||||||
|
|
||||||
|
if (removed === 0) {
|
||||||
|
throw new HttpError('Unable to remove this stash', 400);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function stashActor(actorId, stashId, sessionUser) {
|
async function stashActor(actorId, stashId, sessionUser) {
|
||||||
const stash = await fetchStash(stashId, sessionUser);
|
const stash = await fetchStash(stashId, sessionUser);
|
||||||
|
|
||||||
|
@ -88,6 +119,8 @@ async function stashActor(actorId, stashId, sessionUser) {
|
||||||
stash_id: stash.id,
|
stash_id: stash.id,
|
||||||
actor_id: actorId,
|
actor_id: actorId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return fetchStashes('actor', actorId, sessionUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stashScene(sceneId, stashId, sessionUser) {
|
async function stashScene(sceneId, stashId, sessionUser) {
|
||||||
|
@ -98,6 +131,8 @@ async function stashScene(sceneId, stashId, sessionUser) {
|
||||||
stash_id: stash.id,
|
stash_id: stash.id,
|
||||||
scene_id: sceneId,
|
scene_id: sceneId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return fetchStashes('scene', sceneId, sessionUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stashMovie(movieId, stashId, sessionUser) {
|
async function stashMovie(movieId, stashId, sessionUser) {
|
||||||
|
@ -108,6 +143,8 @@ async function stashMovie(movieId, stashId, sessionUser) {
|
||||||
stash_id: stash.id,
|
stash_id: stash.id,
|
||||||
movie_id: movieId,
|
movie_id: movieId,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return fetchStashes('movie', movieId, sessionUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unstashActor(actorId, stashId, sessionUser) {
|
async function unstashActor(actorId, stashId, sessionUser) {
|
||||||
|
@ -120,6 +157,8 @@ async function unstashActor(actorId, stashId, sessionUser) {
|
||||||
.where('stashes_actors.stash_id', knex.raw('deletable.stash_id'))
|
.where('stashes_actors.stash_id', knex.raw('deletable.stash_id'))
|
||||||
.where('stashes.user_id', sessionUser.id))
|
.where('stashes.user_id', sessionUser.id))
|
||||||
.delete();
|
.delete();
|
||||||
|
|
||||||
|
return fetchStashes('actor', actorId, sessionUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unstashScene(sceneId, stashId, sessionUser) {
|
async function unstashScene(sceneId, stashId, sessionUser) {
|
||||||
|
@ -132,6 +171,8 @@ async function unstashScene(sceneId, stashId, sessionUser) {
|
||||||
.where('stashes_scenes.stash_id', knex.raw('deletable.stash_id'))
|
.where('stashes_scenes.stash_id', knex.raw('deletable.stash_id'))
|
||||||
.where('stashes.user_id', sessionUser.id))
|
.where('stashes.user_id', sessionUser.id))
|
||||||
.delete();
|
.delete();
|
||||||
|
|
||||||
|
return fetchStashes('scene', sceneId, sessionUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unstashMovie(movieId, stashId, sessionUser) {
|
async function unstashMovie(movieId, stashId, sessionUser) {
|
||||||
|
@ -144,11 +185,14 @@ async function unstashMovie(movieId, stashId, sessionUser) {
|
||||||
.where('stashes_movies.stash_id', knex.raw('deletable.stash_id'))
|
.where('stashes_movies.stash_id', knex.raw('deletable.stash_id'))
|
||||||
.where('stashes.user_id', sessionUser.id))
|
.where('stashes.user_id', sessionUser.id))
|
||||||
.delete();
|
.delete();
|
||||||
|
|
||||||
|
return fetchStashes('movie', movieId, sessionUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createStash,
|
createStash,
|
||||||
curateStash,
|
curateStash,
|
||||||
|
removeStash,
|
||||||
stashActor,
|
stashActor,
|
||||||
stashScene,
|
stashScene,
|
||||||
stashMovie,
|
stashMovie,
|
||||||
|
|
|
@ -26,7 +26,7 @@ function curateUser(user) {
|
||||||
|
|
||||||
async function fetchUser(userId, raw) {
|
async function fetchUser(userId, raw) {
|
||||||
const user = await knex('users')
|
const user = await knex('users')
|
||||||
.select(knex.raw('users.*, users_roles.abilities as role_abilities, COALESCE(json_agg(stashes) FILTER (WHERE stashes.id IS NOT NULL), \'[]\') as stashes'))
|
.select(knex.raw('users.*, users_roles.abilities as role_abilities, COALESCE(json_agg(stashes ORDER BY stashes.created_at) FILTER (WHERE stashes.id IS NOT NULL), \'[]\') as stashes'))
|
||||||
.modify((builder) => {
|
.modify((builder) => {
|
||||||
if (typeof userId === 'number') {
|
if (typeof userId === 'number') {
|
||||||
builder.where('users.id', userId);
|
builder.where('users.id', userId);
|
||||||
|
|
|
@ -22,7 +22,7 @@ async function logoutApi(req, res) {
|
||||||
|
|
||||||
async function fetchMeApi(req, res) {
|
async function fetchMeApi(req, res) {
|
||||||
if (req.session.user) {
|
if (req.session.user) {
|
||||||
req.session.user = await fetchUser(req.session.user.id, req.session.user);
|
req.session.user = await fetchUser(req.session.user.id, false, req.session.user);
|
||||||
|
|
||||||
res.send(req.session.user);
|
res.send(req.session.user);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -12,16 +12,36 @@ const schemaExtender = makeExtendSchemaPlugin(_build => ({
|
||||||
}
|
}
|
||||||
|
|
||||||
extend type Actor {
|
extend type Actor {
|
||||||
|
isFavorited: Boolean @requires(columns: ["stashesActors"])
|
||||||
|
isStashed(includeFavorites: Boolean = false): Boolean @requires(columns: ["stashesActors"])
|
||||||
ageFromBirth: Int @requires(columns: ["dateOfBirth"])
|
ageFromBirth: Int @requires(columns: ["dateOfBirth"])
|
||||||
ageAtDeath: Int @requires(columns: ["dateOfBirth", "dateOfDeath"])
|
ageAtDeath: Int @requires(columns: ["dateOfBirth", "dateOfDeath"])
|
||||||
height(units:Units): String @requires(columns: ["height"])
|
height(units: Units): String @requires(columns: ["height"])
|
||||||
weight(units:Units): String @requires(columns: ["weight"])
|
weight(units: Units): String @requires(columns: ["weight"])
|
||||||
penisLength(units:Units): String @requires(columns: ["penis_length"])
|
penisLength(units: Units): String @requires(columns: ["penis_length"])
|
||||||
penisGirth(units:Units): String @requires(columns: ["penis_girth"])
|
penisGirth(units: Units): String @requires(columns: ["penis_girth"])
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
resolvers: {
|
resolvers: {
|
||||||
Actor: {
|
Actor: {
|
||||||
|
isFavorited(parent) {
|
||||||
|
if (!parent['@stashes'] || typeof parent['@stashes'][0]['@stash'].primary === 'undefined') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent['@stashes'].some(({ '@stash': stash }) => stash.primary);
|
||||||
|
},
|
||||||
|
isStashed(parent, args) {
|
||||||
|
if (!parent['@stashes'] || typeof parent['@stashes'][0]['@stash'].primary === 'undefined') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.includeFavorites) {
|
||||||
|
return parent['@stashes'].length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent['@stashes'].some(({ '@stash': stash }) => !stash.primary);
|
||||||
|
},
|
||||||
ageFromBirth(parent, _args, _context, _info) {
|
ageFromBirth(parent, _args, _context, _info) {
|
||||||
if (!parent.dateOfBirth) return null;
|
if (!parent.dateOfBirth) return null;
|
||||||
|
|
||||||
|
|
|
@ -5,17 +5,29 @@ const { makeExtendSchemaPlugin, gql } = require('graphile-utils');
|
||||||
const schemaExtender = makeExtendSchemaPlugin(_build => ({
|
const schemaExtender = makeExtendSchemaPlugin(_build => ({
|
||||||
typeDefs: gql`
|
typeDefs: gql`
|
||||||
extend type Release {
|
extend type Release {
|
||||||
isStashed: Boolean @requires(columns: ["stashesScenesBySceneId"])
|
isFavorited: Boolean @requires(columns: ["stashesScenesBySceneId"])
|
||||||
|
isStashed(includeFavorites: Boolean = false): Boolean @requires(columns: ["stashesScenesBySceneId"])
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
resolvers: {
|
resolvers: {
|
||||||
Release: {
|
Release: {
|
||||||
isStashed(parent) {
|
isFavorited(parent) {
|
||||||
if (!parent['@stashes']) {
|
if (!parent['@stashes'] || typeof parent['@stashes'][0]['@stash'].primary === 'undefined') {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return parent['@stashes'].length > 0;
|
return parent['@stashes'].some(({ '@stash': stash }) => stash.primary);
|
||||||
|
},
|
||||||
|
isStashed(parent, args) {
|
||||||
|
if (!parent['@stashes'] || typeof parent['@stashes'][0]['@stash'].primary === 'undefined') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.includeFavorites) {
|
||||||
|
return parent['@stashes'].length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent['@stashes'].some(({ '@stash': stash }) => !stash.primary);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -45,6 +45,7 @@ const {
|
||||||
|
|
||||||
const {
|
const {
|
||||||
createStash,
|
createStash,
|
||||||
|
removeStash,
|
||||||
stashActor,
|
stashActor,
|
||||||
stashScene,
|
stashScene,
|
||||||
stashMovie,
|
stashMovie,
|
||||||
|
@ -87,6 +88,7 @@ async function initServer() {
|
||||||
|
|
||||||
router.post('/api/stashes', createStash);
|
router.post('/api/stashes', createStash);
|
||||||
router.patch('/api/stashes/:stashId', updateStash);
|
router.patch('/api/stashes/:stashId', updateStash);
|
||||||
|
router.delete('/api/stashes/:stashId', removeStash);
|
||||||
|
|
||||||
router.post('/api/stashes/:stashId/actors', stashActor);
|
router.post('/api/stashes/:stashId/actors', stashActor);
|
||||||
router.post('/api/stashes/:stashId/scenes', stashScene);
|
router.post('/api/stashes/:stashId/scenes', stashScene);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
const {
|
const {
|
||||||
createStash,
|
createStash,
|
||||||
|
removeStash,
|
||||||
stashActor,
|
stashActor,
|
||||||
stashScene,
|
stashScene,
|
||||||
stashMovie,
|
stashMovie,
|
||||||
|
@ -23,44 +24,51 @@ async function updateStashApi(req, res) {
|
||||||
res.send(stash);
|
res.send(stash);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stashActorApi(req, res) {
|
async function removeStashApi(req, res) {
|
||||||
await stashActor(req.body.actorId, req.params.stashId, req.session.user);
|
await removeStash(req.params.stashId, req.session.user);
|
||||||
|
|
||||||
res.status(201).send();
|
res.status(204).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function stashActorApi(req, res) {
|
||||||
|
const stashes = await stashActor(req.body.actorId, req.params.stashId, req.session.user);
|
||||||
|
|
||||||
|
res.send(stashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stashSceneApi(req, res) {
|
async function stashSceneApi(req, res) {
|
||||||
await stashScene(req.body.sceneId, req.params.stashId, req.session.user);
|
const stashes = await stashScene(req.body.sceneId, req.params.stashId, req.session.user);
|
||||||
|
|
||||||
res.status(201).send();
|
res.send(stashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function stashMovieApi(req, res) {
|
async function stashMovieApi(req, res) {
|
||||||
await stashMovie(req.body.movieId, req.params.stashId, req.session.user);
|
const stashes = await stashMovie(req.body.movieId, req.params.stashId, req.session.user);
|
||||||
|
|
||||||
res.status(201).send();
|
res.send(stashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unstashActorApi(req, res) {
|
async function unstashActorApi(req, res) {
|
||||||
await unstashActor(req.params.actorId, req.params.stashId, req.session.user);
|
const stashes = await unstashActor(req.params.actorId, req.params.stashId, req.session.user);
|
||||||
|
|
||||||
res.status(204).send();
|
res.send(stashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unstashSceneApi(req, res) {
|
async function unstashSceneApi(req, res) {
|
||||||
await unstashScene(req.params.sceneId, req.params.stashId, req.session.user);
|
const stashes = await unstashScene(req.params.sceneId, req.params.stashId, req.session.user);
|
||||||
|
|
||||||
res.status(204).send();
|
res.send(stashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function unstashMovieApi(req, res) {
|
async function unstashMovieApi(req, res) {
|
||||||
await unstashMovie(req.params.movieId, req.params.stashId, req.session.user);
|
const stashes = await unstashMovie(req.params.movieId, req.params.stashId, req.session.user);
|
||||||
|
|
||||||
res.status(204).send();
|
res.send(stashes);
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
createStash: createStashApi,
|
createStash: createStashApi,
|
||||||
|
removeStash: removeStashApi,
|
||||||
stashActor: stashActorApi,
|
stashActor: stashActorApi,
|
||||||
stashScene: stashSceneApi,
|
stashScene: stashSceneApi,
|
||||||
stashMovie: stashMovieApi,
|
stashMovie: stashMovieApi,
|
||||||
|
|
Loading…
Reference in New Issue