2022-10-20 12:11:27 +03:00
|
|
|
import { IReduxState } from '../app/types';
|
2022-10-07 11:39:18 +03:00
|
|
|
import { IStateful } from '../base/app/types';
|
|
|
|
|
import { toState } from '../base/redux/functions';
|
2022-06-29 17:50:06 +03:00
|
|
|
|
2023-09-01 15:14:59 +03:00
|
|
|
import logger from './logger';
|
2021-11-16 23:16:18 +02:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Extracts the fqn part from a path, where fqn represents
|
|
|
|
|
* tenant/roomName.
|
|
|
|
|
*
|
2022-03-18 16:16:56 +02:00
|
|
|
* @param {Object} state - A redux state.
|
2021-11-16 23:16:18 +02:00
|
|
|
* @returns {string}
|
|
|
|
|
*/
|
2022-10-20 12:11:27 +03:00
|
|
|
export function extractFqnFromPath(state?: IReduxState) {
|
2022-03-18 16:16:56 +02:00
|
|
|
let pathname;
|
|
|
|
|
|
|
|
|
|
if (window.location.pathname) {
|
|
|
|
|
pathname = window.location.pathname;
|
2022-10-07 11:39:18 +03:00
|
|
|
} else if (state?.['features/base/connection']) {
|
|
|
|
|
pathname = state['features/base/connection'].locationURL?.pathname ?? '';
|
2022-03-18 16:16:56 +02:00
|
|
|
} else {
|
|
|
|
|
return '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const parts = pathname.split('/');
|
2021-11-16 23:16:18 +02:00
|
|
|
const len = parts.length;
|
|
|
|
|
|
2022-03-03 10:08:08 +02:00
|
|
|
return parts.length > 2 ? `${parts[len - 2]}/${parts[len - 1]}` : parts[1];
|
2021-11-16 23:16:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns the url used for fetching dynamic branding.
|
|
|
|
|
*
|
2022-06-29 17:50:06 +03:00
|
|
|
* @param {Object | Function} stateful - The redux store, state, or
|
|
|
|
|
* {@code getState} function.
|
2021-11-16 23:16:18 +02:00
|
|
|
* @returns {string}
|
|
|
|
|
*/
|
2022-10-07 11:39:18 +03:00
|
|
|
export async function getDynamicBrandingUrl(stateful: IStateful) {
|
2022-06-29 17:50:06 +03:00
|
|
|
const state = toState(stateful);
|
2022-07-13 09:53:15 +02:00
|
|
|
|
|
|
|
|
// NB: On web this is dispatched really early, before the config has been stored in the
|
|
|
|
|
// state. Thus, fetch it from the window global.
|
|
|
|
|
const config
|
|
|
|
|
= navigator.product === 'ReactNative' ? state['features/base/config'] : window.config;
|
2021-11-16 23:16:18 +02:00
|
|
|
const { dynamicBrandingUrl } = config;
|
|
|
|
|
|
|
|
|
|
if (dynamicBrandingUrl) {
|
|
|
|
|
return dynamicBrandingUrl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const { brandingDataUrl: baseUrl } = config;
|
2022-06-30 14:40:37 +03:00
|
|
|
const fqn = extractFqnFromPath(state);
|
2021-11-16 23:16:18 +02:00
|
|
|
|
|
|
|
|
if (baseUrl && fqn) {
|
|
|
|
|
return `${baseUrl}?conferenceFqn=${encodeURIComponent(fqn)}`;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Selector used for getting the load state of the dynamic branding data.
|
|
|
|
|
*
|
|
|
|
|
* @param {Object} state - Global state of the app.
|
|
|
|
|
* @returns {boolean}
|
|
|
|
|
*/
|
2022-10-20 12:11:27 +03:00
|
|
|
export function isDynamicBrandingDataLoaded(state: IReduxState) {
|
2021-11-16 23:16:18 +02:00
|
|
|
return state['features/dynamic-branding'].customizationReady;
|
|
|
|
|
}
|
2023-09-01 15:14:59 +03:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Fetch SVG XMLs from branding icons urls.
|
|
|
|
|
*
|
|
|
|
|
* @param {Object} customIcons - The map of branded icons.
|
|
|
|
|
* @returns {Object}
|
|
|
|
|
*/
|
|
|
|
|
export const fetchCustomIcons = async (customIcons: Record<string, string>) => {
|
|
|
|
|
const localCustomIcons: Record<string, string> = {};
|
|
|
|
|
|
|
|
|
|
for (const [ key, url ] of Object.entries(customIcons)) {
|
|
|
|
|
try {
|
|
|
|
|
const response = await fetch(url);
|
|
|
|
|
|
|
|
|
|
if (response.ok) {
|
|
|
|
|
const svgXml = await response.text();
|
|
|
|
|
|
|
|
|
|
localCustomIcons[key] = svgXml;
|
|
|
|
|
} else {
|
|
|
|
|
logger.error(`Failed to fetch ${url}. Status: ${response.status}`);
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
logger.error(`Error fetching ${url}:`, error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return localCustomIcons;
|
|
|
|
|
};
|