diff --git a/src/components/CommunityStatesPad/SubscribedTitle.js b/src/components/CommunityStatesPad/SubscribedTitle.js
index 00ef240c4..79d2f1c5f 100755
--- a/src/components/CommunityStatesPad/SubscribedTitle.js
+++ b/src/components/CommunityStatesPad/SubscribedTitle.js
@@ -1,55 +1,15 @@
import React from 'react'
-// import { ICON_CMD } from '@/config'
-// import { Wrapper } from './styles'
-import Tooltip from '@/components/Tooltip'
import { NumberTitle } from './styles'
-import { PopoverInfo, PopTitle, PopDesc } from './styles/subscribed_title'
-const SubscribedBtn = ({ community, onUndoSubscribe }) => {
- if (community.raw === 'home') {
- return (
-
- 已加入
-
- )
- }
-
- return (
-
- 点击可退出
- 退出后该社区将不会出现在你的左侧列表中
-
- }
- >
- onUndoSubscribe(community)} small>
- 已加入
-
-
- )
-}
-
-const SubscribedTitle = ({ community, onSubscribe, onUndoSubscribe }) => (
- <>
- {community.viewerHasSubscribed ? (
-
+const SubscribedTitle = ({ viewerHasSubscribed }) => (
+
+ {viewerHasSubscribed ? (
+ 已加入
) : (
-
- 点击加入
- 加入后该社区将会出现在你的左侧列表中
-
- }
- >
- onSubscribe(community)}>加入
-
+ 加入
)}
- >
+
)
export default React.memo(SubscribedTitle)
diff --git a/src/components/CommunityStatesPad/index.js b/src/components/CommunityStatesPad/index.js
index 4ae7655ec..e4507e2cf 100755
--- a/src/components/CommunityStatesPad/index.js
+++ b/src/components/CommunityStatesPad/index.js
@@ -29,8 +29,6 @@ const log = buildLog('c:CommunityStatesPad:index')
const CommunityStatesPad = ({
community,
- onSubscribe,
- onUndoSubscribe,
onShowEditorList,
onShowSubscriberList,
withoutFounding,
@@ -52,11 +50,7 @@ const CommunityStatesPad = ({
{!isMobile && (
-
+
)}
@@ -116,6 +114,10 @@ const ColumnView = ({
+ setViewport(true)}
+ onLeave={() => setViewport(false)}
+ />
)
}
diff --git a/src/containers/digest/CommunityDigest/DigestView/RowView/index.js b/src/containers/digest/CommunityDigest/DigestView/RowView/index.js
index 1627f6a52..aa7fc29e8 100644
--- a/src/containers/digest/CommunityDigest/DigestView/RowView/index.js
+++ b/src/containers/digest/CommunityDigest/DigestView/RowView/index.js
@@ -40,8 +40,6 @@ import {
import { tabOnChange } from '../../logic'
// import {
-// onSubscribe,
-// onUndoSubscribe,
// onShowEditorList,
// onShowSubscriberList,
// } from '../../logic'
diff --git a/src/containers/digest/CommunityDigest/logic.js b/src/containers/digest/CommunityDigest/logic.js
index 7a7be7674..1a59c69a1 100755
--- a/src/containers/digest/CommunityDigest/logic.js
+++ b/src/containers/digest/CommunityDigest/logic.js
@@ -41,24 +41,6 @@ export const tabOnChange = (activeThread) => {
send(EVENT.THREAD_CHANGE, { data: { activeThread, topic: subPath } })
}
-export const onSubscribe = (community) => {
- if (!store.isLogin) return store.authWarning()
- if (store.subscribeLoading) return false
-
- // log('onSubscribe: ', community)
- store.mark({ subscribeLoading: true })
- sr71$.mutate(S.subscribeCommunity, { communityId: community.id })
-}
-
-export const onUndoSubscribe = (community) => {
- if (!store.isLogin) return store.authWarning()
- if (store.subscribeLoading) return false
-
- // log('onUndoSubscribe: ', community)
- store.mark({ subscribeLoading: true })
- sr71$.mutate(S.unsubscribeCommunity, { communityId: community.id })
-}
-
export const onShowEditorList = () => {
const type = TYPE.USER_LISTER_COMMUNITY_EDITORS
const data = {
@@ -85,8 +67,15 @@ export const toggleDescExpand = () => {
store.mark({ descExpand: !descExpand })
}
-const markLoading = (maybe = true) =>
- store.mark({ loading: maybe, subscribeLoading: maybe })
+const markLoading = (maybe = true) => store.mark({ loading: maybe })
+
+/**
+ * set digest visiable in current viewport
+ * @param {Boolean} inView
+ */
+export const setViewport = (inViewport) => {
+ store.mark({ inViewport })
+}
// ###############################
// Data & Error handlers
diff --git a/src/containers/digest/CommunityDigest/schema.js b/src/containers/digest/CommunityDigest/schema.js
index b26ec3978..d92f97035 100755
--- a/src/containers/digest/CommunityDigest/schema.js
+++ b/src/containers/digest/CommunityDigest/schema.js
@@ -1,34 +1,12 @@
import gql from 'graphql-tag'
-import { P, F } from '@/schemas'
+import { P } from '@/schemas'
const community = gql`
${P.community}
`
-const subscribeCommunity = gql`
- mutation subscribeCommunity($communityId: ID!) {
- subscribeCommunity(communityId: $communityId) {
- ${F.community}
- contributesDigest
- threads {
- title
- raw
- }
- }
- }
-`
-const unsubscribeCommunity = gql`
- mutation unsubscribeCommunity($communityId: ID!) {
- unsubscribeCommunity(communityId: $communityId) {
- id
- }
- }
-`
-
const schema = {
community,
- subscribeCommunity,
- unsubscribeCommunity,
}
export default schema
diff --git a/src/containers/digest/CommunityDigest/store.js b/src/containers/digest/CommunityDigest/store.js
index 1bc96504d..d5ff8ec65 100755
--- a/src/containers/digest/CommunityDigest/store.js
+++ b/src/containers/digest/CommunityDigest/store.js
@@ -13,7 +13,8 @@ const log = buildLog('S:CommunityDigest')
const CommunityDigest = T.model('CommunityDigest', {
loading: T.optional(T.boolean, false),
descExpand: T.optional(T.boolean, false),
- subscribeLoading: T.optional(T.boolean, false),
+
+ inViewport: T.optional(T.boolean, true),
})
.views((self) => ({
get root() {
diff --git a/src/containers/thread/PostsThread/index.js b/src/containers/thread/PostsThread/index.js
index d6a6ef593..7fcf59777 100755
--- a/src/containers/thread/PostsThread/index.js
+++ b/src/containers/thread/PostsThread/index.js
@@ -12,6 +12,7 @@ import { ICON } from '@/config'
import { C11N, THREAD, ROUTE } from '@/constant'
import { pluggedIn, buildLog } from '@/utils'
+import CommunityJoinBadge from '@/containers/tool/CommunityJoinBadge'
import TagsBar from '@/containers/unit/TagsBar'
import Sticky from '@/components/Sticky'
@@ -30,6 +31,7 @@ import {
LeftPart,
RightPart,
FilterWrapper,
+ BadgeWrapper,
PublisherWrapper,
StickyHolder,
} from './styles'
@@ -97,6 +99,7 @@ const PostsThreadContainer = ({ postsThread: store }) => {
accountInfo: {
customization: { bannerLayout },
},
+ isCommunityDigestInViewport,
} = store
const { subPath } = curRoute
@@ -147,7 +150,7 @@ const PostsThreadContainer = ({ postsThread: store }) => {
{bannerLayout === C11N.DIGEST && (
-
+
{
>
{LabelText[subPath] || '发布帖子'}
-
- {/* */}
-
+
+
+
+
({
toastInfo(options) {
diff --git a/src/containers/thread/PostsThread/styles/index.js b/src/containers/thread/PostsThread/styles/index.js
index f1ce5b635..d9163c2ee 100755
--- a/src/containers/thread/PostsThread/styles/index.js
+++ b/src/containers/thread/PostsThread/styles/index.js
@@ -18,15 +18,21 @@ export const LeftPart = styled.div`
`
export const RightPart = styled.div`
min-width: 200px;
+ max-width: 200px;
padding-top: 20px;
margin-left: 40px;
${css.media.tablet`display: none;`};
`
export const PublisherWrapper = styled.div`
+ display: ${({ show }) => (show ? 'block' : 'none')};
width: 160px;
max-width: 180px;
- margin-left: 8%;
+ margin-left: 16px;
+`
+export const BadgeWrapper = styled.div`
+ display: ${({ show }) => (show ? 'block' : 'none')};
+ margin-left: 18px;
`
export const FilterWrapper = styled.div`
${css.flex('align-center')};
diff --git a/src/containers/tool/CommunityJoinBadge/SubscribeBtn.js b/src/containers/tool/CommunityJoinBadge/SubscribeBtn.js
new file mode 100644
index 000000000..73f390a62
--- /dev/null
+++ b/src/containers/tool/CommunityJoinBadge/SubscribeBtn.js
@@ -0,0 +1,53 @@
+import React from 'react'
+
+import Button from '@/components/Buttons/Button'
+
+import { Wrapper, Text } from './styles/subscribe_btn'
+import { onSubscribe, onCancleSubscribe } from './logic'
+
+const SubscribeButton = ({ community, subscribeLoading }) => {
+ const { viewerHasSubscribed } = community
+
+ if (community.raw === 'home') {
+ return (
+
+
+
+ )
+ }
+
+ return (
+
+ {viewerHasSubscribed ? (
+
+ ) : (
+
+ )}
+
+ )
+}
+
+export default SubscribeButton
diff --git a/src/containers/tool/CommunityJoinBadge/index.js b/src/containers/tool/CommunityJoinBadge/index.js
new file mode 100755
index 000000000..3d747fdb5
--- /dev/null
+++ b/src/containers/tool/CommunityJoinBadge/index.js
@@ -0,0 +1,52 @@
+//
+
+/*
+ *
+ * CommunityJoinBadge
+ *
+ */
+
+import React from 'react'
+import T from 'prop-types'
+
+import { pluggedIn, buildLog } from '@/utils'
+
+import SubscribeBtn from './SubscribeBtn'
+
+import { Wrapper, Title, Desc, BottomLine } from './styles'
+import { useInit } from './logic'
+
+/* eslint-disable-next-line */
+const log = buildLog('C:CommunityJoinBadge')
+
+const CommunityJoinBadgeContainer = ({ communityJoinBadge: store, testId }) => {
+ useInit(store)
+
+ const { curCommunity, subscribeLoading } = store
+ const { title, desc } = curCommunity
+
+ return (
+
+ {title}
+ {desc}
+
+
+
+
+
+ )
+}
+
+CommunityJoinBadgeContainer.propTypes = {
+ communityJoinBadge: T.any.isRequired,
+ testId: T.string,
+}
+
+CommunityJoinBadgeContainer.defaultProps = {
+ testId: 'community-join-badge',
+}
+
+export default pluggedIn(CommunityJoinBadgeContainer)
diff --git a/src/containers/tool/CommunityJoinBadge/logic.js b/src/containers/tool/CommunityJoinBadge/logic.js
new file mode 100755
index 000000000..2e72b54aa
--- /dev/null
+++ b/src/containers/tool/CommunityJoinBadge/logic.js
@@ -0,0 +1,120 @@
+import { useEffect } from 'react'
+
+import { EVENT, ERR } from '@/constant'
+import { asyncSuit, buildLog, subPath2Thread, errRescue } from '@/utils'
+
+import S from './schema'
+
+/* eslint-disable-next-line */
+const log = buildLog('L:CommunityJoinBadge')
+
+const { SR71, $solver, asyncRes, asyncErr } = asyncSuit
+const sr71$ = new SR71({ receive: [EVENT.COMMUNITY_CHANGE] })
+
+let sub$ = null
+let store = null
+
+const loadCommunity = () => {
+ const userHasLogin = store.isLogin
+ const { raw } = store.curCommunity
+
+ markLoading(true)
+
+ sr71$.query(S.community, { raw, userHasLogin })
+}
+
+export const onSubscribe = (community) => {
+ if (!store.isLogin) return store.authWarning()
+ if (store.subscribeLoading) return false
+
+ // log('onSubscribe: ', community)
+ store.mark({ subscribeLoading: true })
+ sr71$.mutate(S.subscribeCommunity, { communityId: community.id })
+}
+
+export const onCancleSubscribe = (community) => {
+ if (!store.isLogin) return store.authWarning()
+ if (store.subscribeLoading) return false
+
+ store.mark({ subscribeLoading: true })
+ sr71$.mutate(S.unsubscribeCommunity, { communityId: community.id })
+}
+
+const markLoading = (maybe = true) =>
+ store.mark({ loading: maybe, subscribeLoading: maybe })
+
+// ###############################
+// Data & Error handlers
+// ###############################
+
+const DataSolver = [
+ {
+ match: asyncRes('community'),
+ action: ({ community }) => {
+ markLoading(false)
+ const { subPath } = store.curRoute
+ log('community: ', community)
+ store.setViewing({
+ community,
+ activeThread: subPath2Thread(subPath),
+ })
+ },
+ },
+ {
+ match: asyncRes('subscribeCommunity'),
+ action: ({ subscribeCommunity }) => {
+ store.addSubscribedCommunity(subscribeCommunity)
+ loadCommunity()
+ },
+ },
+ {
+ match: asyncRes('unsubscribeCommunity'),
+ action: ({ unsubscribeCommunity }) => {
+ store.removeSubscribedCommunity(unsubscribeCommunity)
+ loadCommunity()
+ },
+ },
+ {
+ match: asyncRes(EVENT.COMMUNITY_CHANGE),
+ action: () => loadCommunity(),
+ },
+]
+const ErrSolver = [
+ {
+ match: asyncErr(ERR.GRAPHQL),
+ action: () => markLoading(false),
+ },
+ {
+ match: asyncErr(ERR.TIMEOUT),
+ action: ({ details }) => {
+ markLoading(false)
+ errRescue({ type: ERR.TIMEOUT, details, path: 'AccountEditor' })
+ },
+ },
+ {
+ match: asyncErr(ERR.NETWORK),
+ action: () => {
+ markLoading(false)
+ errRescue({ type: ERR.NETWORK, path: 'CommunityDigest' })
+ },
+ },
+]
+
+// ###############################
+// init & uninit
+// ###############################
+export const useInit = (_store) => {
+ useEffect(() => {
+ store = _store
+ // log('effect init')
+ sub$ = sr71$.data().subscribe($solver(DataSolver, ErrSolver))
+
+ return () => {
+ if (sub$ && !store.loading) {
+ sr71$.stop()
+ sub$.unsubscribe()
+ }
+ // log('effect uninit')
+ }
+ }, [_store])
+}
diff --git a/src/containers/tool/CommunityJoinBadge/schema.js b/src/containers/tool/CommunityJoinBadge/schema.js
new file mode 100755
index 000000000..b26ec3978
--- /dev/null
+++ b/src/containers/tool/CommunityJoinBadge/schema.js
@@ -0,0 +1,34 @@
+import gql from 'graphql-tag'
+import { P, F } from '@/schemas'
+
+const community = gql`
+ ${P.community}
+`
+
+const subscribeCommunity = gql`
+ mutation subscribeCommunity($communityId: ID!) {
+ subscribeCommunity(communityId: $communityId) {
+ ${F.community}
+ contributesDigest
+ threads {
+ title
+ raw
+ }
+ }
+ }
+`
+const unsubscribeCommunity = gql`
+ mutation unsubscribeCommunity($communityId: ID!) {
+ unsubscribeCommunity(communityId: $communityId) {
+ id
+ }
+ }
+`
+
+const schema = {
+ community,
+ subscribeCommunity,
+ unsubscribeCommunity,
+}
+
+export default schema
diff --git a/src/containers/tool/CommunityJoinBadge/store.js b/src/containers/tool/CommunityJoinBadge/store.js
new file mode 100755
index 000000000..c7114fa66
--- /dev/null
+++ b/src/containers/tool/CommunityJoinBadge/store.js
@@ -0,0 +1,33 @@
+/*
+ * CommunityJoinBadge store
+ *
+ */
+
+import { types as T, getParent } from 'mobx-state-tree'
+// import {} from 'ramda'
+
+import { markStates, buildLog, stripMobx } from '@/utils'
+/* eslint-disable-next-line */
+const log = buildLog('S:CommunityJoinBadge')
+
+const CommunityJoinBadge = T.model('CommunityJoinBadge', {
+ subscribeLoading: T.optional(T.boolean, false),
+})
+ .views((self) => ({
+ get root() {
+ return getParent(self)
+ },
+ get curCommunity() {
+ return stripMobx(self.root.viewing.community)
+ },
+ }))
+ .actions((self) => ({
+ authWarning(options) {
+ self.root.authWarning(options)
+ },
+ mark(sobj) {
+ markStates(sobj, self)
+ },
+ }))
+
+export default CommunityJoinBadge
diff --git a/src/containers/tool/CommunityJoinBadge/styles/index.js b/src/containers/tool/CommunityJoinBadge/styles/index.js
new file mode 100755
index 000000000..ab12e0d24
--- /dev/null
+++ b/src/containers/tool/CommunityJoinBadge/styles/index.js
@@ -0,0 +1,37 @@
+import styled from 'styled-components'
+
+// import Img from '@/Img'
+import { theme } from '@/utils'
+
+export const Wrapper = styled.div.attrs((props) => ({
+ 'data-test-id': props.testId,
+}))`
+ position: relative;
+ padding-bottom: 20px;
+ padding-left: 3px;
+`
+export const BottomLine = styled.div`
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ width: 65%;
+ height: 1px;
+ background: #014454;
+`
+export const Title = styled.div`
+ font-size: 16px;
+ font-weight: bold;
+ color: ${theme('thread.articleTitle')};
+`
+export const Desc = styled.div`
+ font-size: 12px;
+ color: ${theme('thread.articleDigest')};
+ margin-top: 5px;
+`
+export const BtnWrapper = styled.div`
+ margin-top: 12px;
+ margin-bottom: 5px;
+`
+export const BtnText = styled.div`
+ padding: 2px 5px;
+`
diff --git a/src/containers/tool/CommunityJoinBadge/styles/subscribe_btn.js b/src/containers/tool/CommunityJoinBadge/styles/subscribe_btn.js
new file mode 100644
index 000000000..bb2f40afa
--- /dev/null
+++ b/src/containers/tool/CommunityJoinBadge/styles/subscribe_btn.js
@@ -0,0 +1,11 @@
+import styled from 'styled-components'
+
+// import Img from '@/Img'
+
+export const Wrapper = styled.div`
+ margin-top: 12px;
+ margin-bottom: 5px;
+`
+export const Text = styled.div`
+ padding: 2px 5px;
+`
diff --git a/src/containers/tool/CommunityJoinBadge/tests/index.test.js b/src/containers/tool/CommunityJoinBadge/tests/index.test.js
new file mode 100755
index 000000000..df29e5696
--- /dev/null
+++ b/src/containers/tool/CommunityJoinBadge/tests/index.test.js
@@ -0,0 +1,10 @@
+// import React from 'react'
+// import { shallow } from 'enzyme'
+
+// import CommunityJoinBadge from '../index'
+
+describe('TODO ', () => {
+ it('Expect to have unit tests specified', () => {
+ expect(true).toEqual(true)
+ })
+})
diff --git a/src/containers/tool/CommunityJoinBadge/tests/store.test.js b/src/containers/tool/CommunityJoinBadge/tests/store.test.js
new file mode 100755
index 000000000..38835eca4
--- /dev/null
+++ b/src/containers/tool/CommunityJoinBadge/tests/store.test.js
@@ -0,0 +1,10 @@
+/*
+ * CommunityJoinBadge store test
+ *
+ */
+
+// import CommunityJoinBadge from '../index'
+
+it('TODO: store test CommunityJoinBadge', () => {
+ expect(1 + 1).toBe(2)
+})
diff --git a/src/stores/RootStore/index.js b/src/stores/RootStore/index.js
index 0edbe87d4..cc1a62ab5 100755
--- a/src/stores/RootStore/index.js
+++ b/src/stores/RootStore/index.js
@@ -94,6 +94,7 @@ import {
CoolGuideContentStore,
// GEN: IMPORT SUBSTORE
+ CommunityJoinBadgeStore,
ArticleEditorStore,
WorksEditorStore,
UserProfileStore,
@@ -210,6 +211,7 @@ const rootStore = T.model({
coolGuideContent: T.optional(CoolGuideContentStore, {}),
// GEN: PLUG SUBSTORE TO ROOTSTORE
+ communityJoinBadge: T.optional(CommunityJoinBadgeStore, {}),
articleEditor: T.optional(ArticleEditorStore, {}),
worksEditor: T.optional(WorksEditorStore, {}),
userProfile: T.optional(UserProfileStore, {}),
diff --git a/src/stores/index.js b/src/stores/index.js
index 3454e6bdc..353a9af91 100755
--- a/src/stores/index.js
+++ b/src/stores/index.js
@@ -96,6 +96,7 @@ export { default as CommunityEditorStore } from '@/containers/editor/CommunityEd
export { default as WorksEditorStore } from '@/containers/editor/WorksEditor/store'
// GEN: EXPORT CONTAINERS STORE HERE
+export { default as CommunityJoinBadgeStore } from '@/containers/tool/CommunityJoinBadge/store'
export { default as ArticleEditorStore } from '@/containers/editor/ArticleEditor/store'
export { default as UserProfileStore } from '@/containers/user/UserProfile/store'
export { default as MembershipContentStore } from '@/containers/content/MembershipContent/store'