From 6f0bbfd56758af305c9dcbb9e4b2b09b8e207ece Mon Sep 17 00:00:00 2001 From: crupest Date: Thu, 1 Oct 2020 23:23:24 +0800 Subject: ... --- Timeline/ClientApp/.vscode/extensions.json | 3 +- .../src/app/views/timeline-common/CollapseCard.tsx | 28 +++++++++ .../app/views/timeline-common/InfoCardTemplate.tsx | 8 +-- .../timeline-common/TimelinePageTemplateUI.tsx | 67 +++++++++++++--------- .../src/app/views/timeline-common/TimelineTop.tsx | 18 ++++++ .../app/views/timeline-common/timeline-common.sass | 27 +++++---- .../src/app/views/timeline/TimelineInfoCard.tsx | 10 +--- .../ClientApp/src/app/views/user/UserInfoCard.tsx | 10 +--- 8 files changed, 110 insertions(+), 61 deletions(-) create mode 100644 Timeline/ClientApp/src/app/views/timeline-common/CollapseCard.tsx create mode 100644 Timeline/ClientApp/src/app/views/timeline-common/TimelineTop.tsx 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 ( +
+
+ + +
+
+ ); +}; + +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 (
- +
-
{children}
+
{children}
); }; 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 { onManage?: (item: TManageItems | "property") => void; onMember: () => void; className?: string; - collapse: boolean; syncStatus: TimelineSyncStatus; toggleCollapse: () => void; } @@ -128,15 +129,26 @@ export default function TimelinePageTemplateUI( const cardCollapseLocalStorageKey = timeline != null ? genCardCollapseLocalStorageKey(timeline.uniqueId) : null; - const [infoCardCollapse, setInfoCardCollapse] = React.useState(true); + const [cardCollapse, setCardCollapse] = React.useState(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( body = ( <> -
- { - const newState = !infoCardCollapse; - setInfoCardCollapse(newState); - if (timeline != null) { - window.localStorage.setItem( - genCardCollapseLocalStorageKey(timeline.uniqueId), - newState.toString() - ); - } - }} - /> -
+ +
+ + +
+
{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 = ({ children }) => { + return ( +
+
+
+
+ {children} +
+ ); +}; + +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 = (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 = (props) => {

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 = (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 = (props) => {
-- cgit v1.2.3