feat: merge mode_list.json into functional_chords.json
This commit is contained in:
+13
-11
@@ -45,28 +45,30 @@ function App() {
|
||||
|
||||
// Load all mode and chord data files in parallel
|
||||
try {
|
||||
const [modeListResponse, functionalChordsResponse] = await Promise.all([
|
||||
fetch(`${import.meta.env.BASE_URL}resources/modes/mode_list.json`),
|
||||
const [functionalChordsResponse] = await Promise.all([
|
||||
fetch(`${import.meta.env.BASE_URL}resources/modes/functional_chords.json`)
|
||||
]);
|
||||
|
||||
const [modeListData, functionalChordsData] = await Promise.all([
|
||||
modeListResponse.json(),
|
||||
const [functionalChordsData] = await Promise.all([
|
||||
functionalChordsResponse.json()
|
||||
]);
|
||||
|
||||
// Store mode data with id, name, and steps
|
||||
KGCore.MODE_DATA = modeListData.modes;
|
||||
console.log(`Loaded ${modeListData.modes.length} modes:`, modeListData.modes.map((m: { name: string }) => m.name));
|
||||
|
||||
// Store functional chords data (T/S/D by mode, including mode-specific chord notes)
|
||||
// Store functional chords data (includes name, steps, T/S/D groups, and chord notes for each mode)
|
||||
KGCore.FUNCTIONAL_CHORDS_DATA = functionalChordsData;
|
||||
console.log(`Loaded functional chords for ${Object.keys(functionalChordsData).length} modes`);
|
||||
} catch (error) {
|
||||
console.error('Failed to load mode/chord data:', error);
|
||||
// Fallback to defaults
|
||||
KGCore.MODE_DATA = [{ id: 'ionian', name: 'Ionian', steps: [2, 2, 1, 2, 2, 2, 1] }];
|
||||
KGCore.FUNCTIONAL_CHORDS_DATA = {};
|
||||
KGCore.FUNCTIONAL_CHORDS_DATA = {
|
||||
ionian: {
|
||||
name: 'Ionian',
|
||||
steps: [2, 2, 1, 2, 2, 2, 1],
|
||||
T: [],
|
||||
S: [],
|
||||
D: [],
|
||||
chords: {}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Log maxBars after initialization completes
|
||||
|
||||
@@ -38,7 +38,7 @@ const PianoRollToolbar: React.FC<PianoRollToolbarProps> = ({
|
||||
<div className="toolbar-left">
|
||||
{/* Left section with mode and chord guide dropdowns */}
|
||||
<KGDropdown
|
||||
options={KGCore.MODE_DATA.map(m => ({ label: m.name, value: m.id }))}
|
||||
options={Object.entries(KGCore.FUNCTIONAL_CHORDS_DATA).map(([id, data]) => ({ label: data.name, value: id }))}
|
||||
value={selectedMode}
|
||||
onChange={(value) => onModeChange(value)}
|
||||
label="Mode"
|
||||
|
||||
+1
-2
@@ -18,8 +18,7 @@ export class KGCore {
|
||||
private static _instance: KGCore | null = null;
|
||||
|
||||
// Global music data resources
|
||||
public static MODE_DATA: Array<{ id: string; name: string; steps: number[] }> = []; // Modes with id, display name, and interval steps
|
||||
public static FUNCTIONAL_CHORDS_DATA: Record<string, { T: string[]; S: string[]; D: string[]; chords: Record<string, string[]> }> = {}; // Functional chords by mode (T/S/D) with mode-specific chord notes
|
||||
public static FUNCTIONAL_CHORDS_DATA: Record<string, { name: string; steps: number[]; T: string[]; S: string[]; D: string[]; chords: Record<string, string[]> }> = {}; // Functional chords by mode (T/S/D) with mode-specific chord notes, and mode metadata
|
||||
|
||||
private currentProject: KGProject = new KGProject();
|
||||
|
||||
|
||||
@@ -16,15 +16,7 @@ import functionalChordsData from '../../public/resources/modes/functional_chords
|
||||
describe('scaleUtil', () => {
|
||||
// Setup: Mock KGCore with real chord data
|
||||
beforeEach(() => {
|
||||
// Mock MODE_DATA with ionian for basic tests
|
||||
KGCore.MODE_DATA = [
|
||||
{ id: 'ionian', name: 'Ionian', steps: [2, 2, 1, 2, 2, 2, 1] },
|
||||
{ id: 'dorian', name: 'Dorian', steps: [2, 1, 2, 2, 2, 1, 2] },
|
||||
{ id: 'aeolian', name: 'Aeolian', steps: [2, 1, 2, 2, 1, 2, 2] },
|
||||
{ id: 'mixolydian', name: 'Mixolydian', steps: [2, 2, 1, 2, 2, 1, 2] }
|
||||
]
|
||||
|
||||
// Use real functional chords data from JSON file
|
||||
// Use real functional chords data from JSON file (includes name, steps, and chord data)
|
||||
KGCore.FUNCTIONAL_CHORDS_DATA = functionalChordsData
|
||||
})
|
||||
|
||||
|
||||
@@ -66,12 +66,12 @@ export const getScalePitchClasses = (rootNote: string, modeSteps: number[]): num
|
||||
* @returns Array of interval steps, or default ionian if not found
|
||||
*/
|
||||
export const getModeSteps = (modeId: string): number[] => {
|
||||
const modeData = KGCore.MODE_DATA.find(m => m.id === modeId);
|
||||
if (!modeData) {
|
||||
const functionalChords = KGCore.FUNCTIONAL_CHORDS_DATA[modeId];
|
||||
if (!functionalChords || !functionalChords.steps) {
|
||||
console.warn(`Mode not found: ${modeId}, defaulting to ionian`);
|
||||
return [2, 2, 1, 2, 2, 2, 1]; // Default to ionian (major scale)
|
||||
}
|
||||
return modeData.steps;
|
||||
return functionalChords.steps;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user