aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2023-08-26 23:49:28 +0800
committercrupest <crupest@outlook.com>2023-08-26 23:49:28 +0800
commit256cc9592a3f31fc392e1ccdb699aa206b7b47ce (patch)
treefdca6f8b1cdbd5ed264a1af9e48496685f4e9a95
parentf5dfd52f6efece2f4cad227044ecf4dd66301bbc (diff)
downloadtimeline-256cc9592a3f31fc392e1ccdb699aa206b7b47ce.tar.gz
timeline-256cc9592a3f31fc392e1ccdb699aa206b7b47ce.tar.bz2
timeline-256cc9592a3f31fc392e1ccdb699aa206b7b47ce.zip
...
-rw-r--r--FrontEnd/src/common.ts2
-rw-r--r--FrontEnd/src/components/AppBar.tsx3
-rw-r--r--FrontEnd/src/components/Card.tsx1
-rw-r--r--FrontEnd/src/components/LoadFailReload.tsx37
-rw-r--r--FrontEnd/src/components/LoadingPage.tsx13
-rw-r--r--FrontEnd/src/components/SearchInput.tsx2
-rw-r--r--FrontEnd/src/components/button/ButtonRowV2.tsx3
-rw-r--r--FrontEnd/src/components/button/LoadingButton.tsx1
-rw-r--r--FrontEnd/src/components/common.ts1
-rw-r--r--FrontEnd/src/components/dialog/ConfirmDialog.css0
-rw-r--r--FrontEnd/src/components/dialog/ConfirmDialog.tsx1
-rw-r--r--FrontEnd/src/components/dialog/OperationDialog.tsx7
-rw-r--r--FrontEnd/src/components/dialog/index.ts1
-rw-r--r--FrontEnd/src/components/hooks.ts14
-rw-r--r--FrontEnd/src/components/hooks/index.ts3
-rw-r--r--FrontEnd/src/components/hooks/responsive.ts7
-rw-r--r--FrontEnd/src/components/hooks/useClickOutside.ts (renamed from FrontEnd/src/utilities/hooks/useClickOutside.ts)2
-rw-r--r--FrontEnd/src/components/hooks/useScrollToBottom.ts (renamed from FrontEnd/src/utilities/hooks/useScrollToBottom.ts)9
-rw-r--r--FrontEnd/src/components/input/InputGroup.tsx16
-rw-r--r--FrontEnd/src/components/menu/Menu.tsx2
-rw-r--r--FrontEnd/src/components/menu/PopupMenu.tsx6
-rw-r--r--FrontEnd/src/pages/login/index.tsx14
-rw-r--r--FrontEnd/src/pages/register/index.tsx26
-rw-r--r--FrontEnd/src/pages/setting/ChangeAvatarDialog.tsx5
-rw-r--r--FrontEnd/src/pages/setting/ChangePasswordDialog.tsx17
-rw-r--r--FrontEnd/src/pages/setting/index.tsx11
-rw-r--r--FrontEnd/src/pages/timeline/Timeline.tsx3
-rw-r--r--FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx4
-rw-r--r--FrontEnd/src/pages/timeline/TimelinePostView.tsx8
-rw-r--r--FrontEnd/src/utilities/hooks.ts5
-rw-r--r--FrontEnd/src/utilities/hooks/mediaQuery.ts5
31 files changed, 72 insertions, 157 deletions
diff --git a/FrontEnd/src/common.ts b/FrontEnd/src/common.ts
index 7c053140..1ca796c3 100644
--- a/FrontEnd/src/common.ts
+++ b/FrontEnd/src/common.ts
@@ -3,8 +3,6 @@
// This error should never occur. If it does, it indicates there is some logic bug in codes.
export class UiLogicError extends Error {}
-export const highlightTimelineUsername = "crupest";
-
export type { I18nText } from "./i18n";
export type { I18nText as Text } from "./i18n";
export { c, convertI18nText } from "./i18n";
diff --git a/FrontEnd/src/components/AppBar.tsx b/FrontEnd/src/components/AppBar.tsx
index da3a946f..1a5c1941 100644
--- a/FrontEnd/src/components/AppBar.tsx
+++ b/FrontEnd/src/components/AppBar.tsx
@@ -2,9 +2,10 @@ import { useState } from "react";
import classnames from "classnames";
import { Link, NavLink } from "react-router-dom";
-import { I18nText, useC, useMobile } from "./common";
import { useUser } from "~src/services/user";
+import { I18nText, useC } from "./common";
+import { useMobile } from "./hooks";
import TimelineLogo from "./TimelineLogo";
import { IconButton } from "./button";
import UserAvatar from "./user/UserAvatar";
diff --git a/FrontEnd/src/components/Card.tsx b/FrontEnd/src/components/Card.tsx
index a8f0d3cc..5d3ef630 100644
--- a/FrontEnd/src/components/Card.tsx
+++ b/FrontEnd/src/components/Card.tsx
@@ -2,6 +2,7 @@ import { ComponentPropsWithoutRef, Ref } from "react";
import classNames from "classnames";
import { ThemeColor } from "./common";
+
import "./Card.css";
interface CardProps extends ComponentPropsWithoutRef<"div"> {
diff --git a/FrontEnd/src/components/LoadFailReload.tsx b/FrontEnd/src/components/LoadFailReload.tsx
deleted file mode 100644
index 81ba1f67..00000000
--- a/FrontEnd/src/components/LoadFailReload.tsx
+++ /dev/null
@@ -1,37 +0,0 @@
-import * as React from "react";
-import { Trans } from "react-i18next";
-
-export interface LoadFailReloadProps {
- className?: string;
- style?: React.CSSProperties;
- onReload: () => void;
-}
-
-const LoadFailReload: React.FC<LoadFailReloadProps> = ({
- onReload,
- className,
- style,
-}) => {
- return (
- <Trans
- i18nKey="loadFailReload"
- parent="div"
- className={className}
- style={style}
- >
- 0
- <a
- href="#"
- onClick={(e) => {
- onReload();
- e.preventDefault();
- }}
- >
- 1
- </a>
- 2
- </Trans>
- );
-};
-
-export default LoadFailReload;
diff --git a/FrontEnd/src/components/LoadingPage.tsx b/FrontEnd/src/components/LoadingPage.tsx
deleted file mode 100644
index 35ee1aa8..00000000
--- a/FrontEnd/src/components/LoadingPage.tsx
+++ /dev/null
@@ -1,13 +0,0 @@
-import * as React from "react";
-
-import Spinner from "./Spinner";
-
-const LoadingPage: React.FC = () => {
- return (
- <div className="position-fixed w-100 h-100 d-flex justify-content-center align-items-center">
- <Spinner />
- </div>
- );
-};
-
-export default LoadingPage;
diff --git a/FrontEnd/src/components/SearchInput.tsx b/FrontEnd/src/components/SearchInput.tsx
index e3216b86..71820bfa 100644
--- a/FrontEnd/src/components/SearchInput.tsx
+++ b/FrontEnd/src/components/SearchInput.tsx
@@ -1,7 +1,7 @@
import classNames from "classnames";
import { useC, Text } from "./common";
-import LoadingButton from "./button/LoadingButton";
+import { LoadingButton } from "./button";
import "./SearchInput.css";
diff --git a/FrontEnd/src/components/button/ButtonRowV2.tsx b/FrontEnd/src/components/button/ButtonRowV2.tsx
index 3467ad52..5129e7f1 100644
--- a/FrontEnd/src/components/button/ButtonRowV2.tsx
+++ b/FrontEnd/src/components/button/ButtonRowV2.tsx
@@ -1,13 +1,14 @@
import { ComponentPropsWithoutRef, Ref } from "react";
import classNames from "classnames";
+import { Text, ThemeColor } from "../common";
+
import Button from "./Button";
import FlatButton from "./FlatButton";
import IconButton from "./IconButton";
import LoadingButton from "./LoadingButton";
import "./ButtonRow.css";
-import { Text, ThemeColor } from "../common";
interface ButtonRowV2ButtonBase {
key: string | number;
diff --git a/FrontEnd/src/components/button/LoadingButton.tsx b/FrontEnd/src/components/button/LoadingButton.tsx
index 7e7d08e6..d9d41ddb 100644
--- a/FrontEnd/src/components/button/LoadingButton.tsx
+++ b/FrontEnd/src/components/button/LoadingButton.tsx
@@ -1,7 +1,6 @@
import classNames from "classnames";
import { I18nText, ThemeColor, useC } from "../common";
-
import Spinner from "../Spinner";
import "./LoadingButton.css";
diff --git a/FrontEnd/src/components/common.ts b/FrontEnd/src/components/common.ts
index e6f7319f..b96388ab 100644
--- a/FrontEnd/src/components/common.ts
+++ b/FrontEnd/src/components/common.ts
@@ -11,4 +11,3 @@ export const themeColors = [
export type ThemeColor = (typeof themeColors)[number];
export { breakpoints } from "./breakpoints";
-export { useMobile } from "./hooks";
diff --git a/FrontEnd/src/components/dialog/ConfirmDialog.css b/FrontEnd/src/components/dialog/ConfirmDialog.css
deleted file mode 100644
index e69de29b..00000000
--- a/FrontEnd/src/components/dialog/ConfirmDialog.css
+++ /dev/null
diff --git a/FrontEnd/src/components/dialog/ConfirmDialog.tsx b/FrontEnd/src/components/dialog/ConfirmDialog.tsx
index 26939c9b..1d997305 100644
--- a/FrontEnd/src/components/dialog/ConfirmDialog.tsx
+++ b/FrontEnd/src/components/dialog/ConfirmDialog.tsx
@@ -1,5 +1,4 @@
import { useC, Text, ThemeColor } from "../common";
-
import Dialog from "./Dialog";
import DialogContainer from "./DialogContainer";
diff --git a/FrontEnd/src/components/dialog/OperationDialog.tsx b/FrontEnd/src/components/dialog/OperationDialog.tsx
index e5db7f4f..96766825 100644
--- a/FrontEnd/src/components/dialog/OperationDialog.tsx
+++ b/FrontEnd/src/components/dialog/OperationDialog.tsx
@@ -2,23 +2,18 @@ import { useState, ReactNode, ComponentProps } from "react";
import classNames from "classnames";
import { useC, Text, ThemeColor } from "../common";
-
import {
useInputs,
InputGroup,
Initializer as InputInitializer,
- InputValueDict,
- InputErrorDict,
InputConfirmValueDict,
} from "../input";
+import { ButtonRow } from "../button";
import Dialog from "./Dialog";
import DialogContainer from "./DialogContainer";
-import { ButtonRow } from "../button";
import "./OperationDialog.css";
-export type { InputInitializer, InputValueDict, InputErrorDict };
-
interface OperationDialogPromptProps {
message?: Text;
customMessage?: Text;
diff --git a/FrontEnd/src/components/dialog/index.ts b/FrontEnd/src/components/dialog/index.ts
index 59f15791..17db8fd0 100644
--- a/FrontEnd/src/components/dialog/index.ts
+++ b/FrontEnd/src/components/dialog/index.ts
@@ -4,6 +4,7 @@ export { default as Dialog } from "./Dialog";
export { default as FullPageDialog } from "./FullPageDialog";
export { default as OperationDialog } from "./OperationDialog";
export { default as ConfirmDialog } from "./ConfirmDialog";
+export { default as DialogContainer } from "./DialogContainer";
type DialogMap<D extends string, V> = {
[K in D]: V;
diff --git a/FrontEnd/src/components/hooks.ts b/FrontEnd/src/components/hooks.ts
deleted file mode 100644
index 523a4538..00000000
--- a/FrontEnd/src/components/hooks.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-// TODO: Migrate hooks
-
-export {
- useIsSmallScreen,
- useClickOutside,
- useScrollToBottom,
-} from "~src/utilities/hooks";
-
-import { useMediaQuery } from "react-responsive";
-import { breakpoints } from "./breakpoints";
-
-export function useMobile(): boolean {
- return useMediaQuery({ maxWidth: breakpoints.sm });
-}
diff --git a/FrontEnd/src/components/hooks/index.ts b/FrontEnd/src/components/hooks/index.ts
new file mode 100644
index 00000000..3c9859bc
--- /dev/null
+++ b/FrontEnd/src/components/hooks/index.ts
@@ -0,0 +1,3 @@
+export { useMobile } from "./responsive";
+export { default as useClickOutside } from "./useClickOutside";
+export { default as useScrollToBottom } from "./useScrollToBottom";
diff --git a/FrontEnd/src/components/hooks/responsive.ts b/FrontEnd/src/components/hooks/responsive.ts
new file mode 100644
index 00000000..6bcce96c
--- /dev/null
+++ b/FrontEnd/src/components/hooks/responsive.ts
@@ -0,0 +1,7 @@
+import { useMediaQuery } from "react-responsive";
+
+import { breakpoints } from "../breakpoints";
+
+export function useMobile(): boolean {
+ return useMediaQuery({ maxWidth: breakpoints.sm });
+}
diff --git a/FrontEnd/src/utilities/hooks/useClickOutside.ts b/FrontEnd/src/components/hooks/useClickOutside.ts
index 6dcbf7b3..828ce7e3 100644
--- a/FrontEnd/src/utilities/hooks/useClickOutside.ts
+++ b/FrontEnd/src/components/hooks/useClickOutside.ts
@@ -3,7 +3,7 @@ import { useRef, useEffect } from "react";
export default function useClickOutside(
element: HTMLElement | null | undefined,
onClickOutside: () => void,
- nextTick?: boolean
+ nextTick?: boolean,
): void {
const onClickOutsideRef = useRef<() => void>(onClickOutside);
diff --git a/FrontEnd/src/utilities/hooks/useScrollToBottom.ts b/FrontEnd/src/components/hooks/useScrollToBottom.ts
index 216746f4..79fcda16 100644
--- a/FrontEnd/src/utilities/hooks/useScrollToBottom.ts
+++ b/FrontEnd/src/components/hooks/useScrollToBottom.ts
@@ -1,6 +1,5 @@
import { useRef, useEffect } from "react";
-import { fromEvent } from "rxjs";
-import { filter, throttleTime } from "rxjs/operators";
+import { fromEvent, filter, throttleTime } from "rxjs";
function useScrollToBottom(
handler: () => void,
@@ -8,7 +7,7 @@ function useScrollToBottom(
option = {
maxOffset: 5,
throttle: 1000,
- }
+ },
): void {
const handlerRef = useRef<(() => void) | null>(null);
@@ -26,9 +25,9 @@ function useScrollToBottom(
filter(
() =>
window.scrollY >=
- document.body.scrollHeight - window.innerHeight - option.maxOffset
+ document.body.scrollHeight - window.innerHeight - option.maxOffset,
),
- throttleTime(option.throttle)
+ throttleTime(option.throttle),
)
.subscribe(() => {
if (enable) {
diff --git a/FrontEnd/src/components/input/InputGroup.tsx b/FrontEnd/src/components/input/InputGroup.tsx
index 4f487344..47a43b38 100644
--- a/FrontEnd/src/components/input/InputGroup.tsx
+++ b/FrontEnd/src/components/input/InputGroup.tsx
@@ -72,12 +72,9 @@ export type InputDirtyDict = Record<string, boolean>;
// use never so you don't have to cast everywhere
export type InputConfirmValueDict = Record<string, never>;
-export type GeneralInputErrorDict =
- | {
- [key: string]: Text | null | undefined;
- }
- | null
- | undefined;
+export type GeneralInputErrorDict = {
+ [key: string]: Text | null | undefined;
+};
type MakeInputInfo<I extends Input> = Omit<I, "value" | "error" | "disabled">;
@@ -87,8 +84,9 @@ export type InputInfo = {
export type Validator = (
values: InputValueDict,
+ errors: GeneralInputErrorDict,
inputs: InputInfo[],
-) => GeneralInputErrorDict;
+) => void;
export type InputScheme = {
inputs: InputInfo[];
@@ -157,7 +155,9 @@ function validate(
values: InputValueDict,
inputs: InputInfo[],
): InputErrorDict {
- return cleanObject(validator?.(values, inputs) ?? {});
+ const errors: GeneralInputErrorDict = {};
+ validator?.(values, errors, inputs);
+ return cleanObject(errors);
}
export function useInputs(options: { init: Initializer }): {
diff --git a/FrontEnd/src/components/menu/Menu.tsx b/FrontEnd/src/components/menu/Menu.tsx
index e8099c76..c01c6cfb 100644
--- a/FrontEnd/src/components/menu/Menu.tsx
+++ b/FrontEnd/src/components/menu/Menu.tsx
@@ -2,9 +2,9 @@ import { CSSProperties } from "react";
import classNames from "classnames";
import { useC, Text, ThemeColor } from "../common";
+import Icon from "../Icon";
import "./Menu.css";
-import Icon from "../Icon";
export type MenuItem =
| {
diff --git a/FrontEnd/src/components/menu/PopupMenu.tsx b/FrontEnd/src/components/menu/PopupMenu.tsx
index 23a67f79..9d90799d 100644
--- a/FrontEnd/src/components/menu/PopupMenu.tsx
+++ b/FrontEnd/src/components/menu/PopupMenu.tsx
@@ -3,11 +3,9 @@ import classNames from "classnames";
import { createPortal } from "react-dom";
import { usePopper } from "react-popper";
-import { useClickOutside } from "~src/utilities/hooks";
-
-import Menu, { MenuItems } from "./Menu";
-
import { ThemeColor } from "../common";
+import { useClickOutside } from "../hooks";
+import Menu, { MenuItems } from "./Menu";
import "./PopupMenu.css";
diff --git a/FrontEnd/src/pages/login/index.tsx b/FrontEnd/src/pages/login/index.tsx
index 582ebd0f..39ea3831 100644
--- a/FrontEnd/src/pages/login/index.tsx
+++ b/FrontEnd/src/pages/login/index.tsx
@@ -6,11 +6,7 @@ import { useUser, userService } from "~src/services/user";
import { useC } from "~src/components/common";
import LoadingButton from "~src/components/button/LoadingButton";
-import {
- InputErrorDict,
- InputGroup,
- useInputs,
-} from "~src/components/input/InputGroup";
+import { InputGroup, useInputs } from "~src/components/input/InputGroup";
import Page from "~src/components/Page";
import "./index.css";
@@ -47,15 +43,13 @@ export default function LoginPage() {
label: "user.rememberMe",
},
],
- validator: ({ username, password }) => {
- const result: InputErrorDict = {};
+ validator: ({ username, password }, errors) => {
if (username === "") {
- result["username"] = "login.emptyUsername";
+ errors["username"] = "login.emptyUsername";
}
if (password === "") {
- result["password"] = "login.emptyPassword";
+ errors["password"] = "login.emptyPassword";
}
- return result;
},
},
dataInit: {},
diff --git a/FrontEnd/src/pages/register/index.tsx b/FrontEnd/src/pages/register/index.tsx
index 9e478612..fa25c2c2 100644
--- a/FrontEnd/src/pages/register/index.tsx
+++ b/FrontEnd/src/pages/register/index.tsx
@@ -7,11 +7,7 @@ import { getHttpTokenClient } from "~src/http/token";
import { userService, useUser } from "~src/services/user";
import { LoadingButton } from "~src/components/button";
-import {
- useInputs,
- InputErrorDict,
- InputGroup,
-} from "~src/components/input/InputGroup";
+import { useInputs, InputGroup } from "~src/components/input/InputGroup";
import "./index.css";
@@ -51,26 +47,22 @@ export default function RegisterPage() {
label: "register.registerCode",
},
],
- validator: ({
- username,
- password,
- confirmPassword,
- registerCode,
- }) => {
- const result: InputErrorDict = {};
+ validator: (
+ { username, password, confirmPassword, registerCode },
+ errors,
+ ) => {
if (username === "") {
- result["username"] = "register.error.usernameEmpty";
+ errors["username"] = "register.error.usernameEmpty";
}
if (password === "") {
- result["password"] = "register.error.passwordEmpty";
+ errors["password"] = "register.error.passwordEmpty";
}
if (confirmPassword !== password) {
- result["confirmPassword"] = "register.error.confirmPasswordWrong";
+ errors["confirmPassword"] = "register.error.confirmPasswordWrong";
}
if (registerCode === "") {
- result["registerCode"] = "register.error.registerCodeEmpty";
+ errors["registerCode"] = "register.error.registerCodeEmpty";
}
- return result;
},
},
dataInit: {},
diff --git a/FrontEnd/src/pages/setting/ChangeAvatarDialog.tsx b/FrontEnd/src/pages/setting/ChangeAvatarDialog.tsx
index c34bcf4f..011c5059 100644
--- a/FrontEnd/src/pages/setting/ChangeAvatarDialog.tsx
+++ b/FrontEnd/src/pages/setting/ChangeAvatarDialog.tsx
@@ -11,9 +11,8 @@ import ImageCropper, {
applyClipToImage,
} from "~src/components/ImageCropper";
import BlobImage from "~src/components/BlobImage";
-import ButtonRowV2 from "~src/components/button/ButtonRowV2";
-import Dialog from "~src/components/dialog/Dialog";
-import DialogContainer from "~src/components/dialog/DialogContainer";
+import { ButtonRowV2 } from "~src/components/button";
+import { Dialog, DialogContainer } from "~src/components/dialog";
import "./ChangeAvatarDialog.css";
diff --git a/FrontEnd/src/pages/setting/ChangePasswordDialog.tsx b/FrontEnd/src/pages/setting/ChangePasswordDialog.tsx
index bfcea92d..946b9fbe 100644
--- a/FrontEnd/src/pages/setting/ChangePasswordDialog.tsx
+++ b/FrontEnd/src/pages/setting/ChangePasswordDialog.tsx
@@ -3,9 +3,7 @@ import { useNavigate } from "react-router-dom";
import { userService } from "~src/services/user";
-import OperationDialog, {
- InputErrorDict,
-} from "~src/components/dialog/OperationDialog";
+import { OperationDialog } from "~src/components/dialog";
interface ChangePasswordDialogProps {
open: boolean;
@@ -47,21 +45,22 @@ export function ChangePasswordDialog(props: ChangePasswordDialogProps) {
password: true,
},
],
- validator: ({ oldPassword, newPassword, retypedNewPassword }) => {
- const result: InputErrorDict = {};
+ validator: (
+ { oldPassword, newPassword, retypedNewPassword },
+ errors,
+ ) => {
if (oldPassword === "") {
- result["oldPassword"] =
+ errors["oldPassword"] =
"settings.dialogChangePassword.errorEmptyOldPassword";
}
if (newPassword === "") {
- result["newPassword"] =
+ errors["newPassword"] =
"settings.dialogChangePassword.errorEmptyNewPassword";
}
if (retypedNewPassword !== newPassword) {
- result["retypedNewPassword"] =
+ errors["retypedNewPassword"] =
"settings.dialogChangePassword.errorRetypeNotMatch";
}
- return result;
},
}}
onProcess={async ({ oldPassword, newPassword }) => {
diff --git a/FrontEnd/src/pages/setting/index.tsx b/FrontEnd/src/pages/setting/index.tsx
index 67416a08..918a77b5 100644
--- a/FrontEnd/src/pages/setting/index.tsx
+++ b/FrontEnd/src/pages/setting/index.tsx
@@ -4,25 +4,26 @@ import {
ReactNode,
ComponentPropsWithoutRef,
} from "react";
-import { useTranslation } from "react-i18next";
+import { useTranslation } from "react-i18next"; // For change language.
import { useNavigate } from "react-router-dom";
import classNames from "classnames";
-import { useC, Text } from "~src/common";
import { useUser, userService } from "~src/services/user";
import { getHttpUserClient } from "~src/http/user";
+import { pushAlert } from "~src/services/alert";
+
+import { useC, Text } from "~src/common";
-import { useDialog } from "~src/components/dialog";
-import ConfirmDialog from "~src/components/dialog/ConfirmDialog";
+import { useDialog, ConfirmDialog } from "~src/components/dialog";
import Card from "~src/components/Card";
import Spinner from "~src/components/Spinner";
import Page from "~src/components/Page";
+
import ChangePasswordDialog from "./ChangePasswordDialog";
import ChangeAvatarDialog from "./ChangeAvatarDialog";
import ChangeNicknameDialog from "./ChangeNicknameDialog";
import "./index.css";
-import { pushAlert } from "~src/services/alert";
interface SettingSectionProps
extends Omit<ComponentPropsWithoutRef<typeof Card>, "title"> {
diff --git a/FrontEnd/src/pages/timeline/Timeline.tsx b/FrontEnd/src/pages/timeline/Timeline.tsx
index f266ec9d..caf4f502 100644
--- a/FrontEnd/src/pages/timeline/Timeline.tsx
+++ b/FrontEnd/src/pages/timeline/Timeline.tsx
@@ -1,6 +1,5 @@
import { useState, useEffect } from "react";
import classnames from "classnames";
-import { useScrollToBottom } from "~src/utilities/hooks";
import { HubConnectionState } from "@microsoft/signalr";
import {
@@ -16,6 +15,8 @@ import {
import { getTimelinePostUpdate$ } from "~src/services/timeline";
+import { useScrollToBottom } from "~src/components/hooks";
+
import TimelinePostList from "./TimelinePostList";
import TimelinePostEdit from "./TimelinePostCreateView";
import TimelineCard from "./TimelineCard";
diff --git a/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx b/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx
index 7b7b8e8c..a7209e75 100644
--- a/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx
+++ b/FrontEnd/src/pages/timeline/TimelineDeleteDialog.tsx
@@ -39,9 +39,9 @@ const TimelineDeleteDialog: React.FC<TimelineDeleteDialog> = (props) => {
label: "",
},
],
- validator: ({ name }) => {
+ validator: ({ name }, errors) => {
if (name !== timeline.nameV2) {
- return { name: "timeline.deleteDialog.notMatch" };
+ errors.name = "timeline.deleteDialog.notMatch";
}
},
}}
diff --git a/FrontEnd/src/pages/timeline/TimelinePostView.tsx b/FrontEnd/src/pages/timeline/TimelinePostView.tsx
index 2a8c5947..6b87ef2a 100644
--- a/FrontEnd/src/pages/timeline/TimelinePostView.tsx
+++ b/FrontEnd/src/pages/timeline/TimelinePostView.tsx
@@ -1,11 +1,13 @@
import { useState } from "react";
-import { getHttpTimelineClient, HttpTimelinePostInfo } from "~src/http/timeline";
+import {
+ getHttpTimelineClient,
+ HttpTimelinePostInfo,
+} from "~src/http/timeline";
import { pushAlert } from "~src/services/alert";
-import { useClickOutside } from "~src/utilities/hooks";
-
+import { useClickOutside } from "~src/components/hooks";
import UserAvatar from "~src/components/user/UserAvatar";
import { useDialog } from "~src/components/dialog";
import FlatButton from "~src/components/button/FlatButton";
diff --git a/FrontEnd/src/utilities/hooks.ts b/FrontEnd/src/utilities/hooks.ts
deleted file mode 100644
index a59f7167..00000000
--- a/FrontEnd/src/utilities/hooks.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import useClickOutside from "./hooks/useClickOutside";
-import useScrollToBottom from "./hooks/useScrollToBottom";
-import { useIsSmallScreen } from "./hooks/mediaQuery";
-
-export { useClickOutside, useScrollToBottom, useIsSmallScreen };
diff --git a/FrontEnd/src/utilities/hooks/mediaQuery.ts b/FrontEnd/src/utilities/hooks/mediaQuery.ts
deleted file mode 100644
index ad55c3c0..00000000
--- a/FrontEnd/src/utilities/hooks/mediaQuery.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import { useMediaQuery } from "react-responsive";
-
-export function useIsSmallScreen(): boolean {
- return useMediaQuery({ maxWidth: 576 });
-}