import { CircularProgress } from "@mui/joy"; import React, { forwardRef, useImperativeHandle, useEffect, useRef, useState, } from "react"; import { default as $ } from "jquery"; import Alert from '@mui/joy/Alert'; import Box from '@mui/joy/Box'; import Button from "@mui/joy/Button"; import Checkbox from "@mui/joy/Checkbox"; import jQuery from "jquery"; import { AutoComplete } from 'primereact/autocomplete'; import { api as API_URL } from '../config'; window.$ = window.jQuery = jQuery; 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).removeClass(removedClass) $(box).addClass(`lyrics-card-${newTheme}`); }); export default function LyricSearch() { return (

Lyric Search


Exclude:
); } export function LyricSearchInputField(opts = {}) { const [value, setValue] = useState(""); const [suggestions, setSuggestions] = useState([]); const [showAlert, setShowAlert] = useState(false); const autoCompleteRef = useRef(null); var search_toast = null; var ret_artist = null; var ret_song = null; var ret_lyrics = null; var start_time = null; var end_time = null; useEffect(() => {}, []); async function handleSearch() { if (autoCompleteRef.current) { autoCompleteRef.current.hide(); } let validSearch = (value.trim() && (value.split(" - ").length > 1)); let box = document.querySelector("[class*='lyrics-card-']") let spinner = $('#spinner'); let excluded_sources = []; $("#exclude-checkboxes").find("input:checkbox").each(function () { if (this.checked) { let src = this.id.replace("excl-", "").toLowerCase(); excluded_sources.push(src); } }); if (validSearch) { // define artist, song + additional checks let a_s_split = value.split(" - ", 2) var [search_artist, search_song] = a_s_split; search_artist = search_artist.trim(); search_song = search_song.trim(); if (! search_artist || ! search_song) { validSearch = false; // artist and song could not be derived } } if (!validSearch) { setShowAlert(true); setTimeout(() => { setShowAlert(false); }, 5000); $("#alert").removeClass("hidden"); return; } if (!$("#alert").hasClass("hidden")) { setShowAlert(false); $("#alert").addClass("hidden"); } $('#spinner').removeClass("hidden"); $(box).addClass("hidden"); //setTimeout(() => { $("#spinner").addClass("hidden"); alert('Not yet implemented.')}, 1000); search_toast = toast.info("Searching...", {style: { color: '#000000', backgroundColor: 'rgba(217, 242, 255, 0.8)'}}); start_time = new Date().getTime() $.ajax({ url: API_URL+'/lyric/search', method: 'POST', contentType: 'application/json; charset=utf-8', data: JSON.stringify({ a: search_artist, s: search_song, excluded_sources: excluded_sources, src: 'Web', extra: true, }) }).done((data, txtStatus, xhr) => { if (data.err || !data.lyrics) { $(spinner).addClass("hidden"); return toast.update(search_toast, { type: "", render: `🙁 ${data.errorText}`, style: { backgroundColor: "rgba(255, 0, 0, 0.5)", color: 'inherit' }, hideProgressBar: true, autoClose: 5000, }) } end_time = new Date().getTime(); let duration = (end_time - start_time) / 1000; ret_artist = data.artist; ret_song = data.song; ret_lyrics = data.lyrics; $(box).removeClass("hidden"); $(spinner).addClass("hidden"); $(box).html(`${ret_artist} - ${ret_song}${ret_lyrics}`); toast.update(search_toast, { type: "", style: { backgroundColor: "rgba(46, 186, 106, 1)", color: 'inherit' }, render: `🦄 Found! (Took ${duration}s)`, autoClose: 2000, hideProgressBar: true }); }).fail((jqXHR, textStatus, error) => { $(spinner).addClass("hidden"); let render_text = `😕 Failed to reach search endpoint (${jqXHR.status})`; if (typeof jqXHR.responseJSON.detail !== "undefined") { render_text += `\n${jqXHR.responseJSON.detail}`; } return toast.update(search_toast, { type: "", render: render_text, style: { backgroundColor: "rgba(255, 0, 0, 0.5)", color: 'inherit' }, hideProgressBar: true, autoClose: 5000, }) }) } const handleKeyDown = (e) => { if (e.key !== "Enter") return; e.preventDefault(); handleSearch(); }; const typeahead_search = (event) => { let query = event.query; $.ajax({ url: API_URL+'/typeahead/lyrics', method: 'POST', contentType: 'application/json; charset=utf-8', data: JSON.stringify({ query: query }), dataType: 'json', success: function (json) { return setSuggestions(json); } }) }; return (
{showAlert && ( setShowAlert(false)} > You must specify both an artist and song to search.
Format: Artist - Song
)}
{ setValue(e.target.value) }} onKeyDown={handleKeyDown} />
); } export const UICheckbox = forwardRef(function UICheckbox(opts = {}, ref) { const [checked, setChecked] = useState(false); const [showAlert, setShowAlert] = useState(false); let valid_exclusions = true; useImperativeHandle(ref, () => ({ setChecked: (val) => setChecked(val), checked, })); const verifyExclusions = (e) => { let exclude_error = false; if (($("#exclude-checkboxes").find("input:checkbox").filter(":checked").length == 3)){ $("#exclude-checkboxes").find("input:checkbox").each(function () { exclude_error = true; this.click(); }); if (exclude_error) { toast.error("All sources were excluded; exclusions have been reset.", { style: { backgroundColor: "rgba(255, 0, 0, 0.5)", color: 'inherit' } }, ); } } }; return (
{ setChecked(e.target.checked); verifyExclusions(); }} />
); }); export function LyricResultBox(opts={}) { return ( ) }