diff --git a/src/components/BaseComponents/NavBar.vue b/src/components/BaseComponents/NavBar.vue index 56bef37c1e9db83f78f09316b7de6ed2324523e4..d296c76ef2fffcc81650b693b4b802c0a9ea7299 100644 --- a/src/components/BaseComponents/NavBar.vue +++ b/src/components/BaseComponents/NavBar.vue @@ -19,11 +19,14 @@ /> </li> <li> - <ChatAlt2Icon - class="m-6 cursor-pointer h-7" - alt="Meldinger" - @click="$router.push('/messages')" - /> + <div class="notification-container"> + <ChatAlt2Icon + class="m-6 cursor-pointer h-7" + alt="Meldinger" + @click="loadMessages()" + /> + <p @click="loadMessages()" class="notification" v-if="newMessages > 0">{{notifications}}</p> + </div> </li> <li> <UserCircleIcon @@ -39,10 +42,25 @@ <script> import { parseUserFromToken } from "@/utils/token-utils"; import { PlusIcon, ChatAlt2Icon, UserCircleIcon } from "@heroicons/vue/outline"; +import ws from '@/services/ws'; export default { name: "NavBar.vue", - + data() { + return { + newMessages: 0, + } + }, + computed: { + notifications() { + // if new messages is greater than 99 show +99 + if (this.newMessages > 99) { + return '+99' + } else { + return this.newMessages + } + } + }, components: { PlusIcon, ChatAlt2Icon, @@ -61,8 +79,37 @@ export default { await this.$router.push("/login"); } }, + loadMessages() { + this.newMessages = 0; + this.$router.push('/messages'); + } }, + created() { + ws.on('NEW_MESSAGE', () => { + this.newMessages += 1; + }, "header"); + } }; </script> -<style scoped></style> +<style scoped> +.notification-container { + position: relative; +} +.notification { + position: absolute; + background-color: #ff5a5f; + top: 0; + min-width: 20px; + min-height: 20px; + padding: 0.25rem; + transform: translate(-80%, -30%); + color: white; + font-size: 10px; + border-radius: 50%; + font-weight: bold; + text-align: center; + right: 0; + cursor: pointer; +} +</style> diff --git a/src/components/ChatComponents/ChatsComponent.vue b/src/components/ChatComponents/ChatsComponent.vue index a297175de8644d7537c033c46a587b6a19d0bc94..c6d1b2e797b50ed1982cb9422c4134d1b0ec2130 100644 --- a/src/components/ChatComponents/ChatsComponent.vue +++ b/src/components/ChatComponents/ChatsComponent.vue @@ -84,10 +84,13 @@ export default { ws.on("NEW_MESSAGE", () => { this.reloadMessages(); - }); + }, "chats"); this.recipientID = (this.$route.query?.userID || null) if(!this.recipientID) this.hambugerDisplay = "block"; }, + unmounted() { + ws.end("NEW_MESSAGE", "chats"); + } }; </script> <style scoped> diff --git a/src/services/ws.js b/src/services/ws.js index b9adba0dd168d0e183dc6b151b95fff38d806ef4..4abaf87878bdcfbb948eee7190eabd39bc158264 100644 --- a/src/services/ws.js +++ b/src/services/ws.js @@ -6,11 +6,15 @@ import { parseCurrentUser } from "@/utils/token-utils"; // Events fired by websocket, MESSAGE const ws = (function () { // Object of all injected functions that the client may want + // These functions will be in a object const handlers = {}; const fire = function (event, data) { if (handlers[event]) { - handlers[event](data); + // for each object in object fire event + for(const key in handlers[event]) { + handlers[event][key](data); + } } }; @@ -42,16 +46,20 @@ const ws = (function () { stompClient.connect({}, onConnected, onError); return { - on: function (event, callback) { - handlers[event] = callback; + on: function (event, callback, id = "none") { + // Generate random id + if(!handlers[event]) { + handlers[event] = {} + }; + handlers[event][id] = callback; }, fire: fire, - isActive: function (event) { - return !!handlers[event]; + isActive: function (event, id = "none") { + return !!handlers[event]?.[id]; }, - end: function (event) { + end: function (event, id = "none") { if (handlers[event]) { - delete handlers[event]; + delete handlers[event][id]; } else { throw new Error("No handler for event: " + event); }