Refresh recordings when data is stale (#20470)
Some checks are pending
CI / AMD64 Build (push) Waiting to run
CI / ARM Build (push) Waiting to run
CI / Jetson Jetpack 6 (push) Waiting to run
CI / AMD64 Extra Build (push) Blocked by required conditions
CI / ARM Extra Build (push) Blocked by required conditions
CI / Synaptics Build (push) Blocked by required conditions
CI / Assemble and push default build (push) Blocked by required conditions

* Refresh recordings when data is stale

* Fix

* Improve checks

* Increase time to 10 minutes
This commit is contained in:
Nicolas Mowen 2025-10-13 17:18:04 -06:00 committed by GitHub
parent 6a031eb9ee
commit 1a1ec8cf91
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 0 deletions

View File

@ -62,6 +62,10 @@ export class DynamicVideoController {
this.playerController.pause(); this.playerController.pause();
} }
isPlaying(): boolean {
return !this.playerController.paused && !this.playerController.ended;
}
seekToTimestamp(time: number, play: boolean = false) { seekToTimestamp(time: number, play: boolean = false) {
if (time < this.timeRange.after || time > this.timeRange.before) { if (time < this.timeRange.after || time > this.timeRange.before) {
this.timeToStart = time; this.timeToStart = time;

View File

@ -484,6 +484,7 @@ export default function Events() {
timeRange={selectedTimeRange} timeRange={selectedTimeRange}
filter={reviewFilter} filter={reviewFilter}
updateFilter={onUpdateFilter} updateFilter={onUpdateFilter}
refreshData={reloadData}
/> />
); );
} }

View File

@ -68,6 +68,8 @@ import { CameraNameLabel } from "@/components/camera/CameraNameLabel";
import { useAllowedCameras } from "@/hooks/use-allowed-cameras"; import { useAllowedCameras } from "@/hooks/use-allowed-cameras";
import { GenAISummaryDialog } from "@/components/overlay/chip/GenAISummaryChip"; import { GenAISummaryDialog } from "@/components/overlay/chip/GenAISummaryChip";
const DATA_REFRESH_TIME = 600000; // 10 minutes
type RecordingViewProps = { type RecordingViewProps = {
startCamera: string; startCamera: string;
startTime: number; startTime: number;
@ -78,6 +80,7 @@ type RecordingViewProps = {
allPreviews?: Preview[]; allPreviews?: Preview[];
filter?: ReviewFilter; filter?: ReviewFilter;
updateFilter: (newFilter: ReviewFilter) => void; updateFilter: (newFilter: ReviewFilter) => void;
refreshData?: () => void;
}; };
export function RecordingView({ export function RecordingView({
startCamera, startCamera,
@ -89,6 +92,7 @@ export function RecordingView({
allPreviews, allPreviews,
filter, filter,
updateFilter, updateFilter,
refreshData,
}: RecordingViewProps) { }: RecordingViewProps) {
const { t } = useTranslation(["views/events"]); const { t } = useTranslation(["views/events"]);
const { data: config } = useSWR<FrigateConfig>("config"); const { data: config } = useSWR<FrigateConfig>("config");
@ -192,6 +196,40 @@ export function RecordingView({
} }
}, [selectedRangeIdx, chunkedTimeRange]); }, [selectedRangeIdx, chunkedTimeRange]);
// visibility tracking for refreshing stale data
const lastVisibilityTime = useRef<number>(Date.now());
useEffect(() => {
const handleVisibilityChange = () => {
if (document.visibilityState === "visible") {
const now = Date.now();
const timeSinceLastVisible = now - lastVisibilityTime.current;
// Only refresh if user was away for a while
// and the video is not currently playing
if (
timeSinceLastVisible >= DATA_REFRESH_TIME &&
refreshData &&
mainControllerRef.current &&
!mainControllerRef.current.isPlaying()
) {
refreshData();
}
lastVisibilityTime.current = now;
} else {
lastVisibilityTime.current = Date.now();
}
};
document.addEventListener("visibilitychange", handleVisibilityChange);
return () => {
document.removeEventListener("visibilitychange", handleVisibilityChange);
};
}, [refreshData]);
// scrubbing and timeline state // scrubbing and timeline state
const [scrubbing, setScrubbing] = useState(false); const [scrubbing, setScrubbing] = useState(false);