Skip to content

Commit 78c52e9

Browse files
committed
Add flag for new projects list on user page, update background gradient colors
1 parent 3b5c219 commit 78c52e9

File tree

3 files changed

+156
-139
lines changed

3 files changed

+156
-139
lines changed

apps/frontend/src/composables/featureFlags.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ export const DEFAULT_FEATURE_FLAGS = validateValues({
3030
newProjectCards: false,
3131
projectBackground: false,
3232
searchBackground: false,
33+
newProjectListUserPage: false,
34+
projectCardBackground: false,
3335
// advancedRendering: true,
3436
// externalLinksNewTab: true,
3537
// notUsingBlockers: false,

apps/frontend/src/pages/user/[id].vue

Lines changed: 150 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -121,154 +121,161 @@
121121
</UserHeader>
122122
</div>
123123
<div class="normal-page__content">
124-
<div v-if="navLinks.length >= 2" class="mb-4 max-w-full overflow-x-auto">
125-
<NavTabs :links="navLinks" />
126-
</div>
127-
<div v-if="projects.length > 0">
128-
<ProjectsList :projects="projects" :project-link="(project) => `/project/${project.id}`">
129-
<template #project-actions>
130-
<ButtonStyled color="brand">
131-
<button><DownloadIcon /> Install</button>
132-
</ButtonStyled>
133-
<ButtonStyled circular>
134-
<button v-tooltip="'Follow'">
135-
<HeartIcon />
136-
</button>
137-
</ButtonStyled>
138-
<ButtonStyled circular>
139-
<button v-tooltip="'Save'">
140-
<BookmarkIcon />
141-
</button>
142-
</ButtonStyled>
143-
<ButtonStyled circular type="transparent">
144-
<button>
145-
<MoreVerticalIcon />
146-
</button>
147-
</ButtonStyled>
148-
</template>
149-
</ProjectsList>
150-
151-
<div
152-
v-if="route.params.projectType !== 'collections'"
153-
:class="'project-list display-mode--' + cosmetics.searchDisplayMode.user"
154-
>
155-
<ProjectCard
156-
v-for="project in (route.params.projectType !== undefined
157-
? projects.filter(
158-
(x) =>
159-
x.project_type ===
160-
route.params.projectType.substr(0, route.params.projectType.length - 1),
161-
)
162-
: projects
163-
)
164-
.slice()
165-
.sort((a, b) => b.downloads - a.downloads)"
166-
:id="project.slug || project.id"
167-
:key="project.id"
168-
:name="project.title"
169-
:display="cosmetics.searchDisplayMode.user"
170-
:featured-image="project.gallery.find((element) => element.featured)?.url"
171-
:description="project.description"
172-
:created-at="project.published"
173-
:updated-at="project.updated"
174-
:downloads="project.downloads.toString()"
175-
:follows="project.followers.toString()"
176-
:icon-url="project.icon_url"
177-
:categories="project.categories"
178-
:client-side="project.client_side"
179-
:server-side="project.server_side"
180-
:status="
181-
auth.user && (auth.user.id === user.id || tags.staffRoles.includes(auth.user.role))
182-
? project.status
183-
: null
184-
"
185-
:type="project.project_type"
186-
:color="project.color"
187-
/>
124+
<ProjectsList
125+
v-if="flags.newProjectListUserPage"
126+
:projects="projects.filter((x) => x.status === 'approved' || x.status === 'archived')"
127+
:project-link="(project) => `/project/${project.id}`"
128+
:experimental-colors="flags.projectCardBackground"
129+
>
130+
<template #project-actions>
131+
<ButtonStyled color="brand">
132+
<button><DownloadIcon /> Install</button>
133+
</ButtonStyled>
134+
<ButtonStyled circular>
135+
<button v-tooltip="'Follow'">
136+
<HeartIcon />
137+
</button>
138+
</ButtonStyled>
139+
<ButtonStyled circular>
140+
<button v-tooltip="'Save'">
141+
<BookmarkIcon />
142+
</button>
143+
</ButtonStyled>
144+
<ButtonStyled circular type="transparent">
145+
<button>
146+
<MoreVerticalIcon />
147+
</button>
148+
</ButtonStyled>
149+
</template>
150+
</ProjectsList>
151+
<template v-else>
152+
<div v-if="navLinks.length >= 2" class="mb-4 max-w-full overflow-x-auto">
153+
<NavTabs :links="navLinks" />
188154
</div>
189-
</div>
190-
<div v-else-if="route.params.projectType !== 'collections'" class="error">
191-
<UpToDate class="icon" /><br />
192-
<span v-if="auth.user && auth.user.id === user.id" class="preserve-lines text">
193-
<IntlFormatted :message-id="messages.profileNoProjectsAuthLabel">
194-
<template #create-link="{ children }">
195-
<a class="link" @click.prevent="$refs.modal_creation.show()">
196-
<component :is="() => children" />
197-
</a>
198-
</template>
199-
</IntlFormatted>
200-
</span>
201-
<span v-else class="text">{{ formatMessage(messages.profileNoProjectsLabel) }}</span>
202-
</div>
203-
<div v-if="['collections'].includes(route.params.projectType)" class="collections-grid">
204-
<nuxt-link
205-
v-for="collection in collections.sort(
155+
<div v-if="projects.length > 0">
156+
<div
157+
v-if="route.params.projectType !== 'collections'"
158+
:class="'project-list display-mode--' + cosmetics.searchDisplayMode.user"
159+
>
160+
<ProjectCard
161+
v-for="project in (route.params.projectType !== undefined
162+
? projects.filter(
163+
(x) =>
164+
x.project_type ===
165+
route.params.projectType.substr(0, route.params.projectType.length - 1),
166+
)
167+
: projects
168+
)
169+
.slice()
170+
.sort((a, b) => b.downloads - a.downloads)"
171+
:id="project.slug || project.id"
172+
:key="project.id"
173+
:name="project.title"
174+
:display="cosmetics.searchDisplayMode.user"
175+
:featured-image="project.gallery.find((element) => element.featured)?.url"
176+
:description="project.description"
177+
:created-at="project.published"
178+
:updated-at="project.updated"
179+
:downloads="project.downloads.toString()"
180+
:follows="project.followers.toString()"
181+
:icon-url="project.icon_url"
182+
:categories="project.categories"
183+
:client-side="project.client_side"
184+
:server-side="project.server_side"
185+
:status="
186+
auth.user &&
187+
(auth.user.id === user.id || tags.staffRoles.includes(auth.user.role))
188+
? project.status
189+
: null
190+
"
191+
:type="project.project_type"
192+
:color="project.color"
193+
/>
194+
</div>
195+
</div>
196+
<div v-else-if="route.params.projectType !== 'collections'" class="error">
197+
<UpToDate class="icon" /><br />
198+
<span v-if="auth.user && auth.user.id === user.id" class="preserve-lines text">
199+
<IntlFormatted :message-id="messages.profileNoProjectsAuthLabel">
200+
<template #create-link="{ children }">
201+
<a class="link" @click.prevent="$refs.modal_creation.show()">
202+
<component :is="() => children" />
203+
</a>
204+
</template>
205+
</IntlFormatted>
206+
</span>
207+
<span v-else class="text">{{ formatMessage(messages.profileNoProjectsLabel) }}</span>
208+
</div>
209+
<div v-if="['collections'].includes(route.params.projectType)" class="collections-grid">
210+
<nuxt-link
211+
v-for="collection in collections.sort(
206212
(a, b) => new Date(b.created) - new Date(a.created),
207213
)"
208-
:key="collection.id"
209-
:to="`/collection/${collection.id}`"
210-
class="card collection-item"
211-
>
212-
<div class="collection">
213-
<Avatar :src="collection.icon_url" class="icon" />
214-
<div class="details">
215-
<h2 class="title">{{ collection.name }}</h2>
216-
<div class="stats">
217-
<LibraryIcon aria-hidden="true" />
218-
Collection
214+
:key="collection.id"
215+
:to="`/collection/${collection.id}`"
216+
class="card collection-item"
217+
>
218+
<div class="collection">
219+
<Avatar :src="collection.icon_url" class="icon" />
220+
<div class="details">
221+
<h2 class="title">{{ collection.name }}</h2>
222+
<div class="stats">
223+
<LibraryIcon aria-hidden="true" />
224+
Collection
225+
</div>
219226
</div>
220227
</div>
221-
</div>
222-
<div class="description">
223-
{{ collection.description }}
224-
</div>
225-
<div class="stat-bar">
226-
<div class="stats">
228+
<div class="description">
229+
{{ collection.description }}
230+
</div>
231+
<div class="stat-bar">
232+
<div class="stats">
227233
<BoxIcon />
228234
{{
229235
`${$formatNumber(collection.projects?.length || 0, false)} project${(collection.projects?.length || 0) !== 1 ? "s" : ""}`
230236
}}
231237
</div>
232-
<div class="stats">
233-
<template v-if="collection.status === 'listed'">
234-
<WorldIcon />
235-
<span> Public </span>
236-
</template>
237-
<template v-else-if="collection.status === 'unlisted'">
238-
<LinkIcon />
239-
<span> Unlisted </span>
240-
</template>
241-
<template v-else-if="collection.status === 'private'">
242-
<LockIcon />
243-
<span> Private </span>
244-
</template>
245-
<template v-else-if="collection.status === 'rejected'">
246-
<XIcon />
247-
<span> Rejected </span>
248-
</template>
238+
<div class="stats">
239+
<template v-if="collection.status === 'listed'">
240+
<WorldIcon />
241+
<span> Public </span>
242+
</template>
243+
<template v-else-if="collection.status === 'unlisted'">
244+
<LinkIcon />
245+
<span> Unlisted </span>
246+
</template>
247+
<template v-else-if="collection.status === 'private'">
248+
<LockIcon />
249+
<span> Private </span>
250+
</template>
251+
<template v-else-if="collection.status === 'rejected'">
252+
<XIcon />
253+
<span> Rejected </span>
254+
</template>
255+
</div>
249256
</div>
250-
</div>
251-
</nuxt-link>
252-
</div>
253-
<div
254-
v-if="route.params.projectType === 'collections' && collections.length === 0"
255-
class="error"
256-
>
257-
<UpToDate class="icon" /><br />
258-
<span v-if="auth.user && auth.user.id === user.id" class="preserve-lines text">
259-
<IntlFormatted :message-id="messages.profileNoCollectionsAuthLabel">
260-
<template #create-link="{ children }">
261-
<a
262-
class="link"
263-
@click.prevent="(event) => $refs.modal_collection_creation.show(event)"
264-
>
265-
<component :is="() => children" />
266-
</a>
267-
</template>
268-
</IntlFormatted>
269-
</span>
270-
<span v-else class="text">{{ formatMessage(messages.profileNoCollectionsLabel) }}</span>
271-
</div>
257+
</nuxt-link>
258+
</div>
259+
<div
260+
v-if="route.params.projectType === 'collections' && collections.length === 0"
261+
class="error"
262+
>
263+
<UpToDate class="icon" /><br />
264+
<span v-if="auth.user && auth.user.id === user.id" class="preserve-lines text">
265+
<IntlFormatted :message-id="messages.profileNoCollectionsAuthLabel">
266+
<template #create-link="{ children }">
267+
<a
268+
class="link"
269+
@click.prevent="(event) => $refs.modal_collection_creation.show(event)"
270+
>
271+
<component :is="() => children" />
272+
</a>
273+
</template>
274+
</IntlFormatted>
275+
</span>
276+
<span v-else class="text">{{ formatMessage(messages.profileNoCollectionsLabel) }}</span>
277+
</div>
278+
</template>
272279
</div>
273280
<div class="normal-page__sidebar">
274281
<UserSidebarOrganizations
@@ -281,6 +288,11 @@
281288
:download-count="sumDownloads"
282289
class="card flex-card experimental-styles-within"
283290
/>
291+
<UserSidebarCollections
292+
:collections="collections.filter((x) => x.status === 'listed')"
293+
:link="(collection) => `/collection/${collection.id}`"
294+
class="card flex-card experimental-styles-within"
295+
/>
284296
<AdPlaceholder
285297
v-if="!auth.user || !isPermission(auth.user.badges, 1 << 0) || flags.showAdsWithPlus"
286298
/>
@@ -313,6 +325,7 @@ import {
313325
UserSidebarBadges,
314326
UserSidebarOrganizations,
315327
ProjectsList,
328+
UserSidebarCollections,
316329
} from "@modrinth/ui";
317330
import { isStaff } from "~/helpers/users.js";
318331
import NavTabs from "~/components/ui/NavTabs.vue";

packages/ui/src/components/project/ProjectBackgroundGradient.vue

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<template>
2-
<div :style="{ '--_accent-color': rgbToOklchHue(props.project.color) }" />
2+
<div :style="{ '--_accent-color': color }" />
33
</template>
44
<script setup lang="ts">
55
import { computed } from 'vue'
@@ -15,12 +15,14 @@ const props = withDefaults(
1515
{},
1616
)
1717
18+
const color = computed(() => rgbToOklchHue(props.project.color))
19+
1820
</script>
1921
<style scoped lang="scss">
2022
div {
2123
width: 100%;
2224
height: 60rem;
23-
background: linear-gradient(to bottom, oklch(40% 10% var(--_accent-color) / 25%), transparent);
25+
background: linear-gradient(to bottom, oklch(40% 30% var(--_accent-color) / 10%), transparent);
2426
opacity: 1;
2527
}
2628
</style>

0 commit comments

Comments
 (0)