mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-07 05:55:27 +03:00
chore: remove most import { t } from "i18next";
This commit is contained in:
parent
52b1c7fbda
commit
78b159ebb1
@ -12,7 +12,7 @@ import { SearchResult } from "@/types/search";
|
|||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { TooltipPortal } from "@radix-ui/react-tooltip";
|
import { TooltipPortal } from "@radix-ui/react-tooltip";
|
||||||
import useContextMenu from "@/hooks/use-contextmenu";
|
import useContextMenu from "@/hooks/use-contextmenu";
|
||||||
import { t } from "i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
type SearchThumbnailProps = {
|
type SearchThumbnailProps = {
|
||||||
searchResult: SearchResult;
|
searchResult: SearchResult;
|
||||||
@ -23,6 +23,7 @@ export default function SearchThumbnail({
|
|||||||
searchResult,
|
searchResult,
|
||||||
onClick,
|
onClick,
|
||||||
}: SearchThumbnailProps) {
|
}: SearchThumbnailProps) {
|
||||||
|
const { t } = useTranslation(["views/search"]);
|
||||||
const apiHost = useApiHost();
|
const apiHost = useApiHost();
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();
|
const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { SearchResult } from "@/types/search";
|
|||||||
import ActivityIndicator from "../indicators/activity-indicator";
|
import ActivityIndicator from "../indicators/activity-indicator";
|
||||||
import SearchResultActions from "../menu/SearchResultActions";
|
import SearchResultActions from "../menu/SearchResultActions";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { t } from "i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
type SearchThumbnailProps = {
|
type SearchThumbnailProps = {
|
||||||
searchResult: SearchResult;
|
searchResult: SearchResult;
|
||||||
@ -25,14 +25,15 @@ export default function SearchThumbnailFooter({
|
|||||||
showObjectLifecycle,
|
showObjectLifecycle,
|
||||||
showSnapshot,
|
showSnapshot,
|
||||||
}: SearchThumbnailProps) {
|
}: SearchThumbnailProps) {
|
||||||
|
const { t } = useTranslation(["views/search"]);
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
|
|
||||||
// date
|
// date
|
||||||
const formattedDate = useFormattedTimestamp(
|
const formattedDate = useFormattedTimestamp(
|
||||||
searchResult.start_time,
|
searchResult.start_time,
|
||||||
config?.ui.time_format == "24hour"
|
config?.ui.time_format == "24hour"
|
||||||
? t("time.formattedTimestampExcludeSeconds.24hour")
|
? t("time.formattedTimestampExcludeSeconds.24hour", { ns: "common" })
|
||||||
: t("time.formattedTimestampExcludeSeconds"),
|
: t("time.formattedTimestampExcludeSeconds", { ns: "common" }),
|
||||||
config?.ui.timezone,
|
config?.ui.timezone,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -14,7 +14,6 @@ import { DateRangePicker } from "../ui/calendar-range";
|
|||||||
import { DateRange } from "react-day-picker";
|
import { DateRange } from "react-day-picker";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import PlatformAwareDialog from "../overlay/dialog/PlatformAwareDialog";
|
import PlatformAwareDialog from "../overlay/dialog/PlatformAwareDialog";
|
||||||
import { t } from "i18next";
|
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
type CalendarFilterButtonProps = {
|
type CalendarFilterButtonProps = {
|
||||||
@ -98,12 +97,13 @@ export function CalendarRangeFilterButton({
|
|||||||
defaultText,
|
defaultText,
|
||||||
updateSelectedRange,
|
updateSelectedRange,
|
||||||
}: CalendarRangeFilterButtonProps) {
|
}: CalendarRangeFilterButtonProps) {
|
||||||
|
const { t } = useTranslation(["components/filter"]);
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
const selectedDate = useFormattedRange(
|
const selectedDate = useFormattedRange(
|
||||||
range?.from == undefined ? 0 : range.from.getTime() / 1000 + 1,
|
range?.from == undefined ? 0 : range.from.getTime() / 1000 + 1,
|
||||||
range?.to == undefined ? 0 : range.to.getTime() / 1000 - 1,
|
range?.to == undefined ? 0 : range.to.getTime() / 1000 - 1,
|
||||||
t("time.formattedTimestampOnlyMonthAndDay"),
|
t("time.formattedTimestampOnlyMonthAndDay", { ns: "common" }),
|
||||||
);
|
);
|
||||||
|
|
||||||
const trigger = (
|
const trigger = (
|
||||||
|
|||||||
@ -10,7 +10,6 @@ import { DropdownMenuSeparator } from "../ui/dropdown-menu";
|
|||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import FilterSwitch from "./FilterSwitch";
|
import FilterSwitch from "./FilterSwitch";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { t } from "i18next";
|
|
||||||
|
|
||||||
type LogSettingsButtonProps = {
|
type LogSettingsButtonProps = {
|
||||||
selectedLabels?: LogSeverity[];
|
selectedLabels?: LogSeverity[];
|
||||||
@ -101,6 +100,7 @@ export function GeneralFilterContent({
|
|||||||
selectedLabels,
|
selectedLabels,
|
||||||
updateLabelFilter,
|
updateLabelFilter,
|
||||||
}: GeneralFilterContentProps) {
|
}: GeneralFilterContentProps) {
|
||||||
|
const { t } = useTranslation(["components/filter"]);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="scrollbar-container h-auto overflow-y-auto overflow-x-hidden">
|
<div className="scrollbar-container h-auto overflow-y-auto overflow-x-hidden">
|
||||||
|
|||||||
@ -20,18 +20,19 @@ import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer";
|
|||||||
import { DialogClose } from "../ui/dialog";
|
import { DialogClose } from "../ui/dialog";
|
||||||
import { LuLogOut, LuSquarePen } from "react-icons/lu";
|
import { LuLogOut, LuSquarePen } from "react-icons/lu";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { t } from "i18next";
|
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import SetPasswordDialog from "../overlay/SetPasswordDialog";
|
import SetPasswordDialog from "../overlay/SetPasswordDialog";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
type AccountSettingsProps = {
|
type AccountSettingsProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function AccountSettings({ className }: AccountSettingsProps) {
|
export default function AccountSettings({ className }: AccountSettingsProps) {
|
||||||
|
const { t } = useTranslation(["views/settings"]);
|
||||||
const { data: profile } = useSWR("profile");
|
const { data: profile } = useSWR("profile");
|
||||||
const { data: config } = useSWR("config");
|
const { data: config } = useSWR("config");
|
||||||
const logoutUrl = config?.proxy?.logout_url || `${baseUrl}api/logout`;
|
const logoutUrl = config?.proxy?.logout_url || `${baseUrl}api/logout`;
|
||||||
@ -50,12 +51,9 @@ export default function AccountSettings({ className }: AccountSettingsProps) {
|
|||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
setPasswordDialogOpen(false);
|
setPasswordDialogOpen(false);
|
||||||
toast.success(
|
toast.success(t("users.toast.success.updatePassword"), {
|
||||||
t("users.toast.success.updatePassword", { ns: "views/settings" }),
|
position: "top-center",
|
||||||
{
|
});
|
||||||
position: "top-center",
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
@ -65,7 +63,6 @@ export default function AccountSettings({ className }: AccountSettingsProps) {
|
|||||||
"Unknown error";
|
"Unknown error";
|
||||||
toast.error(
|
toast.error(
|
||||||
t("users.toast.error.setPasswordFailed", {
|
t("users.toast.error.setPasswordFailed", {
|
||||||
ns: "views/settings",
|
|
||||||
errorMessage,
|
errorMessage,
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
@ -94,7 +91,7 @@ export default function AccountSettings({ className }: AccountSettingsProps) {
|
|||||||
</TooltipTrigger>
|
</TooltipTrigger>
|
||||||
<TooltipPortal>
|
<TooltipPortal>
|
||||||
<TooltipContent side="right">
|
<TooltipContent side="right">
|
||||||
<p>{t("menu.user.account")}</p>
|
<p>{t("menu.user.account", { ns: "common" })}</p>
|
||||||
</TooltipContent>
|
</TooltipContent>
|
||||||
</TooltipPortal>
|
</TooltipPortal>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
@ -107,9 +104,12 @@ export default function AccountSettings({ className }: AccountSettingsProps) {
|
|||||||
<div className="scrollbar-container w-full flex-col overflow-y-auto overflow-x-hidden">
|
<div className="scrollbar-container w-full flex-col overflow-y-auto overflow-x-hidden">
|
||||||
<DropdownMenuLabel>
|
<DropdownMenuLabel>
|
||||||
{t("menu.user.current", {
|
{t("menu.user.current", {
|
||||||
user: profile?.username || t("menu.user.anonymous"),
|
ns: "common",
|
||||||
|
user:
|
||||||
|
profile?.username || t("menu.user.anonymous", { ns: "common" }),
|
||||||
})}{" "}
|
})}{" "}
|
||||||
{t("role." + profile?.role) && `(${t("role." + profile?.role)})`}
|
{t("role." + profile?.role) &&
|
||||||
|
`(${t("role." + profile?.role, { ns: "common" })})`}
|
||||||
</DropdownMenuLabel>
|
</DropdownMenuLabel>
|
||||||
<DropdownMenuSeparator className={isDesktop ? "mt-3" : "mt-1"} />
|
<DropdownMenuSeparator className={isDesktop ? "mt-3" : "mt-1"} />
|
||||||
{profile?.username && profile.username !== "anonymous" && (
|
{profile?.username && profile.username !== "anonymous" && (
|
||||||
@ -117,22 +117,22 @@ export default function AccountSettings({ className }: AccountSettingsProps) {
|
|||||||
className={
|
className={
|
||||||
isDesktop ? "cursor-pointer" : "flex items-center p-2 text-sm"
|
isDesktop ? "cursor-pointer" : "flex items-center p-2 text-sm"
|
||||||
}
|
}
|
||||||
aria-label={t("menu.user.setPassword")}
|
aria-label={t("menu.user.setPassword", { ns: "common" })}
|
||||||
onClick={() => setPasswordDialogOpen(true)}
|
onClick={() => setPasswordDialogOpen(true)}
|
||||||
>
|
>
|
||||||
<LuSquarePen className="mr-2 size-4" />
|
<LuSquarePen className="mr-2 size-4" />
|
||||||
<span>{t("menu.user.setPassword")}</span>
|
<span>{t("menu.user.setPassword", { ns: "common" })}</span>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
<MenuItem
|
<MenuItem
|
||||||
className={
|
className={
|
||||||
isDesktop ? "cursor-pointer" : "flex items-center p-2 text-sm"
|
isDesktop ? "cursor-pointer" : "flex items-center p-2 text-sm"
|
||||||
}
|
}
|
||||||
aria-label={t("menu.user.logout")}
|
aria-label={t("menu.user.logout", { ns: "common" })}
|
||||||
>
|
>
|
||||||
<a className="flex" href={logoutUrl}>
|
<a className="flex" href={logoutUrl}>
|
||||||
<LuLogOut className="mr-2 size-4" />
|
<LuLogOut className="mr-2 size-4" />
|
||||||
<span>{t("menu.user.logout")}</span>
|
<span>{t("menu.user.logout", { ns: "common" })}</span>
|
||||||
</a>
|
</a>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -54,7 +54,6 @@ import { TooltipPortal } from "@radix-ui/react-tooltip";
|
|||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import RestartDialog from "../overlay/dialog/RestartDialog";
|
import RestartDialog from "../overlay/dialog/RestartDialog";
|
||||||
import { t } from "i18next";
|
|
||||||
|
|
||||||
import { useLanguage } from "@/context/language-provider";
|
import { useLanguage } from "@/context/language-provider";
|
||||||
import { useIsAdmin } from "@/hooks/use-is-admin";
|
import { useIsAdmin } from "@/hooks/use-is-admin";
|
||||||
@ -62,12 +61,14 @@ import SetPasswordDialog from "../overlay/SetPasswordDialog";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
type GeneralSettingsProps = {
|
type GeneralSettingsProps = {
|
||||||
className?: string;
|
className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function GeneralSettings({ className }: GeneralSettingsProps) {
|
export default function GeneralSettings({ className }: GeneralSettingsProps) {
|
||||||
|
const { t } = useTranslation(["common"]);
|
||||||
const { data: profile } = useSWR("profile");
|
const { data: profile } = useSWR("profile");
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
const logoutUrl = config?.proxy?.logout_url || "/api/logout";
|
const logoutUrl = config?.proxy?.logout_url || "/api/logout";
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { IoMdArrowRoundBack } from "react-icons/io";
|
|||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { isPWA } from "@/utils/isPWA";
|
import { isPWA } from "@/utils/isPWA";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { t } from "i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
const MobilePageContext = createContext<{
|
const MobilePageContext = createContext<{
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@ -139,6 +139,7 @@ export function MobilePageHeader({
|
|||||||
onClose,
|
onClose,
|
||||||
...props
|
...props
|
||||||
}: MobilePageHeaderProps) {
|
}: MobilePageHeaderProps) {
|
||||||
|
const { t } = useTranslation(["common"]);
|
||||||
const context = useContext(MobilePageContext);
|
const context = useContext(MobilePageContext);
|
||||||
if (!context)
|
if (!context)
|
||||||
throw new Error("MobilePageHeader must be used within MobilePage");
|
throw new Error("MobilePageHeader must be used within MobilePage");
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { TooltipPortal } from "@radix-ui/react-tooltip";
|
|||||||
import { NavData } from "@/types/navigation";
|
import { NavData } from "@/types/navigation";
|
||||||
import { IconType } from "react-icons";
|
import { IconType } from "react-icons";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { t } from "i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
const variants = {
|
const variants = {
|
||||||
primary: {
|
primary: {
|
||||||
@ -35,6 +35,7 @@ export default function NavItem({
|
|||||||
Icon,
|
Icon,
|
||||||
onClick,
|
onClick,
|
||||||
}: NavItemProps) {
|
}: NavItemProps) {
|
||||||
|
const { t } = useTranslation(["common"]);
|
||||||
if (item.enabled == false) {
|
if (item.enabled == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer";
|
|||||||
import { Button } from "../ui/button";
|
import { Button } from "../ui/button";
|
||||||
import { FaVideo } from "react-icons/fa";
|
import { FaVideo } from "react-icons/fa";
|
||||||
import { isMobile } from "react-device-detect";
|
import { isMobile } from "react-device-detect";
|
||||||
import { t } from "i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
type MobileCameraDrawerProps = {
|
type MobileCameraDrawerProps = {
|
||||||
allCameras: string[];
|
allCameras: string[];
|
||||||
@ -15,6 +15,7 @@ export default function MobileCameraDrawer({
|
|||||||
selected,
|
selected,
|
||||||
onSelectCamera,
|
onSelectCamera,
|
||||||
}: MobileCameraDrawerProps) {
|
}: MobileCameraDrawerProps) {
|
||||||
|
const { t } = useTranslation(["common"]);
|
||||||
const [cameraDrawer, setCameraDrawer] = useState(false);
|
const [cameraDrawer, setCameraDrawer] = useState(false);
|
||||||
|
|
||||||
if (!isMobile) {
|
if (!isMobile) {
|
||||||
|
|||||||
@ -21,7 +21,7 @@ import { cn } from "@/lib/utils";
|
|||||||
import { InProgressPreview, VideoPreview } from "../preview/ScrubbablePreview";
|
import { InProgressPreview, VideoPreview } from "../preview/ScrubbablePreview";
|
||||||
import { Preview } from "@/types/preview";
|
import { Preview } from "@/types/preview";
|
||||||
import { baseUrl } from "@/api/baseUrl";
|
import { baseUrl } from "@/api/baseUrl";
|
||||||
import { t } from "i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
type PreviewPlayerProps = {
|
type PreviewPlayerProps = {
|
||||||
review: ReviewSegment;
|
review: ReviewSegment;
|
||||||
@ -42,6 +42,7 @@ export default function PreviewThumbnailPlayer({
|
|||||||
onClick,
|
onClick,
|
||||||
onTimeUpdate,
|
onTimeUpdate,
|
||||||
}: PreviewPlayerProps) {
|
}: PreviewPlayerProps) {
|
||||||
|
const { t } = useTranslation(["components/player"]);
|
||||||
const apiHost = useApiHost();
|
const apiHost = useApiHost();
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();
|
const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();
|
||||||
@ -169,8 +170,8 @@ export default function PreviewThumbnailPlayer({
|
|||||||
const formattedDate = useFormattedTimestamp(
|
const formattedDate = useFormattedTimestamp(
|
||||||
review.start_time,
|
review.start_time,
|
||||||
config?.ui.time_format == "24hour"
|
config?.ui.time_format == "24hour"
|
||||||
? t("time.formattedTimestampExcludeSeconds.24hour")
|
? t("time.formattedTimestampExcludeSeconds.24hour", { ns: "common" })
|
||||||
: t("time.formattedTimestampExcludeSeconds"),
|
: t("time.formattedTimestampExcludeSeconds", { ns: "common" }),
|
||||||
config?.ui?.timezone,
|
config?.ui?.timezone,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,9 @@ import {
|
|||||||
import { Switch } from "./switch";
|
import { Switch } from "./switch";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { LuCheck } from "react-icons/lu";
|
import { LuCheck } from "react-icons/lu";
|
||||||
import { t } from "i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
|
const { t } = useTranslation(["common"]);
|
||||||
|
|
||||||
|
|
||||||
export interface DateRangePickerProps {
|
export interface DateRangePickerProps {
|
||||||
|
|||||||
@ -3,7 +3,9 @@ import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
|
|||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
import { ButtonProps, buttonVariants } from "@/components/ui/button"
|
import { ButtonProps, buttonVariants } from "@/components/ui/button"
|
||||||
import { t } from "i18next"
|
import { useTranslation } from "react-i18next"
|
||||||
|
|
||||||
|
const { t } = useTranslation(["common"])
|
||||||
|
|
||||||
const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
|
const Pagination = ({ className, ...props }: React.ComponentProps<"nav">) => (
|
||||||
<nav
|
<nav
|
||||||
|
|||||||
@ -1,12 +1,13 @@
|
|||||||
import Heading from "@/components/ui/heading";
|
import Heading from "@/components/ui/heading";
|
||||||
import { t } from "i18next";
|
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import { FaExclamationTriangle } from "react-icons/fa";
|
import { FaExclamationTriangle } from "react-icons/fa";
|
||||||
|
|
||||||
export default function AccessDenied() {
|
export default function AccessDenied() {
|
||||||
|
const { t } = useTranslation(["common"]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.title = t("accessDenied.documentTitle");
|
document.title = t("accessDenied.documentTitle");
|
||||||
}, []);
|
}, [t]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex min-h-screen flex-col items-center justify-center text-center">
|
<div className="flex min-h-screen flex-col items-center justify-center text-center">
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
import Heading from "@/components/ui/heading";
|
import Heading from "@/components/ui/heading";
|
||||||
import { t } from "i18next";
|
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
function NoMatch() {
|
function NoMatch() {
|
||||||
|
const { t } = useTranslation(["common"]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
document.title = t("notFound.documentTitle");
|
document.title = t("notFound.documentTitle");
|
||||||
}, []);
|
}, [t]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@ -5,7 +5,6 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||||
import { useResizeObserver } from "@/hooks/resize-observer";
|
import { useResizeObserver } from "@/hooks/resize-observer";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { t } from "i18next";
|
|
||||||
import { useEffect, useMemo, useRef, useState } from "react";
|
import { useEffect, useMemo, useRef, useState } from "react";
|
||||||
import {
|
import {
|
||||||
isDesktop,
|
isDesktop,
|
||||||
@ -15,6 +14,7 @@ import {
|
|||||||
isSafari,
|
isSafari,
|
||||||
useMobileOrientation,
|
useMobileOrientation,
|
||||||
} from "react-device-detect";
|
} from "react-device-detect";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
import { FaCompress, FaExpand } from "react-icons/fa";
|
import { FaCompress, FaExpand } from "react-icons/fa";
|
||||||
import { IoMdArrowBack } from "react-icons/io";
|
import { IoMdArrowBack } from "react-icons/io";
|
||||||
import { LuPictureInPicture } from "react-icons/lu";
|
import { LuPictureInPicture } from "react-icons/lu";
|
||||||
@ -33,6 +33,7 @@ export default function LiveBirdseyeView({
|
|||||||
fullscreen,
|
fullscreen,
|
||||||
toggleFullscreen,
|
toggleFullscreen,
|
||||||
}: LiveBirdseyeViewProps) {
|
}: LiveBirdseyeViewProps) {
|
||||||
|
const { t } = useTranslation(["views/live"]);
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { isPortrait } = useMobileOrientation();
|
const { isPortrait } = useMobileOrientation();
|
||||||
@ -151,7 +152,9 @@ export default function LiveBirdseyeView({
|
|||||||
>
|
>
|
||||||
<IoMdArrowBack className="size-5" />
|
<IoMdArrowBack className="size-5" />
|
||||||
{isDesktop && (
|
{isDesktop && (
|
||||||
<div className="text-primary">{t("button.back")}</div>
|
<div className="text-primary">
|
||||||
|
{t("button.back", { ns: "common" })}
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
@ -167,7 +170,11 @@ export default function LiveBirdseyeView({
|
|||||||
variant={fullscreen ? "overlay" : "primary"}
|
variant={fullscreen ? "overlay" : "primary"}
|
||||||
Icon={fullscreen ? FaCompress : FaExpand}
|
Icon={fullscreen ? FaCompress : FaExpand}
|
||||||
isActive={fullscreen}
|
isActive={fullscreen}
|
||||||
title={fullscreen ? "Close" : "Fullscreen"}
|
title={
|
||||||
|
fullscreen
|
||||||
|
? t("button.close", { ns: "common" })
|
||||||
|
: t("button.fullscreen", { ns: "common" })
|
||||||
|
}
|
||||||
onClick={toggleFullscreen}
|
onClick={toggleFullscreen}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@ -177,7 +184,11 @@ export default function LiveBirdseyeView({
|
|||||||
variant={fullscreen ? "overlay" : "primary"}
|
variant={fullscreen ? "overlay" : "primary"}
|
||||||
Icon={LuPictureInPicture}
|
Icon={LuPictureInPicture}
|
||||||
isActive={pip}
|
isActive={pip}
|
||||||
title={pip ? "Close" : "Picture in Picture"}
|
title={
|
||||||
|
pip
|
||||||
|
? t("button.close", { ns: "common" })
|
||||||
|
: t("button.pictureInPicture", { ns: "common" })
|
||||||
|
}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (!pip) {
|
if (!pip) {
|
||||||
setPip(true);
|
setPip(true);
|
||||||
|
|||||||
@ -41,9 +41,9 @@ import {
|
|||||||
import { FaCompress, FaExpand } from "react-icons/fa";
|
import { FaCompress, FaExpand } from "react-icons/fa";
|
||||||
import useCameraLiveMode from "@/hooks/use-camera-live-mode";
|
import useCameraLiveMode from "@/hooks/use-camera-live-mode";
|
||||||
import { useResizeObserver } from "@/hooks/resize-observer";
|
import { useResizeObserver } from "@/hooks/resize-observer";
|
||||||
import { t } from "i18next";
|
|
||||||
import LiveContextMenu from "@/components/menu/LiveContextMenu";
|
import LiveContextMenu from "@/components/menu/LiveContextMenu";
|
||||||
import { useStreamingSettings } from "@/context/streaming-settings-provider";
|
import { useStreamingSettings } from "@/context/streaming-settings-provider";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
|
||||||
type LiveDashboardViewProps = {
|
type LiveDashboardViewProps = {
|
||||||
cameras: CameraConfig[];
|
cameras: CameraConfig[];
|
||||||
@ -61,6 +61,8 @@ export default function LiveDashboardView({
|
|||||||
fullscreen,
|
fullscreen,
|
||||||
toggleFullscreen,
|
toggleFullscreen,
|
||||||
}: LiveDashboardViewProps) {
|
}: LiveDashboardViewProps) {
|
||||||
|
const { t } = useTranslation(["views/live"]);
|
||||||
|
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
|
|
||||||
// layout
|
// layout
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user