aaa
parent
dff64780f5
commit
55537aa02f
34
src/App.tsx
34
src/App.tsx
|
|
@ -2,24 +2,20 @@ import { useState } from 'react'
|
|||
import './App.css'
|
||||
import { Badge, Button, ListGroup } from 'react-bootstrap';
|
||||
import { initials, finales } from './data';
|
||||
import { BtnColor, Tone } from './types';
|
||||
import { BtnColor, Status, Tone } from './types';
|
||||
import { strings } from './strings';
|
||||
import { useStateContext } from './store';
|
||||
import { Params } from './params';
|
||||
import { ActionType, ToggleType } from './reducer';
|
||||
import { ButtonSet } from './buttons';
|
||||
|
||||
enum Status {params, plaing, plaied, showlist}
|
||||
|
||||
function App() {
|
||||
|
||||
|
||||
const { state, dispatch } = useStateContext();
|
||||
|
||||
//---------------- to found state
|
||||
const isFound = ():boolean => state.foundSyllables!.length > 0
|
||||
const [plaingNo, setPlaingNo ] = useState(0)
|
||||
|
||||
const [ status, setStatus ] = useState(Status.params)
|
||||
const setStatus = (status: Status) => { dispatch({ type: ActionType.setStatus, payload: status}) }
|
||||
|
||||
const beginDictation = (): void => {
|
||||
dispatch({ type: ActionType.refreshPlayList })
|
||||
|
|
@ -36,7 +32,7 @@ const playDictation2 = (randomTones: Tone[]) => {
|
|||
if ( audios.length == 0 ) return
|
||||
for(let x=0; x<audios.length-1;x++)
|
||||
{
|
||||
audios[x].onended = () => setTimeout( () => {
|
||||
audios[x].onended = () => setTimeout( () => {
|
||||
let pno = x+2
|
||||
setPlaingNo(pno)
|
||||
audios[x+1].play()
|
||||
|
|
@ -61,40 +57,44 @@ const refresh = () => {
|
|||
<>
|
||||
<h1>Диктант pīnyīn</h1>
|
||||
<ListGroup>
|
||||
<ListGroup.Item disabled={status != Status.params}>
|
||||
<ListGroup.Item disabled={state.status != Status.params}>
|
||||
<h2>{strings.selectInitiales}</h2>
|
||||
<ButtonSet source={initials} color={BtnColor.blue} toggle={ToggleType.init}/>
|
||||
</ListGroup.Item>
|
||||
|
||||
<ListGroup.Item disabled={status != Status.params}>
|
||||
<ListGroup.Item disabled={state.status != Status.params}>
|
||||
<h2>{strings.selectFinales}</h2>
|
||||
<ButtonSet source={finales} color={BtnColor.green} toggle={ToggleType.fin}/>
|
||||
</ListGroup.Item>
|
||||
|
||||
<ListGroup.Item disabled={status != Status.params}>
|
||||
<ListGroup.Item disabled={state.status != Status.params}>
|
||||
<h2>{strings.params}</h2>
|
||||
<Params/>
|
||||
</ListGroup.Item>
|
||||
<ListGroup.Item>
|
||||
{ status == Status.params &&
|
||||
{ state.status == Status.params &&
|
||||
<>
|
||||
Выбрано {state.initiales!.length} инициалей, {state.finales!.length} финалей, найдено {state.foundSyllables!.length} слогов, { state.foundTones!.length } тонов ,
|
||||
<br/>
|
||||
<Button variant={isFound() ? "success" : "secondary"} size="lg" onClick={()=>beginDictation()} disabled={!isFound()}>
|
||||
{isFound() ? "Начать диктант!" : "Выберите инициали и финали" }
|
||||
<Button
|
||||
variant={state.isFound!() ? "success" : "secondary"}
|
||||
size="lg"
|
||||
onClick={()=>beginDictation()}
|
||||
disabled={!state.isFound!()}>
|
||||
{state.isFound!() ? "Начать диктант!" : "Выберите инициали и финали" }
|
||||
</Button>
|
||||
</>
|
||||
}
|
||||
{
|
||||
status == Status.plaing &&
|
||||
state.status == Status.plaing &&
|
||||
<h1>Воспроизводится...{plaingNo}</h1>
|
||||
}
|
||||
{
|
||||
status == Status.plaied &&
|
||||
state.status == Status.plaied &&
|
||||
<Button variant="success" onClick={()=>setStatus(Status.showlist)}>Показать слоги</Button>
|
||||
}
|
||||
{
|
||||
status == Status.showlist &&
|
||||
state.status == Status.showlist &&
|
||||
<>
|
||||
<div>{renderRandomTones2()}</div>
|
||||
<br/>
|
||||
|
|
|
|||
|
|
@ -3,5 +3,6 @@ export const strings = {
|
|||
selectFinales: 'Выберите финали',
|
||||
selectAll: 'Выбрать все',
|
||||
unselectAll: 'Снять все',
|
||||
params: 'Параметры'
|
||||
params: 'Параметры',
|
||||
sylCount: 'Количество слогов'
|
||||
}
|
||||
|
|
@ -17,12 +17,13 @@ export const ButtonSet = (props: IBtnSerProps) => {
|
|||
return <>
|
||||
<Button variant={ state.allEnabled!(toggle) ? color : Outlined(color) }
|
||||
onClick= {()=>dispatch({type: ActionType.toggleAll, payload: toggle})}>
|
||||
{state.allInitiales ? strings.unselectAll : strings.selectAll}
|
||||
{state.allEnabled!(toggle) ? strings.unselectAll : strings.selectAll}
|
||||
</Button>
|
||||
{ source.map( (part, i) => <Button
|
||||
{ source.map( (part, i) => <Button
|
||||
variant={ state.isEnabled!(toggle, part.index) ? color : Outlined(color) }
|
||||
key={i} onClick={()=>dispatch({
|
||||
type: ActionType.toggleOne,
|
||||
key={i}
|
||||
onClick={()=>dispatch({
|
||||
type: ActionType.toggleOne,
|
||||
payload: { type: toggle, part: part }
|
||||
})}>
|
||||
{part.caption}
|
||||
|
|
|
|||
|
|
@ -8,14 +8,13 @@ export const Params = (): ReactElement => {
|
|||
|
||||
const { state, dispatch } = useStateContext();
|
||||
|
||||
const pausedispatcher = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
const pausedispatcher = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
dispatch({ type: ActionType.setPause, payload: Number(e.target.value)})
|
||||
const countdispatcher = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
const countdispatcher = (e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
dispatch({ type: ActionType.setCount, payload: Number(e.target.value)})
|
||||
|
||||
return <>
|
||||
<h2>{strings.params}</h2>
|
||||
<Form.Label>Количество слогов {state.sylCount}</Form.Label>
|
||||
<Form.Label>{strings.sylCount} {state.sylCount}</Form.Label>
|
||||
<Form.Range value={state.sylCount} min={5} max={50} step={5} onChange={countdispatcher}/>
|
||||
<Form.Label>Пауза между слогами {state.sylPause} секунд</Form.Label>
|
||||
<Form.Range value={state.sylPause} min={1} max={10} step={1} onChange={pausedispatcher}/>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { Context, createContext, Dispatch, ReactElement, useContext, useReducer } from "react";
|
||||
import { reducer, Action, ToggleType } from "./reducer"
|
||||
import { Syllable, SylPart, Tone } from "./types";
|
||||
import { Status, Syllable, SylPart, Tone } from "./types";
|
||||
import { isEnabled } from "./utils";
|
||||
|
||||
export interface IState {
|
||||
|
|
@ -14,7 +14,9 @@ export interface IState {
|
|||
foundTones: Tone[],
|
||||
randomTones: Tone[],
|
||||
allEnabled: (type: ToggleType) => false,
|
||||
isEnabled: (type: ToggleType, index: string) => false
|
||||
isEnabled: (type: ToggleType, index: string) => false,
|
||||
isFound: () => false,
|
||||
status: Status
|
||||
}
|
||||
|
||||
export interface IStore {
|
||||
|
|
@ -37,11 +39,13 @@ export const defaultState:Object = {
|
|||
if ( type === ToggleType.fin ) return (this as IState).allfinales
|
||||
return false
|
||||
},
|
||||
isEnabled: function(type: ToggleType, index: string) {
|
||||
if ( type === ToggleType.init ) return isEnabled((this as IState).initiales!, index)
|
||||
isEnabled: function(type: ToggleType, index: string) {
|
||||
if ( type === ToggleType.init ) return isEnabled((this as IState).initiales!, index)
|
||||
if ( type === ToggleType.fin ) return isEnabled((this as IState).finales!, index)
|
||||
return false
|
||||
}
|
||||
return false
|
||||
},
|
||||
isFound: function():boolean { return (this as IState).foundSyllables!.length > 0 },
|
||||
status: Status.params
|
||||
}
|
||||
|
||||
export const AppContext:Context<IStore> = createContext<IStore>({ state: defaultState as IState, dispatch: () => null })
|
||||
|
|
|
|||
Loading…
Reference in New Issue