From f137daaf3ca4948f4eb99d407eda08142b9392d0 Mon Sep 17 00:00:00 2001 From: mydearxym Date: Sun, 28 Nov 2021 14:42:26 +0800 Subject: [PATCH] feat(status): add global realtime visitors --- .../CommunityDigest/ClassicLayout/index.tsx | 3 ++ .../digest/CommunityDigest/index.tsx | 2 + .../digest/CommunityDigest/store.ts | 4 ++ src/containers/thread/ArticlesThread/logic.ts | 2 +- src/containers/unit/Footer/logic.ts | 26 ++++++++++-- src/containers/unit/Footer/schema.ts | 15 +++++++ src/containers/unit/Footer/store.ts | 2 + .../CommunityStatesPad/NumberGroup.tsx | 10 +++-- src/widgets/CommunityStatesPad/index.tsx | 42 +++++++++++++------ .../CommunityStatesPad/styles/index.ts | 4 ++ .../CommunityStatesPad/styles/number_group.ts | 4 +- 11 files changed, 93 insertions(+), 21 deletions(-) create mode 100644 src/containers/unit/Footer/schema.ts diff --git a/src/containers/digest/CommunityDigest/ClassicLayout/index.tsx b/src/containers/digest/CommunityDigest/ClassicLayout/index.tsx index 8a95a2fe6..01d117fa9 100644 --- a/src/containers/digest/CommunityDigest/ClassicLayout/index.tsx +++ b/src/containers/digest/CommunityDigest/ClassicLayout/index.tsx @@ -27,6 +27,7 @@ const NON_STANDARD_COMMUNITIES = [HCN, 'feedback'] type TProps = { community: TCommunity + realtimeVisitors: number descExpand: boolean activeThread: TThread layout: TC11NLayout @@ -35,6 +36,7 @@ type TProps = { const ClassicLayout: FC = ({ community, + realtimeVisitors, descExpand, activeThread, layout, @@ -62,6 +64,7 @@ const ClassicLayout: FC = ({ community={community} onShowEditorList={onShowEditorList} onShowSubscriberList={onShowSubscriberList} + realtimeVisitors={realtimeVisitors} /> diff --git a/src/containers/digest/CommunityDigest/index.tsx b/src/containers/digest/CommunityDigest/index.tsx index 55ffe6ace..b598444a0 100755 --- a/src/containers/digest/CommunityDigest/index.tsx +++ b/src/containers/digest/CommunityDigest/index.tsx @@ -33,6 +33,7 @@ const CommunityDigestContainer: FC = ({ accountInfo: { customization: { bannerLayout }, }, + realtimeVisitors, curThread, curCommunity, descExpand, @@ -41,6 +42,7 @@ const CommunityDigestContainer: FC = ({ return ( useEffect(() => { store = _store sub$ = sr71$.data().subscribe($solver(DataSolver, ErrSolver)) - console.log('### see me client side?: ', store.isEmpty) + if (store.isEmpty) loadArticles() return () => { diff --git a/src/containers/unit/Footer/logic.ts b/src/containers/unit/Footer/logic.ts index 75b69fbfc..3ba1f0f41 100755 --- a/src/containers/unit/Footer/logic.ts +++ b/src/containers/unit/Footer/logic.ts @@ -1,19 +1,20 @@ import { useEffect } from 'react' import type { TMetric } from '@/spec' -import { EVENT, PAYMENT_USAGE } from '@/constant' +import { EVENT } from '@/constant' import asyncSuit from '@/utils/async' import { send } from '@/utils/helper' import { buildLog } from '@/utils/logger' -// import S from './schema' +import uid from '@/utils/uid' +import S from './schema' import type { TStore } from './store' /* eslint-disable-next-line */ const log = buildLog('L:Footer2') -const { SR71, $solver } = asyncSuit +const { SR71, $solver, asyncRes } = asyncSuit const sr71$ = new SR71() let sub$ = null @@ -25,11 +26,27 @@ export const toggleSponsorHelper = (): void => export const onLogin = (): void => store.authWarning({ hideToast: true }) export const queryDoraemon = (data): void => send(EVENT.QUERY_DORAMON, { data }) +const getOnlineStatus = (): void => { + sr71$.query(S.onlineStatus, { freshkey: uid.gen() }) + + setInterval(() => { + sr71$.query(S.onlineStatus, { freshkey: uid.gen() }) + }, 10000) +} + // ############################### // Data & Error handlers // ############################### -const DataSolver = [] +const DataSolver = [ + { + match: asyncRes('onlineStatus'), + action: ({ onlineStatus }): void => { + const { realtimeVisitors } = onlineStatus + store.mark({ realtimeVisitors }) + }, + }, +] const ErrSolver = [] // ############################### @@ -40,6 +57,7 @@ export const useInit = (_store: TStore, metric: TMetric): void => { store = _store store.mark({ metric }) sub$ = sr71$.data().subscribe($solver(DataSolver, ErrSolver)) + getOnlineStatus() return () => { sub$.unsubscribe() diff --git a/src/containers/unit/Footer/schema.ts b/src/containers/unit/Footer/schema.ts new file mode 100644 index 000000000..ef46a58bd --- /dev/null +++ b/src/containers/unit/Footer/schema.ts @@ -0,0 +1,15 @@ +import { gql } from '@urql/core' + +const onlineStatus = gql` + query ($freshkey: String) { + onlineStatus(freshkey: $freshkey) { + realtimeVisitors + } + } +` + +const schema = { + onlineStatus, +} + +export default schema diff --git a/src/containers/unit/Footer/store.ts b/src/containers/unit/Footer/store.ts index 67edaa350..074ae0850 100755 --- a/src/containers/unit/Footer/store.ts +++ b/src/containers/unit/Footer/store.ts @@ -14,6 +14,8 @@ import { markStates, toJS } from '@/utils/mobx' const FooterStore = T.model('FooterStore', { showSponsor: T.optional(T.boolean, false), metric: T.optional(T.string, METRIC.COMMUNITY), + // online-status + realtimeVisitors: T.optional(T.number, 1), }) .views((self) => ({ get isLogin(): boolean { diff --git a/src/widgets/CommunityStatesPad/NumberGroup.tsx b/src/widgets/CommunityStatesPad/NumberGroup.tsx index 737055130..8aad9874c 100644 --- a/src/widgets/CommunityStatesPad/NumberGroup.tsx +++ b/src/widgets/CommunityStatesPad/NumberGroup.tsx @@ -2,12 +2,14 @@ import { FC, memo } from 'react' import { prettyNum } from '@/utils/helper' import { buildLog } from '@/utils/logger' +import AnimatedCount from '@/widgets/AnimatedCount' import { Wrapper, NumberItem, LargeNumberItem, SubNumberWrapper, + SubNum, GreenDot, PlusSign, } from './styles/number_group' @@ -32,7 +34,7 @@ const NumberGroup: FC = ({ }) => { return ( - {subCount ? ( + {subCount >= 0 ? ( {prettyNum(count)} @@ -42,11 +44,13 @@ const NumberGroup: FC = ({ )} - {subCount && ( + {subCount >= 0 && ( {subPrefix === 'online' && } {subPrefix === 'add' && +} - {subCount} + + + )} diff --git a/src/widgets/CommunityStatesPad/index.tsx b/src/widgets/CommunityStatesPad/index.tsx index 5eb7313a8..687f7813a 100755 --- a/src/widgets/CommunityStatesPad/index.tsx +++ b/src/widgets/CommunityStatesPad/index.tsx @@ -9,6 +9,8 @@ import { FC, memo } from 'react' import type { TCommunity } from '@/spec' import usePlatform from '@/hooks/usePlatform' import { buildLog } from '@/utils/logger' +import { getRandomInt } from '@/utils/helper' +import Tooltip from '@/widgets/Tooltip' import Charger from '@/widgets/Charger' @@ -22,6 +24,7 @@ import { ChargeSection, NumberDivider, NumberTitle, + PopHint, } from './styles' /* eslint-disable-next-line */ @@ -29,6 +32,7 @@ const log = buildLog('c:CommunityStatesPad:index') type TProps = { community: TCommunity + realtimeVisitors?: number withoutFounding?: boolean onShowEditorList?: () => void onShowSubscriberList?: () => void @@ -36,6 +40,7 @@ type TProps = { const CommunityStatesPad: FC = ({ community, + realtimeVisitors = 1, onShowEditorList = log, onShowSubscriberList = log, withoutFounding = true, @@ -48,22 +53,35 @@ const CommunityStatesPad: FC = ({ {!isMobile && 成员} - + + 实时在线人数,后续会单独统计每个子社区的实时在线人数。 + + } + placement="bottom" + > + + 内容 - + 较前一天新增内容,功能开发中} + placement="bottom" + > + + diff --git a/src/widgets/CommunityStatesPad/styles/index.ts b/src/widgets/CommunityStatesPad/styles/index.ts index 20879a27f..f621b0e5b 100755 --- a/src/widgets/CommunityStatesPad/styles/index.ts +++ b/src/widgets/CommunityStatesPad/styles/index.ts @@ -54,3 +54,7 @@ export const NumberDivider = styled.div` `}; ${css.media.mobile`display: none`}; ` + +export const PopHint = styled.div` + width: 200px; +` diff --git a/src/widgets/CommunityStatesPad/styles/number_group.ts b/src/widgets/CommunityStatesPad/styles/number_group.ts index 4e576b53b..37acbcdb4 100644 --- a/src/widgets/CommunityStatesPad/styles/number_group.ts +++ b/src/widgets/CommunityStatesPad/styles/number_group.ts @@ -11,9 +11,11 @@ export const SubNumberWrapper = styled.div` ${css.flex('align-center')}; color: ${theme('banner.numberDesc')}; font-size: 13px; - margin-right: 0.5px; margin-top: -1px; ` +export const SubNum = styled.div` + opacity: 0.6; +` export const GreenDot = styled.div` background: ${theme('baseColor.green')}; width: 5px;