🔨 Add mark all read to message

This commit is contained in:
SebClem 2024-02-19 10:52:37 +01:00
parent 21895edd8d
commit 17a6f1cbec
Signed by: sebclem
GPG Key ID: 5A4308F6A359EA50
4 changed files with 105 additions and 75 deletions

View File

@ -3,16 +3,21 @@ import messageManager from "../tools/messageManager.js";
const messageRouter = express.Router(); const messageRouter = express.Router();
messageRouter.get('/', (req, res, next)=>{ messageRouter.get("/", (req, res) => {
res.json(messageManager.get()) res.json(messageManager.get());
}); });
messageRouter.patch('/:messageId/readed', (req, res, next)=>{ messageRouter.patch("/:messageId/readed", (req, res) => {
if(messageManager.markReaded(req.params.messageId)){ if (messageManager.markReaded(req.params.messageId)) {
res.json(messageManager.get()); res.json(messageManager.get());
}else{ } else {
res.status(404).send(); res.status(404).send();
} }
}); });
messageRouter.post("/allReaded", (req, res) => {
messageManager.markAllReaded();
res.json(messageManager.get());
});
export default messageRouter; export default messageRouter;

View File

@ -7,14 +7,19 @@ const maxMessageLength = 255;
class MessageManager { class MessageManager {
private messages: Message[] = []; private messages: Message[] = [];
public addMessage(type: MessageType, message: string, detail?: string, isImportant = false) { public addMessage(
this.messages.push({ type: MessageType,
message: string,
detail?: string,
isImportant = false
) {
this.messages.unshift({
id: randomUUID(), id: randomUUID(),
message: message, message: message,
type: type, type: type,
time: DateTime.now(), time: DateTime.now(),
viewed: !isImportant, viewed: !isImportant,
detail: detail detail: detail,
}); });
if (this.messages.length > maxMessageLength) { if (this.messages.length > maxMessageLength) {
this.messages.shift(); this.messages.shift();
@ -37,24 +42,28 @@ class MessageManager {
this.addMessage(MessageType.SUCCESS, message, detail); this.addMessage(MessageType.SUCCESS, message, detail);
} }
public get(){ public get() {
return this.messages; return this.messages;
} }
public getById(id: string){ public getById(id: string) {
return this.messages.find(value=>value.id == id); return this.messages.find((value) => value.id == id);
} }
public markReaded(id: string){ public markReaded(id: string) {
const index = this.messages.findIndex(value=>value.id == id); const index = this.messages.findIndex((value) => value.id == id);
if(index == -1){ if (index == -1) {
return false; return false;
} }
this.messages[index].viewed = true; this.messages[index].viewed = true;
return true; return true;
} }
public markAllReaded() {
this.messages.forEach((value: Message) => {
value.viewed = true;
});
}
} }
const messageManager = new MessageManager(); const messageManager = new MessageManager();
export default messageManager; export default messageManager;

View File

@ -1,69 +1,76 @@
<template> <template>
<v-menu activator="#message-btn" :close-on-content-click="false"> <v-menu activator="#message-btn" :close-on-content-click="false">
<v-sheet width="500" border rounded> <v-sheet width="500" border rounded>
<v-toolbar color="surface" density="compact"> <v-toolbar color="surface" density="comfortable" border>
<div class="d-flex justify-center w-100"> <v-toolbar-title>Messages</v-toolbar-title>
<h4>Messages</h4> <v-spacer></v-spacer>
</div> <v-btn icon @click="markAllReaded">
<v-icon color="success">mdi-check-all</v-icon>
</v-btn>
</v-toolbar> </v-toolbar>
<v-divider></v-divider> <v-divider></v-divider>
<v-responsive max-height="350px" class="overflow-y-auto"> <v-responsive max-height="350px" class="overflow-y-auto">
<v-list class="py-0"> <v-list class="py-0">
<template v-for="(item, index) in messages" :key="item.id"> <v-data-iterator :items="messages" item-value="id" items-per-page="-1">
<v-divider v-if="index != 0"></v-divider> <template v-slot:default="{ items, isExpanded, toggleExpand}">
<v-list-item :class="{ 'bg-brown-darken-4': !item.viewed }"> <template v-for="(item, index) in items" :key="item.raw.id">
<v-list-item-title> <v-divider v-if="index != 0"></v-divider>
{{ item.message }} <v-list-item :class="{ 'bg-brown-darken-4': !item.raw.viewed }">
</v-list-item-title> <v-list-item-title>
<template v-slot:prepend> {{ item.raw.message }}
<v-icon </v-list-item-title>
:icon="getMessageIcon(item.type)" <template v-slot:prepend>
:color="getMessageColor(item.type)" <v-icon
class="mr-3" :icon="getMessageIcon(item.raw.type)"
></v-icon> :color="getMessageColor(item.raw.type)"
</template> class="mr-3"
<template v-slot:append> ></v-icon>
<v-btn </template>
v-if="item.detail" <template v-slot:append>
variant="text" <v-btn
icon v-if="item.raw.detail"
color="secondary" variant="text"
@click="show[index] = show[index] ? false : true" icon
size="small" color="secondary"
> @click="toggleExpand(item)"
<v-icon> size="small"
{{ show[index] ? "mdi-chevron-up" : "mdi-information" }} >
</v-icon> <v-icon>
</v-btn> {{ isExpanded(item) ? "mdi-chevron-up" : "mdi-information" }}
<v-scroll-x-transition> </v-icon>
<v-btn </v-btn>
color="success" <v-scroll-x-transition>
variant="text" <v-btn
@click="markReaded(item.id)" color="success"
icon variant="text"
v-show="!item.viewed" @click="markReaded(item.raw.id)"
size="small" icon
> v-show="!item.raw.viewed"
<v-icon>mdi-check</v-icon> size="small"
</v-btn> >
</v-scroll-x-transition> <v-icon>mdi-check</v-icon>
</v-btn>
</v-scroll-x-transition>
<div class="text-caption text-disabled ml-1"> <div class="text-caption text-disabled ml-1">
{{ getTimeDelta(item.time) }} {{ getTimeDelta(item.raw.time) }}
</div> </div>
</template>
</v-list-item>
<v-expand-transition v-if="item.raw.detail">
<div v-if="isExpanded(item)">
<v-divider class="mx-3"></v-divider>
<v-card class="mx-3 my-2" variant="outlined" color="secondary">
<v-card-text>
{{ item.raw.detail }}
</v-card-text>
</v-card>
</div>
</v-expand-transition>
</template> </template>
</v-list-item> </template>
<v-expand-transition v-if="item.detail"> </v-data-iterator>
<div v-show="show[index]">
<v-divider class="mx-3"></v-divider>
<v-card class="mx-3 my-2" variant="outlined" color="secondary">
<v-card-text>
{{ item.detail }}
</v-card-text>
</v-card>
</div>
</v-expand-transition>
</template>
</v-list> </v-list>
</v-responsive> </v-responsive>
</v-sheet> </v-sheet>
@ -153,8 +160,13 @@ function markReaded(id: string) {
}); });
} }
function markAllReaded(){
messageService.markAllRead().then((value) => {
messages.value = value;
})
}
onBeforeUnmount(() => { onBeforeUnmount(() => {
clearInterval(interval); clearInterval(interval);
}); });
</script> </script>
@/store/message

View File

@ -8,3 +8,7 @@ export function getMessages() {
export function markRead(id: string) { export function markRead(id: string) {
return kyClient.patch(`messages/${encodeURI(id)}/readed`).json<Message[]>(); return kyClient.patch(`messages/${encodeURI(id)}/readed`).json<Message[]>();
} }
export function markAllRead(){
return kyClient.post(`messages/allReaded`).json<Message[]>();
}