Added functional stash button on scene tiles.

This commit is contained in:
2024-03-03 02:33:35 +01:00
parent 082d4fc154
commit f56e22230b
13 changed files with 657 additions and 73 deletions

View File

@@ -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);
}

View File

@@ -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;