From f6cf7405074d562c67960af6d21f1725ae879d1c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sun, 27 Aug 2023 22:11:22 +0200 Subject: [PATCH] add emoji support --- website/src/repl/Repl.jsx | 17 +++++------------ website/src/repl/helpers.mjs | 25 +++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 12 deletions(-) create mode 100644 website/src/repl/helpers.mjs diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx index 4bca419a..8dafe8a4 100644 --- a/website/src/repl/Repl.jsx +++ b/website/src/repl/Repl.jsx @@ -5,15 +5,7 @@ This program is free software: you can redistribute it and/or modify it under th */ import { cleanupDraw, cleanupUi, controls, evalScope, getDrawContext, logger } from '@strudel.cycles/core'; -import { - CodeMirror, - cx, - flash, - useHighlighting, - useStrudel, - useKeydown, - updateMiniLocations, -} from '@strudel.cycles/react'; +import { CodeMirror, cx, flash, useHighlighting, useStrudel, useKeydown } from '@strudel.cycles/react'; import { getAudioContext, initAudioOnFirstClick, resetLoadedSounds, webaudioOutput } from '@strudel.cycles/webaudio'; import { createClient } from '@supabase/supabase-js'; import { nanoid } from 'nanoid'; @@ -28,6 +20,7 @@ import { themes } from './themes.mjs'; import { settingsMap, useSettings, setLatestCode } from '../settings.mjs'; import Loader from './Loader'; import { settingPatterns } from '../settings.mjs'; +import { code2hash, hash2code } from './helpers.mjs'; const { latestCode } = settingsMap.get(); @@ -73,11 +66,11 @@ async function initCode() { try { const initialUrl = window.location.href; const hash = initialUrl.split('?')[1]?.split('#')?.[0]; - const codeParam = window.location.href.split('#')[1]; + const codeParam = window.location.href.split('#')[1] || ''; // looking like https://strudel.tidalcycles.org/?J01s5i1J0200 (fixed hash length) if (codeParam) { // looking like https://strudel.tidalcycles.org/#ImMzIGUzIg%3D%3D (hash length depends on code length) - return atob(decodeURIComponent(codeParam || '')); + return hash2code(codeParam); } else if (hash) { return supabase .from('code') @@ -142,7 +135,7 @@ export function Repl({ embedded = false }) { setMiniLocations(meta.miniLocations); setPending(false); setLatestCode(code); - window.location.hash = '#' + encodeURIComponent(btoa(code)); + window.location.hash = '#' + code2hash(code); }, onEvalError: (err) => { setPending(false); diff --git a/website/src/repl/helpers.mjs b/website/src/repl/helpers.mjs new file mode 100644 index 00000000..b86e76f1 --- /dev/null +++ b/website/src/repl/helpers.mjs @@ -0,0 +1,25 @@ +export function unicodeToBase64(text) { + const utf8Bytes = new TextEncoder().encode(text); + const base64String = btoa(String.fromCharCode(...utf8Bytes)); + return base64String; +} + +export function base64ToUnicode(base64String) { + const utf8Bytes = new Uint8Array( + atob(base64String) + .split('') + .map((char) => char.charCodeAt(0)), + ); + const decodedText = new TextDecoder().decode(utf8Bytes); + return decodedText; +} + +export function code2hash(code) { + return encodeURIComponent(unicodeToBase64(code)); + //return '#' + encodeURIComponent(btoa(code)); +} + +export function hash2code(hash) { + return base64ToUnicode(decodeURIComponent(hash)); + //return atob(decodeURIComponent(codeParam || '')); +}