[RN] Converge with Web's ExternalAPI a bit
Web's ExternalAPI accepts an object with properties as one of its constructor arguments and from which it generated a URL. Mobile's JitsiMeetView.loadURLObject is supposed to accept pretty much the same object.
This commit is contained in:
parent
9778aabe98
commit
e542af28a2
|
@ -1,5 +1,6 @@
|
|||
import EventEmitter from 'events';
|
||||
|
||||
import { urlObjectToString } from '../../../react/features/base/util';
|
||||
import {
|
||||
PostMessageTransportBackend,
|
||||
Transport
|
||||
|
@ -58,28 +59,6 @@ function changeParticipantNumber(APIInstance, number) {
|
|||
APIInstance._numberOfParticipants += number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates array with URL params based on the passed config object that will
|
||||
* be used for the Jitsi Meet URL generation.
|
||||
*
|
||||
* @param {Object} config - The config object.
|
||||
* @returns {Array<string>} The array with URL param strings.
|
||||
*/
|
||||
function configToURLParamsArray(config = {}) {
|
||||
const params = [];
|
||||
|
||||
for (const key in config) { // eslint-disable-line guard-for-in
|
||||
try {
|
||||
params.push(
|
||||
`${key}=${encodeURIComponent(JSON.stringify(config[key]))}`);
|
||||
} catch (e) {
|
||||
console.warn(`Error encoding ${key}: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the URL for the iframe.
|
||||
*
|
||||
|
@ -92,42 +71,17 @@ function configToURLParamsArray(config = {}) {
|
|||
* configuration options defined in interface_config.js to be overridden.
|
||||
* @param {string} [options.jwt] - The JWT token if needed by jitsi-meet for
|
||||
* authentication.
|
||||
* @param {boolean} [options.noSsl] - If the value is true https won't be used.
|
||||
* @param {boolean} [options.noSSL] - If the value is true https won't be used.
|
||||
* @param {string} [options.roomName] - The name of the room to join.
|
||||
* @returns {string} The URL.
|
||||
*/
|
||||
function generateURL(domain, options = {}) {
|
||||
const {
|
||||
configOverwrite,
|
||||
interfaceConfigOverwrite,
|
||||
jwt,
|
||||
noSSL,
|
||||
roomName
|
||||
} = options;
|
||||
|
||||
let url = `${noSSL ? 'http' : 'https'}://${domain}/${roomName || ''}`;
|
||||
|
||||
if (jwt) {
|
||||
url += `?jwt=${jwt}`;
|
||||
}
|
||||
|
||||
url += `#jitsi_meet_external_api_id=${id}`;
|
||||
|
||||
const configURLParams = configToURLParamsArray(configOverwrite);
|
||||
|
||||
if (configURLParams.length) {
|
||||
url += `&config.${configURLParams.join('&config.')}`;
|
||||
}
|
||||
|
||||
const interfaceConfigURLParams
|
||||
= configToURLParamsArray(interfaceConfigOverwrite);
|
||||
|
||||
if (interfaceConfigURLParams.length) {
|
||||
url += `&interfaceConfig.${
|
||||
interfaceConfigURLParams.join('&interfaceConfig.')}`;
|
||||
}
|
||||
|
||||
return url;
|
||||
return urlObjectToString({
|
||||
...options,
|
||||
url:
|
||||
`${options.noSSL ? 'http' : 'https'}://${domain
|
||||
}/#jitsi_meet_external_api_id=${id}`
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -90,17 +90,7 @@ function _appNavigateToMandatoryLocation(
|
|||
* @returns {void}
|
||||
*/
|
||||
function dispatchSetLocationURL() {
|
||||
dispatch(
|
||||
setLocationURL(
|
||||
new URL(
|
||||
(newLocation.protocol || 'https:')
|
||||
|
||||
// TODO userinfo
|
||||
|
||||
+ newLocation.host
|
||||
+ (newLocation.pathname || '/')
|
||||
+ newLocation.search
|
||||
+ newLocation.hash)));
|
||||
dispatch(setLocationURL(new URL(newLocation.toString())));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -147,9 +137,7 @@ function _appNavigateToOptionalLocation(
|
|||
}
|
||||
}
|
||||
|
||||
if (!location.protocol) {
|
||||
location.protocol = 'https:';
|
||||
}
|
||||
location.protocol || (location.protocol = 'https:');
|
||||
|
||||
_appNavigateToMandatoryLocation(dispatch, getState, location);
|
||||
}
|
||||
|
@ -213,5 +201,7 @@ function _loadConfig(location: Object) {
|
|||
|
||||
// TDOO userinfo
|
||||
|
||||
return loadConfig(protocol + location.host + (location.contextRoot || '/'));
|
||||
return (
|
||||
loadConfig(
|
||||
`${protocol}//${location.host}${location.contextRoot || '/'}`));
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
/* @flow */
|
||||
|
||||
/**
|
||||
* Parses the parameters from the URL and returns them as a JS object.
|
||||
* Parses the query/search or fragment/hash parameters out of a specific URL and
|
||||
* returns them as a JS object.
|
||||
*
|
||||
* @param {string} url - The URL to parse.
|
||||
* @param {boolean} dontParse - If false or undefined some transformations
|
||||
* (for parsing the value as JSON) are going to be executed.
|
||||
* @param {string} source - Values - "hash"/"search" if "search" the parameters
|
||||
* will parsed from location.search otherwise from location.hash.
|
||||
* @param {boolean} dontParse - If falsy, some transformations (for parsing the
|
||||
* value as JSON) will be executed.
|
||||
* @param {string} source - If {@code 'search'}, the parameters will parsed out
|
||||
* of {@code url.search}; otherwise, out of {@code url.hash}.
|
||||
* @returns {Object}
|
||||
*/
|
||||
export default function parseURLParams(
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
/* @flow */
|
||||
|
||||
/**
|
||||
* The {@link RegExp} pattern of the authority of a URI.
|
||||
*
|
||||
|
@ -127,6 +125,30 @@ export function getLocationContextRoot(location: Object) {
|
|||
: pathname.substring(0, contextRootEndIndex + 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@code Array} with URL parameter {@code String}s out of a
|
||||
* specific {@code Object}.
|
||||
*
|
||||
* @param {Object} obj - The {@code Object} to turn into URL parameter
|
||||
* {@code String}s.
|
||||
* @returns {Array<string>} The {@code Array} with URL parameter {@code String}s
|
||||
* constructed out of the specified {@code obj}.
|
||||
*/
|
||||
function _objectToURLParamsArray(obj = {}) {
|
||||
const params = [];
|
||||
|
||||
for (const key in obj) { // eslint-disable-line guard-for-in
|
||||
try {
|
||||
params.push(
|
||||
`${key}=${encodeURIComponent(JSON.stringify(obj[key]))}`);
|
||||
} catch (e) {
|
||||
console.warn(`Error encoding ${key}: ${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a specific URI string into an object with the well-known properties of
|
||||
* the {@link Location} and/or {@link URL} interfaces implemented by Web
|
||||
|
@ -147,7 +169,9 @@ export function getLocationContextRoot(location: Object) {
|
|||
export function parseStandardURIString(str: string) {
|
||||
/* eslint-disable no-param-reassign */
|
||||
|
||||
const obj = {};
|
||||
const obj = {
|
||||
toString: _standardURIToString
|
||||
};
|
||||
|
||||
let regex;
|
||||
let match;
|
||||
|
@ -200,9 +224,7 @@ export function parseStandardURIString(str: string) {
|
|||
str = str.substring(regex.lastIndex);
|
||||
}
|
||||
if (pathname) {
|
||||
if (!pathname.startsWith('/')) {
|
||||
pathname = `/${pathname}`;
|
||||
}
|
||||
pathname.startsWith('/') || (pathname = `/${pathname}`);
|
||||
} else {
|
||||
pathname = '/';
|
||||
}
|
||||
|
@ -263,6 +285,32 @@ export function parseURIString(uri: ?string) {
|
|||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements {@code href} and {@code toString} for the {@code Object} returned
|
||||
* by {@link #parseStandardURIString}.
|
||||
*
|
||||
* @param {Object} [thiz] - An {@code Object} returned by
|
||||
* {@code #parseStandardURIString} if any; otherwise, it is presumed that the
|
||||
* function is invoked on such an instance.
|
||||
* @returns {string}
|
||||
*/
|
||||
function _standardURIToString(thiz: ?Object) {
|
||||
// eslint-disable-next-line no-invalid-this
|
||||
const { hash, host, pathname, protocol, search } = thiz || this;
|
||||
let str = '';
|
||||
|
||||
protocol && (str += protocol);
|
||||
|
||||
// TODO userinfo
|
||||
|
||||
host && (str += `//${host}`);
|
||||
str += pathname || '/';
|
||||
search && (str += search);
|
||||
hash && (str += hash);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to return a {@code String} representation of a specific
|
||||
* {@code Object} which is supposed to represent a URL. Obviously, if a
|
||||
|
@ -285,7 +333,7 @@ export function toURLString(obj: ?(string | Object)): ?string {
|
|||
if (obj instanceof URL) {
|
||||
str = obj.href;
|
||||
} else {
|
||||
str = _urlObjectToString(obj);
|
||||
str = urlObjectToString(obj);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -303,12 +351,103 @@ export function toURLString(obj: ?(string | Object)): ?string {
|
|||
* {@code Object} similar to the one accepted by the constructor
|
||||
* of Web's ExternalAPI.
|
||||
*
|
||||
* @param {Object} obj - The URL to return a {@code String} representation of.
|
||||
* @param {Object} o - The URL to return a {@code String} representation of.
|
||||
* @returns {string} - A {@code String} representation of the specified
|
||||
* {@code obj}.
|
||||
* {@code Object}.
|
||||
*/
|
||||
function _urlObjectToString({ url }: Object): ?string {
|
||||
// TODO Support properties other than url. Support (pretty much) all
|
||||
// properties accepted by the constructor of Web's ExternalAPI.
|
||||
return url;
|
||||
export function urlObjectToString(o: Object): ?string {
|
||||
const url = parseStandardURIString(o.url || '');
|
||||
|
||||
// protocol
|
||||
if (!url.protocol) {
|
||||
let protocol = o.protocol || o.scheme;
|
||||
|
||||
if (protocol) {
|
||||
// Protocol is supposed to be the scheme and the final ':'. Anyway,
|
||||
// do not make a fuss if the final ':' is not there.
|
||||
protocol.endsWith(':') || (protocol += ':');
|
||||
url.protocol = protocol;
|
||||
}
|
||||
}
|
||||
|
||||
// authority & pathname
|
||||
let { pathname } = url;
|
||||
|
||||
if (!url.host) {
|
||||
// Web's ExternalAPI domain
|
||||
//
|
||||
// It may be host/hostname and pathname with the latter denoting the
|
||||
// tenant.
|
||||
const { host, hostname, pathname: contextRoot, port }
|
||||
= parseStandardURIString(o.domain || o.host || o.hostname);
|
||||
|
||||
// authority
|
||||
if (host) {
|
||||
url.host = host;
|
||||
url.hostname = hostname;
|
||||
url.port = port;
|
||||
}
|
||||
|
||||
// pathname
|
||||
pathname === '/' && contextRoot !== '/' && (pathname = contextRoot);
|
||||
}
|
||||
|
||||
// pathname
|
||||
|
||||
// Web's ExternalAPI roomName
|
||||
const room = o.roomName || o.room;
|
||||
|
||||
if (room
|
||||
&& (url.pathname.endsWith('/')
|
||||
|| !url.pathname.endsWith(`/${room}`))) {
|
||||
pathname.endsWith('/') || (pathname += '/');
|
||||
pathname += room;
|
||||
}
|
||||
|
||||
url.pathname = pathname;
|
||||
|
||||
// query/search
|
||||
|
||||
// Web's ExternalAPI jwt
|
||||
const { jwt } = o;
|
||||
|
||||
if (jwt) {
|
||||
let { search } = url;
|
||||
|
||||
if (search.indexOf('?jwt=') === -1 && search.indexOf('&jwt=') === -1) {
|
||||
search.startsWith('?') || (search = `?${search}`);
|
||||
search.length === 1 || (search += '&');
|
||||
search += `jwt=${jwt}`;
|
||||
|
||||
url.search = search;
|
||||
}
|
||||
}
|
||||
|
||||
// fragment/hash
|
||||
|
||||
let { hash } = url;
|
||||
|
||||
for (const configName of [ 'config', 'interfaceConfig' ]) {
|
||||
const urlParamsArray
|
||||
= _objectToURLParamsArray(
|
||||
o[`${configName}Overwrite`]
|
||||
|| o[configName]
|
||||
|| o[`${configName}Override`]);
|
||||
|
||||
if (urlParamsArray.length) {
|
||||
let urlParamsString
|
||||
= `${configName}.${urlParamsArray.join(`&${configName}.`)}`;
|
||||
|
||||
if (hash.length) {
|
||||
urlParamsString = `&${urlParamsString}`;
|
||||
} else {
|
||||
hash = '#';
|
||||
}
|
||||
hash += urlParamsString;
|
||||
}
|
||||
}
|
||||
|
||||
url.hash = hash;
|
||||
|
||||
return url.toString() || undefined;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue