chore: remove most import { t } from "i18next";

This commit is contained in:
ZhaiSoul 2025-03-16 22:21:29 +08:00
parent 52b1c7fbda
commit 78b159ebb1
16 changed files with 66 additions and 40 deletions

View File

@ -12,7 +12,7 @@ import { SearchResult } from "@/types/search";
import { cn } from "@/lib/utils";
import { TooltipPortal } from "@radix-ui/react-tooltip";
import useContextMenu from "@/hooks/use-contextmenu";
import { t } from "i18next";
import { useTranslation } from "react-i18next";
type SearchThumbnailProps = {
searchResult: SearchResult;
@ -23,6 +23,7 @@ export default function SearchThumbnail({
searchResult,
onClick,
}: SearchThumbnailProps) {
const { t } = useTranslation(["views/search"]);
const apiHost = useApiHost();
const { data: config } = useSWR<FrigateConfig>("config");
const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();

View File

@ -6,7 +6,7 @@ import { SearchResult } from "@/types/search";
import ActivityIndicator from "../indicators/activity-indicator";
import SearchResultActions from "../menu/SearchResultActions";
import { cn } from "@/lib/utils";
import { t } from "i18next";
import { useTranslation } from "react-i18next";
type SearchThumbnailProps = {
searchResult: SearchResult;
@ -25,14 +25,15 @@ export default function SearchThumbnailFooter({
showObjectLifecycle,
showSnapshot,
}: SearchThumbnailProps) {
const { t } = useTranslation(["views/search"]);
const { data: config } = useSWR<FrigateConfig>("config");
// date
const formattedDate = useFormattedTimestamp(
searchResult.start_time,
config?.ui.time_format == "24hour"
? t("time.formattedTimestampExcludeSeconds.24hour")
: t("time.formattedTimestampExcludeSeconds"),
? t("time.formattedTimestampExcludeSeconds.24hour", { ns: "common" })
: t("time.formattedTimestampExcludeSeconds", { ns: "common" }),
config?.ui.timezone,
);

View File

@ -14,7 +14,6 @@ import { DateRangePicker } from "../ui/calendar-range";
import { DateRange } from "react-day-picker";
import { useState } from "react";
import PlatformAwareDialog from "../overlay/dialog/PlatformAwareDialog";
import { t } from "i18next";
import { useTranslation } from "react-i18next";
type CalendarFilterButtonProps = {
@ -98,12 +97,13 @@ export function CalendarRangeFilterButton({
defaultText,
updateSelectedRange,
}: CalendarRangeFilterButtonProps) {
const { t } = useTranslation(["components/filter"]);
const [open, setOpen] = useState(false);
const selectedDate = useFormattedRange(
range?.from == undefined ? 0 : range.from.getTime() / 1000 + 1,
range?.to == undefined ? 0 : range.to.getTime() / 1000 - 1,
t("time.formattedTimestampOnlyMonthAndDay"),
t("time.formattedTimestampOnlyMonthAndDay", { ns: "common" }),
);
const trigger = (

View File

@ -10,7 +10,6 @@ import { DropdownMenuSeparator } from "../ui/dropdown-menu";
import { cn } from "@/lib/utils";
import FilterSwitch from "./FilterSwitch";
import { useTranslation } from "react-i18next";
import { t } from "i18next";
type LogSettingsButtonProps = {
selectedLabels?: LogSeverity[];
@ -101,6 +100,7 @@ export function GeneralFilterContent({
selectedLabels,
updateLabelFilter,
}: GeneralFilterContentProps) {
const { t } = useTranslation(["components/filter"]);
return (
<>
<div className="scrollbar-container h-auto overflow-y-auto overflow-x-hidden">

View File

@ -20,18 +20,19 @@ import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer";
import { DialogClose } from "../ui/dialog";
import { LuLogOut, LuSquarePen } from "react-icons/lu";
import useSWR from "swr";
import { t } from "i18next";
import { useState } from "react";
import axios from "axios";
import { toast } from "sonner";
import SetPasswordDialog from "../overlay/SetPasswordDialog";
import { useTranslation } from "react-i18next";
type AccountSettingsProps = {
className?: string;
};
export default function AccountSettings({ className }: AccountSettingsProps) {
const { t } = useTranslation(["views/settings"]);
const { data: profile } = useSWR("profile");
const { data: config } = useSWR("config");
const logoutUrl = config?.proxy?.logout_url || `${baseUrl}api/logout`;
@ -50,12 +51,9 @@ export default function AccountSettings({ className }: AccountSettingsProps) {
.then((response) => {
if (response.status === 200) {
setPasswordDialogOpen(false);
toast.success(
t("users.toast.success.updatePassword", { ns: "views/settings" }),
{
position: "top-center",
},
);
toast.success(t("users.toast.success.updatePassword"), {
position: "top-center",
});
}
})
.catch((error) => {
@ -65,7 +63,6 @@ export default function AccountSettings({ className }: AccountSettingsProps) {
"Unknown error";
toast.error(
t("users.toast.error.setPasswordFailed", {
ns: "views/settings",
errorMessage,
}),
{
@ -94,7 +91,7 @@ export default function AccountSettings({ className }: AccountSettingsProps) {
</TooltipTrigger>
<TooltipPortal>
<TooltipContent side="right">
<p>{t("menu.user.account")}</p>
<p>{t("menu.user.account", { ns: "common" })}</p>
</TooltipContent>
</TooltipPortal>
</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">
<DropdownMenuLabel>
{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>
<DropdownMenuSeparator className={isDesktop ? "mt-3" : "mt-1"} />
{profile?.username && profile.username !== "anonymous" && (
@ -117,22 +117,22 @@ export default function AccountSettings({ className }: AccountSettingsProps) {
className={
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)}
>
<LuSquarePen className="mr-2 size-4" />
<span>{t("menu.user.setPassword")}</span>
<span>{t("menu.user.setPassword", { ns: "common" })}</span>
</MenuItem>
)}
<MenuItem
className={
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}>
<LuLogOut className="mr-2 size-4" />
<span>{t("menu.user.logout")}</span>
<span>{t("menu.user.logout", { ns: "common" })}</span>
</a>
</MenuItem>
</div>

View File

@ -54,7 +54,6 @@ import { TooltipPortal } from "@radix-ui/react-tooltip";
import { cn } from "@/lib/utils";
import useSWR from "swr";
import RestartDialog from "../overlay/dialog/RestartDialog";
import { t } from "i18next";
import { useLanguage } from "@/context/language-provider";
import { useIsAdmin } from "@/hooks/use-is-admin";
@ -62,12 +61,14 @@ import SetPasswordDialog from "../overlay/SetPasswordDialog";
import { toast } from "sonner";
import axios from "axios";
import { FrigateConfig } from "@/types/frigateConfig";
import { useTranslation } from "react-i18next";
type GeneralSettingsProps = {
className?: string;
};
export default function GeneralSettings({ className }: GeneralSettingsProps) {
const { t } = useTranslation(["common"]);
const { data: profile } = useSWR("profile");
const { data: config } = useSWR<FrigateConfig>("config");
const logoutUrl = config?.proxy?.logout_url || "/api/logout";

View File

@ -5,7 +5,7 @@ import { IoMdArrowRoundBack } from "react-icons/io";
import { cn } from "@/lib/utils";
import { isPWA } from "@/utils/isPWA";
import { Button } from "@/components/ui/button";
import { t } from "i18next";
import { useTranslation } from "react-i18next";
const MobilePageContext = createContext<{
open: boolean;
@ -139,6 +139,7 @@ export function MobilePageHeader({
onClose,
...props
}: MobilePageHeaderProps) {
const { t } = useTranslation(["common"]);
const context = useContext(MobilePageContext);
if (!context)
throw new Error("MobilePageHeader must be used within MobilePage");

View File

@ -9,7 +9,7 @@ import { TooltipPortal } from "@radix-ui/react-tooltip";
import { NavData } from "@/types/navigation";
import { IconType } from "react-icons";
import { cn } from "@/lib/utils";
import { t } from "i18next";
import { useTranslation } from "react-i18next";
const variants = {
primary: {
@ -35,6 +35,7 @@ export default function NavItem({
Icon,
onClick,
}: NavItemProps) {
const { t } = useTranslation(["common"]);
if (item.enabled == false) {
return;
}

View File

@ -3,7 +3,7 @@ import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer";
import { Button } from "../ui/button";
import { FaVideo } from "react-icons/fa";
import { isMobile } from "react-device-detect";
import { t } from "i18next";
import { useTranslation } from "react-i18next";
type MobileCameraDrawerProps = {
allCameras: string[];
@ -15,6 +15,7 @@ export default function MobileCameraDrawer({
selected,
onSelectCamera,
}: MobileCameraDrawerProps) {
const { t } = useTranslation(["common"]);
const [cameraDrawer, setCameraDrawer] = useState(false);
if (!isMobile) {

View File

@ -21,7 +21,7 @@ import { cn } from "@/lib/utils";
import { InProgressPreview, VideoPreview } from "../preview/ScrubbablePreview";
import { Preview } from "@/types/preview";
import { baseUrl } from "@/api/baseUrl";
import { t } from "i18next";
import { useTranslation } from "react-i18next";
type PreviewPlayerProps = {
review: ReviewSegment;
@ -42,6 +42,7 @@ export default function PreviewThumbnailPlayer({
onClick,
onTimeUpdate,
}: PreviewPlayerProps) {
const { t } = useTranslation(["components/player"]);
const apiHost = useApiHost();
const { data: config } = useSWR<FrigateConfig>("config");
const [imgRef, imgLoaded, onImgLoad] = useImageLoaded();
@ -169,8 +170,8 @@ export default function PreviewThumbnailPlayer({
const formattedDate = useFormattedTimestamp(
review.start_time,
config?.ui.time_format == "24hour"
? t("time.formattedTimestampExcludeSeconds.24hour")
: t("time.formattedTimestampExcludeSeconds"),
? t("time.formattedTimestampExcludeSeconds.24hour", { ns: "common" })
: t("time.formattedTimestampExcludeSeconds", { ns: "common" }),
config?.ui?.timezone,
);

View File

@ -12,7 +12,9 @@ import {
import { Switch } from "./switch";
import { cn } from "@/lib/utils";
import { LuCheck } from "react-icons/lu";
import { t } from "i18next";
import { useTranslation } from "react-i18next";
const { t } = useTranslation(["common"]);
export interface DateRangePickerProps {

View File

@ -3,7 +3,9 @@ import { ChevronLeft, ChevronRight, MoreHorizontal } from "lucide-react"
import { cn } from "@/lib/utils"
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">) => (
<nav

View File

@ -1,12 +1,13 @@
import Heading from "@/components/ui/heading";
import { t } from "i18next";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
import { FaExclamationTriangle } from "react-icons/fa";
export default function AccessDenied() {
const { t } = useTranslation(["common"]);
useEffect(() => {
document.title = t("accessDenied.documentTitle");
}, []);
}, [t]);
return (
<div className="flex min-h-screen flex-col items-center justify-center text-center">

View File

@ -1,11 +1,12 @@
import Heading from "@/components/ui/heading";
import { t } from "i18next";
import { useEffect } from "react";
import { useTranslation } from "react-i18next";
function NoMatch() {
const { t } = useTranslation(["common"]);
useEffect(() => {
document.title = t("notFound.documentTitle");
}, []);
}, [t]);
return (
<>

View File

@ -5,7 +5,6 @@ import { Button } from "@/components/ui/button";
import { TooltipProvider } from "@/components/ui/tooltip";
import { useResizeObserver } from "@/hooks/resize-observer";
import { FrigateConfig } from "@/types/frigateConfig";
import { t } from "i18next";
import { useEffect, useMemo, useRef, useState } from "react";
import {
isDesktop,
@ -15,6 +14,7 @@ import {
isSafari,
useMobileOrientation,
} from "react-device-detect";
import { useTranslation } from "react-i18next";
import { FaCompress, FaExpand } from "react-icons/fa";
import { IoMdArrowBack } from "react-icons/io";
import { LuPictureInPicture } from "react-icons/lu";
@ -33,6 +33,7 @@ export default function LiveBirdseyeView({
fullscreen,
toggleFullscreen,
}: LiveBirdseyeViewProps) {
const { t } = useTranslation(["views/live"]);
const { data: config } = useSWR<FrigateConfig>("config");
const navigate = useNavigate();
const { isPortrait } = useMobileOrientation();
@ -151,7 +152,9 @@ export default function LiveBirdseyeView({
>
<IoMdArrowBack className="size-5" />
{isDesktop && (
<div className="text-primary">{t("button.back")}</div>
<div className="text-primary">
{t("button.back", { ns: "common" })}
</div>
)}
</Button>
) : (
@ -167,7 +170,11 @@ export default function LiveBirdseyeView({
variant={fullscreen ? "overlay" : "primary"}
Icon={fullscreen ? FaCompress : FaExpand}
isActive={fullscreen}
title={fullscreen ? "Close" : "Fullscreen"}
title={
fullscreen
? t("button.close", { ns: "common" })
: t("button.fullscreen", { ns: "common" })
}
onClick={toggleFullscreen}
/>
)}
@ -177,7 +184,11 @@ export default function LiveBirdseyeView({
variant={fullscreen ? "overlay" : "primary"}
Icon={LuPictureInPicture}
isActive={pip}
title={pip ? "Close" : "Picture in Picture"}
title={
pip
? t("button.close", { ns: "common" })
: t("button.pictureInPicture", { ns: "common" })
}
onClick={() => {
if (!pip) {
setPip(true);

View File

@ -41,9 +41,9 @@ import {
import { FaCompress, FaExpand } from "react-icons/fa";
import useCameraLiveMode from "@/hooks/use-camera-live-mode";
import { useResizeObserver } from "@/hooks/resize-observer";
import { t } from "i18next";
import LiveContextMenu from "@/components/menu/LiveContextMenu";
import { useStreamingSettings } from "@/context/streaming-settings-provider";
import { useTranslation } from "react-i18next";
type LiveDashboardViewProps = {
cameras: CameraConfig[];
@ -61,6 +61,8 @@ export default function LiveDashboardView({
fullscreen,
toggleFullscreen,
}: LiveDashboardViewProps) {
const { t } = useTranslation(["views/live"]);
const { data: config } = useSWR<FrigateConfig>("config");
// layout