Yuriy Evdokimov 2023-10-23 22:25:44 +05:00
parent f4afb98d37
commit 90682a9170
13 changed files with 101 additions and 38 deletions

1
.env Normal file
View File

@ -0,0 +1 @@
VITE_REACT_APP_VERSION=$npm_package_version

View File

@ -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",

View File

@ -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}

View File

@ -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

View File

@ -10,5 +10,8 @@ export const strings = {
selectInitAndFin: "Выберите инициали и финали",
showSyllables: "Показать слоги",
playAgain: "Повторить",
toBegin: "В начало"
toBegin: "В начало",
version: "Версия",
cpr: "©",
selectTones: "Выберите тоны"
}

View File

@ -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))

View File

@ -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))

View File

@ -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})}>

5
src/copyright.tsx Normal file
View File

@ -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>

View File

@ -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' },

View File

@ -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";

20
src/rendertones.tsx Normal file
View File

@ -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>
}

35
src/selecttones.tsx Normal file
View File

@ -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>
</>
}