mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-06-22 04:11:53 +03:00
* Initial copy timestamp url implementation
* revise url format
* Implement share timestamp dialog
* Use translations
* Add comments
* Add validations to shared link
* Switch to searchEffect implementation
* Add missing accessibility related dialog description
* Change URL format to unix timestamps
* Remove unnecessary useEffect
* Remove duplicated dialog title
* Fixes/improvements based off PR review comments
* Add missing cancel button & separators to dialog
* Make share description clearer
* Bugfix: guard against showing toasts twice
Because this effect ends up running multiple times
* Clamp future timestamps to now
* Revert "Bugfix: guard against showing toasts twice"
This reverts commit 99fa5e1dee.
* Use normal separator
Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
* Fixes based off PR review comments
* Bugfix: Share dialog was not receiving the player timestamp after removing key that triggered remounts
* Defer `setRecording` and return true from hook for cleanup
* Remove timeout defer hack in favor of refactored hook
* Attempt to replay video muted on NotAllowedError
* Use separate persistent mute and temporary forced mute states
* Align cancel button with other dialogs
* Prevent wrapping on dialog title
* Remove extra "back" button on mobile drawer
* Fix back navigation when coming from direct shared timestamp links
* Use new timeformat hook
* Simplify dialog radio buttons
* Apply suggestions from code review
Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
---------
Co-authored-by: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com>
57 lines
1.3 KiB
TypeScript
57 lines
1.3 KiB
TypeScript
import { baseUrl } from "@/api/baseUrl.ts";
|
|
|
|
export const RECORDING_REVIEW_LINK_PARAM = "timestamp";
|
|
|
|
export type RecordingReviewLinkState = {
|
|
camera: string;
|
|
timestamp: number;
|
|
};
|
|
|
|
export function parseRecordingReviewLink(
|
|
value: string | null,
|
|
): RecordingReviewLinkState | undefined {
|
|
if (!value) {
|
|
return undefined;
|
|
}
|
|
|
|
const separatorIndex = value.lastIndexOf("_");
|
|
|
|
if (separatorIndex <= 0 || separatorIndex == value.length - 1) {
|
|
return undefined;
|
|
}
|
|
|
|
const camera = value.slice(0, separatorIndex);
|
|
const timestamp = value.slice(separatorIndex + 1);
|
|
|
|
if (!camera || !timestamp) {
|
|
return undefined;
|
|
}
|
|
|
|
const parsedTimestamp = Number(timestamp);
|
|
const now = Math.floor(Date.now() / 1000);
|
|
|
|
if (!Number.isFinite(parsedTimestamp) || parsedTimestamp <= 0) {
|
|
return undefined;
|
|
}
|
|
|
|
return {
|
|
camera,
|
|
// clamp future timestamps to now
|
|
timestamp: Math.min(Math.floor(parsedTimestamp), now),
|
|
};
|
|
}
|
|
|
|
export function createRecordingReviewUrl(
|
|
pathname: string,
|
|
state: RecordingReviewLinkState,
|
|
): string {
|
|
const url = new URL(baseUrl);
|
|
url.pathname = pathname.startsWith("/") ? pathname : `/${pathname}`;
|
|
url.searchParams.set(
|
|
RECORDING_REVIEW_LINK_PARAM,
|
|
`${state.camera}_${Math.floor(state.timestamp)}`,
|
|
);
|
|
|
|
return url.toString();
|
|
}
|