aboutsummaryrefslogtreecommitdiff
path: root/FrontEnd/src
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2023-09-14 23:47:16 +0800
committercrupest <crupest@outlook.com>2023-09-14 23:47:16 +0800
commit40b4871c3f7bfe04f332ae7fb687fd7d9ae34734 (patch)
treecba45fa30627a704c2fb5132eff3f936ba1dd54e /FrontEnd/src
parentc1f79460d57a4daba75bdc34b7b7a3ea2d7254b3 (diff)
downloadtimeline-40b4871c3f7bfe04f332ae7fb687fd7d9ae34734.tar.gz
timeline-40b4871c3f7bfe04f332ae7fb687fd7d9ae34734.tar.bz2
timeline-40b4871c3f7bfe04f332ae7fb687fd7d9ae34734.zip
...
Diffstat (limited to 'FrontEnd/src')
-rw-r--r--FrontEnd/src/pages/timeline/ConnectionStatusBadge.css2
-rw-r--r--FrontEnd/src/pages/timeline/ConnectionStatusBadge.tsx21
-rw-r--r--FrontEnd/src/pages/timeline/Timeline.tsx2
-rw-r--r--FrontEnd/src/pages/timeline/TimelinePostCreateView.css54
-rw-r--r--FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx16
-rw-r--r--FrontEnd/src/pages/timeline/edit/ImagePostEdit.css4
-rw-r--r--FrontEnd/src/pages/timeline/edit/ImagePostEdit.tsx36
-rw-r--r--FrontEnd/src/pages/timeline/edit/MarkdownPostEdit.css (renamed from FrontEnd/src/pages/timeline/MarkdownPostEdit.css)0
-rw-r--r--FrontEnd/src/pages/timeline/edit/MarkdownPostEdit.tsx (renamed from FrontEnd/src/pages/timeline/MarkdownPostEdit.tsx)0
-rw-r--r--FrontEnd/src/pages/timeline/edit/PlainTextPostEdit.css18
-rw-r--r--FrontEnd/src/pages/timeline/edit/PlainTextPostEdit.tsx26
-rw-r--r--FrontEnd/src/pages/timeline/edit/TimelinePostCreateView.css33
-rw-r--r--FrontEnd/src/pages/timeline/edit/TimelinePostCreateView.tsx (renamed from FrontEnd/src/pages/timeline/TimelinePostCreateView.tsx)86
13 files changed, 140 insertions, 158 deletions
diff --git a/FrontEnd/src/pages/timeline/ConnectionStatusBadge.css b/FrontEnd/src/pages/timeline/ConnectionStatusBadge.css
index fc01484e..f2f8df66 100644
--- a/FrontEnd/src/pages/timeline/ConnectionStatusBadge.css
+++ b/FrontEnd/src/pages/timeline/ConnectionStatusBadge.css
@@ -22,7 +22,7 @@
}
.connection-status-badge.warning {
- color: #e4a700;
+ color: #e4a700; /* TODO: Warning color */
}
.connection-status-badge.warning::before {
diff --git a/FrontEnd/src/pages/timeline/ConnectionStatusBadge.tsx b/FrontEnd/src/pages/timeline/ConnectionStatusBadge.tsx
index 2b820454..63990878 100644
--- a/FrontEnd/src/pages/timeline/ConnectionStatusBadge.tsx
+++ b/FrontEnd/src/pages/timeline/ConnectionStatusBadge.tsx
@@ -1,14 +1,13 @@
-import * as React from "react";
-import classnames from "classnames";
+import classNames from "classnames";
import { HubConnectionState } from "@microsoft/signalr";
-import { useTranslation } from "react-i18next";
+
+import { useC }from '~/src/components/common';
import "./ConnectionStatusBadge.css";
-export interface ConnectionStatusBadgeProps {
+interface ConnectionStatusBadgeProps {
status: HubConnectionState;
className?: string;
- style?: React.CSSProperties;
}
const classNameMap: Record<HubConnectionState, string> = {
@@ -19,23 +18,19 @@ const classNameMap: Record<HubConnectionState, string> = {
Reconnecting: "warning",
};
-const ConnectionStatusBadge: React.FC<ConnectionStatusBadgeProps> = (props) => {
- const { status, className, style } = props;
-
- const { t } = useTranslation();
+export default function ConnectionStatusBadge({status, className}: ConnectionStatusBadgeProps) {
+ const c = useC();
return (
<div
- className={classnames(
+ className={classNames(
"connection-status-badge",
classNameMap[status],
className
)}
- style={style}
>
- {t(`connectionState.${status}`)}
+ {c(`connectionState.${status}`)}
</div>
);
};
-export default ConnectionStatusBadge;
diff --git a/FrontEnd/src/pages/timeline/Timeline.tsx b/FrontEnd/src/pages/timeline/Timeline.tsx
index 1d8e28d5..32cbf8c8 100644
--- a/FrontEnd/src/pages/timeline/Timeline.tsx
+++ b/FrontEnd/src/pages/timeline/Timeline.tsx
@@ -18,8 +18,8 @@ import { getTimelinePostUpdate$ } from "~src/services/timeline";
import { useScrollToBottom } from "~src/components/hooks";
import TimelinePostList from "./TimelinePostList";
-import TimelinePostEdit from "./TimelinePostCreateView";
import TimelineInfoCard from "./TimelineInfoCard";
+import TimelinePostEdit from "./edit/TimelinePostCreateView";
import "./Timeline.css";
diff --git a/FrontEnd/src/pages/timeline/TimelinePostCreateView.css b/FrontEnd/src/pages/timeline/TimelinePostCreateView.css
deleted file mode 100644
index e483ca17..00000000
--- a/FrontEnd/src/pages/timeline/TimelinePostCreateView.css
+++ /dev/null
@@ -1,54 +0,0 @@
-.timeline-post-create-card {
- position: sticky !important;
- top: 106px;
- z-index: 100;
- margin-right: 200px;
-}
-
-@media (max-width: 576px) {
- .timeline-post-create-container {
- padding-top: 60px;
- }
-
- .timeline-post-create-card{
- margin-right: 0;
- }
-}
-
-.timeline-post-create {
- display: flex;
-}
-
-.timeline-post-create-edit-area {
- flex-grow: 1;
-}
-
-.timeline-post-create-edit-text {
- width: 100%;
- height: 100%;
- background-color: var(--cru-background-color);
- color: var(--cru-text-major-color);
- border: 1px solid var(--cru-text-major-color);
- padding: 0.5em;
- border-radius: 5px;
-}
-
-.timeline-post-create-edit-text:hover {
- border-color: var(--cru-clickable-secondary-normal-color)
-}
-
-.timeline-post-create-edit-text:focus {
- border-color: var(--cru-clickable-secondary-normal-color)
-}
-
-.timeline-post-create-image {
- max-width: 100px;
- max-height: 100px;
-}
-
-.timeline-post-create-right-area {
- display: flex;
- flex-direction: column;
- align-items: center;
- margin-left: 1em;
-}
diff --git a/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx b/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx
index ee5388cb..79838d58 100644
--- a/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx
+++ b/FrontEnd/src/pages/timeline/TimelinePropertyChangeDialog.tsx
@@ -1,5 +1,3 @@
-import * as React from "react";
-
import {
getHttpTimelineClient,
HttpTimelineInfo,
@@ -10,7 +8,7 @@ import {
import OperationDialog from "~src/components/dialog/OperationDialog";
-export interface TimelinePropertyChangeDialogProps {
+interface TimelinePropertyChangeDialogProps {
timeline: HttpTimelineInfo;
onChange: () => void;
}
@@ -21,11 +19,10 @@ const labelMap: { [key in TimelineVisibility]: string } = {
Register: "timeline.visibility.register",
};
-const TimelinePropertyChangeDialog: React.FC<
- TimelinePropertyChangeDialogProps
-> = (props) => {
- const { timeline, onChange } = props;
-
+export default function TimelinePropertyChangeDialog({
+ timeline,
+ onChange,
+}: TimelinePropertyChangeDialogProps) {
return (
<OperationDialog
title={"timeline.dialogChangeProperty.title"}
@@ -78,6 +75,5 @@ const TimelinePropertyChangeDialog: React.FC<
}}
/>
);
-};
+}
-export default TimelinePropertyChangeDialog;
diff --git a/FrontEnd/src/pages/timeline/edit/ImagePostEdit.css b/FrontEnd/src/pages/timeline/edit/ImagePostEdit.css
new file mode 100644
index 00000000..3d5e895c
--- /dev/null
+++ b/FrontEnd/src/pages/timeline/edit/ImagePostEdit.css
@@ -0,0 +1,4 @@
+.timeline-post-create-image {
+ max-width: 100px;
+ max-height: 100px;
+}
diff --git a/FrontEnd/src/pages/timeline/edit/ImagePostEdit.tsx b/FrontEnd/src/pages/timeline/edit/ImagePostEdit.tsx
new file mode 100644
index 00000000..d25d04b4
--- /dev/null
+++ b/FrontEnd/src/pages/timeline/edit/ImagePostEdit.tsx
@@ -0,0 +1,36 @@
+import classNames from "classnames";
+
+import BlobImage from "~/src/components/BlobImage";
+
+interface TimelinePostEditImageProps {
+ file: File;
+ onChange: (file: File | null) => void;
+ disabled: boolean;
+ className?: string;
+}
+
+export default function ImagePostEdit(props: TimelinePostEditImageProps) {
+ const { file, onChange, disabled, className } = props;
+
+ return (
+ <div
+ className={classNames("timeline-post-create-edit-container", className)}
+ >
+ <input
+ type="file"
+ accept="image/*"
+ disabled={disabled}
+ onChange={(e) => {
+ const files = e.target.files;
+ if (files == null || files.length === 0) {
+ onChange(null);
+ } else {
+ onChange(files[0]);
+ }
+ }}
+ className="mx-3 my-1"
+ />
+ {file && <BlobImage src={file} className="timeline-post-create-image" />}
+ </div>
+ );
+}
diff --git a/FrontEnd/src/pages/timeline/MarkdownPostEdit.css b/FrontEnd/src/pages/timeline/edit/MarkdownPostEdit.css
index 33a77943..33a77943 100644
--- a/FrontEnd/src/pages/timeline/MarkdownPostEdit.css
+++ b/FrontEnd/src/pages/timeline/edit/MarkdownPostEdit.css
diff --git a/FrontEnd/src/pages/timeline/MarkdownPostEdit.tsx b/FrontEnd/src/pages/timeline/edit/MarkdownPostEdit.tsx
index d10d3f2d..d10d3f2d 100644
--- a/FrontEnd/src/pages/timeline/MarkdownPostEdit.tsx
+++ b/FrontEnd/src/pages/timeline/edit/MarkdownPostEdit.tsx
diff --git a/FrontEnd/src/pages/timeline/edit/PlainTextPostEdit.css b/FrontEnd/src/pages/timeline/edit/PlainTextPostEdit.css
new file mode 100644
index 00000000..0f2b9dbd
--- /dev/null
+++ b/FrontEnd/src/pages/timeline/edit/PlainTextPostEdit.css
@@ -0,0 +1,18 @@
+.timeline-post-create-edit-text {
+ width: 100%;
+ height: 100%;
+ background-color: var(--cru-background-color);
+ color: var(--cru-text-major-color);
+ border: 1px solid var(--cru-text-major-color);
+ padding: 0.5em;
+ border-radius: 5px;
+}
+
+.timeline-post-create-edit-text:hover {
+ border-color: var(--cru-clickable-secondary-normal-color);
+}
+
+.timeline-post-create-edit-text:focus {
+ border-color: var(--cru-clickable-secondary-normal-color);
+}
+
diff --git a/FrontEnd/src/pages/timeline/edit/PlainTextPostEdit.tsx b/FrontEnd/src/pages/timeline/edit/PlainTextPostEdit.tsx
new file mode 100644
index 00000000..1bea3daf
--- /dev/null
+++ b/FrontEnd/src/pages/timeline/edit/PlainTextPostEdit.tsx
@@ -0,0 +1,26 @@
+import classNames from 'classnames'
+
+interface TimelinePostEditTextProps {
+ text: string;
+ disabled: boolean;
+ onChange: (text: string) => void;
+ className?: string;
+}
+
+export default function TimelinePostEditText(props: TimelinePostEditTextProps) {
+ const { text, disabled, onChange, className } = props;
+
+ return (
+ <div className={classNames("timeline-post-create-edit-container", className)}>
+ <textarea
+ value={text}
+ disabled={disabled}
+ onChange={(event) => {
+ onChange(event.target.value);
+ }}
+ className={classNames("timeline-post-create-edit-text")}
+ />
+ </div>
+ );
+}
+
diff --git a/FrontEnd/src/pages/timeline/edit/TimelinePostCreateView.css b/FrontEnd/src/pages/timeline/edit/TimelinePostCreateView.css
new file mode 100644
index 00000000..5e93d9f2
--- /dev/null
+++ b/FrontEnd/src/pages/timeline/edit/TimelinePostCreateView.css
@@ -0,0 +1,33 @@
+.timeline-post-create-card {
+ position: sticky !important;
+ top: 106px;
+ z-index: 100;
+ margin-right: 200px;
+}
+
+@media (max-width: 576px) {
+ .timeline-post-create-container {
+ padding-top: 60px;
+ }
+
+ .timeline-post-create-card{
+ margin-right: 0;
+ }
+}
+
+.timeline-post-create {
+ display: flex;
+}
+
+.timeline-post-create-edit-area {
+ flex-grow: 1;
+}
+
+
+
+.timeline-post-create-right-area {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-left: 1em;
+}
diff --git a/FrontEnd/src/pages/timeline/TimelinePostCreateView.tsx b/FrontEnd/src/pages/timeline/edit/TimelinePostCreateView.tsx
index 70925cd9..45d742f7 100644
--- a/FrontEnd/src/pages/timeline/TimelinePostCreateView.tsx
+++ b/FrontEnd/src/pages/timeline/edit/TimelinePostCreateView.tsx
@@ -1,5 +1,6 @@
import { useState, useEffect, ChangeEventHandler } from "react";
import { useTranslation } from "react-i18next";
+import classNames from "classnames";
import { UiLogicError } from "~src/common";
@@ -13,93 +14,20 @@ import {
import base64 from "~src/utilities/base64";
import { pushAlert } from "~src/components/alert";
-import BlobImage from "~src/components/BlobImage";
import LoadingButton from "~src/components/button/LoadingButton";
import PopupMenu from "~src/components/menu/PopupMenu";
-import MarkdownPostEdit from "./MarkdownPostEdit";
-import TimelinePostCard from "./TimelinePostCard";
-import TimelinePostContainer from "./TimelinePostContainer";
+import TimelinePostCard from "../TimelinePostCard";
+import TimelinePostContainer from "../TimelinePostContainer";
import IconButton from "~src/components/button/IconButton";
-import "./TimelinePostCreateView.css";
-import classNames from "classnames";
-
-interface TimelinePostEditTextProps {
- text: string;
- disabled: boolean;
- onChange: (text: string) => void;
- className?: string;
-}
-
-function TimelinePostEditText(props: TimelinePostEditTextProps) {
- const { text, disabled, onChange, className } = props;
-
- return (
- <textarea
- value={text}
- disabled={disabled}
- onChange={(event) => {
- onChange(event.target.value);
- }}
- className={classNames("timeline-post-create-edit-text", className)}
- />
- );
-}
-
-interface TimelinePostEditImageProps {
- onSelect: (file: File | null) => void;
- disabled: boolean;
-}
-
-function TimelinePostEditImage(props: TimelinePostEditImageProps) {
- const { onSelect, disabled } = props;
+import PlainTextPostEdit from './PlainTextPostEdit'
+import MarkdownPostEdit from "./MarkdownPostEdit";
- const { t } = useTranslation();
+import "./TimelinePostCreateView.css";
- const [file, setFile] = useState<File | null>(null);
- const [error, setError] = useState<boolean>(false);
- const onInputChange: ChangeEventHandler<HTMLInputElement> = (e) => {
- setError(false);
- const files = e.target.files;
- if (files == null || files.length === 0) {
- setFile(null);
- onSelect(null);
- } else {
- setFile(files[0]);
- }
- };
- useEffect(() => {
- return () => {
- onSelect(null);
- };
- }, [onSelect]);
- return (
- <>
- <input
- type="file"
- onChange={onInputChange}
- accept="image/*"
- disabled={disabled}
- className="mx-3 my-1"
- />
- {file != null && !error && (
- <BlobImage
- src={file}
- className="timeline-post-create-image"
- onLoad={() => onSelect(file)}
- onError={() => {
- onSelect(null);
- setError(true);
- }}
- />
- )}
- {error ? <div className="text-danger">{t("loadImageError")}</div> : null}
- </>
- );
-}
type PostKind = "text" | "markdown" | "image";
@@ -212,7 +140,7 @@ function TimelinePostEdit(props: TimelinePostEditProps) {
{(() => {
if (kind === "text") {
return (
- <TimelinePostEditText
+ <PlainTextPostEdit
className="timeline-post-create-edit-text"
text={text}
disabled={process}