You've already forked AstralRinth
forked from xxxOFFxxx/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,156 +1,157 @@
|
||||
<template>
|
||||
<div>
|
||||
<section class="universal-card">
|
||||
<Breadcrumbs
|
||||
v-if="history"
|
||||
current-title="History"
|
||||
:link-stack="[{ href: `/dashboard/notifications`, label: 'Notifications' }]"
|
||||
/>
|
||||
<div class="header__row">
|
||||
<div class="header__title">
|
||||
<h2 v-if="history" class="text-2xl">Notification history</h2>
|
||||
<h2 v-else class="text-2xl">Notifications</h2>
|
||||
</div>
|
||||
<template v-if="!history">
|
||||
<Button v-if="data.hasRead" @click="updateRoute()">
|
||||
<HistoryIcon />
|
||||
View history
|
||||
</Button>
|
||||
<Button v-if="notifications.length > 0" color="danger" @click="readAll()">
|
||||
<CheckCheckIcon />
|
||||
Mark all as read
|
||||
</Button>
|
||||
</template>
|
||||
</div>
|
||||
<Chips
|
||||
v-if="notifTypes.length > 1"
|
||||
v-model="selectedType"
|
||||
:items="notifTypes"
|
||||
:format-label="(x) => (x === 'all' ? 'All' : formatProjectType(x).replace('_', ' ') + 's')"
|
||||
:capitalize="false"
|
||||
/>
|
||||
<p v-if="pending">Loading notifications...</p>
|
||||
<template v-else-if="error">
|
||||
<p>Error loading notifications:</p>
|
||||
<pre>
|
||||
<div>
|
||||
<section class="universal-card">
|
||||
<Breadcrumbs
|
||||
v-if="history"
|
||||
current-title="History"
|
||||
:link-stack="[{ href: `/dashboard/notifications`, label: 'Notifications' }]"
|
||||
/>
|
||||
<div class="header__row">
|
||||
<div class="header__title">
|
||||
<h2 v-if="history" class="text-2xl">Notification history</h2>
|
||||
<h2 v-else class="text-2xl">Notifications</h2>
|
||||
</div>
|
||||
<template v-if="!history">
|
||||
<Button v-if="data.hasRead" @click="updateRoute()">
|
||||
<HistoryIcon />
|
||||
View history
|
||||
</Button>
|
||||
<Button v-if="notifications.length > 0" color="danger" @click="readAll()">
|
||||
<CheckCheckIcon />
|
||||
Mark all as read
|
||||
</Button>
|
||||
</template>
|
||||
</div>
|
||||
<Chips
|
||||
v-if="notifTypes.length > 1"
|
||||
v-model="selectedType"
|
||||
:items="notifTypes"
|
||||
:format-label="(x) => (x === 'all' ? 'All' : formatProjectType(x).replace('_', ' ') + 's')"
|
||||
:capitalize="false"
|
||||
/>
|
||||
<p v-if="pending">Loading notifications...</p>
|
||||
<template v-else-if="error">
|
||||
<p>Error loading notifications:</p>
|
||||
<pre>
|
||||
{{ error }}
|
||||
</pre>
|
||||
</template>
|
||||
<template v-else-if="notifications && notifications.length > 0">
|
||||
<NotificationItem
|
||||
v-for="notification in notifications"
|
||||
:key="notification.id"
|
||||
:notifications="notifications"
|
||||
class="universal-card recessed"
|
||||
:notification="notification"
|
||||
:auth="auth"
|
||||
raised
|
||||
@update:notifications="() => refresh()"
|
||||
/>
|
||||
</template>
|
||||
<p v-else>You don't have any unread notifications.</p>
|
||||
<div class="flex justify-end">
|
||||
<Pagination :page="page" :count="pages" @switch-page="changePage" />
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else-if="notifications && notifications.length > 0">
|
||||
<NotificationItem
|
||||
v-for="notification in notifications"
|
||||
:key="notification.id"
|
||||
:notifications="notifications"
|
||||
class="universal-card recessed"
|
||||
:notification="notification"
|
||||
:auth="auth"
|
||||
raised
|
||||
@update:notifications="() => refresh()"
|
||||
/>
|
||||
</template>
|
||||
<p v-else>You don't have any unread notifications.</p>
|
||||
<div class="flex justify-end">
|
||||
<Pagination :page="page" :count="pages" @switch-page="changePage" />
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
<script setup>
|
||||
import { CheckCheckIcon, HistoryIcon } from "@modrinth/assets";
|
||||
import { Button, Chips, Pagination } from "@modrinth/ui";
|
||||
import { formatProjectType } from "@modrinth/utils";
|
||||
import Breadcrumbs from "~/components/ui/Breadcrumbs.vue";
|
||||
import NotificationItem from "~/components/ui/NotificationItem.vue";
|
||||
import { CheckCheckIcon, HistoryIcon } from '@modrinth/assets'
|
||||
import { Button, Chips, Pagination } from '@modrinth/ui'
|
||||
import { formatProjectType } from '@modrinth/utils'
|
||||
|
||||
import Breadcrumbs from '~/components/ui/Breadcrumbs.vue'
|
||||
import NotificationItem from '~/components/ui/NotificationItem.vue'
|
||||
import {
|
||||
fetchExtraNotificationData,
|
||||
groupNotifications,
|
||||
markAsRead,
|
||||
} from "~/helpers/platform-notifications.ts";
|
||||
fetchExtraNotificationData,
|
||||
groupNotifications,
|
||||
markAsRead,
|
||||
} from '~/helpers/platform-notifications.ts'
|
||||
|
||||
useHead({
|
||||
title: "Notifications - Modrinth",
|
||||
});
|
||||
title: 'Notifications - Modrinth',
|
||||
})
|
||||
|
||||
const auth = await useAuth();
|
||||
const route = useNativeRoute();
|
||||
const router = useNativeRouter();
|
||||
const auth = await useAuth()
|
||||
const route = useNativeRoute()
|
||||
const router = useNativeRouter()
|
||||
|
||||
const history = computed(() => route.name === "dashboard-notifications-history");
|
||||
const selectedType = ref("all");
|
||||
const page = ref(1);
|
||||
const perPage = ref(50);
|
||||
const history = computed(() => route.name === 'dashboard-notifications-history')
|
||||
const selectedType = ref('all')
|
||||
const page = ref(1)
|
||||
const perPage = ref(50)
|
||||
|
||||
const { data, pending, error, refresh } = await useAsyncData(
|
||||
async () => {
|
||||
const pageNum = page.value - 1;
|
||||
const showRead = history.value;
|
||||
const notifications = await useBaseFetch(`user/${auth.value.user.id}/notifications`);
|
||||
async () => {
|
||||
const pageNum = page.value - 1
|
||||
const showRead = history.value
|
||||
const notifications = await useBaseFetch(`user/${auth.value.user.id}/notifications`)
|
||||
|
||||
const typesInFeed = [
|
||||
...new Set(notifications.filter((n) => showRead || !n.read).map((n) => n.type)),
|
||||
];
|
||||
const typesInFeed = [
|
||||
...new Set(notifications.filter((n) => showRead || !n.read).map((n) => n.type)),
|
||||
]
|
||||
|
||||
const filtered = notifications.filter(
|
||||
(n) =>
|
||||
(selectedType.value === "all" || n.type === selectedType.value) && (showRead || !n.read),
|
||||
);
|
||||
const filtered = notifications.filter(
|
||||
(n) =>
|
||||
(selectedType.value === 'all' || n.type === selectedType.value) && (showRead || !n.read),
|
||||
)
|
||||
|
||||
const pages = Math.max(1, Math.ceil(filtered.length / perPage.value));
|
||||
const pages = Math.max(1, Math.ceil(filtered.length / perPage.value))
|
||||
|
||||
return fetchExtraNotificationData(
|
||||
filtered.slice(pageNum * perPage.value, pageNum * perPage.value + perPage.value),
|
||||
).then((notifs) => ({
|
||||
notifications: notifs,
|
||||
notifTypes: typesInFeed.length > 1 ? ["all", ...typesInFeed] : typesInFeed,
|
||||
pages,
|
||||
hasRead: notifications.some((n) => n.read),
|
||||
}));
|
||||
},
|
||||
{ watch: [page, history, selectedType] },
|
||||
);
|
||||
return fetchExtraNotificationData(
|
||||
filtered.slice(pageNum * perPage.value, pageNum * perPage.value + perPage.value),
|
||||
).then((notifs) => ({
|
||||
notifications: notifs,
|
||||
notifTypes: typesInFeed.length > 1 ? ['all', ...typesInFeed] : typesInFeed,
|
||||
pages,
|
||||
hasRead: notifications.some((n) => n.read),
|
||||
}))
|
||||
},
|
||||
{ watch: [page, history, selectedType] },
|
||||
)
|
||||
|
||||
const notifications = computed(() =>
|
||||
data.value ? groupNotifications(data.value.notifications, history.value) : [],
|
||||
);
|
||||
data.value ? groupNotifications(data.value.notifications, history.value) : [],
|
||||
)
|
||||
|
||||
const notifTypes = computed(() => data.value?.notifTypes || []);
|
||||
const pages = computed(() => data.value?.pages ?? 1);
|
||||
const notifTypes = computed(() => data.value?.notifTypes || [])
|
||||
const pages = computed(() => data.value?.pages ?? 1)
|
||||
|
||||
function updateRoute() {
|
||||
router.push(history.value ? "/dashboard/notifications" : "/dashboard/notifications/history");
|
||||
selectedType.value = "all";
|
||||
page.value = 1;
|
||||
router.push(history.value ? '/dashboard/notifications' : '/dashboard/notifications/history')
|
||||
selectedType.value = 'all'
|
||||
page.value = 1
|
||||
}
|
||||
|
||||
async function readAll() {
|
||||
const ids = notifications.value.flatMap((n) => [
|
||||
n.id,
|
||||
...(n.grouped_notifs ? n.grouped_notifs.map((g) => g.id) : []),
|
||||
]);
|
||||
const ids = notifications.value.flatMap((n) => [
|
||||
n.id,
|
||||
...(n.grouped_notifs ? n.grouped_notifs.map((g) => g.id) : []),
|
||||
])
|
||||
|
||||
await markAsRead(ids);
|
||||
await refresh();
|
||||
await markAsRead(ids)
|
||||
await refresh()
|
||||
}
|
||||
|
||||
function changePage(newPage) {
|
||||
page.value = newPage;
|
||||
if (import.meta.client) window.scrollTo({ top: 0, behavior: "smooth" });
|
||||
page.value = newPage
|
||||
if (import.meta.client) window.scrollTo({ top: 0, behavior: 'smooth' })
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.read-toggle-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-card-md);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--spacing-card-md);
|
||||
|
||||
.label__title {
|
||||
margin: 0;
|
||||
}
|
||||
.label__title {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.header__title {
|
||||
h2 {
|
||||
margin: 0 auto 0 0;
|
||||
}
|
||||
h2 {
|
||||
margin: 0 auto 0 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user