2 minute read

Tags: ,

GitHub

我要學50音

  • 實作後的成果
  • 隨著每天的更新都會變化唷唷~~

DAY 24

import {
  Box,
  Button,
  FormControl,
  Grid,
  InputLabel,
  MenuItem,
  Select,
} from "@mui/material";
import { DataGrid } from "@mui/x-data-grid";
import React, { useEffect, useState } from "react";
import { hiraganaList } from "../../shared/model/aiueoObj";
import RecordVoiceOverIcon from "@mui/icons-material/RecordVoiceOver";

//
// IMPORT ZONE
//

function Day222324() {
  const [isPaused, setIsPaused] = useState(false);
  const [voice, setVoice] = useState(null);

  useEffect(() => {
    const synth = window.speechSynthesis;
    const voices = synth.getVoices();
    const jpVoice = voices.filter((d) => d.lang === "ja-JP");
    if (jpVoice.lenth !== 0) {
      setVoice(jpVoice[0]);
    } else {
      setVoice(voices[0]);
    }
  }, []);

  const handlePlay = (words) => {
    const synth = window.speechSynthesis;

    if (isPaused) {
      synth.resume();
    } else {
      const u = new SpeechSynthesisUtterance(words);
      console.log("u", u);
      u.voice = voice;
      synth.speak(u);
    }
    setIsPaused(false);
  };

  const handleVocieOnChange = (v) => {
    setVoice(v.target.value);
  };

  const hiraganaListRow = [...hiraganaList].map((d, idx) =>
    Object.assign(d, { id: idx })
  );

  const columns = [
    {
      field: "name",
      headerName: "",
      width: 100,
      align: "center",
      headerAlign: "center",
    },
    {
      field: "",
      headerName: "あ段",
      width: 100,
      align: "center",
      headerAlign: "center",
      renderCell: (row) => {
        if (!row.formattedValue) return null;
        return (
          <>
            <div>{row.value}</div>
            <Button
              startIcon={<RecordVoiceOverIcon />}
              color="primary"
              onClick={() => handlePlay(row.formattedValue)}
            />
          </>
        );
      },
    },
    {
      field: "",
      headerName: "い段",
      width: 100,
      align: "center",
      headerAlign: "center",
      renderCell: (row) => {
        if (!row.formattedValue) return null;
        return (
          <>
            <div>{row.value}</div>
            <Button
              startIcon={<RecordVoiceOverIcon />}
              color="primary"
              onClick={() => handlePlay(row.formattedValue)}
            />
          </>
        );
      },
    },
    {
      field: "",
      headerName: "う段",
      width: 100,
      align: "center",
      headerAlign: "center",
      renderCell: (row) => {
        if (!row.formattedValue) return null;
        return (
          <>
            <div>{row.value}</div>
            <Button
              startIcon={<RecordVoiceOverIcon />}
              color="primary"
              onClick={() => handlePlay(row.formattedValue)}
            />
          </>
        );
      },
    },
    {
      field: "",
      headerName: "え段",
      width: 100,
      align: "center",
      headerAlign: "center",
      renderCell: (row) => {
        if (!row.formattedValue) return null;
        return (
          <>
            <div>{row.value}</div>
            <Button
              startIcon={<RecordVoiceOverIcon />}
              color="primary"
              onClick={() => handlePlay(row.formattedValue)}
            />
          </>
        );
      },
    },
    {
      field: "",
      headerName: "お段",
      width: 100,
      align: "center",
      headerAlign: "center",
      renderCell: (row) => {
        if (!row.formattedValue) return null;
        return (
          <>
            <div>{row.value}</div>
            <Button
              startIcon={<RecordVoiceOverIcon />}
              color="primary"
              onClick={() => handlePlay(row.formattedValue)}
            />
          </>
        );
      },
    },
    {
      field: "",
      headerName: "ん段",
      width: 100,
      align: "center",
      headerAlign: "center",
      renderCell: (row) => {
        if (!row.formattedValue) return null;
        return (
          <>
            {row.formattedValue.toString()}
            <Button
              startIcon={<RecordVoiceOverIcon />}
              color="primary"
              onClick={() => handlePlay(row.formattedValue)}
            />
          </>
        );
      },
    },
    {
      field: "words",
      headerName: "念起來",
      width: 150,
      align: "center",
      headerAlign: "center",
      renderCell: (row) => {
        const text = row.formattedValue.toString();
        return (
          <>
            {/* {row.value} */}
            {/* <TextField
                onChange={(e) => {
                
                }}
              /> */}
            <Button
              startIcon={<RecordVoiceOverIcon />}
              color="primary"
              onClick={() => handlePlay(text)}
            />
          </>
        );
      },
    },
  ];

  return (
    <Grid
      container
      spacing=
      style=
    >
      <Grid item xs={12}>
        <h1>Day 22 23 24 再複習一下 50 </h1>
      </Grid>
      <Grid item xs={2} justifyItems="center">
        選擇語系
      </Grid>
      <Grid item xs={10}>
        <FormControl fullWidth>
          <InputLabel> 選擇說話語音</InputLabel>
          <Select
            value={voice?.name}
            label="選擇說話語音"
            onChange={(v) => handleVocieOnChange(v)}
          >
            {window.speechSynthesis.getVoices().map((voice) => (
              <MenuItem key={voice.name} value={voice}>
                {voice.name}
              </MenuItem>
            ))}
          </Select>
        </FormControl>
      </Grid>
      <Grid container alignContent="center" justifyContent={"center"}>
        <Grid item>
          <Box>
            <Grid item>
              <DataGrid
                style=
                columns={columns}
                rows={hiraganaListRow}
              />
            </Grid>
          </Box>
        </Grid>
      </Grid>
    </Grid>
  );
}

export default Day222324;

Reference