Files
traxxx-web/components/stashes/stashes.vue

201 lines
4.2 KiB
Vue

<script setup>
import { computed, inject, ref } from 'vue';
import StashDialog from '#/components/stashes/create.vue';
import StashTile from '#/components/stashes/tile.vue';
import { get } from '#/src/api.js';
const pageContext = inject('pageContext');
const user = pageContext.user;
const stashes = ref(pageContext.pageProps.stashes);
const profile = ref(pageContext.pageProps.profile);
const showStashDialog = ref(false);
const showArchived = ref(false);
const sortings = ['used', 'name', 'size', 'created'];
const sorting = ref('size');
async function reloadStashes() {
// profile.value = await get(`/users/${profile.value.id}`);
stashes.value = await get(`/users/${profile.value.id}/stashes`);
}
const sortedStashes = computed(() => stashes.value
.toSorted((stashA, stashB) => {
return stashA.createdAt - stashB.createdAt;
})
.toSorted((stashA, stashB) => {
if (sorting.value === 'used') {
return stashB.lastStashAt - stashA.lastStashAt;
}
if (sorting.value === 'name') {
return stashA.name.localeCompare(stashB.name);
}
if (sorting.value === 'size') {
return (stashB.stashedScenes + stashB.stashedMovies + stashB.stashedActors)
- (stashA.stashedScenes + stashA.stashedMovies + stashA.stashedActors);
}
if (sorting.value === 'created') {
return stashA.createdAt - stashB.createdAt;
}
return 0;
})
.toSorted((stashA, stashB) => {
// always put favorites first
return stashB.isPrimary - stashA.isPrimary;
}));
const activeStashes = computed(() => sortedStashes.value.filter((stash) => !stash.isArchived));
const archivedStashes = computed(() => sortedStashes.value.filter((stash) => stash.isArchived));
function toggleSorting() {
sorting.value = sortings[(sortings.indexOf(sorting.value) + 1) % sortings.length];
}
</script>
<template>
<section class="profile-section">
<div class="section-header noselect">
<button
v-if="profile.id === user?.id"
class="button"
@click="showStashDialog = true"
>
<Icon icon="folder-plus2" />
<span class="button-label">New stash</span>
</button>
<Icon
v-if="sorting === 'used'"
v-tooltip="'By last stash'"
icon="sort-heart"
class="sort"
@click="toggleSorting"
/>
<Icon
v-if="sorting === 'name'"
v-tooltip="'By name'"
icon="sort-alpha-asc"
class="sort"
@click="toggleSorting"
/>
<Icon
v-if="sorting === 'size'"
v-tooltip="'By total stashed'"
icon="sort-amount-desc"
class="sort"
@click="toggleSorting"
/>
<Icon
v-if="sorting === 'created'"
v-tooltip="'By stash age'"
icon="sort-time-asc"
class="sort"
@click="toggleSorting"
/>
</div>
<StashDialog
v-if="showStashDialog"
@created="showStashDialog = false; reloadStashes();"
@close="showStashDialog = false"
/>
<ul class="stashes nolist">
<li
v-for="stash in activeStashes"
:key="`stash-${stash.id}`"
>
<StashTile
:stash="stash"
:profile="profile"
@reload="reloadStashes"
/>
</li>
</ul>
<h3
v-if="archivedStashes.length > 0"
class="archived-heading"
@click="showArchived = !showArchived"
><Icon icon="drawer3" />{{ showArchived ? 'Hide' : `Show ${archivedStashes.length}` }} archived {{ archivedStashes.length > 1 ? 'stashes' : 'stash' }}</h3>
<ul
v-if="showArchived"
class="stashes nolist"
>
<li
v-for="stash in archivedStashes"
:key="`stash-${stash.id}`"
>
<StashTile
:stash="stash"
:profile="profile"
@reload="reloadStashes"
/>
</li>
</ul>
</section>
</template>
<style scoped>
.profile-section .section-header {
display: flex;
justify-content: center;
margin-bottom: .5rem;
gap: 1rem;
}
.stashes {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(13rem, 1fr));
gap: .5rem;
padding: 0 0 1rem 0;
}
.sort {
padding: .5rem 1rem;
fill: var(--glass);
&:hover {
fill: var(--primary);
cursor: pointer;
}
}
.archived-heading {
display: flex;
align-items: center;
font-size: 1rem;
color: var(--glass);
cursor: pointer;
.icon {
fill: var(--glass);
margin-right: .75rem;
transform: translateY(-1px);
}
}
@media(--compact) {
.stashes {
padding: 0 1rem 1rem 1rem;
}
}
@media(--small-20) {
.stashes {
padding: 0 .5rem 1rem .5rem;
}
}
</style>