11import type { NotificationClickEvent } from '/@/types/InlineNotificationReplies'
22import apis from '/@/lib/apis'
33import router from '/@/router'
4- import { isIOSApp } from '/@/lib/dom/browser'
4+ import { isIOSApp , isPWA , isWebKit } from '/@/lib/dom/browser'
55import type { ChannelId , DMChannelId } from '/@/types/entity-ids'
66import { createNotificationArgumentsCreator } from './notificationArguments'
77import type { OnCanUpdate } from './updateToast'
88import { setupUpdateToast } from './updateToast'
99import type { FirebasePayloadData } from './firebase'
1010import { setupFirebaseApp , getFirebaseApp } from './firebase'
11- import { requestNotificationPermission } from './requestPermission'
1211import {
1312 getMessaging ,
1413 onMessage ,
1514 getToken as getTokenFb ,
1615 deleteToken as deleteTokenFb
1716} from 'firebase/messaging'
1817import { wait } from '/@/lib/basic/timer'
18+ import { useToastStore } from '/@/store/ui/toast'
1919
2020const appName = window . traQConfig . name || 'traQ'
2121const ignoredChannels = window . traQConfig . inlineReplyDisableChannels ?? [ ]
@@ -48,7 +48,7 @@ const notify = async (
4848 return regist . showNotification ( notificationTitle , notificationOptions )
4949 }
5050 }
51- if ( window . Notification ?. permission === 'granted' ) {
51+ if ( Notification ?. permission === 'granted' ) {
5252 return new Notification ( notificationTitle , notificationOptions )
5353 }
5454 return null
@@ -63,10 +63,30 @@ export const connectFirebase = async (onCanUpdate: OnCanUpdate) => {
6363 }
6464 }
6565
66- if ( window . Notification ) {
66+ if ( Notification ) {
6767 if ( Notification . permission === 'default' ) {
68- // 上でNotificationが存在していることを確認している
69- const permission = await requestNotificationPermission ( )
68+ // 上で Notification が存在していることを確認している
69+ const permission = await ( ( ) => {
70+ // WebKit ではユーザージェスチャーを起点としたポップアップのみ許可される
71+ if ( isWebKit ( ) && isPWA ( ) ) {
72+ const { addToast, deleteToast } = useToastStore ( )
73+
74+ return new Promise < NotificationPermission > ( ( resolve , reject ) => {
75+ addToast ( {
76+ type : 'info' ,
77+ text : '【通知を有効にしてください】\nメッセージ受信時に通知が届くようになります。(クリックで許可)' ,
78+ timeout : Infinity ,
79+ onClick : id => {
80+ deleteToast ( id )
81+ Notification . requestPermission ( ) . then ( resolve ) . catch ( reject )
82+ }
83+ } )
84+ } )
85+ } else {
86+ return Notification . requestPermission ( )
87+ }
88+ } ) ( )
89+
7090 if ( permission === 'granted' ) {
7191 notify ( { title : `ようこそ${ appName } へ!!` } , true )
7292 } else {
@@ -102,9 +122,9 @@ export const connectFirebase = async (onCanUpdate: OnCanUpdate) => {
102122
103123 setupUpdateToast ( registration , onCanUpdate )
104124
105- if ( window . Notification ?. permission !== 'granted' ) {
125+ if ( Notification ?. permission !== 'granted' ) {
106126 // eslint-disable-next-line no-console
107- console . warn ( `[Notification] permission ${ window . Notification ?. permission } ` )
127+ console . warn ( `[Notification] permission ${ Notification ?. permission } ` )
108128 return
109129 }
110130 if ( ! firebaseApp ) {
@@ -162,7 +182,7 @@ export const connectFirebase = async (onCanUpdate: OnCanUpdate) => {
162182}
163183
164184export const deleteToken = ( ) => {
165- if ( window . Notification ?. permission !== 'granted' ) return
185+ if ( Notification ?. permission !== 'granted' ) return
166186
167187 const firebaseApp = getFirebaseApp ( )
168188 const messaging = getMessaging ( firebaseApp )
0 commit comments