fix gitignore glob excluding ts files

This commit is contained in:
Josh Hawkins 2023-12-07 11:53:11 -06:00
parent fb1a4974c8
commit 52e72cbbbc
8 changed files with 503 additions and 2 deletions

1
.gitignore vendored
View File

@ -8,7 +8,6 @@ config/*
!config/*.example
models
*.mp4
*.ts
*.db
*.csv
frigate/version.py

View File

@ -0,0 +1,7 @@
declare global {
interface Window {
baseUrl?: any;
}
}
export const baseUrl = `${window.location.protocol}//${window.location.host}${window.baseUrl || '/'}`;

View 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
View 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))
}

View File

@ -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() {

View 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
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

61
web-new/vite.config.ts Normal file
View 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,
},
})