From faaed61384caec34fba8c49c7aeb6f5f08f5cf42 Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Mon, 11 Dec 2023 22:01:08 +0100 Subject: [PATCH] fix: do not sync activePattern between tabs + only deselect activePattern if code in url differs --- website/src/repl/Repl.jsx | 18 ++++++++++++++--- website/src/repl/panel/PatternsTab.jsx | 4 +++- website/src/settings.mjs | 28 +++++++++++++++++--------- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/website/src/repl/Repl.jsx b/website/src/repl/Repl.jsx index 4ff92a80..32765477 100644 --- a/website/src/repl/Repl.jsx +++ b/website/src/repl/Repl.jsx @@ -17,7 +17,15 @@ import { prebake } from './prebake.mjs'; import * as tunes from './tunes.mjs'; import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon'; import { themes } from './themes.mjs'; -import { settingsMap, useSettings, setLatestCode, updateUserCode, setActivePattern } from '../settings.mjs'; +import { + settingsMap, + useSettings, + setLatestCode, + updateUserCode, + setActivePattern, + getActivePattern, + getUserPattern, +} from '../settings.mjs'; import Loader from './Loader'; import { settingPatterns } from '../settings.mjs'; import { code2hash, hash2code } from './helpers.mjs'; @@ -131,7 +139,6 @@ export function Repl({ embedded = false }) { isLineWrappingEnabled, panelPosition, isZen, - activePattern, } = useSettings(); const paintOptions = useMemo(() => ({ fontFamily }), [fontFamily]); @@ -177,7 +184,12 @@ export function Repl({ embedded = false }) { let msg; if (decoded) { setCode(decoded); - setActivePattern(''); + const activePattern = getActivePattern(); + if (getUserPattern(activePattern)?.code !== decoded) { + // code in url is not the last active patterns code => must be something else + // deselect last active pattern to not overwrite it on next evaluation + setActivePattern(''); + } msg = `I have loaded the code from the URL.`; } else if (latestCode) { setCode(latestCode); diff --git a/website/src/repl/panel/PatternsTab.jsx b/website/src/repl/panel/PatternsTab.jsx index 103eda19..4466b599 100644 --- a/website/src/repl/panel/PatternsTab.jsx +++ b/website/src/repl/panel/PatternsTab.jsx @@ -10,6 +10,7 @@ import { newUserPattern, renameActivePattern, setActivePattern, + useActivePattern, useSettings, } from '../../settings.mjs'; import * as tunes from '../tunes.mjs'; @@ -19,7 +20,8 @@ function classNames(...classes) { } export function PatternsTab({ context }) { - const { userPatterns, activePattern } = useSettings(); + const { userPatterns } = useSettings(); + const activePattern = useActivePattern(); const isExample = useMemo(() => activePattern && !!tunes[activePattern], [activePattern]); return (
diff --git a/website/src/settings.mjs b/website/src/settings.mjs index 2f76d68c..8a85e4a8 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -1,4 +1,4 @@ -import { persistentMap } from '@nanostores/persistent'; +import { persistentMap, persistentAtom } from '@nanostores/persistent'; import { useStore } from '@nanostores/react'; import { register } from '@strudel.cycles/core'; import * as tunes from './repl/tunes.mjs'; @@ -20,11 +20,23 @@ export const defaultSettings = { soundsFilter: 'all', panelPosition: 'bottom', userPatterns: '{}', - activePattern: '', }; export const settingsMap = persistentMap('strudel-settings', defaultSettings); +// active pattern is separate, because it shouldn't sync state across tabs +// reason: https://github.com/tidalcycles/strudel/issues/857 +const $activePattern = persistentAtom('activePattern', '', { listen: false }); +export function setActivePattern(key) { + $activePattern.set(key); +} +export function getActivePattern() { + return $activePattern.get(); +} +export function useActivePattern() { + return useStore($activePattern); +} + export function useSettings() { const state = useStore(settingsMap); return { @@ -117,7 +129,7 @@ export function getUserPattern(key) { } export function renameActivePattern() { - let activePattern = getSetting('activePattern'); + let activePattern = getActivePattern(); let userPatterns = getUserPatterns(); if (!userPatterns[activePattern]) { alert('Cannot rename examples'); @@ -140,7 +152,7 @@ export function renameActivePattern() { export function updateUserCode(code) { const userPatterns = getUserPatterns(); - let activePattern = getSetting('activePattern'); + let activePattern = getActivePattern(); // check if code is that of an example tune const [example] = Object.entries(tunes).find(([_, tune]) => tune === code) || []; if (example && (!activePattern || activePattern === example)) { @@ -161,7 +173,7 @@ export function updateUserCode(code) { } export function deleteActivePattern() { - let activePattern = getSetting('activePattern'); + let activePattern = getActivePattern(); if (!activePattern) { console.warn('cannot delete: no pattern selected'); return; @@ -179,7 +191,7 @@ export function deleteActivePattern() { } export function duplicateActivePattern() { - let activePattern = getSetting('activePattern'); + let activePattern = getActivePattern(); let latestCode = getSetting('latestCode'); if (!activePattern) { console.warn('cannot duplicate: no pattern selected'); @@ -191,10 +203,6 @@ export function duplicateActivePattern() { setActivePattern(activePattern); } -export function setActivePattern(key) { - settingsMap.setKey('activePattern', key); -} - export function importUserPatternJSON(jsonString) {} export async function importPatterns(fileList) {