Use react-hot-toast for important notifications
This commit is contained in:
parent
6e96aeb821
commit
e3167a18ea
5 changed files with 55 additions and 11 deletions
28
package-lock.json
generated
28
package-lock.json
generated
|
|
@ -21,6 +21,7 @@
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-dropzone": "^14.3.5",
|
"react-dropzone": "^14.3.5",
|
||||||
|
"react-hot-toast": "^2.5.1",
|
||||||
"react-pdf": "^9.2.1",
|
"react-pdf": "^9.2.1",
|
||||||
"string-similarity": "^4.0.4",
|
"string-similarity": "^4.0.4",
|
||||||
"uuid": "^11.0.5"
|
"uuid": "^11.0.5"
|
||||||
|
|
@ -2186,7 +2187,6 @@
|
||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
"devOptional": true,
|
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/damerau-levenshtein": {
|
"node_modules/damerau-levenshtein": {
|
||||||
|
|
@ -3537,6 +3537,15 @@
|
||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/goober": {
|
||||||
|
"version": "2.1.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/goober/-/goober-2.1.16.tgz",
|
||||||
|
"integrity": "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"csstype": "^3.0.10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/gopd": {
|
"node_modules/gopd": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
|
||||||
|
|
@ -5521,6 +5530,23 @@
|
||||||
"react": ">= 16.8 || 18.0.0"
|
"react": ">= 16.8 || 18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-hot-toast": {
|
||||||
|
"version": "2.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-hot-toast/-/react-hot-toast-2.5.1.tgz",
|
||||||
|
"integrity": "sha512-54Gq1ZD1JbmAb4psp9bvFHjS7lje+8ubboUmvKZkCsQBLH6AOpZ9JemfRvIdHcfb9AZXRaFLrb3qUobGYDJhFQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"csstype": "^3.1.3",
|
||||||
|
"goober": "^2.1.16"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">=16",
|
||||||
|
"react-dom": ">=16"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-is": {
|
"node_modules/react-is": {
|
||||||
"version": "16.13.1",
|
"version": "16.13.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@
|
||||||
"react": "^19.0.0",
|
"react": "^19.0.0",
|
||||||
"react-dom": "^19.0.0",
|
"react-dom": "^19.0.0",
|
||||||
"react-dropzone": "^14.3.5",
|
"react-dropzone": "^14.3.5",
|
||||||
|
"react-hot-toast": "^2.5.1",
|
||||||
"react-pdf": "^9.2.1",
|
"react-pdf": "^9.2.1",
|
||||||
"string-similarity": "^4.0.4",
|
"string-similarity": "^4.0.4",
|
||||||
"uuid": "^11.0.5"
|
"uuid": "^11.0.5"
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { Providers } from "./providers";
|
||||||
import { Metadata } from "next";
|
import { Metadata } from "next";
|
||||||
import Script from "next/script";
|
import Script from "next/script";
|
||||||
import { Footer } from "@/components/Footer";
|
import { Footer } from "@/components/Footer";
|
||||||
|
import { Toaster } from 'react-hot-toast';
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: "OpenReader WebUI",
|
title: "OpenReader WebUI",
|
||||||
|
|
@ -69,6 +70,7 @@ export default function RootLayout({
|
||||||
{!isDev && <Footer />}
|
{!isDev && <Footer />}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<Toaster />
|
||||||
</Providers>
|
</Providers>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,17 @@
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
import toast from 'react-hot-toast';
|
||||||
|
|
||||||
export function PDFSkeleton() {
|
export function PDFSkeleton() {
|
||||||
const [showNotification, setShowNotification] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
setShowNotification(true);
|
toast('There might be an issue with the file import. Please try again.', {
|
||||||
|
icon: '⚠️',
|
||||||
|
style: {
|
||||||
|
background: 'var(--background)',
|
||||||
|
color: 'var(--accent)',
|
||||||
|
},
|
||||||
|
duration: 5000,
|
||||||
|
});
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
|
|
@ -13,11 +19,6 @@ export function PDFSkeleton() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center justify-center min-h-[50vh] w-full">
|
<div className="flex flex-col items-center justify-center min-h-[50vh] w-full">
|
||||||
{showNotification && (
|
|
||||||
<div className="fixed top-4 left-1/2 transform -translate-x-1/2 bg-yellow-100 border border-yellow-400 text-yellow-700 px-4 py-2 rounded shadow-lg z-50">
|
|
||||||
There might be an issue with the file import. Please try again.
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
<div className="flex flex-col items-center gap-4">
|
<div className="flex flex-col items-center gap-4">
|
||||||
<div className="w-12 h-12 border-4 border-accent border-t-transparent rounded-full animate-spin"></div>
|
<div className="w-12 h-12 border-4 border-accent border-t-transparent rounded-full animate-spin"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ import React, {
|
||||||
} from 'react';
|
} from 'react';
|
||||||
import OpenAI from 'openai';
|
import OpenAI from 'openai';
|
||||||
import { Howl } from 'howler';
|
import { Howl } from 'howler';
|
||||||
|
import toast from 'react-hot-toast';
|
||||||
|
|
||||||
import { useConfig } from '@/contexts/ConfigContext';
|
import { useConfig } from '@/contexts/ConfigContext';
|
||||||
import { splitIntoSentences, preprocessSentenceForAudio } from '@/utils/nlp';
|
import { splitIntoSentences, preprocessSentenceForAudio } from '@/utils/nlp';
|
||||||
|
|
@ -136,8 +137,21 @@ export function TTSProvider({ children }: { children: React.ReactNode }) {
|
||||||
|
|
||||||
// If skipBlank is enabled and there's no text and we are playing audio, automatically move to next page
|
// If skipBlank is enabled and there's no text and we are playing audio, automatically move to next page
|
||||||
if (isPlaying && skipBlank && newSentences.length === 0 && currDocPage < currDocPages!) {
|
if (isPlaying && skipBlank && newSentences.length === 0 && currDocPage < currDocPages!) {
|
||||||
console.log('Skipping blank page:', currDocPage);
|
|
||||||
incrementPage();
|
incrementPage();
|
||||||
|
|
||||||
|
toast.success(`Skipping blank page ${currDocPage}`, {
|
||||||
|
id: `page-${currDocPage}`,
|
||||||
|
iconTheme: {
|
||||||
|
primary: 'var(--accent)',
|
||||||
|
secondary: 'var(--background)',
|
||||||
|
},
|
||||||
|
style: {
|
||||||
|
background: 'var(--background)',
|
||||||
|
color: 'var(--accent)',
|
||||||
|
},
|
||||||
|
duration: 1000,
|
||||||
|
position: 'top-center',
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue