add favicon badge for unread notifs

This commit is contained in:
Shpuld Shpuldson 2020-11-02 15:46:49 +02:00
parent f0a66448ee
commit 350eb489c2
6 changed files with 64 additions and 1 deletions

View file

@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Import/export a muted users - Import/export a muted users
- Proper handling of deletes when using websocket streaming - Proper handling of deletes when using websocket streaming
- Added optimistic chat message sending, so you can start writing next message before the previous one has been sent - Added optimistic chat message sending, so you can start writing next message before the previous one has been sent
- Added a small red badge to the favicon when there's unread notifications
### Fixed ### Fixed
- Fixed chats list not updating its order when new messages come in - Fixed chats list not updating its order when new messages come in

View file

@ -5,7 +5,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no"> <meta name="viewport" content="width=device-width, initial-scale=1,user-scalable=no">
<title>Pleroma</title> <title>Pleroma</title>
<!--server-generated-meta--> <!--server-generated-meta-->
<link rel="icon" type="image/png" href="/favicon.png"> <link rel="icon" type="image/png" href="/static/dev_favicon.png">
</head> </head>
<body class="hidden"> <body class="hidden">
<noscript>To use Pleroma, please enable JavaScript.</noscript> <noscript>To use Pleroma, please enable JavaScript.</noscript>

View file

@ -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 backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js' import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js'
import { applyTheme } from '../services/style_setter/style_setter.js' import { applyTheme } from '../services/style_setter/style_setter.js'
import FaviconService from '../services/favicon_service/favicon_service.js'
let staticInitialResults = null let staticInitialResults = null
@ -326,6 +327,8 @@ const afterStoreSetup = async ({ store, i18n }) => {
const width = windowWidth() const width = windowWidth()
store.dispatch('setMobileLayout', width <= 800) store.dispatch('setMobileLayout', width <= 800)
FaviconService.initFaviconService()
const overrides = window.___pleromafe_dev_overrides || {} const overrides = window.___pleromafe_dev_overrides || {}
const server = (typeof overrides.target !== 'undefined') ? overrides.target : window.location.origin const server = (typeof overrides.target !== 'undefined') ? overrides.target : window.location.origin
store.dispatch('setInstanceOption', { name: 'server', value: server }) store.dispatch('setInstanceOption', { name: 'server', value: server })

View file

@ -6,6 +6,7 @@ import {
filteredNotificationsFromStore, filteredNotificationsFromStore,
unseenNotificationsFromStore unseenNotificationsFromStore
} from '../../services/notification_utils/notification_utils.js' } from '../../services/notification_utils/notification_utils.js'
import FaviconService from '../../services/favicon_service/favicon_service.js'
import { library } from '@fortawesome/fontawesome-svg-core' import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons' import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
@ -75,8 +76,10 @@ const Notifications = {
watch: { watch: {
unseenCountTitle (count) { unseenCountTitle (count) {
if (count > 0) { if (count > 0) {
FaviconService.drawFaviconBadge()
this.$store.dispatch('setPageTitle', `(${count})`) this.$store.dispatch('setPageTitle', `(${count})`)
} else { } else {
FaviconService.clearFaviconBadge()
this.$store.dispatch('setPageTitle', '') this.$store.dispatch('setPageTitle', '')
} }
} }

View file

@ -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

BIN
static/dev_favicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB