From 350eb489c22e6bac20de92284193a87af63c52a9 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Mon, 2 Nov 2020 15:46:49 +0200 Subject: add favicon badge for unread notifs --- src/boot/after_store.js | 3 ++ src/components/notifications/notifications.js | 3 ++ src/services/favicon_service/favicon_service.js | 56 +++++++++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 src/services/favicon_service/favicon_service.js (limited to 'src') diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 3cbbf020..b472fcf6 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -7,6 +7,7 @@ import { getOrCreateApp, getClientToken } from '../services/new_api/oauth.js' import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js' import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js' import { applyTheme } from '../services/style_setter/style_setter.js' +import FaviconService from '../services/favicon_service/favicon_service.js' let staticInitialResults = null @@ -326,6 +327,8 @@ const afterStoreSetup = async ({ store, i18n }) => { const width = windowWidth() store.dispatch('setMobileLayout', width <= 800) + FaviconService.initFaviconService() + const overrides = window.___pleromafe_dev_overrides || {} const server = (typeof overrides.target !== 'undefined') ? overrides.target : window.location.origin store.dispatch('setInstanceOption', { name: 'server', value: server }) diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 4b479e13..49258563 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -6,6 +6,7 @@ import { filteredNotificationsFromStore, unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils.js' +import FaviconService from '../../services/favicon_service/favicon_service.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faCircleNotch } from '@fortawesome/free-solid-svg-icons' @@ -75,8 +76,10 @@ const Notifications = { watch: { unseenCountTitle (count) { if (count > 0) { + FaviconService.drawFaviconBadge() this.$store.dispatch('setPageTitle', `(${count})`) } else { + FaviconService.clearFaviconBadge() this.$store.dispatch('setPageTitle', '') } } diff --git a/src/services/favicon_service/favicon_service.js b/src/services/favicon_service/favicon_service.js new file mode 100644 index 00000000..8e3f1170 --- /dev/null +++ b/src/services/favicon_service/favicon_service.js @@ -0,0 +1,56 @@ +import { find } from 'lodash' + +const createFaviconService = () => { + let favimg, favcanvas, favcontext, favicon + const faviconWidth = 48 + const faviconHeight = 48 + const strokeColor = 'rgb(200, 0, 0)' + const fillColor = 'rgb(255, 90, 90)' + const badgeRadius = 12 + + const initFaviconService = () => { + const nodes = document.getElementsByTagName('link') + favicon = find(nodes, node => node.rel === 'icon') + if (favicon) { + favcanvas = document.createElement('canvas') + favcanvas.width = faviconWidth + favcanvas.height = faviconHeight + favimg = new Image() + favimg.src = favicon.href + favcontext = favcanvas.getContext('2d') + } + } + + const clearFaviconBadge = () => { + if (!favimg || !favcontext || !favicon) return + + favcontext.clearRect(0, 0, faviconWidth, faviconHeight) + favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight) + favicon.href = favcanvas.toDataURL('image/png') + } + + const drawFaviconBadge = () => { + if (!favimg || !favcontext || !favcontext) return + + clearFaviconBadge() + + favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight) + favcontext.fillStyle = fillColor + favcontext.strokeStyle = strokeColor + favcontext.beginPath() + favcontext.arc(faviconWidth - badgeRadius, faviconHeight - badgeRadius, badgeRadius, 0, 2 * Math.PI, false) + favcontext.fill() + favcontext.stroke() + favicon.href = favcanvas.toDataURL('image/png') + } + + return { + initFaviconService, + clearFaviconBadge, + drawFaviconBadge + } +} + +const FaviconService = createFaviconService() + +export default FaviconService -- cgit v1.2.3-70-g09d2 From 1fa046126eb8a048440ff97be8febe3a8c6e6e58 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Mon, 2 Nov 2020 16:45:15 +0200 Subject: make badge just a ball, make it use theming --- src/services/favicon_service/favicon_service.js | 13 ++++++------- static/dev_favicon.png | Bin 7528 -> 13331 bytes static/favicon.png | Bin 0 -> 12920 bytes 3 files changed, 6 insertions(+), 7 deletions(-) create mode 100644 static/favicon.png (limited to 'src') diff --git a/src/services/favicon_service/favicon_service.js b/src/services/favicon_service/favicon_service.js index 8e3f1170..5fa8e5c3 100644 --- a/src/services/favicon_service/favicon_service.js +++ b/src/services/favicon_service/favicon_service.js @@ -4,9 +4,7 @@ const createFaviconService = () => { let favimg, favcanvas, favcontext, favicon const faviconWidth = 48 const faviconHeight = 48 - const strokeColor = 'rgb(200, 0, 0)' - const fillColor = 'rgb(255, 90, 90)' - const badgeRadius = 12 + const badgeRadius = 14 const initFaviconService = () => { const nodes = document.getElementsByTagName('link') @@ -34,13 +32,14 @@ const createFaviconService = () => { clearFaviconBadge() + const style = getComputedStyle(document.body) + const badgeColor = `${style.getPropertyValue('--badgeNotification') || 'rgb(240, 100, 100)'}` + favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight) - favcontext.fillStyle = fillColor - favcontext.strokeStyle = strokeColor + favcontext.fillStyle = badgeColor favcontext.beginPath() - favcontext.arc(faviconWidth - badgeRadius, faviconHeight - badgeRadius, badgeRadius, 0, 2 * Math.PI, false) + favcontext.arc(faviconWidth - badgeRadius, badgeRadius, badgeRadius, 0, 2 * Math.PI, false) favcontext.fill() - favcontext.stroke() favicon.href = favcanvas.toDataURL('image/png') } diff --git a/static/dev_favicon.png b/static/dev_favicon.png index 8b53d746..4223d5ca 100644 Binary files a/static/dev_favicon.png and b/static/dev_favicon.png differ diff --git a/static/favicon.png b/static/favicon.png new file mode 100644 index 00000000..d1206dc5 Binary files /dev/null and b/static/favicon.png differ -- cgit v1.2.3-70-g09d2 From 0206b2bcc5cceae937bdad1922c57f8c84621d26 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Tue, 3 Nov 2020 11:55:29 +0200 Subject: change favicon dimensions for high res, add handling when favicon isn't available --- src/services/favicon_service/favicon_service.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/services/favicon_service/favicon_service.js b/src/services/favicon_service/favicon_service.js index 5fa8e5c3..d1ddee41 100644 --- a/src/services/favicon_service/favicon_service.js +++ b/src/services/favicon_service/favicon_service.js @@ -2,9 +2,9 @@ import { find } from 'lodash' const createFaviconService = () => { let favimg, favcanvas, favcontext, favicon - const faviconWidth = 48 - const faviconHeight = 48 - const badgeRadius = 14 + const faviconWidth = 128 + const faviconHeight = 128 + const badgeRadius = 32 const initFaviconService = () => { const nodes = document.getElementsByTagName('link') @@ -19,11 +19,15 @@ const createFaviconService = () => { } } + const isImageLoaded = (img) => img.complete && img.naturalHeight !== 0 + const clearFaviconBadge = () => { if (!favimg || !favcontext || !favicon) return favcontext.clearRect(0, 0, faviconWidth, faviconHeight) - favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight) + if (isImageLoaded(favimg)) { + favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight) + } favicon.href = favcanvas.toDataURL('image/png') } @@ -35,7 +39,9 @@ const createFaviconService = () => { const style = getComputedStyle(document.body) const badgeColor = `${style.getPropertyValue('--badgeNotification') || 'rgb(240, 100, 100)'}` - favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight) + if (isImageLoaded(favimg)) { + favcontext.drawImage(favimg, 0, 0, favimg.width, favimg.height, 0, 0, faviconWidth, faviconHeight) + } favcontext.fillStyle = badgeColor favcontext.beginPath() favcontext.arc(faviconWidth - badgeRadius, badgeRadius, badgeRadius, 0, 2 * Math.PI, false) -- cgit v1.2.3-70-g09d2