diff --git a/package-lock.json b/package-lock.json index e07dd663f..26f9c45b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "license": "Apache License 2.0", "dependencies": { "@babel/core": "^7.13.14", - "@groupher/react-editor": "^1.1.28", + "@groupher/react-editor": "^1.1.29", "@next/bundle-analyzer": "^9.4.4", "@sentry/browser": "5.17.0", "@sentry/node": "5.17.0", @@ -24,6 +24,7 @@ "chalk": "^2.4.1", "compatible-debug": "^1.0.0", "cookie-parser": "^1.4.4", + "cookies-next": "^2.0.3", "core-js": "3.6.5", "cross-env": "^7.0.2", "express": "^4.16.4", @@ -31,7 +32,6 @@ "graphql": "^15.5.1", "graphql-request": "3.5.0", "graphql-voyager": "^1.0.0-rc.31", - "js-cookie": "^2.2.0", "mastani-codehighlight": "0.0.7", "mobx": "6.3.2", "mobx-react": "7.2.0", @@ -1537,9 +1537,9 @@ } }, "node_modules/@groupher/react-editor": { - "version": "1.1.28", - "resolved": "https://registry.npmjs.org/@groupher/react-editor/-/react-editor-1.1.28.tgz", - "integrity": "sha512-xKc7lxRELIZ6+Nsv1ktX/c5L14Bl2Nq9hcR237z9zz+I9uCOT2JnIUKvR9qzlE7infJrHG9Vcgpm2x1DuEUf1w==", + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/@groupher/react-editor/-/react-editor-1.1.29.tgz", + "integrity": "sha512-j5a2J/aTulaNwnThzU0p9Bwgs4fGXBGQF4vMJB5j0wqWVSU3a5I75qd+kDQtjtHd9KFNf68jYBFuPdca63qLdw==", "dependencies": { "@groupher/editor-alert": "^1.0.27", "@groupher/editor-code": "^1.0.30", @@ -2634,6 +2634,11 @@ "@types/node": "*" } }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, "node_modules/@types/fined": { "version": "1.1.3", "integrity": "sha512-CWYnSRnun3CGbt6taXeVo2lCbuaj4mchVJ4UF/BdU5TSuIn3AmS13pGMwCsBUoehGbhZrBrpNJZSZI5EVilXww==", @@ -2778,8 +2783,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.9.1", - "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" + "version": "16.11.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", + "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -6868,6 +6874,16 @@ "version": "1.0.6", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "node_modules/cookies-next": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cookies-next/-/cookies-next-2.0.3.tgz", + "integrity": "sha512-sgYc9YxR7eTbZ1ifYhHbwMCVau/deXGx2rhQoIsq3otR+mf1ZfsvMbilS0BzWhk0s1TyOVWalNE7JcaiZfwsGQ==", + "dependencies": { + "@types/cookie": "^0.4.1", + "@types/node": "^16.10.2", + "cookie": "^0.4.0" + } + }, "node_modules/copy-concurrently": { "version": "1.0.5", "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", @@ -23610,9 +23626,9 @@ } }, "@groupher/react-editor": { - "version": "1.1.28", - "resolved": "https://registry.npmjs.org/@groupher/react-editor/-/react-editor-1.1.28.tgz", - "integrity": "sha512-xKc7lxRELIZ6+Nsv1ktX/c5L14Bl2Nq9hcR237z9zz+I9uCOT2JnIUKvR9qzlE7infJrHG9Vcgpm2x1DuEUf1w==", + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/@groupher/react-editor/-/react-editor-1.1.29.tgz", + "integrity": "sha512-j5a2J/aTulaNwnThzU0p9Bwgs4fGXBGQF4vMJB5j0wqWVSU3a5I75qd+kDQtjtHd9KFNf68jYBFuPdca63qLdw==", "requires": { "@groupher/editor-alert": "^1.0.27", "@groupher/editor-code": "^1.0.30", @@ -24495,6 +24511,11 @@ "@types/node": "*" } }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==" + }, "@types/fined": { "version": "1.1.3", "integrity": "sha512-CWYnSRnun3CGbt6taXeVo2lCbuaj4mchVJ4UF/BdU5TSuIn3AmS13pGMwCsBUoehGbhZrBrpNJZSZI5EVilXww==", @@ -24640,8 +24661,9 @@ "dev": true }, "@types/node": { - "version": "16.9.1", - "integrity": "sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==" + "version": "16.11.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.1.tgz", + "integrity": "sha512-PYGcJHL9mwl1Ek3PLiYgyEKtwTMmkMw4vbiyz/ps3pfdRYLVv+SN7qHVAImrjdAXxgluDEw6Ph4lyv+m9UpRmA==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -27858,6 +27880,16 @@ "version": "1.0.6", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "cookies-next": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/cookies-next/-/cookies-next-2.0.3.tgz", + "integrity": "sha512-sgYc9YxR7eTbZ1ifYhHbwMCVau/deXGx2rhQoIsq3otR+mf1ZfsvMbilS0BzWhk0s1TyOVWalNE7JcaiZfwsGQ==", + "requires": { + "@types/cookie": "^0.4.1", + "@types/node": "^16.10.2", + "cookie": "^0.4.0" + } + }, "copy-concurrently": { "version": "1.0.5", "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", diff --git a/package.json b/package.json index 74c606bbe..f00a54c21 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ }, "dependencies": { "@babel/core": "^7.13.14", - "@groupher/react-editor": "^1.1.28", + "@groupher/react-editor": "^1.1.29", "@next/bundle-analyzer": "^9.4.4", "@sentry/browser": "5.17.0", "@sentry/node": "5.17.0", @@ -56,6 +56,7 @@ "chalk": "^2.4.1", "compatible-debug": "^1.0.0", "cookie-parser": "^1.4.4", + "cookies-next": "^2.0.3", "core-js": "3.6.5", "cross-env": "^7.0.2", "express": "^4.16.4", @@ -63,7 +64,6 @@ "graphql": "^15.5.1", "graphql-request": "3.5.0", "graphql-voyager": "^1.0.0-rc.31", - "js-cookie": "^2.2.0", "mastani-codehighlight": "0.0.7", "mobx": "6.3.2", "mobx-react": "7.2.0", diff --git a/server/helper.js b/server/helper.js index a8d2b2372..f860689b9 100644 --- a/server/helper.js +++ b/server/helper.js @@ -9,7 +9,6 @@ const renderAndCache = ({ req, res, path }) => { // do not cache in dev mode if (dev) { const pagePath = path || req.path - console.log('# pagePath: ', pagePath) return app.render(req, res, pagePath, { ...req.query, ...req.params, diff --git a/src/components/AnimatedCount/AnimatedCount.tsx b/src/components/AnimatedCount/AnimatedCount.tsx index 94773e115..14f8bd134 100644 --- a/src/components/AnimatedCount/AnimatedCount.tsx +++ b/src/components/AnimatedCount/AnimatedCount.tsx @@ -13,7 +13,7 @@ const AnimatedCount: FC = ({ active = false, }) => { return ( - + import('./AnimatedCount'), { active: boolean } return ( - + {count} ) diff --git a/src/components/AnimatedCount/styles/index.ts b/src/components/AnimatedCount/styles/index.ts index 421cca912..f016d025d 100755 --- a/src/components/AnimatedCount/styles/index.ts +++ b/src/components/AnimatedCount/styles/index.ts @@ -1,15 +1,13 @@ import styled from 'styled-components' import type { TSIZE, TActive } from '@/spec' -import { theme } from '@/utils/themes' -import { getFontSize } from './metric' +import { getFontSize, getCountColor } from './metric' -type TWrapper = { size: TSIZE } & TActive +type TWrapper = { size: TSIZE; count: number } & TActive export const Wrapper = styled.div` - color: ${({ $active }) => - $active ? '#139C9E' : theme('thread.articleTitle')}; + color: ${({ $active, count }) => getCountColor($active, count)}; font-size: ${({ size }) => getFontSize(size)}; font-weight: ${({ $active }) => ($active ? 'bold' : 'normal')}; overflow-y: hidden; diff --git a/src/components/AnimatedCount/styles/metric.ts b/src/components/AnimatedCount/styles/metric.ts index 813945fe9..dcb66c727 100644 --- a/src/components/AnimatedCount/styles/metric.ts +++ b/src/components/AnimatedCount/styles/metric.ts @@ -1,6 +1,8 @@ import type { TSIZE } from '@/spec' import { SIZE } from '@/constant' +import { theme } from '@/utils/themes' + export const getFontSize = (size: TSIZE): string => { switch (size) { case SIZE.TINY: { @@ -15,4 +17,10 @@ export const getFontSize = (size: TSIZE): string => { } } -export const holder = 1 +export const getCountColor = ($active: boolean, count: number): string => { + if ($active) return '#139C9E' + if (count === 0) return '#4f7478' + if (count >= 5) return theme('thread.articleTitle') + + return theme('thread.articleDigest') +} diff --git a/src/components/ArtimentBody/index.tsx b/src/components/ArtimentBody/index.tsx index 0a1aa97b0..5378a0dea 100755 --- a/src/components/ArtimentBody/index.tsx +++ b/src/components/ArtimentBody/index.tsx @@ -52,7 +52,7 @@ const ArtimentBody: FC = ({ return ( - + ({ 'data-test-id': testid, }))`` -export const Body = styled.div<{ lineClampNum: number }>` - font-size: 16px; +type TBody = { lineClampNum: number; mode: 'article' | 'comment' } +export const Body = styled.div` + font-size: ${({ mode }) => (mode === 'article' ? '16px' : '15px')}; line-height: 1.85; position: relative; display: -webkit-box; diff --git a/src/components/Buttons/SubmitButton.tsx b/src/components/Buttons/SubmitButton.tsx index 04da5d0ab..43bdba066 100644 --- a/src/components/Buttons/SubmitButton.tsx +++ b/src/components/Buttons/SubmitButton.tsx @@ -33,7 +33,7 @@ const SubmitButton: FC = ({ {publishDone ? ( - 已完成 + 已提交 ) : ( { - return ( - - {users.totalCount !== 0 && ( - <> - 参与讨论 ({users.totalCount}) - - - - - )} - - ) -} - -DesktopView.propTypes = { - data: T.shape({ - communities: T.arrayOf( - T.shape({ - id: T.string, - title: T.string, - logo: T.string, - raw: T.string, - }), - ), - pagedCommentsParticipators: T.shape({ - entries: T.array, - totalCount: T.number, - }), - tags: T.arrayOf( - T.shape({ - id: T.string, - title: T.string, - color: T.string, - raw: T.string, - }), - ), - }), -} - -DesktopView.defaultProps = { - data: { - communities: [], - tags: [], - pagedCommentsParticipators: { - entries: [], - totalCount: 0, - }, - }, -} - -export default React.memo(DesktopView) diff --git a/src/components/ContentSourceCard/MobileView.js b/src/components/ContentSourceCard/MobileView.js deleted file mode 100644 index c8f05e9ff..000000000 --- a/src/components/ContentSourceCard/MobileView.js +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * MobileView - * - */ - -import React from 'react' -import T from 'prop-types' - -import { buildLog } from '@/utils/logger' -import CommunityList from '@/components/CommunityList' - -import UserList from './UserList' -import { - Wrapper, - Block, - Divider, - Title, - Desc, - NoMoreDesc, -} from './styles/mobile_view' - -/* eslint-disable-next-line */ -const log = buildLog('c:MobileView:index') - -const MobileView = ({ - data: { communities, pagedCommentsParticipators: users }, -}) => { - return ( - - - {users.totalCount !== 0 && ( - <> - 参与讨论 ({users.totalCount}) - - - - - )} - - - - 所属社区 - - 不属于任何社区} - /> - - - - ) -} - -MobileView.propTypes = { - data: T.shape({ - communities: T.arrayOf( - T.shape({ - id: T.string, - title: T.string, - logo: T.string, - raw: T.string, - }), - ), - pagedCommentsParticipators: T.shape({ - entries: T.array, - totalCount: T.number, - }), - tags: T.arrayOf( - T.shape({ - id: T.string, - title: T.string, - color: T.string, - raw: T.string, - }), - ), - }), -} - -MobileView.defaultProps = { - data: { - communities: [], - tags: [], - pagedCommentsParticipators: { - entries: [], - totalCount: 0, - }, - }, -} - -export default React.memo(MobileView) diff --git a/src/components/ContentSourceCard/TagList.js b/src/components/ContentSourceCard/TagList.js deleted file mode 100755 index 09c19a9d9..000000000 --- a/src/components/ContentSourceCard/TagList.js +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react' -import { isEmpty } from 'ramda' - -import { Wrapper, TagDot, TagTitle, NoMoreDesc } from './styles/tag_list' - -const TagList = ({ items }) => { - if (isEmpty(items)) return 无标签 - - return ( - <> - {items.map((t) => ( - - - {t.title} - - ))} - - ) -} - -export default React.memo(TagList) diff --git a/src/components/ContentSourceCard/UserList.js b/src/components/ContentSourceCard/UserList.js deleted file mode 100755 index fa2fedc7f..000000000 --- a/src/components/ContentSourceCard/UserList.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react' - -import Tooltip from '@/components/Tooltip' -import { Wrapper, Avatar, PopInfo } from './styles/user_list' - -const UserList = ({ items }) => ( - - {items.map((user) => ( - {user.nickname}} - > -
- -
-
- ))} -
-) - -export default React.memo(UserList) diff --git a/src/components/ContentSourceCard/index.js b/src/components/ContentSourceCard/index.js deleted file mode 100755 index 07da87eba..000000000 --- a/src/components/ContentSourceCard/index.js +++ /dev/null @@ -1,65 +0,0 @@ -/* - * - * ContentSourceCard - * - */ - -import React from 'react' -import T from 'prop-types' - -import usePlatform from '@/hooks/usePlatform' -import { buildLog } from '@/utils/logger' - -import DesktopView from './DesktopView' -import MobileView from './MobileView' - -/* eslint-disable-next-line */ -const log = buildLog('c:ContentSourceCard:index') - -const ContentSourceCard = (props) => { - const { isMobile } = usePlatform() - - return ( - - {!isMobile ? : } - - ) -} - -ContentSourceCard.propTypes = { - data: T.shape({ - communities: T.arrayOf( - T.shape({ - id: T.string, - title: T.string, - logo: T.string, - raw: T.string, - }), - ), - pagedCommentsParticipators: T.shape({ - entries: T.array, - totalCount: T.number, - }), - tags: T.arrayOf( - T.shape({ - id: T.string, - title: T.string, - color: T.string, - raw: T.string, - }), - ), - }), -} - -ContentSourceCard.defaultProps = { - data: { - communities: [], - tags: [], - pagedCommentsParticipators: { - entries: [], - totalCount: 0, - }, - }, -} - -export default React.memo(ContentSourceCard) diff --git a/src/components/ContentSourceCard/styles/desktop_view.ts b/src/components/ContentSourceCard/styles/desktop_view.ts deleted file mode 100644 index f787882dd..000000000 --- a/src/components/ContentSourceCard/styles/desktop_view.ts +++ /dev/null @@ -1,30 +0,0 @@ -import styled from 'styled-components' - -import { theme } from '@/utils/themes' -import css from '@/utils/css' - -export const Wrapper = styled.div` - min-height: 100px; - padding: 10px; - padding-bottom: 0; - max-width: 300px; - width: 100%; - flex-wrap: wrap; -` -export const Title = styled.div` - color: ${theme('thread.articleTitle')}; - font-size: 1em; -` -export const Desc = styled.div<{ column: boolean }>` - ${css.flex()}; - margin-top: 15px; - margin-bottom: 20px; - flex-direction: ${({ column }) => (column ? 'column' : 'row')}; - flex-wrap: wrap; -` -// export const Divider = styled.div` -// margin-top: 10px; -// margin-bottom: 10px; -// border-bottom: 1px solid; -// border-color: ${theme('drawer.sideDivider')}; -// ` diff --git a/src/components/ContentSourceCard/styles/mobile_view.ts b/src/components/ContentSourceCard/styles/mobile_view.ts deleted file mode 100644 index 8b15904c9..000000000 --- a/src/components/ContentSourceCard/styles/mobile_view.ts +++ /dev/null @@ -1,37 +0,0 @@ -import styled from 'styled-components' - -import { theme } from '@/utils/themes' -import css from '@/utils/css' - -export const Wrapper = styled.div` - ${css.flex('align-center')}; - width: 100%; - min-height: 120px; - padding: 0 25px; -` -export const Block = styled.div` - width: 40%; -` -export const Title = styled.div` - color: ${theme('thread.articleTitle')}; - font-size: 14px; -` -export const Desc = styled.div<{ column: boolean }>` - ${css.flex()}; - margin-top: 10px; - margin-bottom: 10px; - - flex-direction: ${({ column }) => (column ? 'column' : 'row')}; - flex-wrap: wrap; -` -export const Divider = styled.div` - min-height: 80px; - width: 1px; - margin-left: 5%; - margin-right: 10%; - background-color: ${theme('drawer.sideDivider')}; -` -export const NoMoreDesc = styled.div` - color: ${theme('banner.desc')}; - font-style: italic; -` diff --git a/src/components/ContentSourceCard/styles/tag_list.ts b/src/components/ContentSourceCard/styles/tag_list.ts deleted file mode 100755 index bf8c9307d..000000000 --- a/src/components/ContentSourceCard/styles/tag_list.ts +++ /dev/null @@ -1,22 +0,0 @@ -import styled from 'styled-components' - -import { theme } from '@/utils/themes' -import css from '@/utils/css' - -export const Wrapper = styled.div` - ${css.flex()}; - margin-bottom: 12px; - margin-left: 2px; -` -export const TagDot = styled.div` - ${css.circle(10)}; - background: ${theme('baseColor.red')}; - margin-right: 5px; -` -export const TagTitle = styled.div` - margin-top: -5px; -` -export const NoMoreDesc = styled.div` - color: ${theme('banner.desc')}; - font-style: italic; -` diff --git a/src/components/ContentSourceCard/styles/user_list.ts b/src/components/ContentSourceCard/styles/user_list.ts deleted file mode 100755 index 39b2c9402..000000000 --- a/src/components/ContentSourceCard/styles/user_list.ts +++ /dev/null @@ -1,19 +0,0 @@ -import styled from 'styled-components' - -import { theme } from '@/utils/themes' -import css from '@/utils/css' -import Img from '@/Img' - -export const Wrapper = styled.div` - ${css.flex()}; - flex-wrap: wrap; -` -export const Avatar = styled(Img)` - ${css.circle(20)}; - margin-right: 5px; - margin-bottom: 6px; -` -export const PopInfo = styled.div` - padding: 5px 10px; - color: ${theme('thread.articleTitle')}; -` diff --git a/src/components/ContentSourceCard/tests/index.test.ts b/src/components/ContentSourceCard/tests/index.test.ts deleted file mode 100755 index 21bb90c27..000000000 --- a/src/components/ContentSourceCard/tests/index.test.ts +++ /dev/null @@ -1,10 +0,0 @@ -// import React from 'react' -// import { shallow } from 'enzyme' - -// import ContentSourceCard from '../index' - -describe('TODO ', () => { - it('Expect to have unit tests specified', () => { - expect(true).toEqual(true) - }) -}) diff --git a/src/components/Header/DesktopView/ArticleLayout.tsx b/src/components/Header/DesktopView/ArticleLayout.tsx index 415f94cd3..f4e7e9b09 100644 --- a/src/components/Header/DesktopView/ArticleLayout.tsx +++ b/src/components/Header/DesktopView/ArticleLayout.tsx @@ -7,9 +7,14 @@ import { FC } from 'react' import { ICON } from '@/config' + import { buildLog } from '@/utils/logger' +import { authWarn } from '@/utils/helper' +import Tooltip from '@/components/Tooltip' +import UserCard from '@/components/Cards/UserCard' import Navigator from '@/components/Navigator' +import { useAccount } from '@/hooks' import type { TProps } from '../index' import { @@ -17,6 +22,7 @@ import { InnerWrapper, RouterWrapper, Operations, + LoginHint, MoreIcon, } from '../styles/desktop_view/article_layout' @@ -24,6 +30,8 @@ import { const log = buildLog('C:Header') const ArticleHeader: FC = ({ metric, c11n, community }) => { + const { isLogin, user } = useAccount() + return ( @@ -35,7 +43,20 @@ const ArticleHeader: FC = ({ metric, c11n, community }) => { /> - + {!isLogin ? ( + authWarn({ hideToast: true })}> + 登入 + + ) : ( + } + delay={0} + placement="bottom" + interactive={false} + > + + + )} diff --git a/src/components/Header/styles/desktop_view/article_layout.ts b/src/components/Header/styles/desktop_view/article_layout.ts index d0999a4d0..69bf2c880 100644 --- a/src/components/Header/styles/desktop_view/article_layout.ts +++ b/src/components/Header/styles/desktop_view/article_layout.ts @@ -28,6 +28,16 @@ export const Operations = styled.div<{ metric: TMetric }>` justify-content: ${({ metric }) => getStickerJustify(metric)}; ${({ metric }) => css.fitStickerWidth(metric)}; ` +export const LoginHint = styled.div` + color: ${theme('thread.articleTitle')}; + font-size: 13px; + margin-top: 1px; + + &:hover { + color: ${theme('button.primary')}; + cursor: pointer; + } +` export const MoreIcon = styled(Img)` fill: ${theme('banner.desc')}; ${css.size(24)}; diff --git a/src/components/Icons/CloseCross.tsx b/src/components/Icons/CloseCross.tsx new file mode 100644 index 000000000..ba647be18 --- /dev/null +++ b/src/components/Icons/CloseCross.tsx @@ -0,0 +1,17 @@ +import { memo, SVGProps } from 'react' + +const CloseCross = (props: SVGProps) => { + return ( + + + + ) +} + +export default memo(CloseCross) diff --git a/src/components/Icons/UserBadge.tsx b/src/components/Icons/UserBadge.tsx new file mode 100644 index 000000000..cffec18c5 --- /dev/null +++ b/src/components/Icons/UserBadge.tsx @@ -0,0 +1,18 @@ +import { memo, SVGProps } from 'react' + +const UserBadge = (props: SVGProps) => { + return ( + + + + ) +} + +export default memo(UserBadge) diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx index 0e61e9f64..f2d6b9f8f 100755 --- a/src/components/Modal/index.tsx +++ b/src/components/Modal/index.tsx @@ -77,13 +77,8 @@ const Modal: FC = ({ offsetTop={offsetTop} > setVisibleOnPage(true)} /> - - Esc + {showCloseBtn && } + {showCloseBtn && Esc} e.stopPropagation()}> {children} diff --git a/src/components/Modal/styles/index.ts b/src/components/Modal/styles/index.ts index e2646a664..3e774b5b1 100755 --- a/src/components/Modal/styles/index.ts +++ b/src/components/Modal/styles/index.ts @@ -5,6 +5,7 @@ import { theme } from '@/utils/themes' import css from '@/utils/css' import animate from '@/utils/animations' import Img from '@/Img' +import CloseCrossSVG from '@/icons/CloseCross' // display: ${props => (props.show ? 'block' : 'none')}; export const Mask = styled.div` @@ -51,20 +52,18 @@ export const ChildrenWrapper = styled.div` height: auto; overflow-y: scroll; ` -type TCloseBtn = TActive & { mode: string } -export const CloseBtn = styled(Img)` - fill: ${({ mode }) => - mode === 'default' ? theme('font') : theme('baseColor.red')}; +type TCloseBtn = { mode: string } +export const CloseBtn = styled(CloseCrossSVG)` position: absolute; top: 0; right: -48px; + fill: ${({ mode }) => + mode === 'default' ? '#0A658A' : theme('baseColor.red')}; ${css.size(30)}; - display: ${({ show }) => (show ? 'block' : 'none')}; z-index: ${css.zIndex.modalCloseBtn}; &:hover { - animation: ${animate.rotate360} 2s cubic-bezier(0, 0.56, 0.24, 0.72); - font-weight: bold; + animation: ${animate.pulse} 0.3s linear; cursor: pointer; } ` diff --git a/src/components/Pagi/styles/index.ts b/src/components/Pagi/styles/index.ts index ff0e72ffd..1577b554a 100755 --- a/src/components/Pagi/styles/index.ts +++ b/src/components/Pagi/styles/index.ts @@ -22,16 +22,18 @@ export const EmptyWrapper = styled(Wrapper)` ${css.flex('align-both')}; ` export const BottomMsg = styled.div` - font-size: 1.1rem; + font-size: 16px; color: ${theme('thread.articleDigest')}; - opacity: 0.7; + opacity: 0.6; &:before { - content: '~~'; + content: '\/\\*'; margin-right: 10px; + font-family: monospace; } &:after { - content: '~~'; + content: '*/'; margin-left: 10px; + font-family: monospace; } ` export const CommonCenterArrowIcon = styled(Img)` diff --git a/src/components/Switcher/styles/icon_selector.ts b/src/components/Switcher/styles/icon_selector.ts index 347b19e17..9deb5ccb2 100644 --- a/src/components/Switcher/styles/icon_selector.ts +++ b/src/components/Switcher/styles/icon_selector.ts @@ -52,6 +52,7 @@ export const Label = styled.label` ` export const DescText = styled.div` ${css.flex('align-both')}; + color: ${theme('thread.articleTitle')}; min-width: 90px; padding: 5px 10px; ` diff --git a/src/components/Upvote/ArticleLayout.tsx b/src/components/Upvote/ArticleLayout.tsx index 1e00dcbf0..799893dae 100644 --- a/src/components/Upvote/ArticleLayout.tsx +++ b/src/components/Upvote/ArticleLayout.tsx @@ -37,6 +37,7 @@ const Upvote: FC = ({ viewerHasUpvoted={viewerHasUpvoted} type={UPVOTE_LAYOUT.ARTICLE} onAction={onAction} + count={count} /> diff --git a/src/components/Upvote/BlogListLayout.tsx b/src/components/Upvote/BlogListLayout.tsx index 80fa161e7..934a7766f 100644 --- a/src/components/Upvote/BlogListLayout.tsx +++ b/src/components/Upvote/BlogListLayout.tsx @@ -32,7 +32,11 @@ const Upvote: FC = ({ return ( - + diff --git a/src/components/Upvote/CommentLayout.tsx b/src/components/Upvote/CommentLayout.tsx index 79797ccaa..4b78d66ad 100644 --- a/src/components/Upvote/CommentLayout.tsx +++ b/src/components/Upvote/CommentLayout.tsx @@ -8,6 +8,7 @@ import { FC, memo } from 'react' import { buildLog } from '@/utils/logger' +import { UPVOTE_LAYOUT } from '@/constant' import AnimatedCount from '@/components/AnimatedCount' import UpvoteBtn from './UpvoteBtn' @@ -32,10 +33,15 @@ const Upvote: FC = ({ return ( - + - + ) diff --git a/src/components/Upvote/DefaultLayout.tsx b/src/components/Upvote/DefaultLayout.tsx index 6fbf33420..bbfdba87d 100644 --- a/src/components/Upvote/DefaultLayout.tsx +++ b/src/components/Upvote/DefaultLayout.tsx @@ -42,7 +42,11 @@ const Upvote: FC = ({ return ( - + {!noOne && } diff --git a/src/components/Upvote/PostListLayout.tsx b/src/components/Upvote/PostListLayout.tsx index 5453adae7..ee9df8d54 100644 --- a/src/components/Upvote/PostListLayout.tsx +++ b/src/components/Upvote/PostListLayout.tsx @@ -32,7 +32,11 @@ const Upvote: FC = ({ return ( - + diff --git a/src/components/Upvote/UpvoteBtn.tsx b/src/components/Upvote/UpvoteBtn.tsx index 702cc0b35..ad6ae49b0 100644 --- a/src/components/Upvote/UpvoteBtn.tsx +++ b/src/components/Upvote/UpvoteBtn.tsx @@ -25,12 +25,14 @@ const log = buildLog('c:Upvote:index') type TProps = { type?: TUpvoteLayout viewerHasUpvoted?: boolean + count?: number onAction: (viewerHasUpvoted: boolean) => void } const UpvoteBtn: FC = ({ type = 'default', viewerHasUpvoted = false, + count = 0, onAction, }) => { const [showAnimation, setShowAnimation] = useState(false) @@ -58,7 +60,7 @@ const UpvoteBtn: FC = ({ ) : ( )} - + diff --git a/src/components/Upvote/WorksArticleLayout.tsx b/src/components/Upvote/WorksArticleLayout.tsx index 3c3fc1a33..b369f08f6 100644 --- a/src/components/Upvote/WorksArticleLayout.tsx +++ b/src/components/Upvote/WorksArticleLayout.tsx @@ -55,6 +55,7 @@ const Upvote: FC = ({ viewerHasUpvoted={viewerHasUpvoted} type={UPVOTE_LAYOUT.WORKS_ARTICLE} onAction={onAction} + count={count} /> = ({ return ( - + diff --git a/src/components/Upvote/styles/comment_layout.ts b/src/components/Upvote/styles/comment_layout.ts index 24003a422..18ff59a5b 100755 --- a/src/components/Upvote/styles/comment_layout.ts +++ b/src/components/Upvote/styles/comment_layout.ts @@ -15,9 +15,9 @@ export const Wrapper = styled.div.attrs(({ testid }: TTestable) => ({ margin-top: 2px; ` export const UpWrapper = styled.div` - margin-left: 7px; + margin-left: 9px; ` export const CountWrapper = styled.div` margin-top: -4px; - margin-left: 1px; + margin-left: 2px; ` diff --git a/src/components/Upvote/styles/metric.ts b/src/components/Upvote/styles/metric.ts index 4ec1d7cd3..76c004176 100644 --- a/src/components/Upvote/styles/metric.ts +++ b/src/components/Upvote/styles/metric.ts @@ -1,12 +1,25 @@ import type { TUpvoteLayout } from '@/spec' import { UPVOTE_LAYOUT } from '@/constant' +import { theme } from '@/utils/themes' + +export const getIconColor = ($active: boolean, count: number): string => { + if ($active) return '#139B9D;' + if (count === 0) return '#4f7478' + + return theme('thread.articleDigest') +} + export const getIconSize = (type: TUpvoteLayout): string => { switch (type) { case UPVOTE_LAYOUT.ARTICLE: { return '30px;' } + case UPVOTE_LAYOUT.COMMENT: { + return '16px;' + } + case UPVOTE_LAYOUT.WORKS_ARTICLE: { return '22px;' } @@ -59,6 +72,10 @@ export const getShadowTopOffset = (type: TUpvoteLayout): string => { export const getWindowLeftOffset = (type: TUpvoteLayout): string => { switch (type) { + case UPVOTE_LAYOUT.COMMENT: { + return '6px' + } + case UPVOTE_LAYOUT.WORKS_ARTICLE: { return '8px' } @@ -75,6 +92,10 @@ export const getWindowTopOffset = (type: TUpvoteLayout): string => { return '10px' } + case UPVOTE_LAYOUT.COMMENT: { + return '7px' + } + default: { return '8px' } diff --git a/src/components/Upvote/styles/upvote_btn.ts b/src/components/Upvote/styles/upvote_btn.ts index 9198c65c6..bf76a5405 100644 --- a/src/components/Upvote/styles/upvote_btn.ts +++ b/src/components/Upvote/styles/upvote_btn.ts @@ -14,6 +14,7 @@ import { getShadowTopOffset, getWindowLeftOffset, getWindowTopOffset, + getIconColor, } from './metric' const topBubbles = keyframes` @@ -196,10 +197,9 @@ export const ArticleShipWindow = styled(ShipWindow)` opacity: 0.5; ` -type TUpIcon = { type: TUpvoteLayout } & TActive +type TUpIcon = { type: TUpvoteLayout; count: number } & TActive export const UpIcon = styled(UpvoteIcon)` - fill: ${({ $active }) => - $active ? '#139B9D;' : theme('thread.articleDigest')}; + fill: ${({ $active, count }) => getIconColor($active, count)}; width: ${({ type }) => getIconSize(type)}; height: ${({ type }) => getIconSize(type)}; diff --git a/src/components/WordsCounter/styles/index.ts b/src/components/WordsCounter/styles/index.ts index 1ff08f5af..dc4f1302e 100755 --- a/src/components/WordsCounter/styles/index.ts +++ b/src/components/WordsCounter/styles/index.ts @@ -36,4 +36,5 @@ export const Slash = styled.div` ` export const TotalNum = styled.div` font-size: 12px; + color: ${theme('thread.articleDigest')}; ` diff --git a/src/containers/content/ArticleContent/DesktopView/index.tsx b/src/containers/content/ArticleContent/DesktopView/index.tsx index cd54ef0e7..56ec1ef69 100644 --- a/src/containers/content/ArticleContent/DesktopView/index.tsx +++ b/src/containers/content/ArticleContent/DesktopView/index.tsx @@ -83,7 +83,7 @@ const ArticleContentContainer: FC = ({ onLeave={() => checkAnchor(ref?.current)} /> - + diff --git a/src/containers/content/ArticleContent/MobileView/index.tsx b/src/containers/content/ArticleContent/MobileView/index.tsx index ed77b94bf..954b69b03 100644 --- a/src/containers/content/ArticleContent/MobileView/index.tsx +++ b/src/containers/content/ArticleContent/MobileView/index.tsx @@ -80,7 +80,7 @@ const PostContentContainer: FC = ({ {/* @ts-ignore */} - + diff --git a/src/containers/content/WorksContent/store.ts b/src/containers/content/WorksContent/store.ts index 41720eee7..372a11f84 100755 --- a/src/containers/content/WorksContent/store.ts +++ b/src/containers/content/WorksContent/store.ts @@ -4,7 +4,7 @@ */ import { types as T, Instance } from 'mobx-state-tree' -import { findIndex, propEq, values } from 'ramda' +import { values } from 'ramda' import type { TPagedWorks } from '@/spec' import { markStates, toJS } from '@/utils/mobx' diff --git a/src/containers/editor/RichEditor/Options/index.tsx b/src/containers/editor/RichEditor/Options/index.tsx index 52b639be3..45c47de1e 100644 --- a/src/containers/editor/RichEditor/Options/index.tsx +++ b/src/containers/editor/RichEditor/Options/index.tsx @@ -11,6 +11,10 @@ type TProps = { const Options: FC = ({ type, onLinkChange, onUseTemplateChange }) => { switch (type) { + case 'comment': { + return null + } + case 'works': { return } diff --git a/src/containers/editor/RichEditor/RealEditor.tsx b/src/containers/editor/RichEditor/RealEditor.tsx index 6300f8c20..cce7cc669 100644 --- a/src/containers/editor/RichEditor/RealEditor.tsx +++ b/src/containers/editor/RichEditor/RealEditor.tsx @@ -24,6 +24,7 @@ const log = buildLog('C:RichEditor') type TProps = { richEditor?: TStore + placeholder?: string data?: string type?: 'article' | 'works' | 'job' | 'comment' | 'radar' reinitOnPropsChange?: boolean @@ -35,6 +36,7 @@ type TProps = { const RichEditorContainer: FC = ({ richEditor: store, data, + placeholder = "// 正文内容('Tab' 键快速插入)", type = 'article', reinitOnPropsChange = false, onChange = log, @@ -46,17 +48,18 @@ const RichEditorContainer: FC = ({ // 使用模板 or 转载或翻译 or 请保持友善 return ( - + - + diff --git a/src/containers/editor/RichEditor/styles/index.ts b/src/containers/editor/RichEditor/styles/index.ts index ea48c256c..55c7b943b 100755 --- a/src/containers/editor/RichEditor/styles/index.ts +++ b/src/containers/editor/RichEditor/styles/index.ts @@ -1,22 +1,25 @@ -import styled, { createGlobalStyle } from 'styled-components' +import styled from 'styled-components' import css from '@/utils/css' import { theme } from '@/utils/themes' +import { getWidth, getMinHeight } from './metric' + export const Wrapper = styled.div` ${css.flexColumn('align-center')}; position: relative; width: 100%; /* height: 100%; */ ` -export const InnerWrapper = styled.div` - width: 680px; +export const InnerWrapper = styled.div<{ type: string }>` + width: ${({ type }) => getWidth(type)}; ` -export const EditorWrapper = styled.div.attrs(() => ({ +const EditWrapperBase = styled.div<{ type: string }>`` +export const EditorWrapper = styled(EditWrapperBase).attrs(() => ({ spellCheck: false, }))` color: ${theme('thread.articleTitle')}; - min-height: 390px; + min-height: ${({ type }) => getMinHeight(type)}; // // media therdhold is 651 width: 100%; diff --git a/src/containers/editor/RichEditor/styles/metric.ts b/src/containers/editor/RichEditor/styles/metric.ts new file mode 100644 index 000000000..a42a0db8b --- /dev/null +++ b/src/containers/editor/RichEditor/styles/metric.ts @@ -0,0 +1,21 @@ +export const getWidth = (type) => { + switch (type) { + case 'comment': { + return '600px' + } + default: { + return '680px' + } + } +} + +export const getMinHeight = (type) => { + switch (type) { + case 'comment': { + return '250px' + } + default: { + return '390px' + } + } +} diff --git a/src/containers/layout/GlobalLayout/logic.ts b/src/containers/layout/GlobalLayout/logic.ts index 1d91f4ddb..a1449dc9d 100755 --- a/src/containers/layout/GlobalLayout/logic.ts +++ b/src/containers/layout/GlobalLayout/logic.ts @@ -85,6 +85,10 @@ export const useInit = (_store: TStore, extra): void => { // scrollbars: { autoHide: 'scroll', autoHideDelay: 500 }, // }) + console.log( + 'global accountInfo isValidSession: ', + store.accountInfo.isValidSession, + ) const { online, isMobile } = extra store.mark({ online, isMobile }) diff --git a/src/containers/tool/ArticleSticker/CommentSticker.tsx b/src/containers/tool/ArticleSticker/CommentSticker.tsx index fbaa4db00..89151b7a5 100644 --- a/src/containers/tool/ArticleSticker/CommentSticker.tsx +++ b/src/containers/tool/ArticleSticker/CommentSticker.tsx @@ -4,9 +4,9 @@ * */ -import { FC, memo, useEffect } from 'react' +import { FC, memo } from 'react' -import type { TArticle, TPagedUsers } from '@/spec' +import type { TCommentsState } from '@/spec' import { ICON } from '@/config' import { buildLog } from '@/utils/logger' @@ -18,37 +18,33 @@ import UserCard from '@/components/Cards/UserCard' import { Wrapper, Title, - JoinCount, + TotalNum, UsersWrapper, Avatar, MoreUserWrapper, MoreIcon, Divider, } from './styles/comment_sticker' -import { loadPagedCommentsParticipants } from './logic' /* eslint-disable-next-line */ const log = buildLog('c:CommentSticker:index') type TProps = { show: boolean - participants: TPagedUsers + commentsState: TCommentsState } -const CommentSticker: FC = ({ show, participants }) => { - useEffect(() => { - if (show) loadPagedCommentsParticipants() - }, [show]) - +const CommentSticker: FC = ({ show, commentsState }) => { + const { participants, participantsCount, isViewerJoined } = commentsState return ( - 共<JoinCount>{participants.totalCount}</JoinCount> + 共<TotalNum highlight={isViewerJoined}>{participantsCount}</TotalNum> 人参与讨论 - {participants.totalCount !== 0 && ( + {participantsCount !== 0 && ( - {participants.entries.map((user) => ( + {participants.map((user) => ( = ({ show, participants }) => { ))} - {participants.pageNumber > 1 && ( + {participants.length > participantsCount && ( diff --git a/src/containers/tool/ArticleSticker/index.tsx b/src/containers/tool/ArticleSticker/index.tsx index 7a32660d8..e7878173c 100755 --- a/src/containers/tool/ArticleSticker/index.tsx +++ b/src/containers/tool/ArticleSticker/index.tsx @@ -48,7 +48,7 @@ const ArticleStickerContainer: FC = ({ metric = METRIC.ARTICLE, }) => { useInit(store) - const { pagedCommentsParticipantsData } = store + const { commentsState } = store const { showLeftSticker, @@ -78,7 +78,7 @@ const ArticleStickerContainer: FC = ({ /> diff --git a/src/containers/tool/ArticleSticker/logic.ts b/src/containers/tool/ArticleSticker/logic.ts index a6b24aad1..60df645b9 100755 --- a/src/containers/tool/ArticleSticker/logic.ts +++ b/src/containers/tool/ArticleSticker/logic.ts @@ -43,17 +43,17 @@ export const handleUpvote = (viewerHasUpvoted: boolean): void => { : sr71$.mutate(S.getUndoUpvoteSchema(meta.thread), { id }) } -export const loadPagedCommentsParticipants = (): void => { - const { viewingArticle: article } = store - - const args = { - id: article.id, - thread: article.meta.thread, - filter: { page: 1, size: 20 }, - } - log('load comments query args: ', args) - sr71$.query(S.pagedCommentsParticipants, args) -} +// export const loadPagedCommentsParticipants = (): void => { +// const { viewingArticle: article } = store + +// const args = { +// id: article.id, +// thread: article.meta.thread, +// filter: { page: 1, size: 20 }, +// } +// log('load comments query args: ', args) +// sr71$.query(S.pagedCommentsParticipants, args) +// } // update the real upvoteCount after upvote action const handleUovoteRes = ({ upvotesCount }) => { diff --git a/src/containers/tool/ArticleSticker/schema.ts b/src/containers/tool/ArticleSticker/schema.ts index 25debe416..ecd8e3897 100644 --- a/src/containers/tool/ArticleSticker/schema.ts +++ b/src/containers/tool/ArticleSticker/schema.ts @@ -1,20 +1,20 @@ -import { gql } from '@urql/core' +// import { gql } from '@urql/core' import { F } from '@/schemas' -const pagedCommentsParticipants = gql` - query($id: ID!, $thread: Thread, $filter: PagedFilter!) { - pagedCommentsParticipants(id: $id, thread: $thread, filter: $filter) { - entries { - ${F.author} - } - ${F.pagedCounts} - - } - } -` +// const pagedCommentsParticipants = gql` +// query($id: ID!, $thread: Thread, $filter: PagedFilter!) { +// pagedCommentsParticipants(id: $id, thread: $thread, filter: $filter) { +// entries { +// ${F.author} +// } +// ${F.pagedCounts} + +// } +// } +// ` const schema = { - pagedCommentsParticipants, + // pagedCommentsParticipants, getUpvoteSchema: F.getUpvoteSchema, getUndoUpvoteSchema: F.getUndoUpvoteSchema, } diff --git a/src/containers/tool/ArticleSticker/store.ts b/src/containers/tool/ArticleSticker/store.ts index a6da1bcee..5e136ec37 100755 --- a/src/containers/tool/ArticleSticker/store.ts +++ b/src/containers/tool/ArticleSticker/store.ts @@ -12,6 +12,7 @@ import type { TScrollDirection, TThread, TPagedUsers, + TCommentsState, } from '@/spec' import { markStates, toJS } from '@/utils/mobx' import { PagedUsers, emptyPagi } from '@/model' @@ -72,8 +73,9 @@ const ArticleSticker = T.model('ArticleSticker', { return !isArticleInViewport }, - get pagedCommentsParticipantsData(): TPagedUsers { - return toJS(self.pagedCommentsParticipants) + get commentsState(): TCommentsState { + const root = getParent(self) as TRootStore + return root.comments.basicState }, })) .actions((self) => ({ diff --git a/src/containers/tool/ArticleSticker/styles/comment_sticker.ts b/src/containers/tool/ArticleSticker/styles/comment_sticker.ts index 65f1fc073..e6ed32fc9 100644 --- a/src/containers/tool/ArticleSticker/styles/comment_sticker.ts +++ b/src/containers/tool/ArticleSticker/styles/comment_sticker.ts @@ -7,10 +7,10 @@ import Img from '@/Img' export const Wrapper = styled.div` min-height: 100px; - margin-left: 42px; + margin-left: 120px; margin-top: 50px; padding-bottom: 0; - width: 65%; + width: calc(100% - 50px); max-width: 200px; flex-wrap: wrap; visibility: ${({ show }) => (show ? 'visible' : 'hidden')}; @@ -21,8 +21,9 @@ export const Title = styled.div` margin-bottom: 15px; margin-left: 3px; ` -export const JoinCount = styled.span` - color: ${theme('comment.number')}; +export const TotalNum = styled.span<{ highlight: boolean }>` + color: ${({ highlight }) => + highlight ? theme('comment.number') : theme('thread.articleTitle')}; font-size: 13px; margin-left: 4px; margin-right: 4px; diff --git a/src/containers/unit/ArticleFooter/styles/author_info/index.ts b/src/containers/unit/ArticleFooter/styles/author_info/index.ts index 7e506fead..a959ed2f8 100644 --- a/src/containers/unit/ArticleFooter/styles/author_info/index.ts +++ b/src/containers/unit/ArticleFooter/styles/author_info/index.ts @@ -42,6 +42,6 @@ export const AvatarIntro = styled.div` margin-top: 2px; ` export const Avatar = styled(Img)` - ${css.circle(38)}; + ${css.circle(33)}; margin-bottom: 16px; ` diff --git a/src/containers/unit/Comments/Comment/Actions.tsx b/src/containers/unit/Comments/Comment/Actions.tsx index fb3e54594..11c45aa13 100755 --- a/src/containers/unit/Comments/Comment/Actions.tsx +++ b/src/containers/unit/Comments/Comment/Actions.tsx @@ -1,6 +1,6 @@ import { FC, memo, useCallback } from 'react' -import type { TAccount, TComment } from '@/spec' +import type { TComment } from '@/spec' import { ICON } from '@/config' import { useAccount } from '@/hooks' @@ -8,19 +8,19 @@ import IconButton from '@/components/Buttons/IconButton' import MenuButton from '@/components/Buttons/MenuButton' import { SpaceGrow } from '@/components/Common' -import { Wrapper, ReplyAction } from '../styles/comment/actions' -import { openUpdateEditor, openReplyEditor, onDelete } from '../logic' +import { Wrapper, ReplyAction, MoreWrapper } from '../styles/comment/actions' +import { openUpdateEditor, openReplyEditor } from '../logic' type TProps = { data: TComment } const menuOptions = [ - { - key: 'quote', - icon: `${ICON}/shape/quote.svg`, - title: '引用', - }, + // { + // key: 'quote', + // icon: `${ICON}/shape/quote.svg`, + // title: '引用', + // }, { key: 'share', icon: `${ICON}/article/share.svg`, @@ -35,11 +35,10 @@ const menuOptions = [ const Actions: FC = ({ data }) => { const { user } = useAccount() - const accountId = user.id let extraOptions = [] - if (String(data.author.id) === accountId) { + if (data.author.login === user.login) { extraOptions = [ { key: 'edit', @@ -70,7 +69,7 @@ const Actions: FC = ({ data }) => { return openUpdateEditor(data) } case 'delete': { - return onDelete(data) + return console.log('todo: delete') } default: { // eslint-disable-next-line no-useless-return @@ -90,7 +89,9 @@ const Actions: FC = ({ data }) => { extraOptions={extraOptions} onClick={handleAction} > - + + + ) diff --git a/src/containers/unit/Comments/Comment/DeleteMask.tsx b/src/containers/unit/Comments/Comment/DeleteMask.tsx deleted file mode 100755 index d1500464e..000000000 --- a/src/containers/unit/Comments/Comment/DeleteMask.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { FC, memo } from 'react' - -import Button from '@/components/Buttons/Button' - -import { - DeleteOverlay, - DeleteHintText, - DeleteBtnGroup, -} from '../styles/comment/delete_mask' - -import { cancelDelete, deleteComment } from '../logic' - -type TProps = { - show: boolean -} - -const DeleteMask: FC = ({ show }) => { - return ( - - 删除后该该讨论将不可恢复 - - -    - - - - ) -} - -export default memo(DeleteMask) diff --git a/src/containers/unit/Comments/Comment/DesktopView/DefaultLayout.tsx b/src/containers/unit/Comments/Comment/DesktopView/DefaultLayout.tsx index 2fa8dfb90..991693284 100644 --- a/src/containers/unit/Comments/Comment/DesktopView/DefaultLayout.tsx +++ b/src/containers/unit/Comments/Comment/DesktopView/DefaultLayout.tsx @@ -11,7 +11,6 @@ import ArtimentBody from '@/components/ArtimentBody' import Header from '../Header' import ReplyBar from '../ReplyBar' -import DeleteMask from '../DeleteMask' import Footer from '../Footer' import { @@ -39,11 +38,15 @@ const getSelection = () => { type TProps = { data: TComment - tobeDeleteId: string isReply?: boolean + showInnerRef?: boolean } -const DefaultLayout: FC = ({ data, tobeDeleteId, isReply = false }) => { +const DefaultLayout: FC = ({ + data, + isReply = false, + showInnerRef = false, +}) => { const { isPinned, meta } = data const { isArticleAuthorUpvoted } = meta const isSolution = false @@ -56,8 +59,7 @@ const DefaultLayout: FC = ({ data, tobeDeleteId, isReply = false }) => { 置顶讨论 )} - - + = ({ data, tobeDeleteId, isReply = false }) => { /> {isArticleAuthorUpvoted && ( 作者顶过} + content={作者赞过} placement="bottom" noPadding > - + )} {isSolution && ( @@ -90,9 +92,9 @@ const DefaultLayout: FC = ({ data, tobeDeleteId, isReply = false }) => { -
+
- {data.replyTo && } + {!isReply && data.replyTo && } = (props) => { diff --git a/src/containers/unit/Comments/Comment/Header.tsx b/src/containers/unit/Comments/Comment/Header.tsx index a07967327..86f989b74 100755 --- a/src/containers/unit/Comments/Comment/Header.tsx +++ b/src/containers/unit/Comments/Comment/Header.tsx @@ -17,15 +17,19 @@ import { Nickname, UserBase, AuthorTag, + RefToOther, + RefLabel, + RefUser, ShortIntro, } from '../styles/comment/header' type TProps = { data: TComment + showInnerRef: boolean } -const CommentHeader: FC = ({ data }) => { - const { author } = data +const CommentHeader: FC = ({ data, showInnerRef }) => { + const { author, meta } = data const avatarSize = author.bio ? 26 : 24 return ( @@ -42,6 +46,12 @@ const CommentHeader: FC = ({ data }) => { {author.nickname} {data.isArticleAuthor && 作者} + {showInnerRef && meta.isReplyToOthers && ( + + 回复 + {data.replyTo?.author?.nickname} + + )} diff --git a/src/containers/unit/Comments/Comment/MobileView/index.tsx b/src/containers/unit/Comments/Comment/MobileView/index.tsx index f30bda728..21e2ffdb9 100644 --- a/src/containers/unit/Comments/Comment/MobileView/index.tsx +++ b/src/containers/unit/Comments/Comment/MobileView/index.tsx @@ -5,7 +5,6 @@ import MarkDownRender from '@/components/MarkDownRender' import Upvote from '@/components/Upvote' import ReplyBar from '../ReplyBar' -import DeleteMask from '../DeleteMask' import Footer from '../Footer' import Header from './Header' @@ -18,11 +17,10 @@ import { CommentBodyInfo, } from '../../styles/comment/mobile_view/index' -const MobileView = ({ data, tobeDeleteId, accountInfo }) => { +const MobileView = ({ data, accountInfo }) => { return ( - - +
diff --git a/src/containers/unit/Comments/CommentBodyEditor.tsx b/src/containers/unit/Comments/CommentBodyEditor.tsx deleted file mode 100755 index 3c7a9845c..000000000 --- a/src/containers/unit/Comments/CommentBodyEditor.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { FC, memo } from 'react' -import dynamic from 'next/dynamic' - -import { InputEditorWrapper } from './styles/comment_editor' -import EditorFooter from './EditorFooter' - -import { - // onCommentInputChange, - backToEditor, - createCommentPreview, - onCommentInputBlur, -} from './logic' - -export const BodyEditor = dynamic( - () => import('@/containers/editor/RichEditor'), - { - /* eslint-disable react/display-name */ - loading: () =>
loading
, - }, -) - -type TProps = { - showInputEditor?: boolean - body: string - onCreate: () => void - creating: boolean -} - -const CommentBodyEditor: FC = ({ - showInputEditor = true, - body, - onCreate, - creating, -}) => { - return ( -
- - - - - -
- ) -} - -export default memo(CommentBodyEditor) diff --git a/src/containers/unit/Comments/CommentEditor.tsx b/src/containers/unit/Comments/CommentEditor.tsx deleted file mode 100755 index 57c3127bf..000000000 --- a/src/containers/unit/Comments/CommentEditor.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { FC, memo } from 'react' - -import type { TAccount, TUser } from '@/spec' -import MarkDownRender from '@/components/MarkDownRender' - -import EditorHeader from './EditorHeader' -import EditorFooter from './EditorFooter' -import CommentBodyEditor from './CommentBodyEditor' - -import { Container, PreviewerWrapper } from './styles/comment_editor' -import { backToEditor, createCommentPreview } from './logic' - -type TProps = { - referUsers: TUser[] - accountInfo: TAccount - - /* TODO: () => void */ - onCreate?: any - - restProps: { - countCurrent: number - showInputBox: boolean - showInputEditor: boolean - showInputPreview: boolean - editContent: string - creating: boolean - } -} - -const CommentEditor: FC = (props) => { - const { - referUsers, - accountInfo, - onCreate, - restProps: { - countCurrent, - showInputBox, - showInputEditor, - showInputPreview, - editContent, - creating, - }, - } = props - - return ( - - - {showInputEditor && ( - - )} - {showInputPreview && ( -
- - - - -
- )} -
- ) -} - -export default memo(CommentEditor) diff --git a/src/containers/unit/Comments/CommentReplyEditor.tsx b/src/containers/unit/Comments/CommentReplyEditor.tsx deleted file mode 100755 index 773c5c322..000000000 --- a/src/containers/unit/Comments/CommentReplyEditor.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import { FC, memo } from 'react' -import dynamic from 'next/dynamic' - -import type { TAccount, TUser, TComment } from '@/spec' - -import MarkDownRender from '@/components/MarkDownRender' - -import ReplyToBar from './ReplyToBar' -import ReplyEditorHeader from './ReplyEditorHeader' -import EditorFooter from './EditorFooter' - -import { - Wrapper, - InputEditorWrapper, - PreviewWrapper, -} from './styles/comment_reply_editor' - -import { - onReplyInputChange, - createReplyComment, - replyBackToEditor, - replyCommentPreview, -} from './logic' - -export const BodyEditor = dynamic( - () => import('@/containers/editor/RichEditor'), - { - /* eslint-disable react/display-name */ - loading: () =>
loading
, - }, -) - -type TProps = { - referUsers: TUser[] - show: boolean - isEdit: boolean - accountInfo: TAccount - showReplyPreview: boolean - - restProps: { - countCurrent: number - replyContent: string - replyToComment: TComment - replying: boolean - } -} - -const CommentReplyEditor: FC = ({ - referUsers, - show, - isEdit, - accountInfo, - showReplyPreview, - restProps: { countCurrent, replyContent, replyToComment, replying }, -}) => { - return ( - - - - {!isEdit && } - - {show ? ( -
- - - -
- ) : ( - - - - )} - -
- ) -} - -export default memo(CommentReplyEditor) diff --git a/src/containers/unit/Comments/Editor/BodyEditor.tsx b/src/containers/unit/Comments/Editor/BodyEditor.tsx new file mode 100755 index 000000000..123ea5871 --- /dev/null +++ b/src/containers/unit/Comments/Editor/BodyEditor.tsx @@ -0,0 +1,28 @@ +import { FC, memo } from 'react' + +import RichEditor from '@/containers/editor/RichEditor' + +type TProps = { + body?: string + onChange?: (v: string) => void + placeholder?: string +} + +const CommentBodyEditor: FC = ({ + body, + onChange, + placeholder = "// 评论内容('Tab' 键快速插入)", +}) => { + return ( +
+ onChange(JSON.stringify(v))} + /> +
+ ) +} + +export default memo(CommentBodyEditor) diff --git a/src/containers/unit/Comments/Editor/Footer.tsx b/src/containers/unit/Comments/Editor/Footer.tsx new file mode 100755 index 000000000..19e2038ed --- /dev/null +++ b/src/containers/unit/Comments/Editor/Footer.tsx @@ -0,0 +1,43 @@ +import { FC, memo } from 'react' + +import type { TSubmitState } from '@/spec' + +import WordsCounter from '@/components/WordsCounter' +import SubmitButton from '@/components/Buttons/SubmitButton' + +import { Wrapper } from '../styles/editor/footer' +import { setWordsCountState } from '../logic' + +type TProps = { + body: string + label?: string + submitState: TSubmitState + onPublish: () => void + onCancel: () => void +} + +const EditorFooter: FC = ({ + body, + label = '发 布', + submitState, + onPublish, + onCancel, +}) => ( + + + + +) + +export default memo(EditorFooter) diff --git a/src/containers/unit/Comments/Editor/Header.tsx b/src/containers/unit/Comments/Editor/Header.tsx new file mode 100755 index 000000000..b2b735667 --- /dev/null +++ b/src/containers/unit/Comments/Editor/Header.tsx @@ -0,0 +1,45 @@ +import { FC, memo } from 'react' + +import type { TAccount } from '@/spec' +import { ICON } from '@/config' + +import { SpaceGrow } from '@/components/Common' + +import { + Wrapper, + ExpandWrapper, + HintText, + UserAvatar, + LeaveResponseText, + LeaveResponseUsername, + PenIcon, +} from '../styles/editor/header' + +import { openEditor } from '../logic' + +type TProps = { + accountInfo: TAccount + showEditor: boolean +} + +const EditorHeader: FC = ({ accountInfo, showEditor }) => { + if (showEditor) { + return ( + + 创建评论: + + {accountInfo.nickname} + + ) + } + return ( + + + 参与讨论 + + + + ) +} + +export default memo(EditorHeader) diff --git a/src/containers/unit/Comments/Editor/PublishEditor.tsx b/src/containers/unit/Comments/Editor/PublishEditor.tsx new file mode 100644 index 000000000..e1c3c53e7 --- /dev/null +++ b/src/containers/unit/Comments/Editor/PublishEditor.tsx @@ -0,0 +1,50 @@ +import { FC, memo } from 'react' + +import type { TAccount, TSubmitState } from '@/spec' + +import Header from './Header' +import BodyEditor from './BodyEditor' +import Footer from './Footer' + +import { Wrapper, ExpandWrapper } from '../styles/editor/publish_editor' +import { commentOnChange, createComment, closeEditor } from '../logic' + +type TProps = { + accountInfo: TAccount + body: string + submitState: TSubmitState + showEditor: boolean +} + +const PublishEditor: FC = ({ + accountInfo, + submitState, + showEditor, + body, +}) => { + if (!showEditor) { + return ( + +
+ + ) + } + return ( + +
+ commentOnChange(v, 'commentBody')} + /> + +