You've already forked AstralRinth
forked from didirus/AstralRinth
New collections (#1484)
* [WIP] Transfer collections to own branch * fixes * rewrite js * Add visibility dropdown to collection edit modal * Add visibility badges to collection page * Update visibility options and icons in collection page * Add delete functionality to collection modal * Collection project deletion flow * remove "visit project" button on overflow * Remove via checklist not individually * Update manage title in settings.vue * remove collections from settings page * hook up collections page * collection header to look like project header * Refactor layout.scss and collections.vue * fix omorphia * Update * Conform collections to old design structure * Update navigation links and remove unused code * Add collection view and collections to user page * Refactor user project display logic * Add collection creation functionality and update profile labels * Add function calls to initialize user collections * Refactor collection page layout and functionality * Add initialization of user collections in create function * Fix styling issue in collection page * Update collection status to private * remove name * Refactor card component and update grid layout * Finish collections --------- Co-authored-by: Carter <safe@fea.st>
This commit is contained in:
@@ -140,6 +140,7 @@
|
||||
<div class="markdown-body" v-html="renderString(licenseText)" />
|
||||
</div>
|
||||
</Modal>
|
||||
<CollectionCreateModal ref="modal_collection" :project-ids="[project.id]" />
|
||||
<div
|
||||
:class="{
|
||||
'normal-page': true,
|
||||
@@ -214,6 +215,7 @@
|
||||
/>
|
||||
</Categories>
|
||||
<hr class="card-divider" />
|
||||
|
||||
<div class="primary-stat">
|
||||
<DownloadIcon class="primary-stat__icon" aria-hidden="true" />
|
||||
<div class="primary-stat__text">
|
||||
@@ -223,6 +225,7 @@
|
||||
download<span v-if="project.downloads !== 1">s</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="primary-stat">
|
||||
<HeartIcon class="primary-stat__icon" aria-hidden="true" />
|
||||
<div class="primary-stat__text">
|
||||
@@ -262,13 +265,9 @@
|
||||
<hr class="card-divider" />
|
||||
<div class="input-group">
|
||||
<template v-if="auth.user">
|
||||
<button class="iconified-button" @click="() => reportProject(project.id)">
|
||||
<ReportIcon aria-hidden="true" />
|
||||
Report
|
||||
</button>
|
||||
<button
|
||||
v-if="!user.follows.find((x) => x.id === project.id)"
|
||||
class="iconified-button"
|
||||
class="btn"
|
||||
@click="userFollowProject(project)"
|
||||
>
|
||||
<HeartIcon aria-hidden="true" />
|
||||
@@ -276,12 +275,59 @@
|
||||
</button>
|
||||
<button
|
||||
v-if="user.follows.find((x) => x.id === project.id)"
|
||||
class="iconified-button"
|
||||
class="btn"
|
||||
@click="userUnfollowProject(project)"
|
||||
>
|
||||
<HeartIcon fill="currentColor" aria-hidden="true" />
|
||||
Unfollow
|
||||
</button>
|
||||
<PopoutMenu class="btn" direction="right" position="bottom" from="top-right">
|
||||
<BookmarkIcon aria-hidden="true" />
|
||||
Save
|
||||
<template #menu>
|
||||
<input
|
||||
v-model="displayCollectionsSearch"
|
||||
type="text"
|
||||
placeholder="Search collections..."
|
||||
class="search-input menu-search"
|
||||
/>
|
||||
<div v-if="collections.length > 0" class="collections-list">
|
||||
<Checkbox
|
||||
v-for="option in collections"
|
||||
:key="option.id"
|
||||
:model-value="option.projects.includes(project.id)"
|
||||
class="popout-checkbox"
|
||||
@update:model-value="userCollectProject(option, project.id)"
|
||||
>
|
||||
{{ option.name }}
|
||||
</Checkbox>
|
||||
</div>
|
||||
<div v-else class="menu-text">
|
||||
<p class="popout-text">No collections found.</p>
|
||||
</div>
|
||||
<button class="btn collection-button" @click="$refs.modal_collection.show()">
|
||||
<PlusIcon />
|
||||
Create new collection
|
||||
</button>
|
||||
</template>
|
||||
</PopoutMenu>
|
||||
<OverflowMenu
|
||||
class="btn icon-only"
|
||||
:options="[
|
||||
{
|
||||
id: 'report',
|
||||
action: () => reportProject(project.id),
|
||||
color: 'red',
|
||||
hoverOnly: true,
|
||||
},
|
||||
{ id: 'copy-id', action: () => copyId() },
|
||||
]"
|
||||
direction="right"
|
||||
>
|
||||
<MoreHorizontalIcon />
|
||||
<template #report> <ReportIcon /> Report</template>
|
||||
<template #copy-id> <ClipboardCopyIcon /> Copy ID</template>
|
||||
</OverflowMenu>
|
||||
</template>
|
||||
<template v-else>
|
||||
<nuxt-link class="iconified-button" to="/auth/sign-in">
|
||||
@@ -292,6 +338,24 @@
|
||||
<HeartIcon aria-hidden="true" />
|
||||
Follow
|
||||
</nuxt-link>
|
||||
|
||||
<OverflowMenu
|
||||
class="btn icon-only"
|
||||
:options="[
|
||||
{
|
||||
id: 'report',
|
||||
action: () => navigateTo('/auth/sign-in'),
|
||||
color: 'red',
|
||||
hoverOnly: true,
|
||||
},
|
||||
{ id: 'copy-id', action: () => copyId() },
|
||||
]"
|
||||
direction="right"
|
||||
>
|
||||
<MoreHorizontalIcon />
|
||||
<template #report> <ReportIcon /> Report</template>
|
||||
<template #copy-id> <ClipboardCopyIcon /> Copy ID</template>
|
||||
</OverflowMenu>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
@@ -668,7 +732,17 @@
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { Promotion, ChartIcon } from 'omorphia'
|
||||
import {
|
||||
Promotion,
|
||||
OverflowMenu,
|
||||
PopoutMenu,
|
||||
BookmarkIcon,
|
||||
MoreHorizontalIcon,
|
||||
ClipboardCopyIcon,
|
||||
PlusIcon,
|
||||
Checkbox,
|
||||
ChartIcon,
|
||||
} from 'omorphia'
|
||||
import CalendarIcon from '~/assets/images/utils/calendar.svg'
|
||||
import ClearIcon from '~/assets/images/utils/clear.svg'
|
||||
import DownloadIcon from '~/assets/images/utils/download.svg'
|
||||
@@ -711,6 +785,8 @@ import VersionIcon from '~/assets/images/utils/version.svg'
|
||||
import { renderString } from '~/helpers/parse.js'
|
||||
import { reportProject } from '~/utils/report-helpers.ts'
|
||||
import Breadcrumbs from '~/components/ui/Breadcrumbs.vue'
|
||||
import { userCollectProject } from '~/composables/user.js'
|
||||
import CollectionCreateModal from '~/components/ui/CollectionCreateModal.vue'
|
||||
|
||||
const data = useNuxtApp()
|
||||
const route = useRoute()
|
||||
@@ -721,6 +797,15 @@ const user = await useUser()
|
||||
const cosmetics = useCosmetics()
|
||||
const tags = useTags()
|
||||
|
||||
const displayCollectionsSearch = ref('')
|
||||
const collections = computed(() =>
|
||||
user.value && user.value.collections
|
||||
? user.value.collections.filter((x) =>
|
||||
x.name.toLowerCase().includes(displayCollectionsSearch.value.toLowerCase())
|
||||
)
|
||||
: []
|
||||
)
|
||||
|
||||
if (
|
||||
!route.params.id ||
|
||||
!(
|
||||
@@ -1132,7 +1217,6 @@ const collapsedChecklist = ref(false)
|
||||
}
|
||||
|
||||
.project__header {
|
||||
overflow: hidden;
|
||||
.project__gallery {
|
||||
display: none;
|
||||
}
|
||||
@@ -1141,11 +1225,12 @@ const collapsedChecklist = ref(false)
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 10rem;
|
||||
background-color: var(--color-button-bg-active);
|
||||
img {
|
||||
width: 100%;
|
||||
height: 10rem;
|
||||
object-fit: cover;
|
||||
background-color: var(--color-button-bg-active);
|
||||
border-radius: var(--size-rounded-card) var(--size-rounded-card) 0 0;
|
||||
}
|
||||
}
|
||||
.project__icon {
|
||||
@@ -1160,6 +1245,9 @@ const collapsedChecklist = ref(false)
|
||||
background: none;
|
||||
border-radius: unset;
|
||||
}
|
||||
.input-group {
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
.project-info {
|
||||
@@ -1367,4 +1455,44 @@ const collapsedChecklist = ref(false)
|
||||
.normal-page__sidebar .mod-button {
|
||||
margin-top: var(--spacing-card-sm);
|
||||
}
|
||||
|
||||
.popout-checkbox {
|
||||
padding: var(--gap-sm) var(--gap-md);
|
||||
white-space: nowrap;
|
||||
&:hover {
|
||||
filter: brightness(0.95);
|
||||
}
|
||||
}
|
||||
|
||||
.popout-heading {
|
||||
padding: var(--gap-sm) var(--gap-md);
|
||||
padding-bottom: 0;
|
||||
font-size: var(--font-size-nm);
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.collection-button {
|
||||
margin: var(--gap-sm) var(--gap-md);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.menu-text {
|
||||
padding: 0 var(--gap-md);
|
||||
font-size: var(--font-size-nm);
|
||||
color: var(--color-secondary);
|
||||
}
|
||||
|
||||
.menu-search {
|
||||
margin: var(--gap-sm) var(--gap-md);
|
||||
width: calc(100% - var(--gap-md) * 2);
|
||||
}
|
||||
|
||||
.collections-list {
|
||||
max-height: 40rem;
|
||||
overflow-y: auto;
|
||||
background-color: var(--color-bg);
|
||||
border-radius: var(--radius-md);
|
||||
margin: var(--gap-sm) var(--gap-md);
|
||||
padding: var(--gap-sm);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -288,10 +288,10 @@ import {
|
||||
ImageIcon,
|
||||
TransferIcon,
|
||||
ConfirmModal,
|
||||
Modal,
|
||||
FileInput,
|
||||
DropArea,
|
||||
} from 'omorphia'
|
||||
import Modal from '~/components/ui/Modal.vue'
|
||||
|
||||
const props = defineProps({
|
||||
project: {
|
||||
|
||||
Reference in New Issue
Block a user