Fix lint checks
This commit is contained in:
parent
d37c634216
commit
61c2ce2107
@ -1,7 +1,14 @@
|
||||
<script setup>
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { SpinnerIcon, GameIcon, TimerIcon, StopCircleIcon, PlayIcon, DownloadIcon } from '@modrinth/assets'
|
||||
import {
|
||||
SpinnerIcon,
|
||||
GameIcon,
|
||||
TimerIcon,
|
||||
StopCircleIcon,
|
||||
PlayIcon,
|
||||
DownloadIcon,
|
||||
} from '@modrinth/assets'
|
||||
import { ButtonStyled, Avatar, SmartClickable } from '@modrinth/ui'
|
||||
import { convertFileSrc } from '@tauri-apps/api/core'
|
||||
import { finish_install, kill, run } from '@/helpers/profile'
|
||||
@ -129,19 +136,21 @@ onUnmounted(() => unlisten())
|
||||
<template>
|
||||
<SmartClickable class="card-shadow bg-bg-raised rounded-xl" @mouseenter="checkProcess">
|
||||
<template #clickable>
|
||||
<router-link class="no-click-animation" :to="`/instance/${encodeURIComponent(instance.path)}/`" />
|
||||
<router-link
|
||||
class="no-click-animation"
|
||||
:to="`/instance/${encodeURIComponent(instance.path)}/`"
|
||||
/>
|
||||
</template>
|
||||
<div
|
||||
v-if="compact"
|
||||
class="grid grid-cols-[auto_1fr_auto] p-3 pl-4 gap-2"
|
||||
>
|
||||
<div v-if="compact" class="grid grid-cols-[auto_1fr_auto] p-3 pl-4 gap-2">
|
||||
<Avatar
|
||||
size="48px"
|
||||
:src="instance.icon_path ? convertFileSrc(instance.icon_path) : null"
|
||||
:tint-by="instance.path"
|
||||
alt="Mod card"
|
||||
/>
|
||||
<div class="h-full flex items-center font-bold text-contrast leading-normal smart-clickable:underline-on-hover">
|
||||
<div
|
||||
class="h-full flex items-center font-bold text-contrast leading-normal smart-clickable:underline-on-hover"
|
||||
>
|
||||
<span class="line-clamp-2">{{ instance.name }}</span>
|
||||
</div>
|
||||
<div class="flex items-center smart-clickable:allow-pointer-events">
|
||||
@ -171,11 +180,7 @@ onUnmounted(() => unlisten())
|
||||
<span class="text-sm"> Played {{ dayjs(instance.last_played).fromNow() }} </span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
v-else
|
||||
class="p-4 rounded-xl flex gap-3 group"
|
||||
@mouseenter="checkProcess"
|
||||
>
|
||||
<div v-else class="p-4 rounded-xl flex gap-3 group" @mouseenter="checkProcess">
|
||||
<div class="relative flex items-center justify-center">
|
||||
<Avatar
|
||||
size="48px"
|
||||
@ -224,7 +229,9 @@ onUnmounted(() => unlisten())
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-1">
|
||||
<p class="m-0 text-md font-bold text-contrast leading-tight line-clamp-1 smart-clickable:underline-on-hover">
|
||||
<p
|
||||
class="m-0 text-md font-bold text-contrast leading-tight line-clamp-1 smart-clickable:underline-on-hover"
|
||||
>
|
||||
{{ instance.name }}
|
||||
</p>
|
||||
<div class="flex items-center col-span-3 gap-1 text-secondary font-semibold mt-auto">
|
||||
|
||||
@ -11,7 +11,10 @@ defineProps<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="instance" class="flex justify-between items-center border-0 border-b border-solid border-divider pb-4">
|
||||
<div
|
||||
v-if="instance"
|
||||
class="flex justify-between items-center border-0 border-b border-solid border-divider pb-4"
|
||||
>
|
||||
<router-link
|
||||
:to="`/instance/${encodeURIComponent(instance.path)}`"
|
||||
tabindex="-1"
|
||||
|
||||
@ -5,7 +5,6 @@ import { formatNumber, formatCategory } from '@modrinth/utils'
|
||||
import { computed } from 'vue'
|
||||
import dayjs from 'dayjs'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
dayjs.extend(relativeTime)
|
||||
|
||||
@ -45,10 +44,7 @@ const toColor = computed(() => {
|
||||
class="card-shadow bg-bg-raised rounded-xl overflow-clip cursor-pointer hover:brightness-90 transition-all"
|
||||
>
|
||||
<template #clickable>
|
||||
<router-link
|
||||
class="no-click-animation"
|
||||
:to="`/project/${project.slug}`"
|
||||
/>
|
||||
<router-link class="no-click-animation" :to="`/project/${project.slug}`" />
|
||||
</template>
|
||||
<div
|
||||
class="w-full aspect-[2/1] bg-cover bg-center bg-no-repeat"
|
||||
@ -60,12 +56,13 @@ const toColor = computed(() => {
|
||||
'https://launcher-files.modrinth.com/assets/maze-bg.png'
|
||||
})`,
|
||||
}"
|
||||
>
|
||||
</div>
|
||||
></div>
|
||||
<div class="flex flex-col justify-center gap-2 px-4 py-3">
|
||||
<div class="flex gap-2 items-center">
|
||||
<Avatar size="48px" :src="project.icon_url" />
|
||||
<div class="h-full flex items-center font-bold text-contrast leading-normal smart-clickable:underline-on-hover">
|
||||
<div
|
||||
class="h-full flex items-center font-bold text-contrast leading-normal smart-clickable:underline-on-hover"
|
||||
>
|
||||
<span class="line-clamp-2">{{ project.title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -34,8 +34,9 @@ const installed: Ref<boolean> = ref(false)
|
||||
|
||||
function checkInstallStatus() {
|
||||
if (props.instanceContent) {
|
||||
installed.value = Object.values(props.instanceContent)
|
||||
.some((content) => content.metadata?.project_id === projectId.value)
|
||||
installed.value = Object.values(props.instanceContent).some(
|
||||
(content) => content.metadata?.project_id === projectId.value,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,14 +11,16 @@
|
||||
)
|
||||
"
|
||||
:experimental-colors="themeStore.featureFlags.project_card_background"
|
||||
:creator-link=" creator ?
|
||||
asLink(
|
||||
{
|
||||
path: `/user/${creator}`,
|
||||
query: { i: props.instance ? props.instance.path : undefined },
|
||||
},
|
||||
() => emit('open'),
|
||||
) : undefined
|
||||
:creator-link="
|
||||
creator
|
||||
? asLink(
|
||||
{
|
||||
path: `/user/${creator}`,
|
||||
query: { i: props.instance ? props.instance.path : undefined },
|
||||
},
|
||||
() => emit('open'),
|
||||
)
|
||||
: undefined
|
||||
"
|
||||
>
|
||||
<template #actions>
|
||||
@ -42,12 +44,8 @@
|
||||
<script setup lang="ts">
|
||||
import { DownloadIcon, CheckIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, NewProjectCard, asLink } from '@modrinth/ui'
|
||||
import type {
|
||||
Project,
|
||||
SearchResult} from '@modrinth/utils';
|
||||
import {
|
||||
isSearchResult
|
||||
} from '@modrinth/utils'
|
||||
import type { Project, SearchResult } from '@modrinth/utils'
|
||||
import { isSearchResult } from '@modrinth/utils'
|
||||
import dayjs from 'dayjs'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
import { ref, computed } from 'vue'
|
||||
@ -58,14 +56,17 @@ dayjs.extend(relativeTime)
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
project: Project | SearchResult
|
||||
instance?: GameInstance
|
||||
installed?: boolean
|
||||
}>(), {
|
||||
instance: undefined,
|
||||
installed: false,
|
||||
})
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
project: Project | SearchResult
|
||||
instance?: GameInstance
|
||||
installed?: boolean
|
||||
}>(),
|
||||
{
|
||||
instance: undefined,
|
||||
installed: false,
|
||||
},
|
||||
)
|
||||
|
||||
const emit = defineEmits(['open', 'install'])
|
||||
|
||||
@ -85,6 +86,8 @@ async function install() {
|
||||
)
|
||||
}
|
||||
|
||||
const projectId = computed(() => isSearchResult(props.project) ? props.project.project_id : props.project.id)
|
||||
const creator = computed(() => isSearchResult(props.project) ? props.project.author : undefined)
|
||||
const projectId = computed(() =>
|
||||
isSearchResult(props.project) ? props.project.project_id : props.project.id,
|
||||
)
|
||||
const creator = computed(() => (isSearchResult(props.project) ? props.project.author : undefined))
|
||||
</script>
|
||||
|
||||
@ -30,31 +30,37 @@ watch(
|
||||
)
|
||||
</script>
|
||||
<template>
|
||||
<h2 class="m-0 text-lg font-extrabold text-contrast">
|
||||
Feature flags
|
||||
</h2>
|
||||
<h2 class="m-0 text-lg font-extrabold text-contrast">Feature flags</h2>
|
||||
<p class="mt-1 mb-0 leading-tight text-secondary">
|
||||
These are developer tools that are not intended to be used by end users except for debugging purposes.
|
||||
These are developer tools that are not intended to be used by end users except for debugging
|
||||
purposes.
|
||||
</p>
|
||||
<p class="my-3 font-bold">Do not report bugs or issues if you have any feature flags enabled.</p>
|
||||
<div v-for="option in options" :key="option" class="mt-2 px-4 py-3 flex items-center justify-between bg-bg rounded-2xl">
|
||||
<div
|
||||
v-for="option in options"
|
||||
:key="option"
|
||||
class="mt-2 px-4 py-3 flex items-center justify-between bg-bg rounded-2xl"
|
||||
>
|
||||
<div>
|
||||
<h2 class="m-0 text-base font-bold text-primary capitalize">
|
||||
{{ option.replace(new RegExp('_', "g"), ' ') }}
|
||||
{{ option.replace(new RegExp('_', 'g'), ' ') }}
|
||||
</h2>
|
||||
<p class="m-0 text-sm text-secondary">Default: {{ DEFAULT_FEATURE_FLAGS[option] }}</p>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-1">
|
||||
<ButtonStyled type="transparent">
|
||||
<button class="text-sm" :disabled="getStoreValue(option) === DEFAULT_FEATURE_FLAGS[option]" @click="() => setStoreValue(option, !themeStore.featureFlags[option])">
|
||||
<button
|
||||
class="text-sm"
|
||||
:disabled="getStoreValue(option) === DEFAULT_FEATURE_FLAGS[option]"
|
||||
@click="() => setStoreValue(option, !themeStore.featureFlags[option])"
|
||||
>
|
||||
Reset to default
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<Toggle
|
||||
id="advanced-rendering"
|
||||
:model-value="getStoreValue(option)"
|
||||
|
||||
@update:model-value="() => setStoreValue(option, !themeStore.featureFlags[option])"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -12,18 +12,17 @@ export async function useInstanceContext() {
|
||||
const instance: Ref<GameInstance | undefined> = ref()
|
||||
const instanceContent: Ref<InstanceContentMap | undefined> = ref()
|
||||
|
||||
await loadInstance();
|
||||
await loadInstance()
|
||||
|
||||
watch(route, () => {
|
||||
loadInstance()
|
||||
})
|
||||
|
||||
async function loadInstance() {
|
||||
[instance.value, instanceContent.value] =
|
||||
await Promise.all([
|
||||
route.query.i ? getInstance(route.query.i).catch(handleError) : Promise.resolve(),
|
||||
route.query.i ? getInstanceProjects(route.query.i).catch(handleError) : Promise.resolve(),
|
||||
])
|
||||
;[instance.value, instanceContent.value] = await Promise.all([
|
||||
route.query.i ? getInstance(route.query.i).catch(handleError) : Promise.resolve(),
|
||||
route.query.i ? getInstanceProjects(route.query.i).catch(handleError) : Promise.resolve(),
|
||||
])
|
||||
}
|
||||
|
||||
const instanceQueryAppendage = computed(() => {
|
||||
|
||||
2
apps/app-frontend/src/helpers/types.d.ts
vendored
2
apps/app-frontend/src/helpers/types.d.ts
vendored
@ -37,7 +37,7 @@ type InstanceContent = {
|
||||
file_name: string
|
||||
size: number
|
||||
metadata?: {
|
||||
project_id: ModrinthId,
|
||||
project_id: ModrinthId
|
||||
version_id: ModrinthId
|
||||
}
|
||||
update_version_id: string
|
||||
|
||||
@ -26,15 +26,13 @@ import { get_categories, get_game_versions, get_loaders } from '@/helpers/tags'
|
||||
import type { LocationQuery } from 'vue-router'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import SearchCard from '@/components/ui/SearchCard.vue'
|
||||
import { get as getInstance, get_projects as getInstanceProjects } from '@/helpers/profile.js'
|
||||
import { get_search_results } from '@/helpers/cache.js'
|
||||
import NavTabs from '@/components/ui/NavTabs.vue'
|
||||
import InstanceIndicator from '@/components/ui/InstanceIndicator.vue'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
import ContextMenu from '@/components/ui/ContextMenu.vue'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
import { InstanceContentMap, useInstanceContext } from '@/composables/instance-context.ts'
|
||||
import { useInstanceContext } from '@/composables/instance-context.ts'
|
||||
import type { SearchResult } from '@modrinth/utils'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
@ -1,8 +1,21 @@
|
||||
<template>
|
||||
<Teleport to="#sidebar-teleport-target">
|
||||
<CollectionSidebarDescription v-if="collection" :collection="collection" class="project-sidebar-section" />
|
||||
<CollectionSidebarCurator v-if="curator" :user="curator" :link="`/user/${curator.id}`" class="project-sidebar-section" />
|
||||
<CollectionSidebarDetails v-if="collection" :collection="collection" class="project-sidebar-section" />
|
||||
<CollectionSidebarDescription
|
||||
v-if="collection"
|
||||
:collection="collection"
|
||||
class="project-sidebar-section"
|
||||
/>
|
||||
<CollectionSidebarCurator
|
||||
v-if="curator"
|
||||
:user="curator"
|
||||
:link="`/user/${curator.id}`"
|
||||
class="project-sidebar-section"
|
||||
/>
|
||||
<CollectionSidebarDetails
|
||||
v-if="collection"
|
||||
:collection="collection"
|
||||
class="project-sidebar-section"
|
||||
/>
|
||||
</Teleport>
|
||||
<div v-if="collection" class="p-6 flex flex-col gap-4">
|
||||
<InstanceIndicator :instance="instance" />
|
||||
@ -10,9 +23,7 @@
|
||||
<template #actions>
|
||||
<ButtonStyled v-if="themeStore.devMode" circular type="transparent" size="large">
|
||||
<OverflowMenu
|
||||
:options="[
|
||||
{ id: 'copy-id', action: () => copyId(), shown: themeStore.devMode },
|
||||
]"
|
||||
:options="[{ id: 'copy-id', action: () => copyId(), shown: themeStore.devMode }]"
|
||||
aria-label="More options"
|
||||
>
|
||||
<MoreVerticalIcon aria-hidden="true" />
|
||||
@ -25,9 +36,17 @@
|
||||
</template>
|
||||
</CollectionHeader>
|
||||
<div v-if="projects">
|
||||
<ProjectsList :projects="projects" :project-link="(project) => `/project/${project.id}${instanceQueryAppendage}`" :experimental-colors="themeStore.featureFlags.project_card_background">
|
||||
<ProjectsList
|
||||
:projects="projects"
|
||||
:project-link="(project) => `/project/${project.id}${instanceQueryAppendage}`"
|
||||
:experimental-colors="themeStore.featureFlags.project_card_background"
|
||||
>
|
||||
<template #project-actions="{ project }">
|
||||
<ProjectCardActions :instance="instance" :instance-content="instanceContent" :project="project" />
|
||||
<ProjectCardActions
|
||||
:instance="instance"
|
||||
:instance-content="instanceContent"
|
||||
:project="project"
|
||||
/>
|
||||
</template>
|
||||
</ProjectsList>
|
||||
</div>
|
||||
@ -43,7 +62,10 @@ import {
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
OverflowMenu,
|
||||
CollectionHeader, CollectionSidebarCurator, CollectionSidebarDescription, CollectionSidebarDetails
|
||||
CollectionHeader,
|
||||
CollectionSidebarCurator,
|
||||
CollectionSidebarDescription,
|
||||
CollectionSidebarDetails,
|
||||
} from '@modrinth/ui'
|
||||
import { ClipboardCopyIcon, MoreVerticalIcon } from '@modrinth/assets'
|
||||
import { useVIntl } from '@vintl/vintl'
|
||||
@ -64,14 +86,18 @@ const curator: Ref<User | null> = ref(null)
|
||||
const projects: Ref<Project[]> = ref([])
|
||||
|
||||
async function fetchCollection() {
|
||||
collection.value = await useFetch(`https://api.modrinth.com/v3/collection/${route.params.id}`).catch(handleError)
|
||||
collection.value = await useFetch(
|
||||
`https://api.modrinth.com/v3/collection/${route.params.id}`,
|
||||
).catch(handleError)
|
||||
|
||||
if (!collection.value) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
[ projects.value, curator.value ] = await Promise.all([
|
||||
useFetch(`https://api.modrinth.com/v2/projects?ids=${encodeURIComponent(JSON.stringify(collection.value.projects))}`),
|
||||
;[projects.value, curator.value] = await Promise.all([
|
||||
useFetch(
|
||||
`https://api.modrinth.com/v2/projects?ids=${encodeURIComponent(JSON.stringify(collection.value.projects))}`,
|
||||
),
|
||||
useFetch(`https://api.modrinth.com/v2/user/${collection.value.user}`).catch(handleError),
|
||||
])
|
||||
|
||||
@ -94,10 +120,9 @@ watch(
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
|
||||
async function copyId() {
|
||||
if (collection.value) {
|
||||
await navigator.clipboard.writeText(String(collection.value.id));
|
||||
await navigator.clipboard.writeText(String(collection.value.id))
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -69,7 +69,10 @@
|
||||
name: x.author.name,
|
||||
type: x.author.type,
|
||||
id: x.author.slug,
|
||||
link: { path: `/${x.author.type}/${x.author.slug}`, query: { i: props.instance.path } },
|
||||
link: {
|
||||
path: `/${x.author.type}/${x.author.slug}`,
|
||||
query: { i: props.instance.path },
|
||||
},
|
||||
linkProps: { target: '_blank' },
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,23 @@
|
||||
<template>
|
||||
<Teleport to="#sidebar-teleport-target">
|
||||
<OrganizationSidebarMembers v-if="organization" :members="organization.members" :user-link="(user) => `/user/${user.id}`" class="project-sidebar-section" />
|
||||
<OrganizationSidebarMembers
|
||||
v-if="organization"
|
||||
:members="organization.members"
|
||||
:user-link="(user) => `/user/${user.id}`"
|
||||
class="project-sidebar-section"
|
||||
/>
|
||||
</Teleport>
|
||||
<div v-if="organization" class="flex flex-col gap-4 p-6">
|
||||
<InstanceIndicator :instance="instance" />
|
||||
<OrganizationHeader :organization="organization" :download-count="sumDownloads" :project-count="projects.length">
|
||||
<OrganizationHeader
|
||||
:organization="organization"
|
||||
:download-count="sumDownloads"
|
||||
:project-count="projects.length"
|
||||
>
|
||||
<template #actions>
|
||||
<ButtonStyled v-if="themeStore.devMode" circular type="transparent" size="large">
|
||||
<OverflowMenu
|
||||
:options="[
|
||||
{ id: 'copy-id', action: () => copyId(), shown: themeStore.devMode },
|
||||
]"
|
||||
:options="[{ id: 'copy-id', action: () => copyId(), shown: themeStore.devMode }]"
|
||||
aria-label="More options"
|
||||
>
|
||||
<MoreVerticalIcon aria-hidden="true" />
|
||||
@ -23,9 +30,17 @@
|
||||
</template>
|
||||
</OrganizationHeader>
|
||||
<div v-if="projects">
|
||||
<ProjectsList :projects="projects" :project-link="(project) => `/project/${project.id}${instanceQueryAppendage}`" :experimental-colors="themeStore.featureFlags.project_card_background">
|
||||
<ProjectsList
|
||||
:projects="projects"
|
||||
:project-link="(project) => `/project/${project.id}${instanceQueryAppendage}`"
|
||||
:experimental-colors="themeStore.featureFlags.project_card_background"
|
||||
>
|
||||
<template #project-actions="{ project }">
|
||||
<ProjectCardActions :project="project" :instance="instance" :instance-content="instanceContent" />
|
||||
<ProjectCardActions
|
||||
:project="project"
|
||||
:instance="instance"
|
||||
:instance-content="instanceContent"
|
||||
/>
|
||||
</template>
|
||||
</ProjectsList>
|
||||
</div>
|
||||
@ -41,9 +56,10 @@ import {
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
OverflowMenu,
|
||||
OrganizationHeader, OrganizationSidebarMembers
|
||||
OrganizationHeader,
|
||||
OrganizationSidebarMembers,
|
||||
} from '@modrinth/ui'
|
||||
import { ClipboardCopyIcon, MoreVerticalIcon, DownloadIcon, HeartIcon, BookmarkIcon } from '@modrinth/assets'
|
||||
import { ClipboardCopyIcon, MoreVerticalIcon } from '@modrinth/assets'
|
||||
import { useVIntl } from '@vintl/vintl'
|
||||
import { useFetch } from '@/helpers/fetch'
|
||||
import type { Project, Organization, ProjectV3, Environment } from '@modrinth/utils'
|
||||
@ -63,35 +79,41 @@ const projects: Ref<Project[]> = ref([])
|
||||
const { instance, instanceContent, instanceQueryAppendage } = await useInstanceContext()
|
||||
|
||||
async function fetchOrganization() {
|
||||
organization.value = await useFetch(`https://api.modrinth.com/v3/organization/${route.params.id}`).catch(handleError)
|
||||
projects.value = (await useFetch(`https://api.modrinth.com/v3/organization/${route.params.id}/projects`).catch(handleError)).map((projectV3: ProjectV3) => {
|
||||
organization.value = await useFetch(
|
||||
`https://api.modrinth.com/v3/organization/${route.params.id}`,
|
||||
).catch(handleError)
|
||||
projects.value = (
|
||||
await useFetch(`https://api.modrinth.com/v3/organization/${route.params.id}/projects`).catch(
|
||||
handleError,
|
||||
)
|
||||
).map((projectV3: ProjectV3) => {
|
||||
let type = projectV3.project_types[0]
|
||||
|
||||
if (type === 'plugin' || type === 'datapack') {
|
||||
type = 'mod'
|
||||
}
|
||||
|
||||
let clientSide: Environment = 'unknown';
|
||||
let serverSide: Environment = 'unknown';
|
||||
let clientSide: Environment = 'unknown'
|
||||
let serverSide: Environment = 'unknown'
|
||||
|
||||
const singleplayer = projectV3.singleplayer && projectV3.singleplayer[0];
|
||||
const clientAndServer = projectV3.client_and_server && projectV3.client_and_server[0];
|
||||
const clientOnly = projectV3.client_only && projectV3.client_only[0];
|
||||
const serverOnly = projectV3.server_only && projectV3.server_only[0];
|
||||
const singleplayer = projectV3.singleplayer && projectV3.singleplayer[0]
|
||||
const clientAndServer = projectV3.client_and_server && projectV3.client_and_server[0]
|
||||
const clientOnly = projectV3.client_only && projectV3.client_only[0]
|
||||
const serverOnly = projectV3.server_only && projectV3.server_only[0]
|
||||
|
||||
// quick and dirty hack to show envs as legacy
|
||||
if (singleplayer && clientAndServer && !clientOnly && !serverOnly) {
|
||||
clientSide = "required";
|
||||
serverSide = "required";
|
||||
clientSide = 'required'
|
||||
serverSide = 'required'
|
||||
} else if (singleplayer && clientAndServer && clientOnly && !serverOnly) {
|
||||
clientSide = "required";
|
||||
serverSide = "unsupported";
|
||||
clientSide = 'required'
|
||||
serverSide = 'unsupported'
|
||||
} else if (singleplayer && clientAndServer && !clientOnly && serverOnly) {
|
||||
clientSide = "unsupported";
|
||||
serverSide = "required";
|
||||
clientSide = 'unsupported'
|
||||
serverSide = 'required'
|
||||
} else if (singleplayer && clientAndServer && clientOnly && serverOnly) {
|
||||
clientSide = "optional";
|
||||
serverSide = "optional";
|
||||
clientSide = 'optional'
|
||||
serverSide = 'optional'
|
||||
}
|
||||
|
||||
const projectV2: Project = {
|
||||
@ -109,7 +131,7 @@ async function fetchOrganization() {
|
||||
})
|
||||
|
||||
if (!organization.value) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
breadcrumbs.setName('Organization', organization.value.name)
|
||||
@ -130,20 +152,19 @@ const themeStore = useTheming()
|
||||
|
||||
async function copyId() {
|
||||
if (organization.value) {
|
||||
await navigator.clipboard.writeText(String(organization.value.id));
|
||||
await navigator.clipboard.writeText(String(organization.value.id))
|
||||
}
|
||||
}
|
||||
|
||||
const sumDownloads = computed(() => {
|
||||
let sum = 0;
|
||||
let sum = 0
|
||||
|
||||
for (const project of projects.value) {
|
||||
sum += project.downloads;
|
||||
sum += project.downloads
|
||||
}
|
||||
|
||||
return sum;
|
||||
});
|
||||
|
||||
return sum
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.project-sidebar-section {
|
||||
|
||||
@ -204,7 +204,9 @@ async function fetchProjectData() {
|
||||
])
|
||||
|
||||
if (project.organization) {
|
||||
organization.value = await useFetch(`https://api.modrinth.com/v3/organization/${project.organization}`).catch(handleError)
|
||||
organization.value = await useFetch(
|
||||
`https://api.modrinth.com/v3/organization/${project.organization}`,
|
||||
).catch(handleError)
|
||||
}
|
||||
|
||||
versions.value = versions.value.sort((a, b) => dayjs(b.date_published) - dayjs(a.date_published))
|
||||
|
||||
@ -1,13 +1,21 @@
|
||||
<template>
|
||||
<Teleport to="#sidebar-teleport-target">
|
||||
<UserSidebarOrganizations :organizations="organizations" :link="(org: Organization) => `/organization/${org.id}${instanceQueryAppendage}`" class="project-sidebar-section" />
|
||||
<UserSidebarOrganizations
|
||||
:organizations="organizations"
|
||||
:link="(org: Organization) => `/organization/${org.id}${instanceQueryAppendage}`"
|
||||
class="project-sidebar-section"
|
||||
/>
|
||||
<UserSidebarBadges
|
||||
v-if="user"
|
||||
:user="user"
|
||||
:download-count="sumDownloads"
|
||||
class="project-sidebar-section"
|
||||
/>
|
||||
<UserSidebarCollections :collections="collections" :link="(collection: Collection) => `/collection/${collection.id}${instanceQueryAppendage}`" class="project-sidebar-section" />
|
||||
<UserSidebarCollections
|
||||
:collections="collections"
|
||||
:link="(collection: Collection) => `/collection/${collection.id}${instanceQueryAppendage}`"
|
||||
class="project-sidebar-section"
|
||||
/>
|
||||
</Teleport>
|
||||
<div v-if="user" class="p-6 flex flex-col gap-4">
|
||||
<InstanceIndicator :instance="instance" />
|
||||
@ -16,9 +24,13 @@
|
||||
<ButtonStyled circular type="transparent" size="large">
|
||||
<OverflowMenu
|
||||
:options="[
|
||||
{ id: 'report', link: `https://modrinth.com/report?item=user&itemID=${user.id}`, color: 'red' },
|
||||
{ id: 'copy-id', action: () => copyId(), shown: themeStore.devMode },
|
||||
]"
|
||||
{
|
||||
id: 'report',
|
||||
link: `https://modrinth.com/report?item=user&itemID=${user.id}`,
|
||||
color: 'red',
|
||||
},
|
||||
{ id: 'copy-id', action: () => copyId(), shown: themeStore.devMode },
|
||||
]"
|
||||
aria-label="More options"
|
||||
>
|
||||
<MoreVerticalIcon aria-hidden="true" />
|
||||
@ -35,9 +47,17 @@
|
||||
</template>
|
||||
</UserHeader>
|
||||
<div v-if="projects">
|
||||
<ProjectsList :projects="projects" :project-link="(project) => `/project/${project.id}${instanceQueryAppendage}`" :experimental-colors="themeStore.featureFlags.project_card_background">
|
||||
<ProjectsList
|
||||
:projects="projects"
|
||||
:project-link="(project) => `/project/${project.id}${instanceQueryAppendage}`"
|
||||
:experimental-colors="themeStore.featureFlags.project_card_background"
|
||||
>
|
||||
<template #project-actions="{ project }">
|
||||
<ProjectCardActions :instance="instance" :instance-content="instanceContent" :project="project" />
|
||||
<ProjectCardActions
|
||||
:instance="instance"
|
||||
:instance-content="instanceContent"
|
||||
:project="project"
|
||||
/>
|
||||
</template>
|
||||
</ProjectsList>
|
||||
</div>
|
||||
@ -55,7 +75,8 @@ import {
|
||||
commonMessages,
|
||||
OverflowMenu,
|
||||
UserHeader,
|
||||
UserSidebarBadges, UserSidebarCollections
|
||||
UserSidebarBadges,
|
||||
UserSidebarCollections,
|
||||
} from '@modrinth/ui'
|
||||
import { ReportIcon, ClipboardCopyIcon, MoreVerticalIcon } from '@modrinth/assets'
|
||||
import { useVIntl } from '@vintl/vintl'
|
||||
@ -77,15 +98,17 @@ const organizations: Ref<Organization[]> = ref([])
|
||||
const collections: Ref<Collection[]> = ref([])
|
||||
|
||||
async function fetchUser() {
|
||||
[ user.value, projects.value, organizations.value, collections.value ] = await Promise.all([
|
||||
;[user.value, projects.value, organizations.value, collections.value] = await Promise.all([
|
||||
useFetch(`https://api.modrinth.com/v2/user/${route.params.id}`).catch(handleError),
|
||||
useFetch(`https://api.modrinth.com/v2/user/${route.params.id}/projects`).catch(handleError),
|
||||
useFetch(`https://api.modrinth.com/v3/user/${route.params.id}/organizations`).catch(handleError),
|
||||
useFetch(`https://api.modrinth.com/v3/user/${route.params.id}/collections`).catch(handleError)
|
||||
useFetch(`https://api.modrinth.com/v3/user/${route.params.id}/organizations`).catch(
|
||||
handleError,
|
||||
),
|
||||
useFetch(`https://api.modrinth.com/v3/user/${route.params.id}/collections`).catch(handleError),
|
||||
])
|
||||
|
||||
if (!user.value) {
|
||||
return;
|
||||
return
|
||||
}
|
||||
|
||||
breadcrumbs.setContext({ name: 'User', link: `/user/${user.value.username}` })
|
||||
@ -107,22 +130,21 @@ watch(
|
||||
|
||||
const themeStore = useTheming()
|
||||
|
||||
|
||||
async function copyId() {
|
||||
if (user.value) {
|
||||
await navigator.clipboard.writeText(String(user.value.id));
|
||||
await navigator.clipboard.writeText(String(user.value.id))
|
||||
}
|
||||
}
|
||||
|
||||
const sumDownloads = computed(() => {
|
||||
let sum = 0;
|
||||
let sum = 0
|
||||
|
||||
for (const project of projects.value) {
|
||||
sum += project.downloads;
|
||||
sum += project.downloads
|
||||
}
|
||||
|
||||
return sum;
|
||||
});
|
||||
return sum
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.project-sidebar-section {
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
export const DEFAULT_FEATURE_FLAGS = {
|
||||
'project_background': false,
|
||||
'page_path': false,
|
||||
'project_card_background': false,
|
||||
project_background: false,
|
||||
page_path: false,
|
||||
project_card_background: false,
|
||||
}
|
||||
|
||||
export const useTheming = defineStore('themeStore', {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user