pinyindct-open/src/reducer.ts

111 lines
3.9 KiB
TypeScript

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<number>(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<number>(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
}
}