Refactor Root component to accept additional props and enhance LyricSearch functionality with URL hash handling and lyrics sanitization.
This commit is contained in:
@@ -16,7 +16,7 @@ const MediaRequestForm = lazy(() => import('./TRip/MediaRequestForm.jsx'));
|
||||
const RequestManagement = lazy(() => import('./TRip/RequestManagement.jsx'));
|
||||
const Player = lazy(() => import('./AudioPlayer.jsx'));
|
||||
|
||||
export default function Root({ child, user = undefined }) {
|
||||
export default function Root({ child, user = undefined, ...props }) {
|
||||
window.toast = toast;
|
||||
const theme = document.documentElement.getAttribute("data-theme")
|
||||
usePrimeReactThemeSwitcher(theme);
|
||||
@@ -35,7 +35,7 @@ export default function Root({ child, user = undefined }) {
|
||||
Work in progress... bugs are to be expected.
|
||||
</Alert> */}
|
||||
{child == "LoginPage" && (<LoginPage client:only="react" />)}
|
||||
{child == "LyricSearch" && (<LyricSearch client:only="react" />)}
|
||||
{child == "LyricSearch" && (<LyricSearch {...props} client:only="react" />)}
|
||||
{child == "Player" && (<Player client:only="react" user={user} />)}
|
||||
{child == "Memes" && <Memes client:only="react" />}
|
||||
{child == "qs2.MediaRequestForm" && <MediaRequestForm client:only="react" />}
|
||||
|
||||
@@ -18,6 +18,7 @@ import { API_URL } from '../config';
|
||||
|
||||
export default function LyricSearch() {
|
||||
const [showLyrics, setShowLyrics] = useState(false);
|
||||
|
||||
return (
|
||||
<div className="lyric-search">
|
||||
<h2 className="title">
|
||||
@@ -52,6 +53,29 @@ export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
|
||||
const autoCompleteRef = useRef(null);
|
||||
const [theme, setTheme] = useState(document.documentElement.getAttribute("data-theme") || "light");
|
||||
|
||||
// Handle URL hash changes and initial load
|
||||
useEffect(() => {
|
||||
const handleHashChange = () => {
|
||||
const hash = window.location.hash.slice(1); // Remove the # symbol
|
||||
if (hash) {
|
||||
try {
|
||||
const [artist, song] = decodeURIComponent(hash).split('/');
|
||||
if (artist && song) {
|
||||
setValue(`${artist} - ${song}`);
|
||||
handleSearch(`${artist} - ${song}`);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Failed to parse URL hash:', e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('hashchange', handleHashChange);
|
||||
handleHashChange(); // Handle initial load
|
||||
|
||||
return () => window.removeEventListener('hashchange', handleHashChange);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const handler = (e) => {
|
||||
const newTheme = e.detail;
|
||||
@@ -118,17 +142,17 @@ export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const handleSearch = async () => {
|
||||
const handleSearch = async (searchValue = value) => {
|
||||
if (autoCompleteRef.current) {
|
||||
autoCompleteRef.current.hide();
|
||||
}
|
||||
|
||||
if (!value.includes(" - ")) {
|
||||
if (!searchValue.includes(" - ")) {
|
||||
setAlertVisible(true);
|
||||
return;
|
||||
}
|
||||
|
||||
const [artist, song] = value.split(" - ", 2).map((v) => v.trim());
|
||||
const [artist, song] = searchValue.split(" - ", 2).map((v) => v.trim());
|
||||
if (!artist || !song) {
|
||||
setAlertVisible(true);
|
||||
return;
|
||||
@@ -169,6 +193,10 @@ export function LyricSearchInputField({ id, placeholder, setShowLyrics }) {
|
||||
setLyricsResult({ artist: data.artist, song: data.song, lyrics: data.lyrics });
|
||||
setShowLyrics(true);
|
||||
|
||||
// Update URL hash with search parameters
|
||||
const hash = `#${encodeURIComponent(data.artist)}/${encodeURIComponent(data.song)}`;
|
||||
window.history.pushState(null, '', hash);
|
||||
|
||||
toast.update(searchToastRef.current, {
|
||||
type: "success",
|
||||
render: `Found! (Took ${duration}s)`,
|
||||
|
||||
@@ -7,7 +7,10 @@ import LyricSearch from '../components/LyricSearch.jsx';
|
||||
<Base>
|
||||
<section>
|
||||
<div class="prose prose-neutral dark:prose-invert">
|
||||
<Root child="LyricSearch" client:only="react" />
|
||||
<Root
|
||||
child="LyricSearch"
|
||||
client:only="react"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</Base>
|
||||
|
||||
Reference in New Issue
Block a user