✨ Show time and id at messages
This commit is contained in:
		| @@ -20,6 +20,7 @@ | ||||
|     "@capacitor/preferences": "^5.0.7", | ||||
|     "@fontsource/roboto": "^5.0.12", | ||||
|     "@mdi/font": "^7.4.47", | ||||
|     "dayjs": "^1.11.10", | ||||
|     "dompurify": "^3.0.11", | ||||
|     "marked": "^12.0.1", | ||||
|     "nprogress": "^0.2.0", | ||||
|   | ||||
| @@ -2,11 +2,9 @@ | ||||
|   <div class="relative transition-colors transition-300 message-item"> | ||||
|     <a v-if="props.item?.reply_to" :href="`#m${props.item?.reply_to.id}`"> | ||||
|       <div class="pl-2 mb-0.5 text-sm opacity-80 flex items-center"> | ||||
|         <v-icon icon="mdi-reply" class="me-2" /> | ||||
|         <v-icon icon="mdi-reply" class="me-2 mb-1" /> | ||||
|         <v-avatar size="18" class="me-1.5" :image="replyingFromPicture"></v-avatar> | ||||
|         <span class="me-1 text-xs overflow-hidden ws-nowarp text-ellipsis">{{ props.item?.reply_to?.content }}</span> | ||||
|         <span class="text-xs overflow-hidden ws-nowarp text-ellipsis"> | ||||
|           from {{ props.item?.reply_to?.sender.account.name }} | ||||
|         </span> | ||||
|       </div> | ||||
|     </a> | ||||
|  | ||||
| @@ -21,7 +19,11 @@ | ||||
|       </div> | ||||
|  | ||||
|       <div class="flex-grow-1"> | ||||
|         <div class="font-bold text-sm">{{ props.item?.sender.account.nick }}</div> | ||||
|         <div class="flex gap-1.25 text-sm items-baseline"> | ||||
|           <span class="font-bold">{{ props.item?.sender.account.nick }}</span> | ||||
|           <span class="opacity-80">{{ createdAt }}</span> | ||||
|           <span class="opacity-60 text-xs">#{{ props.item?.id }}</span> | ||||
|         </div> | ||||
|         <div>{{ props.item?.content }}</div> | ||||
|  | ||||
|         <message-attachment | ||||
| @@ -35,8 +37,10 @@ | ||||
|         <v-card> | ||||
|           <div class="flex px-2 py-0.5"> | ||||
|             <v-btn icon="mdi-reply" size="x-small" variant="text" @click="replyMessage" /> | ||||
|             <v-btn v-if="isOwned" icon="mdi-pencil" size="x-small" variant="text" color="warning" @click="editMessage" /> | ||||
|             <v-btn v-if="isOwned" icon="mdi-delete" size="x-small" variant="text" color="error" @click="deleteMessage" /> | ||||
|             <v-btn v-if="isOwned" icon="mdi-pencil" size="x-small" variant="text" color="warning" | ||||
|                    @click="editMessage" /> | ||||
|             <v-btn v-if="isOwned" icon="mdi-delete" size="x-small" variant="text" color="error" | ||||
|                    @click="deleteMessage" /> | ||||
|           </div> | ||||
|         </v-card> | ||||
|       </div> | ||||
| @@ -48,6 +52,8 @@ | ||||
| import { useChannels } from "@/stores/channels" | ||||
| import { useUserinfo } from "@/stores/userinfo" | ||||
| import { computed } from "vue" | ||||
| import dayjs from "dayjs" | ||||
| import relativeTime from "dayjs/plugin/relativeTime" | ||||
| import MessageAttachment from "@/components/chat/renderer/MessageAttachment.vue" | ||||
|  | ||||
| const id = useUserinfo() | ||||
| @@ -55,7 +61,15 @@ const channels = useChannels() | ||||
|  | ||||
| const props = defineProps<{ item: any }>() | ||||
|  | ||||
| dayjs.extend(relativeTime) | ||||
|  | ||||
| const isOwned = computed(() => props.item?.sender?.account_id === id.userinfo.idSet.messaging) | ||||
| const createdAt = computed(() => dayjs(props.item?.created_at).fromNow()) | ||||
|  | ||||
| const replyingFromPicture = computed(() => props.item?.reply_to.sender.account?.avatar ? | ||||
|   props.item?.reply_to.sender.account?.avatar : | ||||
|   null | ||||
| ) | ||||
|  | ||||
| function replyMessage() { | ||||
|   channels.related.messages.reply_to = JSON.parse(JSON.stringify(props.item)) | ||||
|   | ||||
| @@ -1,7 +1,15 @@ | ||||
| <template> | ||||
|   <v-snackbar v-model="ui.snackbar" v-bind="ui.snackbar"> | ||||
|     <div v-html="ui.snackbar.content"></div> | ||||
|     <v-progress-linear v-if="ui.snackbar.loading" class="snackbar-progress" indeterminate /> | ||||
|   </v-snackbar> | ||||
|  | ||||
|   <v-snackbar v-model="ui.reconnection.messages"> | ||||
|     <div>Reconnecting with messaging server...</div> | ||||
|     <v-progress-linear v-if="ui.snackbar.loading" class="snackbar-progress" indeterminate /> | ||||
|   </v-snackbar> | ||||
|   <v-snackbar v-model="ui.reconnection.notifications"> | ||||
|     <div>Reconnecting with notifications server...</div> | ||||
|     <v-progress-linear v-if="ui.snackbar.loading" class="snackbar-progress" indeterminate /> | ||||
|   </v-snackbar> | ||||
| </template> | ||||
| @@ -12,7 +20,7 @@ import { useUI } from "@/stores/ui" | ||||
| const ui = useUI() | ||||
| </script> | ||||
|  | ||||
| <style scoped> | ||||
| <style> | ||||
| .snackbar-progress { | ||||
|   margin: 12px -16px -14px; | ||||
|   width: calc(100% + 64px); | ||||
|   | ||||
| @@ -3,6 +3,7 @@ import { reactive, ref, watch } from "vue" | ||||
| import { checkLoggedIn, getAtk } from "@/stores/userinfo" | ||||
| import { buildRequestUrl, request } from "@/scripts/request" | ||||
| import { useRoute } from "vue-router" | ||||
| import { useUI } from "@/stores/ui" | ||||
|  | ||||
| export const useChannels = defineStore("channels", () => { | ||||
|   let socket: WebSocket | ||||
| @@ -61,6 +62,8 @@ export const useChannels = defineStore("channels", () => { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   const ui = useUI() | ||||
|  | ||||
|   async function connect() { | ||||
|     if (!(await checkLoggedIn())) return | ||||
|  | ||||
| @@ -74,12 +77,20 @@ export const useChannels = defineStore("channels", () => { | ||||
|     }) | ||||
|     socket.addEventListener("close", (event) => { | ||||
|       console.warn("[MESSAGING] The unified websocket is disconnected... ", event.reason, event.code) | ||||
|       if(reconnectCount <= 3) { | ||||
|       const reconnect = () => { | ||||
|         reconnectCount = 0 | ||||
|         connect().then(() => { | ||||
|           console.warn("[MESSAGING] Now reconnecting!") | ||||
|           ui.reconnection.messages = false | ||||
|           reconnectCount++ | ||||
|         }) | ||||
|       } | ||||
|       ui.reconnection.messages = true | ||||
|       if (reconnectCount <= 3) { | ||||
|         reconnect() | ||||
|       } else { | ||||
|         setTimeout(() => reconnect(), 3000) | ||||
|       } | ||||
|  | ||||
|     }) | ||||
|     socket.addEventListener("message", (event) => { | ||||
|       const data = JSON.parse(event.data) | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import { checkLoggedIn, getAtk } from "@/stores/userinfo" | ||||
| import { buildRequestUrl, request } from "@/scripts/request" | ||||
| import { LocalNotifications } from "@capacitor/local-notifications" | ||||
| import { Capacitor } from "@capacitor/core" | ||||
| import { useUI } from "@/stores/ui" | ||||
|  | ||||
| export const useNotifications = defineStore("notifications", () => { | ||||
|   let socket: WebSocket | ||||
| @@ -40,6 +41,8 @@ export const useNotifications = defineStore("notifications", () => { | ||||
|     total.value-- | ||||
|   } | ||||
|  | ||||
|   const ui = useUI() | ||||
|  | ||||
|   async function connect() { | ||||
|     if (!(await checkLoggedIn())) return | ||||
|  | ||||
| @@ -53,12 +56,19 @@ export const useNotifications = defineStore("notifications", () => { | ||||
|     }) | ||||
|     socket.addEventListener("close", (event) => { | ||||
|       console.warn("[NOTIFICATIONS] The listen websocket is disconnected... ", event.reason, event.code) | ||||
|       if (reconnectCount <= 3) { | ||||
|       const reconnect = () => { | ||||
|         reconnectCount = 0 | ||||
|         connect().then(() => { | ||||
|           console.warn("[NOTIFICATIONS] Now reconnecting!") | ||||
|           ui.reconnection.notifications = false | ||||
|           reconnectCount++ | ||||
|         }) | ||||
|       } | ||||
|       ui.reconnection.notifications = true | ||||
|       if (reconnectCount <= 3) { | ||||
|         reconnect() | ||||
|       } else { | ||||
|         setTimeout(() => reconnect(), 3000) | ||||
|       } | ||||
|     }) | ||||
|     socket.addEventListener("message", (event) => { | ||||
|       const data = JSON.parse(event.data) | ||||
|   | ||||
| @@ -3,6 +3,10 @@ import { reactive, ref } from "vue" | ||||
|  | ||||
| export const useUI = defineStore("ui", () => { | ||||
|   const snackbar = ref<any>(null) | ||||
|   const reconnection = reactive({ | ||||
|     notifications: false, | ||||
|     messages: false, | ||||
|   }) | ||||
|  | ||||
|   const safeArea = reactive({ | ||||
|     top: 0, | ||||
| @@ -23,5 +27,5 @@ export const useUI = defineStore("ui", () => { | ||||
|    }, 5000) | ||||
|   } | ||||
|  | ||||
|   return { safeArea, snackbar, showSnackbar, showErrorSnackbar } | ||||
|   return { safeArea, snackbar, reconnection, showSnackbar, showErrorSnackbar } | ||||
| }) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user