From 204c9640503b9691fe0f7c2e736af7060ab96e0c Mon Sep 17 00:00:00 2001 From: Felix Roos Date: Sat, 13 Jan 2024 23:53:46 +0100 Subject: [PATCH] integrate public patterns into patterns tab --- website/src/components/SharedPatterns.tsx | 46 +++++++++----------- website/src/repl/panel/PatternsTab.jsx | 52 ++++++++++++++++++++++- website/src/repl/util.mjs | 10 ++++- website/src/settings.mjs | 31 +++++++++++++- 4 files changed, 108 insertions(+), 31 deletions(-) diff --git a/website/src/components/SharedPatterns.tsx b/website/src/components/SharedPatterns.tsx index bbd5cc8d..1cdca792 100644 --- a/website/src/components/SharedPatterns.tsx +++ b/website/src/components/SharedPatterns.tsx @@ -1,53 +1,43 @@ -import { createClient } from '@supabase/supabase-js'; import { useCallback, useEffect, useMemo, useState } from 'react'; -import type { Database, Tables } from '../../database.types'; +import type { Tables } from '../../database.types'; import { getMetadata } from '../metadata_parser'; +import { loadFeaturedPatterns, loadPublicPatterns } from '../repl/util.mjs'; -function PatternLink({ pattern }: { pattern: Tables<'code'> }) { +export function PatternLabel({ pattern }: { pattern: Tables<'code'> }) { const meta = useMemo(() => getMetadata(pattern.code), [pattern]); - // console.log('meta', meta); return ( - + <> {pattern.id}. {meta.title || pattern.hash} by {meta.by.join(',') || 'Anonymous'} - + ); } -export function SharedPatterns() { +export const usePublicPatterns = () => { const [publicPatterns, setPublicPatterns] = useState[] | null>([]); const [featuredPatterns, setFeaturedPatterns] = useState[] | null>([]); const init = useCallback(async () => { - const supabase = createClient( - 'https://pidxdsxphlhzjnzmifth.supabase.co', - 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InBpZHhkc3hwaGxoempuem1pZnRoIiwicm9sZSI6ImFub24iLCJpYXQiOjE2NTYyMzA1NTYsImV4cCI6MTk3MTgwNjU1Nn0.bqlw7802fsWRnqU5BLYtmXk_k-D1VFmbkHMywWc15NM', - ); - const { data: _publicPatterns } = await supabase - .from('code') - .select() - .eq('public', true) - .limit(20) - .order('id', { ascending: false }); - const { data: _featuredPatterns } = await supabase - .from('code') - .select() - .eq('featured', true) - .limit(20) - .order('id', { ascending: false }); + const { data: _publicPatterns } = await loadPublicPatterns(); + const { data: _featuredPatterns } = await loadFeaturedPatterns(); setPublicPatterns(_publicPatterns); setFeaturedPatterns(_featuredPatterns); - /* console.log('public', publicPatterns); - console.log('featured', featuredPatterns); */ }, []); useEffect(() => { init(); }, [useCallback]); + return { publicPatterns, featuredPatterns }; +}; + +export function SharedPatterns() { + const { publicPatterns, featuredPatterns } = usePublicPatterns(); return (

Featured

{featuredPatterns?.map((pattern, i) => (
- + + +
))}
@@ -55,7 +45,9 @@ export function SharedPatterns() {
{publicPatterns?.map((pattern, i) => (
- + + +
))}
diff --git a/website/src/repl/panel/PatternsTab.jsx b/website/src/repl/panel/PatternsTab.jsx index 4466b599..a3d67460 100644 --- a/website/src/repl/panel/PatternsTab.jsx +++ b/website/src/repl/panel/PatternsTab.jsx @@ -1,6 +1,8 @@ import { DocumentDuplicateIcon, PencilSquareIcon, TrashIcon } from '@heroicons/react/20/solid'; import { useMemo } from 'react'; import { + $featuredPatterns, + $publicPatterns, clearUserPatterns, deleteActivePattern, duplicateActivePattern, @@ -14,6 +16,8 @@ import { useSettings, } from '../../settings.mjs'; import * as tunes from '../tunes.mjs'; +import { PatternLabel } from '../../components/SharedPatterns'; +import { useStore } from '@nanostores/react'; function classNames(...classes) { return classes.filter(Boolean).join(' '); @@ -22,6 +26,8 @@ function classNames(...classes) { export function PatternsTab({ context }) { const { userPatterns } = useSettings(); const activePattern = useActivePattern(); + const featuredPatterns = useStore($featuredPatterns); + const publicPatterns = useStore($publicPatterns); const isExample = useMemo(() => activePattern && !!tunes[activePattern], [activePattern]); return (
@@ -94,8 +100,52 @@ export function PatternsTab({ context }) {
+ {featuredPatterns && ( +
+

Featured Patterns

+ +
+ )} + {publicPatterns && ( +
+

Last Creations

+ +
+ )}
-

Examples

+

Stock Examples

{Object.entries(tunes).map(([key, tune]) => ( { } initializeAudioOutput(); }; + +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 }); +} diff --git a/website/src/settings.mjs b/website/src/settings.mjs index 0e433806..2f973a2f 100644 --- a/website/src/settings.mjs +++ b/website/src/settings.mjs @@ -1,8 +1,22 @@ +import { atom } from 'nanostores'; import { persistentMap, persistentAtom } from '@nanostores/persistent'; import { useStore } from '@nanostores/react'; import { register } from '@strudel.cycles/core'; import * as tunes from './repl/tunes.mjs'; import { logger } from '@strudel.cycles/core'; +import { loadPublicPatterns, loadFeaturedPatterns } from './repl/util.mjs'; + +export let $publicPatterns = atom([]); +export let $featuredPatterns = atom([]); + +async function loadDBPatterns() { + const { data: publicPatterns } = await loadPublicPatterns(); + $publicPatterns.set(publicPatterns); + const { data: featuredPatterns } = await loadFeaturedPatterns(); + $featuredPatterns.set(featuredPatterns); +} + +loadDBPatterns(); export const defaultAudioDeviceName = 'System Standard'; @@ -172,12 +186,25 @@ export function updateUserCode(code) { setActivePattern(example); return; } - + const publicPattern = $publicPatterns.get().find((pat) => pat.code === code); + if (publicPattern) { + setActivePattern(publicPattern.hash); + return; + } + const featuredPattern = $featuredPatterns.get().find((pat) => pat.code === code); + if (featuredPattern) { + setActivePattern(featuredPattern.hash); + return; + } if (!activePattern) { // create new user pattern activePattern = newUserPattern(); setActivePattern(activePattern); - } else if (!!tunes[activePattern] && code !== tunes[activePattern]) { + } else if ( + (!!tunes[activePattern] && code !== tunes[activePattern]) || // fork example tune? + $publicPatterns.get().find((p) => p.hash === activePattern) || // fork public pattern? + $featuredPatterns.get().find((p) => p.hash === activePattern) // fork featured pattern? + ) { // fork example activePattern = getNextCloneName(activePattern); setActivePattern(activePattern);