Svg: Fix Teact errors for filters (#5482)
This commit is contained in:
parent
f379461cbb
commit
18c8f4c58f
@ -86,7 +86,6 @@ import GiveawayModal from './premium/GiveawayModal.async';
|
|||||||
import PremiumMainModal from './premium/PremiumMainModal.async';
|
import PremiumMainModal from './premium/PremiumMainModal.async';
|
||||||
import StarsGiftingPickerModal from './premium/StarsGiftingPickerModal.async';
|
import StarsGiftingPickerModal from './premium/StarsGiftingPickerModal.async';
|
||||||
import SafeLinkModal from './SafeLinkModal.async';
|
import SafeLinkModal from './SafeLinkModal.async';
|
||||||
import SvgController from './SvgController';
|
|
||||||
import ConfettiContainer from './visualEffects/ConfettiContainer';
|
import ConfettiContainer from './visualEffects/ConfettiContainer';
|
||||||
import SnapEffectContainer from './visualEffects/SnapEffectContainer';
|
import SnapEffectContainer from './visualEffects/SnapEffectContainer';
|
||||||
import WaveContainer from './visualEffects/WaveContainer';
|
import WaveContainer from './visualEffects/WaveContainer';
|
||||||
@ -588,7 +587,6 @@ const Main = ({
|
|||||||
<DeleteFolderDialog folder={deleteFolderDialog} />
|
<DeleteFolderDialog folder={deleteFolderDialog} />
|
||||||
<ReactionPicker isOpen={isReactionPickerOpen} />
|
<ReactionPicker isOpen={isReactionPickerOpen} />
|
||||||
<DeleteMessageModal isOpen={isDeleteMessageModalOpen} />
|
<DeleteMessageModal isOpen={isDeleteMessageModalOpen} />
|
||||||
<SvgController />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,45 +0,0 @@
|
|||||||
import React, { memo, useEffect } from '../../lib/teact/teact';
|
|
||||||
|
|
||||||
import { createCallbackManager } from '../../util/callbacks';
|
|
||||||
import generateUniqueId from '../../util/generateUniqueId';
|
|
||||||
|
|
||||||
import useForceUpdate from '../../hooks/useForceUpdate';
|
|
||||||
|
|
||||||
import Portal from '../ui/Portal';
|
|
||||||
|
|
||||||
const DEFINITION_MAP = new Map<string, React.ReactElement>();
|
|
||||||
const CALLBACK_MANAGER = createCallbackManager();
|
|
||||||
|
|
||||||
const SvgController = () => {
|
|
||||||
const forceUpdate = useForceUpdate();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
return CALLBACK_MANAGER.addCallback(forceUpdate);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Portal>
|
|
||||||
<svg width="0" height="0" viewBox="0 0 1 1" className="svg-definitions">
|
|
||||||
<defs>
|
|
||||||
{Array.from(DEFINITION_MAP.values())}
|
|
||||||
</defs>
|
|
||||||
</svg>
|
|
||||||
</Portal>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default memo(SvgController);
|
|
||||||
|
|
||||||
export function addSvgDefinition(element: React.ReactElement, id?: string) {
|
|
||||||
id ??= generateUniqueId();
|
|
||||||
element.props.id = id;
|
|
||||||
|
|
||||||
DEFINITION_MAP.set(element.props.id, element);
|
|
||||||
CALLBACK_MANAGER.runCallbacks();
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function removeSvgDefinition(id: string) {
|
|
||||||
DEFINITION_MAP.delete(id);
|
|
||||||
CALLBACK_MANAGER.runCallbacks();
|
|
||||||
}
|
|
||||||
@ -9,12 +9,11 @@ import { SVG_NAMESPACE } from '../../../config';
|
|||||||
import { selectTabState } from '../../../global/selectors';
|
import { selectTabState } from '../../../global/selectors';
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import buildStyle from '../../../util/buildStyle';
|
import buildStyle from '../../../util/buildStyle';
|
||||||
|
import { addSvgDefinition, removeSvgDefinition } from '../../../util/svgController';
|
||||||
import windowSize from '../../../util/windowSize';
|
import windowSize from '../../../util/windowSize';
|
||||||
|
|
||||||
import useLastCallback from '../../../hooks/useLastCallback';
|
import useLastCallback from '../../../hooks/useLastCallback';
|
||||||
|
|
||||||
import { addSvgDefinition, removeSvgDefinition } from '../SvgController';
|
|
||||||
|
|
||||||
import styles from './WaveContainer.module.scss';
|
import styles from './WaveContainer.module.scss';
|
||||||
|
|
||||||
import waveRipple from '../../../assets/wave_ripple.svg';
|
import waveRipple from '../../../assets/wave_ripple.svg';
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
import React, { useEffect } from '../../lib/teact/teact';
|
import React, { useEffect } from '../../lib/teact/teact';
|
||||||
|
|
||||||
import { SVG_NAMESPACE } from '../../config';
|
import { SVG_NAMESPACE } from '../../config';
|
||||||
|
import { addSvgDefinition, removeSvgDefinition } from '../../util/svgController';
|
||||||
import { hexToRgb } from '../../util/switchTheme';
|
import { hexToRgb } from '../../util/switchTheme';
|
||||||
|
|
||||||
import { addSvgDefinition, removeSvgDefinition } from '../../components/main/SvgController';
|
|
||||||
|
|
||||||
const SVG_MAP = new Map<string, SvgColorFilter>();
|
const SVG_MAP = new Map<string, SvgColorFilter>();
|
||||||
|
|
||||||
class SvgColorFilter {
|
class SvgColorFilter {
|
||||||
|
|||||||
47
src/util/svgController.ts
Normal file
47
src/util/svgController.ts
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
import { SVG_NAMESPACE } from '../config';
|
||||||
|
import { requestMutation } from '../lib/fasterdom/fasterdom';
|
||||||
|
import jsxToHtml from './element/jsxToHtml';
|
||||||
|
import generateUniqueId from './generateUniqueId';
|
||||||
|
|
||||||
|
const DEFINITION_MAP = new Map<string, Element>();
|
||||||
|
|
||||||
|
let defs: SVGElement | undefined;
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
if (defs) return;
|
||||||
|
|
||||||
|
const container = document.createElementNS(SVG_NAMESPACE, 'svg');
|
||||||
|
container.setAttribute('width', '0');
|
||||||
|
container.setAttribute('height', '0');
|
||||||
|
container.setAttribute('viewBox', '0 0 1 1');
|
||||||
|
container.classList.add('svg-definitions');
|
||||||
|
document.body.appendChild(container);
|
||||||
|
|
||||||
|
defs = document.createElementNS(SVG_NAMESPACE, 'defs');
|
||||||
|
container.appendChild(defs);
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendElement(element: Element) {
|
||||||
|
requestMutation(() => {
|
||||||
|
if (!defs) init();
|
||||||
|
defs!.appendChild(element);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addSvgDefinition(element: React.JSX.Element, id?: string) {
|
||||||
|
id ??= generateUniqueId();
|
||||||
|
element.props.id = id;
|
||||||
|
|
||||||
|
const htmlElement = jsxToHtml(element)[0];
|
||||||
|
DEFINITION_MAP.set(element.props.id, htmlElement);
|
||||||
|
appendElement(htmlElement);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeSvgDefinition(id: string) {
|
||||||
|
const element = DEFINITION_MAP.get(id);
|
||||||
|
if (element) {
|
||||||
|
element.remove();
|
||||||
|
DEFINITION_MAP.delete(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user