forked from akai/readest
Refactor Toast to global component (#122)
* Refactor Toast to global component, use eventDispatcher to dispatch toast events * Error handling for TTS
This commit is contained in:
@@ -18,7 +18,6 @@ import {
|
||||
handleClick,
|
||||
handleWheel,
|
||||
} from '../utils/iframeEventHandlers';
|
||||
import Toast from '@/components/Toast';
|
||||
|
||||
const FoliateViewer: React.FC<{
|
||||
bookKey: string;
|
||||
@@ -39,7 +38,7 @@ const FoliateViewer: React.FC<{
|
||||
return () => clearTimeout(timer);
|
||||
}, [toastMessage]);
|
||||
|
||||
useProgressSync(bookKey, setToastMessage);
|
||||
useProgressSync(bookKey);
|
||||
|
||||
const progressRelocateHandler = (event: Event) => {
|
||||
const detail = (event as CustomEvent).detail;
|
||||
@@ -164,9 +163,6 @@ const FoliateViewer: React.FC<{
|
||||
onClick={(event) => handleTurnPage(event)}
|
||||
ref={containerRef}
|
||||
/>
|
||||
{toastMessage && (
|
||||
<Toast message={toastMessage} toastClass='toast-top toast-end' alertClass='alert-success' />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,10 +5,10 @@ import { useEffect, Suspense, useRef } from 'react';
|
||||
|
||||
import { useEnv } from '@/context/EnvContext';
|
||||
import { useLibraryStore } from '@/store/libraryStore';
|
||||
|
||||
import ReaderContent from './ReaderContent';
|
||||
import { AboutWindow } from '@/components/AboutWindow';
|
||||
import { useSettingsStore } from '@/store/settingsStore';
|
||||
import { AboutWindow } from '@/components/AboutWindow';
|
||||
import { Toast } from '@/components/Toast';
|
||||
import ReaderContent from './ReaderContent';
|
||||
|
||||
const Reader: React.FC<{ ids?: string }> = ({ ids }) => {
|
||||
const { envConfig } = useEnv();
|
||||
@@ -37,6 +37,7 @@ const Reader: React.FC<{ ids?: string }> = ({ ids }) => {
|
||||
<Suspense>
|
||||
<ReaderContent ids={ids} settings={settings} />
|
||||
<AboutWindow />
|
||||
<Toast />
|
||||
</Suspense>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -23,7 +23,6 @@ import { useFoliateEvents } from '../../hooks/useFoliateEvents';
|
||||
import { useNotesSync } from '../../hooks/useNotesSync';
|
||||
import { getPopupPosition, getPosition, Position, TextSelection } from '@/utils/sel';
|
||||
import { eventDispatcher } from '@/utils/event';
|
||||
import Toast from '@/components/Toast';
|
||||
import AnnotationPopup from './AnnotationPopup';
|
||||
import WiktionaryPopup from './WiktionaryPopup';
|
||||
import WikipediaPopup from './WikipediaPopup';
|
||||
@@ -57,7 +56,6 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
const [annotPopupPosition, setAnnotPopupPosition] = useState<Position>();
|
||||
const [dictPopupPosition, setDictPopupPosition] = useState<Position>();
|
||||
const [translatorPopupPosition, setTranslatorPopupPosition] = useState<Position>();
|
||||
const [toastMessage, setToastMessage] = useState('');
|
||||
const [highlightOptionsVisible, setHighlightOptionsVisible] = useState(false);
|
||||
|
||||
const [selectedStyle, setSelectedStyle] = useState<HighlightStyle>(
|
||||
@@ -196,11 +194,6 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selection, bookKey]);
|
||||
|
||||
useEffect(() => {
|
||||
const timer = setTimeout(() => setToastMessage(''), 2000);
|
||||
return () => clearTimeout(timer);
|
||||
}, [toastMessage]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!progress) return;
|
||||
const { location } = progress;
|
||||
@@ -225,7 +218,12 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
|
||||
const handleCopy = () => {
|
||||
if (!selection || !selection.text) return;
|
||||
setToastMessage(_('Copied to notebook'));
|
||||
eventDispatcher.dispatch('toast', {
|
||||
type: 'info',
|
||||
message: _('Copied to notebook'),
|
||||
className: 'whitespace-nowrap',
|
||||
timeout: 2000,
|
||||
});
|
||||
|
||||
const { booknotes: annotations = [] } = config;
|
||||
if (selection) navigator.clipboard.writeText(selection.text);
|
||||
@@ -414,8 +412,6 @@ const Annotator: React.FC<{ bookKey: string }> = ({ bookKey }) => {
|
||||
onHighlight={handleHighlight}
|
||||
/>
|
||||
)}
|
||||
|
||||
{toastMessage && <Toast message={toastMessage} alertClass='bg-neutual text-content' />}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -7,12 +7,14 @@ import { useReaderStore } from '@/store/readerStore';
|
||||
import Popup from '@/components/Popup';
|
||||
import TTSPanel from './TTSPanel';
|
||||
import TTSIcon from './TTSIcon';
|
||||
import { useTranslation } from '@/hooks/useTranslation';
|
||||
|
||||
const POPUP_WIDTH = 260;
|
||||
const POPUP_HEIGHT = 80;
|
||||
const POPUP_PADDING = 10;
|
||||
|
||||
const TTSControl = () => {
|
||||
const _ = useTranslation();
|
||||
const { getView } = useReaderStore();
|
||||
const [isPlaying, setIsPlaying] = useState(false);
|
||||
const [showPanel, setShowPanel] = useState(false);
|
||||
@@ -44,11 +46,19 @@ const TTSControl = () => {
|
||||
const view = getView(bookKey);
|
||||
if (!view) return;
|
||||
|
||||
const ttsClient = new WebSpeechClient();
|
||||
const ttsController = new TTSController(ttsClient, view);
|
||||
ttsControllerRef.current = ttsController;
|
||||
ttsControllerRef.current.speak(ssml);
|
||||
setIsPlaying(true);
|
||||
try {
|
||||
const ttsClient = new WebSpeechClient();
|
||||
const ttsController = new TTSController(ttsClient, view);
|
||||
ttsControllerRef.current = ttsController;
|
||||
ttsControllerRef.current.speak(ssml);
|
||||
setIsPlaying(true);
|
||||
} catch (error) {
|
||||
eventDispatcher.dispatch('toast', {
|
||||
message: _('TTS not supported in this device'),
|
||||
type: 'error',
|
||||
});
|
||||
console.error(error);
|
||||
}
|
||||
};
|
||||
|
||||
const handleTogglePlay = async () => {
|
||||
@@ -59,7 +69,7 @@ const TTSControl = () => {
|
||||
ttsController.pause();
|
||||
setIsPlaying(false);
|
||||
} else {
|
||||
await ttsController.start();
|
||||
ttsController.start();
|
||||
setIsPlaying(true);
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user