Added functional stash button on scene tiles.
This commit is contained in:
@@ -78,6 +78,7 @@
|
||||
<VDropdown
|
||||
v-if="user"
|
||||
:triggers="['click']"
|
||||
:prevent-overflow="true"
|
||||
>
|
||||
<div class="userpanel">
|
||||
<img
|
||||
@@ -90,12 +91,22 @@
|
||||
<div class="menu">
|
||||
<a
|
||||
:href="`/user/${user.username}`"
|
||||
class="menu-header"
|
||||
class="menu-header ellipsis"
|
||||
>{{ user.username }}</a>
|
||||
|
||||
<ul class="menu-list nolist">
|
||||
<li class="menu-item">
|
||||
<a
|
||||
:href="`/user/${user.username}`"
|
||||
class="menu-button nolink"
|
||||
>
|
||||
<Icon icon="vcard" />
|
||||
View profile
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li
|
||||
class="menu-item logout"
|
||||
class="menu-button menu-item logout"
|
||||
@click="logout"
|
||||
><Icon icon="exit2" />Log out</li>
|
||||
</ul>
|
||||
@@ -201,9 +212,9 @@ async function logout() {
|
||||
height: 2rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: solid 1px var(--shadow-weak-20);
|
||||
border-radius: 1rem;
|
||||
background: var(--background);
|
||||
background: var(--background-dark-10);
|
||||
box-shadow: inset 0 0 3px var(--shadow-weak-40);
|
||||
|
||||
.input {
|
||||
padding: .5rem 0 .5rem 1rem;
|
||||
@@ -225,7 +236,10 @@ async function logout() {
|
||||
}
|
||||
|
||||
&.focused {
|
||||
/*
|
||||
border: solid 1px var(--primary-light-10);
|
||||
*/
|
||||
box-shadow: inset 0 0 3px var(--shadow-weak-30);
|
||||
|
||||
.icon {
|
||||
fill: var(--primary);
|
||||
@@ -258,25 +272,32 @@ async function logout() {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.menu {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.menu-header {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: .75rem 1rem;
|
||||
border-bottom: solid 1px var(--shadow-weak-30);
|
||||
color: var(--shadow-strong-30);
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.menu-item {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.menu-button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: .5rem;
|
||||
padding: .5rem .5rem .5rem .75rem;
|
||||
|
||||
.icon {
|
||||
fill: var(--shadow);
|
||||
margin-right: .5rem;
|
||||
margin-right: .75rem;
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -286,8 +307,6 @@ async function logout() {
|
||||
}
|
||||
|
||||
.logout {
|
||||
color: var(--error);
|
||||
|
||||
.icon {
|
||||
fill: var(--error);
|
||||
}
|
||||
|
||||
@@ -1,18 +1,34 @@
|
||||
<template>
|
||||
<div class="tile">
|
||||
<Link
|
||||
:href="`/scene/${scene.id}/${scene.slug}`"
|
||||
target="_blank"
|
||||
class="poster"
|
||||
>
|
||||
<img
|
||||
v-if="scene.poster"
|
||||
:src="scene.poster.isS3 ? `https://cdndev.traxxx.me/${scene.poster.thumbnail}` : `/media/${scene.poster.thumbnail}`"
|
||||
:style="{ 'background-image': scene.poster.isS3 ? `url(https://cdndev.traxxx.me/${scene.poster.lazy})` : `url(/media/${scene.poster.lazy})` }"
|
||||
loading="lazy"
|
||||
class="thumbnail"
|
||||
<div class="poster-container">
|
||||
<Link
|
||||
:href="`/scene/${scene.id}/${scene.slug}`"
|
||||
target="_blank"
|
||||
class="poster"
|
||||
>
|
||||
</Link>
|
||||
<img
|
||||
v-if="scene.poster"
|
||||
:src="scene.poster.isS3 ? `https://cdndev.traxxx.me/${scene.poster.thumbnail}` : `/media/${scene.poster.thumbnail}`"
|
||||
:style="{ 'background-image': scene.poster.isS3 ? `url(https://cdndev.traxxx.me/${scene.poster.lazy})` : `url(/media/${scene.poster.lazy})` }"
|
||||
loading="lazy"
|
||||
class="thumbnail"
|
||||
>
|
||||
</Link>
|
||||
|
||||
<Icon
|
||||
v-show="favorited"
|
||||
icon="heart7"
|
||||
class="heart favorited"
|
||||
@click.native.stop="unstash"
|
||||
/>
|
||||
|
||||
<Icon
|
||||
v-show="!favorited"
|
||||
icon="heart8"
|
||||
class="heart"
|
||||
@click.native.stop="stash"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="meta">
|
||||
<div class="channel">
|
||||
@@ -80,14 +96,42 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, inject } from 'vue';
|
||||
import { format } from 'date-fns';
|
||||
|
||||
defineProps({
|
||||
import { post, del } from '#/src/api.js';
|
||||
|
||||
import Icon from '../icon/icon.vue';
|
||||
|
||||
const props = defineProps({
|
||||
scene: {
|
||||
type: Object,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const pageContext = inject('pageContext');
|
||||
const user = pageContext.user;
|
||||
|
||||
const favorited = ref(props.scene.stashes.some((sceneStash) => sceneStash.primary));
|
||||
|
||||
async function stash() {
|
||||
try {
|
||||
favorited.value = true;
|
||||
await post(`/stashes/${user.primaryStash.id}/scenes`, { sceneId: props.scene.id });
|
||||
} catch (error) {
|
||||
favorited.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function unstash() {
|
||||
try {
|
||||
favorited.value = false;
|
||||
await del(`/stashes/${user.primaryStash.id}/scenes/${props.scene.id}`);
|
||||
} catch (error) {
|
||||
favorited.value = true;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@@ -100,9 +144,17 @@ defineProps({
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 0 3px var(--shadow-weak-20);
|
||||
|
||||
.heart {
|
||||
fill: var(--text-light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.poster-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.poster {
|
||||
display: block;
|
||||
height: 14rem;
|
||||
@@ -118,6 +170,26 @@ defineProps({
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.icon.heart {
|
||||
width: 2rem;
|
||||
height: 1.5rem;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: .5rem .5rem 1rem 1rem;
|
||||
fill: var(--highlight-strong-10);
|
||||
filter: drop-shadow(0 0 3px var(--shadow));
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
fill: var(--primary);
|
||||
}
|
||||
|
||||
&.favorited {
|
||||
fill: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.meta {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
Reference in New Issue
Block a user