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
This commit is contained in:
akshitkrnagpal 2018-06-23 06:21:50 +05:30 committed by Saúl Ibarra Corretgé
parent d73f80e7bf
commit 3bd9970c12
10 changed files with 147 additions and 28 deletions

View file

@ -46,6 +46,10 @@ type Props = {
*/ */
_name: string; _name: string;
/**
* Default Jitsi Server URL.
*/
_serverURL: string;
}; };
/** /**
@ -82,6 +86,7 @@ class Conference extends Component<Props, *> {
const parentNode = this._ref.current; const parentNode = this._ref.current;
const room = this.props.location.state.room; const room = this.props.location.state.room;
const serverURL = this.props.location.state.serverURL const serverURL = this.props.location.state.serverURL
|| this.props._serverURL
|| config.defaultServerURL; || config.defaultServerURL;
const script = document.createElement('script'); const script = document.createElement('script');
@ -263,14 +268,16 @@ class Conference extends Component<Props, *> {
* @returns {{ * @returns {{
* _avatarURL: string, * _avatarURL: string,
* _email: string, * _email: string,
* _name: string * _name: string,
* _serverURL: string
* }} * }}
*/ */
function _mapStateToProps(state: Object) { function _mapStateToProps(state: Object) {
return { return {
_avatarURL: state.settings.avatarURL, _avatarURL: state.settings.avatarURL,
_email: state.settings.email, _email: state.settings.email,
_name: state.settings.name _name: state.settings.name,
_serverURL: state.settings.serverURL
}; };
} }

View file

@ -8,7 +8,7 @@ export default {
/** /**
* The default server URL of Jitsi Meet Deployment that will be used. * 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. * URL to send feedback.

View file

@ -28,3 +28,12 @@ export const SET_EMAIL = Symbol('SET_EMAIL');
*/ */
export const SET_NAME = Symbol('SET_NAME'); 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');

View file

@ -1,6 +1,13 @@
// @flow // @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. * Set Avatar URL.
@ -49,3 +56,21 @@ export function setName(name: string) {
name 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)
};
}

View file

@ -9,9 +9,10 @@ import React, { Component } from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import type { Dispatch } from 'redux'; import type { Dispatch } from 'redux';
import config from '../../config';
import { closeDrawer, DrawerContainer, Logo } from '../../navbar'; import { closeDrawer, DrawerContainer, Logo } from '../../navbar';
import { AvatarContainer, ProfileContainer } from '../styled'; import { AvatarContainer, SettingsContainer } from '../styled';
import { setEmail, setName } from '../actions'; import { setEmail, setName, setServerURL } from '../actions';
type Props = { type Props = {
@ -39,6 +40,11 @@ type Props = {
* Name of the user. * Name of the user.
*/ */
_name: string; _name: string;
/**
* Default Jitsi Server URL.
*/
_serverURL: string;
}; };
/** /**
@ -58,6 +64,8 @@ class SettingsDrawer extends Component<Props, *> {
this._onEmailFormSubmit = this._onEmailFormSubmit.bind(this); this._onEmailFormSubmit = this._onEmailFormSubmit.bind(this);
this._onNameBlur = this._onNameBlur.bind(this); this._onNameBlur = this._onNameBlur.bind(this);
this._onNameFormSubmit = this._onNameFormSubmit.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<Props, *> {
onBackButton = { this._onBackButton } onBackButton = { this._onBackButton }
primaryIcon = { <Logo /> } > primaryIcon = { <Logo /> } >
<DrawerContainer> <DrawerContainer>
<ProfileContainer> <SettingsContainer>
<AvatarContainer> <AvatarContainer>
<Avatar <Avatar
size = 'xlarge' size = 'xlarge'
@ -95,7 +103,16 @@ class SettingsDrawer extends Component<Props, *> {
type = 'text' type = 'text'
value = { this.props._email } /> value = { this.props._email } />
</form> </form>
</ProfileContainer> <form onSubmit = { this._onServerURLFormSubmit }>
<FieldText
label = 'Server URL'
onBlur = { this._onServerURLBlur }
placeholder = { config.defaultServerURL }
shouldFitContainer = { true }
type = 'text'
value = { this.props._serverURL } />
</form>
</SettingsContainer>
</DrawerContainer> </DrawerContainer>
</AkCustomDrawer> </AkCustomDrawer>
); );
@ -170,6 +187,37 @@ class SettingsDrawer extends Component<Props, *> {
// $FlowFixMe // $FlowFixMe
this.props.dispatch(setName(event.currentTarget.elements[0].value)); this.props.dispatch(setName(event.currentTarget.elements[0].value));
} }
_onServerURLBlur: (*) => void;
/**
* Updates Server URL in (redux) state when it is updated.
*
* @param {SyntheticInputEvent<HTMLInputElement>} event - Event by which
* this function is called.
* @returns {void}
*/
_onServerURLBlur(event: SyntheticInputEvent<HTMLInputElement>) {
this.props.dispatch(setServerURL(event.currentTarget.value));
}
_onServerURLFormSubmit: (*) => void;
/**
* Prevents submission of the form and updates Server URL.
*
* @param {SyntheticEvent<HTMLFormElement>} event - Event by which
* this function is called.
* @returns {void}
*/
_onServerURLFormSubmit(event: SyntheticEvent<HTMLFormElement>) {
event.preventDefault();
// $FlowFixMe
const serverURL = event.currentTarget.elements[0].value;
this.props.dispatch(setServerURL(serverURL));
}
} }
/** /**
@ -179,14 +227,16 @@ class SettingsDrawer extends Component<Props, *> {
* @returns {{ * @returns {{
* _avatarURL: string, * _avatarURL: string,
* _email: string, * _email: string,
* _name: string * _name: string,
* _serverURL: string
* }} * }}
*/ */
function _mapStateToProps(state: Object) { function _mapStateToProps(state: Object) {
return { return {
_avatarURL: state.settings.avatarURL, _avatarURL: state.settings.avatarURL,
_email: state.settings.email, _email: state.settings.email,
_name: state.settings.name _name: state.settings.name,
_serverURL: state.settings.serverURL
}; };
} }

