Deeplinking (#2760)
* feat(Deeplinking): Implement for web. * ref(unsupported_browser): Move the mobile version to deeplinking feature * feat(deeplinking_mobile): Redesign. * fix(deeplinking): Use interface.NATIVE_APP_NAME. * feat(dial_in_summary): Add the PIN to the number link. * fix(deep_linking): Handle use case when there isn't deep linking image. * fix(deep_linking): css * fix(deep_linking): deeplink -> "deep linking" * fix(deeplinking_css): Remove position: fixed * docs(deeplinking): Add comment for the openWebApp action.
This commit is contained in:
committed by
virtuacoplenny
parent
fd44721bac
commit
eb19f94598
@@ -1,16 +0,0 @@
|
||||
/**
|
||||
* The type of the Redux action which signals that the React Component
|
||||
* UnsupportedMobileBrowser which was rendered as a promotion of the mobile app
|
||||
* on a browser was dismissed by the user. For example, the Web app may possibly
|
||||
* run in Google Chrome on Android but we choose to promote the mobile app
|
||||
* anyway claiming the user experience provided by the Web app is inferior to
|
||||
* that of the mobile app. Eventually, the user may choose to dismiss the
|
||||
* promotion of the mobile app and take their chances with the Web app instead.
|
||||
* If unused, then we have chosen to force the mobile app and not allow the Web
|
||||
* app in mobile browsers.
|
||||
*
|
||||
* {
|
||||
* type: DISMISS_MOBILE_APP_PROMO
|
||||
* }
|
||||
*/
|
||||
export const DISMISS_MOBILE_APP_PROMO = Symbol('DISMISS_MOBILE_APP_PROMO');
|
||||
@@ -1,21 +0,0 @@
|
||||
import { DISMISS_MOBILE_APP_PROMO } from './actionTypes';
|
||||
|
||||
/**
|
||||
* Returns a Redux action which signals that the UnsupportedMobileBrowser which
|
||||
* was rendered as a promotion of the mobile app on a browser was dismissed by
|
||||
* the user. For example, the Web app may possibly run in Google Chrome
|
||||
* on Android but we choose to promote the mobile app anyway claiming the user
|
||||
* experience provided by the Web app is inferior to that of the mobile app.
|
||||
* Eventually, the user may choose to dismiss the promotion of the mobile app
|
||||
* and take their chances with the Web app instead. If unused, then we have
|
||||
* chosen to force the mobile app and not allow the Web app in mobile browsers.
|
||||
*
|
||||
* @returns {{
|
||||
* type: DISMISS_MOBILE_APP_PROMO
|
||||
* }}
|
||||
*/
|
||||
export function dismissMobileAppPromo() {
|
||||
return {
|
||||
type: DISMISS_MOBILE_APP_PROMO
|
||||
};
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
/* @flow */
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
/**
|
||||
* React component that represents HTML style element with CSS specific to
|
||||
* unsupported mobile browser components.
|
||||
*
|
||||
* @private
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
export default class HideNotificationBarStyles extends Component<*> {
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
// Temasys provide lib-jitsi-meet/modules/RTC/adapter.screenshare.js
|
||||
// which detects whether the browser supports WebRTC. If the browser
|
||||
// does not support WebRTC, it displays an alert in the form of a yellow
|
||||
// bar at the top of the page. The alert notifies the user that the
|
||||
// browser does not support WebRTC and, if Temasys provide a plugin for
|
||||
// the browser, the alert contains a button to initiate installing the
|
||||
// browser. When Temasys do not provide a plugin for the browser, we do
|
||||
// not want the alert on the unsupported-browser page because the
|
||||
// notification about the lack of WebRTC support is the whole point of
|
||||
// the unsupported-browser page.
|
||||
return (
|
||||
<style type = 'text/css'>
|
||||
{
|
||||
'iframe[name="adapterjs-alert"] { display: none; }'
|
||||
}
|
||||
</style>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/* @flow */
|
||||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import HideNotificationBarStyle from './HideNotificationBarStyle';
|
||||
|
||||
declare var interfaceConfig: Object;
|
||||
|
||||
/**
|
||||
* React component representing no mobile app page.
|
||||
*
|
||||
* @class NoMobileApp
|
||||
*/
|
||||
export default class NoMobileApp extends Component<*> {
|
||||
/**
|
||||
* Renders the component.
|
||||
*
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const ns = 'no-mobile-app';
|
||||
|
||||
return (
|
||||
<div className = { ns }>
|
||||
<h2 className = { `${ns}__title` }>
|
||||
Video chat isn't available on mobile.
|
||||
</h2>
|
||||
<p className = { `${ns}__description` }>
|
||||
Please use { interfaceConfig.APP_NAME } on desktop to join
|
||||
calls.
|
||||
</p>
|
||||
|
||||
<HideNotificationBarStyle />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,9 @@ import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { translate } from '../../base/i18n';
|
||||
import { Platform } from '../../base/react';
|
||||
import { HideNotificationBarStyle, Platform } from '../../base/react';
|
||||
|
||||
import { CHROME, FIREFOX, IE, SAFARI } from './browserLinks';
|
||||
import HideNotificationBarStyle from './HideNotificationBarStyle';
|
||||
|
||||
/**
|
||||
* The namespace of the CSS styles of UnsupportedDesktopBrowser.
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
/* @flow */
|
||||
|
||||
import PropTypes from 'prop-types';
|
||||
import React, { Component } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { translate, translateToHTML } from '../../base/i18n';
|
||||
import { Platform } from '../../base/react';
|
||||
import { URI_PROTOCOL_PATTERN } from '../../base/util';
|
||||
import { DialInSummary } from '../../invite';
|
||||
import HideNotificationBarStyle from './HideNotificationBarStyle';
|
||||
|
||||
declare var interfaceConfig: Object;
|
||||
|
||||
/**
|
||||
* The namespace of the CSS styles of UnsupportedMobileBrowser.
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
const _SNS = 'unsupported-mobile-browser';
|
||||
|
||||
/**
|
||||
* The namespace of the i18n/translation keys of UnsupportedMobileBrowser.
|
||||
*
|
||||
* @private
|
||||
* @type {string}
|
||||
*/
|
||||
const _TNS = 'unsupportedBrowser';
|
||||
|
||||
/**
|
||||
* The map of platforms to URLs at which the mobile app for the associated
|
||||
* platform is available for download.
|
||||
*
|
||||
* @private
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
const _URLS = {
|
||||
android: interfaceConfig.MOBILE_DOWNLOAD_LINK_ANDROID
|
||||
|| 'https://play.google.com/store/apps/details?id=org.jitsi.meet',
|
||||
ios: interfaceConfig.MOBILE_DOWNLOAD_LINK_IOS
|
||||
|| 'https://itunes.apple.com/us/app/jitsi-meet/id1165103905'
|
||||
};
|
||||
|
||||
/**
|
||||
* React component representing mobile browser page.
|
||||
*
|
||||
* @class UnsupportedMobileBrowser
|
||||
*/
|
||||
class UnsupportedMobileBrowser extends Component<*, *> {
|
||||
state: Object;
|
||||
|
||||
/**
|
||||
* UnsupportedMobileBrowser component's property types.
|
||||
*
|
||||
* @static
|
||||
*/
|
||||
static propTypes = {
|
||||
/**
|
||||
* The name of the conference attempting to being joined.
|
||||
*/
|
||||
_room: PropTypes.string,
|
||||
|
||||
/**
|
||||
* The function to translate human-readable text.
|
||||
*
|
||||
* @public
|
||||
* @type {Function}
|
||||
*/
|
||||
t: PropTypes.func
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the text and URL of the `Start a conference` / `Join the
|
||||
* conversation` button which takes the user to the mobile app.
|
||||
*
|
||||
* @inheritdoc
|
||||
*/
|
||||
componentWillMount() {
|
||||
// If the user installed the app while this Component was displayed
|
||||
// (e.g. the user clicked the Download the App button), then we would
|
||||
// like to open the current URL in the mobile app. The only way to do it
|
||||
// appears to be a link with an app-specific scheme, not a Universal
|
||||
// Link.
|
||||
const appScheme = interfaceConfig.MOBILE_APP_SCHEME || 'org.jitsi.meet';
|
||||
|
||||
// Replace the protocol part with the app scheme.
|
||||
const joinURL
|
||||
= window.location.href.replace(
|
||||
new RegExp(`^${URI_PROTOCOL_PATTERN}`), `${appScheme}:`);
|
||||
|
||||
this.setState({
|
||||
joinURL
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements React's {@link Component#render()}.
|
||||
*
|
||||
* @inheritdoc
|
||||
* @returns {ReactElement}
|
||||
*/
|
||||
render() {
|
||||
const { _room, t } = this.props;
|
||||
|
||||
const openAppButtonClassName
|
||||
= `${_SNS}__button ${_SNS}__button_primary`;
|
||||
const appName
|
||||
= interfaceConfig.ADD_PEOPLE_APP_NAME || interfaceConfig.APP_NAME;
|
||||
|
||||
return (
|
||||
<div className = { _SNS }>
|
||||
<div className = { `${_SNS}__body` }>
|
||||
<img
|
||||
className = { `${_SNS}__logo` }
|
||||
src = 'images/logo-blue.svg' />
|
||||
<p className = { `${_SNS}__text` }>
|
||||
{
|
||||
translateToHTML(
|
||||
t,
|
||||
`${_TNS}.appNotInstalled`,
|
||||
{ app: appName })
|
||||
}
|
||||
</p>
|
||||
<a href = { this.state.joinURL }>
|
||||
<button className = { openAppButtonClassName }>
|
||||
{ t(`${_TNS}.openApp`,
|
||||
{ app: appName }) }
|
||||
</button>
|
||||
</a>
|
||||
<a href = { _URLS[Platform.OS] }>
|
||||
<button className = { `${_SNS}__button` }>
|
||||
{ t(`${_TNS}.downloadApp`) }
|
||||
</button>
|
||||
</a>
|
||||
{ _room
|
||||
? <DialInSummary
|
||||
className = 'unsupported-dial-in'
|
||||
clickableNumbers = { true }
|
||||
room = { _room } />
|
||||
: null }
|
||||
</div>
|
||||
<HideNotificationBarStyle />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maps (parts of) the Redux state to the associated props for the
|
||||
* {@code UnsupportedMobileBrowser} component.
|
||||
*
|
||||
* @param {Object} state - The Redux state.
|
||||
* @private
|
||||
* @returns {{
|
||||
* _room: string
|
||||
* }}
|
||||
*/
|
||||
function _mapStateToProps(state) {
|
||||
return {
|
||||
_room: state['features/base/conference'].room
|
||||
};
|
||||
}
|
||||
|
||||
export default translate(connect(_mapStateToProps)(UnsupportedMobileBrowser));
|
||||
@@ -1,8 +1,3 @@
|
||||
export { default as HideNotificationBarStyle }
|
||||
from './HideNotificationBarStyle';
|
||||
export { default as NoMobileApp } from './NoMobileApp';
|
||||
export { default as PluginRequiredBrowser } from './PluginRequiredBrowser';
|
||||
export { default as UnsupportedDesktopBrowser }
|
||||
from './UnsupportedDesktopBrowser';
|
||||
export { default as UnsupportedMobileBrowser }
|
||||
from './UnsupportedMobileBrowser';
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
export * from './actions';
|
||||
export * from './components';
|
||||
|
||||
import './middleware';
|
||||
import './reducer';
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
import { ReducerRegistry } from '../base/redux';
|
||||
|
||||
import { DISMISS_MOBILE_APP_PROMO } from './actionTypes';
|
||||
|
||||
ReducerRegistry.register(
|
||||
'features/unsupported-browser',
|
||||
(state = {}, action) => {
|
||||
switch (action.type) {
|
||||
case DISMISS_MOBILE_APP_PROMO:
|
||||
return {
|
||||
...state,
|
||||
|
||||
/**
|
||||
* The indicator which determines whether the React
|
||||
* Component UnsupportedMobileBrowser which was rendered as
|
||||
* a promotion of the mobile app on a browser was dismissed
|
||||
* by the user. If unused, then we have chosen to force the
|
||||
* mobile app and not allow the Web app in mobile browsers.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
mobileAppPromoDismissed: true
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
});
|
||||
Reference in New Issue
Block a user