From 3bd9970c12c8c76a7e989ec0bcc75fe3afcf390f Mon Sep 17 00:00:00 2001 From: akshitkrnagpal Date: Sat, 23 Jun 2018 06:21:50 +0530 Subject: [PATCH] Add ability to configure the server URL The configured server URL will be used when the room URL is not a full URL. If a full URL is given, the target server is joined. The default server URL is https://meet.jit.si --- .../conference/components/Conference.js | 11 +++- app/features/config/index.js | 2 +- app/features/settings/actionTypes.js | 9 +++ app/features/settings/actions.js | 27 +++++++- .../settings/components/SettingsDrawer.js | 62 +++++++++++++++++-- app/features/settings/reducer.js | 19 +++++- ...ofileContainer.js => SettingsContainer.js} | 0 app/features/settings/styled/index.js | 2 +- app/features/utils/functions.js | 35 ++++++++--- app/features/welcome/components/Welcome.js | 8 +-- 10 files changed, 147 insertions(+), 28 deletions(-) rename app/features/settings/styled/{ProfileContainer.js => SettingsContainer.js} (100%) diff --git a/app/features/conference/components/Conference.js b/app/features/conference/components/Conference.js index 49950fb..f50fbe4 100644 --- a/app/features/conference/components/Conference.js +++ b/app/features/conference/components/Conference.js @@ -46,6 +46,10 @@ type Props = { */ _name: string; + /** + * Default Jitsi Server URL. + */ + _serverURL: string; }; /** @@ -82,6 +86,7 @@ class Conference extends Component { const parentNode = this._ref.current; const room = this.props.location.state.room; const serverURL = this.props.location.state.serverURL + || this.props._serverURL || config.defaultServerURL; const script = document.createElement('script'); @@ -263,14 +268,16 @@ class Conference extends Component { * @returns {{ * _avatarURL: string, * _email: string, - * _name: string + * _name: string, + * _serverURL: string * }} */ function _mapStateToProps(state: Object) { return { _avatarURL: state.settings.avatarURL, _email: state.settings.email, - _name: state.settings.name + _name: state.settings.name, + _serverURL: state.settings.serverURL }; } diff --git a/app/features/config/index.js b/app/features/config/index.js index 4be9486..e81da74 100644 --- a/app/features/config/index.js +++ b/app/features/config/index.js @@ -8,7 +8,7 @@ export default { /** * The default server URL of Jitsi Meet Deployment that will be used. */ - defaultServerURL: 'https://meet.jit.si/', + defaultServerURL: 'https://meet.jit.si', /** * URL to send feedback. diff --git a/app/features/settings/actionTypes.js b/app/features/settings/actionTypes.js index 977ef4d..d5186ce 100644 --- a/app/features/settings/actionTypes.js +++ b/app/features/settings/actionTypes.js @@ -28,3 +28,12 @@ export const SET_EMAIL = Symbol('SET_EMAIL'); */ export const SET_NAME = Symbol('SET_NAME'); +/** + * The type of (redux) action that sets the Server URL. + * + * { + * type: SET_SERVER_URL, + * serverURL: string + * } + */ +export const SET_SERVER_URL = Symbol('SET_SERVER_URL'); diff --git a/app/features/settings/actions.js b/app/features/settings/actions.js index dd5a383..3689292 100644 --- a/app/features/settings/actions.js +++ b/app/features/settings/actions.js @@ -1,6 +1,13 @@ // @flow -import { SET_AVATAR_URL, SET_EMAIL, SET_NAME } from './actionTypes'; +import { + SET_AVATAR_URL, + SET_EMAIL, + SET_NAME, + SET_SERVER_URL +} from './actionTypes'; + +import { normalizeServerURL } from '../utils'; /** * Set Avatar URL. @@ -49,3 +56,21 @@ export function setName(name: string) { name }; } + +/** + * Set Server URL. + * + * @param {string} serverURL - Server URL. + * @returns {{ + * type: SET_SERVER_URL, + * serverURL: ?string + * }} + */ +export function setServerURL(serverURL: string) { + return { + type: SET_SERVER_URL, + serverURL: normalizeServerURL(serverURL) + }; +} + + diff --git a/app/features/settings/components/SettingsDrawer.js b/app/features/settings/components/SettingsDrawer.js index 7869cd2..72d3a37 100644 --- a/app/features/settings/components/SettingsDrawer.js +++ b/app/features/settings/components/SettingsDrawer.js @@ -9,9 +9,10 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; import type { Dispatch } from 'redux'; +import config from '../../config'; import { closeDrawer, DrawerContainer, Logo } from '../../navbar'; -import { AvatarContainer, ProfileContainer } from '../styled'; -import { setEmail, setName } from '../actions'; +import { AvatarContainer, SettingsContainer } from '../styled'; +import { setEmail, setName, setServerURL } from '../actions'; type Props = { @@ -39,6 +40,11 @@ type Props = { * Name of the user. */ _name: string; + + /** + * Default Jitsi Server URL. + */ + _serverURL: string; }; /** @@ -58,6 +64,8 @@ class SettingsDrawer extends Component { this._onEmailFormSubmit = this._onEmailFormSubmit.bind(this); this._onNameBlur = this._onNameBlur.bind(this); this._onNameFormSubmit = this._onNameFormSubmit.bind(this); + this._onServerURLBlur = this._onServerURLBlur.bind(this); + this._onServerURLFormSubmit = this._onServerURLFormSubmit.bind(this); } /** @@ -73,7 +81,7 @@ class SettingsDrawer extends Component { onBackButton = { this._onBackButton } primaryIcon = { } > - + { type = 'text' value = { this.props._email } /> - +
+ + +
); @@ -170,6 +187,37 @@ class SettingsDrawer extends Component { // $FlowFixMe this.props.dispatch(setName(event.currentTarget.elements[0].value)); } + + _onServerURLBlur: (*) => void; + + /** + * Updates Server URL in (redux) state when it is updated. + * + * @param {SyntheticInputEvent} event - Event by which + * this function is called. + * @returns {void} + */ + _onServerURLBlur(event: SyntheticInputEvent) { + this.props.dispatch(setServerURL(event.currentTarget.value)); + } + + _onServerURLFormSubmit: (*) => void; + + /** + * Prevents submission of the form and updates Server URL. + * + * @param {SyntheticEvent} event - Event by which + * this function is called. + * @returns {void} + */ + _onServerURLFormSubmit(event: SyntheticEvent) { + event.preventDefault(); + + // $FlowFixMe + const serverURL = event.currentTarget.elements[0].value; + + this.props.dispatch(setServerURL(serverURL)); + } } /** @@ -179,14 +227,16 @@ class SettingsDrawer extends Component { * @returns {{ * _avatarURL: string, * _email: string, - * _name: string + * _name: string, + * _serverURL: string * }} */ function _mapStateToProps(state: Object) { return { _avatarURL: state.settings.avatarURL, _email: state.settings.email, - _name: state.settings.name + _name: state.settings.name, + _serverURL: state.settings.serverURL }; } diff --git a/app/features/settings/reducer.js b/app/features/settings/reducer.js index 02d42d5..5daaf4e 100644 --- a/app/features/settings/reducer.js +++ b/app/features/settings/reducer.js @@ -4,12 +4,18 @@ import os from 'os'; import { getAvatarURL } from '../utils'; -import { SET_AVATAR_URL, SET_EMAIL, SET_NAME } from './actionTypes'; +import { + SET_AVATAR_URL, + SET_EMAIL, + SET_NAME, + SET_SERVER_URL +} from './actionTypes'; type State = { avatarURL: string, email: string, - name: string + name: string, + serverURL: ?string }; const username = os.userInfo().username; @@ -17,7 +23,8 @@ const username = os.userInfo().username; const DEFAULT_STATE = { avatarURL: getAvatarURL({ id: username }), email: '', - name: username + name: username, + serverURL: undefined }; /** @@ -47,6 +54,12 @@ export default (state: State = DEFAULT_STATE, action: Object) => { name: action.name }; + case SET_SERVER_URL: + return { + ...state, + serverURL: action.serverURL + }; + default: return state; } diff --git a/app/features/settings/styled/ProfileContainer.js b/app/features/settings/styled/SettingsContainer.js similarity index 100% rename from app/features/settings/styled/ProfileContainer.js rename to app/features/settings/styled/SettingsContainer.js diff --git a/app/features/settings/styled/index.js b/app/features/settings/styled/index.js index ed00704..c46e575 100644 --- a/app/features/settings/styled/index.js +++ b/app/features/settings/styled/index.js @@ -1,2 +1,2 @@ export { default as AvatarContainer } from './AvatarContainer'; -export { default as ProfileContainer } from './ProfileContainer'; +export { default as SettingsContainer } from './SettingsContainer'; diff --git a/app/features/utils/functions.js b/app/features/utils/functions.js index 5f31ddd..7c49d19 100644 --- a/app/features/utils/functions.js +++ b/app/features/utils/functions.js @@ -5,6 +5,32 @@ import { shell } from 'electron'; import md5 from 'js-md5'; +/** + * Return true if Electron app is running on Mac system. + * + * @returns {boolean} + */ +export function isElectronMac() { + return process.platform === 'darwin'; +} + +/** + * Normalizes the given server URL so it has the proper scheme. + * + * @param {string} url - URL with or without scheme. + * @returns {string} + */ +export function normalizeServerURL(url: string) { + // eslint-disable-next-line no-param-reassign + url = url.trim(); + + if (url && url.indexOf('://') === -1) { + return `https://${url}`; + } + + return url; +} + /** * Opens the provided link in default broswer. * @@ -15,15 +41,6 @@ export function openExternalLink(link: string) { shell.openExternal(link); } -/** - * Return true if Electron app is running on Mac system. - * - * @returns {boolean} - */ -export function isElectronMac() { - return process.platform === 'darwin'; -} - /** * Returns the Avatar URL to be used. * diff --git a/app/features/welcome/components/Welcome.js b/app/features/welcome/components/Welcome.js index 663bc80..d6cf1c9 100644 --- a/app/features/welcome/components/Welcome.js +++ b/app/features/welcome/components/Welcome.js @@ -11,6 +11,7 @@ import { connect } from 'react-redux'; import { push } from 'react-router-redux'; import { Navbar } from '../../navbar'; +import { normalizeServerURL } from '../../utils'; import { WelcomeWrapper as Wrapper, Content, Form } from '../styled'; @@ -123,11 +124,8 @@ class Welcome extends Component { // Take the substring before last slash to be the Server URL. serverURL = inputURL.substring(0, lastIndexOfSlash); - // If no protocol is specified in the input we assume and append - // the HTTPS protocol scheme. - if (serverURL.indexOf('://') === -1) { - serverURL = `https://${serverURL}`; - } + // Normalize the server URL. + serverURL = normalizeServerURL(serverURL); } // Don't navigate if no room was specified.