111
parent
f4afb98d37
commit
90682a9170
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"name": "vite-1",
|
||||
"name": "pinyindictation",
|
||||
"author": {"email": "rurik19@yandex.ru", "name": "Yuriy Evdokimov"},
|
||||
"private": true,
|
||||
"version": "0.0.0",
|
||||
"version": "1.0.2",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
|
|
|||
|
|
@ -59,4 +59,6 @@
|
|||
.tone2 { color: rgb(255, 170, 0) }
|
||||
.tone3 { color: rgb(85, 170, 0) }
|
||||
.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 './App.css'
|
||||
import { Button, ListGroup } from 'react-bootstrap';
|
||||
import { initials, finales } from './data';
|
||||
import { initials, finales } from './pinyin';
|
||||
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';
|
||||
import { getAudio } from './utils';
|
||||
import { RenderTones } from './rendertones';
|
||||
import { getAudio } from './audio';
|
||||
import { Copyright } from './copyright';
|
||||
import { SelectTones } from './selecttones';
|
||||
|
||||
function App() {
|
||||
|
||||
|
|
@ -65,23 +68,7 @@ const playPlayList = () => {
|
|||
playlist[0].play()
|
||||
}
|
||||
|
||||
const playTone = (index: string) => {
|
||||
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 (
|
||||
return (
|
||||
<>
|
||||
<h1>{strings.mainHeader}</h1>
|
||||
<ListGroup>
|
||||
|
|
@ -96,6 +83,11 @@ const renderPlayList = () => {
|
|||
<ButtonSet source={finales} color={BtnColor.green} toggle={ToggleType.fin}/>
|
||||
</ListGroup.Item>
|
||||
|
||||
<ListGroup.Item disabled={status != Status.params}>
|
||||
<h2>{strings.selectTones}</h2>
|
||||
<SelectTones/>
|
||||
</ListGroup.Item>
|
||||
|
||||
<ListGroup.Item disabled={status != Status.params}>
|
||||
<h2>{strings.params}</h2>
|
||||
<Params/>
|
||||
|
|
@ -129,16 +121,16 @@ const renderPlayList = () => {
|
|||
{
|
||||
status == Status.showlist &&
|
||||
<>
|
||||
<div>{renderPlayList()}</div>
|
||||
<RenderTones tones={state.randomTones!}/>
|
||||
<br/>
|
||||
<Button variant="success" onClick={()=> setStatus(Status.params)}>{strings.toBegin}</Button>
|
||||
</>
|
||||
}
|
||||
</ListGroup.Item>
|
||||
<ListGroup.Item><Copyright/></ListGroup.Item>
|
||||
</ListGroup>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
|
||||
export default App
|
||||
|
|
@ -10,5 +10,8 @@ export const strings = {
|
|||
selectInitAndFin: "Выберите инициали и финали",
|
||||
showSyllables: "Показать слоги",
|
||||
playAgain: "Повторить",
|
||||
toBegin: "В начало"
|
||||
toBegin: "В начало",
|
||||
version: "Версия",
|
||||
cpr: "©",
|
||||
selectTones: "Выберите тоны"
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import { syllables } from "./data"
|
||||
import { syllables } from "./pinyin"
|
||||
import { BtnColor, SylPart, Syllable } from "./types"
|
||||
|
||||
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 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()
|
||||
}
|
||||
|
||||
export const playTone = async (toneName: string) => {
|
||||
const audio = new Audio(`/src/assets/audio/${toneName}.mp3`)
|
||||
await audio.play()
|
||||
}
|
||||
// export const playTone = async (toneName: string) => {
|
||||
// const audio = new Audio(`/src/assets/audio/${toneName}.mp3`)
|
||||
// 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) => {
|
||||
const { state, dispatch } = useStateContext();
|
||||
const { source, color, toggle } = props;
|
||||
const { state, dispatch } = useStateContext()
|
||||
const { source, color, toggle } = props
|
||||
return <>
|
||||
<Button variant={ state.allEnabled!(toggle) ? color : Outlined(color) }
|
||||
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"
|
||||
|
||||
export const initials: SylPart[] = [
|
||||
export const initials: SylPart[] = [
|
||||
{ caption: '-', index: '-' },
|
||||
{ caption: 'y', index: 'y' },
|
||||
{ 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 { SylPart, Syllable, Tone } from "./types";
|
||||
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