Newer
Older
mobile.raikyakun.app / node / src / utils / ios.ts
nutrition 14 hours ago 1 KB 利便性向上
// ネイティブ呼び出しを Promise でラップ
let resolverMap = new Map<string, (r: NotificationResult) => void>()

function callNative(handlerName: string): Promise<NotificationResult> {
	return new Promise((resolve, reject) => {
		if (
			typeof window === 'undefined' ||
			!window.webkit?.messageHandlers?.[handlerName]
		) {
			return reject(new Error('native handler not found'))
		}

		// 一意 ID を生成して resolver に登録
		const id = Date.now().toString(36) + Math.random().toString(36).slice(2)
		resolverMap.set(id, resolve)

		// コールバック受信口を一度だけ定義
		if (!window.__nativeCallback) {
			window.__nativeCallback = (res) => {
				const { id } = res
				if (id && resolverMap.has(id)) {
					resolverMap.get(id)!(res)
					resolverMap.delete(id)
				}
			}
		}

		// ネイティブへ送信
		window.webkit!.messageHandlers[handlerName].postMessage(id)
	})
}

export const checkNotificationStatus = () =>
	callNative('checkNotificationStatus')

export const requestNotificationPermission = () =>
	callNative('requestNotificationPermission')