diff --git a/website/src/repl/panel/PatternsTab.jsx b/website/src/repl/panel/PatternsTab.jsx
index 5cf9c8d6..083d93c4 100644
--- a/website/src/repl/panel/PatternsTab.jsx
+++ b/website/src/repl/panel/PatternsTab.jsx
@@ -1,8 +1,7 @@
-import { DocumentDuplicateIcon, TrashIcon } from '@heroicons/react/20/solid';
-import { useSettings } from '../../settings.mjs';
import {
exportPatterns,
importPatterns,
+ patternFilterName,
useActivePattern,
useViewingPatternData,
userPattern,
@@ -11,6 +10,8 @@ import { useMemo } from 'react';
import { getMetadata } from '../../metadata_parser';
import { useExamplePatterns } from '../useExamplePatterns';
import { parseJSON } from '../util.mjs';
+import { ButtonGroup } from './Forms.jsx';
+import { settingsMap, useSettings } from '../../settings.mjs';
function classNames(...classes) {
return classes.filter(Boolean).join(' ');
@@ -18,14 +19,22 @@ function classNames(...classes) {
function PatternLabel({ pattern } /* : { pattern: Tables<'code'> } */) {
const meta = useMemo(() => getMetadata(pattern.code), [pattern]);
+ let title = meta.title;
+ if (title == null) {
+ title == pattern.hash;
+ }
+ if (title == null) {
+ const date = new Date(pattern.created_at);
+ if (isNaN(date)) {
+ return;
+ }
+ title = date.toLocaleDateString();
+ }
+ if (title == null) {
+ title = 'unnamed';
+ }
- return (
- <>{`${pattern.id}: ${
- meta.title ?? pattern.hash ?? pattern.created_at != null
- ? new Date(pattern.created_at).toLocaleDateString()
- : 'unnamed'
- } by ${Array.isArray(meta.by) ? meta.by.join(',') : 'Anonymous'}`}>
- );
+ return <>{`${pattern.id}: ${title} by ${Array.isArray(meta.by) ? meta.by.join(',') : 'Anonymous'}`}>;
}
function PatternButton({ showOutline, onClick, pattern, showHiglight }) {
@@ -81,7 +90,7 @@ export function PatternsTab({ context }) {
const viewingPatternStore = useViewingPatternData();
const viewingPatternData = parseJSON(viewingPatternStore);
- const { userPatterns } = useSettings();
+ const { userPatterns, patternFilter } = useSettings();
const examplePatterns = useExamplePatterns();
const collections = examplePatterns.collections;
@@ -93,89 +102,91 @@ export function PatternsTab({ context }) {
const isUserPattern = userPatterns[viewingPatternID] != null;
return (
-
+
+
settingsMap.setKey('patternFilter', value)}
+ items={patternFilterName}
+ >
- {viewingIDIsValid && (
-
-
{`${viewingPatternID}`}
-
+ {patternFilter === patternFilterName.user && (
+
+
{
+ const { data } = userPattern.createAndAddToDB();
+ updateCodeWindow(data);
+ }}
+ />
+ {
const { data } = userPattern.duplicate(viewingPatternData);
updateCodeWindow(data);
}}
- labelIsHidden
- >
-
-
- {isUserPattern && (
- {
- const { data } = userPattern.delete(viewingPatternID);
- updateCodeWindow({ ...data, collection: userPattern.collection });
- }}
- labelIsHidden
- >
-
-
- )}
-
-
- )}
-
updateCodeWindow({ ...userPatterns[id], collection: userPattern.collection }, false)}
- patterns={userPatterns}
- started={context.started}
- activePattern={activePattern}
- viewingPatternID={viewingPatternID}
- />
-
-
- {Array.from(collections.keys()).map((collection) => {
- const patterns = collections.get(collection);
- return (
-
- {collection}
-
-
updateCodeWindow({ ...patterns[id], collection }, false)}
- started={context.started}
- patterns={patterns}
- activePattern={activePattern}
+ {
+ const { data } = userPattern.clearAll();
+ updateCodeWindow(data);
+ }}
/>
-
- );
- })}
+ {/* {viewingIDIsValid && (
+
+
{`${viewingPatternID}`}
+
+ )} */}
+
+ updateCodeWindow({ ...userPatterns[id], collection: userPattern.collection }, false)}
+ patterns={userPatterns}
+ started={context.started}
+ activePattern={activePattern}
+ viewingPatternID={viewingPatternID}
+ />
+
+ )}
+
+ {patternFilter !== patternFilterName.user &&
+ Array.from(collections.keys()).map((collection) => {
+ const patterns = collections.get(collection);
+ return (
+
+ {collection}
+
+
updateCodeWindow({ ...patterns[id], collection }, false)}
+ started={context.started}
+ patterns={patterns}
+ activePattern={activePattern}
+ />
+
+
+ );
+ })}
+
);
}
diff --git a/website/src/repl/useExamplePatterns.jsx b/website/src/repl/useExamplePatterns.jsx
index 92874db6..08629d44 100644
--- a/website/src/repl/useExamplePatterns.jsx
+++ b/website/src/repl/useExamplePatterns.jsx
@@ -4,7 +4,7 @@ import { useMemo } from 'react';
import * as tunes from '../repl/tunes.mjs';
export const stockPatterns = Object.fromEntries(
- Object.entries(tunes).map(([key, code], i) => [i, { id: i, code, collection: collectionName.stock }]),
+ Object.entries(tunes).map(([key, code], i) => [i, { id: i, code, collection: 'Stock Examples' }]),
);
export const useExamplePatterns = () => {
@@ -14,7 +14,7 @@ export const useExamplePatterns = () => {
const pats = new Map();
pats.set(collectionName.featured, featuredPatterns);
pats.set(collectionName.public, publicPatterns);
- pats.set(collectionName.stock, stockPatterns);
+ // pats.set(collectionName.stock, stockPatterns);
return pats;
}, [featuredPatterns, publicPatterns]);
diff --git a/website/src/settings.mjs b/website/src/settings.mjs
index 788e991c..80d18ad7 100644
--- a/website/src/settings.mjs
+++ b/website/src/settings.mjs
@@ -1,6 +1,7 @@
import { persistentMap } from '@nanostores/persistent';
import { useStore } from '@nanostores/react';
import { register } from '@strudel/core';
+import { patternFilterName } from './user_pattern_utils.mjs';
export const defaultAudioDeviceName = 'System Standard';
@@ -20,6 +21,7 @@ export const defaultSettings = {
latestCode: '',
isZen: false,
soundsFilter: 'all',
+ patternFilter: patternFilterName.community,
panelPosition: 'right',
userPatterns: '{}',
audioDeviceName: defaultAudioDeviceName,
diff --git a/website/src/user_pattern_utils.mjs b/website/src/user_pattern_utils.mjs
index 6d5c4e3e..f9fef8d2 100644
--- a/website/src/user_pattern_utils.mjs
+++ b/website/src/user_pattern_utils.mjs
@@ -16,6 +16,11 @@ export const collectionName = {
featured: 'Featured',
};
+export const patternFilterName = {
+ community: 'community',
+ user: 'user',
+};
+
export let $viewingPatternData = persistentAtom(
'viewingPatternData',
{