This commit is contained in:
2025-09-22 11:07:28 -04:00
parent 47f631fedb
commit aa5ad8327e
9 changed files with 821 additions and 620 deletions

View File

@@ -8,8 +8,8 @@
background: #181a20;
}
/* Video.js player */
.video-js-mod {
/* Video.js player styles */
.video-player-fullscreen {
position: fixed;
top: 0;
left: 0;
@@ -17,98 +17,105 @@
height: 100vh;
object-fit: contain;
background: #000;
}
.vjs-tech {
.video-tech {
object-fit: contain;
}
/* Main app layout */
/* Main app container */
.app-container {
display: flex;
flex-direction: column;
height: 100vh;
width: 100vw;
margin: 0;
width: 95vw;
max-width: 95vw;
margin: 0 auto;
padding: 0;
gap: 12px;
/* background: #181a20; */
gap: 0;
}
.flex-group {
display: flex;
flex-direction: column; /* or 'row' if you want horizontal grouping */
flex: 1 1 0;
min-width: 0;
}
/* Section containers */
.section-box-horiz {
overflow: visible;
flex-direction: row;
display: flex;
align-items: center;
justify-content: center;
}
/* Section containers */
.section-box {
flex: 0 0 5%;
overflow: visible;
/* background: #23272f; */
/* padding: 0;
box-sizing: border-box;
border-radius: 10px;
margin: 0 16px;
box-shadow: 0 2px 8px rgba(0,0,0,0.10); */
display: flex;
align-items: center;
justify-content: center;
}
.timeline-container {
flex: 0 0 24%;
overflow: visible;
background: #20232a;
padding: 0;
box-sizing: border-box;
border-radius: 10px;
margin: 0 16px;
box-shadow: 0 2px 8px rgba(0,0,0,0.10);
display: flex;
align-items: center;
justify-content: center;
}
.section-box:last-of-type {
flex: 1 1 68%;
overflow: hidden;
/* Controls section */
.controls-section {
width: 100%;
margin-bottom: 12px;
background: #23272f;
padding: 0;
box-sizing: border-box;
border-radius: 10px;
margin: 0 16px 16px 16px;
box-shadow: 0 2px 8px rgba(0,0,0,0.10);
display: flex;
align-items: center;
justify-content: center;
padding: 16px 0;
text-align: center;
box-sizing: border-box;
}
/* Responsive tweaks */
/* Control group wrapper */
.control-group {
display: inline-block;
vertical-align: middle;
min-width: 10%;
margin: 0 8px;
}
/* Status display section */
.status-section {
width: 100%;
margin-bottom: 12px;
}
/* Timeline container */
.timeline-section {
width: 100%;
height: 30vh;
min-height: 200px;
background: #20232a;
border-radius: 10px;
margin: 0 auto;
box-shadow: 0 2px 8px rgba(0,0,0,0.10);
text-align: center;
box-sizing: border-box;
margin-bottom: 12px;
padding: 0;
}
/* Video player section */
.video-section {
width: 100%;
height: 60vw;
margin-top: 12px;
min-height: 40vw;
background: #23272f;
border-radius: 10px;
margin: 0 auto;
box-shadow: 0 2px 8px rgba(0,0,0,0.10);
text-align: center;
box-sizing: border-box;
margin-bottom: 12px;
padding: 0;
}
/* Date range picker styles */
.date-picker-wrapper {
max-width: 98vw;
padding: 12px 8px;
border-radius: 8px;
}
/* Responsive styles */
@media (max-width: 600px) {
.app-container {
gap: 6px;
gap: 0;
}
.section-box,
.timeline-container,
.section-box:last-of-type {
margin: 0 4px;
.video-section,
.timeline-section {
margin: 0 4px 8px 4px;
border-radius: 6px;
padding: 0;
}
.date-range-selector {
.date-picker-wrapper {
max-width: 98vw;
padding: 12px 8px;
border-radius: 8px;
}
}
.controls-section {
padding: 8px 0;
}
}

View File

@@ -155,6 +155,8 @@ function App() {
newData["videos"] = newData["videos"].filter(
(vid) => vid["embed_scores"]["score"][1] >= floatValue
);
newData['threshold'] = floatValue;
console.log(newData['threshold'])
setDataResults(newData);
}
@@ -209,22 +211,59 @@ function App() {
);
}
}
// Memoize the timeline click handler
const handleTimelineClick = useCallback(
(path, timeoffset) => {
if (playerRef.current && playerInstanceRef.current) {
playerInstanceRef.current.src({
src: "api/" + path,
type: "video/mp4",
});
playerInstanceRef.current.on("loadedmetadata", () => {
playerInstanceRef.current.currentTime(timeoffset);
});
}
},
[] // Empty dependency array since it only uses playerRef
);
const handleTimelineClick = useCallback(
(path, timeoffset) => {
if (playerRef.current && playerInstanceRef.current) {
const player = playerInstanceRef.current;
console.log("Setting video source:", "api/" + path);
console.log("Target time offset:", timeoffset);
// Clear any existing source first
player.reset();
player.src({
src: "api/" + path,
type: "video/mp4",
});
player.load();
// Add multiple event listeners for debugging
player.one("loadedmetadata", () => {
console.log("Video metadata loaded");
console.log("Video duration:", player.duration());
player.currentTime(timeoffset);
// Try to play after setting time
const playPromise = player.play();
if (playPromise !== undefined) {
playPromise.then(() => {
console.log("Video started playing");
}).catch(error => {
console.error("Error playing video:", error);
});
}
});
player.one("error", (e) => {
console.error("Video error:", e);
console.error("Player error:", player.error());
});
player.one("loadstart", () => {
console.log("Load started");
});
player.one("canplay", () => {
console.log("Video can start playing");
});
} else {
console.error("Player ref not available");
}
},
[]
);
useEffect(() => {
const params = new URLSearchParams(window.location.search);
@@ -263,12 +302,8 @@ function App() {
return (
<div className="app-container">
<div
className={`section-box-horiz${
drawerOpen ? " drawer-open" : ""
}`}
>
<div className="flex-group">
<div className="controls-section">
<div className="control-group">
<CustomDateRangePicker
startDate={startRange}
endDate={endRange}
@@ -276,52 +311,46 @@ function App() {
setEndRange={setEndRange}
/>
</div>
<div className="flex-group">
<div style={{ position: "relative", width: "100%" }}>
<input
type="text"
placeholder="Enter query"
value={queryText}
onChange={(e) => setQueryText(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") handleResubmit();
}}
style={{
marginLeft: "16px",
marginRight: "16px",
padding: "8px",
borderRadius: "4px",
border: "1px solid #343a40",
color: "#fff",
backgroundColor: "#23272f",
width: "100%",
minWidth: 0,
boxSizing: "border-box",
fontSize: "1.1em",
transition: "width 0.2s",
}}
ref={inputRef}
size={Math.max(queryText.length, 1)}
/>
</div>
<div className="control-group">
<input
type="text"
placeholder="Enter query"
value={queryText}
onChange={(e) => setQueryText(e.target.value)}
onKeyDown={(e) => {
if (e.key === "Enter") handleResubmit();
}}
style={{
// padding: "8px",
// borderRadius: "4px",
// border: "1px solid #343a40",
// color: "#fff",
// backgroundColor: "#23272f",
// width: "100%",
// minWidth: 0,
// boxSizing: "border-box",
fontSize: "1.1em",
// transition: "width 0.2s",
}}
ref={inputRef}
size={Math.max(queryText.length, 25)}
/>
</div>
<div
className="flex-group"
className="control-group"
style={{ visibility: queryChanged ? "hidden" : "visible" }}
>
<label
style={{
marginLeft: "8px",
marginRight: "8px",
color: "#fff",
}}
>
Threshold:
</label>
<label style={{ color: "#fff" }}>Threshold:</label>
</div>
<div
className="flex-group"
style={{ visibility: queryChanged ? "hidden" : "visible" }}
className="control-group"
style={{
display: "inline-block",
verticalAlign: "middle",
margin: "0 8px",
width: "120px",
visibility: queryChanged ? "hidden" : "visible",
}}
>
<input
type="range"
@@ -339,15 +368,13 @@ function App() {
/>
</div>
<div
className="flex-group"
className="control-group"
style={{ visibility: queryChanged ? "hidden" : "visible" }}
>
<span style={{ marginLeft: "8px", color: "#fff" }}>
{sliderValue.toFixed(2)}
</span>
<span style={{ color: "#fff" }}>{sliderValue.toFixed(2)}</span>
</div>
<div
className="flex-group"
className="control-group"
style={{ visibility: queryChanged ? "visible" : "hidden" }}
>
<button
@@ -363,18 +390,20 @@ function App() {
</button>
</div>
</div>
<div>
<div className="status-section">
<StatusesDisplayHUD statusMessages={statusMessages} />
</div>
<div className="timeline-container">
<div className="timeline-section">
<EmbedTimeline
chartRef={chartRef}
data_in={dataResults}
onTimelineClick={handleTimelineClick}
/>
</div>
<div className="section-box">
<div className="video-section vjs-16-9 vjs-fluid">
<VideoPlayer
videoRef={playerRef}
playerInstanceRef={playerInstanceRef}

File diff suppressed because it is too large Load Diff