You've already forked AstralRinth
forked from didirus/AstralRinth
refactor: migrate to common eslint+prettier configs (#4168)
* refactor: migrate to common eslint+prettier configs * fix: prettier frontend * feat: config changes * fix: lint issues * fix: lint * fix: type imports * fix: cyclical import issue * fix: lockfile * fix: missing dep * fix: switch to tabs * fix: continue switch to tabs * fix: rustfmt parity * fix: moderation lint issue * fix: lint issues * fix: ui intl * fix: lint issues * Revert "fix: rustfmt parity" This reverts commit cb99d2376c321d813d4b7fc7e2a213bb30a54711. * feat: revert last rs
This commit is contained in:
@@ -1,39 +1,39 @@
|
||||
<script setup lang="ts">
|
||||
import { useVIntl, defineMessages } from '@vintl/vintl'
|
||||
import type { VersionChannel } from '@modrinth/utils'
|
||||
import { defineMessages, useVIntl } from '@vintl/vintl'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
channel: VersionChannel
|
||||
large?: boolean
|
||||
}>(),
|
||||
{
|
||||
large: false,
|
||||
},
|
||||
defineProps<{
|
||||
channel: VersionChannel
|
||||
large?: boolean
|
||||
}>(),
|
||||
{
|
||||
large: false,
|
||||
},
|
||||
)
|
||||
|
||||
const messages = defineMessages({
|
||||
releaseSymbol: {
|
||||
id: 'project.versions.channel.release.symbol',
|
||||
defaultMessage: 'R',
|
||||
},
|
||||
betaSymbol: {
|
||||
id: 'project.versions.channel.beta.symbol',
|
||||
defaultMessage: 'B',
|
||||
},
|
||||
alphaSymbol: {
|
||||
id: 'project.versions.channel.alpha.symbol',
|
||||
defaultMessage: 'A',
|
||||
},
|
||||
releaseSymbol: {
|
||||
id: 'project.versions.channel.release.symbol',
|
||||
defaultMessage: 'R',
|
||||
},
|
||||
betaSymbol: {
|
||||
id: 'project.versions.channel.beta.symbol',
|
||||
defaultMessage: 'B',
|
||||
},
|
||||
alphaSymbol: {
|
||||
id: 'project.versions.channel.alpha.symbol',
|
||||
defaultMessage: 'A',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
:class="`flex ${large ? 'text-lg w-[2.625rem] h-[2.625rem]' : 'text-sm w-9 h-9'} font-bold justify-center items-center rounded-full ${channel === 'release' ? 'bg-bg-green text-brand-green' : channel === 'beta' ? 'bg-bg-orange text-brand-orange' : 'bg-bg-red text-brand-red'}`"
|
||||
>
|
||||
{{ channel ? formatMessage(messages[`${channel}Symbol`]) : '?' }}
|
||||
</div>
|
||||
<div
|
||||
:class="`flex ${large ? 'text-lg w-[2.625rem] h-[2.625rem]' : 'text-sm w-9 h-9'} font-bold justify-center items-center rounded-full ${channel === 'release' ? 'bg-bg-green text-brand-green' : channel === 'beta' ? 'bg-bg-orange text-brand-orange' : 'bg-bg-red text-brand-red'}`"
|
||||
>
|
||||
{{ channel ? formatMessage(messages[`${channel}Symbol`]) : '?' }}
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -1,95 +1,96 @@
|
||||
<template>
|
||||
<div class="experimental-styles-within flex flex-col gap-3">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<ManySelect
|
||||
v-model="selectedPlatforms"
|
||||
:options="filterOptions.platform"
|
||||
:dropdown-id="`${baseId}-platform`"
|
||||
@change="updateFilters"
|
||||
>
|
||||
<FilterIcon class="h-5 w-5 text-secondary" />
|
||||
Platform
|
||||
<template #option="{ option }">
|
||||
{{ formatCategory(option) }}
|
||||
</template>
|
||||
</ManySelect>
|
||||
<ManySelect
|
||||
v-model="selectedGameVersions"
|
||||
:options="filterOptions.gameVersion"
|
||||
:dropdown-id="`${baseId}-game-version`"
|
||||
search
|
||||
@change="updateFilters"
|
||||
>
|
||||
<FilterIcon class="h-5 w-5 text-secondary" />
|
||||
Game versions
|
||||
<template #footer>
|
||||
<Checkbox v-model="showSnapshots" class="mx-1" :label="`Show all versions`" />
|
||||
</template>
|
||||
</ManySelect>
|
||||
<ManySelect
|
||||
v-model="selectedChannels"
|
||||
:options="filterOptions.channel"
|
||||
:dropdown-id="`${baseId}-channel`"
|
||||
@change="updateFilters"
|
||||
>
|
||||
<FilterIcon class="h-5 w-5 text-secondary" />
|
||||
Channels
|
||||
<template #option="{ option }">
|
||||
{{ option === 'release' ? 'Release' : option === 'beta' ? 'Beta' : 'Alpha' }}
|
||||
</template>
|
||||
</ManySelect>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-1 empty:hidden">
|
||||
<TagItem
|
||||
v-if="selectedChannels.length + selectedGameVersions.length + selectedPlatforms.length > 1"
|
||||
class="transition-transform active:scale-[0.95]"
|
||||
:action="clearFilters"
|
||||
>
|
||||
<XCircleIcon />
|
||||
Clear all filters
|
||||
</TagItem>
|
||||
<TagItem
|
||||
v-for="channel in selectedChannels"
|
||||
:key="`remove-filter-${channel}`"
|
||||
:style="`--_color: var(--color-${channel === 'alpha' ? 'red' : channel === 'beta' ? 'orange' : 'green'});--_bg-color: var(--color-${channel === 'alpha' ? 'red' : channel === 'beta' ? 'orange' : 'green'}-highlight)`"
|
||||
:action="() => toggleFilter('channel', channel)"
|
||||
>
|
||||
<XIcon />
|
||||
{{ channel.slice(0, 1).toUpperCase() + channel.slice(1) }}
|
||||
</TagItem>
|
||||
<TagItem
|
||||
v-for="version in selectedGameVersions"
|
||||
:key="`remove-filter-${version}`"
|
||||
:action="() => toggleFilter('gameVersion', version)"
|
||||
>
|
||||
<XIcon />
|
||||
{{ version }}
|
||||
</TagItem>
|
||||
<TagItem
|
||||
v-for="platform in selectedPlatforms"
|
||||
:key="`remove-filter-${platform}`"
|
||||
:style="`--_color: var(--color-platform-${platform})`"
|
||||
:action="() => toggleFilter('platform', platform)"
|
||||
>
|
||||
<XIcon />
|
||||
{{ formatCategory(platform) }}
|
||||
</TagItem>
|
||||
</div>
|
||||
</div>
|
||||
<div class="experimental-styles-within flex flex-col gap-3">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<ManySelect
|
||||
v-model="selectedPlatforms"
|
||||
:options="filterOptions.platform"
|
||||
:dropdown-id="`${baseId}-platform`"
|
||||
@change="updateFilters"
|
||||
>
|
||||
<FilterIcon class="h-5 w-5 text-secondary" />
|
||||
Platform
|
||||
<template #option="{ option }">
|
||||
{{ formatCategory(option) }}
|
||||
</template>
|
||||
</ManySelect>
|
||||
<ManySelect
|
||||
v-model="selectedGameVersions"
|
||||
:options="filterOptions.gameVersion"
|
||||
:dropdown-id="`${baseId}-game-version`"
|
||||
search
|
||||
@change="updateFilters"
|
||||
>
|
||||
<FilterIcon class="h-5 w-5 text-secondary" />
|
||||
Game versions
|
||||
<template #footer>
|
||||
<Checkbox v-model="showSnapshots" class="mx-1" :label="`Show all versions`" />
|
||||
</template>
|
||||
</ManySelect>
|
||||
<ManySelect
|
||||
v-model="selectedChannels"
|
||||
:options="filterOptions.channel"
|
||||
:dropdown-id="`${baseId}-channel`"
|
||||
@change="updateFilters"
|
||||
>
|
||||
<FilterIcon class="h-5 w-5 text-secondary" />
|
||||
Channels
|
||||
<template #option="{ option }">
|
||||
{{ option === 'release' ? 'Release' : option === 'beta' ? 'Beta' : 'Alpha' }}
|
||||
</template>
|
||||
</ManySelect>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-1 empty:hidden">
|
||||
<TagItem
|
||||
v-if="selectedChannels.length + selectedGameVersions.length + selectedPlatforms.length > 1"
|
||||
class="transition-transform active:scale-[0.95]"
|
||||
:action="clearFilters"
|
||||
>
|
||||
<XCircleIcon />
|
||||
Clear all filters
|
||||
</TagItem>
|
||||
<TagItem
|
||||
v-for="channel in selectedChannels"
|
||||
:key="`remove-filter-${channel}`"
|
||||
:style="`--_color: var(--color-${channel === 'alpha' ? 'red' : channel === 'beta' ? 'orange' : 'green'});--_bg-color: var(--color-${channel === 'alpha' ? 'red' : channel === 'beta' ? 'orange' : 'green'}-highlight)`"
|
||||
:action="() => toggleFilter('channel', channel)"
|
||||
>
|
||||
<XIcon />
|
||||
{{ channel.slice(0, 1).toUpperCase() + channel.slice(1) }}
|
||||
</TagItem>
|
||||
<TagItem
|
||||
v-for="version in selectedGameVersions"
|
||||
:key="`remove-filter-${version}`"
|
||||
:action="() => toggleFilter('gameVersion', version)"
|
||||
>
|
||||
<XIcon />
|
||||
{{ version }}
|
||||
</TagItem>
|
||||
<TagItem
|
||||
v-for="platform in selectedPlatforms"
|
||||
:key="`remove-filter-${platform}`"
|
||||
:style="`--_color: var(--color-platform-${platform})`"
|
||||
:action="() => toggleFilter('platform', platform)"
|
||||
>
|
||||
<XIcon />
|
||||
{{ formatCategory(platform) }}
|
||||
</TagItem>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { FilterIcon, XCircleIcon, XIcon } from '@modrinth/assets'
|
||||
import { ManySelect, Checkbox } from '../index'
|
||||
import { type Version, formatCategory, type GameVersionTag } from '@modrinth/utils'
|
||||
import { ref, computed } from 'vue'
|
||||
import { formatCategory, type GameVersionTag, type Version } from '@modrinth/utils'
|
||||
import { computed, ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import TagItem from '../base/TagItem.vue'
|
||||
import { Checkbox, ManySelect } from '../index'
|
||||
|
||||
const props = defineProps<{
|
||||
versions: Version[]
|
||||
gameVersions: GameVersionTag[]
|
||||
baseId?: string
|
||||
versions: Version[]
|
||||
gameVersions: GameVersionTag[]
|
||||
baseId?: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits(['update:query'])
|
||||
@@ -104,42 +105,42 @@ type FilterType = 'channel' | 'gameVersion' | 'platform'
|
||||
type Filter = string
|
||||
|
||||
const filterOptions = computed(() => {
|
||||
const filters: Record<FilterType, Filter[]> = {
|
||||
channel: [],
|
||||
gameVersion: [],
|
||||
platform: [],
|
||||
}
|
||||
const filters: Record<FilterType, Filter[]> = {
|
||||
channel: [],
|
||||
gameVersion: [],
|
||||
platform: [],
|
||||
}
|
||||
|
||||
const platformSet = new Set()
|
||||
const gameVersionSet = new Set()
|
||||
const channelSet = new Set()
|
||||
const platformSet = new Set()
|
||||
const gameVersionSet = new Set()
|
||||
const channelSet = new Set()
|
||||
|
||||
for (const version of props.versions) {
|
||||
for (const loader of version.loaders) {
|
||||
platformSet.add(loader)
|
||||
}
|
||||
for (const gameVersion of version.game_versions) {
|
||||
gameVersionSet.add(gameVersion)
|
||||
}
|
||||
channelSet.add(version.version_type)
|
||||
}
|
||||
for (const version of props.versions) {
|
||||
for (const loader of version.loaders) {
|
||||
platformSet.add(loader)
|
||||
}
|
||||
for (const gameVersion of version.game_versions) {
|
||||
gameVersionSet.add(gameVersion)
|
||||
}
|
||||
channelSet.add(version.version_type)
|
||||
}
|
||||
|
||||
if (channelSet.size > 0) {
|
||||
filters.channel = Array.from(channelSet) as Filter[]
|
||||
filters.channel.sort((a, b) => allChannels.value.indexOf(a) - allChannels.value.indexOf(b))
|
||||
}
|
||||
if (gameVersionSet.size > 0) {
|
||||
const gameVersions = props.gameVersions.filter((x) => gameVersionSet.has(x.version))
|
||||
if (channelSet.size > 0) {
|
||||
filters.channel = Array.from(channelSet) as Filter[]
|
||||
filters.channel.sort((a, b) => allChannels.value.indexOf(a) - allChannels.value.indexOf(b))
|
||||
}
|
||||
if (gameVersionSet.size > 0) {
|
||||
const gameVersions = props.gameVersions.filter((x) => gameVersionSet.has(x.version))
|
||||
|
||||
filters.gameVersion = gameVersions
|
||||
.filter((x) => (showSnapshots.value ? true : x.version_type === 'release'))
|
||||
.map((x) => x.version)
|
||||
}
|
||||
if (platformSet.size > 0) {
|
||||
filters.platform = Array.from(platformSet) as Filter[]
|
||||
}
|
||||
filters.gameVersion = gameVersions
|
||||
.filter((x) => (showSnapshots.value ? true : x.version_type === 'release'))
|
||||
.map((x) => x.version)
|
||||
}
|
||||
if (platformSet.size > 0) {
|
||||
filters.platform = Array.from(platformSet) as Filter[]
|
||||
}
|
||||
|
||||
return filters
|
||||
return filters
|
||||
})
|
||||
|
||||
const selectedChannels = ref<string[]>([])
|
||||
@@ -151,62 +152,62 @@ selectedGameVersions.value = route.query.g ? getArrayOrString(route.query.g) : [
|
||||
selectedPlatforms.value = route.query.l ? getArrayOrString(route.query.l) : []
|
||||
|
||||
async function toggleFilters(type: FilterType, filters: Filter[]) {
|
||||
for (const filter of filters) {
|
||||
await toggleFilter(type, filter, true)
|
||||
}
|
||||
for (const filter of filters) {
|
||||
await toggleFilter(type, filter, true)
|
||||
}
|
||||
|
||||
updateFilters()
|
||||
updateFilters()
|
||||
}
|
||||
|
||||
async function toggleFilter(type: FilterType, filter: Filter, bulk = false) {
|
||||
if (type === 'channel') {
|
||||
selectedChannels.value = selectedChannels.value.includes(filter)
|
||||
? selectedChannels.value.filter((x) => x !== filter)
|
||||
: [...selectedChannels.value, filter]
|
||||
} else if (type === 'gameVersion') {
|
||||
selectedGameVersions.value = selectedGameVersions.value.includes(filter)
|
||||
? selectedGameVersions.value.filter((x) => x !== filter)
|
||||
: [...selectedGameVersions.value, filter]
|
||||
} else if (type === 'platform') {
|
||||
selectedPlatforms.value = selectedPlatforms.value.includes(filter)
|
||||
? selectedPlatforms.value.filter((x) => x !== filter)
|
||||
: [...selectedPlatforms.value, filter]
|
||||
}
|
||||
if (!bulk) {
|
||||
updateFilters()
|
||||
}
|
||||
if (type === 'channel') {
|
||||
selectedChannels.value = selectedChannels.value.includes(filter)
|
||||
? selectedChannels.value.filter((x) => x !== filter)
|
||||
: [...selectedChannels.value, filter]
|
||||
} else if (type === 'gameVersion') {
|
||||
selectedGameVersions.value = selectedGameVersions.value.includes(filter)
|
||||
? selectedGameVersions.value.filter((x) => x !== filter)
|
||||
: [...selectedGameVersions.value, filter]
|
||||
} else if (type === 'platform') {
|
||||
selectedPlatforms.value = selectedPlatforms.value.includes(filter)
|
||||
? selectedPlatforms.value.filter((x) => x !== filter)
|
||||
: [...selectedPlatforms.value, filter]
|
||||
}
|
||||
if (!bulk) {
|
||||
updateFilters()
|
||||
}
|
||||
}
|
||||
|
||||
async function clearFilters() {
|
||||
selectedChannels.value = []
|
||||
selectedGameVersions.value = []
|
||||
selectedPlatforms.value = []
|
||||
selectedChannels.value = []
|
||||
selectedGameVersions.value = []
|
||||
selectedPlatforms.value = []
|
||||
|
||||
updateFilters()
|
||||
updateFilters()
|
||||
}
|
||||
|
||||
function updateFilters() {
|
||||
emit('update:query', {
|
||||
c: selectedChannels.value,
|
||||
g: selectedGameVersions.value,
|
||||
l: selectedPlatforms.value,
|
||||
page: undefined,
|
||||
})
|
||||
emit('update:query', {
|
||||
c: selectedChannels.value,
|
||||
g: selectedGameVersions.value,
|
||||
l: selectedPlatforms.value,
|
||||
page: undefined,
|
||||
})
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
toggleFilter,
|
||||
toggleFilters,
|
||||
selectedChannels,
|
||||
selectedGameVersions,
|
||||
selectedPlatforms,
|
||||
toggleFilter,
|
||||
toggleFilters,
|
||||
selectedChannels,
|
||||
selectedGameVersions,
|
||||
selectedPlatforms,
|
||||
})
|
||||
|
||||
function getArrayOrString(x: string | string[]): string[] {
|
||||
if (typeof x === 'string') {
|
||||
return [x]
|
||||
} else {
|
||||
return x
|
||||
}
|
||||
if (typeof x === 'string') {
|
||||
return [x]
|
||||
} else {
|
||||
return x
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,46 +1,47 @@
|
||||
<template>
|
||||
<div
|
||||
class="grid grid-cols-[min-content_auto_min-content_min-content] items-center gap-2 rounded-2xl border-[1px] border-divider bg-bg p-2"
|
||||
>
|
||||
<VersionChannelIndicator :channel="version.version_type" />
|
||||
<div class="flex min-w-0 flex-col gap-1">
|
||||
<h1 class="my-0 truncate text-nowrap text-base font-extrabold leading-none text-contrast">
|
||||
{{ version.version_number }}
|
||||
</h1>
|
||||
<p class="m-0 truncate text-nowrap text-xs font-semibold text-secondary">
|
||||
{{ version.name }}
|
||||
</p>
|
||||
</div>
|
||||
<ButtonStyled color="brand">
|
||||
<a :href="downloadUrl" class="min-w-0" @click="emit('onDownload')">
|
||||
<DownloadIcon aria-hidden="true" /> Download
|
||||
</a>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled circular>
|
||||
<nuxt-link
|
||||
:to="`/project/${props.version.project_id}/version/${props.version.id}`"
|
||||
class="min-w-0"
|
||||
aria-label="Open project page"
|
||||
@click="emit('onNavigate')"
|
||||
>
|
||||
<ExternalIcon aria-hidden="true" />
|
||||
</nuxt-link>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<div
|
||||
class="grid grid-cols-[min-content_auto_min-content_min-content] items-center gap-2 rounded-2xl border-[1px] border-divider bg-bg p-2"
|
||||
>
|
||||
<VersionChannelIndicator :channel="version.version_type" />
|
||||
<div class="flex min-w-0 flex-col gap-1">
|
||||
<h1 class="my-0 truncate text-nowrap text-base font-extrabold leading-none text-contrast">
|
||||
{{ version.version_number }}
|
||||
</h1>
|
||||
<p class="m-0 truncate text-nowrap text-xs font-semibold text-secondary">
|
||||
{{ version.name }}
|
||||
</p>
|
||||
</div>
|
||||
<ButtonStyled color="brand">
|
||||
<a :href="downloadUrl" class="min-w-0" @click="emit('onDownload')">
|
||||
<DownloadIcon aria-hidden="true" /> Download
|
||||
</a>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled circular>
|
||||
<nuxt-link
|
||||
:to="`/project/${props.version.project_id}/version/${props.version.id}`"
|
||||
class="min-w-0"
|
||||
aria-label="Open project page"
|
||||
@click="emit('onNavigate')"
|
||||
>
|
||||
<ExternalIcon aria-hidden="true" />
|
||||
</nuxt-link>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ButtonStyled, VersionChannelIndicator } from '../index'
|
||||
import { DownloadIcon, ExternalIcon } from '@modrinth/assets'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { ButtonStyled, VersionChannelIndicator } from '../index'
|
||||
|
||||
const props = defineProps<{
|
||||
version: Version
|
||||
version: Version
|
||||
}>()
|
||||
|
||||
const downloadUrl = computed(() => {
|
||||
const primary: VersionFile = props.version.files.find((x) => x.primary) || props.version.files[0]
|
||||
return primary.url
|
||||
const primary: VersionFile = props.version.files.find((x) => x.primary) || props.version.files[0]
|
||||
return primary.url
|
||||
})
|
||||
|
||||
const emit = defineEmits(['onDownload', 'onNavigate'])
|
||||
|
||||
Reference in New Issue
Block a user