diff options
Diffstat (limited to 'FrontEnd/src')
-rw-r--r-- | FrontEnd/src/app/locales/en/translation.json | 5 | ||||
-rw-r--r-- | FrontEnd/src/app/locales/zh/translation.json | 5 | ||||
-rw-r--r-- | FrontEnd/src/app/views/common/Menu.tsx | 5 | ||||
-rw-r--r-- | FrontEnd/src/app/views/common/common.sass | 3 | ||||
-rw-r--r-- | FrontEnd/src/app/views/timeline-common/TimelinePostEdit.tsx | 44 |
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" |