diff --git a/site/index.html b/site/index.html index 0bd86b4..a49a708 100644 --- a/site/index.html +++ b/site/index.html @@ -3,6 +3,7 @@ Keppler +
diff --git a/site/src/components/application/script.js b/site/src/components/application/script.js index 432f47c..12bfdf4 100644 --- a/site/src/components/application/script.js +++ b/site/src/components/application/script.js @@ -1,6 +1,7 @@ import Connexion from '@/components/connexion' import ProjectsHub from '@/components/projects-hub' import Project from '@/components/project' +import Favicon from '@/components/favicon' export default { @@ -10,7 +11,8 @@ export default { Connexion, ProjectsHub, - Project + Project, + Favicon }, computed: diff --git a/site/src/components/application/template.html b/site/src/components/application/template.html index 6f34de3..973cba8 100644 --- a/site/src/components/application/template.html +++ b/site/src/components/application/template.html @@ -2,6 +2,9 @@ + + + diff --git a/site/src/components/chat/script.js b/site/src/components/chat/script.js index 92ab924..8225bc5 100644 --- a/site/src/components/chat/script.js +++ b/site/src/components/chat/script.js @@ -6,8 +6,7 @@ export default { return { userName: '', - messageText: '', - unreadCount: 0 + messageText: '' } }, @@ -36,6 +35,11 @@ export default scrollbarWidth() { return this.$store.state.scrollbarWidth + }, + + unreadCount() + { + return this.$store.state.chat.unreadCount } }, @@ -48,11 +52,6 @@ export default messages() { - if(!this.atBottom || !this.open) - { - this.unreadCount++ - } - window.requestAnimationFrame(() => { if(this.atBottom) @@ -107,12 +106,6 @@ export default onHeaderClick() { this.$store.commit('toggleChat') - - // Reset unread count - if(this.open) - { - this.unreadCount = 0 - } }, onUserNameChange() @@ -167,12 +160,6 @@ export default onMessagesScroll() { this.atBottom = this.$messages.scrollTop + this.$messages.offsetHeight >= this.$innerMessages.offsetHeight - 15 - - // Reset unread count - if(this.atBottom) - { - this.unreadCount = 0 - } }, onQuestionRemoveClick() @@ -204,7 +191,7 @@ export default scrollToBottom() { - this.$messages.scrollTop = this.$innerMessages.offsetHeight - this.$messages.offsetHeight + 10 + this.$messages.scrollTop = this.$innerMessages.offsetHeight - this.$messages.offsetHeight + 15 }, formatMinutes(time) diff --git a/site/src/components/favicon/index.vue b/site/src/components/favicon/index.vue new file mode 100644 index 0000000..246515d --- /dev/null +++ b/site/src/components/favicon/index.vue @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/site/src/components/favicon/script.js b/site/src/components/favicon/script.js new file mode 100644 index 0000000..bc99bbf --- /dev/null +++ b/site/src/components/favicon/script.js @@ -0,0 +1,85 @@ +export default +{ + name: 'favicon', + + computed: + { + + chatUnreadCount() + { + return this.$store.state.chat.unreadCount + } + }, + + watch: + { + chatUnreadCount: 'onChatUnreadCountChange' + }, + + created() + { + this.$favicon = document.querySelector('.favicon') + + this.size = 16 * window.devicePixelRatio + this.notifSize = 0.2 + + this.canvas = document.createElement('canvas') + this.canvas.width = this.size + this.canvas.height = this.size + + this.context = this.canvas.getContext('2d') + + this.image = new Image() + + this.image.addEventListener('load', () => + { + this.updateFavicon() + }) + + this.image.src = require('../../../static/images/favicon-32x32.png') + }, + + methods: + { + onChatUnreadCountChange() + { + this.updateFavicon() + }, + + updateFavicon() + { + // Clear + this.context.clearRect(0, 0, this.size, this.size) + + // Draw image + this.context.drawImage(this.image, 0, 0, this.size, this.size) + + // // Draw file notif + // this.context.beginPath() + // this.context.arc(this.size * (1 - this.notifSize), this.size * (1 - this.notifSize), this.size * this.notifSize, 0, Math.PI * 2) + + // this.context.fillStyle = '#9B52F5' + // this.context.fill() + + // this.context.strokeStyle = '#360079' + // this.context.stroke() + + // Draw chat notif + if(this.chatUnreadCount > 0) + { + this.context.beginPath() + this.context.arc(this.size * (1 - this.notifSize), this.size * (1 - this.notifSize), this.size * this.notifSize, 0, Math.PI * 2) + // this.context.arc(this.size * (1 - this.notifSize * 2.25), this.size * (1 - this.notifSize), this.size * this.notifSize, 0, Math.PI * 2) + + this.context.fillStyle = '#ff763d' + this.context.fill() + + this.context.strokeStyle = '#ad1d3c' + this.context.stroke() + } + + // Add to DOM + this.$favicon.setAttribute('href', this.canvas.toDataURL()) + } + } +} \ No newline at end of file diff --git a/site/src/components/favicon/style.styl b/site/src/components/favicon/style.styl new file mode 100644 index 0000000..e69de29 diff --git a/site/src/components/favicon/template.html b/site/src/components/favicon/template.html new file mode 100644 index 0000000..094418b --- /dev/null +++ b/site/src/components/favicon/template.html @@ -0,0 +1,2 @@ +
+
\ No newline at end of file diff --git a/site/src/store/modules/chat.js b/site/src/store/modules/chat.js index 6acae63..ec40f9a 100644 --- a/site/src/store/modules/chat.js +++ b/site/src/store/modules/chat.js @@ -7,7 +7,8 @@ export default { messages: [], pendingMessage: null, pendingAlert: null, - question: null + question: null, + unreadCount: 0 }, mutations: @@ -16,6 +17,13 @@ export default { { state.messages.push(data) + // Add to unread count if not open or document is hidden (tab not active) + if(!state.open || document.hidden) + { + state.unreadCount++ + } + + // Clamp if(state.messages.length > 100) { state.messages.splice(0, state.messages.length - 100) @@ -50,6 +58,7 @@ export default { openChat(state) { + state.unreadCount = 0 state.open = true }, @@ -60,6 +69,7 @@ export default { toggleChat(state) { + state.unreadCount = 0 state.open = !state.open } } diff --git a/site/static/images/favicon-32x32.png b/site/static/images/favicon-32x32.png new file mode 100644 index 0000000..7adffd0 Binary files /dev/null and b/site/static/images/favicon-32x32.png differ