From 4d17746be0daff8f566ec102d4d119321cda8c53 Mon Sep 17 00:00:00 2001 From: crupest Date: Fri, 31 Jul 2020 00:57:22 +0800 Subject: Add sync state badge. --- .../ClientApp/src/app/locales/en/translation.ts | 5 ++ Timeline/ClientApp/src/app/locales/scheme.ts | 5 ++ .../ClientApp/src/app/locales/zh/translation.ts | 5 ++ Timeline/ClientApp/src/app/timeline/Timeline.tsx | 5 +- .../src/app/timeline/TimelinePageTemplateUI.tsx | 66 +++++++++++++++++++--- .../ClientApp/src/app/timeline/timeline-ui.sass | 18 ++++++ Timeline/ClientApp/src/app/timeline/timeline.sass | 6 ++ 7 files changed, 98 insertions(+), 12 deletions(-) (limited to 'Timeline/ClientApp/src') diff --git a/Timeline/ClientApp/src/app/locales/en/translation.ts b/Timeline/ClientApp/src/app/locales/en/translation.ts index 6abe910e..2f8fb312 100644 --- a/Timeline/ClientApp/src/app/locales/en/translation.ts +++ b/Timeline/ClientApp/src/app/locales/en/translation.ts @@ -92,6 +92,11 @@ const translation: TranslationResource = { 'This is a dangerous action. If you are sure to delete timeline<1>{{name}}, please input its name below and click confirm button.', notMatch: 'Name does not match.', }, + postSyncState: { + syncing: 'Syncing', + synced: 'Synced', + offline: 'Offline', + }, post: { deleteDialog: { title: 'Confirm Delete', diff --git a/Timeline/ClientApp/src/app/locales/scheme.ts b/Timeline/ClientApp/src/app/locales/scheme.ts index 19ac6c31..7aa7e125 100644 --- a/Timeline/ClientApp/src/app/locales/scheme.ts +++ b/Timeline/ClientApp/src/app/locales/scheme.ts @@ -83,6 +83,11 @@ export default interface TranslationResource { inputPrompt: string; notMatch: string; }; + postSyncState: { + syncing: string; + synced: string; + offline: string; + }; post: { deleteDialog: { title: string; diff --git a/Timeline/ClientApp/src/app/locales/zh/translation.ts b/Timeline/ClientApp/src/app/locales/zh/translation.ts index 372979c0..35cfa38c 100644 --- a/Timeline/ClientApp/src/app/locales/zh/translation.ts +++ b/Timeline/ClientApp/src/app/locales/zh/translation.ts @@ -88,6 +88,11 @@ const translation: TranslationResource = { '这是一个危险的操作。如果您确认要删除时间线<1>{{name}},请在下面输入它的名字并点击确认。', notMatch: '名字不匹配', }, + postSyncState: { + syncing: '同步中', + synced: '同步成功', + offline: '离线', + }, post: { deleteDialog: { title: '确认删除', diff --git a/Timeline/ClientApp/src/app/timeline/Timeline.tsx b/Timeline/ClientApp/src/app/timeline/Timeline.tsx index 849933cf..7c3a93fb 100644 --- a/Timeline/ClientApp/src/app/timeline/Timeline.tsx +++ b/Timeline/ClientApp/src/app/timeline/Timeline.tsx @@ -53,10 +53,7 @@ const Timeline: React.FC = (props) => { return (
{(() => { diff --git a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx index 3c8e312c..0d8ad278 100644 --- a/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx +++ b/Timeline/ClientApp/src/app/timeline/TimelinePageTemplateUI.tsx @@ -8,7 +8,7 @@ import arrowsAngleContractIcon from 'bootstrap-icons/icons/arrows-angle-contract import arrowsAngleExpandIcon from 'bootstrap-icons/icons/arrows-angle-expand.svg'; import { getAlertHost } from '../common/alert-service'; -import { useEventEmiiter } from '../common'; +import { useEventEmiiter, UiLogicError } from '../common'; import { TimelineInfo, TimelinePostListState, @@ -23,6 +23,53 @@ import Timeline, { import AppBar from '../common/AppBar'; import TimelinePostEdit, { TimelinePostSendCallback } from './TimelinePostEdit'; +const TimelinePostSyncStateBadge: React.FC<{ + state: 'syncing' | 'synced' | 'offline'; +}> = ({ state }) => { + const { t } = useTranslation(); + + return ( +
+ {(() => { + switch (state) { + case 'syncing': { + return ( + <> + + + {t('timeline.postSyncState.syncing')} + + + ); + } + case 'synced': { + return ( + <> + + + {t('timeline.postSyncState.synced')} + + + ); + } + case 'offline': { + return ( + <> + + + {t('timeline.postSyncState.offline')} + + + ); + } + default: + throw new UiLogicError('Unknown sync state.'); + } + })()} +
+ ); +}; + export interface TimelineCardComponentProps { timeline: TimelineInfo; onManage?: (item: TManageItems | 'property') => void; @@ -147,7 +194,7 @@ export default function TimelinePageTemplateUI( } else { if (timeline != null) { let timelineBody: React.ReactElement; - if (postListState != null) { + if (postListState != null && postListState.state !== 'loading') { if (postListState.state === 'forbid') { timelineBody = (

{t('timeline.messageCantSee')}

@@ -165,12 +212,15 @@ export default function TimelinePageTemplateUI( ); timelineBody = ( - +
+ + +
); if (props.onPost != null) { timelineBody = ( diff --git a/Timeline/ClientApp/src/app/timeline/timeline-ui.sass b/Timeline/ClientApp/src/app/timeline/timeline-ui.sass index b92327bd..952e4659 100644 --- a/Timeline/ClientApp/src/app/timeline/timeline-ui.sass +++ b/Timeline/ClientApp/src/app/timeline/timeline-ui.sass @@ -16,3 +16,21 @@ .timeline-page-top-space transition: height 0.5s +.timeline-sync-state-badge + position: absolute + top: 0 + right: 0 + z-index: 1 + font-size: 0.8em + margin-top: 4px + padding: 3px 8px + border-radius: 5px + background: #e8fbff + +.timeline-sync-state-badge-pin + display: inline-block + width: 0.4em + height: 0.4em + border-radius: 50% + vertical-align: middle + margin-right: 0.6em diff --git a/Timeline/ClientApp/src/app/timeline/timeline.sass b/Timeline/ClientApp/src/app/timeline/timeline.sass index 4f69295b..b224e973 100644 --- a/Timeline/ClientApp/src/app/timeline/timeline.sass +++ b/Timeline/ClientApp/src/app/timeline/timeline.sass @@ -1,5 +1,11 @@ @use 'sass:color' +.timeline + display: flex + flex-direction: column + z-index: 0 + position: relative + @keyframes timeline-enter-animation-mask-animation to height: 0 -- cgit v1.2.3