From 4773b12a3b2882d8311a7f8080aad10e7631faf9 Mon Sep 17 00:00:00 2001 From: Akshit Kr Nagpal Date: Sun, 27 May 2018 03:21:12 +0530 Subject: [PATCH] Add initial welcome page --- .flowconfig | 3 +- app/features/app/components/App.js | 18 +- .../conference/components/Conference.js | 97 +- app/features/conference/index.js | 2 + app/features/conference/styled/Wrapper.js | 7 + app/features/conference/styled/index.js | 1 + app/features/welcome/components/Welcome.js | 124 ++ app/features/welcome/components/index.js | 1 + app/features/welcome/index.js | 2 + app/features/welcome/styled/Content.js | 10 + app/features/welcome/styled/Form.js | 8 + app/features/welcome/styled/WelcomeWrapper.js | 9 + app/features/welcome/styled/index.js | 3 + app/index.html | 2 - app/index.js | 5 + package-lock.json | 1338 ++++++++++++++++- package.json | 10 +- webpack.config.js | 7 + 18 files changed, 1588 insertions(+), 59 deletions(-) create mode 100644 app/features/conference/styled/Wrapper.js create mode 100644 app/features/conference/styled/index.js create mode 100644 app/features/welcome/components/Welcome.js create mode 100644 app/features/welcome/components/index.js create mode 100644 app/features/welcome/index.js create mode 100644 app/features/welcome/styled/Content.js create mode 100644 app/features/welcome/styled/Form.js create mode 100644 app/features/welcome/styled/WelcomeWrapper.js create mode 100644 app/features/welcome/styled/index.js diff --git a/.flowconfig b/.flowconfig index 1c8ac50..01618f8 100644 --- a/.flowconfig +++ b/.flowconfig @@ -1,6 +1,7 @@ [ignore] -.*/node_modules/.* +.*/node_modules/@atlaskit/.*/*.js.flow .*/build/.* +.*/node_modules/electron-packager/test/fixtures/infer-malformed-json/.* [include] diff --git a/app/features/app/components/App.js b/app/features/app/components/App.js index 944caa6..92498e3 100644 --- a/app/features/app/components/App.js +++ b/app/features/app/components/App.js @@ -1,9 +1,13 @@ // @flow +import { AtlasKitThemeProvider } from '@atlaskit/theme'; + import React, { Component } from 'react'; +import { HashRouter as Router, Route, Switch } from 'react-router-dom'; import { Conference } from '../../conference'; import config from '../../config'; +import { Welcome } from '../../welcome'; /** * Main component encapsulating the entire application. @@ -28,7 +32,19 @@ export default class App extends Component<*> { */ render() { return ( - + + + + + + + + ); } } diff --git a/app/features/conference/components/Conference.js b/app/features/conference/components/Conference.js index 69d09bc..f27d225 100644 --- a/app/features/conference/components/Conference.js +++ b/app/features/conference/components/Conference.js @@ -1,59 +1,120 @@ // @flow -import { Component } from 'react'; +import React, { Component } from 'react'; import { RemoteControl, setupScreenSharingForWindow, setupAlwaysOnTopRender, setupWiFiStats - - // $FlowFixMe } from 'jitsi-meet-electron-utils'; import config from '../../config'; +import { Wrapper } from '../styled'; + +type Props = { + + /** + * React Router history object. + * This contains implementations for managing session history. + */ + history: Object; + + /** + * React Router match object. + * This contains parameters passed through component. + */ + match: Object; +}; + /** * Conference component. */ -export default class Conference extends Component<*> { +export default class Conference extends Component { /** - * Attach the script + * Reference to the element of this component. + */ + _ref: Object; + + /** + * External API object. + */ + _api: Object; + + /** + * Initializes a new {@code Conference} instance. + * + * @inheritdoc + */ + constructor() { + super(); + + this._ref = React.createRef(); + } + + /** + * Attach the script to this component. */ componentDidMount() { + const parentNode = this._ref.current; + const room = this.props.match.params.room; + const domain = this.props.match.params.domain || config.defaultDomain; + const script = document.createElement('script'); script.async = true; - script.onload = this._onScriptLoad; - script.onerror = console.error; - script.src = `https://${config.defaultDomain}/external_api.js`; + script.onload = () => this._onScriptLoad(parentNode, room, domain); + script.onerror = () => this._navigateToHome(); + script.src = `https://${domain}/external_api.js`; - // $FlowFixMe - document.head.appendChild(script); + this._ref.current.appendChild(script); } + /** + * Remove conference on unmounting. + */ + componentWillUnmount() { + if (this._api) { + this._api.dispose(); + } + } /** - * Render function of component. + * Implements React's {@link Component#render()}. * - * @return {ReactElement} + * @inheritdoc + * @returns {ReactElement} */ render() { - return null; + return ; } /** - * When the script is loaded attach utils from jitsi-meet-electron-utils + * Navigates to home screen (Welcome). */ - _onScriptLoad() { + _navigateToHome() { + this.props.history.push('/'); + } + + /** + * When the script is loaded create the iframe element in this component + * and attach utils from jitsi-meet-electron-utils. + */ + _onScriptLoad(parentNode: Object, roomName: string, domain: string) { const JitsiMeetExternalAPI = window.JitsiMeetExternalAPI; - const api = new JitsiMeetExternalAPI(config.defaultDomain); - const iframe = api.getIFrame(); + this._api = new JitsiMeetExternalAPI(domain, { + parentNode, + roomName + }); + const iframe = this._api.getIFrame(); setupScreenSharingForWindow(iframe); new RemoteControl(iframe); // eslint-disable-line no-new - setupAlwaysOnTopRender(api); + setupAlwaysOnTopRender(this._api); setupWiFiStats(iframe); + + this._api.on('readyToClose', () => this._navigateToHome()); } } diff --git a/app/features/conference/index.js b/app/features/conference/index.js index 07635cb..213d6c1 100644 --- a/app/features/conference/index.js +++ b/app/features/conference/index.js @@ -1 +1,3 @@ export * from './components'; +export * from './styled'; + diff --git a/app/features/conference/styled/Wrapper.js b/app/features/conference/styled/Wrapper.js new file mode 100644 index 0000000..c2e9850 --- /dev/null +++ b/app/features/conference/styled/Wrapper.js @@ -0,0 +1,7 @@ +// @flow + +import styled from 'styled-components'; + +export default styled.div` + height: 100vh; +`; diff --git a/app/features/conference/styled/index.js b/app/features/conference/styled/index.js new file mode 100644 index 0000000..50472e0 --- /dev/null +++ b/app/features/conference/styled/index.js @@ -0,0 +1 @@ +export { default as Wrapper } from './Wrapper'; diff --git a/app/features/welcome/components/Welcome.js b/app/features/welcome/components/Welcome.js new file mode 100644 index 0000000..761be85 --- /dev/null +++ b/app/features/welcome/components/Welcome.js @@ -0,0 +1,124 @@ +// @flow + +import { AtlasKitThemeProvider } from '@atlaskit/theme'; +import Button from '@atlaskit/button'; +import { FieldTextStateless } from '@atlaskit/field-text'; + +import React, { Component } from 'react'; +import URL from 'url'; + +import { WelcomeWrapper as Wrapper, Content, Form } from '../styled'; + + +type Props = { + + /** + * React Router history object. + * This contains implementations for managing session history. + */ + history: Object; +}; + +type State = { + + /** + * URL of the room to join. + * If this is not a url it will be treated as room name for default domain. + */ + url: string; +}; + +/** + * Welcome Component. + */ +export default class Welcome extends Component { + /** + * Initializes a new {@code Welcome} instance. + * + * @inheritdoc + */ + constructor(props: Props) { + super(props); + + this.state = { + url: '' + }; + + // Bind event handlers. + this._onURLChange = this._onURLChange.bind(this); + this._onFormSubmit = this._onFormSubmit.bind(this); + this._onJoin = this._onJoin.bind(this); + } + + /** + * Render function of component. + * + * @return {ReactElement} + */ + render() { + return ( + + + +
+ + + +
+
+
+ ); + } + + _onFormSubmit: (*) => void; + + /** + * Prevents submission of the form and delegates the join logic. + */ + _onFormSubmit(event: Event) { + event.preventDefault(); + this._onJoin(); + } + + _onJoin: (*) => void; + + /** + * Redirect and join conference. + */ + _onJoin() { + const url = URL.parse(this.state.url); + + // Check if the parsed url is a full url or just room name. + if (url.host && url.path) { + + // This will be triggered when the full url is present. + this.props.history.push(url.host + url.path); + } else { + + // Directly to the the path. + this.props.history.push(url.path); + } + } + + _onURLChange: (*) => void; + + /** + * Keeps URL input value and URL in state in sync. + */ + _onURLChange(event: SyntheticInputEvent) { + this.setState({ + url: event.currentTarget.value + }); + } +} diff --git a/app/features/welcome/components/index.js b/app/features/welcome/components/index.js new file mode 100644 index 0000000..091c2f5 --- /dev/null +++ b/app/features/welcome/components/index.js @@ -0,0 +1 @@ +export { default as Welcome } from './Welcome'; diff --git a/app/features/welcome/index.js b/app/features/welcome/index.js new file mode 100644 index 0000000..f0ec1c6 --- /dev/null +++ b/app/features/welcome/index.js @@ -0,0 +1,2 @@ +export * from './components'; +export * from './styled'; diff --git a/app/features/welcome/styled/Content.js b/app/features/welcome/styled/Content.js new file mode 100644 index 0000000..33fcb67 --- /dev/null +++ b/app/features/welcome/styled/Content.js @@ -0,0 +1,10 @@ +// @flow + +import styled from 'styled-components'; + +export default styled.div` + align-items: center; + display: flex; + margin: 0 auto; + padding: 30px; +`; diff --git a/app/features/welcome/styled/Form.js b/app/features/welcome/styled/Form.js new file mode 100644 index 0000000..dcb562f --- /dev/null +++ b/app/features/welcome/styled/Form.js @@ -0,0 +1,8 @@ +// Flow + +import styled from 'styled-components'; + +export default styled.form` + width: 350px; + margin: 0 15px; +`; diff --git a/app/features/welcome/styled/WelcomeWrapper.js b/app/features/welcome/styled/WelcomeWrapper.js new file mode 100644 index 0000000..3fe50b7 --- /dev/null +++ b/app/features/welcome/styled/WelcomeWrapper.js @@ -0,0 +1,9 @@ +// @flow + +import styled from 'styled-components'; + +export default styled.div` + background: linear-gradient(#165ecc,#44A5FF); + display: flex; + height: 100vh; +`; diff --git a/app/features/welcome/styled/index.js b/app/features/welcome/styled/index.js new file mode 100644 index 0000000..6b132d9 --- /dev/null +++ b/app/features/welcome/styled/index.js @@ -0,0 +1,3 @@ +export { default as Content } from './Content'; +export { default as Form } from './Form'; +export { default as WelcomeWrapper } from './WelcomeWrapper'; diff --git a/app/index.html b/app/index.html index befc6f9..45a0543 100644 --- a/app/index.html +++ b/app/index.html @@ -3,8 +3,6 @@