Added stashes with experimental row security policies. Added tag photos.

This commit is contained in:
DebaucheryLibrarian
2021-03-14 04:54:43 +01:00
parent 816529b0ca
commit e371e9725a
58 changed files with 610 additions and 172 deletions

View File

@@ -49,7 +49,7 @@ async function login() {
this.success = false;
try {
await this.$store.dispatch('login', {
const user = await this.$store.dispatch('login', {
username: this.username,
password: this.password,
});
@@ -57,7 +57,7 @@ async function login() {
this.success = true;
setTimeout(() => {
this.$router.replace(this.$route.query.ref || { name: 'home' });
this.$router.replace(this.$route.query.ref || { name: 'user', params: { username: user.username } });
}, 1000);
} catch (error) {
this.error = error.message;

View File

@@ -93,82 +93,7 @@
</div>
<template v-slot:tooltip>
<div class="menu">
<ul class="menu-items noselect">
<router-link
v-if="!me"
to="/login"
class="menu-item"
@click.stop
>
<Icon icon="enter2" />Log in
</router-link>
<li
v-if="me"
class="menu-username"
>{{ me.username }}</li>
<li
v-if="me"
class="menu-item"
@click.stop="$store.dispatch('logout')"
>
<Icon icon="enter2" />Log out
</li>
<li
v-show="!sfw"
class="menu-item"
@click.stop="setSfw(true)"
>
<Icon
icon="flower"
class="toggle noselect"
/>Safe mode
</li>
<li
v-show="sfw"
class="menu-item"
@click.stop="setSfw(false)"
>
<Icon
icon="fire"
class="toggle noselect"
/>Filth mode
</li>
<li
v-show="theme === 'light'"
class="menu-item"
@click.stop="setTheme('dark')"
>
<Icon
icon="moon"
class="toggle noselect"
/>Dark theme
</li>
<li
v-show="theme === 'dark'"
class="menu-item"
@click.stop="setTheme('light')"
>
<Icon
icon="sun"
class="toggle noselect"
/>Light theme
</li>
<li
class="menu-item"
@click="$emit('showFilters', true)"
>
<Icon icon="filter" />Filters
</li>
</ul>
</div>
<Menu />
</template>
</Tooltip>
@@ -201,34 +126,14 @@
</template>
<script>
import { mapState } from 'vuex';
import Menu from './menu.vue';
import Search from './search.vue';
import logo from '../../img/logo.svg';
function sfw(state) {
return state.ui.sfw;
}
function theme(state) {
return state.ui.theme;
}
function me(state) {
return state.auth.user;
}
function setTheme(newTheme) {
this.$store.dispatch('setTheme', newTheme);
}
function setSfw(enabled) {
this.$store.dispatch('setSfw', enabled);
}
export default {
components: {
Menu,
Search,
},
emits: ['toggleSidebar', 'showFilters'],
@@ -239,17 +144,6 @@ export default {
showFilters: false,
};
},
computed: {
...mapState({
sfw,
theme,
me,
}),
},
methods: {
setSfw,
setTheme,
},
};
</script>
@@ -414,51 +308,6 @@ export default {
}
}
.menu-items {
list-style: none;
padding: 0;
margin: 0;
}
.menu-item {
display: flex;
padding: .75rem 1rem .75rem .75rem;
color: inherit;
text-decoration: none;
.icon {
fill: var(--darken);
margin: 0 1rem 0 0;
}
&.disabled {
color: var(--darken-weak);
cursor: default;
.icon {
fill: var(--darken-weak);
}
}
&:hover:not(.disabled) {
cursor: pointer;
color: var(--primary);
.icon {
fill: var(--primary);
}
}
}
.menu-username {
font-weight: bold;
color: var(--shadow-strong);
font-size: .9rem;
padding: .75rem 1rem;
border-bottom: solid 1px var(--shadow-hint);
text-align: center;
}
.search-compact {
display: none;
height: 100%;

View File

@@ -0,0 +1,168 @@
<template>
<div class="menu">
<ul class="menu-items noselect">
<router-link
v-if="me"
:to="{ name: 'user', params: { username: me.username } }"
class="menu-username"
>{{ me.username }}</router-link>
<router-link
v-else
to="/login"
class="menu-item"
@click.stop
>
<Icon icon="enter2" />Log in
</router-link>
<li
v-if="me"
class="menu-item"
@click.stop="$store.dispatch('logout')"
>
<Icon icon="enter2" />Log out
</li>
<li
v-show="!sfw"
class="menu-item"
@click.stop="setSfw(true)"
>
<Icon
icon="flower"
class="toggle noselect"
/>Safe mode
</li>
<li
v-show="sfw"
class="menu-item"
@click.stop="setSfw(false)"
>
<Icon
icon="fire"
class="toggle noselect"
/>Filth mode
</li>
<li
v-show="theme === 'light'"
class="menu-item"
@click.stop="setTheme('dark')"
>
<Icon
icon="moon"
class="toggle noselect"
/>Dark theme
</li>
<li
v-show="theme === 'dark'"
class="menu-item"
@click.stop="setTheme('light')"
>
<Icon
icon="sun"
class="toggle noselect"
/>Light theme
</li>
<li
class="menu-item"
@click="$emit('showFilters', true)"
>
<Icon icon="filter" />Filters
</li>
</ul>
</div>
</template>
<script>
import { mapState } from 'vuex';
function sfw(state) {
return state.ui.sfw;
}
function theme(state) {
return state.ui.theme;
}
function me(state) {
return state.auth.user;
}
function setTheme(newTheme) {
this.$store.dispatch('setTheme', newTheme);
}
function setSfw(enabled) {
this.$store.dispatch('setSfw', enabled);
}
export default {
computed: {
...mapState({
sfw,
theme,
me,
}),
},
methods: {
setSfw,
setTheme,
},
};
</script>
<style lang="scss" scoped>
@import 'breakpoints';
.menu-items {
list-style: none;
padding: 0;
margin: 0;
}
.menu-item {
display: flex;
padding: .75rem 1rem .75rem .75rem;
color: inherit;
text-decoration: none;
.icon {
fill: var(--darken);
margin: 0 1rem 0 0;
}
&.disabled {
color: var(--darken-weak);
cursor: default;
.icon {
fill: var(--darken-weak);
}
}
&:hover:not(.disabled) {
cursor: pointer;
color: var(--primary);
.icon {
fill: var(--primary);
}
}
}
.menu-username {
display: block;
font-weight: bold;
color: var(--shadow-strong);
font-size: .9rem;
padding: .75rem 1rem;
border-bottom: solid 1px var(--shadow-hint);
text-align: center;
text-decoration: none;
}
</style>

View File

@@ -73,7 +73,10 @@
>{{ release.entity.name }}</h3>
</a>
<span class="row">
<span
v-if="release.actors?.length > 0"
class="row"
>
<ul
class="actors nolist"
:title="release.actors.map(actor => actor.name).join(', ')"
@@ -106,7 +109,7 @@
>{{ release.shootId }}</span>
<ul
v-if="release.tags.length > 0"
v-if="release.tags?.length > 0"
:title="release.tags.map(tag => tag.name).join(', ')"
class="tags nolist"
>

View File

@@ -4,7 +4,7 @@
:class="{ new: release.isNew }"
>
<span
v-if="release.entity.type !== 'network' && !release.entity.independent && release.entity.parent"
v-if="release.entity && release.entity.type !== 'network' && !release.entity.independent && release.entity.parent"
class="site"
>
<router-link
@@ -33,7 +33,7 @@
</span>
<router-link
v-else
v-else-if="release.entity"
:to="`/${release.entity.type}/${release.entity.slug}`"
class="site site-link"
>

View File

@@ -0,0 +1,113 @@
<template>
<div
v-if="user"
class="user"
>
<div class="header">
<h2 class="username">{{ user.username }}</h2>
</div>
<section
v-if="stashes.length > 0"
class="section"
>
<h3 class="heading">Stashes</h3>
<ul class="stashes nolist">
<li
v-for="stash in stashes"
:key="stash.id"
>
<h4 class="stash-name">{{ stash.name }}</h4>
<ul class="stash nolist actors">
<li
v-for="item in stash.actors"
:key="item.id"
><Actor :actor="item.actor" /></li>
</ul>
<ul class="stash nolist scenes">
<li
v-for="item in stash.scenes"
:key="item.id"
><Scene :release="item.scene" /></li>
</ul>
</li>
</ul>
</section>
</div>
</template>
<script>
import Actor from '../actors/tile.vue';
import Scene from '../releases/scene-tile.vue';
async function mounted() {
this.user = await this.$store.dispatch('fetchMe');
this.stashes = await this.$store.dispatch('fetchUserStashes', this.user.id);
}
export default {
components: {
Actor,
Scene,
},
data() {
return {
user: this.$route.params.username === this.$store.state.auth.user?.username
? this.$store.state.auth.user
: null,
stashes: [],
};
},
mounted,
};
</script>
<style lang="scss" scoped>
.header {
padding: 1rem;
background: var(--profile);
}
.username {
margin: 0;
font-size: 1.5rem;
color: var(--text-light);
}
.section {
padding: 1rem;
margin: 0 0 1rem 0;
}
.heading {
color: var(--primary);
}
.stash {
margin: 0 0 1rem 0;
}
.stash-name {
color: var(--shadow-strong);
margin: 0 0 1rem 0;
}
.actors {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(10rem, 1fr));
grid-gap: .5rem;
flex-grow: 1;
flex-wrap: wrap;
}
.scenes {
width: 100%;
display: grid;
grid-template-columns: repeat(auto-fill, minmax(22rem, 1fr));
grid-gap: .5rem;
box-sizing: border-box;
}
</style>