mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-07 11:45:24 +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
|
||||
models
|
||||
*.mp4
|
||||
*.ts
|
||||
*.db
|
||||
*.csv
|
||||
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";
|
||||
import { useDetectState } from "@/api/ws";
|
||||
import useSWR from "swr";
|
||||
import { FrigateConfig } from "@/types/frigateConfig.ts";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import Heading from "@/components/ui/heading";
|
||||
|
||||
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