diff --git a/public/icons/static/article/cc-by.svg b/public/icons/static/article/cc-by.svg new file mode 100644 index 000000000..211260d5b --- /dev/null +++ b/public/icons/static/article/cc-by.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/static/article/cc-nc.svg b/public/icons/static/article/cc-nc.svg new file mode 100644 index 000000000..0db547ce7 --- /dev/null +++ b/public/icons/static/article/cc-nc.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/static/article/cc-nd.svg b/public/icons/static/article/cc-nd.svg new file mode 100644 index 000000000..a632ac135 --- /dev/null +++ b/public/icons/static/article/cc-nd.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/static/article/cc-raw.svg b/public/icons/static/article/cc-raw.svg new file mode 100644 index 000000000..99b55cc9f --- /dev/null +++ b/public/icons/static/article/cc-raw.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/static/article/cc.svg b/public/icons/static/article/cc.svg new file mode 100644 index 000000000..3dfd59cf0 --- /dev/null +++ b/public/icons/static/article/cc.svg @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/public/icons/static/article/collect-bookmark.svg b/public/icons/static/article/collect-bookmark.svg new file mode 100644 index 000000000..c568aa01a --- /dev/null +++ b/public/icons/static/article/collect-bookmark.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/static/article/copyright-approve.svg b/public/icons/static/article/copyright-approve.svg new file mode 100644 index 000000000..7dd38a7cd --- /dev/null +++ b/public/icons/static/article/copyright-approve.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/static/article/copyright-forbid.svg b/public/icons/static/article/copyright-forbid.svg new file mode 100644 index 000000000..a8c511d08 --- /dev/null +++ b/public/icons/static/article/copyright-forbid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/static/article/copyright-printer.svg b/public/icons/static/article/copyright-printer.svg new file mode 100644 index 000000000..34ea8a5a0 --- /dev/null +++ b/public/icons/static/article/copyright-printer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/icons/static/article/copyright.svg b/public/icons/static/article/copyright.svg new file mode 100644 index 000000000..191dbc07d --- /dev/null +++ b/public/icons/static/article/copyright.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/components/Buttons/IconButton.tsx b/src/components/Buttons/IconButton.tsx index 87667ab6d..c34b1c8f0 100644 --- a/src/components/Buttons/IconButton.tsx +++ b/src/components/Buttons/IconButton.tsx @@ -30,7 +30,7 @@ const IconButton: FC = ({ active = false, dimWhenIdle = false, hint = null, - hintDelay = 1000, + hintDelay = 500, hintPlacement = 'top', onClick = console.log, }) => { diff --git a/src/components/Buttons/styles/arrow_link.ts b/src/components/Buttons/styles/arrow_link.ts index ff0ba243e..45d00662a 100644 --- a/src/components/Buttons/styles/arrow_link.ts +++ b/src/components/Buttons/styles/arrow_link.ts @@ -14,17 +14,17 @@ export const Wrapper = styled.a` ` type TText = { hoverColor: string; size: string } export const Text = styled.div` - color: ${({ color }) => color || theme('thread.articleDigest')}; + color: ${({ color }) => color || '#327ca1'}; font-size: ${({ size }) => getTextSize(size)}; ${Wrapper}:hover & { - color: ${({ hoverColor }) => hoverColor || theme('thread.articleTitle')}; + color: ${({ hoverColor }) => hoverColor || '#327ca1'}; visibility: visible; } ` type TIcon = { color: string; size: string } const Icon = styled(Img)` - fill: ${({ color }) => color || theme('thread.articleDigest')}; + fill: ${({ color }) => color || '#327ca1'}; width: ${({ size }) => getIconSize(size)}; height: ${({ size }) => getIconSize(size)}; display: block; @@ -37,7 +37,7 @@ export const RightIcon = styled(Icon)<{ hoverColor: string }>` visibility: hidden; ${Wrapper}:hover & { - fill: ${({ hoverColor }) => hoverColor || theme('thread.articleTitle')}; + fill: ${({ hoverColor }) => hoverColor || '#327ca1'}; margin-left: 10px; visibility: visible; } diff --git a/src/components/Copyright/Label.tsx b/src/components/Copyright/Label.tsx new file mode 100644 index 000000000..c561d40b1 --- /dev/null +++ b/src/components/Copyright/Label.tsx @@ -0,0 +1,41 @@ +import { FC, memo } from 'react' + +import { ICON } from '@/config' +import { Wrapper, Icon, Text } from './styles/label' + +type TProps = { + type?: 'cc' | 'approve' | 'forbid' +} + +const Label: FC = ({ type }) => { + switch (type) { + case 'approve': { + return ( + + + 转载需授权 + + ) + } + + case 'forbid': { + return ( + + + 禁止转载 + + ) + } + + default: { + return ( + + + 知识共享 4.0 + + ) + } + } +} + +export default memo(Label) diff --git a/src/components/Copyright/ReadOnlyPanel.tsx b/src/components/Copyright/ReadOnlyPanel.tsx new file mode 100644 index 000000000..6508ed241 --- /dev/null +++ b/src/components/Copyright/ReadOnlyPanel.tsx @@ -0,0 +1,88 @@ +import { FC, memo } from 'react' + +import { ICON } from '@/config' +import { ArrowLink } from '@/components/Buttons' + +import { + Wrapper, + Header, + Icon, + Title, + Desc, + Items, + DescItem, + Footer, +} from './styles/readonly_panel' + +type TProps = { + type?: 'cc' | 'approve' | 'forbid' +} + +const ReadOnlyPanel: FC = ({ type }) => { + switch (type) { + case 'approve': { + return ( + +
+ + 转载需授权 +
+ + 根据作者设置,转载需获取本人授权。相关联系方式可参考作者主页。 + +
+ ) + } + + case 'forbid': { + return ( + +
+ + 禁止转载 +
+ + 根据作者设置,本文严禁任何方式的转载,如有疑问,请尝试联系作者。 + +
+ ) + } + + default: { + return ( + +
+ + 知识共享 4.0 +
+ + + 本作品采用知识共享「署名-非商业性使用-禁止演绎 4.0 + 国际」许可证授权。 + + + 署名 + + + 非商业性使用 + + + 禁止演绎 + + + +
+ + 查看完整版本 + +
+
+ ) + } + } +} + +export default memo(ReadOnlyPanel) diff --git a/src/components/Copyright/index.tsx b/src/components/Copyright/index.tsx new file mode 100755 index 000000000..a14ca87a5 --- /dev/null +++ b/src/components/Copyright/index.tsx @@ -0,0 +1,76 @@ +/* + * + * Copyright + * + */ + +import { FC, memo } from 'react' + +import type { TCopyright } from '@/spec' +import Tooltip from '@/components/Tooltip' +import { buildLog } from '@/utils' + +import Label from './Label' +import SettingMenu from '@/components/SettingMenu' +import ReadOnlyPanel from './ReadOnlyPanel' +import { Wrapper } from './styles' + +/* eslint-disable-next-line */ +const log = buildLog('c:Copyright:index') + +const options = [ + { + title: '知识共享 4.0', + desc: '署名-非商业性使用-禁止演绎', + key: 'cc', + }, + { + title: '转载需授权', + desc: '转载需得到我的明确授权。', + key: 'approve', + }, + { + title: '禁止转载', + desc: '禁止一切形式的转载,有疑问联系我。', + key: 'forbid', + }, +] + +type TProps = { + testid?: string + type?: TCopyright + mode?: 'readonly' | 'editable' + onChange?: (type: string) => void +} + +const Copyright: FC = ({ + testid = 'copyright', + type = 'cc', + mode = 'readonly', + onChange = log, +}) => { + return ( + + + ) : ( + + ) + } + placement="top" + trigger="click" + noPadding + > + + + ) +} + +export default memo(Copyright) diff --git a/src/components/Copyright/styles/index.ts b/src/components/Copyright/styles/index.ts new file mode 100755 index 000000000..82dbbc6f1 --- /dev/null +++ b/src/components/Copyright/styles/index.ts @@ -0,0 +1,23 @@ +import styled from 'styled-components' + +import type { TTestable } from '@/spec' + +import Img from '@/Img' +import { css, theme } from '@/utils' + +export const Wrapper = styled.div.attrs(({ testid }: TTestable) => ({ + 'data-test-id': testid, +}))`` + +export const Label = styled.div` + ${css.flex('align-center')}; +` +export const Icon = styled(Img)` + ${css.size(14)}; + fill: ${theme('thread.articleDigest')}; +` +export const Text = styled.div` + font-size: 12px; + color: ${theme('thread.articleDigest')}; + margin-right: 5px; +` diff --git a/src/components/Copyright/styles/label.ts b/src/components/Copyright/styles/label.ts new file mode 100755 index 000000000..d5c3eba51 --- /dev/null +++ b/src/components/Copyright/styles/label.ts @@ -0,0 +1,29 @@ +import styled from 'styled-components' + +import Img from '@/Img' +import { css, theme } from '@/utils' + +export const Wrapper = styled.div` + ${css.flex('align-center')}; + cursor: pointer; +` +export const Icon = styled(Img)` + fill: ${theme('thread.articleDigest')}; + ${css.size(13)}; + + ${Wrapper}:hover & { + fill: ${theme('thread.articleTitle')}; + } + + transition: fill 0.2s; +` +export const Text = styled.div` + font-size: 13px; + color: ${theme('thread.articleDigest')}; + margin-left: 6px; + + ${Wrapper}:hover & { + color: ${theme('thread.articleTitle')}; + } + transition: color 0.2s; +` diff --git a/src/components/Copyright/styles/readonly_panel.ts b/src/components/Copyright/styles/readonly_panel.ts new file mode 100755 index 000000000..e055e97b9 --- /dev/null +++ b/src/components/Copyright/styles/readonly_panel.ts @@ -0,0 +1,39 @@ +import styled from 'styled-components' +import IconText from '@/components/IconText' + +import Img from '@/Img' +import { css, theme } from '@/utils' + +export const Wrapper = styled.div` + ${css.flexColumn()}; + width: 240px; + padding-left: 5px; +` +export const Header = styled.div` + ${css.flex('align-center')}; +` +export const Icon = styled(Img)` + ${css.size(18)}; + fill: ${theme('thread.articleTitle')}; +` +export const Title = styled.div` + font-size: 16px; + color: ${theme('thread.articleTitle')}; + margin-left: 8px; +` +export const Desc = styled.div` + font-size: 13px; + color: ${theme('thread.articleDigest')}; + margin-top: 8px; + margin-bottom: 8px; +` +export const Items = styled.div` + margin-top: 10px; + margin-bottom: 6px; +` +export const DescItem = styled(IconText)` + margin-bottom: 3px; +` +export const Footer = styled.div` + ${css.flex('align-center')}; +` diff --git a/src/components/Copyright/tests/index.test.ts b/src/components/Copyright/tests/index.test.ts new file mode 100755 index 000000000..53890bb26 --- /dev/null +++ b/src/components/Copyright/tests/index.test.ts @@ -0,0 +1,10 @@ +// import React from 'react' +// import { shallow } from 'enzyme' + +// import Copyright from '../index' + +describe('TODO ', () => { + it('Expect to have unit tests specified', () => { + expect(true).toEqual(true) + }) +}) diff --git a/src/components/IconText/index.tsx b/src/components/IconText/index.tsx index aea5babc2..239ea4139 100755 --- a/src/components/IconText/index.tsx +++ b/src/components/IconText/index.tsx @@ -7,6 +7,7 @@ import { FC, ReactNode, memo } from 'react' import type { TSIZE } from '@/spec' +import { ICON } from '@/config' import { buildLog, nilOrEmpty } from '@/utils' import { SIZE } from '@/constant' @@ -16,26 +17,44 @@ import { Wrapper, Icon, Text } from './styles' const log = buildLog('c:IconText:index') type TProps = { - iconSrc: string + iconSrc?: string | null + path?: string | null round?: boolean children: ReactNode size?: TSIZE margin?: string + highlight?: boolean + className?: string } const IconText: FC = ({ - iconSrc, + className = '', + iconSrc = null, + path = null, round = false, children, size = SIZE.SMALL, margin, -}) => ( - - {!nilOrEmpty(iconSrc) && ( - - )} - {children} - -) + highlight = false, +}) => { + const src = iconSrc || `${ICON}/${path}` + + return ( + + {!nilOrEmpty(src) && ( + + )} + + {children} + + + ) +} export default memo(IconText) diff --git a/src/components/IconText/styles/index.ts b/src/components/IconText/styles/index.ts index c437d2764..8e7eb61c0 100755 --- a/src/components/IconText/styles/index.ts +++ b/src/components/IconText/styles/index.ts @@ -10,6 +10,7 @@ type TIcon = { size: TSIZE margin: string round: boolean + highlight: boolean } export const Wrapper = styled.div.attrs(({ testid }: TTestable) => ({ @@ -18,15 +19,22 @@ export const Wrapper = styled.div.attrs(({ testid }: TTestable) => ({ ${css.flex('align-center')}; ` export const Icon = styled(Img)` - fill: ${theme('thread.articleDigest')}; + fill: ${({ highlight }) => + highlight ? theme('thread.articleTitle') : theme('thread.articleDigest')}; width: ${({ size }) => getIconSize(size)}; height: ${({ size }) => getIconSize(size)}; margin-right: ${({ size, margin }) => margin || getMargin(size)}; display: block; border-radius: ${({ round }) => (round ? '100%' : '0')}; ` -export const Text = styled.div<{ size: TSIZE }>` +type TText = { + size: TSIZE + highlight: boolean +} + +export const Text = styled.div` ${css.flex('align-center')}; - color: ${theme('thread.articleDigest')}; + color: ${({ highlight }) => + highlight ? theme('thread.articleTitle') : theme('thread.articleDigest')}; font-size: ${({ size }) => getTextSize(size)}; ` diff --git a/src/components/PromotionList/Spotlight.tsx b/src/components/PromotionList/Spotlight.tsx index 7a3623af7..6267212ae 100755 --- a/src/components/PromotionList/Spotlight.tsx +++ b/src/components/PromotionList/Spotlight.tsx @@ -3,10 +3,10 @@ import { FC, memo } from 'react' import type { TItem } from './spec' import { Wrapper, - ItemWrapper, Header, - Logo, Title, + JoinWrapper, + JoinNumber, Desc, } from './styles/spotlight' @@ -16,13 +16,14 @@ type TProps = { const Spotlight: FC = ({ item }) => ( - -
- {item.title} - -
- {item.desc} -
+
+ {item.title} +
+ {item.desc} + + 58 + 人已加入 +
) diff --git a/src/components/PromotionList/styles/index.ts b/src/components/PromotionList/styles/index.ts index c2422eae3..00350ba5e 100755 --- a/src/components/PromotionList/styles/index.ts +++ b/src/components/PromotionList/styles/index.ts @@ -3,10 +3,10 @@ import styled from 'styled-components' import { css, theme } from '@/utils' export const Wrapper = styled.div` - margin-left: 20px; + margin-left: 15px; min-height: 150px; max-width: 180px; - margin-top: 10px; + margin-top: 15px; ` export const Header = styled.div` ${css.flex('justify-between', 'align-center')}; diff --git a/src/components/PromotionList/styles/spotlight.ts b/src/components/PromotionList/styles/spotlight.ts index 258dde889..e3b512b78 100755 --- a/src/components/PromotionList/styles/spotlight.ts +++ b/src/components/PromotionList/styles/spotlight.ts @@ -1,37 +1,36 @@ import styled from 'styled-components' import { css, theme } from '@/utils' -import Img from '@/Img' export const Wrapper = styled.div` ${css.flexColumn()}; background: #06303b; - padding: 15px 10px; + padding: 10px; width: 100%; min-height: 120px; border-radius: 5px; - margin-left: -5px; -` -export const ItemWrapper = styled.div` - ${css.flexColumn()}; + margin-left: -8px; ` export const Header = styled.div` ${css.flex('align-center', 'justify-between')}; margin-left: 2px; ` -export const Logo = styled(Img)` - ${css.size(25)}; - border-radius: 5px; - margin-right: 10px; - /* TODO: for dark themes */ - filter: saturate(0.8); -` export const Title = styled.div` color: ${theme('thread.articleTitle')}; font-size: 15px; ` export const Desc = styled.div` color: ${theme('thread.articleDigest')}; + flex-grow: 1; font-size: 12px; margin-top: 12px; ` +export const JoinWrapper = styled.div` + ${css.flex('align-center')}; + color: ${theme('thread.articleDigest')}; + font-size: 12px; +` +export const JoinNumber = styled.div` + color: ${theme('thread.articleTitle')}; + margin-right: 3px; +` diff --git a/src/components/SettingMenu/index.tsx b/src/components/SettingMenu/index.tsx new file mode 100755 index 000000000..2214b3140 --- /dev/null +++ b/src/components/SettingMenu/index.tsx @@ -0,0 +1,53 @@ +/* + * + * SettingMenu + * + */ + +import { FC, memo } from 'react' + +import { buildLog } from '@/utils' + +import { Wrapper, Option, ActiveDot, Title, Desc } from './styles' + +/* eslint-disable-next-line */ +const log = buildLog('c:SettingMenu:index') + +type TProps = { + testid?: string + width?: number | null + activeKey?: string + withActive?: boolean + options: { + title: string + desc?: string + key: string + }[] + onChange?: (type: string) => void +} + +const SettingMenu: FC = ({ + testid = 'setting-menu', + options, + width = 220, + activeKey = null, + onChange = log, +}) => { + return ( + + {options.map((option) => ( + + ))} + + ) +} + +export default memo(SettingMenu) diff --git a/src/components/SettingMenu/styles/index.ts b/src/components/SettingMenu/styles/index.ts new file mode 100755 index 000000000..5510187f0 --- /dev/null +++ b/src/components/SettingMenu/styles/index.ts @@ -0,0 +1,42 @@ +import styled from 'styled-components' + +import type { TTestable, TActive } from '@/spec' + +// import Img from '@/Img' +import { css, theme } from '@/utils' + +type TWrapper = TTestable & { width: number } + +export const Wrapper = styled.div.attrs(({ testid }: TTestable) => ({ + 'data-test-id': testid, +}))` + ${css.flexColumn()}; + width: ${({ width }) => `${width}px`}; +` +export const Option = styled.div` + position: relative; + padding: 10px 15px; + padding-left: 40px; + background: ${({ $active }) => ($active ? '#0d3b4a' : 'transparent')}; + + &:hover { + cursor: pointer; + background: #0d3b4a; + } +` +export const ActiveDot = styled.div` + ${css.circle(6)}; + background: #107eae; + position: absolute; + left: 20px; + top: 18px; +` +export const Title = styled.div` + color: ${theme('thread.articleTitle')}; + font-size: 15px; +` +export const Desc = styled.div` + color: ${theme('thread.articleDigest')}; + font-size: 12px; + margin-top: 2px; +` diff --git a/src/components/SettingMenu/tests/index.test.ts b/src/components/SettingMenu/tests/index.test.ts new file mode 100755 index 000000000..8b87ddbc6 --- /dev/null +++ b/src/components/SettingMenu/tests/index.test.ts @@ -0,0 +1,10 @@ +// import React from 'react' +// import { shallow } from 'enzyme' + +// import SettingMenu from '../index' + +describe('TODO ', () => { + it('Expect to have unit tests specified', () => { + expect(true).toEqual(true) + }) +}) diff --git a/src/components/Tooltip/styles/index.ts b/src/components/Tooltip/styles/index.ts index f62365c0e..b7c1bc904 100755 --- a/src/components/Tooltip/styles/index.ts +++ b/src/components/Tooltip/styles/index.ts @@ -10,6 +10,8 @@ export const StyledTippy = styled(Tippy)` box-shadow: ${theme('popover.boxShadow')}; outline: none; max-width: 480px !important; + border: 1px solid; + border-color: ${theme('popover.borderColor')}; border-radius: 5px; padding: 10px; diff --git a/src/containers/unit/ArticleFooter/Actions/ActionItem.js b/src/containers/unit/ArticleFooter/Actions/ActionItem.tsx similarity index 70% rename from src/containers/unit/ArticleFooter/Actions/ActionItem.js rename to src/containers/unit/ArticleFooter/Actions/ActionItem.tsx index 0df945244..f2dd461ba 100644 --- a/src/containers/unit/ArticleFooter/Actions/ActionItem.js +++ b/src/containers/unit/ArticleFooter/Actions/ActionItem.tsx @@ -1,5 +1,6 @@ -import React from 'react' +import { FC, memo } from 'react' +import type { TAccount, TArticle, TCommunity } from '@/spec' import { ICON, ICON_BASE } from '@/config' import ImgFallback from '@/components/ImgFallback' @@ -15,7 +16,18 @@ import { CommunityIcon, } from '../styles/actions/action_item' -const ActionItem = ({ item: { author, article, community, insertedAt } }) => { +type TProps = { + item: { + author: TAccount + article: TArticle + community: TCommunity + insertedAt: string + } +} + +const ActionItem: FC = ({ + item: { author, article, community, insertedAt }, +}) => { return ( @@ -37,4 +49,4 @@ const ActionItem = ({ item: { author, article, community, insertedAt } }) => { ) } -export default React.memo(ActionItem) +export default memo(ActionItem) diff --git a/src/containers/unit/ArticleFooter/Actions/OperationPanel.js b/src/containers/unit/ArticleFooter/Actions/OperationPanel.tsx similarity index 87% rename from src/containers/unit/ArticleFooter/Actions/OperationPanel.js rename to src/containers/unit/ArticleFooter/Actions/OperationPanel.tsx index 98e99053e..be6cd51c4 100644 --- a/src/containers/unit/ArticleFooter/Actions/OperationPanel.js +++ b/src/containers/unit/ArticleFooter/Actions/OperationPanel.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import { FC, memo } from 'react' import { ICON } from '@/config' @@ -28,7 +28,7 @@ const tmpItems = [ }, ] -const OperationPanel = () => { +const OperationPanel: FC = () => { return ( @@ -41,4 +41,4 @@ const OperationPanel = () => { ) } -export default React.memo(OperationPanel) +export default memo(OperationPanel) diff --git a/src/containers/unit/ArticleFooter/Actions/RefersPanel.js b/src/containers/unit/ArticleFooter/Actions/RefersPanel.tsx similarity index 91% rename from src/containers/unit/ArticleFooter/Actions/RefersPanel.js rename to src/containers/unit/ArticleFooter/Actions/RefersPanel.tsx index f590a947a..cd5bc15db 100644 --- a/src/containers/unit/ArticleFooter/Actions/RefersPanel.js +++ b/src/containers/unit/ArticleFooter/Actions/RefersPanel.tsx @@ -1,4 +1,4 @@ -import React from 'react' +import { FC, memo } from 'react' import { ICON } from '@/config' @@ -43,7 +43,7 @@ const tmpItems = [ }, ] -const RefersPanel = () => { +const RefersPanel: FC = () => { return ( @@ -56,4 +56,4 @@ const RefersPanel = () => { ) } -export default React.memo(RefersPanel) +export default memo(RefersPanel) diff --git a/src/containers/unit/ArticleFooter/Actions/index.js b/src/containers/unit/ArticleFooter/Actions/index.js deleted file mode 100644 index 8427d45ff..000000000 --- a/src/containers/unit/ArticleFooter/Actions/index.js +++ /dev/null @@ -1,43 +0,0 @@ -import React from 'react' - -import { ICON } from '@/config' -import { useDevice } from '@/hooks' - -import { Space } from '@/components/Common' - -import { - Wrapper, - Item, - ReferIcon, - RecordIcon, - ReferNum, - Text, -} from '../styles/actions' -import { toggleActionPanel } from '../logic' - -const Actions = ({ showReferenceList, showOperationList }) => { - const { isMobile } = useDevice() - - return ( - - toggleActionPanel('reference-list')}> - - - 6 - {!isMobile && } - 引用 - - - - toggleActionPanel('operation-list')}> - - - 操作 - {!isMobile && 记录} - - - - ) -} - -export default React.memo(Actions) diff --git a/src/containers/unit/ArticleFooter/Actions/index.tsx b/src/containers/unit/ArticleFooter/Actions/index.tsx new file mode 100644 index 000000000..eb4eea473 --- /dev/null +++ b/src/containers/unit/ArticleFooter/Actions/index.tsx @@ -0,0 +1,39 @@ +import { FC, memo } from 'react' + +import { useDevice } from '@/hooks' + +import DotDivider from '@/components/DotDivider' + +import { Wrapper, Item, ReferNum, Text } from '../styles/actions' +import { toggleActionPanel } from '../logic' + +type TProps = { + showReferenceList: boolean + showOperationList: boolean +} + +const Actions: FC = ({ showReferenceList, showOperationList }) => { + const { isMobile } = useDevice() + + return ( + + toggleActionPanel('reference-list')}> + + 6 + {!isMobile && } + 引用 + + + + toggleActionPanel('operation-list')}> + 日志 + + + + 举报 + + + ) +} + +export default memo(Actions) diff --git a/src/containers/unit/ArticleFooter/AuthorInfo/SocialList.js b/src/containers/unit/ArticleFooter/AuthorInfo/SocialList.js deleted file mode 100644 index e542b9787..000000000 --- a/src/containers/unit/ArticleFooter/AuthorInfo/SocialList.js +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react' - -import { ICON } from '@/config' -import { Wrapper, CursorDivider, Icon } from '../styles/author_info/social_list' - -const SocialList = ({ items }) => { - return ( - - - {items.map((item) => ( - - ))} - - ) -} - -export default React.memo(SocialList) diff --git a/src/containers/unit/ArticleFooter/AuthorInfo/SocialList.tsx b/src/containers/unit/ArticleFooter/AuthorInfo/SocialList.tsx new file mode 100644 index 000000000..8b8f18888 --- /dev/null +++ b/src/containers/unit/ArticleFooter/AuthorInfo/SocialList.tsx @@ -0,0 +1,22 @@ +import { FC, memo } from 'react' +import { keys } from 'ramda' + +import { ICON } from '@/config' +import { Wrapper, CursorDivider, Icon } from '../styles/author_info/social_list' + +type TProps = { + items: Record +} + +const SocialList: FC = ({ items }) => { + return ( + + + {keys(items).map((platform) => ( + + ))} + + ) +} + +export default memo(SocialList) diff --git a/src/containers/unit/ArticleFooter/AuthorInfo/index.js b/src/containers/unit/ArticleFooter/AuthorInfo/index.tsx similarity index 54% rename from src/containers/unit/ArticleFooter/AuthorInfo/index.js rename to src/containers/unit/ArticleFooter/AuthorInfo/index.tsx index c6b67e843..d39c78ed7 100644 --- a/src/containers/unit/ArticleFooter/AuthorInfo/index.js +++ b/src/containers/unit/ArticleFooter/AuthorInfo/index.tsx @@ -4,10 +4,10 @@ * */ -import React from 'react' -import T from 'prop-types' +import { FC, memo } from 'react' import { isEmpty, pickBy } from 'ramda' +import type { TAccount } from '@/spec' import { buildLog } from '@/utils' import { Button } from '@/components/Buttons' @@ -29,8 +29,16 @@ import { /* eslint-disable-next-line */ const log = buildLog('c:AuthorInfo:index') -const AuthorInfo = ({ testid, author }) => { - const socialItems = pickBy((v) => !!v, author.social) +type TProps = { + testid?: string + author: TAccount +} + +const AuthorInfo: FC = ({ testid = 'author-info', author }) => { + const socialItems = pickBy((v) => !!v, author.social) as Record< + string, + string + > return ( @@ -45,7 +53,7 @@ const AuthorInfo = ({ testid, author }) => { } + fallback={} />