misc
This commit is contained in:
@@ -14,7 +14,6 @@ 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 }) {
|
||||
window.toast = toast;
|
||||
const theme = document.documentElement.getAttribute("data-theme")
|
||||
|
@@ -11,7 +11,6 @@ const STATIONS = {
|
||||
rock: { label: "Rock" },
|
||||
rap: { label: "Rap" },
|
||||
electronic: { label: "Electronic" },
|
||||
classical: { label: "Classical" },
|
||||
pop: { label: "Pop" },
|
||||
};
|
||||
|
||||
@@ -84,8 +83,8 @@ export default function Player() {
|
||||
const hls = new Hls({
|
||||
lowLatencyMode: true,
|
||||
abrEnabled: false,
|
||||
liveSyncDuration: 2.5, // seconds behind live edge target
|
||||
liveMaxLatencyDuration: 3.5, // max allowed latency before catchup
|
||||
liveSyncDuration: 1.0, // seconds behind live edge target
|
||||
liveMaxLatencyDuration: 2.0, // max allowed latency before catchup
|
||||
liveCatchUpPlaybackRate: 1.05, // playback speed when catching up
|
||||
});
|
||||
|
||||
@@ -111,8 +110,6 @@ export default function Player() {
|
||||
|
||||
// Update elapsed time smoothly
|
||||
useEffect(() => {
|
||||
if (!isPlaying) return;
|
||||
|
||||
const intervalId = setInterval(() => {
|
||||
const now = Date.now();
|
||||
const deltaSec = (now - lastUpdateTimestamp.current) / 1000;
|
||||
|
@@ -1,10 +1,10 @@
|
||||
---
|
||||
import { metaData, API_URL } from "../config";
|
||||
import { metaData, ENVIRONMENT } from "../config";
|
||||
import RandomMsg from "../components/RandomMsg";
|
||||
import { buildTime, buildNumber } from '../utils/buildTime.js';
|
||||
|
||||
const YEAR = new Date().getFullYear();
|
||||
var ENVIRONMENT = (Astro.url.hostname === "localhost") ? "Dev": "Prod";
|
||||
|
||||
|
||||
|
||||
---
|
||||
|
@@ -4,7 +4,7 @@ import { Button } from "@mui/joy";
|
||||
import { Accordion, AccordionTab } from "primereact/accordion";
|
||||
import { AutoComplete } from "primereact/autocomplete";
|
||||
import BreadcrumbNav from "./BreadcrumbNav";
|
||||
import { API_URL } from "@/config";
|
||||
import { API_URL, ENVIRONMENT } from "@/config";
|
||||
|
||||
export default function MediaRequestForm() {
|
||||
const [type, setType] = useState("artist");
|
||||
@@ -25,6 +25,8 @@ export default function MediaRequestForm() {
|
||||
const debounceTimeout = useRef(null);
|
||||
const autoCompleteRef = useRef(null);
|
||||
|
||||
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); // Helper for delays
|
||||
|
||||
// Helper fetch wrapper that includes cookies automatically
|
||||
const authFetch = async (url, options = {}) => {
|
||||
const opts = {
|
||||
@@ -55,10 +57,17 @@ export default function MediaRequestForm() {
|
||||
|
||||
debounceTimeout.current = setTimeout(async () => {
|
||||
try {
|
||||
// Ensure at least 600ms between actual requests
|
||||
const now = Date.now();
|
||||
if (!searchArtists.lastCall) searchArtists.lastCall = 0;
|
||||
const elapsed = now - searchArtists.lastCall;
|
||||
const minDelay = 600; // ms
|
||||
if (elapsed < minDelay) await delay(minDelay - elapsed);
|
||||
|
||||
searchArtists.lastCall = Date.now();
|
||||
|
||||
const res = await authFetch(
|
||||
`${API_URL}/trip/get_artists_by_name?artist=${encodeURIComponent(
|
||||
query
|
||||
)}`,
|
||||
`${API_URL}/trip/get_artists_by_name?artist=${encodeURIComponent(query)}`
|
||||
);
|
||||
if (!res.ok) throw new Error("API error");
|
||||
const data = await res.json();
|
||||
@@ -67,9 +76,11 @@ export default function MediaRequestForm() {
|
||||
toast.error("Failed to fetch artist suggestions.");
|
||||
setArtistSuggestions([]);
|
||||
}
|
||||
}, 300);
|
||||
}, 500); // debounce 500ms
|
||||
};
|
||||
|
||||
|
||||
|
||||
//helpers for string truncation
|
||||
const truncate = (text, maxLen) =>
|
||||
maxLen <= 3
|
||||
@@ -205,18 +216,23 @@ export default function MediaRequestForm() {
|
||||
if (type !== "artist" || albums.length === 0) return;
|
||||
|
||||
let isCancelled = false;
|
||||
|
||||
const albumsToFetch = albums.filter((a) => !tracksByAlbum[a.id]);
|
||||
|
||||
if (albumsToFetch.length === 0) return;
|
||||
|
||||
const fetchTracksSequentially = async () => {
|
||||
const minDelay = 600; // ms between API requests
|
||||
for (const album of albumsToFetch) {
|
||||
if (isCancelled) break;
|
||||
|
||||
setLoadingAlbumId(album.id);
|
||||
|
||||
try {
|
||||
const now = Date.now();
|
||||
if (!fetchTracksSequentially.lastCall) fetchTracksSequentially.lastCall = 0;
|
||||
const elapsed = now - fetchTracksSequentially.lastCall;
|
||||
if (elapsed < minDelay) await delay(minDelay - elapsed);
|
||||
fetchTracksSequentially.lastCall = Date.now();
|
||||
|
||||
const res = await authFetch(`${API_URL}/trip/get_tracks_by_album_id/${album.id}`);
|
||||
if (!res.ok) throw new Error("API error");
|
||||
const data = await res.json();
|
||||
@@ -299,7 +315,12 @@ export default function MediaRequestForm() {
|
||||
try {
|
||||
// Example: simulate submission delay
|
||||
await new Promise((resolve) => setTimeout(resolve, 1500));
|
||||
toast.success("Request submitted!");
|
||||
const allSelectedIds = Object.values(selectedTracks)
|
||||
.filter(arr => Array.isArray(arr)) // skip null entries
|
||||
.flat();
|
||||
toast.success(`Request submitted! (${allSelectedIds.length} tracks)`);
|
||||
console.debug("Requested: ", selectedTracks);
|
||||
console.debug("Flattened: ", allSelectedIds);
|
||||
} catch (err) {
|
||||
toast.error("Failed to submit request.");
|
||||
} finally {
|
||||
@@ -310,6 +331,7 @@ export default function MediaRequestForm() {
|
||||
return (
|
||||
<div className="max-w-3xl mx-auto my-10 p-6 rounded-xl shadow-md bg-white dark:bg-neutral-900 text-neutral-900 dark:text-neutral-100 border border-neutral-200 dark:border-neutral-700">
|
||||
<style>{`
|
||||
/* Accordion tab backgrounds & text */
|
||||
.p-accordion-tab {
|
||||
background-color: #ffffff;
|
||||
color: #000000;
|
||||
@@ -318,14 +340,65 @@ export default function MediaRequestForm() {
|
||||
background-color: #1e1e1e;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* Accordion header link */
|
||||
.p-accordion-header .p-accordion-header-link {
|
||||
background-color: #f9f9f9;
|
||||
color: #000000;
|
||||
}
|
||||
[data-theme="dark"] .p-accordion-header .p-accordion-header-link {
|
||||
background-color: #1e1e1e !important;
|
||||
color: #ffffff !important;
|
||||
}
|
||||
|
||||
/* Accordion content panel */
|
||||
.p-accordion-content {
|
||||
background-color: #fafafa;
|
||||
color: #000000;
|
||||
}
|
||||
[data-theme="dark"] .p-accordion-content {
|
||||
background-color: #2a2a2a;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* Track list UL/LI styling */
|
||||
.p-accordion-content ul {
|
||||
padding-left: 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
[data-theme="dark"] .p-accordion-content ul {
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
/* Track items */
|
||||
.p-accordion-content li {
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
}
|
||||
[data-theme="dark"] .p-accordion-content li {
|
||||
background-color: #2a2a2a;
|
||||
border-bottom: 1px solid #444;
|
||||
}
|
||||
|
||||
/* Checkboxes inside track list */
|
||||
.p-accordion-content input[type="checkbox"] {
|
||||
accent-color: #1d4ed8; /* optional for consistent dark mode styling */
|
||||
}
|
||||
|
||||
/* Loading spinner (optional darker style) */
|
||||
[data-theme="dark"] .animate-spin {
|
||||
border-color: #555;
|
||||
border-top-color: #1d4ed8;
|
||||
}
|
||||
|
||||
/* Small text like audio quality, duration, version */
|
||||
.p-accordion-content span {
|
||||
color: #555;
|
||||
}
|
||||
[data-theme="dark"] .p-accordion-content span {
|
||||
color: #aaa;
|
||||
}
|
||||
`}</style>
|
||||
|
||||
<BreadcrumbNav currentPage="request" />
|
||||
@@ -369,6 +442,7 @@ export default function MediaRequestForm() {
|
||||
field="artist"
|
||||
completeMethod={searchArtists}
|
||||
onChange={handleArtistChange}
|
||||
minLength={3}
|
||||
placeholder="Artist"
|
||||
dropdown
|
||||
className="w-full"
|
||||
@@ -454,13 +528,13 @@ export default function MediaRequestForm() {
|
||||
checked={selected?.includes(String(track.id))}
|
||||
onChange={() => toggleTrack(id, track.id)}
|
||||
className="cursor-pointer"
|
||||
aria-label={`Select track ${track.title}`}
|
||||
aria-label={`Select track ${track.title} `}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => handleTrackClick(track.id, selectedArtist.artist, track.title)}
|
||||
className="font-medium text-blue-600 hover:underline cursor-pointer bg-transparent border-none p-0"
|
||||
aria-label={`Download track ${track.title}`}
|
||||
aria-label={`Download track ${track.title} `}
|
||||
>
|
||||
{track.title}
|
||||
</button>
|
||||
|
@@ -14,3 +14,4 @@ export const socialLinks = {
|
||||
|
||||
export const MAJOR_VERSION = "0.0"
|
||||
export const RELEASE_FLAG = "Alpha";
|
||||
export const ENVIRONMENT = import.meta.env.DEV ? "Dev" : "Prod";
|
@@ -1,8 +1,9 @@
|
||||
---
|
||||
import MediaRequestForm from "@/components/qs2/MediaRequestForm"
|
||||
import MediaRequestForm from "@/components/TRip/MediaRequestForm"
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import Root from "@/components/AppLayout.jsx";
|
||||
import { verifyToken } from "@/utils/jwt";
|
||||
import { ENVIRONMENT } from "@/config";
|
||||
|
||||
const token = Astro.cookies.get("access_token")?.value;
|
||||
let user = null;
|
||||
|
@@ -3,14 +3,16 @@ import MediaRequestForm from "@/components/TRip/MediaRequestForm"
|
||||
import Base from "@/layouts/Base.astro";
|
||||
import Root from "@/components/AppLayout.jsx";
|
||||
import { verifyToken } from "@/utils/jwt";
|
||||
import { ENVIRONMENT } from "@/config";
|
||||
|
||||
const token = Astro.cookies.get("access_token")?.value;
|
||||
let user = null;
|
||||
|
||||
try {
|
||||
const IS_DEV = (ENVIRONMENT==="Dev");
|
||||
if (token) {
|
||||
user = verifyToken(token);
|
||||
if (user) {
|
||||
if (IS_DEV) {
|
||||
console.log("Verified!", user);
|
||||
} else {
|
||||
throw Error("Authentication required");
|
||||
|
Reference in New Issue
Block a user