fix: 404 when returning to collections dashboard (#5963)

* fix 404 when returning to collections dashboard, fix a couple hydration
issues

* fix clippy

* fmt

* fix hydration issue on revenue page

* fix transfer history page error

---------

Co-authored-by: aecsocket <aecsocket@tutanota.com>
This commit is contained in:
Prospector
2026-05-02 09:33:19 -07:00
committed by GitHub
parent c2359275ff
commit be618d96f4
10 changed files with 94 additions and 79 deletions

View File

@@ -1,7 +1,9 @@
<template>
<NuxtLayout>
<NuxtRouteAnnouncer />
<LoadingBar />
<ClientOnly>
<LoadingBar />
</ClientOnly>
<NotificationPanel />
<I18nDebugPanel />
<NuxtPage />

View File

@@ -186,7 +186,9 @@
getProjectTypeSentenceMessage(
projectTypes.length === 1 ? projectTypes[0] : 'project',
),
{ count: formatCompactNumberPlural(projects?.length || 0) },
{
count: formatCompactNumberPlural(projects?.length || 0),
},
),
}"
>
@@ -532,8 +534,8 @@ const returnLink = computed(() => {
return null
})
const isFollowingCollection = computed(() => route.params.id === 'following')
const collectionId = computed(() => route.params.id)
const isFollowingCollection = computed(() => collectionId.value === 'following')
// Static collection for "following" page
const followingCollection = computed(() =>
@@ -560,13 +562,13 @@ const {
} = useQuery({
queryKey: computed(() => ['collection', collectionId.value]),
queryFn: () => api.labrinth.collections.get(collectionId.value),
enabled: computed(() => !isFollowingCollection.value),
enabled: computed(() => !!collectionId.value && !isFollowingCollection.value),
})
watch(
collectionError,
(error) => {
if (error && !isFollowingCollection.value) {
if (error && collectionId.value && !isFollowingCollection.value) {
const status = error.statusCode ?? error.status ?? 404
showError({
fatal: true,

View File

@@ -70,7 +70,12 @@
date: date.date ? formatDate(date.date) : '',
})
}}
<Tooltip theme="dismissable-prompt" :triggers="['hover', 'focus']" no-auto-focus>
<Tooltip
theme="dismissable-prompt"
:triggers="['hover', 'focus']"
no-auto-focus
:aria-id="`${baseId}-date-segment-tooltip-${i}`"
>
<nuxt-link
class="inline-flex items-center justify-center text-link"
to="/legal/cmp-info#pending"
@@ -99,7 +104,12 @@
class="zone--striped-small zone--striped--gray my-auto block size-4 rounded-full bg-button-bg opacity-90 md:size-5"
></span>
{{ formatMessage(messages.processing) }}
<Tooltip theme="dismissable-prompt" :triggers="['hover', 'focus']" no-auto-focus>
<Tooltip
theme="dismissable-prompt"
:triggers="['hover', 'focus']"
no-auto-focus
:aria-id="`${baseId}-processing-tooltip`"
>
<InProgressIcon class="inline-block size-4 align-middle md:size-5" />
<template #popper>
<div class="w-[250px] font-semibold text-contrast">
@@ -292,6 +302,8 @@ type RevenueBarSegment = {
const hoveredSeg = ref<string | null>(null)
const baseId = useId()
const withdrawModal = ref<InstanceType<typeof CreatorWithdrawModal>>()
async function openWithdrawModal() {
withdrawModal.value?.show?.()

View File

@@ -117,6 +117,53 @@ const formatMonth = useFormatDateTime({
const client = injectModrinthClient()
const generatedState = useGeneratedState()
const messages = defineMessages({
transactionsHeader: {
id: 'dashboard.revenue.transactions.header',
defaultMessage: 'Transactions',
},
headTitle: {
id: 'dashboard.revenue.transactions.head-title',
defaultMessage: 'Transaction history',
},
received: {
id: 'dashboard.revenue.stats.received',
defaultMessage: 'Received',
},
withdrawn: {
id: 'dashboard.revenue.stats.withdrawn',
defaultMessage: 'Withdrawn',
},
transactions: {
id: 'dashboard.revenue.stats.transactions',
defaultMessage: 'Transactions',
},
noTransactions: {
id: 'dashboard.revenue.transactions.none',
defaultMessage: 'No transactions',
},
noTransactionsDesc: {
id: 'dashboard.revenue.transactions.none.desc',
defaultMessage: 'Your payouts and withdrawals will appear here.',
},
downloadCsv: {
id: 'dashboard.revenue.transactions.btn.download-csv',
defaultMessage: 'Download as CSV',
},
allYears: {
id: 'dashboard.revenue.transactions.year.all',
defaultMessage: 'All years',
},
thisMonth: {
id: 'dashboard.revenue.transactions.period.this-month',
defaultMessage: 'This month',
},
lastMonth: {
id: 'dashboard.revenue.transactions.period.last-month',
defaultMessage: 'Last month',
},
})
useHead({
title: () => `${formatMessage(messages.headTitle)} - Modrinth`,
})
@@ -318,51 +365,4 @@ const downloadTransactionsCSV = () => {
}
const onDownloadCSV = useClientTry(async () => await downloadTransactionsCSV())
const messages = defineMessages({
transactionsHeader: {
id: 'dashboard.revenue.transactions.header',
defaultMessage: 'Transactions',
},
headTitle: {
id: 'dashboard.revenue.transactions.head-title',
defaultMessage: 'Transaction history',
},
received: {
id: 'dashboard.revenue.stats.received',
defaultMessage: 'Received',
},
withdrawn: {
id: 'dashboard.revenue.stats.withdrawn',
defaultMessage: 'Withdrawn',
},
transactions: {
id: 'dashboard.revenue.stats.transactions',
defaultMessage: 'Transactions',
},
noTransactions: {
id: 'dashboard.revenue.transactions.none',
defaultMessage: 'No transactions',
},
noTransactionsDesc: {
id: 'dashboard.revenue.transactions.none.desc',
defaultMessage: 'Your payouts and withdrawals will appear here.',
},
downloadCsv: {
id: 'dashboard.revenue.transactions.btn.download-csv',
defaultMessage: 'Download as CSV',
},
allYears: {
id: 'dashboard.revenue.transactions.year.all',
defaultMessage: 'All years',
},
thisMonth: {
id: 'dashboard.revenue.transactions.period.this-month',
defaultMessage: 'This month',
},
lastMonth: {
id: 'dashboard.revenue.transactions.period.last-month',
defaultMessage: 'Last month',
},
})
</script>

View File

@@ -228,8 +228,7 @@ pub async fn install_zipped_mrpack_files(
let num_files = pack.files.len();
loading_try_for_each_concurrent(
futures::stream::iter(pack.files.into_iter())
.map(Ok::<PackFile, crate::Error>),
futures::stream::iter(pack.files).map(Ok::<PackFile, crate::Error>),
None,
Some(&loading_bar),
70.0,

View File

@@ -150,8 +150,8 @@ pub async fn resolve_server_address(
match resolver.srv_lookup(format!("_minecraft._tcp.{host}")).await {
Err(e)
if e.proto()
.filter(|x| x.kind().is_no_records_found())
.is_some() =>
.as_ref()
.is_some_and(|x| x.kind().is_no_records_found()) =>
{
None
}

View File

@@ -791,7 +791,7 @@ pub async fn remove_server_from_profile(
index: usize,
) -> Result<()> {
let mut servers = servers_data::read(profile_path).await?;
if servers.get(index).filter(|x| !x.hidden).is_none() {
if servers.get(index).as_ref().is_none_or(|x| x.hidden) {
return Err(ErrorKind::InputError(format!(
"No removable server at index {index}"
))

View File

@@ -59,31 +59,28 @@ pub async fn init_watcher() -> crate::Result<FileWatcher> {
.nth(1)
.map(|x| x.as_os_str());
if first_file_name
.filter(|x| *x == "crash-reports")
.is_some()
.as_ref()
.is_some_and(|x| *x == "crash-reports")
&& e.path
.extension()
.filter(|x| *x == "txt")
.is_some()
.as_ref()
.is_some_and(|x| *x == "txt")
{
crash_task(profile_path_str);
} else if !visited_profiles.contains(&profile_path)
{
let event = if first_file_name
.filter(|x| *x == "servers.dat")
.is_some()
.as_ref()
.is_some_and(|x| *x == "servers.dat")
{
Some(ProfilePayloadType::ServersUpdated)
} else if first_file_name
.filter(|x| {
*x == "saves"
&& e.path
.file_name()
.filter(|x| *x == "level.dat")
.is_some()
})
.is_some()
{
} else if first_file_name.as_ref().is_some_and(|x| {
*x == "saves"
&& e.path
.file_name()
.as_ref()
.is_some_and(|x| *x == "level.dat")
}) {
tracing::info!(
"World updated: {}",
e.path.display()
@@ -113,8 +110,8 @@ pub async fn init_watcher() -> crate::Result<FileWatcher> {
}
Some(ProfilePayloadType::WorldUpdated { world })
} else if first_file_name
.filter(|x| *x == "saves")
.is_none()
.as_ref()
.is_none_or(|x| *x != "saves")
{
Some(ProfilePayloadType::Synced)
} else {

View File

@@ -283,7 +283,7 @@ fn check_modpack_update(
.collect();
// Sort by date_published descending (newest first)
compatible_versions.sort_by(|a, b| b.date_published.cmp(&a.date_published));
compatible_versions.sort_by_key(|b| std::cmp::Reverse(b.date_published));
// Find the newest compatible version
if let Some(newest) = compatible_versions.first() {

View File

@@ -1,8 +1,11 @@
<script setup lang="ts">
import { Menu } from 'floating-vue'
import { useId } from 'vue'
import { TagItem, TagTagItem } from '../base'
const id = useId()
defineProps<{
tags: string[]
}>()
@@ -13,7 +16,7 @@ defineOptions({
</script>
<template>
<Menu :delay="{ hide: 50, show: 0 }" no-auto-focus>
<Menu :delay="{ hide: 50, show: 0 }" no-auto-focus :aria-id="id">
<TagItem v-if="tags.length > 0" v-bind="$attrs" tabindex="0"> +{{ tags.length }} </TagItem>
<template #popper>
<div class="flex gap-1 flex-wrap max-w-[20rem]">