View file

@ -4,12 +4,18 @@ import os from 'os';
import { getAvatarURL } from '../utils'; 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 = { type State = {
avatarURL: string, avatarURL: string,
email: string, email: string,
name: string name: string,
serverURL: ?string
}; };
const username = os.userInfo().username; const username = os.userInfo().username;
@ -17,7 +23,8 @@ const username = os.userInfo().username;
const DEFAULT_STATE = { const DEFAULT_STATE = {
avatarURL: getAvatarURL({ id: username }), avatarURL: getAvatarURL({ id: username }),
email: '', email: '',
name: username name: username,
serverURL: undefined
}; };
/** /**
@ -47,6 +54,12 @@ export default (state: State = DEFAULT_STATE, action: Object) => {
name: action.name name: action.name
}; };
case SET_SERVER_URL:
return {
...state,
serverURL: action.serverURL
};
default: default:
return state; return state;
} }

View file

@ -1,2 +1,2 @@
export { default as AvatarContainer } from './AvatarContainer'; export { default as AvatarContainer } from './AvatarContainer';
export { default as ProfileContainer } from './ProfileContainer'; export { default as SettingsContainer } from './SettingsContainer';

View file

@ -5,6 +5,32 @@
import { shell } from 'electron'; import { shell } from 'electron';
import md5 from 'js-md5'; 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. * Opens the provided link in default broswer.
* *
@ -15,15 +41,6 @@ export function openExternalLink(link: string) {
shell.openExternal(link); 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. * Returns the Avatar URL to be used.
* *

View file

@ -11,6 +11,7 @@ import { connect } from 'react-redux';
import { push } from 'react-router-redux'; import { push } from 'react-router-redux';
import { Navbar } from '../../navbar'; import { Navbar } from '../../navbar';
import { normalizeServerURL } from '../../utils';
import { WelcomeWrapper as Wrapper, Content, Form } from '../styled'; import { WelcomeWrapper as Wrapper, Content, Form } from '../styled';
@ -123,11 +124,8 @@ class Welcome extends Component<Props, State> {
// Take the substring before last slash to be the Server URL. // Take the substring before last slash to be the Server URL.
serverURL = inputURL.substring(0, lastIndexOfSlash); serverURL = inputURL.substring(0, lastIndexOfSlash);
// If no protocol is specified in the input we assume and append // Normalize the server URL.
// the HTTPS protocol scheme. serverURL = normalizeServerURL(serverURL);
if (serverURL.indexOf('://') === -1) {
serverURL = `https://${serverURL}`;
}
} }
// Don't navigate if no room was specified. // Don't navigate if no room was specified.