cleaning up
This commit is contained in:
parent
7adfe6f2df
commit
6cb156d876
6 changed files with 249 additions and 390 deletions
|
|
@ -12,18 +12,17 @@ import { defaultAudioDeviceName } from '../settings.mjs';
|
|||
import { getAudioDevices, setAudioDevice } from './util.mjs';
|
||||
import { StrudelMirror, defaultSettings } from '@strudel/codemirror';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { settingsMap, useSettings } from '../settings.mjs';
|
||||
import {
|
||||
initUserCode,
|
||||
setActivePattern,
|
||||
setLatestCode,
|
||||
settingsMap,
|
||||
useSettings,
|
||||
getViewingPattern,
|
||||
setViewingPattern,
|
||||
createPatternID,
|
||||
userPattern,
|
||||
getNextCloneID,
|
||||
} from '../settings.mjs';
|
||||
getViewingPatternData,
|
||||
setViewingPatternData,
|
||||
} from '../user_pattern_utils.mjs';
|
||||
import { Header } from './Header';
|
||||
import Loader from './Loader';
|
||||
import { Panel } from './panel/Panel';
|
||||
|
|
@ -32,12 +31,8 @@ import { prebake } from './prebake.mjs';
|
|||
import { getRandomTune, initCode, loadModules, shareCode, ReplContext } from './util.mjs';
|
||||
import PlayCircleIcon from '@heroicons/react/20/solid/PlayCircleIcon';
|
||||
import './Repl.css';
|
||||
import { useExamplePatterns } from './useExamplePatterns';
|
||||
|
||||
const { code: randomTune, name } = getRandomTune();
|
||||
|
||||
//
|
||||
|
||||
const { latestCode } = settingsMap.get();
|
||||
|
||||
let modulesLoading, presets, drawContext, clearCanvas, isIframe;
|
||||
|
|
@ -50,8 +45,6 @@ if (typeof window !== 'undefined') {
|
|||
isIframe = window.location !== window.parent.location;
|
||||
}
|
||||
|
||||
let viewingPatternData = { id: '', code: null, collection: userPattern.source };
|
||||
|
||||
export function Repl({ embedded = false }) {
|
||||
const isEmbedded = embedded || isIframe;
|
||||
const { panelPosition, isZen } = useSettings();
|
||||
|
|
@ -83,23 +76,24 @@ export function Repl({ embedded = false }) {
|
|||
const { code } = all;
|
||||
setLatestCode(code);
|
||||
window.location.hash = '#' + code2hash(code);
|
||||
const viewingPatternData = getViewingPatternData();
|
||||
|
||||
const data = { ...viewingPatternData, code };
|
||||
let id = getViewingPattern();
|
||||
const isExamplePattern = viewingPatternData.collection != userPattern.source;
|
||||
let id = data.id;
|
||||
const isExamplePattern = viewingPatternData.collection !== userPattern.collection;
|
||||
|
||||
if (isExamplePattern) {
|
||||
const codeHasChanged = code !== viewingPatternData.code;
|
||||
if (codeHasChanged) {
|
||||
// fork example
|
||||
id = getNextCloneID(id);
|
||||
id = createPatternID();
|
||||
setViewingPattern(id);
|
||||
viewingPatternData = userPattern.update(id, data).data;
|
||||
setViewingPatternData(userPattern.update(id, data).data);
|
||||
}
|
||||
} else {
|
||||
id = id == null ? createPatternID() : id;
|
||||
setViewingPattern(id);
|
||||
viewingPatternData = userPattern.update(id, data).data;
|
||||
setViewingPatternData(userPattern.update(id, data).data);
|
||||
}
|
||||
setActivePattern(id);
|
||||
},
|
||||
|
|
@ -176,7 +170,7 @@ export function Repl({ embedded = false }) {
|
|||
};
|
||||
|
||||
const handleUpdate = async (id, data, reset = false) => {
|
||||
viewingPatternData = data;
|
||||
setViewingPatternData(data);
|
||||
if (reset) {
|
||||
await resetEditor();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,13 @@
|
|||
import { DocumentDuplicateIcon, PencilSquareIcon, TrashIcon } from '@heroicons/react/20/solid';
|
||||
|
||||
import { DocumentDuplicateIcon, TrashIcon } from '@heroicons/react/20/solid';
|
||||
import { useSettings } from '../../settings.mjs';
|
||||
import {
|
||||
$featuredPatterns,
|
||||
$publicPatterns,
|
||||
exportPatterns,
|
||||
importPatterns,
|
||||
useActivePattern,
|
||||
useViewingPattern,
|
||||
useSettings,
|
||||
userPattern,
|
||||
examplePattern,
|
||||
} from '../../settings.mjs';
|
||||
|
||||
} from '../../user_pattern_utils.mjs';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { getMetadata } from '../../metadata_parser';
|
||||
import { useExamplePatterns } from '../useExamplePatterns';
|
||||
|
||||
|
|
@ -24,19 +17,14 @@ function classNames(...classes) {
|
|||
|
||||
function PatternLabel({ pattern } /* : { pattern: Tables<'code'> } */) {
|
||||
const meta = useMemo(() => getMetadata(pattern.code), [pattern]);
|
||||
|
||||
return (
|
||||
<>{`${pattern.id}: ${meta.title ?? pattern.hash ?? 'unnamed'} by ${
|
||||
Array.isArray(meta.by) ? meta.by.join(',') : 'Anonymous'
|
||||
}`}</>
|
||||
<>{`${pattern.id}: ${
|
||||
meta.title ?? pattern.hash ?? new Date(pattern.created_at).toLocaleDateString() ?? 'unnamed'
|
||||
} by ${Array.isArray(meta.by) ? meta.by.join(',') : 'Anonymous'}`}</>
|
||||
);
|
||||
}
|
||||
|
||||
const getPatternLabel = (pattern) => {
|
||||
return `${pattern.id}: ${meta.title ?? pattern.hash ?? 'unnamed'} by ${
|
||||
Array.isArray(meta.by) ? meta.by.join(',') : 'Anonymous'
|
||||
}`;
|
||||
};
|
||||
|
||||
function PatternButton({ showOutline, onClick, pattern, showHiglight }) {
|
||||
return (
|
||||
<a
|
||||
|
|
@ -52,24 +40,6 @@ function PatternButton({ showOutline, onClick, pattern, showHiglight }) {
|
|||
);
|
||||
}
|
||||
|
||||
// function ListButton() {
|
||||
// return (
|
||||
// <a
|
||||
// key={pattern.id}
|
||||
// className={classNames(
|
||||
// 'mr-4 hover:opacity-50 cursor-pointer block',
|
||||
// pattern.hash === activePattern ? 'outline outline-1' : '',
|
||||
// )}
|
||||
// onClick={() => {
|
||||
// setActivePattern(pattern.hash);
|
||||
// context.handleUpdate(pattern.code, true);
|
||||
// }}
|
||||
// >
|
||||
// <PatternLabel pattern={pattern} />
|
||||
// </a>
|
||||
// );
|
||||
// }
|
||||
|
||||
function PatternButtons({ patterns, activePattern, onClick, viewingPattern, started }) {
|
||||
return (
|
||||
<div className="font-mono text-sm">
|
||||
|
|
@ -89,28 +59,27 @@ function PatternButtons({ patterns, activePattern, onClick, viewingPattern, star
|
|||
);
|
||||
}
|
||||
|
||||
function ActionButton({ children, onClick, label, labelIsHidden }) {
|
||||
return (
|
||||
<button className="hover:opacity-50" onClick={onClick} title={label}>
|
||||
{labelIsHidden !== true && label}
|
||||
{children}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
export function PatternsTab({ context }) {
|
||||
const activePattern = useActivePattern();
|
||||
const viewingPattern = useViewingPattern();
|
||||
const { userPatterns } = useSettings();
|
||||
const examplePatterns = useExamplePatterns();
|
||||
const collections = examplePatterns.collections;
|
||||
const examplesData = examplePatterns.patterns;
|
||||
|
||||
const updateCodeWindow = (id, data, reset = false) => {
|
||||
context.handleUpdate(id, data, reset);
|
||||
// if (patternSource === userPattern.source) {
|
||||
|
||||
// } else {
|
||||
// const source = otherPatterns.get(patternSource);
|
||||
// const data = source[id];
|
||||
// }
|
||||
};
|
||||
|
||||
const isUserPattern = userPatterns[viewingPattern] != null;
|
||||
|
||||
// const isExample = useMemo(() => activePattern && !!tunes[activePattern], [activePattern]);
|
||||
|
||||
return (
|
||||
<div className="px-4 w-full dark:text-white text-stone-900 space-y-4 pb-4">
|
||||
<section>
|
||||
|
|
@ -118,69 +87,56 @@ export function PatternsTab({ context }) {
|
|||
<div className="flex items-center mb-2 space-x-2 overflow-auto">
|
||||
<h1 className="text-xl">{`${viewingPattern}`}</h1>
|
||||
<div className="space-x-4 flex w-min">
|
||||
{/* {!isExample && (
|
||||
<button
|
||||
className="hover:opacity-50"
|
||||
onClick={() => {
|
||||
const { id, data } = userPattern.rename(viewingPattern);
|
||||
updateCodeWindow(id, data.code);
|
||||
}}
|
||||
title="Rename"
|
||||
>
|
||||
<PencilSquareIcon className="w-5 h-5" />
|
||||
</button>
|
||||
)} */}
|
||||
<button
|
||||
className="hover:opacity-50"
|
||||
<ActionButton
|
||||
label="Duplicate"
|
||||
onClick={() => {
|
||||
const { id, data } = userPattern.duplicate(viewingPattern);
|
||||
updateCodeWindow(id, data.code);
|
||||
const { id, data } = userPattern.duplicate(
|
||||
userPattern.getPatternData(id) ?? examplePatterns.patterns[id],
|
||||
);
|
||||
updateCodeWindow(id, data);
|
||||
}}
|
||||
title="Duplicate"
|
||||
labelIsHidden
|
||||
>
|
||||
<DocumentDuplicateIcon className="w-5 h-5" />
|
||||
</button>
|
||||
</ActionButton>
|
||||
{isUserPattern && (
|
||||
<button
|
||||
className="hover:opacity-50"
|
||||
<ActionButton
|
||||
label="Delete"
|
||||
onClick={() => {
|
||||
const { id, data } = userPattern.delete(viewingPattern);
|
||||
updateCodeWindow(id, { ...data, collection: userPattern.source });
|
||||
updateCodeWindow(id, { ...data, collection: userPattern.collection });
|
||||
}}
|
||||
title="Delete"
|
||||
labelIsHidden
|
||||
>
|
||||
<TrashIcon className="w-5 h-5" />
|
||||
</button>
|
||||
</ActionButton>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<PatternButtons
|
||||
onClick={(id) => updateCodeWindow(id, { ...userPatterns[id], collection: userPattern.source }, false)}
|
||||
onClick={(id) => updateCodeWindow(id, { ...userPatterns[id], collection: userPattern.collection }, false)}
|
||||
patterns={userPatterns}
|
||||
started={context.started}
|
||||
activePattern={activePattern}
|
||||
viewingPattern={viewingPattern}
|
||||
/>
|
||||
<div className="pr-4 space-x-4 border-b border-foreground mb-2 h-8 flex overflow-auto max-w-full items-center">
|
||||
<button
|
||||
className="hover:opacity-50"
|
||||
<ActionButton
|
||||
label="new"
|
||||
onClick={() => {
|
||||
const { id, data } = userPattern.create();
|
||||
updateCodeWindow(id, data.code);
|
||||
const { id, data } = userPattern.createAndAddToDB();
|
||||
updateCodeWindow(id, data);
|
||||
}}
|
||||
>
|
||||
new
|
||||
</button>
|
||||
<button
|
||||
className="hover:opacity-50"
|
||||
/>
|
||||
<ActionButton
|
||||
label="clear"
|
||||
onClick={() => {
|
||||
const { id, data } = userPattern.clearAll();
|
||||
updateCodeWindow(id, data.code);
|
||||
updateCodeWindow(id, data);
|
||||
}}
|
||||
>
|
||||
clear
|
||||
</button>
|
||||
/>
|
||||
|
||||
<label className="hover:opacity-50 cursor-pointer">
|
||||
<input
|
||||
style={{ display: 'none' }}
|
||||
|
|
@ -191,14 +147,11 @@ export function PatternsTab({ context }) {
|
|||
/>
|
||||
import
|
||||
</label>
|
||||
<button className="hover:opacity-50" onClick={() => exportPatterns()}>
|
||||
export
|
||||
</button>
|
||||
<ActionButton label="export" onClick={exportPatterns} />
|
||||
</div>
|
||||
</section>
|
||||
{Array.from(collections.keys()).map((collection) => {
|
||||
const patterns = collections.get(collection);
|
||||
|
||||
return (
|
||||
<section key={collection}>
|
||||
<h2 className="text-xl mb-2">{collection}</h2>
|
||||
|
|
|
|||
|
|
@ -1,34 +1,23 @@
|
|||
import { examplePattern, $featuredPatterns, $publicPatterns } from '../settings.mjs';
|
||||
import { $featuredPatterns, $publicPatterns } from '../user_pattern_utils.mjs';
|
||||
import { useStore } from '@nanostores/react';
|
||||
import { useCallback, useMemo } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import * as tunes from '../repl/tunes.mjs';
|
||||
|
||||
export const useExamplePatterns = () => {
|
||||
const featuredPatterns = useStore($featuredPatterns);
|
||||
const publicPatterns = useStore($publicPatterns);
|
||||
const collections = useMemo(() => {
|
||||
const stockPatterns = Object.fromEntries(Object.entries(tunes).map(([key, code], i) => [i, { id: i, code }]));
|
||||
const pats = new Map();
|
||||
pats.set('Featured', featuredPatterns);
|
||||
pats.set('Last Creations', publicPatterns);
|
||||
pats.set(examplePattern.source, examplePattern.getAll());
|
||||
pats.set('Stock Examples', stockPatterns);
|
||||
return pats;
|
||||
}, [featuredPatterns, publicPatterns]);
|
||||
|
||||
const patterns = useMemo(() => {
|
||||
const allPatterns = Object.assign({}, ...collections.values());
|
||||
return allPatterns;
|
||||
return Object.assign({}, ...collections.values());
|
||||
}, [collections]);
|
||||
|
||||
// const examplePatterns = examplePattern.getAll();
|
||||
|
||||
// const collections = new Map();
|
||||
// collections.set('Featured', featuredPatterns);
|
||||
// collections.set('Last Creations', publicPatterns);
|
||||
// collections.set(examplePattern.source, examplePatterns);
|
||||
// const patterns = {
|
||||
// ...examplePatterns,
|
||||
// ...publicPatterns,
|
||||
// ...examplePatterns,
|
||||
// };
|
||||
|
||||
return { patterns, collections };
|
||||
};
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import { createClient } from '@supabase/supabase-js';
|
|||
import { nanoid } from 'nanoid';
|
||||
import { writeText } from '@tauri-apps/api/clipboard';
|
||||
import { createContext } from 'react';
|
||||
import { $publicPatterns, $featuredPatterns } from '../settings.mjs';
|
||||
|
||||
// Create a single supabase client for interacting with your database
|
||||
export const supabase = createClient(
|
||||
|
|
@ -17,33 +16,6 @@ export const supabase = createClient(
|
|||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBpZHhkc3hwaGxoempuem1pZnRoIiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTYyMzA1NTYsImV4cCI6MTk3MTgwNjU1Nn0.bqlw7802fsWRnqU5BLYtmXk_k-D1VFmbkHMywWc15NM',
|
||||
);
|
||||
|
||||
export function loadPublicPatterns() {
|
||||
return supabase.from('code').select().eq('public', true).limit(20).order('id', { ascending: false });
|
||||
}
|
||||
|
||||
export function loadFeaturedPatterns() {
|
||||
return supabase.from('code').select().eq('featured', true).limit(20).order('id', { ascending: false });
|
||||
}
|
||||
|
||||
async function loadDBPatterns() {
|
||||
try {
|
||||
const { data: publicPatterns } = await loadPublicPatterns();
|
||||
const { data: featuredPatterns } = await loadFeaturedPatterns();
|
||||
const featured = {};
|
||||
const pub = {};
|
||||
publicPatterns?.forEach((data, key) => (pub[data.id ?? key] = data));
|
||||
featuredPatterns?.forEach((data, key) => (featured[data.id ?? key] = data));
|
||||
$publicPatterns.set(pub);
|
||||
$featuredPatterns.set(featured);
|
||||
} catch (err) {
|
||||
console.error('error loading patterns');
|
||||
}
|
||||
}
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
loadDBPatterns();
|
||||
}
|
||||
|
||||
export async function initCode() {
|
||||
// load code from url hash (either short hash from database or decode long hash)
|
||||
try {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue