Add Toastify customizations to global CSS to reduce need for inline styling.
Improve theme handling in LyricSearch component
This commit is contained in:
@@ -14,39 +14,25 @@ import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||
import { AutoComplete } from 'primereact/autocomplete';
|
||||
import { API_URL } from '../config';
|
||||
|
||||
const theme = document.documentElement.getAttribute("data-theme")
|
||||
|
||||
|
||||
document.addEventListener('set-theme', (e) => {
|
||||
const box = document.querySelector("[class*='lyrics-card-']");
|
||||
let removedClass = "lyrics-card-dark";
|
||||
let newTheme = e.detail;
|
||||
if (newTheme !== "light") {
|
||||
removedClass = "lyrics-card-light";
|
||||
}
|
||||
box?.classList.remove(removedClass);
|
||||
box?.classList.add(`lyrics-card-${newTheme}`);
|
||||
});
|
||||
|
||||
export default function LyricSearch() {
|
||||
const [showLyrics, setShowLyrics] = useState(false);
|
||||
const [showLyrics, setShowLyrics] = useState(false);
|
||||
return (
|
||||
<div className="lyric-search">
|
||||
<h2 className="title">
|
||||
<span>Lyric Search</span>
|
||||
</h2>
|
||||
<div className="card-text my-4">
|
||||
<label for="lyric-search-input">Search:</label>
|
||||
<LyricSearchInputField
|
||||
id="lyric-search-input"
|
||||
placeholder="Artist - Song"
|
||||
setShowLyrics={setShowLyrics} />
|
||||
<div id="spinner" className="hidden">
|
||||
<CircularProgress
|
||||
variant="plain"
|
||||
color="primary"
|
||||
size="md"/></div>
|
||||
</div>
|
||||
<h2 className="title">
|
||||
<span>Lyric Search</span>
|
||||
</h2>
|
||||
<div className="card-text my-4">
|
||||
<label for="lyric-search-input">Search:</label>
|
||||
<LyricSearchInputField
|
||||
id="lyric-search-input"
|
||||
placeholder="Artist - Song"
|
||||
setShowLyrics={setShowLyrics} />
|
||||
<div id="spinner" className="hidden">
|
||||
<CircularProgress
|
||||
variant="plain"
|
||||
color="primary"
|
||||
size="md" /></div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -61,6 +47,20 @@ export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
|
||||
const [excludedSources, setExcludedSources] = useState([]);
|
||||
const [lyricsResult, setLyricsResult] = useState(null);
|
||||
const autoCompleteRef = useRef(null);
|
||||
const [theme, setTheme] = useState(document.documentElement.getAttribute("data-theme") || "light");
|
||||
|
||||
useEffect(() => {
|
||||
const handler = (e) => {
|
||||
const newTheme = e.detail;
|
||||
setTheme(newTheme);
|
||||
};
|
||||
document.addEventListener('set-theme', handler);
|
||||
return () => {
|
||||
document.removeEventListener('set-theme', handler);
|
||||
};
|
||||
}, []);
|
||||
|
||||
|
||||
|
||||
// Typeahead: fetch suggestions
|
||||
const fetchSuggestions = async (event) => {
|
||||
@@ -136,12 +136,7 @@ export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
|
||||
setLyricsResult(null);
|
||||
setShowLyrics(false);
|
||||
|
||||
const toastId = toast.info("Searching...", {
|
||||
style: {
|
||||
color: "#000",
|
||||
backgroundColor: "rgba(217, 242, 255, 0.8)",
|
||||
},
|
||||
});
|
||||
const toastId = toast.info("Searching...");
|
||||
|
||||
const startTime = Date.now();
|
||||
|
||||
@@ -168,17 +163,17 @@ export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
|
||||
setShowLyrics(true);
|
||||
|
||||
toast.update(toastId, {
|
||||
type: "success",
|
||||
render: `🦄 Found! (Took ${duration}s)`,
|
||||
type: "",
|
||||
style: { backgroundColor: "rgba(46, 186, 106, 1)" },
|
||||
className: "Toastify__toast--success",
|
||||
autoClose: 2000,
|
||||
hideProgressBar: true,
|
||||
});
|
||||
} catch (error) {
|
||||
toast.update(toastId, {
|
||||
type: "error",
|
||||
render: `😕 ${error.message}`,
|
||||
type: "",
|
||||
style: { backgroundColor: "rgba(255, 0, 0, 0.5)" },
|
||||
autoClose: 5000,
|
||||
hideProgressBar: true,
|
||||
});
|
||||
@@ -241,14 +236,14 @@ export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
|
||||
)}
|
||||
|
||||
{lyricsResult && (
|
||||
<div className={`lyrics-card lyrics-card-${theme} mt-4 p-4 rounded-md shadow-md`}>
|
||||
<div className="lyrics-content">
|
||||
<div style={{ textAlign: "center", fontWeight: "bold", marginBottom: "1rem" }}>
|
||||
{lyricsResult.artist} - {lyricsResult.song}
|
||||
<div className={`lyrics-card lyrics-card-${theme} mt-4 p-4 rounded-md shadow-md`}>
|
||||
<div className="lyrics-content">
|
||||
<div style={{ textAlign: "center", fontWeight: "bold", marginBottom: "1rem" }}>
|
||||
{lyricsResult.artist} - {lyricsResult.song}
|
||||
</div>
|
||||
<div dangerouslySetInnerHTML={{ __html: lyricsResult.lyrics }} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
@@ -269,9 +264,7 @@ export const UICheckbox = forwardRef(function UICheckbox(props = {}, ref) {
|
||||
|
||||
if (checkedCount === 3) {
|
||||
checkboxes.forEach(cb => cb.click());
|
||||
toast.error("All sources were excluded; exclusions have been reset.", {
|
||||
style: { backgroundColor: "rgba(255, 0, 0, 0.5)", color: "inherit" }
|
||||
});
|
||||
toast.error("All sources were excluded; exclusions have been reset.");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -300,7 +293,7 @@ export const UICheckbox = forwardRef(function UICheckbox(props = {}, ref) {
|
||||
});
|
||||
|
||||
|
||||
export function LyricResultBox(opts={}) {
|
||||
export function LyricResultBox(opts = {}) {
|
||||
return (
|
||||
<div>
|
||||
<Box className={`lyrics-card lyrics-card-${theme}`} sx={{ p: 2 }}>
|
||||
|
@@ -2,7 +2,7 @@ import React from "react";
|
||||
|
||||
export default function BreadcrumbNav({ currentPage }) {
|
||||
const pages = [
|
||||
{ key: "request", label: "Request Media", href: "." },
|
||||
{ key: "request", label: "Request Media", href: "../" },
|
||||
{ key: "management", label: "Manage Requests", href: "requests" },
|
||||
];
|
||||
|
||||
|
Reference in New Issue
Block a user