mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-11-04 15:13:57 -05:00
fix build warnings from tailwind, fonts, and fast refresh (#24359)
fix duplicated styles, move fonts to src/assets/fonts for vite to bundle (nginx already rewrites correctly), and fix fast refresh for PreviewController, auth context/provider, and statusbar context
This commit is contained in:
1 parent
cabdffea20
commit
79ca18d439
40 files changed
+112
-115
No files matched your search
@@ -343,13 +343,6 @@ http {
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
location /fonts/ {
|
||||
access_log off;
|
||||
expires 1y;
|
||||
include security_headers.conf;
|
||||
add_header Cache-Control "public";
|
||||
}
|
||||
|
||||
location /locales/ {
|
||||
access_log off;
|
||||
include security_headers.conf;
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -2,7 +2,7 @@ import { useEmbeddingsReindexProgress } from "@/api/ws";
|
||||
import {
|
||||
StatusBarMessagesContext,
|
||||
StatusMessage,
|
||||
} from "@/context/statusbar-provider";
|
||||
} from "@/context/statusbar-context";
|
||||
import useStats, { useAutoFrigateStats } from "@/hooks/use-stats";
|
||||
import StatusBarNotices from "@/components/health/StatusBarNotices";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
FormMessage,
|
||||
} from "@/components/ui/form";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-provider";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-context";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import axios from "axios";
|
||||
|
||||
@@ -61,7 +61,7 @@ import {
|
||||
JsonValue,
|
||||
} from "@/types/configForm";
|
||||
import ActivityIndicator from "@/components/indicators/activity-indicator";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-provider";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-context";
|
||||
import {
|
||||
cameraUpdateTopicMap,
|
||||
globalCameraDefaultSections,
|
||||
|
||||
@@ -19,7 +19,7 @@ import useNavigation from "@/hooks/use-navigation";
|
||||
import {
|
||||
StatusBarMessagesContext,
|
||||
StatusMessage,
|
||||
} from "@/context/statusbar-provider";
|
||||
} from "@/context/statusbar-context";
|
||||
import { Link } from "react-router-dom";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { isMobile } from "react-device-detect";
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
export abstract class PreviewController {
|
||||
public camera = "";
|
||||
|
||||
constructor(camera: string) {
|
||||
this.camera = camera;
|
||||
}
|
||||
|
||||
abstract scrubToTimestamp(time: number): boolean;
|
||||
|
||||
abstract finishedSeeking(): void;
|
||||
|
||||
abstract setNewPreviewStartTime(time: number): void;
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
} from "@/hooks/use-camera-previews";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useCameraFriendlyName } from "@/hooks/use-camera-friendly-name";
|
||||
import { PreviewController } from "./PreviewController";
|
||||
|
||||
type PreviewPlayerProps = {
|
||||
previewRef?: (ref: HTMLDivElement | null) => void;
|
||||
@@ -102,20 +103,6 @@ export default function PreviewPlayer({
|
||||
);
|
||||
}
|
||||
|
||||
export abstract class PreviewController {
|
||||
public camera = "";
|
||||
|
||||
constructor(camera: string) {
|
||||
this.camera = camera;
|
||||
}
|
||||
|
||||
abstract scrubToTimestamp(time: number): boolean;
|
||||
|
||||
abstract finishedSeeking(): void;
|
||||
|
||||
abstract setNewPreviewStartTime(time: number): void;
|
||||
}
|
||||
|
||||
type PreviewVideoPlayerProps = {
|
||||
visibilityRef?: (ref: HTMLDivElement | null) => void;
|
||||
className?: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Recording } from "@/types/record";
|
||||
import { DynamicPlayback } from "@/types/playback";
|
||||
import { PreviewController } from "../PreviewPlayer";
|
||||
import { PreviewController } from "../PreviewController";
|
||||
import { TimeRange, TrackingDetailsSequence } from "@/types/timeline";
|
||||
import {
|
||||
calculateInpointOffset,
|
||||
|
||||
@@ -16,7 +16,8 @@ import {
|
||||
RecordingCoverage,
|
||||
} from "@/types/record";
|
||||
import { Preview } from "@/types/preview";
|
||||
import PreviewPlayer, { PreviewController } from "../PreviewPlayer";
|
||||
import PreviewPlayer from "../PreviewPlayer";
|
||||
import { PreviewController } from "../PreviewController";
|
||||
import { DynamicVideoController } from "./DynamicVideoController";
|
||||
import HlsVideoPlayer, { HlsSource } from "../HlsVideoPlayer";
|
||||
import { useDetailStream } from "@/context/detail-stream-context";
|
||||
|
||||
@@ -65,7 +65,7 @@ import {
|
||||
import { buildConfigDataForPath } from "@/utils/configUtil";
|
||||
import { useConfigSchema } from "@/hooks/use-config-schema";
|
||||
import { useRestart } from "@/api/ws";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-provider";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-context";
|
||||
import RestartDialog from "@/components/overlay/dialog/RestartDialog";
|
||||
import ActivityIndicator from "@/components/indicators/activity-indicator";
|
||||
import SaveAllPreviewPopover from "@/components/overlay/detail/SaveAllPreviewPopover";
|
||||
|
||||
@@ -99,7 +99,11 @@ export default function AnimatedCircularProgressBar({
|
||||
</svg>
|
||||
<span
|
||||
data-current-value={currentPercent}
|
||||
className="duration-[var(--transition-length)] delay-[var(--delay)] absolute inset-0 m-auto size-fit ease-linear animate-in fade-in"
|
||||
className="absolute inset-0 m-auto size-fit ease-linear animate-in fade-in"
|
||||
style={{
|
||||
animationDuration: "var(--transition-length)",
|
||||
animationDelay: "var(--delay)",
|
||||
}}
|
||||
>
|
||||
{currentPercent}%
|
||||
</span>
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { createContext } from "react";
|
||||
|
||||
export interface AuthState {
|
||||
user: { username: string; role: string | null } | null;
|
||||
allowedCameras: string[];
|
||||
isLoading: boolean;
|
||||
isAuthenticated: boolean; // true if auth is required
|
||||
}
|
||||
|
||||
interface AuthContextType {
|
||||
auth: AuthState;
|
||||
login: (user: AuthState["user"]) => void;
|
||||
logout: () => void;
|
||||
}
|
||||
|
||||
export const AuthContext = createContext<AuthContextType>({
|
||||
auth: {
|
||||
user: null,
|
||||
allowedCameras: [],
|
||||
isLoading: true,
|
||||
isAuthenticated: false,
|
||||
},
|
||||
login: () => {},
|
||||
logout: () => {},
|
||||
});
|
||||
@@ -1,30 +1,7 @@
|
||||
import axios from "axios";
|
||||
import { createContext, useEffect, useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import useSWR from "swr";
|
||||
|
||||
interface AuthState {
|
||||
user: { username: string; role: string | null } | null;
|
||||
allowedCameras: string[];
|
||||
isLoading: boolean;
|
||||
isAuthenticated: boolean; // true if auth is required
|
||||
}
|
||||
|
||||
interface AuthContextType {
|
||||
auth: AuthState;
|
||||
login: (user: AuthState["user"]) => void;
|
||||
logout: () => void;
|
||||
}
|
||||
|
||||
export const AuthContext = createContext<AuthContextType>({
|
||||
auth: {
|
||||
user: null,
|
||||
allowedCameras: [],
|
||||
isLoading: true,
|
||||
isAuthenticated: false,
|
||||
},
|
||||
login: () => {},
|
||||
logout: () => {},
|
||||
});
|
||||
import { AuthContext, AuthState } from "./auth-context";
|
||||
|
||||
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
||||
const [auth, setAuth] = useState<AuthState>({
|
||||
@@ -6,7 +6,7 @@ import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import { StatusBarMessagesProvider } from "@/context/statusbar-provider";
|
||||
import { LanguageProvider } from "./language-provider";
|
||||
import { StreamingSettingsProvider } from "./streaming-settings-provider";
|
||||
import { AuthProvider } from "./auth-context";
|
||||
import { AuthProvider } from "./auth-provider";
|
||||
|
||||
type TProvidersProps = {
|
||||
children: ReactNode;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { createContext } from "react";
|
||||
|
||||
export type StatusMessage = {
|
||||
id: string;
|
||||
text: string;
|
||||
color?: string;
|
||||
link?: string;
|
||||
};
|
||||
|
||||
export type StatusMessagesState = {
|
||||
[key: string]: StatusMessage[];
|
||||
};
|
||||
|
||||
type StatusBarMessagesContextValue = {
|
||||
messages: StatusMessagesState;
|
||||
addMessage: (
|
||||
key: string,
|
||||
message: string,
|
||||
color?: string,
|
||||
messageId?: string,
|
||||
link?: string,
|
||||
) => string | undefined;
|
||||
removeMessage: (key: string, messageId: string) => void;
|
||||
clearMessages: (key: string) => void;
|
||||
};
|
||||
|
||||
export const StatusBarMessagesContext =
|
||||
createContext<StatusBarMessagesContextValue | null>(null);
|
||||
@@ -1,42 +1,13 @@
|
||||
import { useState, ReactNode, useCallback, useMemo } from "react";
|
||||
import {
|
||||
createContext,
|
||||
useState,
|
||||
ReactNode,
|
||||
useCallback,
|
||||
useMemo,
|
||||
} from "react";
|
||||
|
||||
export type StatusMessage = {
|
||||
id: string;
|
||||
text: string;
|
||||
color?: string;
|
||||
link?: string;
|
||||
};
|
||||
|
||||
export type StatusMessagesState = {
|
||||
[key: string]: StatusMessage[];
|
||||
};
|
||||
StatusBarMessagesContext,
|
||||
StatusMessagesState,
|
||||
} from "@/context/statusbar-context";
|
||||
|
||||
type StatusBarMessagesProviderProps = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
type StatusBarMessagesContextValue = {
|
||||
messages: StatusMessagesState;
|
||||
addMessage: (
|
||||
key: string,
|
||||
message: string,
|
||||
color?: string,
|
||||
messageId?: string,
|
||||
link?: string,
|
||||
) => string | undefined;
|
||||
removeMessage: (key: string, messageId: string) => void;
|
||||
clearMessages: (key: string) => void;
|
||||
};
|
||||
|
||||
export const StatusBarMessagesContext =
|
||||
createContext<StatusBarMessagesContextValue | null>(null);
|
||||
|
||||
export function StatusBarMessagesProvider({
|
||||
children,
|
||||
}: StatusBarMessagesProviderProps) {
|
||||
|
||||
+18
-18
@@ -48,126 +48,126 @@ html {
|
||||
font-style: normal;
|
||||
font-weight: 100;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-Thin.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-Thin.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-weight: 100;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-ThinItalic.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-ThinItalic.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 200;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-ExtraLight.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-ExtraLight.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-weight: 200;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-ExtraLightItalic.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-ExtraLightItalic.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-Light.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-Light.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-LightItalic.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-LightItalic.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-Regular.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-Regular.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-Italic.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-Italic.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-Medium.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-Medium.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-MediumItalic.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-MediumItalic.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-SemiBold.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-SemiBold.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-SemiBoldItalic.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-SemiBoldItalic.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-Bold.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-Bold.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-BoldItalic.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-BoldItalic.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 800;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-ExtraBold.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-ExtraBold.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-weight: 800;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-ExtraBoldItalic.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-ExtraBoldItalic.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: normal;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-Black.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-Black.woff2") format("woff2");
|
||||
}
|
||||
@font-face {
|
||||
font-family: "Inter";
|
||||
font-style: italic;
|
||||
font-weight: 900;
|
||||
font-display: swap;
|
||||
src: url("../fonts/Inter-BlackItalic.woff2") format("woff2");
|
||||
src: url("./assets/fonts/Inter-BlackItalic.woff2") format("woff2");
|
||||
}
|
||||
|
||||
.react-resizable-handle {
|
||||
|
||||
@@ -61,9 +61,8 @@ import {
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu";
|
||||
import PreviewPlayer, {
|
||||
PreviewController,
|
||||
} from "@/components/player/PreviewPlayer";
|
||||
import PreviewPlayer from "@/components/player/PreviewPlayer";
|
||||
import { PreviewController } from "@/components/player/PreviewController";
|
||||
import SummaryTimeline from "@/components/timeline/SummaryTimeline";
|
||||
import { RecordingStartingPoint } from "@/types/record";
|
||||
import VideoControls from "@/components/player/VideoControls";
|
||||
|
||||
@@ -3,9 +3,8 @@ import ReviewFilterGroup from "@/components/filter/ReviewFilterGroup";
|
||||
import DebugReplayDialog from "@/components/overlay/DebugReplayDialog";
|
||||
import ExportDialog from "@/components/overlay/ExportDialog";
|
||||
import ActionsDropdown from "@/components/overlay/ActionsDropdown";
|
||||
import PreviewPlayer, {
|
||||
PreviewController,
|
||||
} from "@/components/player/PreviewPlayer";
|
||||
import PreviewPlayer from "@/components/player/PreviewPlayer";
|
||||
import { PreviewController } from "@/components/player/PreviewController";
|
||||
import { DynamicVideoController } from "@/components/player/dynamic/DynamicVideoController";
|
||||
import DynamicVideoPlayer from "@/components/player/dynamic/DynamicVideoPlayer";
|
||||
import QualitySelector from "@/components/player/QualitySelector";
|
||||
|
||||
@@ -58,7 +58,7 @@ import {
|
||||
import type { ProfileState } from "@/types/profile";
|
||||
import { getProfileColor } from "@/utils/profileColors";
|
||||
import { isReplayCamera } from "@/utils/cameraUtil";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-provider";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-context";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
Select,
|
||||
|
||||
@@ -12,7 +12,7 @@ import { toast } from "sonner";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { Link } from "react-router-dom";
|
||||
import { LuExternalLink } from "react-icons/lu";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-provider";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-context";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
|
||||
@@ -14,7 +14,7 @@ import { useCallback, useContext, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import axios from "axios";
|
||||
import { toast } from "sonner";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-provider";
|
||||
import { StatusBarMessagesContext } from "@/context/statusbar-context";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
type RegionGridSettingsViewProps = {
|
||||
|
||||
Reference in new issue
Block a user