mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-08 12:15:25 +03:00
fix gitignore glob excluding ts files
This commit is contained in:
parent
fb1a4974c8
commit
52e72cbbbc
1
.gitignore
vendored
1
.gitignore
vendored
@ -8,7 +8,6 @@ config/*
|
|||||||
!config/*.example
|
!config/*.example
|
||||||
models
|
models
|
||||||
*.mp4
|
*.mp4
|
||||||
*.ts
|
|
||||||
*.db
|
*.db
|
||||||
*.csv
|
*.csv
|
||||||
frigate/version.py
|
frigate/version.py
|
||||||
|
|||||||
7
web-new/src/api/baseUrl.ts
Normal file
7
web-new/src/api/baseUrl.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
baseUrl?: any;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const baseUrl = `${window.location.protocol}//${window.location.host}${window.baseUrl || '/'}`;
|
||||||
25
web-new/src/lib/formatTimeAgo.ts
Normal file
25
web-new/src/lib/formatTimeAgo.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
const formatter = new Intl.RelativeTimeFormat(undefined, {
|
||||||
|
numeric: "always",
|
||||||
|
})
|
||||||
|
|
||||||
|
const DIVISIONS: { amount: number; name: Intl.RelativeTimeFormatUnit }[] = [
|
||||||
|
{ amount: 60, name: "seconds" },
|
||||||
|
{ amount: 60, name: "minutes" },
|
||||||
|
{ amount: 24, name: "hours" },
|
||||||
|
{ amount: 7, name: "days" },
|
||||||
|
{ amount: 4.34524, name: "weeks" },
|
||||||
|
{ amount: 12, name: "months" },
|
||||||
|
{ amount: Number.POSITIVE_INFINITY, name: "years" },
|
||||||
|
]
|
||||||
|
|
||||||
|
export function formatTimeAgo(date: Date) {
|
||||||
|
let duration = (date.getTime() - new Date().getTime()) / 1000
|
||||||
|
|
||||||
|
for (let i = 0; i < DIVISIONS.length; i++) {
|
||||||
|
const division = DIVISIONS[i]
|
||||||
|
if (Math.abs(duration) < division.amount) {
|
||||||
|
return formatter.format(Math.round(duration), division.name)
|
||||||
|
}
|
||||||
|
duration /= division.amount
|
||||||
|
}
|
||||||
|
}
|
||||||
6
web-new/src/lib/utils.ts
Normal file
6
web-new/src/lib/utils.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { type ClassValue, clsx } from "clsx"
|
||||||
|
import { twMerge } from "tailwind-merge"
|
||||||
|
|
||||||
|
export function cn(...inputs: ClassValue[]) {
|
||||||
|
return twMerge(clsx(inputs))
|
||||||
|
}
|
||||||
@ -12,7 +12,7 @@ import {
|
|||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { useDetectState } from "@/api/ws";
|
import { useDetectState } from "@/api/ws";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig.ts";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import Heading from "@/components/ui/heading";
|
import Heading from "@/components/ui/heading";
|
||||||
|
|
||||||
export function Dashboard() {
|
export function Dashboard() {
|
||||||
|
|||||||
402
web-new/src/types/frigateConfig.ts
Normal file
402
web-new/src/types/frigateConfig.ts
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
export interface FrigateConfig {
|
||||||
|
audio: {
|
||||||
|
enabled: boolean;
|
||||||
|
enabled_in_config: boolean | null;
|
||||||
|
filters: string[] | null;
|
||||||
|
listen: string[];
|
||||||
|
max_not_heard: number;
|
||||||
|
min_volume: number;
|
||||||
|
num_threads: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
birdseye: {
|
||||||
|
enabled: boolean;
|
||||||
|
height: number;
|
||||||
|
mode: "objects";
|
||||||
|
quality: number;
|
||||||
|
restream: boolean;
|
||||||
|
width: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
cameras: {
|
||||||
|
[cameraName: string]: {
|
||||||
|
audio: {
|
||||||
|
enabled: boolean;
|
||||||
|
enabled_in_config: boolean;
|
||||||
|
filters: string[] | null;
|
||||||
|
listen: string[];
|
||||||
|
max_not_heard: number;
|
||||||
|
min_volume: number;
|
||||||
|
num_threads: number;
|
||||||
|
};
|
||||||
|
best_image_timeout: number;
|
||||||
|
birdseye: {
|
||||||
|
enabled: boolean;
|
||||||
|
mode: "objects";
|
||||||
|
order: number;
|
||||||
|
};
|
||||||
|
detect: {
|
||||||
|
annotation_offset: number;
|
||||||
|
enabled: boolean;
|
||||||
|
fps: number;
|
||||||
|
height: number;
|
||||||
|
max_disappeared: number;
|
||||||
|
min_initialized: number;
|
||||||
|
stationary: {
|
||||||
|
interval: number;
|
||||||
|
max_frames: {
|
||||||
|
default: number | null;
|
||||||
|
objects: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
threshold: number;
|
||||||
|
};
|
||||||
|
width: number;
|
||||||
|
};
|
||||||
|
enabled: boolean;
|
||||||
|
ffmpeg: {
|
||||||
|
global_args: string[];
|
||||||
|
hwaccel_args: string;
|
||||||
|
input_args: string;
|
||||||
|
inputs: {
|
||||||
|
global_args: string[];
|
||||||
|
hwaccel_args: string[];
|
||||||
|
input_args: string;
|
||||||
|
path: string;
|
||||||
|
roles: string[];
|
||||||
|
}[];
|
||||||
|
output_args: {
|
||||||
|
detect: string[];
|
||||||
|
record: string;
|
||||||
|
rtmp: string;
|
||||||
|
};
|
||||||
|
retry_interval: number;
|
||||||
|
};
|
||||||
|
ffmpeg_cmds: {
|
||||||
|
cmd: string;
|
||||||
|
roles: string[];
|
||||||
|
}[];
|
||||||
|
live: {
|
||||||
|
height: number;
|
||||||
|
quality: number;
|
||||||
|
stream_name: string;
|
||||||
|
};
|
||||||
|
motion: {
|
||||||
|
contour_area: number;
|
||||||
|
delta_alpha: number;
|
||||||
|
frame_alpha: number;
|
||||||
|
frame_height: number;
|
||||||
|
improve_contrast: boolean;
|
||||||
|
lightning_threshold: number;
|
||||||
|
mask: string[];
|
||||||
|
mqtt_off_delay: number;
|
||||||
|
threshold: number;
|
||||||
|
};
|
||||||
|
mqtt: {
|
||||||
|
bounding_box: boolean;
|
||||||
|
crop: boolean;
|
||||||
|
enabled: boolean;
|
||||||
|
height: number;
|
||||||
|
quality: number;
|
||||||
|
required_zones: string[];
|
||||||
|
timestamp: boolean;
|
||||||
|
};
|
||||||
|
name: string;
|
||||||
|
objects: {
|
||||||
|
filters: {
|
||||||
|
[objectName: string]: {
|
||||||
|
mask: string | null;
|
||||||
|
max_area: number;
|
||||||
|
max_ratio: number;
|
||||||
|
min_area: number;
|
||||||
|
min_ratio: number;
|
||||||
|
min_score: number;
|
||||||
|
threshold: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
mask: string;
|
||||||
|
track: string[];
|
||||||
|
};
|
||||||
|
onvif: {
|
||||||
|
autotracking: {
|
||||||
|
calibrate_on_startup: boolean,
|
||||||
|
enabled: boolean;
|
||||||
|
enabled_in_config: boolean;
|
||||||
|
movement_weights: string[];
|
||||||
|
required_zones: string[];
|
||||||
|
return_preset: string;
|
||||||
|
timeout: number;
|
||||||
|
track: string[];
|
||||||
|
zoom_factor: number;
|
||||||
|
zooming: string;
|
||||||
|
};
|
||||||
|
host: string;
|
||||||
|
password: string | null;
|
||||||
|
port: number;
|
||||||
|
user: string | null;
|
||||||
|
};
|
||||||
|
record: {
|
||||||
|
enabled: boolean;
|
||||||
|
enabled_in_config: boolean;
|
||||||
|
events: {
|
||||||
|
objects: string[] | null;
|
||||||
|
post_capture: number;
|
||||||
|
pre_capture: number;
|
||||||
|
required_zones: string[];
|
||||||
|
retain: {
|
||||||
|
default: number;
|
||||||
|
mode: string;
|
||||||
|
objects: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
expire_interval: number;
|
||||||
|
export: {
|
||||||
|
timelapse_args: string;
|
||||||
|
};
|
||||||
|
preview: {
|
||||||
|
quality: string;
|
||||||
|
};
|
||||||
|
retain: {
|
||||||
|
days: number;
|
||||||
|
mode: string;
|
||||||
|
};
|
||||||
|
sync_recordings: boolean;
|
||||||
|
};
|
||||||
|
rtmp: {
|
||||||
|
enabled: boolean;
|
||||||
|
};
|
||||||
|
snapshots: {
|
||||||
|
bounding_box: boolean;
|
||||||
|
clean_copy: boolean;
|
||||||
|
crop: boolean;
|
||||||
|
enabled: boolean;
|
||||||
|
height: number | null;
|
||||||
|
quality: number;
|
||||||
|
required_zones: string[];
|
||||||
|
retain: {
|
||||||
|
default: number;
|
||||||
|
mode: string;
|
||||||
|
objects: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
timestamp: boolean;
|
||||||
|
};
|
||||||
|
timestamp_style: {
|
||||||
|
color: {
|
||||||
|
blue: number;
|
||||||
|
green: number;
|
||||||
|
red: number;
|
||||||
|
};
|
||||||
|
effect: string | null;
|
||||||
|
format: string;
|
||||||
|
position: string;
|
||||||
|
thickness: number;
|
||||||
|
};
|
||||||
|
ui: {
|
||||||
|
dashboard: boolean;
|
||||||
|
order: number;
|
||||||
|
};
|
||||||
|
webui_url: string | null;
|
||||||
|
zones: {
|
||||||
|
[zoneName: string]: {
|
||||||
|
coordinates: string;
|
||||||
|
filters: Record<string, unknown>;
|
||||||
|
inertia: number;
|
||||||
|
objects: any[];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
database: {
|
||||||
|
path: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
detect: {
|
||||||
|
annotation_offset: number;
|
||||||
|
enabled: boolean;
|
||||||
|
fps: number;
|
||||||
|
height: number | null;
|
||||||
|
max_disappeared: number | null;
|
||||||
|
min_initialized: number | null;
|
||||||
|
stationary: {
|
||||||
|
interval: number | null;
|
||||||
|
max_frames: {
|
||||||
|
default: number | null;
|
||||||
|
objects: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
threshold: number | null;
|
||||||
|
};
|
||||||
|
width: number | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
detectors: {
|
||||||
|
coral: {
|
||||||
|
device: string;
|
||||||
|
model: {
|
||||||
|
height: number;
|
||||||
|
input_pixel_format: string;
|
||||||
|
input_tensor: string;
|
||||||
|
labelmap: Record<string, string>;
|
||||||
|
labelmap_path: string | null;
|
||||||
|
model_type: string;
|
||||||
|
path: string;
|
||||||
|
width: number;
|
||||||
|
};
|
||||||
|
type: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
environment_vars: Record<string, unknown>;
|
||||||
|
|
||||||
|
ffmpeg: {
|
||||||
|
global_args: string[];
|
||||||
|
hwaccel_args: string;
|
||||||
|
input_args: string;
|
||||||
|
output_args: {
|
||||||
|
detect: string[];
|
||||||
|
record: string;
|
||||||
|
rtmp: string;
|
||||||
|
};
|
||||||
|
retry_interval: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
go2rtc: Record<string, unknown>;
|
||||||
|
|
||||||
|
live: {
|
||||||
|
height: number;
|
||||||
|
quality: number;
|
||||||
|
stream_name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
logger: {
|
||||||
|
default: string;
|
||||||
|
logs: Record<string, string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
model: {
|
||||||
|
height: number;
|
||||||
|
input_pixel_format: string;
|
||||||
|
input_tensor: string;
|
||||||
|
labelmap: Record<string, unknown>;
|
||||||
|
labelmap_path: string | null;
|
||||||
|
model_type: string;
|
||||||
|
path: string | null;
|
||||||
|
width: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
motion: Record<string, unknown> | null;
|
||||||
|
|
||||||
|
mqtt: {
|
||||||
|
client_id: string;
|
||||||
|
enabled: boolean;
|
||||||
|
host: string;
|
||||||
|
port: number;
|
||||||
|
stats_interval: number;
|
||||||
|
tls_ca_certs: string | null;
|
||||||
|
tls_client_cert: string | null;
|
||||||
|
tls_client_key: string | null;
|
||||||
|
tls_insecure: boolean | null;
|
||||||
|
topic_prefix: string;
|
||||||
|
user: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
objects: {
|
||||||
|
filters: {
|
||||||
|
[objectName: string]: {
|
||||||
|
mask: string | null;
|
||||||
|
max_area: number;
|
||||||
|
max_ratio: number;
|
||||||
|
min_area: number;
|
||||||
|
min_ratio: number;
|
||||||
|
min_score: number;
|
||||||
|
threshold: number;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
mask: string;
|
||||||
|
track: string[];
|
||||||
|
};
|
||||||
|
|
||||||
|
plus: {
|
||||||
|
enabled: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
record: {
|
||||||
|
enabled: boolean;
|
||||||
|
enabled_in_config: boolean | null;
|
||||||
|
events: {
|
||||||
|
objects: string[] | null;
|
||||||
|
post_capture: number;
|
||||||
|
pre_capture: number;
|
||||||
|
required_zones: string[];
|
||||||
|
retain: {
|
||||||
|
default: number;
|
||||||
|
mode: string;
|
||||||
|
objects: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
expire_interval: number;
|
||||||
|
export: {
|
||||||
|
timelapse_args: string;
|
||||||
|
};
|
||||||
|
preview: {
|
||||||
|
quality: string;
|
||||||
|
};
|
||||||
|
retain: {
|
||||||
|
days: number;
|
||||||
|
mode: string;
|
||||||
|
};
|
||||||
|
sync_recordings: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
rtmp: {
|
||||||
|
enabled: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
snapshots: {
|
||||||
|
bounding_box: boolean;
|
||||||
|
clean_copy: boolean;
|
||||||
|
crop: boolean;
|
||||||
|
enabled: boolean;
|
||||||
|
height: number | null;
|
||||||
|
quality: number;
|
||||||
|
required_zones: string[];
|
||||||
|
retain: {
|
||||||
|
default: number;
|
||||||
|
mode: string;
|
||||||
|
objects: Record<string, unknown>;
|
||||||
|
};
|
||||||
|
timestamp: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
telemetry: {
|
||||||
|
network_interfaces: any[];
|
||||||
|
stats: {
|
||||||
|
amd_gpu_stats: boolean;
|
||||||
|
intel_gpu_stats: boolean;
|
||||||
|
network_bandwidth: boolean;
|
||||||
|
};
|
||||||
|
version_check: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
timestamp_style: {
|
||||||
|
color: {
|
||||||
|
blue: number;
|
||||||
|
green: number;
|
||||||
|
red: number;
|
||||||
|
};
|
||||||
|
effect: string | null;
|
||||||
|
format: string;
|
||||||
|
position: string;
|
||||||
|
thickness: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
ui: {
|
||||||
|
date_style: string;
|
||||||
|
live_mode: string;
|
||||||
|
strftime_fmt: string | null;
|
||||||
|
time_format: string;
|
||||||
|
time_style: string;
|
||||||
|
timezone: string | null;
|
||||||
|
use_experimental: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
1
web-new/src/vite-env.d.ts
vendored
Normal file
1
web-new/src/vite-env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
/// <reference types="vite/client" />
|
||||||
61
web-new/vite.config.ts
Normal file
61
web-new/vite.config.ts
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/// <reference types="vitest" />
|
||||||
|
import path from "path"
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import react from '@vitejs/plugin-react-swc'
|
||||||
|
import monacoEditorPlugin from 'vite-plugin-monaco-editor';
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
define: {
|
||||||
|
'import.meta.vitest': 'undefined',
|
||||||
|
},
|
||||||
|
server: {
|
||||||
|
proxy: {
|
||||||
|
'/api': {
|
||||||
|
target: 'http://localhost:5000',
|
||||||
|
ws: true,
|
||||||
|
},
|
||||||
|
'/vod': {
|
||||||
|
target: 'http://localhost:5000'
|
||||||
|
},
|
||||||
|
'/exports': {
|
||||||
|
target: 'http://localhost:5000'
|
||||||
|
},
|
||||||
|
'/ws': {
|
||||||
|
target: 'ws://localhost:5000',
|
||||||
|
ws: true,
|
||||||
|
},
|
||||||
|
'/live': {
|
||||||
|
target: 'ws://localhost:5000',
|
||||||
|
changeOrigin: true,
|
||||||
|
ws: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
react(),
|
||||||
|
monacoEditorPlugin.default({
|
||||||
|
customWorkers: [{ label: 'yaml', entry: 'monaco-yaml/yaml.worker' }],
|
||||||
|
languageWorkers: ['editorWorkerService'], // we don't use any of the default languages
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"@": path.resolve(__dirname, "./src"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
test: {
|
||||||
|
environment: 'jsdom',
|
||||||
|
alias: {
|
||||||
|
'testing-library': path.resolve(__dirname, './__test__/testing-library.js'),
|
||||||
|
},
|
||||||
|
setupFiles: ['./__test__/test-setup.ts'],
|
||||||
|
includeSource: ['src/**/*.{js,jsx,ts,tsx}'],
|
||||||
|
coverage: {
|
||||||
|
reporter: ['text-summary', 'text'],
|
||||||
|
},
|
||||||
|
mockReset: true,
|
||||||
|
restoreMocks: true,
|
||||||
|
globals: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
Loading…
Reference in New Issue
Block a user