aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src
diff options
context:
space:
mode:
Diffstat (limited to 'FrontEnd/src')
-rw-r--r--FrontEnd/src/app/locales/en/translation.json5
-rw-r--r--FrontEnd/src/app/locales/zh/translation.json5
-rw-r--r--FrontEnd/src/app/views/common/Menu.tsx5
-rw-r--r--FrontEnd/src/app/views/common/common.sass3
-rw-r--r--FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx44
5 files changed, 48 insertions, 14 deletions
diff --git a/FrontEnd/src/app/locales/en/translation.json b/FrontEnd/src/app/locales/en/translation.json
index 63b2a1be..4002ee4f 100644
--- a/FrontEnd/src/app/locales/en/translation.json
+++ b/FrontEnd/src/app/locales/en/translation.json
@@ -99,6 +99,11 @@
"notMatch": "Name does not match."
},
"post": {
+ "type": {
+ "text": "Plain Text",
+ "markdown": "Markdown",
+ "image": "Image"
+ },
"deleteDialog": {
"title": "Confirm Delete",
"prompt": "Are you sure to delete the post? This operation is not recoverable."
diff --git a/FrontEnd/src/app/locales/zh/translation.json b/FrontEnd/src/app/locales/zh/translation.json
index 296966c4..3f966d7c 100644
--- a/FrontEnd/src/app/locales/zh/translation.json
+++ b/FrontEnd/src/app/locales/zh/translation.json
@@ -99,6 +99,11 @@
"notMatch": "名字不匹配"
},
"post": {
+ "type": {
+ "text": "纯文本",
+ "markdown": "Markdown",
+ "image": "图片"
+ },
"deleteDialog": {
"title": "确认删除",
"prompt": "确定删除这个消息?这个操作不可撤销。"
diff --git a/FrontEnd/src/app/views/common/Menu.tsx b/FrontEnd/src/app/views/common/Menu.tsx
index c2110c9c..54650f22 100644
--- a/FrontEnd/src/app/views/common/Menu.tsx
+++ b/FrontEnd/src/app/views/common/Menu.tsx
@@ -12,6 +12,7 @@ export type MenuItem =
| {
type: "button";
text: I18nText;
+ iconClassName?: string;
color?: BootstrapThemeColor;
onClick: () => void;
};
@@ -44,6 +45,9 @@ const Menu: React.FC<MenuProps> = ({ items, className, onItemClicked }) => {
onItemClicked?.();
}}
>
+ {item.iconClassName != null ? (
+ <i className={clsx(item.iconClassName, "cru-menu-item-icon")} />
+ ) : null}
{convertI18nText(item.text, t)}
</div>
);
@@ -67,7 +71,6 @@ export const PopupMenu: React.FC<PopupMenuProps> = ({ items, children }) => {
return (
<OverlayTrigger
trigger="click"
- placement="bottom"
rootClose
overlay={
<Popover id="menu-popover">
diff --git a/FrontEnd/src/app/views/common/common.sass b/FrontEnd/src/app/views/common/common.sass
index 819408a0..0a30d995 100644
--- a/FrontEnd/src/app/views/common/common.sass
+++ b/FrontEnd/src/app/views/common/common.sass
@@ -87,5 +87,8 @@
color: white
background-color: $value
+.cru-menu-item-icon
+ margin-right: 1em
+
.cru-menu-divider
border-top: 1px solid $gray-200
diff --git a/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx b/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx
index 9d742514..6c428b74 100644
--- a/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx
+++ b/FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx
@@ -17,6 +17,7 @@ import { base64 } from "@/http/common";
import BlobImage from "../common/BlobImage";
import LoadingButton from "../common/LoadingButton";
+import { PopupMenu } from "../common/Menu";
interface TimelinePostEditTextProps {
text: string;
@@ -67,6 +68,12 @@ const TimelinePostEditImage: React.FC<TimelinePostEditImageProps> = (props) => {
}
};
+ React.useEffect(() => {
+ return () => {
+ onSelect(null);
+ };
+ }, [onSelect]);
+
return (
<>
<Form.File
@@ -92,6 +99,14 @@ 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",
+};
+
export interface TimelinePostEditProps {
className?: string;
timeline: HttpTimelineInfo;
@@ -106,8 +121,6 @@ const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => {
const [process, setProcess] = React.useState<boolean>(false);
- type PostKind = "text" | "markdown" | "image";
-
const [kind, setKind] = React.useState<PostKind>("text");
const [text, setText] = React.useState<string>("");
@@ -250,18 +263,23 @@ const TimelinePostEdit: React.FC<TimelinePostEditProps> = (props) => {
</Col>
<Col xs="auto" className="align-self-end m-1">
<div className="d-block text-center mt-1 mb-2">
- <Form.Control
- as="select"
- value={kind}
- onChange={(event) => {
- const { value } = event.currentTarget;
- setKind(value as PostKind);
- }}
+ <PopupMenu
+ items={(["text", "image", "markdown"] as const).map((kind) => ({
+ type: "button",
+ text: `timeline.post.type.${kind}`,
+ iconClassName: postKindIconClassNameMap[kind],
+ onClick: () => {
+ setKind(kind);
+ },
+ }))}
>
- <option value="text">text</option>
- <option value="image">image</option>
- <option value="markdown">markdown</option>
- </Form.Control>
+ <i
+ className={clsx(
+ postKindIconClassNameMap[kind],
+ "icon-button large"
+ )}
+ />
+ </PopupMenu>
</div>
<LoadingButton
variant="primary"