diff --git a/package-lock.json b/package-lock.json index 01d628b..a9fcc91 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1382,6 +1382,10 @@ "license": "MIT" }, "node_modules/@types/react": { + + "version": "19.2.2", + "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.2.tgz", + "integrity": "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==", "version": "19.2.0", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.0.tgz", "integrity": "sha512-1LOH8xovvsKsCBq1wnT4ntDUdCJKmnEakhsuoUSy6ExlHCkGP2hqnatagYTgFk6oeL0VU31u7SNjunPN+GchtA==", @@ -1392,6 +1396,9 @@ } }, "node_modules/@types/react-dom": { + "version": "19.2.1", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.1.tgz", + "integrity": "sha512-/EEvYBdT3BflCWvTMO7YkYBHVE9Ci6XdqZciZANQgKpaiDRGOLIlRo91jbTNRQjgPFWVaRxcYc0luVNFitz57A==", "version": "19.2.0", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.2.0.tgz", "integrity": "sha512-brtBs0MnE9SMx7px208g39lRmC5uHZs96caOJfTjFcYSLHNamvaSMfJNagChVNkup2SdtOxKX1FDBkRSJe1ZAg==", @@ -1493,6 +1500,9 @@ "license": "MIT" }, "node_modules/baseline-browser-mapping": { + "version": "2.8.15", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.15.tgz", + "integrity": "sha512-qsJ8/X+UypqxHXN75M7dF88jNK37dLBRW7LeUzCPz+TNs37G8cfWy9nWzS+LS//g600zrt2le9KuXt0rWfDz5Q==", "version": "2.8.12", "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.8.12.tgz", "integrity": "sha512-vAPMQdnyKCBtkmQA6FMCBvU9qFIppS3nzyXnEM+Lo2IAhG4Mpjv9cCxMudhgV3YdNNJv6TNqXy97dfRVL2LmaQ==", @@ -1558,6 +1568,9 @@ } }, "node_modules/caniuse-lite": { + "version": "1.0.30001749", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001749.tgz", + "integrity": "sha512-0rw2fJOmLfnzCRbkm8EyHL8SvI2Apu5UbnQuTsJ0ClgrH8hcwFooJ1s5R0EP8o8aVrFu8++ae29Kt9/gZAZp/Q==", "version": "1.0.30001748", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001748.tgz", "integrity": "sha512-5P5UgAr0+aBmNiplks08JLw+AW/XG/SurlgZLgB1dDLfAw7EfRGxIwzPHxdSCGY/BTKDqIVyJL87cCN6s0ZR0w==", @@ -1686,6 +1699,9 @@ "license": "MIT" }, "node_modules/electron-to-chromium": { + "version": "1.5.234", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.234.tgz", + "integrity": "sha512-RXfEp2x+VRYn8jbKfQlRImzoJU01kyDvVPBmG39eU2iuRVhuS6vQNocB8J0/8GrIMLnPzgz4eW6WiRnJkTuNWg==", "version": "1.5.230", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.230.tgz", "integrity": "sha512-A6A6Fd3+gMdaed9wX83CvHYJb4UuapPD5X5SLq72VZJzxHSY0/LUweGXRWmQlh2ln7KV7iw7jnwXK7dlPoOnHQ==", @@ -2514,6 +2530,9 @@ } }, "node_modules/react-router": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.4.tgz", + "integrity": "sha512-SD3G8HKviFHg9xj7dNODUKDFgpG4xqD5nhyd0mYoB5iISepuZAvzSr8ywxgxKJ52yRzf/HWtVHc9AWwoTbljvA==", "version": "7.9.3", "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.9.3.tgz", "integrity": "sha512-4o2iWCFIwhI/eYAIL43+cjORXYn/aRQPgtFRRZb3VzoyQ5Uej0Bmqj7437L97N9NJW4wnicSwLOLS+yCXfAPgg==", @@ -2536,6 +2555,12 @@ } }, "node_modules/react-router-dom": { + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.4.tgz", + "integrity": "sha512-f30P6bIkmYvnHHa5Gcu65deIXoA2+r3Eb6PJIAddvsT9aGlchMatJ51GgpU470aSqRRbFX22T70yQNUGuW3DfA==", + "license": "MIT", + "dependencies": { + "react-router": "7.9.4" "version": "7.9.3", "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.9.3.tgz", "integrity": "sha512-1QSbA0TGGFKTAc/aWjpfW/zoEukYfU4dc1dLkT/vvf54JoGMkW+fNA+3oyo2gWVW1GM7BxjJVHz5GnPJv40rvg==", diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000..ce96794 Binary files /dev/null and b/public/favicon.ico differ diff --git a/public/manifest.json b/public/manifest.json new file mode 100644 index 0000000..7e33f37 --- /dev/null +++ b/public/manifest.json @@ -0,0 +1,8 @@ +{ + "name": "Sonara Synth", + "short_name": "Sonara", + "start_url": "/", + "display": "standalone", + "background_color": "#000", + "theme_color": "#00ff88" +} diff --git a/src/components/PresetControls.jsx b/src/components/PresetControls.jsx new file mode 100644 index 0000000..5a9dd14 --- /dev/null +++ b/src/components/PresetControls.jsx @@ -0,0 +1,35 @@ +import React, { useRef } from "react"; +import { savePreset, loadPreset } from "../utils/presetManager"; + +export default function PresetControls({ synthState, onPresetLoad }) { + const fileInputRef = useRef(); + + const handleLoadClick = () => fileInputRef.current.click(); + + const handleFileChange = (e) => { + const file = e.target.files[0]; + if (!file) return; + loadPreset( + file, + (preset) => { + onPresetLoad(preset); + alert("✅ Preset loaded successfully!"); + }, + (error) => alert("❌ Error loading preset: " + error) + ); + }; + + return ( +