aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-04-30 23:02:44 +0800
committercrupest <crupest@outlook.com>2022-04-30 23:02:44 +0800
commit5a095290db9abf5f8e9528ef4f56c0b974231ad1 (patch)
treee5100870518af9dbce285f9c7cd0099c5b6b2865 /FrontEnd/src
parentfff1a785aad30ebc9e96bbf973c7916143193b36 (diff)
downloadtimeline-5a095290db9abf5f8e9528ef4f56c0b974231ad1.tar.gz
timeline-5a095290db9abf5f8e9528ef4f56c0b974231ad1.tar.bz2
timeline-5a095290db9abf5f8e9528ef4f56c0b974231ad1.zip
...
Diffstat (limited to 'FrontEnd/src')
-rw-r--r--FrontEnd/src/views/admin/UserAdmin.tsx7
-rw-r--r--FrontEnd/src/views/center/TimelineBoard.tsx12
-rw-r--r--FrontEnd/src/views/common/alert/AlertHost.tsx7
-rw-r--r--FrontEnd/src/views/common/button/IconButton.css9
-rw-r--r--FrontEnd/src/views/common/button/IconButton.tsx25
-rw-r--r--FrontEnd/src/views/common/dailog/FullPageDialog.tsx6
-rw-r--r--FrontEnd/src/views/common/index.css13
-rw-r--r--FrontEnd/src/views/home/TimelineListView.tsx4
-rw-r--r--FrontEnd/src/views/timeline/CollapseButton.tsx12
-rw-r--r--FrontEnd/src/views/timeline/MarkdownPostEdit.tsx14
-rw-r--r--FrontEnd/src/views/timeline/TimelineCard.tsx16
-rw-r--r--FrontEnd/src/views/timeline/TimelineDeleteDialog.tsx2
-rw-r--r--FrontEnd/src/views/timeline/TimelinePostEdit.tsx19
-rw-r--r--FrontEnd/src/views/timeline/TimelinePostView.tsx7
14 files changed, 95 insertions, 58 deletions
diff --git a/FrontEnd/src/views/admin/UserAdmin.tsx b/FrontEnd/src/views/admin/UserAdmin.tsx
index fd4ff881..02fb0d12 100644
--- a/FrontEnd/src/views/admin/UserAdmin.tsx
+++ b/FrontEnd/src/views/admin/UserAdmin.tsx
@@ -10,6 +10,7 @@ import OperationDialog, {
import Button from "../common/button/Button";
import Spinner from "../common/Spinner";
import FlatButton from "../common/button/FlatButton";
+import IconButton from "../common/button/IconButton";
const CreateUserDialog: React.FC<{
open: boolean;
@@ -181,8 +182,10 @@ const UserItem: React.FC<UserItemProps> = ({ user, onChange }) => {
return (
<>
<div className="admin-user-item">
- <i
- className="bi-pencil-square cru-float-right icon-button cru-color-primary-enhance"
+ <IconButton
+ icon="pencil-square"
+ color="primary-enhance"
+ className="cru-float-right"
onClick={() => setEditMaskVisible(true)}
/>
<h5 className="cru-color-primary">{user.username}</h5>
diff --git a/FrontEnd/src/views/center/TimelineBoard.tsx b/FrontEnd/src/views/center/TimelineBoard.tsx
index 45b4a8a5..7ff4e0a4 100644
--- a/FrontEnd/src/views/center/TimelineBoard.tsx
+++ b/FrontEnd/src/views/center/TimelineBoard.tsx
@@ -9,6 +9,7 @@ import LoadFailReload from "../common/LoadFailReload";
import FlatButton from "../common/button/FlatButton";
import Card from "../common/Card";
import Spinner from "../common/Spinner";
+import IconButton from "../common/button/IconButton";
interface TimelineBoardItemProps {
timeline: TimelineBookmark;
@@ -42,12 +43,15 @@ const TimelineBoardItem: React.FC<TimelineBoardItemProps> = ({
<span className="flex-grow-1"></span>
{actions != null ? (
<div className="right">
- <i
- className="bi-trash icon-button cru-color-danger px-2"
+ <IconButton
+ icon="trash"
+ color="danger"
+ className="px-2"
onClick={actions.onDelete}
/>
- <i
- className="bi-grip-vertical icon-button px-2 touch-action-none"
+ <IconButton
+ icon="grip-vertical"
+ className="px-2 touch-action-none"
onPointerDown={(e) => {
e.currentTarget.setPointerCapture(e.pointerId);
actions.onMove.start(e);
diff --git a/FrontEnd/src/views/common/alert/AlertHost.tsx b/FrontEnd/src/views/common/alert/AlertHost.tsx
index ba6d6a0f..92db78fa 100644
--- a/FrontEnd/src/views/common/alert/AlertHost.tsx
+++ b/FrontEnd/src/views/common/alert/AlertHost.tsx
@@ -6,6 +6,8 @@ import classNames from "classnames";
import { alertService, AlertInfoEx, AlertInfo } from "@/services/alert";
import { convertI18nText } from "@/common";
+import IconButton from "../button/IconButton";
+
import "./alert.css";
interface AutoCloseAlertProps {
@@ -67,8 +69,9 @@ export const AutoCloseAlert: React.FC<AutoCloseAlertProps> = (props) => {
})()}
</div>
<div className="cru-alert-close-button-container">
- <i
- className={classNames("icon-button bi-x cru-alert-close-button")}
+ <IconButton
+ icon="x"
+ className="cru-alert-close-button"
onClick={close}
/>
</div>
diff --git a/FrontEnd/src/views/common/button/IconButton.css b/FrontEnd/src/views/common/button/IconButton.css
new file mode 100644
index 00000000..ef4dca00
--- /dev/null
+++ b/FrontEnd/src/views/common/button/IconButton.css
@@ -0,0 +1,9 @@
+.cru-icon-button {
+ color: var(--cru-theme-color);
+ font-size: 1.4rem;
+ cursor: pointer;
+}
+
+.cru-icon-button.large {
+ font-size: 1.6rem;
+}
diff --git a/FrontEnd/src/views/common/button/IconButton.tsx b/FrontEnd/src/views/common/button/IconButton.tsx
new file mode 100644
index 00000000..56c62588
--- /dev/null
+++ b/FrontEnd/src/views/common/button/IconButton.tsx
@@ -0,0 +1,25 @@
+import classNames from "classnames";
+import React from "react";
+
+export type IconButtonProps = {
+ icon: string;
+ color?: string;
+ large?: boolean;
+} & React.ComponentPropsWithRef<"i">;
+
+export default function IconButton(props: IconButtonProps): JSX.Element {
+ const { icon, color, className, large, ...otherProps } = props;
+
+ return (
+ <i
+ className={classNames(
+ "cru-icon-button",
+ large && "large",
+ "bi-" + icon,
+ color ? "cru-" + color : "cru-primary",
+ className
+ )}
+ {...otherProps}
+ />
+ );
+}
diff --git a/FrontEnd/src/views/common/dailog/FullPageDialog.tsx b/FrontEnd/src/views/common/dailog/FullPageDialog.tsx
index 3c7f9d0b..ef76f2f2 100644
--- a/FrontEnd/src/views/common/dailog/FullPageDialog.tsx
+++ b/FrontEnd/src/views/common/dailog/FullPageDialog.tsx
@@ -4,6 +4,7 @@ import classnames from "classnames";
import { CSSTransition } from "react-transition-group";
import "./FullPageDialog.css";
+import IconButton from "../button/IconButton";
export interface FullPageDialogProps {
show: boolean;
@@ -28,8 +29,9 @@ const FullPageDialog: React.FC<FullPageDialogProps> = ({
>
<div className="cru-full-page">
<div className="cru-full-page-top-bar">
- <i
- className="icon-button bi-arrow-left ms-3 cru-full-page-back-button"
+ <IconButton
+ icon="arrow-left"
+ className="ms-3 cru-full-page-back-button"
onClick={onBack}
/>
</div>
diff --git a/FrontEnd/src/views/common/index.css b/FrontEnd/src/views/common/index.css
index 05fdce04..f6f14d2d 100644
--- a/FrontEnd/src/views/common/index.css
+++ b/FrontEnd/src/views/common/index.css
@@ -243,19 +243,6 @@
height: 100%;
}
-.icon-button {
- font-size: 1.4rem;
- cursor: pointer;
-}
-
-.icon-button.large {
- font-size: 1.6rem;
-}
-
-.icon-button.primary-enhance {
- color: var(--cru-primary-enhance-color);
-}
-
.cru-avatar {
width: 60px;
height: 60px;
diff --git a/FrontEnd/src/views/home/TimelineListView.tsx b/FrontEnd/src/views/home/TimelineListView.tsx
index b26f1f70..7bffba76 100644
--- a/FrontEnd/src/views/home/TimelineListView.tsx
+++ b/FrontEnd/src/views/home/TimelineListView.tsx
@@ -6,6 +6,8 @@ import { convertI18nText, I18nText } from "@/common";
import { TimelineBookmark } from "@/http/bookmark";
+import IconButton from "../common/button/IconButton";
+
interface TimelineListItemProps {
timeline: TimelineBookmark;
}
@@ -24,7 +26,7 @@ const TimelineListItem: React.FC<TimelineListItemProps> = ({ timeline }) => {
{timeline.timelineOwner}/{timeline.timelineName}
</div>
<Link to={`${timeline.timelineOwner}/${timeline.timelineName}`}>
- <i className="icon-button bi-arrow-right ms-3" />
+ <IconButton icon="arrow-right" className="ms-3" />
</Link>
</div>
);
diff --git a/FrontEnd/src/views/timeline/CollapseButton.tsx b/FrontEnd/src/views/timeline/CollapseButton.tsx
index 31976228..b8d06916 100644
--- a/FrontEnd/src/views/timeline/CollapseButton.tsx
+++ b/FrontEnd/src/views/timeline/CollapseButton.tsx
@@ -1,5 +1,6 @@
import React from "react";
-import classnames from "classnames";
+
+import IconButton from "../common/button/IconButton";
const CollapseButton: React.FC<{
collapse: boolean;
@@ -8,13 +9,10 @@ const CollapseButton: React.FC<{
style?: React.CSSProperties;
}> = ({ collapse, onClick, className, style }) => {
return (
- <i
+ <IconButton
+ icon={collapse ? "arrows-angle-expand" : "arrows-angle-contract"}
onClick={onClick}
- className={classnames(
- collapse ? "bi-arrows-angle-expand" : "bi-arrows-angle-contract",
- "cru-color-primary icon-button",
- className
- )}
+ className={className}
style={style}
/>
);
diff --git a/FrontEnd/src/views/timeline/MarkdownPostEdit.tsx b/FrontEnd/src/views/timeline/MarkdownPostEdit.tsx
index 35a2bbf5..9ab40e54 100644
--- a/FrontEnd/src/views/timeline/MarkdownPostEdit.tsx
+++ b/FrontEnd/src/views/timeline/MarkdownPostEdit.tsx
@@ -10,6 +10,7 @@ import FlatButton from "../common/button/FlatButton";
import TabPages from "../common/tab/TabPages";
import ConfirmDialog from "../common/dailog/ConfirmDialog";
import Spinner from "../common/Spinner";
+import IconButton from "../common/button/IconButton";
import "./MarkdownPostEdit.css";
@@ -113,8 +114,11 @@ const MarkdownPostEdit: React.FC<MarkdownPostEditProps> = ({
<Spinner />
) : (
<div>
- <i
- className="icon-button large bi-x cru-color-danger cru-align-middle me-2"
+ <IconButton
+ icon="x"
+ color="danger"
+ large
+ className="cru-align-middle me-2"
onClick={() => {
if (canLeave) {
onClose();
@@ -158,9 +162,11 @@ const MarkdownPostEdit: React.FC<MarkdownPostEditProps> = ({
src={image.url}
className="timeline-markdown-post-edit-image"
/>
- <i
+ <IconButton
+ icon="trash"
+ color="danger"
className={classnames(
- "bi-trash text-danger icon-button timeline-markdown-post-edit-image-delete-button",
+ "timeline-markdown-post-edit-image-delete-button",
process && "d-none"
)}
onClick={() => {
diff --git a/FrontEnd/src/views/timeline/TimelineCard.tsx b/FrontEnd/src/views/timeline/TimelineCard.tsx
index d258dc75..b1146ad5 100644
--- a/FrontEnd/src/views/timeline/TimelineCard.tsx
+++ b/FrontEnd/src/views/timeline/TimelineCard.tsx
@@ -19,6 +19,7 @@ import ConnectionStatusBadge from "./ConnectionStatusBadge";
import CollapseButton from "./CollapseButton";
import { TimelineMemberDialog } from "./TimelineMember";
import TimelinePropertyChangeDialog from "./TimelinePropertyChangeDialog";
+import IconButton from "../common/button/IconButton";
export interface TimelinePageCardProps {
timeline: HttpTimelineInfo;
@@ -67,11 +68,9 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
</small>
<div className="mt-2 cru-text-end">
{user != null ? (
- <i
- className={classnames(
- timeline.isBookmark ? "bi-bookmark-fill" : "bi-bookmark",
- "icon-button cru-color-primary me-3"
- )}
+ <IconButton
+ icon={timeline.isBookmark ? "bookmark-fill" : "bookmark"}
+ className="me-3"
onClick={() => {
getHttpBookmarkClient()
[timeline.isBookmark ? "delete" : "post"](
@@ -90,8 +89,9 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
}}
/>
) : null}
- <i
- className={"icon-button bi-people cru-color-primary me-3"}
+ <IconButton
+ icon="people"
+ className="me-3"
onClick={() => setDialog("member")}
/>
{timeline.manageable ? (
@@ -112,7 +112,7 @@ const TimelineCard: React.FC<TimelinePageCardProps> = (props) => {
]}
containerClassName="d-inline"
>
- <i className="icon-button bi-three-dots-vertical cru-color-primary" />
+ <IconButton icon="three-dots-vertical" />
</PopupMenu>
) : null}
</div>
diff --git a/FrontEnd/src/views/timeline/TimelineDeleteDialog.tsx b/FrontEnd/src/views/timeline/TimelineDeleteDialog.tsx
index 5b57b0c4..3a339622 100644
--- a/FrontEnd/src/views/timeline/TimelineDeleteDialog.tsx
+++ b/FrontEnd/src/views/timeline/TimelineDeleteDialog.tsx
@@ -27,7 +27,7 @@ const TimelineDeleteDialog: React.FC<TimelineDeleteDialog> = (props) => {
return (
<Trans
i18nKey="timeline.deleteDialog.inputPrompt"
- values={[{ name: timeline.nameV2 }]}
+ values={{ name: timeline.nameV2 }}
>
0<code className="mx-2">1</code>2
</Trans>
diff --git a/FrontEnd/src/views/timeline/TimelinePostEdit.tsx b/FrontEnd/src/views/timeline/TimelinePostEdit.tsx
index 3b42f38d..f1c5b22c 100644
--- a/FrontEnd/src/views/timeline/TimelinePostEdit.tsx
+++ b/FrontEnd/src/views/timeline/TimelinePostEdit.tsx
@@ -1,5 +1,4 @@
import React from "react";
-import classnames from "classnames";
import { useTranslation } from "react-i18next";
import { UiLogicError } from "@/common";
@@ -20,6 +19,7 @@ import LoadingButton from "../common/button/LoadingButton";
import PopupMenu from "../common/menu/PopupMenu";
import MarkdownPostEdit from "./MarkdownPostEdit";
import TimelinePostEditCard from "./TimelinePostEditCard";
+import IconButton from "../common/button/IconButton";
import "./TimelinePostEdit.css";
@@ -104,10 +104,10 @@ const TimelinePostEditImage: React.FC<TimelinePostEditImageProps> = (props) => {
type PostKind = "text" | "markdown" | "image";
-const postKindIconClassNameMap: Record<PostKind, string> = {
- text: "bi-fonts",
- markdown: "bi-markdown",
- image: "bi-image",
+const postKindIconMap: Record<PostKind, string> = {
+ text: "fonts",
+ markdown: "markdown",
+ image: "image",
};
export interface TimelinePostEditProps {
@@ -237,7 +237,7 @@ const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => {
items={(["text", "image", "markdown"] as const).map((kind) => ({
type: "button",
text: `timeline.post.type.${kind}`,
- iconClassName: postKindIconClassNameMap[kind],
+ iconClassName: postKindIconMap[kind],
onClick: () => {
if (kind === "markdown") {
setShowMarkdown(true);
@@ -247,12 +247,7 @@ const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => {
},
}))}
>
- <i
- className={classnames(
- postKindIconClassNameMap[kind],
- "icon-button large"
- )}
- />
+ <IconButton large icon={postKindIconMap[kind]} />
</PopupMenu>
</div>
<LoadingButton
diff --git a/FrontEnd/src/views/timeline/TimelinePostView.tsx b/FrontEnd/src/views/timeline/TimelinePostView.tsx
index 8a4da9ab..ca6ee2c5 100644
--- a/FrontEnd/src/views/timeline/TimelinePostView.tsx
+++ b/FrontEnd/src/views/timeline/TimelinePostView.tsx
@@ -14,6 +14,7 @@ import ConfirmDialog from "../common/dailog/ConfirmDialog";
import TimelineLine from "./TimelineLine";
import TimelinePostContentView from "./TimelinePostContentView";
import PostPropertyChangeDialog from "./PostPropertyChangeDialog";
+import IconButton from "../common/button/IconButton";
export interface TimelinePostViewProps {
post: HttpTimelinePostInfo;
@@ -70,8 +71,10 @@ const TimelinePostView: React.FC<TimelinePostViewProps> = (props) => {
style={cardStyle}
>
{post.editable ? (
- <i
- className="bi-chevron-down icon-button primary-enhance cru-float-right"
+ <IconButton
+ icon="chevron-down"
+ color="primary-enhance"
+ className="cru-float-right"
onClick={(e) => {
setOperationMaskVisible(true);
e.stopPropagation();