feat(branding) add support for custom icons

pull/13817/head jitsi-meet_8946
Mihaela Dumitru 2 years ago committed by Saúl Ibarra Corretgé
parent cc344cb548
commit 36045100bf
  1. 10
      config.js
  2. 1
      react/features/app/middlewares.any.ts
  3. 17
      react/features/base/icons/components/SvgXmlIcon.native.tsx
  4. 26
      react/features/base/icons/components/SvgXmlIcon.web.tsx
  5. 32
      react/features/base/icons/components/withBranding.tsx
  6. 224
      react/features/base/icons/svg/constants.ts
  7. 344
      react/features/base/icons/svg/index.ts
  8. 29
      react/features/dynamic-branding/functions.any.ts
  9. 29
      react/features/dynamic-branding/middleware.any.ts
  10. 3
      react/features/dynamic-branding/middleware.native.ts
  11. 1
      react/features/dynamic-branding/middleware.web.ts
  12. 3
      react/features/dynamic-branding/reducer.ts

@ -1298,6 +1298,16 @@ var config = {
// A list of images that can be used as video backgrounds.
// When this field is present, the default images will be replaced with those provided.
virtualBackgrounds: ['https://example.com/img.jpg'],
// Object containing customized icons that should replace the default ones.
// The keys need to be the exact same icon names used in here:
// https://github.com/jitsi/jitsi-meet/blob/master/react/features/base/icons/svg/index.ts
// To avoid having the icons trimmed or displayed in an unexpected way, please provide svg
// files containing svg xml icons in the size that the default icons come in.
customIcons: {
IconArrowUp: 'https://example.com/arrow-up.svg',
IconDownload: 'https://example.com/download.svg',
IconRemoteControlStart: 'https://example.com/remote-start.svg',
},
// Object containing a theme's properties. It also supports partial overwrites of the main theme.
// For a list of all possible theme tokens and their current defaults, please check:
// https://github.com/jitsi/jitsi-meet/tree/master/resources/custom-theme/custom-theme.json

@ -27,6 +27,7 @@ import '../connection-indicator/middleware';
import '../deep-linking/middleware';
import '../device-selection/middleware';
import '../display-name/middleware';
import '../dynamic-branding/middleware';
import '../etherpad/middleware';
import '../filmstrip/middleware';
import '../follow-me/middleware';

@ -0,0 +1,17 @@
import React from 'react';
import { SvgFromXml } from 'react-native-svg';
/**
* SVG rendering component.
*
* @returns {JSX.Element}
*/
const SvgXmlIcon = ({ src, ...rest }: {
src: string;
}): JSX.Element => (
<SvgFromXml
override = { rest }
xml = { src } />
);
export default SvgXmlIcon;

@ -0,0 +1,26 @@
import React, { useMemo } from 'react';
/**
* SVG rendering component.
*
* @returns {JSX.Element}
*/
const SvgXmlIcon = ({ src, ...rest }: {
src: string;
}): JSX.Element => {
const svgDocument = new DOMParser().parseFromString(src, 'image/svg+xml');
const element = svgDocument.documentElement.outerHTML;
const attributes = useMemo(() => Object.entries(rest).map(
([ key, value ]) => `${key}="${value}"`)
.join(' '), [ rest ]);
const html = element.replace('<svg', `<svg ${attributes}`);
return (
<div // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML = {{ __html: html }}
{ ...rest } />
);
};
export default SvgXmlIcon;

@ -0,0 +1,32 @@
import React from 'react';
import { useSelector } from 'react-redux';
import { IReduxState } from '../../../app/types';
import SvgXmlIcon from './SvgXmlIcon';
/**
* Icon wrapper that checks for branding before returning the SVG component.
*
* @returns {JSX.Element}
*/
const withBranding = ({ DefaultIcon, iconName }: {
DefaultIcon: any;
iconName: string;
}) => (props: any) => {
const src = useSelector((state: IReduxState) =>
state['features/dynamic-branding']?.brandedIcons?.[iconName]
);
if (src) {
return (
<SvgXmlIcon
src = { src }
{ ...props } />
);
}
return <DefaultIcon { ...props } />;
};
export default withBranding;

@ -0,0 +1,224 @@
import { default as IconRecordAccount } from './account-record.svg';
import { default as IconAddUser } from './add-user.svg';
import { default as IconArrowBack } from './arrow-back.svg';
import { default as IconArrowDownLarge } from './arrow-down-large.svg';
import { default as IconArrowDown } from './arrow-down.svg';
import { default as IconArrowLeft } from './arrow-left.svg';
import { default as IconArrowRight } from './arrow-right.svg';
import { default as IconArrowUpLarge } from './arrow-up-large.svg';
import { default as IconArrowUp } from './arrow-up.svg';
import { default as IconBell } from './bell.svg';
import { default as IconBluetooth } from './bluetooth.svg';
import { default as IconCalendar } from './calendar.svg';
import { default as IconCameraRefresh } from './camera-refresh.svg';
import { default as IconCar } from './car.svg';
import { default as IconChatUnread } from './chat-unread.svg';
import { default as IconCheck } from './check.svg';
import { default as IconCloseCircle } from './close-circle.svg';
import { default as IconCloseLarge } from './close-large.svg';
import { default as IconCloudUpload } from './cloud-upload.svg';
import { default as IconCode } from './code.svg';
import { default as IconConnection } from './connection.svg';
import { default as IconRecordContact } from './contact-record.svg';
import { default as IconCopy } from './copy.svg';
import { default as IconDotsHorizontal } from './dots-horizontal.svg';
import { default as IconDownload } from './download.svg';
import { default as IconE2EE } from './e2ee.svg';
import { default as IconEdit } from './edit.svg';
import { default as IconEmotionsAngry } from './emotions-angry.svg';
import { default as IconEmotionsDisgusted } from './emotions-disgusted.svg';
import { default as IconEmotionsFearful } from './emotions-fearful.svg';
import { default as IconEmotionsHappy } from './emotions-happy.svg';
import { default as IconEmotionsNeutral } from './emotions-neutral.svg';
import { default as IconEmotionsSad } from './emotions-sad.svg';
import { default as IconEmotionsSurprised } from './emotions-surprised.svg';
import { default as IconEnlarge } from './enlarge.svg';
import { default as IconEnterFullscreen } from './enter-fullscreen.svg';
import { default as IconEnvelope } from './envelope.svg';
import { default as IconExclamationSolid } from './exclamation-solid.svg';
import { default as IconExclamationTriangle } from './exclamation-triangle.svg';
import { default as IconExitFullscreen } from './exit-fullscreen.svg';
import { default as IconFaceSmile } from './face-smile.svg';
import { default as IconFavoriteSolid } from './favorite-solid.svg';
import { default as IconFavorite } from './favorite.svg';
import { default as IconFeedback } from './feedback.svg';
import { default as IconGear } from './gear.svg';
import { default as IconGoogle } from './google.svg';
import { default as IconHangup } from './hangup.svg';
import { default as IconDeviceHeadphone } from './headset.svg';
import { default as IconHelp } from './help.svg';
import { default as IconHighlight } from './highlight.svg';
import { default as IconRingGroup } from './icon-ring-group.svg';
import { default as IconImage } from './image.svg';
import { default as IconInfoCircle } from './info-circle.svg';
import { default as IconInfo } from './info.svg';
import { default as IconRecordLead } from './lead-record.svg';
import { default as IconMessage } from './message.svg';
import { default as IconMeter } from './meter.svg';
import { default as IconMicSlash } from './mic-slash.svg';
import { default as IconMic } from './mic.svg';
import { default as IconModerator } from './moderator.svg';
import { default as IconConnectionInactive } from './ninja.svg';
import { default as IconNoiseSuppressionOff } from './noise-suppression-off.svg';
import { default as IconNoiseSuppressionOn } from './noise-suppression-on.svg';
import { default as IconOffice365 } from './office365.svg';
import { default as IconRecordOpportunity } from './opportunity-record.svg';
import { default as IconPerformance } from './performance.svg';
import { default as IconPhoneRinging } from './phone-ringing.svg';
import { default as IconPin } from './pin.svg';
import { default as IconPinned } from './pinned.svg';
import { default as IconPlay } from './play.svg';
import { default as IconPlus } from './plus.svg';
import { default as IconRaiseHand } from './raise-hand.svg';
import { default as IconRecord } from './record.svg';
import { default as IconReply } from './reply.svg';
import { default as IconRestore } from './restore.svg';
import { default as IconScreenshare } from './screenshare.svg';
import { default as IconSearch } from './search.svg';
import { default as IconSecurityOff } from './security-off.svg';
import { default as IconSecurityOn } from './security-on.svg';
import { default as IconSend } from './send.svg';
import { default as IconShareDoc } from './share-doc.svg';
import { default as IconShare } from './share.svg';
import { default as IconShortcuts } from './shortcuts.svg';
import { default as IconSip } from './sip.svg';
import { default as IconSites } from './sites.svg';
import { default as IconRemoteControlStart } from './start-remote-control.svg';
import { default as IconRemoteControlStop } from './stop-remote-control.svg';
import { default as IconStopScreenshare } from './stop-screenshare.svg';
import { default as IconStop } from './stop.svg';
import { default as IconSubtitles } from './subtitles.svg';
import { default as IconTileView } from './tile-view.svg';
import { default as IconTrash } from './trash.svg';
import { default as IconUserDeleted } from './user-deleted.svg';
import { default as IconUser } from './user.svg';
import { default as IconUsers } from './users.svg';
import { default as IconVideoOff } from './video-off.svg';
import { default as IconVideo } from './video.svg';
import { default as IconAudioOnlyOff } from './visibility-off.svg';
import { default as IconAudioOnly } from './visibility.svg';
import { default as IconVolumeOff } from './volume-off.svg';
import { default as IconVolumeUp } from './volume-up.svg';
import { default as IconWarningCircle } from './warning-circle.svg';
import { default as IconWarning } from './warning.svg';
import { default as IconWhiteboardHide } from './whiteboard-hide.svg';
import { default as IconWhiteboard } from './whiteboard.svg';
import { default as IconWifi1Bar } from './wifi-1.svg';
import { default as IconWifi2Bars } from './wifi-2.svg';
import { default as IconWifi3Bars } from './wifi-3.svg';
import { default as IconYahoo } from './yahoo.svg';
/**
* Map containing the default icons.
*/
export const DEFAULT_ICON: Record<string, any> = {
IconAddUser,
IconArrowBack,
IconArrowDown,
IconArrowDownLarge,
IconArrowLeft,
IconArrowUp,
IconArrowUpLarge,
IconAudioOnly,
IconAudioOnlyOff,
IconBluetooth,
IconBell,
IconCalendar,
IconCameraRefresh,
IconCar,
IconChatUnread,
IconCheck,
IconCloseCircle,
IconCloseLarge,
IconCloudUpload,
IconCode,
IconConnection,
IconConnectionInactive,
IconCopy,
IconDeviceHeadphone,
IconDotsHorizontal,
IconDownload,
IconE2EE,
IconEdit,
IconEnlarge,
IconEnterFullscreen,
IconEnvelope,
IconEmotionsAngry,
IconEmotionsDisgusted,
IconEmotionsFearful,
IconEmotionsHappy,
IconEmotionsNeutral,
IconEmotionsSad,
IconEmotionsSurprised,
IconExclamationSolid,
IconExclamationTriangle,
IconExitFullscreen,
IconFaceSmile,
IconFavorite,
IconFavoriteSolid,
IconFeedback,
IconGear,
IconGoogle,
IconHangup,
IconHelp,
IconHighlight,
IconImage,
IconInfo,
IconInfoCircle,
IconMessage,
IconMeter,
IconMic,
IconMicSlash,
IconModerator,
IconNoiseSuppressionOff,
IconNoiseSuppressionOn,
IconArrowRight,
IconOffice365,
IconPerformance,
IconPhoneRinging,
IconPin,
IconPinned,
IconPlay,
IconPlus,
IconRaiseHand,
IconRecord,
IconRecordAccount,
IconRecordContact,
IconRecordLead,
IconRecordOpportunity,
IconRemoteControlStart,
IconRemoteControlStop,
IconReply,
IconRestore,
IconRingGroup,
IconScreenshare,
IconSearch,
IconSecurityOff,
IconSecurityOn,
IconSend,
IconShare,
IconShareDoc,
IconShortcuts,
IconSip,
IconSites,
IconStop,
IconStopScreenshare,
IconSubtitles,
IconTileView,
IconTrash,
IconUserDeleted,
IconUsers,
IconUser,
IconVideo,
IconVideoOff,
IconVolumeOff,
IconVolumeUp,
IconWarning,
IconWarningCircle,
IconWhiteboard,
IconWhiteboardHide,
IconWifi1Bar,
IconWifi2Bars,
IconWifi3Bars,
IconYahoo
};

@ -1,109 +1,235 @@
export { default as IconAddUser } from './add-user.svg';
export { default as IconArrowBack } from './arrow-back.svg';
export { default as IconArrowDown } from './arrow-down.svg';
export { default as IconArrowDownLarge } from './arrow-down-large.svg';
export { default as IconArrowLeft } from './arrow-left.svg';
export { default as IconArrowUp } from './arrow-up.svg';
export { default as IconArrowUpLarge } from './arrow-up-large.svg';
export { default as IconAudioOnly } from './visibility.svg';
export { default as IconAudioOnlyOff } from './visibility-off.svg';
export { default as IconBluetooth } from './bluetooth.svg';
export { default as IconBell } from './bell.svg';
export { default as IconCalendar } from './calendar.svg';
export { default as IconCameraRefresh } from './camera-refresh.svg';
export { default as IconCar } from './car.svg';
export { default as IconChatUnread } from './chat-unread.svg';
export { default as IconCheck } from './check.svg';
export { default as IconCloseCircle } from './close-circle.svg';
export { default as IconCloseLarge } from './close-large.svg';
export { default as IconCloudUpload } from './cloud-upload.svg';
export { default as IconCode } from './code.svg';
export { default as IconConnection } from './connection.svg';
export { default as IconConnectionInactive } from './ninja.svg';
export { default as IconCopy } from './copy.svg';
export { default as IconDeviceHeadphone } from './headset.svg';
export { default as IconDotsHorizontal } from './dots-horizontal.svg';
export { default as IconDownload } from './download.svg';
export { default as IconE2EE } from './e2ee.svg';
export { default as IconEdit } from './edit.svg';
export { default as IconEnlarge } from './enlarge.svg';
export { default as IconEnterFullscreen } from './enter-fullscreen.svg';
export { default as IconEnvelope } from './envelope.svg';
export { default as IconEmotionsAngry } from './emotions-angry.svg';
export { default as IconEmotionsDisgusted } from './emotions-disgusted.svg';
export { default as IconEmotionsFearful } from './emotions-fearful.svg';
export { default as IconEmotionsHappy } from './emotions-happy.svg';
export { default as IconEmotionsNeutral } from './emotions-neutral.svg';
export { default as IconEmotionsSad } from './emotions-sad.svg';
export { default as IconEmotionsSurprised } from './emotions-surprised.svg';
export { default as IconExclamationSolid } from './exclamation-solid.svg';
export { default as IconExclamationTriangle } from './exclamation-triangle.svg';
export { default as IconExitFullscreen } from './exit-fullscreen.svg';
export { default as IconFaceSmile } from './face-smile.svg';
export { default as IconFavorite } from './favorite.svg';
export { default as IconFavoriteSolid } from './favorite-solid.svg';
export { default as IconFeedback } from './feedback.svg';
export { default as IconGear } from './gear.svg';
export { default as IconGoogle } from './google.svg';
export { default as IconHangup } from './hangup.svg';
export { default as IconHelp } from './help.svg';
export { default as IconHighlight } from './highlight.svg';
export { default as IconImage } from './image.svg';
export { default as IconInfo } from './info.svg';
export { default as IconInfoCircle } from './info-circle.svg';
export { default as IconMessage } from './message.svg';
export { default as IconMeter } from './meter.svg';
export { default as IconMic } from './mic.svg';
export { default as IconMicSlash } from './mic-slash.svg';
export { default as IconModerator } from './moderator.svg';
export { default as IconNoiseSuppressionOff } from './noise-suppression-off.svg';
export { default as IconNoiseSuppressionOn } from './noise-suppression-on.svg';
export { default as IconArrowRight } from './arrow-right.svg';
export { default as IconOffice365 } from './office365.svg';
export { default as IconPerformance } from './performance.svg';
export { default as IconPhoneRinging } from './phone-ringing.svg';
export { default as IconPin } from './pin.svg';
export { default as IconPinned } from './pinned.svg';
export { default as IconPlay } from './play.svg';
export { default as IconPlus } from './plus.svg';
export { default as IconRaiseHand } from './raise-hand.svg';
export { default as IconRecord } from './record.svg';
export { default as IconRecordAccount } from './account-record.svg';
export { default as IconRecordContact } from './contact-record.svg';
export { default as IconRecordLead } from './lead-record.svg';
export { default as IconRecordOpportunity } from './opportunity-record.svg';
export { default as IconRemoteControlStart } from './start-remote-control.svg';
export { default as IconRemoteControlStop } from './stop-remote-control.svg';
export { default as IconReply } from './reply.svg';
export { default as IconRestore } from './restore.svg';
export { default as IconRingGroup } from './icon-ring-group.svg';
export { default as IconScreenshare } from './screenshare.svg';
export { default as IconSearch } from './search.svg';
export { default as IconSecurityOff } from './security-off.svg';
export { default as IconSecurityOn } from './security-on.svg';
export { default as IconSend } from './send.svg';
export { default as IconShare } from './share.svg';
export { default as IconShareDoc } from './share-doc.svg';
export { default as IconShortcuts } from './shortcuts.svg';
export { default as IconSip } from './sip.svg';
export { default as IconSites } from './sites.svg';
export { default as IconStop } from './stop.svg';
export { default as IconStopScreenshare } from './stop-screenshare.svg';
export { default as IconSubtitles } from './subtitles.svg';
export { default as IconTileView } from './tile-view.svg';
export { default as IconTrash } from './trash.svg';
export { default as IconUserDeleted } from './user-deleted.svg';
export { default as IconUsers } from './users.svg';
export { default as IconUser } from './user.svg';
export { default as IconVideo } from './video.svg';
export { default as IconVideoOff } from './video-off.svg';
export { default as IconVolumeOff } from './volume-off.svg';
export { default as IconVolumeUp } from './volume-up.svg';
export { default as IconWarning } from './warning.svg';
export { default as IconWarningCircle } from './warning-circle.svg';
export { default as IconWhiteboard } from './whiteboard.svg';
export { default as IconWhiteboardHide } from './whiteboard-hide.svg';
export { default as IconWifi1Bar } from './wifi-1.svg';
export { default as IconWifi2Bars } from './wifi-2.svg';
export { default as IconWifi3Bars } from './wifi-3.svg';
export { default as IconYahoo } from './yahoo.svg';
import withBranding from '../components/withBranding';
import { DEFAULT_ICON } from './constants';
const {
IconAddUser,
IconArrowBack,
IconArrowDown,
IconArrowDownLarge,
IconArrowLeft,
IconArrowUp,
IconArrowUpLarge,
IconAudioOnly,
IconAudioOnlyOff,
IconBluetooth,
IconBell,
IconCalendar,
IconCameraRefresh,
IconCar,
IconChatUnread,
IconCheck,
IconCloseCircle,
IconCloseLarge,
IconCloudUpload,
IconCode,
IconConnection,
IconConnectionInactive,
IconCopy,
IconDeviceHeadphone,
IconDotsHorizontal,
IconDownload,
IconE2EE,
IconEdit,
IconEnlarge,
IconEnterFullscreen,
IconEnvelope,
IconEmotionsAngry,
IconEmotionsDisgusted,
IconEmotionsFearful,
IconEmotionsHappy,
IconEmotionsNeutral,
IconEmotionsSad,
IconEmotionsSurprised,
IconExclamationSolid,
IconExclamationTriangle,
IconExitFullscreen,
IconFaceSmile,
IconFavorite,
IconFavoriteSolid,
IconFeedback,
IconGear,
IconGoogle,
IconHangup,
IconHelp,
IconHighlight,
IconImage,
IconInfo,
IconInfoCircle,
IconMessage,
IconMeter,
IconMic,
IconMicSlash,
IconModerator,
IconNoiseSuppressionOff,
IconNoiseSuppressionOn,
IconArrowRight,
IconOffice365,
IconPerformance,
IconPhoneRinging,
IconPin,
IconPinned,
IconPlay,
IconPlus,
IconRaiseHand,
IconRecord,
IconRecordAccount,
IconRecordContact,
IconRecordLead,
IconRecordOpportunity,
IconRemoteControlStart,
IconRemoteControlStop,
IconReply,
IconRestore,
IconRingGroup,
IconScreenshare,
IconSearch,
IconSecurityOff,
IconSecurityOn,
IconSend,
IconShare,
IconShareDoc,
IconShortcuts,
IconSip,
IconSites,
IconStop,
IconStopScreenshare,
IconSubtitles,
IconTileView,
IconTrash,
IconUserDeleted,
IconUsers,
IconUser,
IconVideo,
IconVideoOff,
IconVolumeOff,
IconVolumeUp,
IconWarning,
IconWarningCircle,
IconWhiteboard,
IconWhiteboardHide,
IconWifi1Bar,
IconWifi2Bars,
IconWifi3Bars,
IconYahoo
} = Object.keys(DEFAULT_ICON).reduce((exportedIcons: Record<string, any>, key) => {
return {
...exportedIcons,
[key]: withBranding({
iconName: key,
DefaultIcon: DEFAULT_ICON[key]
})
};
}, {});
export {
IconAddUser,
IconArrowBack,
IconArrowDown,
IconArrowDownLarge,
IconArrowLeft,
IconArrowUp,
IconArrowUpLarge,
IconAudioOnly,
IconAudioOnlyOff,
IconBluetooth,
IconBell,
IconCalendar,
IconCameraRefresh,
IconCar,
IconChatUnread,
IconCheck,
IconCloseCircle,
IconCloseLarge,
IconCloudUpload,
IconCode,
IconConnection,
IconConnectionInactive,
IconCopy,
IconDeviceHeadphone,
IconDotsHorizontal,
IconDownload,
IconE2EE,
IconEdit,
IconEnlarge,
IconEnterFullscreen,
IconEnvelope,
IconEmotionsAngry,
IconEmotionsDisgusted,
IconEmotionsFearful,
IconEmotionsHappy,
IconEmotionsNeutral,
IconEmotionsSad,
IconEmotionsSurprised,
IconExclamationSolid,
IconExclamationTriangle,
IconExitFullscreen,
IconFaceSmile,
IconFavorite,
IconFavoriteSolid,
IconFeedback,
IconGear,
IconGoogle,
IconHangup,
IconHelp,
IconHighlight,
IconImage,
IconInfo,
IconInfoCircle,
IconMessage,
IconMeter,
IconMic,
IconMicSlash,
IconModerator,
IconNoiseSuppressionOff,
IconNoiseSuppressionOn,
IconArrowRight,
IconOffice365,
IconPerformance,
IconPhoneRinging,
IconPin,
IconPinned,
IconPlay,
IconPlus,
IconRaiseHand,
IconRecord,
IconRecordAccount,
IconRecordContact,
IconRecordLead,
IconRecordOpportunity,
IconRemoteControlStart,
IconRemoteControlStop,
IconReply,
IconRestore,
IconRingGroup,
IconScreenshare,
IconSearch,
IconSecurityOff,
IconSecurityOn,
IconSend,
IconShare,
IconShareDoc,
IconShortcuts,
IconSip,
IconSites,
IconStop,
IconStopScreenshare,
IconSubtitles,
IconTileView,
IconTrash,
IconUserDeleted,
IconUsers,
IconUser,
IconVideo,
IconVideoOff,
IconVolumeOff,
IconVolumeUp,
IconWarning,
IconWarningCircle,
IconWhiteboard,
IconWhiteboardHide,
IconWifi1Bar,
IconWifi2Bars,
IconWifi3Bars,
IconYahoo
};

@ -2,6 +2,7 @@ import { IReduxState } from '../app/types';
import { IStateful } from '../base/app/types';
import { toState } from '../base/redux/functions';
import logger from './logger';
/**
* Extracts the fqn part from a path, where fqn represents
@ -64,3 +65,31 @@ export async function getDynamicBrandingUrl(stateful: IStateful) {
export function isDynamicBrandingDataLoaded(state: IReduxState) {
return state['features/dynamic-branding'].customizationReady;
}
/**
* 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;
};

@ -0,0 +1,29 @@
import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { SET_DYNAMIC_BRANDING_DATA } from './actionTypes';
import { fetchCustomIcons } from './functions.any';
import logger from './logger';
MiddlewareRegistry.register(() => next => action => {
switch (action.type) {
case SET_DYNAMIC_BRANDING_DATA: {
const { customIcons } = action.value;
if (customIcons) {
fetchCustomIcons(customIcons)
.then(localCustomIcons => {
action.value.brandedIcons = localCustomIcons;
return next(action);
})
.catch((error: any) => {
logger.error('Error fetching branded custom icons:', error);
});
}
break;
}
}
return next(action);
});

@ -4,6 +4,7 @@ import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
import { SET_DYNAMIC_BRANDING_DATA } from './actionTypes';
import { fetchCustomBrandingData } from './actions.native';
import './middleware.any';
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {
@ -20,6 +21,7 @@ MiddlewareRegistry.register(store => next => action => {
avatarBackgrounds = [],
backgroundColor,
backgroundImageUrl,
brandedIcons,
didPageUrl,
inviteDomain
} = action.value;
@ -28,6 +30,7 @@ MiddlewareRegistry.register(store => next => action => {
avatarBackgrounds,
backgroundColor,
backgroundImageUrl,
brandedIcons,
didPageUrl,
inviteDomain
};

@ -5,6 +5,7 @@ import { SET_DYNAMIC_BRANDING_DATA } from './actionTypes';
import { fetchCustomBrandingData } from './actions.any';
import { createMuiBrandingTheme } from './functions.web';
import './middleware.any';
MiddlewareRegistry.register(store => next => action => {
switch (action.type) {

@ -146,6 +146,7 @@ export interface IDynamicBrandingState {
avatarBackgrounds: string[];
backgroundColor: string;
backgroundImageUrl: string;
brandedIcons?: Record<string, string>;
customizationFailed: boolean;
customizationReady: boolean;
defaultBranding: boolean;
@ -171,6 +172,7 @@ ReducerRegistry.register<IDynamicBrandingState>(STORE_NAME, (state = DEFAULT_STA
avatarBackgrounds,
backgroundColor,
backgroundImageUrl,
brandedIcons,
defaultBranding,
didPageUrl,
inviteDomain,
@ -187,6 +189,7 @@ ReducerRegistry.register<IDynamicBrandingState>(STORE_NAME, (state = DEFAULT_STA
avatarBackgrounds,
backgroundColor,
backgroundImageUrl,
brandedIcons,
defaultBranding,
didPageUrl,
inviteDomain,

Loading…
Cancel
Save