111
parent
f4afb98d37
commit
90682a9170
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"name": "vite-1",
|
"name": "pinyindictation",
|
||||||
|
"author": {"email": "rurik19@yandex.ru", "name": "Yuriy Evdokimov"},
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.0.0",
|
"version": "1.0.2",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|
|
||||||
|
|
@ -59,4 +59,6 @@
|
||||||
.tone2 { color: rgb(255, 170, 0) }
|
.tone2 { color: rgb(255, 170, 0) }
|
||||||
.tone3 { color: rgb(85, 170, 0) }
|
.tone3 { color: rgb(85, 170, 0) }
|
||||||
.tone4 { color: rgb(0, 0, 255) }
|
.tone4 { color: rgb(0, 0, 255) }
|
||||||
.tone5 { color: rgb(50, 50, 50) }
|
.tone5 { color: rgb(50, 50, 50) }
|
||||||
|
|
||||||
|
.cpr { color: gray}
|
||||||
36
src/App.tsx
36
src/App.tsx
|
|
@ -1,14 +1,17 @@
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import './App.css'
|
import './App.css'
|
||||||
import { Button, ListGroup } from 'react-bootstrap';
|
import { Button, ListGroup } from 'react-bootstrap';
|
||||||
import { initials, finales } from './data';
|
import { initials, finales } from './pinyin';
|
||||||
import { BtnColor, Status, Tone } from './types';
|
import { BtnColor, Status, Tone } from './types';
|
||||||
import { strings } from './strings';
|
import { strings } from './strings';
|
||||||
import { useStateContext } from './store';
|
import { useStateContext } from './store';
|
||||||
import { Params } from './params';
|
import { Params } from './params';
|
||||||
import { ActionType, ToggleType } from './reducer';
|
import { ActionType, ToggleType } from './reducer';
|
||||||
import { ButtonSet } from './buttons';
|
import { ButtonSet } from './buttons';
|
||||||
import { getAudio } from './utils';
|
import { RenderTones } from './rendertones';
|
||||||
|
import { getAudio } from './audio';
|
||||||
|
import { Copyright } from './copyright';
|
||||||
|
import { SelectTones } from './selecttones';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
|
||||||
|
|
@ -65,23 +68,7 @@ const playPlayList = () => {
|
||||||
playlist[0].play()
|
playlist[0].play()
|
||||||
}
|
}
|
||||||
|
|
||||||
const playTone = (index: string) => {
|
return (
|
||||||
getAudio(index).play()
|
|
||||||
}
|
|
||||||
|
|
||||||
const renderPlayList = () => {
|
|
||||||
|
|
||||||
return state.randomTones!.map(
|
|
||||||
(ton, i) => { return <span key={i}
|
|
||||||
className={`syllable tone${ton.num}`}
|
|
||||||
onClick = {()=>playTone(ton.tone)}
|
|
||||||
>
|
|
||||||
{i+1}{'. '}{ton.caption}{' '}
|
|
||||||
</span> }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
<>
|
||||||
<h1>{strings.mainHeader}</h1>
|
<h1>{strings.mainHeader}</h1>
|
||||||
<ListGroup>
|
<ListGroup>
|
||||||
|
|
@ -96,6 +83,11 @@ const renderPlayList = () => {
|
||||||
<ButtonSet source={finales} color={BtnColor.green} toggle={ToggleType.fin}/>
|
<ButtonSet source={finales} color={BtnColor.green} toggle={ToggleType.fin}/>
|
||||||
</ListGroup.Item>
|
</ListGroup.Item>
|
||||||
|
|
||||||
|
<ListGroup.Item disabled={status != Status.params}>
|
||||||
|
<h2>{strings.selectTones}</h2>
|
||||||
|
<SelectTones/>
|
||||||
|
</ListGroup.Item>
|
||||||
|
|
||||||
<ListGroup.Item disabled={status != Status.params}>
|
<ListGroup.Item disabled={status != Status.params}>
|
||||||
<h2>{strings.params}</h2>
|
<h2>{strings.params}</h2>
|
||||||
<Params/>
|
<Params/>
|
||||||
|
|
@ -129,16 +121,16 @@ const renderPlayList = () => {
|
||||||
{
|
{
|
||||||
status == Status.showlist &&
|
status == Status.showlist &&
|
||||||
<>
|
<>
|
||||||
<div>{renderPlayList()}</div>
|
<RenderTones tones={state.randomTones!}/>
|
||||||
<br/>
|
<br/>
|
||||||
<Button variant="success" onClick={()=> setStatus(Status.params)}>{strings.toBegin}</Button>
|
<Button variant="success" onClick={()=> setStatus(Status.params)}>{strings.toBegin}</Button>
|
||||||
</>
|
</>
|
||||||
}
|
}
|
||||||
</ListGroup.Item>
|
</ListGroup.Item>
|
||||||
|
<ListGroup.Item><Copyright/></ListGroup.Item>
|
||||||
</ListGroup>
|
</ListGroup>
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App
|
export default App
|
||||||
|
|
||||||
|
|
@ -10,5 +10,8 @@ export const strings = {
|
||||||
selectInitAndFin: "Выберите инициали и финали",
|
selectInitAndFin: "Выберите инициали и финали",
|
||||||
showSyllables: "Показать слоги",
|
showSyllables: "Показать слоги",
|
||||||
playAgain: "Повторить",
|
playAgain: "Повторить",
|
||||||
toBegin: "В начало"
|
toBegin: "В начало",
|
||||||
|
version: "Версия",
|
||||||
|
cpr: "©",
|
||||||
|
selectTones: "Выберите тоны"
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { syllables } from "./data"
|
import { syllables } from "./pinyin"
|
||||||
import { BtnColor, SylPart, Syllable } from "./types"
|
import { BtnColor, SylPart, Syllable } from "./types"
|
||||||
|
|
||||||
export const isEnabled = (arr: SylPart[], find: string): boolean => arr.some((str) => str.index==find)
|
export const isEnabled = (arr: SylPart[], find: string): boolean => arr.some((str) => str.index==find)
|
||||||
|
|
@ -36,6 +36,3 @@ export const GetSyllablesByInitAndFin = (initiales:SylPart[], finales: SylPart[]
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Outlined = (color: BtnColor):string => `outline-${color}`
|
export const Outlined = (color: BtnColor):string => `outline-${color}`
|
||||||
export const getAudioPath = (index: string):string => `/audio/${index}.mp3`
|
|
||||||
|
|
||||||
export const getAudio = (index: string):HTMLAudioElement => new Audio(getAudioPath(index))
|
|
||||||
15
src/audio.ts
15
src/audio.ts
|
|
@ -3,7 +3,14 @@ export const playFile = (filename: string) => {
|
||||||
audio.play()
|
audio.play()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const playTone = async (toneName: string) => {
|
// export const playTone = async (toneName: string) => {
|
||||||
const audio = new Audio(`/src/assets/audio/${toneName}.mp3`)
|
// const audio = new Audio(`/src/assets/audio/${toneName}.mp3`)
|
||||||
await audio.play()
|
// await audio.play()
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
export const playTone = (index: string) => {
|
||||||
|
getAudio(index).play()
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getAudioPath = (index: string):string => `/audio/${index}.mp3`
|
||||||
|
export const getAudio = (index: string):HTMLAudioElement => new Audio(getAudioPath(index))
|
||||||
|
|
@ -12,8 +12,8 @@ export interface IBtnSerProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ButtonSet = (props: IBtnSerProps) => {
|
export const ButtonSet = (props: IBtnSerProps) => {
|
||||||
const { state, dispatch } = useStateContext();
|
const { state, dispatch } = useStateContext()
|
||||||
const { source, color, toggle } = props;
|
const { source, color, toggle } = props
|
||||||
return <>
|
return <>
|
||||||
<Button variant={ state.allEnabled!(toggle) ? color : Outlined(color) }
|
<Button variant={ state.allEnabled!(toggle) ? color : Outlined(color) }
|
||||||
onClick= {()=>dispatch({type: ActionType.toggleAll, payload: toggle})}>
|
onClick= {()=>dispatch({type: ActionType.toggleAll, payload: toggle})}>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { ReactElement } from "react";
|
||||||
|
import { strings } from "./strings";
|
||||||
|
import { author } from '../package.json'
|
||||||
|
|
||||||
|
export const Copyright = ():ReactElement => <div className="cpr">{strings.version} {import.meta.env.VITE_REACT_APP_VERSION} {strings.cpr}{author.name}</div>
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { SylPart, Syllable, Tone } from "./types"
|
import { SylPart, Syllable, Tone } from "./types"
|
||||||
|
|
||||||
export const initials: SylPart[] = [
|
export const initials: SylPart[] = [
|
||||||
{ caption: '-', index: '-' },
|
{ caption: '-', index: '-' },
|
||||||
{ caption: 'y', index: 'y' },
|
{ caption: 'y', index: 'y' },
|
||||||
{ caption: 'w', index: 'w' },
|
{ caption: 'w', index: 'w' },
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { finales, initials, tones } from "./data";
|
import { finales, initials, tones } from "./pinyin";
|
||||||
import { IState } from "./store";
|
import { IState } from "./store";
|
||||||
import { SylPart, Syllable, Tone } from "./types";
|
import { SylPart, Syllable, Tone } from "./types";
|
||||||
import { GetSyllablesByInitAndFin, getRandomArray, toggle } from "./utils";
|
import { GetSyllablesByInitAndFin, getRandomArray, toggle } from "./utils";
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
import { ReactElement } from "react";
|
||||||
|
import { playTone } from "./audio";
|
||||||
|
import { Tone } from "./types";
|
||||||
|
|
||||||
|
interface IRenderTonesProps {
|
||||||
|
tones: Tone[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RenderTones = (props:IRenderTonesProps):ReactElement => {
|
||||||
|
const { tones } = props
|
||||||
|
return <div>
|
||||||
|
{ tones!.map(
|
||||||
|
(ton, i) => { return <span key={i}
|
||||||
|
className={`syllable tone${ton.num}`}
|
||||||
|
onClick={() => playTone(ton.tone)}
|
||||||
|
>
|
||||||
|
{i + 1}{'. '}{ton.caption}{' '}
|
||||||
|
</span> } ) }
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { useStateContext } from "./store"
|
||||||
|
import { Form } from "react-bootstrap";
|
||||||
|
|
||||||
|
export const SelectTones = () => {
|
||||||
|
// const { state, dispatch } = useStateContext()
|
||||||
|
return <>
|
||||||
|
<Form>
|
||||||
|
<Form.Check // prettier-ignore
|
||||||
|
inline
|
||||||
|
type="switch"
|
||||||
|
id="first-switch"
|
||||||
|
label="Первый"
|
||||||
|
/>
|
||||||
|
<Form.Check // prettier-ignore
|
||||||
|
inline
|
||||||
|
type="switch"
|
||||||
|
label="Второй"
|
||||||
|
id="second-switch"
|
||||||
|
/>
|
||||||
|
</Form><Form>
|
||||||
|
<Form.Check // prettier-ignore
|
||||||
|
inline
|
||||||
|
type="switch"
|
||||||
|
id="third-switch"
|
||||||
|
label="Третий"
|
||||||
|
/>
|
||||||
|
<Form.Check // prettier-ignore
|
||||||
|
inline
|
||||||
|
type="switch"
|
||||||
|
label="Четвёртый"
|
||||||
|
id="fourth-switch"
|
||||||
|
/>
|
||||||
|
</Form>
|
||||||
|
</>
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue