aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2020-10-01 23:23:24 +0800
committercrupest <crupest@outlook.com>2020-10-01 23:23:24 +0800
commitd8245fa9703c532dac85980f0c25cae0a1f9e0dc (patch)
tree48ca91263756d685afa598ba4c2392f884be50c9
parent0b353ca6f3e540eb4850ac6121a0c678c6cbd17b (diff)
downloadtimeline-d8245fa9703c532dac85980f0c25cae0a1f9e0dc.tar.gz
timeline-d8245fa9703c532dac85980f0c25cae0a1f9e0dc.tar.bz2
timeline-d8245fa9703c532dac85980f0c25cae0a1f9e0dc.zip
...
-rw-r--r--Timeline/ClientApp/.vscode/extensions.json3
-rw-r--r--Timeline/ClientApp/src/app/views/timeline-common/CollapseCard.tsx28
-rw-r--r--Timeline/ClientApp/src/app/views/timeline-common/InfoCardTemplate.tsx8
-rw-r--r--Timeline/ClientApp/src/app/views/timeline-common/TimelinePageTemplateUI.tsx67
-rw-r--r--Timeline/ClientApp/src/app/views/timeline-common/TimelineTop.tsx18
-rw-r--r--Timeline/ClientApp/src/app/views/timeline-common/timeline-common.sass27
-rw-r--r--Timeline/ClientApp/src/app/views/timeline/TimelineInfoCard.tsx10
-rw-r--r--Timeline/ClientApp/src/app/views/user/UserInfoCard.tsx10
8 files changed, 110 insertions, 61 deletions
diff --git a/Timeline/ClientApp/.vscode/extensions.json b/Timeline/ClientApp/.vscode/extensions.json
index 7d55bb42..be640996 100644
--- a/Timeline/ClientApp/.vscode/extensions.json
+++ b/Timeline/ClientApp/.vscode/extensions.json
@@ -3,6 +3,7 @@
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"arcanis.vscode-zipfs",
- "syler.sass-indented"
+ "syler.sass-indented",
+ "editorconfig.editorconfig"
]
}
diff --git a/Timeline/ClientApp/src/app/views/timeline-common/CollapseCard.tsx b/Timeline/ClientApp/src/app/views/timeline-common/CollapseCard.tsx
new file mode 100644
index 00000000..1c233058
--- /dev/null
+++ b/Timeline/ClientApp/src/app/views/timeline-common/CollapseCard.tsx
@@ -0,0 +1,28 @@
+import React from "react";
+import clsx from "clsx";
+
+import SyncStatusBadge, {
+ TimelineSyncStatus,
+} from "../timeline-common/SyncStatusBadge";
+import CollapseButton from "../timeline-common/CollapseButton";
+
+const CollapseCard: React.FC<{
+ className?: string;
+ syncStatus: TimelineSyncStatus;
+ toggleCollapse: () => void;
+ visible: boolean;
+}> = ({ className, syncStatus, toggleCollapse, visible }) => {
+ return (
+ <div
+ style={{ visibility: visible ? "visible" : "hidden" }}
+ className={clsx("cru-card p-2", className)}
+ >
+ <div className="d-flex align-items-center">
+ <SyncStatusBadge status={syncStatus} className="mr-2" />
+ <CollapseButton collapse onClick={toggleCollapse} />
+ </div>
+ </div>
+ );
+};
+
+export default CollapseCard;
diff --git a/Timeline/ClientApp/src/app/views/timeline-common/InfoCardTemplate.tsx b/Timeline/ClientApp/src/app/views/timeline-common/InfoCardTemplate.tsx
index a8de20aa..a5166aa4 100644
--- a/Timeline/ClientApp/src/app/views/timeline-common/InfoCardTemplate.tsx
+++ b/Timeline/ClientApp/src/app/views/timeline-common/InfoCardTemplate.tsx
@@ -8,17 +8,17 @@ import CollapseButton from "../timeline-common/CollapseButton";
const InfoCardTemplate: React.FC<
Pick<
TimelineCardComponentProps<"">,
- "collapse" | "toggleCollapse" | "syncStatus" | "className"
+ "toggleCollapse" | "syncStatus" | "className"
> & { children: React.ReactElement[] }
-> = ({ collapse, toggleCollapse, syncStatus, className, children }) => {
+> = ({ toggleCollapse, syncStatus, className, children }) => {
return (
<div className={clsx("cru-card p-2 clearfix", className)}>
<div className="float-right d-flex align-items-center">
<SyncStatusBadge status={syncStatus} className="mr-2" />
- <CollapseButton collapse={collapse} onClick={toggleCollapse} />
+ <CollapseButton collapse={false} onClick={toggleCollapse} />
</div>
- <div style={{ display: collapse ? "none" : "block" }}>{children}</div>
+ <div>{children}</div>
</div>
);
};
diff --git a/Timeline/ClientApp/src/app/views/timeline-common/TimelinePageTemplateUI.tsx b/Timeline/ClientApp/src/app/views/timeline-common/TimelinePageTemplateUI.tsx
index 58fd024b..ef13fa50 100644
--- a/Timeline/ClientApp/src/app/views/timeline-common/TimelinePageTemplateUI.tsx
+++ b/Timeline/ClientApp/src/app/views/timeline-common/TimelinePageTemplateUI.tsx
@@ -16,6 +16,8 @@ import Timeline, {
TimelinePostInfoEx,
TimelineDeleteCallback,
} from "./Timeline";
+import TimelineTop from "./TimelineTop";
+import CollapseCard from "./CollapseCard";
import TimelinePostEdit, { TimelinePostSendCallback } from "./TimelinePostEdit";
import { TimelineSyncStatus } from "./SyncStatusBadge";
import clsx from "clsx";
@@ -25,7 +27,6 @@ export interface TimelineCardComponentProps<TManageItems> {
onManage?: (item: TManageItems | "property") => void;
onMember: () => void;
className?: string;
- collapse: boolean;
syncStatus: TimelineSyncStatus;
toggleCollapse: () => void;
}
@@ -128,15 +129,26 @@ export default function TimelinePageTemplateUI<TManageItems>(
const cardCollapseLocalStorageKey =
timeline != null ? genCardCollapseLocalStorageKey(timeline.uniqueId) : null;
- const [infoCardCollapse, setInfoCardCollapse] = React.useState<boolean>(true);
+ const [cardCollapse, setCardCollapse] = React.useState<boolean>(true);
React.useEffect(() => {
if (cardCollapseLocalStorageKey != null) {
const savedCollapse =
window.localStorage.getItem(cardCollapseLocalStorageKey) === "true";
- setInfoCardCollapse(savedCollapse);
+ setCardCollapse(savedCollapse);
}
}, [cardCollapseLocalStorageKey]);
+ const toggleCardCollapse = (): void => {
+ const newState = !cardCollapse;
+ setCardCollapse(newState);
+ if (timeline != null) {
+ window.localStorage.setItem(
+ genCardCollapseLocalStorageKey(timeline.uniqueId),
+ newState.toString()
+ );
+ }
+ };
+
let body: React.ReactElement;
if (props.error != null) {
@@ -207,30 +219,31 @@ export default function TimelinePageTemplateUI<TManageItems>(
body = (
<>
- <div
- className={clsx(
- "timeline-template-info-card",
- infoCardCollapse && "my-collapse"
- )}
- >
- <CardComponent
- timeline={timeline}
- onManage={props.onManage}
- onMember={props.onMember}
- syncStatus={syncStatus}
- collapse={infoCardCollapse}
- toggleCollapse={() => {
- const newState = !infoCardCollapse;
- setInfoCardCollapse(newState);
- if (timeline != null) {
- window.localStorage.setItem(
- genCardCollapseLocalStorageKey(timeline.uniqueId),
- newState.toString()
- );
- }
- }}
- />
- </div>
+ <TimelineTop>
+ <div
+ className={clsx(
+ "timeline-template-card-container",
+ cardCollapse || "my-expand"
+ )}
+ >
+ <CollapseCard
+ visible={cardCollapse}
+ syncStatus={syncStatus}
+ toggleCollapse={toggleCardCollapse}
+ />
+ <CardComponent
+ className={clsx(
+ "timeline-template-card",
+ cardCollapse && "d-none"
+ )}
+ timeline={timeline}
+ onManage={props.onManage}
+ onMember={props.onMember}
+ syncStatus={syncStatus}
+ toggleCollapse={toggleCardCollapse}
+ />
+ </div>
+ </TimelineTop>
{timelineBody}
</>
);
diff --git a/Timeline/ClientApp/src/app/views/timeline-common/TimelineTop.tsx b/Timeline/ClientApp/src/app/views/timeline-common/TimelineTop.tsx
new file mode 100644
index 00000000..a98d3687
--- /dev/null
+++ b/Timeline/ClientApp/src/app/views/timeline-common/TimelineTop.tsx
@@ -0,0 +1,18 @@
+import React from "react";
+
+export interface TimelineTopProps {
+ children: React.ReactElement;
+}
+
+const TimelineTop: React.FC<TimelineTopProps> = ({ children }) => {
+ return (
+ <div className="timeline-top">
+ <div className="timeline-line-area">
+ <div className="timeline-line-segment"></div>
+ </div>
+ {children}
+ </div>
+ );
+};
+
+export default TimelineTop;
diff --git a/Timeline/ClientApp/src/app/views/timeline-common/timeline-common.sass b/Timeline/ClientApp/src/app/views/timeline-common/timeline-common.sass
index 79df9249..aa3544fe 100644
--- a/Timeline/ClientApp/src/app/views/timeline-common/timeline-common.sass
+++ b/Timeline/ClientApp/src/app/views/timeline-common/timeline-common.sass
@@ -70,6 +70,13 @@ $timeline-line-color-current: #36c2e6
animation: 1s infinite alternate
animation-name: timeline-line-node-noncurrent
+.timeline-top
+ display: flex
+ justify-content: space-between
+
+ .timeline-line-segment
+ flex: 1 1 auto
+
.current
.timeline-line
&-segment
@@ -84,7 +91,7 @@ $timeline-line-color-current: #36c2e6
animation-name: timeline-line-node-current
.timeline-content-area
- padding-top: 18px
+ padding: 10px 0
flex-grow: 1
.timeline-item-delete-button
@@ -124,17 +131,15 @@ $timeline-line-color-current: #36c2e6
vertical-align: middle
margin-right: 0.6em
-.timeline-template-info-card
+.timeline-template-card-container
position: sticky
z-index: 1
top: 56px
- padding: 0.5em
-
- @include media-breakpoint-down(sm)
- padding-bottom: 0
+ margin: 0.5em
- &.my-collapse
- float: right
-
- @include media-breakpoint-up(sm)
- float: right
+.timeline-template-card
+ width: 360px
+ max-width: calc(100vw - 1em)
+ position: absolute
+ top: 0
+ right: 0
diff --git a/Timeline/ClientApp/src/app/views/timeline/TimelineInfoCard.tsx b/Timeline/ClientApp/src/app/views/timeline/TimelineInfoCard.tsx
index d764a275..6966ab41 100644
--- a/Timeline/ClientApp/src/app/views/timeline/TimelineInfoCard.tsx
+++ b/Timeline/ClientApp/src/app/views/timeline/TimelineInfoCard.tsx
@@ -16,14 +16,7 @@ export type TimelineInfoCardProps = TimelineCardComponentProps<
>;
const TimelineInfoCard: React.FC<TimelineInfoCardProps> = (props) => {
- const {
- timeline,
- onMember,
- onManage,
- collapse,
- syncStatus,
- toggleCollapse,
- } = props;
+ const { timeline, onMember, onManage, syncStatus, toggleCollapse } = props;
const { t } = useTranslation();
@@ -33,7 +26,6 @@ const TimelineInfoCard: React.FC<TimelineInfoCardProps> = (props) => {
<InfoCardTemplate
className={props.className}
syncStatus={syncStatus}
- collapse={collapse}
toggleCollapse={toggleCollapse}
>
<h3 className="text-primary mx-3 d-inline-block align-middle">
diff --git a/Timeline/ClientApp/src/app/views/user/UserInfoCard.tsx b/Timeline/ClientApp/src/app/views/user/UserInfoCard.tsx
index 4cf11e62..bad2a9e1 100644
--- a/Timeline/ClientApp/src/app/views/user/UserInfoCard.tsx
+++ b/Timeline/ClientApp/src/app/views/user/UserInfoCard.tsx
@@ -16,14 +16,7 @@ export type UserInfoCardProps = TimelineCardComponentProps<
>;
const UserInfoCard: React.FC<UserInfoCardProps> = (props) => {
- const {
- timeline,
- onMember,
- onManage,
- syncStatus,
- collapse,
- toggleCollapse,
- } = props;
+ const { timeline, onMember, onManage, syncStatus, toggleCollapse } = props;
const { t } = useTranslation();
const avatar = useAvatar(timeline?.owner?.username);
@@ -32,7 +25,6 @@ const UserInfoCard: React.FC<UserInfoCardProps> = (props) => {
<InfoCardTemplate
className={props.className}
syncStatus={syncStatus}
- collapse={collapse}
toggleCollapse={toggleCollapse}
>
<div>