import { finales, initials, tones } from "./pinyin"; import { IState } from "./store"; import { SylPart, Syllable, Tone } from "./types"; import { GetSyllablesByInitAndFin, getRandomArray, toggleSylPart, toggle, included } from "./utils"; export enum ActionType { toggleOne, toggleAll, refresh, setPause, setCount, setStatus, playing, toneSelect } export enum ToggleType { init, fin } export type TogglePayload = { type: ToggleType, part: SylPart } export type Action = { type: ActionType, payload?: number | ToggleType | TogglePayload }; interface IFounds { foundSyllables:Syllable[], foundTones: Tone[], randomTones: Tone[] } interface IInitResult extends IFounds { allInitiales?:boolean, initiales: SylPart[] } interface IFinResult extends IFounds { allfinales?:boolean, finales: SylPart[] } interface IToneSelectResult extends IFounds { toneChecks: number[] } const proceedFounds = ( initiales: SylPart[], finales:SylPart[], tonesCheck:number[], count: number):IFounds=> { const foundSyllables:Syllable[] = GetSyllablesByInitAndFin( initiales, finales ) const foundTones = tones.filter( t => foundSyllables.some( syl => syl.tones.some( st => st===t.tone && included(tonesCheck, t.num) ) ) ) const randomTones = getRandomArray(foundTones, count) return { foundSyllables, foundTones, randomTones } } const ProceedAllInitials = (state: IState):IInitResult => { const toggled = state.allInitiales ? [] as SylPart[] : initials return { allInitiales: !state.allInitiales, initiales: toggled, ...proceedFounds(toggled, state.finales, state.toneChecks, state.sylCount) } } const ProceedAllFinales = (state: IState):IFinResult => { const toggled = state.allfinales ? [] as SylPart[] : finales return { allfinales: !state.allfinales, finales: toggled, ...proceedFounds(state.initiales, toggled, state.toneChecks, state.sylCount) } } const ProceedInitiale = (state: IState, index: SylPart):IInitResult => { const toggled = toggleSylPart(state.initiales,index) return { initiales: toggled, ...proceedFounds(toggled, state.finales, state.toneChecks, state.sylCount) } } const ProceedFinale = (state: IState, index: SylPart):IFinResult => { const toggled = toggleSylPart(state.finales,index) return { finales: toggled, ...proceedFounds(state.initiales, toggled, state.toneChecks, state.sylCount) } } const ProceedToneSelect = (state: IState, index: number):IToneSelectResult => { const toggled = toggle(state.toneChecks, index) return { toneChecks: toggled, ...proceedFounds(state.initiales, state.finales, toggled, state.sylCount) } } export const reducer = (state:IState, action:Action):IState => { switch (action.type) { case ActionType.setPause: return { ...state, sylPause: action.payload as number } case ActionType.setCount: return { ...state, sylCount: action.payload as number, randomTones: getRandomArray(state.foundTones, action.payload as number) } case ActionType.refresh: return { ...state, randomTones: getRandomArray(state.foundTones, state.sylCount)} case ActionType.toggleAll: { if (action.payload as ToggleType === ToggleType.init) return { ...state, ...ProceedAllInitials(state) } if (action.payload as ToggleType === ToggleType.fin) return { ...state, ...ProceedAllFinales(state) } return state } case ActionType.toggleOne: { if ( (action.payload as TogglePayload).type === ToggleType.init) return { ...state, ...ProceedInitiale(state, (action.payload as TogglePayload).part ) } if ( (action.payload as TogglePayload).type === ToggleType.fin) return { ...state, ...ProceedFinale(state, (action.payload as TogglePayload).part ) } return state } case ActionType.toneSelect: return { ...state, ...ProceedToneSelect(state, (action.payload as number) ) } default: return state } }