YACWC
This commit is contained in:
@@ -15,6 +15,7 @@ function App() {
|
|||||||
const [statusMessages, setStatusMessages] = useState([]);
|
const [statusMessages, setStatusMessages] = useState([]);
|
||||||
const [markerTime, setMarkerTime] = useState(0);
|
const [markerTime, setMarkerTime] = useState(0);
|
||||||
const playerRef = useRef(null);
|
const playerRef = useRef(null);
|
||||||
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
||||||
const playerInstanceRef = useRef(null);
|
const playerInstanceRef = useRef(null);
|
||||||
// State for the values
|
// State for the values
|
||||||
window.chartRef = chartRef;
|
window.chartRef = chartRef;
|
||||||
@@ -22,6 +23,8 @@ function App() {
|
|||||||
window.playerInstanceRef = playerInstanceRef;
|
window.playerInstanceRef = playerInstanceRef;
|
||||||
// Slider states
|
// Slider states
|
||||||
|
|
||||||
|
const inputRef = useRef(null);
|
||||||
|
|
||||||
const [sliderMin, setSliderMin] = useState(0.0);
|
const [sliderMin, setSliderMin] = useState(0.0);
|
||||||
const [sliderMax, setSliderMax] = useState(1.0);
|
const [sliderMax, setSliderMax] = useState(1.0);
|
||||||
// Date range states
|
// Date range states
|
||||||
@@ -39,16 +42,25 @@ function App() {
|
|||||||
const [lastSubmitted, setLastSubmitted] = useState({
|
const [lastSubmitted, setLastSubmitted] = useState({
|
||||||
startRange,
|
startRange,
|
||||||
endRange,
|
endRange,
|
||||||
sliderValue,
|
|
||||||
queryText,
|
queryText,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check if any value has changed
|
// // Check if any value has changed
|
||||||
const hasChanged =
|
// const queryChanged =
|
||||||
startRange !== lastSubmitted.startRange ||
|
// startRange !== lastSubmitted.startRange ||
|
||||||
endRange !== lastSubmitted.endRange ||
|
// endRange !== lastSubmitted.endRange ||
|
||||||
sliderValue !== lastSubmitted.sliderValue ||
|
// queryText !== lastSubmitted.queryText;
|
||||||
queryText !== lastSubmitted.queryText;
|
|
||||||
|
// Check if queryText is different from lastSubmitted.queryText
|
||||||
|
const textChanged = queryText !== lastSubmitted.queryText;
|
||||||
|
|
||||||
|
const startChanged =
|
||||||
|
startRange.getTime() !== new Date(lastSubmitted.startRange).getTime();
|
||||||
|
|
||||||
|
const endChanged =
|
||||||
|
endRange.getTime() !== new Date(lastSubmitted.endRange).getTime();
|
||||||
|
|
||||||
|
const queryChanged = textChanged || startChanged || endChanged;
|
||||||
|
|
||||||
const streamComputeStatus = () => {
|
const streamComputeStatus = () => {
|
||||||
fetch("api/return_status")
|
fetch("api/return_status")
|
||||||
@@ -78,7 +90,6 @@ function App() {
|
|||||||
let c_line = JSON.parse(line);
|
let c_line = JSON.parse(line);
|
||||||
|
|
||||||
if (c_line["task"] !== "DONE_QUIT") {
|
if (c_line["task"] !== "DONE_QUIT") {
|
||||||
console.log(c_line);
|
|
||||||
setStatusMessages((msgs) => [
|
setStatusMessages((msgs) => [
|
||||||
...msgs,
|
...msgs,
|
||||||
c_line,
|
c_line,
|
||||||
@@ -98,8 +109,6 @@ function App() {
|
|||||||
};
|
};
|
||||||
// Function to resubmit fetch
|
// Function to resubmit fetch
|
||||||
const handleResubmit = (doTestMode = false) => {
|
const handleResubmit = (doTestMode = false) => {
|
||||||
console.log("startRange, endRange:", startRange, endRange);
|
|
||||||
console.log("test mode:", doTestMode);
|
|
||||||
let startRangeUse;
|
let startRangeUse;
|
||||||
let endRangeUse;
|
let endRangeUse;
|
||||||
if (doTestMode == true) {
|
if (doTestMode == true) {
|
||||||
@@ -114,7 +123,6 @@ function App() {
|
|||||||
endRangeUse = endRange;
|
endRangeUse = endRange;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Using date range:", startRangeUse, endRangeUse);
|
|
||||||
setStartRange(startRangeUse);
|
setStartRange(startRangeUse);
|
||||||
setEndRange(endRangeUse);
|
setEndRange(endRangeUse);
|
||||||
|
|
||||||
@@ -134,9 +142,8 @@ function App() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
setLastSubmitted({
|
setLastSubmitted({
|
||||||
startRangeUse,
|
startRange: startRangeUse,
|
||||||
endRangeUse,
|
endRange: endRangeUse,
|
||||||
sliderValue,
|
|
||||||
queryText,
|
queryText,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -256,7 +263,11 @@ function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="app-container">
|
<div className="app-container">
|
||||||
<div className="section-box-horiz">
|
<div
|
||||||
|
className={`section-box-horiz${
|
||||||
|
drawerOpen ? " drawer-open" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
<div className="flex-group">
|
<div className="flex-group">
|
||||||
<CustomDateRangePicker
|
<CustomDateRangePicker
|
||||||
startDate={startRange}
|
startDate={startRange}
|
||||||
@@ -266,23 +277,38 @@ function App() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-group">
|
<div className="flex-group">
|
||||||
<input
|
<div style={{ position: "relative", width: "100%" }}>
|
||||||
type="text"
|
<input
|
||||||
placeholder="Enter query"
|
type="text"
|
||||||
value={queryText}
|
placeholder="Enter query"
|
||||||
onChange={(e) => setQueryText(e.target.value)}
|
value={queryText}
|
||||||
style={{
|
onChange={(e) => setQueryText(e.target.value)}
|
||||||
marginLeft: "16px",
|
onKeyDown={(e) => {
|
||||||
marginRight: "16px",
|
if (e.key === "Enter") handleResubmit();
|
||||||
padding: "8px",
|
}}
|
||||||
borderRadius: "4px",
|
style={{
|
||||||
border: "1px solid #343a40",
|
marginLeft: "16px",
|
||||||
color: "#fff", // Text white
|
marginRight: "16px",
|
||||||
backgroundColor: "#23272f", // Optional: dark background for contrast
|
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>
|
</div>
|
||||||
<div className="flex-group">
|
<div
|
||||||
|
className="flex-group"
|
||||||
|
style={{ visibility: queryChanged ? "hidden" : "visible" }}
|
||||||
|
>
|
||||||
<label
|
<label
|
||||||
style={{
|
style={{
|
||||||
marginLeft: "8px",
|
marginLeft: "8px",
|
||||||
@@ -293,7 +319,10 @@ function App() {
|
|||||||
Threshold:
|
Threshold:
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-group">
|
<div
|
||||||
|
className="flex-group"
|
||||||
|
style={{ visibility: queryChanged ? "hidden" : "visible" }}
|
||||||
|
>
|
||||||
<input
|
<input
|
||||||
type="range"
|
type="range"
|
||||||
min={sliderMin}
|
min={sliderMin}
|
||||||
@@ -302,19 +331,36 @@ function App() {
|
|||||||
value={sliderValue}
|
value={sliderValue}
|
||||||
onChange={(e) => updateDataAndValue(e.target.value)}
|
onChange={(e) => updateDataAndValue(e.target.value)}
|
||||||
style={{
|
style={{
|
||||||
width: "120px",
|
width: "100%",
|
||||||
color: "#fff", // Text white
|
color: "#fff",
|
||||||
backgroundColor: "#23272f", // Optional: dark background for contrast
|
backgroundColor: "#23272f",
|
||||||
|
minWidth: 0,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-group">
|
<div
|
||||||
|
className="flex-group"
|
||||||
|
style={{ visibility: queryChanged ? "hidden" : "visible" }}
|
||||||
|
>
|
||||||
<span style={{ marginLeft: "8px", color: "#fff" }}>
|
<span style={{ marginLeft: "8px", color: "#fff" }}>
|
||||||
{sliderValue.toFixed(2)}
|
{sliderValue.toFixed(2)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-group">
|
<div
|
||||||
<button onClick={handleResubmit}>Resubmit</button>
|
className="flex-group"
|
||||||
|
style={{ visibility: queryChanged ? "visible" : "hidden" }}
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
onClick={handleResubmit}
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
padding: "12px 0",
|
||||||
|
fontSize: "1.1em",
|
||||||
|
marginTop: "8px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Resubmit
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
|||||||
@@ -443,16 +443,30 @@ const EmbedTimeline = React.memo(function EmbedTimeline({
|
|||||||
|
|
||||||
// --- Chart Event Handlers ---
|
// --- Chart Event Handlers ---
|
||||||
async function onChartClick(params, echarts) {
|
async function onChartClick(params, echarts) {
|
||||||
|
let pixel;
|
||||||
const nativeEvent = params.event.event;
|
const nativeEvent = params.event.event;
|
||||||
const pixel = [nativeEvent.offsetX, nativeEvent.offsetY];
|
|
||||||
|
// Support both mouse and touch events
|
||||||
|
if (nativeEvent.touches && nativeEvent.touches.length > 0) {
|
||||||
|
// Touch event
|
||||||
|
const rect = nativeEvent.target.getBoundingClientRect();
|
||||||
|
const touch = nativeEvent.touches[0];
|
||||||
|
pixel = [
|
||||||
|
touch.clientX - rect.left,
|
||||||
|
touch.clientY - rect.top
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
// Mouse event
|
||||||
|
pixel = [nativeEvent.offsetX, nativeEvent.offsetY];
|
||||||
|
}
|
||||||
|
|
||||||
const dataCoord = echarts.convertFromPixel({ seriesIndex: 0 }, pixel);
|
const dataCoord = echarts.convertFromPixel({ seriesIndex: 0 }, pixel);
|
||||||
|
|
||||||
const res = await fetch("/api/events/click", {
|
const res = await fetch("/api/events/click", {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: { "Content-Type": "application/json" },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
timestamp:
|
timestamp: mapVirtualToRealTime(dataCoord[0], breaks, virtualTime) / 1000,
|
||||||
mapVirtualToRealTime(dataCoord[0], breaks, virtualTime) / 1000,
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
if (!res.ok) throw new Error(`HTTP error: ${res.status}`);
|
if (!res.ok) throw new Error(`HTTP error: ${res.status}`);
|
||||||
|
|||||||
@@ -2,6 +2,37 @@ import { useTable } from "react-table";
|
|||||||
import { useMemo } from "react";
|
import { useMemo } from "react";
|
||||||
import "./StatusDisplay.css";
|
import "./StatusDisplay.css";
|
||||||
|
|
||||||
|
function ProgressBar({ progress, total }) {
|
||||||
|
const percent = total ? Math.round((progress / total) * 100) : 0;
|
||||||
|
return (
|
||||||
|
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
background: "#181a20",
|
||||||
|
borderRadius: 6,
|
||||||
|
width: 80,
|
||||||
|
height: 14,
|
||||||
|
overflow: "hidden",
|
||||||
|
border: "1px solid #3a7afe",
|
||||||
|
marginRight: 8,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
width: `${percent}%`,
|
||||||
|
height: "100%",
|
||||||
|
background: "#3a7afe",
|
||||||
|
transition: "width 0.3s",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<span style={{ color: "#e0e6ed", fontSize: 13 }}>
|
||||||
|
{progress}/{total} ({percent}%)
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function StatusesDisplayHUD({ statusMessages }) {
|
export default function StatusesDisplayHUD({ statusMessages }) {
|
||||||
const msg = {};
|
const msg = {};
|
||||||
const dataPre = {};
|
const dataPre = {};
|
||||||
@@ -9,7 +40,19 @@ export default function StatusesDisplayHUD({ statusMessages }) {
|
|||||||
{ Header: "When", accessor: "WHEN" },
|
{ Header: "When", accessor: "WHEN" },
|
||||||
{ Header: "Scheduled", accessor: "SCHEDULED" },
|
{ Header: "Scheduled", accessor: "SCHEDULED" },
|
||||||
{ Header: "Queued", accessor: "QUEUED" },
|
{ Header: "Queued", accessor: "QUEUED" },
|
||||||
{ Header: "Processing", accessor: "VECTOR_CALC" },
|
{
|
||||||
|
Header: "Processing",
|
||||||
|
accessor: "VECTOR_CALC",
|
||||||
|
Cell: ({ value }) =>
|
||||||
|
value && value.type === "progress" ? (
|
||||||
|
<ProgressBar
|
||||||
|
progress={value.progress}
|
||||||
|
total={value.how_many}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
value || ""
|
||||||
|
),
|
||||||
|
},
|
||||||
{ Header: "Calculating", accessor: "SCORE_CALC" },
|
{ Header: "Calculating", accessor: "SCORE_CALC" },
|
||||||
{ Header: "Status", accessor: "STATUS" },
|
{ Header: "Status", accessor: "STATUS" },
|
||||||
];
|
];
|
||||||
@@ -55,8 +98,13 @@ export default function StatusesDisplayHUD({ statusMessages }) {
|
|||||||
m["progress"] +
|
m["progress"] +
|
||||||
"/" +
|
"/" +
|
||||||
m["how_many"];
|
m["how_many"];
|
||||||
dataPre[when_key]["VECTOR_CALC"] =
|
// dataPre[when_key]["VECTOR_CALC"] =
|
||||||
m["progress"] + "/" + m["how_many"];
|
// m["progress"] + "/" + m["how_many"];
|
||||||
|
dataPre[when_key]["VECTOR_CALC"] = {
|
||||||
|
progress: m["progress"],
|
||||||
|
how_many: m["how_many"],
|
||||||
|
type: "progress",
|
||||||
|
};
|
||||||
break;
|
break;
|
||||||
case "VECTOR_CALC_IN_FOLDER_DONE":
|
case "VECTOR_CALC_IN_FOLDER_DONE":
|
||||||
msg_show = "Finished processing videos";
|
msg_show = "Finished processing videos";
|
||||||
@@ -72,7 +120,7 @@ export default function StatusesDisplayHUD({ statusMessages }) {
|
|||||||
msg_show = c_task;
|
msg_show = c_task;
|
||||||
}
|
}
|
||||||
msg[when_key] = msg_show;
|
msg[when_key] = msg_show;
|
||||||
console.log(when_key);
|
// console.log(when_key);
|
||||||
dataPre[when_key]["STATUS"] = msg_show;
|
dataPre[when_key]["STATUS"] = msg_show;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -86,48 +134,42 @@ export default function StatusesDisplayHUD({ statusMessages }) {
|
|||||||
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
|
const { getTableProps, getTableBodyProps, headerGroups, rows, prepareRow } =
|
||||||
useTable({ columns: columnsMemo, data });
|
useTable({ columns: columnsMemo, data });
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="table-container">
|
|
||||||
<table
|
|
||||||
{...getTableProps()}
|
|
||||||
style={{ "--col-count": columns.length - 1 }}
|
|
||||||
>
|
|
||||||
{rows.length > 0 && (
|
|
||||||
<thead>
|
|
||||||
{headerGroups.map((headerGroup) => (
|
|
||||||
<tr {...headerGroup.getHeaderGroupProps()}>
|
|
||||||
{headerGroup.headers.map((column) => (
|
|
||||||
<th {...column.getHeaderProps()}>
|
|
||||||
{column.render("Header")}
|
|
||||||
</th>
|
|
||||||
))}
|
|
||||||
</tr>
|
|
||||||
))}
|
|
||||||
</thead>
|
|
||||||
)}
|
|
||||||
<tbody {...getTableBodyProps()}>
|
|
||||||
{rows.map((row) => {
|
|
||||||
prepareRow(row);
|
|
||||||
return (
|
|
||||||
<tr {...row.getRowProps()}>
|
|
||||||
{row.cells.map((cell) => (
|
|
||||||
<td {...cell.getCellProps()}>
|
|
||||||
{cell.render("Cell")}
|
|
||||||
</td>
|
|
||||||
))}
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
})}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{Object.entries(msg).map(([when, messages], idx) => (
|
{rows.length > 0 && (
|
||||||
<StatusDisplay key={when} when={when} message={messages} />
|
<div className="table-container">
|
||||||
))}
|
<table
|
||||||
|
{...getTableProps()}
|
||||||
|
style={{ "--col-count": columns.length - 1 }}
|
||||||
|
>
|
||||||
|
<thead>
|
||||||
|
{headerGroups.map((headerGroup) => (
|
||||||
|
<tr {...headerGroup.getHeaderGroupProps()}>
|
||||||
|
{headerGroup.headers.map((column) => (
|
||||||
|
<th {...column.getHeaderProps()}>
|
||||||
|
{column.render("Header")}
|
||||||
|
</th>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</thead>
|
||||||
|
<tbody {...getTableBodyProps()}>
|
||||||
|
{rows.map((row) => {
|
||||||
|
prepareRow(row);
|
||||||
|
return (
|
||||||
|
<tr {...row.getRowProps()}>
|
||||||
|
{row.cells.map((cell) => (
|
||||||
|
<td {...cell.getCellProps()}>
|
||||||
|
{cell.render("Cell")}
|
||||||
|
</td>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user