1
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<v-snackbar
|
||||
v-model="snackbar"
|
||||
:color="colors[message?.type] || colors.info"
|
||||
:timeout="4000"
|
||||
:timeout="2000"
|
||||
location="bottom"
|
||||
class="global-snackbar"
|
||||
multi-line
|
||||
@@ -21,7 +21,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, onBeforeUnmount } from 'vue';
|
||||
import { defineComponent, ref, onBeforeUnmount, nextTick } from 'vue';
|
||||
import messageService from '@/utils/message';
|
||||
|
||||
export default defineComponent({
|
||||
@@ -44,8 +44,12 @@ export default defineComponent({
|
||||
info: 'info'
|
||||
};
|
||||
|
||||
const unsubscribe = messageService?.onSnackbar?.((msg) => {
|
||||
const unsubscribe = messageService?.onSnackbar?.(async (msg) => {
|
||||
if (!msg) return;
|
||||
if (snackbar.value) {
|
||||
snackbar.value = false;
|
||||
await nextTick();
|
||||
}
|
||||
message.value = msg;
|
||||
snackbar.value = true;
|
||||
});
|
||||
|
||||
@@ -1,49 +1,37 @@
|
||||
<template>
|
||||
<v-navigation-drawer v-model="drawer" location="right" temporary width="400">
|
||||
<v-toolbar color="primary">
|
||||
<v-toolbar-title>
|
||||
消息记录
|
||||
<v-chip v-if="unreadCount" color="error" size="x-small" class="ml-2">
|
||||
{{ unreadCount }}
|
||||
</v-chip>
|
||||
</v-toolbar-title>
|
||||
<v-toolbar-title>消息记录</v-toolbar-title>
|
||||
<template #append>
|
||||
<v-btn icon="mdi-delete" variant="text" color="white" @click="clear" />
|
||||
<v-btn icon="mdi-delete" variant="text" @click="clearMessages" />
|
||||
</template>
|
||||
</v-toolbar>
|
||||
|
||||
<v-list class="pa-4">
|
||||
<template v-if="visibleMessages.length">
|
||||
<v-slide-y-transition group>
|
||||
<v-list-item
|
||||
v-for="msg in visibleMessages"
|
||||
:key="msg.id"
|
||||
:active="!msg.read"
|
||||
class="mb-3"
|
||||
rounded
|
||||
@click="markAsRead(msg.id)"
|
||||
>
|
||||
<template #prepend>
|
||||
<v-icon :icon="icons[msg.type]" :color="colors[msg.type]" size="20" />
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-item v-for="msg in messages" :key="msg.id" rounded>
|
||||
<template #prepend>
|
||||
<v-icon :icon="icons[msg.type]" :color="colors[msg.type]" size="20" />
|
||||
</template>
|
||||
|
||||
<div class="d-flex flex-column flex-grow-1 px-3">
|
||||
<v-list-item-title>{{ msg.title }}</v-list-item-title>
|
||||
<v-list-item-subtitle v-if="msg.content">{{ msg.content }}</v-list-item-subtitle>
|
||||
<span class="text-caption text-grey">{{ new Date(msg.timestamp).toLocaleTimeString() }}</span>
|
||||
</div>
|
||||
<v-list-item-title>{{ msg.title }}</v-list-item-title>
|
||||
<v-list-item-subtitle v-if="msg.content">{{
|
||||
msg.content
|
||||
}}</v-list-item-subtitle>
|
||||
<span class="text-caption text-grey">
|
||||
{{ new Date(msg.timestamp).toLocaleTimeString() }}
|
||||
</span>
|
||||
|
||||
<template #append>
|
||||
<v-btn icon="mdi-delete" variant="text" size="small" @click.stop="deleteMessage(msg.id)" />
|
||||
</template>
|
||||
</v-list-item>
|
||||
</v-slide-y-transition>
|
||||
<template #append>
|
||||
<v-btn
|
||||
icon="mdi-delete"
|
||||
variant="text"
|
||||
size="small"
|
||||
@click="deleteMessage(msg.id)"
|
||||
/>
|
||||
</template>
|
||||
</v-list-item>
|
||||
|
||||
<v-btn v-if="hasMore" variant="tonal" block class="mt-4" @click="loadMore">
|
||||
加载更多
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list-item v-else>
|
||||
<v-list-item v-if="!messages.length">
|
||||
<template #prepend>
|
||||
<v-icon icon="mdi-inbox" color="grey" />
|
||||
</template>
|
||||
@@ -54,58 +42,43 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, ref, computed, onBeforeUnmount } from 'vue';
|
||||
import messageService from '@/utils/message';
|
||||
import { defineComponent, ref } from "vue";
|
||||
import messageService from "@/utils/message";
|
||||
|
||||
export default defineComponent({
|
||||
name: 'MessageLog',
|
||||
name: "MessageLog",
|
||||
setup() {
|
||||
const drawer = ref(false);
|
||||
const messages = ref([]);
|
||||
const unreadCount = ref(0);
|
||||
const page = ref(1);
|
||||
const PAGE_SIZE = 20;
|
||||
|
||||
const visibleMessages = computed(() => messages.value.slice(0, page.value * PAGE_SIZE));
|
||||
const hasMore = computed(() => visibleMessages.value.length < messages.value.length);
|
||||
|
||||
const icons = {
|
||||
success: 'mdi-check-circle',
|
||||
error: 'mdi-alert-circle',
|
||||
warning: 'mdi-alert',
|
||||
info: 'mdi-information'
|
||||
success: "mdi-check-circle",
|
||||
error: "mdi-alert-circle",
|
||||
warning: "mdi-alert",
|
||||
info: "mdi-information",
|
||||
};
|
||||
|
||||
const colors = {
|
||||
success: 'success',
|
||||
error: 'error',
|
||||
warning: 'warning',
|
||||
info: 'primary'
|
||||
success: "success",
|
||||
error: "error",
|
||||
warning: "warning",
|
||||
info: "primary",
|
||||
};
|
||||
|
||||
const unsubscribe = messageService?.onLog?.(msgs => {
|
||||
if (!msgs) return;
|
||||
messages.value = msgs.reverse();
|
||||
unreadCount.value = messageService.getUnreadCount();
|
||||
messageService.onLog((msgs) => {
|
||||
if (msgs) {
|
||||
messages.value = msgs;
|
||||
}
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => unsubscribe?.());
|
||||
|
||||
return {
|
||||
drawer,
|
||||
unreadCount,
|
||||
visibleMessages,
|
||||
hasMore,
|
||||
messages,
|
||||
icons,
|
||||
colors,
|
||||
loadMore: () => page.value++,
|
||||
markAsRead: id => messageService?.markAsRead?.(id),
|
||||
deleteMessage: id => messageService?.deleteMessage?.(id),
|
||||
clear: () => {
|
||||
messageService?.clearMessages?.();
|
||||
messages.value = [];
|
||||
}
|
||||
deleteMessage: (id) => messageService.deleteMessage(id),
|
||||
clearMessages: () => messageService.clearMessages(),
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user