2020-01-29 20:37:25 +01:00
|
|
|
<template>
|
2023-04-08 02:01:42 +02:00
|
|
|
<MkPagination ref="pagingComponent" :pagination="pagination">
|
|
|
|
<template #empty>
|
|
|
|
<div class="_fullinfo">
|
|
|
|
<img
|
|
|
|
src="/static-assets/badges/info.png"
|
|
|
|
class="_ghost"
|
|
|
|
alt="Info"
|
|
|
|
/>
|
|
|
|
<div>{{ i18n.ts.noNotifications }}</div>
|
|
|
|
</div>
|
|
|
|
</template>
|
2022-01-09 13:35:35 +01:00
|
|
|
|
2023-04-08 02:01:42 +02:00
|
|
|
<template #default="{ items: notifications }">
|
|
|
|
<XList
|
|
|
|
v-slot="{ item: notification }"
|
|
|
|
class="elsfgstc"
|
|
|
|
:items="notifications"
|
|
|
|
:no-gap="true"
|
|
|
|
>
|
|
|
|
<XNote
|
|
|
|
v-if="
|
|
|
|
['reply', 'quote', 'mention'].includes(
|
|
|
|
notification.type
|
|
|
|
)
|
|
|
|
"
|
|
|
|
:key="notification.id"
|
|
|
|
:note="notification.note"
|
2023-06-23 01:46:18 +02:00
|
|
|
:collapsedReply="
|
|
|
|
notification.type === 'reply' ||
|
|
|
|
(notification.type === 'mention' &&
|
|
|
|
notification.note.replyId != null)
|
|
|
|
"
|
2023-04-08 02:01:42 +02:00
|
|
|
/>
|
|
|
|
<XNotification
|
|
|
|
v-else
|
|
|
|
:key="notification.id"
|
|
|
|
:notification="notification"
|
|
|
|
:with-time="true"
|
|
|
|
:full="true"
|
|
|
|
class="_panel notification"
|
|
|
|
/>
|
|
|
|
</XList>
|
|
|
|
</template>
|
|
|
|
</MkPagination>
|
2020-01-29 20:37:25 +01:00
|
|
|
</template>
|
|
|
|
|
2022-01-09 13:35:35 +01:00
|
|
|
<script lang="ts" setup>
|
2023-04-08 02:01:42 +02:00
|
|
|
import {
|
|
|
|
defineComponent,
|
|
|
|
markRaw,
|
|
|
|
onUnmounted,
|
|
|
|
onMounted,
|
|
|
|
computed,
|
|
|
|
ref,
|
|
|
|
} from "vue";
|
|
|
|
import { notificationTypes } from "calckey-js";
|
|
|
|
import MkPagination, { Paging } from "@/components/MkPagination.vue";
|
|
|
|
import XNotification from "@/components/MkNotification.vue";
|
|
|
|
import XList from "@/components/MkDateSeparatedList.vue";
|
|
|
|
import XNote from "@/components/MkNote.vue";
|
|
|
|
import * as os from "@/os";
|
|
|
|
import { stream } from "@/stream";
|
|
|
|
import { $i } from "@/account";
|
|
|
|
import { i18n } from "@/i18n";
|
2022-01-09 13:35:35 +01:00
|
|
|
|
|
|
|
const props = defineProps<{
|
2023-04-08 02:01:42 +02:00
|
|
|
includeTypes?: (typeof notificationTypes)[number][];
|
2022-01-09 13:35:35 +01:00
|
|
|
unreadOnly?: boolean;
|
|
|
|
}>();
|
|
|
|
|
|
|
|
const pagingComponent = ref<InstanceType<typeof MkPagination>>();
|
|
|
|
|
|
|
|
const pagination: Paging = {
|
2023-04-08 02:01:42 +02:00
|
|
|
endpoint: "i/notifications" as const,
|
2022-01-09 13:35:35 +01:00
|
|
|
limit: 10,
|
|
|
|
params: computed(() => ({
|
2022-03-06 08:06:27 +01:00
|
|
|
includeTypes: props.includeTypes ?? undefined,
|
2023-04-08 02:01:42 +02:00
|
|
|
excludeTypes: props.includeTypes
|
|
|
|
? undefined
|
|
|
|
: $i.mutingNotificationTypes,
|
2022-01-09 13:35:35 +01:00
|
|
|
unreadOnly: props.unreadOnly,
|
|
|
|
})),
|
|
|
|
};
|
|
|
|
|
|
|
|
const onNotification = (notification) => {
|
2023-04-08 02:01:42 +02:00
|
|
|
const isMuted = props.includeTypes
|
|
|
|
? !props.includeTypes.includes(notification.type)
|
|
|
|
: $i.mutingNotificationTypes.includes(notification.type);
|
|
|
|
if (isMuted || document.visibilityState === "visible") {
|
|
|
|
stream.send("readNotification", {
|
2022-06-05 05:26:36 +02:00
|
|
|
id: notification.id,
|
2022-01-09 13:35:35 +01:00
|
|
|
});
|
|
|
|
}
|
2020-07-29 16:03:08 +02:00
|
|
|
|
2022-01-09 13:35:35 +01:00
|
|
|
if (!isMuted) {
|
|
|
|
pagingComponent.value.prepend({
|
|
|
|
...notification,
|
2023-04-08 02:01:42 +02:00
|
|
|
isRead: document.visibilityState === "visible",
|
2022-01-09 13:35:35 +01:00
|
|
|
});
|
2020-01-29 20:37:25 +01:00
|
|
|
}
|
2022-01-09 13:35:35 +01:00
|
|
|
};
|
|
|
|
|
2022-06-25 20:12:58 +02:00
|
|
|
let connection;
|
|
|
|
|
2022-01-09 13:35:35 +01:00
|
|
|
onMounted(() => {
|
2023-04-08 02:01:42 +02:00
|
|
|
connection = stream.useChannel("main");
|
|
|
|
connection.on("notification", onNotification);
|
|
|
|
connection.on("readAllNotifications", () => {
|
2022-04-30 14:52:07 +02:00
|
|
|
if (pagingComponent.value) {
|
|
|
|
for (const item of pagingComponent.value.queue) {
|
|
|
|
item.isRead = true;
|
|
|
|
}
|
|
|
|
for (const item of pagingComponent.value.items) {
|
|
|
|
item.isRead = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2023-04-08 02:01:42 +02:00
|
|
|
connection.on("readNotifications", (notificationIds) => {
|
2022-04-30 14:52:07 +02:00
|
|
|
if (pagingComponent.value) {
|
|
|
|
for (let i = 0; i < pagingComponent.value.queue.length; i++) {
|
2023-04-08 02:01:42 +02:00
|
|
|
if (
|
|
|
|
notificationIds.includes(pagingComponent.value.queue[i].id)
|
|
|
|
) {
|
2022-04-30 14:52:07 +02:00
|
|
|
pagingComponent.value.queue[i].isRead = true;
|
|
|
|
}
|
|
|
|
}
|
2023-04-08 02:01:42 +02:00
|
|
|
for (
|
|
|
|
let i = 0;
|
|
|
|
i < (pagingComponent.value.items || []).length;
|
|
|
|
i++
|
|
|
|
) {
|
|
|
|
if (
|
|
|
|
notificationIds.includes(pagingComponent.value.items[i].id)
|
|
|
|
) {
|
2022-04-30 14:52:07 +02:00
|
|
|
pagingComponent.value.items[i].isRead = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2022-06-25 20:12:58 +02:00
|
|
|
});
|
2022-04-30 14:52:07 +02:00
|
|
|
|
2022-06-25 20:12:58 +02:00
|
|
|
onUnmounted(() => {
|
|
|
|
if (connection) connection.dispose();
|
2020-01-29 20:37:25 +01:00
|
|
|
});
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
2021-08-21 10:40:15 +02:00
|
|
|
.elsfgstc {
|
|
|
|
background: var(--panel);
|
2023-03-26 05:33:44 +02:00
|
|
|
border-radius: var(--radius);
|
2021-08-21 10:40:15 +02:00
|
|
|
}
|
2020-01-29 20:37:25 +01:00
|
|
|
</style>
|