201 lines
4.2 KiB
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>
|