diff --git a/frontend/dashboard/src/api/registry/overlays.ts b/frontend/dashboard/src/api/registry/overlays.ts index 98099240e..d042b319d 100644 --- a/frontend/dashboard/src/api/registry/overlays.ts +++ b/frontend/dashboard/src/api/registry/overlays.ts @@ -2,12 +2,23 @@ import { useMutation } from '@tanstack/vue-query'; import { protectedApiClient } from '@/api/twirp'; -function fromBinary(binary: string) { - const bytes = new Uint8Array(binary.length); - for (let i = 0; i < bytes.length; i++) { - bytes[i] = binary.charCodeAt(i); - } - return String.fromCharCode(...new Uint16Array(bytes.buffer)); +function b64EncodeUnicode(str: string) { + return btoa( + encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function toSolidBytes(match, p1) { + return String.fromCharCode(parseInt('0x' + p1)); + }), + ); +} + +function b64DecodeUnicode(str: string) { + return decodeURIComponent( + atob(str) + .split('') + .map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }) + .join(''), + ); } export const useOverlaysParseHtml = () => useMutation({ @@ -16,9 +27,9 @@ export const useOverlaysParseHtml = () => useMutation({ return ''; } const req = await protectedApiClient.overlaysParseHtml({ - html: btoa(htmlString), + html: b64EncodeUnicode(htmlString), }); - return fromBinary(req.response.html); + return b64DecodeUnicode(req.response.html); }, }); diff --git a/frontend/overlays/src/pages/overlaysRegistry.tsx b/frontend/overlays/src/pages/overlaysRegistry.tsx index a6a344526..14ae6b763 100644 --- a/frontend/overlays/src/pages/overlaysRegistry.tsx +++ b/frontend/overlays/src/pages/overlaysRegistry.tsx @@ -32,14 +32,6 @@ export interface LayerSettings { htmlOverlayJs: string } -function fromBase64(binary: string) { - const bytes = new Uint8Array(binary.length); - for (let i = 0; i < bytes.length; i++) { - bytes[i] = binary.charCodeAt(i); - } - return String.fromCharCode(...new Uint16Array(bytes.buffer)); -} - export const OverlaysRegistry: React.FC = () => { const [url, setUrl] = useState(null); const { apiKey, overlayId } = useParams(); @@ -142,7 +134,7 @@ export const OverlaysRegistry: React.FC = () => { return
{ textWrap: 'nowrap', }} className={'layer-' + layer.id} - dangerouslySetInnerHTML={{ __html: layer.htmlContent ? fromBase64(layer.htmlContent) : '' }} + dangerouslySetInnerHTML={{ __html: layer.htmlContent ? b64DecodeUnicode(layer.htmlContent) : '' }} /> ; })}
; }; + + +function b64EncodeUnicode(str: string) { + return btoa( + encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function toSolidBytes(match, p1) { + return String.fromCharCode(parseInt('0x' + p1)); + }), + ); +} + +function b64DecodeUnicode(str: string) { + return decodeURIComponent( + atob(str) + .split('') + .map(function (c) { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }) + .join(''), + ); +}