123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- /* eslint-disable lines-around-comment */
- import { Theme } from '@mui/material';
- import React, { useCallback, useEffect, useMemo } from 'react';
- import { WithTranslation } from 'react-i18next';
- import { useDispatch, useSelector } from 'react-redux';
- import { makeStyles } from 'tss-react/mui';
-
- import { createDeepLinkingPageEvent } from '../../analytics/AnalyticsEvents';
- import { sendAnalytics } from '../../analytics/functions';
- import { IReduxState } from '../../app/types';
- import { IDeeplinkingConfig, IDeeplinkingMobileConfig } from '../../base/config/configType';
- import { isSupportedMobileBrowser } from '../../base/environment/environment';
- import { translate } from '../../base/i18n/functions';
- import Platform from '../../base/react/Platform.web';
- import { withPixelLineHeight } from '../../base/styles/functions.web';
- import Button from '../../base/ui/components/web/Button';
- import DialInSummary from '../../invite/components/dial-in-summary/web/DialInSummary';
- import { openWebApp } from '../actions';
- import { _TNS } from '../constants';
- import { generateDeepLinkingURL } from '../functions';
-
-
- const PADDINGS = {
- topBottom: 24,
- leftRight: 40
- };
-
- const useStyles = makeStyles()((theme: Theme) => {
- return {
- container: {
- background: '#1E1E1E',
- width: '100vw',
- height: '100vh',
- overflowX: 'hidden',
- overflowY: 'auto',
- justifyContent: 'center',
- display: 'flex',
- '& a': {
- textDecoration: 'none'
- }
- },
- contentPane: {
- display: 'flex',
- alignItems: 'center',
- flexDirection: 'column',
- padding: `${PADDINGS.topBottom}px ${PADDINGS.leftRight}px`,
- maxWidth: 410,
- color: theme.palette.text01
- },
- launchingMeetingLabel: {
- marginTop: 24,
- textAlign: 'center',
- marginBottom: 32,
- ...withPixelLineHeight(theme.typography.heading5)
- },
- roomNameLabel: {
- ...withPixelLineHeight(theme.typography.bodyLongRegularLarge)
- },
- joinMeetWrapper: {
- marginTop: 24,
- width: '100%'
- },
- labelDescription: {
- textAlign: 'center',
- marginTop: 16,
- ...withPixelLineHeight(theme.typography.bodyShortRegularLarge)
- },
- linkWrapper: {
- display: 'flex',
- justifyContent: 'center',
- alignItems: 'center',
- marginTop: 8,
- width: '100%'
- },
- linkLabel: {
- color: theme.palette.link01,
- ...withPixelLineHeight(theme.typography.bodyLongBoldLarge)
- },
- supportedBrowserContent: {
- marginTop: 16,
- display: 'flex',
- flexDirection: 'column',
- alignItems: 'center',
- justifyContent: 'center'
- },
- labelOr: {
- ...withPixelLineHeight(theme.typography.bodyShortRegularLarge)
- },
- separator: {
- marginTop: '32px',
- height: 1,
- width: `calc(100% + ${2 * PADDINGS.leftRight}px)`,
- background: theme.palette.ui03
- }
- };
- });
-
- const DeepLinkingMobilePage: React.FC<WithTranslation> = ({ t }) => {
- const deeplinkingCfg = useSelector((state: IReduxState) =>
- state['features/base/config']?.deeplinking || {} as IDeeplinkingConfig);
- const { hideLogo } = deeplinkingCfg;
- const deepLinkingUrl: string = useSelector(generateDeepLinkingURL);
- const room = useSelector((state: IReduxState) => decodeURIComponent(state['features/base/conference'].room || ''));
- const url = useSelector((state: IReduxState) => state['features/base/connection'] || {});
- const dispatch = useDispatch();
- const { classes: styles } = useStyles();
-
- const generateDownloadURL = useCallback(() => {
- const { downloadLink, dynamicLink, appScheme }
- = (deeplinkingCfg?.[Platform.OS as keyof typeof deeplinkingCfg] || {}) as IDeeplinkingMobileConfig;
-
- if (downloadLink && typeof dynamicLink === 'undefined') {
- return downloadLink;
- }
-
- const {
- apn,
- appCode,
- customDomain,
- ibi,
- isi
- } = dynamicLink || {};
-
- const domain = customDomain ?? `https://${appCode}.app.goo.gl`;
-
- return `${domain}/?link=${
- encodeURIComponent(window.location.href)}&apn=${
- apn}&ibi=${
- ibi}&isi=${
- isi}&ius=${
- appScheme}&efr=1`;
- }, [ deeplinkingCfg ]);
-
- const onDownloadApp = useCallback(() => {
- sendAnalytics(
- createDeepLinkingPageEvent(
- 'clicked', 'downloadAppButton', { isMobileBrowser: true }));
- }, []);
-
- const onLaunchWeb = useCallback(() => {
- sendAnalytics(
- createDeepLinkingPageEvent(
- 'clicked', 'launchWebButton', { isMobileBrowser: true }));
- dispatch(openWebApp());
- }, []);
-
- const onOpenApp = useCallback(() => {
- sendAnalytics(
- createDeepLinkingPageEvent(
- 'clicked', 'openAppButton', { isMobileBrowser: true }));
- }, []);
-
- const onOpenLinkProperties = useMemo(() => {
- const { downloadLink }
- = (deeplinkingCfg?.[Platform.OS as keyof typeof deeplinkingCfg] || {}) as IDeeplinkingMobileConfig;
-
- if (downloadLink) {
- return {
- // When opening a link to the download page, we want to let the
- // OS itself handle intercepting and opening the appropriate
- // app store. This avoids potential issues with browsers, such
- // as iOS Chrome, not opening the store properly.
- };
- }
-
- return {
- // When falling back to another URL (Firebase) let the page be
- // opened in a new window. This helps prevent the user getting
- // trapped in an app-open-cycle where going back to the mobile
- // browser re-triggers the app-open behavior.
- target: '_blank',
- rel: 'noopener noreferrer'
- };
- }, [ deeplinkingCfg ]);
-
- useEffect(() => {
- sendAnalytics(
- createDeepLinkingPageEvent(
- 'displayed', 'DeepLinkingMobile', { isMobileBrowser: true }));
- }, []);
-
-
- return (
- <div className = { styles.container }>
- <div className = { styles.contentPane }>
- {!hideLogo && (<img
- alt = { t('welcomepage.logo.logoDeepLinking') }
- src = 'images/logo-deep-linking-mobile.png' />
- )}
-
- <div className = { styles.launchingMeetingLabel }>{ t(`${_TNS}.launchMeetingLabel`) }</div>
- <div className = ''>{room}</div>
- <a
- { ...onOpenLinkProperties }
- className = { styles.joinMeetWrapper }
- href = { deepLinkingUrl }
- onClick = { onOpenApp }
- target = '_top'>
- <Button
- fullWidth = { true }
- label = { t(`${_TNS}.joinInAppNew`) } />
- </a>
- <div className = { styles.labelDescription }>{ t(`${_TNS}.noMobileApp`) }</div>
- <a
- { ...onOpenLinkProperties }
- className = { styles.linkWrapper }
- href = { generateDownloadURL() }
- onClick = { onDownloadApp }
- target = '_top'>
- <div className = { styles.linkLabel }>{ t(`${_TNS}.downloadMobileApp`) }</div>
- </a>
- {isSupportedMobileBrowser() ? (
- <div className = { styles.supportedBrowserContent }>
- <div className = { styles.labelOr }>OR</div>
- <a
- className = { styles.linkWrapper }
- onClick = { onLaunchWeb }
- target = '_top'>
- <div className = { styles.linkLabel }>{ t(`${_TNS}.joinInBrowser`) }</div>
- </a>
- </div>
- ) : (
- <div className = { styles.labelDescription }>
- {t(`${_TNS}.unsupportedBrowser`)}
- </div>
- )}
- <div className = { styles.separator } />
- <DialInSummary
- className = 'deep-linking-dial-in'
- clickableNumbers = { true }
- room = { room }
- url = { url } />
- </div>
- </div>
- );
- };
-
- export default translate(DeepLinkingMobilePage);
|