import axios from 'axios'; import * as log from 'loglevel'; import { useContext, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { MiniAppContext } from '../context/miniAppContext'; import { MiniAppAPI } from '../model/miniAppApi'; import { MiniAppErrorType } from '../model/miniAppError'; import { checkPermission, PermissionName, PermissionStatus, } from '../model/permission'; import msgHandler from '../utils/iframe/messageHandler'; import mock, { unmockable } from '../utils/mock'; import useHelper from './bridge/useHelper'; import usePayPay from './bridge/usePayPay'; import usePermission from './bridge/usePermission'; import useRouter from './useRouter'; import GetPushToken from '../model/bridge/getPushToken'; import GetUAID from '../model/bridge/getUAID'; import GetBatteryLevel from '../model/bridge/getBatteryLevel'; import GetUserLocation from '../model/bridge/getUserLocation'; import GetPermissionStatus from '../model/bridge/getPermissionStatus'; import GetStorageData from '../model/bridge/getStorageData'; import GetSessionData from '../model/bridge/getSessionData'; import RemoveStorageData from '../model/bridge/removeStorageData'; import SetSessionData from '../model/bridge/setSessionData'; import SetStorageData from '../model/bridge/setStorageData'; import CheckBiometricAuthenticationAvailability from '../model/bridge/checkBiometricAuthenticationAvailability'; import GetDeviceInformation from '../model/bridge/getDeviceInformation'; import GetKycInformation from '../model/bridge/getKycInformation'; import GetCompassInfo from '../model/bridge/getCompassInfo'; import SetScreenBrightness from '../model/bridge/setScreenBrightness'; import GetIpAddress from '../model/bridge/getIpAddress'; import CheckAppInstall from '../model/bridge/checkAppInstall'; import OpenAppSettings from '../model/bridge/openAppSettings'; import Present from '../model/bridge/present'; import GenerateCodeImage from '../model/bridge/generateCodeImage'; import GetAppLaunchOptions from '../model/bridge/getAppLaunchOptions'; import GetBalance from '../model/bridge/getBalance'; import GetUserProfile from '../model/bridge/getUserProfile'; import PageWillAppear from '../model/bridge/pageWillAppear'; import PageWillDisappear from '../model/bridge/pageWillDisappear'; import PaypayWillEnterBackground from '../model/bridge/paypayWillEnterBackground'; import PaypayWillEnterForeground from '../model/bridge/paypayWillEnterForeground'; import RequestInternal from '../model/bridge/requestInternal'; import Request from '../model/bridge/request'; import LoadNotificationStatus from '../model/bridge/loadNotificationStatus'; import { getNotificationStatus } from '../factory/api'; import DownloadFile from '../model/bridge/downloadFile'; import GetSavedFileList from '../model/bridge/getSavedFileList'; import RemoveSavedFile from '../model/bridge/removeSavedFile'; function useJsbridge(inputFile: any) { const { state } = useContext(MiniAppContext); const { t } = useTranslation(); const { navigationStack, navigateTo, navigateBack, backButtonTap, backButtonDidTap, popAll, redirectTo, navigateToRemote, switchTab, navigationHelper, displayBackButton, openWebview, webviewProps, } = useRouter(); const { navbgColor, setNavigationBarBackgroundColor, pageBackgroundColor, setPageBackgroundColor, navTitle, setNavBarTitle, navBarTextColor, setNavBarTextStyle, setEnablePullDownRefresh, alertParams, setAlertParams, updateParams, setUpdateWarning, actionSheetParams, setActionSheet, generateMapOptions, navBarHeight, setNavBarHeight, getTopBarHeight, detectShakeMotion, setNavigationStyle, ionAlertParams, setIonAlert, startBiometricAuthentication, showTabsParams, setShowTabsVisibility, hasRefresh, setHasRefresh, } = useHelper(); const { makePayment, checkoutProps, topup, topupProps } = usePayPay(); const { photoParams, takePhoto, requestPermission, requestPermissionProps, } = usePermission(); useEffect(() => { const getMockJson = async () => { try { const res = await axios.get(`/workspace/mock.json`); return res.data; } catch (error) { return null; } }; const receiveMessageFromIndex = async (event: any) => { if ( event !== undefined && typeof event.data === 'string' && event.data.length > 0 ) { let data: any; try { data = JSON.parse(event.data); log.debug(`Received: ${event.data}`); } catch (error) { log.error(`Request failed: ${JSON.stringify(error)}`); return; } const mockData = await getMockJson(); if (data.payload && mockData && !unmockable.has(data.event)) { data.payload.mock = data.payload.mock ? data.payload.mock : mockData[data.event]; } if (data.payload?.mock && !unmockable.has(data.event)) { log.info(`Mock: ${JSON.stringify(data.payload.mock)}`); mock(data.payload); return; } switch (data.event) { case MiniAppAPI.getPushToken: { return new GetPushToken().execute(data.payload); } case MiniAppAPI.getUAID: { return new GetUAID().execute(data.payload); } case MiniAppAPI.getBatteryLevel: { return new GetBatteryLevel().execute(data.payload); } case MiniAppAPI.getUserLocation: { return new GetUserLocation().execute(data.payload); } case MiniAppAPI.getPermissionStatus: { return new GetPermissionStatus().execute(data.payload); } case MiniAppAPI.getStorageData: { return new GetStorageData().execute(data.payload); } case MiniAppAPI.getSessionData: { return new GetSessionData().execute(data.payload); } case MiniAppAPI.removeStorageData: { return new RemoveStorageData().execute(data.payload); } case MiniAppAPI.setSessionData: { return new SetSessionData().execute(data.payload); } case MiniAppAPI.setStorageData: { return new SetStorageData().execute(data.payload); } case MiniAppAPI.closeApp: { return () => window.location.reload(); } case MiniAppAPI.checkBiometricAuthenticationAvailability: { return new CheckBiometricAuthenticationAvailability().execute( data.payload ); } case MiniAppAPI.getDeviceInformation: { return new GetDeviceInformation().execute(data.payload); } case MiniAppAPI.getKycInformation: { return new GetKycInformation().execute(data.payload); } case MiniAppAPI.getCompassInfo: { return new GetCompassInfo().execute(data.payload); } case MiniAppAPI.setScreenBrightness: { return new SetScreenBrightness().execute(data.payload); } case MiniAppAPI.getIpAddress: { return new GetIpAddress().execute(data.payload); } case MiniAppAPI.checkAppInstall: { return new CheckAppInstall().execute(data.payload); } case MiniAppAPI.openAppSettings: { return new OpenAppSettings().execute(data.payload); } case MiniAppAPI.present: { return new Present().execute(data.payload); } case MiniAppAPI.generateCodeImage: { return new GenerateCodeImage().execute(data.payload); } case MiniAppAPI.getAppLaunchOptions: { return new GetAppLaunchOptions().execute(data.payload); } case MiniAppAPI.getBalance: { return new GetBalance().execute(data.payload); } case MiniAppAPI.getUserProfile: { return new GetUserProfile().execute(data.payload); } case MiniAppAPI.downloadFile: { return new DownloadFile().execute( data.payload, state.whiteListDomains ); } case MiniAppAPI.getSavedFileList: { return new GetSavedFileList().execute(data.payload); } case MiniAppAPI.removeSavedFile: { return new RemoveSavedFile().execute(data.payload); } case MiniAppAPI.loadNotificationStatus: { try { getNotificationStatus().then((res: any) => { setHasRefresh(res?.data?.unsigned?.data?.hasRefresh); return new LoadNotificationStatus().execute( data.payload, hasRefresh ); }); } catch {} break; } case MiniAppAPI.pageWillAppear: { return new PageWillAppear().execute( data.payload, navigationHelper.activeView() ); } case MiniAppAPI.pageWillDisappear: { return new PageWillDisappear().execute( data.payload, navigationHelper.activeView() ); } case MiniAppAPI.paypayWillEnterForeground: { return new PaypayWillEnterForeground().execute( data.payload, navigationHelper.activeView() ); } case MiniAppAPI.paypayWillEnterBackground: { return new PaypayWillEnterBackground().execute( data.payload, navigationHelper.activeView() ); } case MiniAppAPI.requestInternal: { return new RequestInternal().execute(data.payload); } case MiniAppAPI.request: { return new Request().execute(data.payload, state.whiteListDomains); } } let suppressCompleteCB = false; const actions = new Map([ [MiniAppAPI.navigateTo, () => navigateTo(data.payload)], [MiniAppAPI.navigateBack, () => navigateBack()], [ MiniAppAPI.backButtonDidTap, () => { backButtonDidTap(navigationHelper.activeView(), data.payload); suppressCompleteCB = true; }, ], [MiniAppAPI.popAll, () => popAll()], [MiniAppAPI.redirectTo, () => redirectTo(data.payload)], [MiniAppAPI.navigateToRemote, () => navigateToRemote(data.payload)], [MiniAppAPI.switchTab, () => switchTab(data.payload)], [ MiniAppAPI.setNavigationStyle, () => { setNavigationStyle(data.payload); suppressCompleteCB = true; }, ], [ MiniAppAPI.setEnablePullDownRefresh, () => setEnablePullDownRefresh(data.payload), ], [ MiniAppAPI.startBiometricAuthentication, () => { startBiometricAuthentication(data.payload); suppressCompleteCB = true; }, ], [ MiniAppAPI.showUpdateWarning, () => { setUpdateWarning({ ...data.payload, visible: true, }); suppressCompleteCB = true; }, ], [ MiniAppAPI.showAlert, () => { setIonAlert({ ...data.payload, button: [ { text: data?.payload?.buttonTitle ?? 'OK', handler: () => { msgHandler( data?.payload?.originId, data?.payload?.completeCB ); }, }, ], showAlert: true, }); suppressCompleteCB = true; }, ], [ 'showMenusheet', () => { setAlertParams({ ...data.payload, buttonTitle: data?.payload?.buttonTitle ?? 'OK', alertBoxName: 'showMenusheet', showAlert: true, }); suppressCompleteCB = true; }, ], [ MiniAppAPI.openMap, () => { setActionSheet( data?.payload, generateMapOptions(data?.payload), 'マップで開く' ); suppressCompleteCB = true; }, ], [ MiniAppAPI.showErrorSheet, () => { setAlertParams({ ...data.payload, alertBoxName: 'showErrorSheet', showAlert: true, }); suppressCompleteCB = true; }, ], [ MiniAppAPI.openApp, () => { setAlertParams({ ...data.payload, alertBoxName: 'openApp', buttonTitle: t('openApp.confirm'), showAlert: true, }); suppressCompleteCB = true; }, ], [MiniAppAPI.setTitle, () => setNavBarTitle(data.payload)], [ MiniAppAPI.setBackgroundColor, () => setPageBackgroundColor(data.payload), ], [ MiniAppAPI.setNavigationBarBackgroundColor, () => setNavigationBarBackgroundColor(data.payload), ], [MiniAppAPI.getTopBarHeight, () => getTopBarHeight(data.payload)], [ MiniAppAPI.setNavigationBarTextStyle, () => setNavBarTextStyle(data.payload), ], /* Deeplink & Share */ [MiniAppAPI.openWebview, () => openWebview(data.payload)], /* PayPay */ [ MiniAppAPI.topup, () => { topup(data.payload); suppressCompleteCB = true; }, ], /* Transaction namespace */ [ MiniAppAPI.scanCode, () => { setAlertParams({ ...data.payload, text: '', buttonTitle: 'OK', alertBoxName: 'scanCode', showAlert: true, }); suppressCompleteCB = true; }, ], [ MiniAppAPI.makePayment, () => { makePayment(data.payload); suppressCompleteCB = true; }, ], /* Permission */ [ MiniAppAPI.requestPermission, () => { requestPermission(data.payload); suppressCompleteCB = true; }, ], [ MiniAppAPI.detectShakeMotion, () => { detectShakeMotion(navigationHelper.activeView(), data.payload); suppressCompleteCB = true; }, ], [ MiniAppAPI.takePhoto, () => { inputFile.current.click(); takePhoto(data.payload); suppressCompleteCB = true; }, ], [ MiniAppAPI.setTabBarVisibility, () => { setShowTabsVisibility(data?.payload); }, ], // [MiniAppAPI.log, () => console.log(data?.payload?.message)], [ MiniAppAPI.share, () => { setAlertParams({ ...data.payload, buttonTitle: t('button.close'), alertBoxName: 'share', showAlert: true, }); }, ], [ MiniAppAPI.getContactList, async () => { const grantStatus = await checkPermission( PermissionName.mini_app_user_contacts ); if (grantStatus !== PermissionStatus.granted) { msgHandler(data.payload?.originId, data.payload?.failCB, { errorCode: MiniAppErrorType.insufficientScope, }); return; } setAlertParams({ ...data.payload, alertBoxName: 'getContactList', buttonTitle: t('button.allow'), showAlert: true, }); suppressCompleteCB = true; }, ], [ 'default', () => { suppressCompleteCB = true; }, ], ]); const action = actions.get(data.event) || actions.get('default'); await action?.call(null); if (!suppressCompleteCB) { msgHandler(data?.payload?.originId, data?.payload?.completeCB); } } }; window.addEventListener('message', receiveMessageFromIndex, false); return () => window.removeEventListener('message', receiveMessageFromIndex); }); return { navigationStack, navbgColor, pageBackgroundColor, navTitle, navBarTextColor, alertParams, navBarHeight, setNavBarHeight, photoParams, setAlertParams, navigationHelper, backButtonTap, checkoutProps, topupProps, updateParams, setUpdateWarning, actionSheetParams, setActionSheet, requestPermissionProps, ionAlertParams, setIonAlert, displayBackButton, webviewProps, showTabsParams, hasRefresh, setHasRefresh, }; } export default useJsbridge;