diff --git a/src/components/Buttons/FollowButton/FollowedBtn.js b/src/components/Buttons/FollowButton/FollowedBtn.js deleted file mode 100644 index 9e3197ef4..000000000 --- a/src/components/Buttons/FollowButton/FollowedBtn.js +++ /dev/null @@ -1,30 +0,0 @@ -import React from 'react' - -import { ICON_CMD } from '@/config' -import Button from '@/components/Buttons/Button' - -import { BtnWrapper, WatchIcon, LoadingIcon } from '../styles/follow_button' - -const FollowBtn = ({ size, loading, onClick }) => { - return ( - <> - {loading ? ( - - ) : ( - - )} - - ) -} - -export default React.memo(FollowBtn) diff --git a/src/components/Buttons/FollowButton/FollowedBtn.tsx b/src/components/Buttons/FollowButton/FollowedBtn.tsx new file mode 100644 index 000000000..d5b52ff9a --- /dev/null +++ b/src/components/Buttons/FollowButton/FollowedBtn.tsx @@ -0,0 +1,29 @@ +import { FC, memo } from 'react' + +import { TSIZE_TSM } from '@/spec' +import { LavaLampLoading } from '@/components/Loading' + +import { BtnWrapper, FollowedButton } from '../styles/follow_button' + +type TProps = { + size: TSIZE_TSM + loading: boolean + text: string + onClick: () => void +} + +const FollowBtn: FC = ({ size, loading, text, onClick }) => { + return ( + <> + {loading ? ( + + ) : ( + + {text} + + )} + + ) +} + +export default memo(FollowBtn) diff --git a/src/components/Buttons/FollowButton/FollowingBtn.js b/src/components/Buttons/FollowButton/FollowingBtn.js deleted file mode 100644 index c07b4b228..000000000 --- a/src/components/Buttons/FollowButton/FollowingBtn.js +++ /dev/null @@ -1,49 +0,0 @@ -import React from 'react' - -import { ICON_CMD } from '@/config' - -import Button from '@/components/Buttons/Button' -import Tooltip from '@/components/Tooltip' - -import { - BtnWrapper, - WatchedIcon, - Popinfo, - LoadingIcon, -} from '../styles/follow_button' - -const FollowingBtn = ({ size, loading, noBorderWhenFollowed, onClick }) => { - return ( - <> - {loading ? ( - - ) : ( - 点击取消关注} - > - - - )} - - ) -} - -export default React.memo(FollowingBtn) diff --git a/src/components/Buttons/FollowButton/FollowingBtn.tsx b/src/components/Buttons/FollowButton/FollowingBtn.tsx new file mode 100644 index 000000000..55d04591f --- /dev/null +++ b/src/components/Buttons/FollowButton/FollowingBtn.tsx @@ -0,0 +1,53 @@ +import { FC, memo } from 'react' + +import { TSIZE_TSM } from '@/spec' +import { ICON } from '@/config' + +import { LavaLampLoading } from '@/components/Loading' +import Tooltip from '@/components/Tooltip' + +import { + BtnWrapper, + Popinfo, + CheckedIcon, + FollowingButton, +} from '../styles/follow_button' + +type TProps = { + size: TSIZE_TSM + loading: boolean + text: string + onClick: () => void +} + +const FollowingBtn: FC = ({ size, loading, text, onClick }) => { + return ( + <> + {loading ? ( + + ) : ( + 点击取消关注} + noPadding + > + + + + {text} + + + + )} + + ) +} + +export default memo(FollowingBtn) diff --git a/src/components/Buttons/FollowButton/index.js b/src/components/Buttons/FollowButton/index.js deleted file mode 100644 index a706986b0..000000000 --- a/src/components/Buttons/FollowButton/index.js +++ /dev/null @@ -1,86 +0,0 @@ -/* - * - * FollowButton - * - */ - -import React, { useState, useCallback } from 'react' -import T from 'prop-types' -import { values } from 'ramda' - -import { buildLog } from '@/utils' -import { SIZE } from '@/constant' - -import FollowingBtn from './FollowingBtn' -import FollowedBtn from './FollowedBtn' - -/* eslint-disable-next-line */ -const log = buildLog('c:FollowButton:index') - -const FollowButton = ({ - hasFollowed, - size, - loading, - userId, - fakeLoading, - noBorderWhenFollowed, - onFollow, - onUndoFollow, -}) => { - const [simuLoading, setSimuLoading] = useState(false) - const isLoading = fakeLoading ? simuLoading : loading - - const handleFollow = useCallback(() => { - if (fakeLoading) { - setSimuLoading(true) - setTimeout(() => setSimuLoading(false), 1000) - } - onFollow(userId) - }, [fakeLoading, onFollow, userId]) - - const handleUndoFollow = useCallback(() => { - if (fakeLoading) { - setSimuLoading(true) - setTimeout(() => setSimuLoading(false), 1000) - } - onUndoFollow(userId) - }, [fakeLoading, onUndoFollow, userId]) - - return ( - <> - {hasFollowed ? ( - - ) : ( - - )} - - ) -} - -FollowButton.propTypes = { - hasFollowed: T.bool, - userId: T.string.isRequired, - size: T.oneOf(values(SIZE)), - onFollow: T.func, - onUndoFollow: T.func, - fakeLoading: T.bool, - loading: T.bool, - noBorderWhenFollowed: T.bool, -} - -FollowButton.defaultProps = { - size: SIZE.SMALL, - onFollow: log, - onUndoFollow: log, - fakeLoading: false, - loading: false, - hasFollowed: false, - noBorderWhenFollowed: false, -} - -export default React.memo(FollowButton) diff --git a/src/components/Buttons/FollowButton/index.tsx b/src/components/Buttons/FollowButton/index.tsx new file mode 100644 index 000000000..681d765c3 --- /dev/null +++ b/src/components/Buttons/FollowButton/index.tsx @@ -0,0 +1,80 @@ +/* + * FollowButton + */ + +import { FC, memo, useState, useCallback } from 'react' + +import { TID, TSIZE_TSM } from '@/spec' +import { buildLog } from '@/utils' +import { SIZE } from '@/constant' + +import FollowingBtn from './FollowingBtn' +import FollowedBtn from './FollowedBtn' + +/* eslint-disable-next-line */ +const log = buildLog('c:FollowButton:index') + +type TProps = { + hasFollowed?: boolean + userId?: TID + size?: TSIZE_TSM + loading?: boolean + fakeLoading?: boolean + followText?: string + followingText?: string + onFollow?: (userId: TID) => void + onUndoFollow?: (userId: TID) => void +} + +const FollowButton: FC = ({ + userId, + size = SIZE.SMALL, + fakeLoading = false, + loading = false, + hasFollowed = false, + followText = '关 注', + followingText = '已关注', + onFollow = log, + onUndoFollow = log, +}) => { + const [simuLoading, setSimuLoading] = useState(false) + const isLoading = fakeLoading ? simuLoading : loading + + const handleFollow = useCallback(() => { + if (fakeLoading) { + setSimuLoading(true) + setTimeout(() => setSimuLoading(false), 1500) + } + onFollow(userId) + }, [fakeLoading, onFollow, userId]) + + const handleUndoFollow = useCallback(() => { + if (fakeLoading) { + setSimuLoading(true) + setTimeout(() => setSimuLoading(false), 1500) + } + onUndoFollow(userId) + }, [fakeLoading, onUndoFollow, userId]) + + return ( + <> + {hasFollowed ? ( + + ) : ( + + )} + + ) +} + +export default memo(FollowButton) diff --git a/src/components/Buttons/styles/follow_button/index.ts b/src/components/Buttons/styles/follow_button/index.ts index bec3e5917..e79c0a14d 100644 --- a/src/components/Buttons/styles/follow_button/index.ts +++ b/src/components/Buttons/styles/follow_button/index.ts @@ -1,16 +1,16 @@ import styled from 'styled-components' import { theme, animate, css } from '@/utils' +import Button from '@/components/Buttons/Button' import Img from '@/Img' export const BtnWrapper = styled.div` ${css.flex('align-center')}; + padding: 2px 5px; ` const BtnIcon = styled(Img)` - height: 12px; - width: 12px; - display: block; - margin-right: 3px; + ${css.size(14)}; + margin-right: 2px; ` export const WatchIcon = styled(BtnIcon)` fill: ${theme('button.fg')}; @@ -30,3 +30,23 @@ export const LoadingIcon = styled(BtnIcon)<{ light: boolean }>` ${css.size(15)}; animation: ${animate.rotate360} 1s linear infinite; ` +export const CheckedIcon = styled(BtnIcon)` + fill: ${theme('baseColor.green')}; +` +export const FollowedButton = styled(Button)` + border-radius: 10px; +` +export const FollowingButton = styled(Button)` + color: ${theme('thread.articleTitle')}; + /* color: ${theme('baseColor.green')}; */ + border: none; + border-radius: 10px; + background: #003745; + padding-top: 2px; + padding-bottom: 2px; + + &:hover { + background: #003745; + /* border: 1px solid; */ + } +` diff --git a/src/components/Loading/LavaLampLoading.tsx b/src/components/Loading/LavaLampLoading.tsx index eb2b9c9f5..6f00955dc 100644 --- a/src/components/Loading/LavaLampLoading.tsx +++ b/src/components/Loading/LavaLampLoading.tsx @@ -1,14 +1,19 @@ import { FC, memo } from 'react' -import { range } from 'ramda' +import { range, merge } from 'ramda' + +import type { TSpace, TSIZE_TSM } from '@/spec' +import { SIZE } from '@/constant' -import type { TSpace } from '@/spec' import { Wrapper, Container, Circle } from './styles/lava_lamp_loading' -type TProps = TSpace +type TProps = TSpace & { size?: TSIZE_TSM } const LavaLampLoading: FC = (props) => { + const { size } = props + const _props = merge({ size: size || SIZE.MEDIUM }, props) + return ( - + {range(0, 9).map((num) => ( diff --git a/src/components/Loading/styles/lava_lamp_loading.ts b/src/components/Loading/styles/lava_lamp_loading.ts index daf01b1bb..66c39e237 100644 --- a/src/components/Loading/styles/lava_lamp_loading.ts +++ b/src/components/Loading/styles/lava_lamp_loading.ts @@ -1,8 +1,10 @@ import styled, { keyframes } from 'styled-components' -import type { TSpace } from '@/spec' +import type { TSpace, TSIZE_TSM } from '@/spec' import { css, getRandomInt } from '@/utils' +import { getLavaLampScale } from './metric' + const grow = keyframes` from {transform: scale(0,0); opacity: 0;} to {transform: scale(1,1); opacity: 1;} @@ -11,7 +13,9 @@ const move = keyframes` from {transform: translateX(0px)} to {transform: translateX(80px)} ` -export const Wrapper = styled.div` + +type TWrapper = TSpace & { size: TSIZE_TSM } +export const Wrapper = styled.div` ${css.flex('align-both')}; overflow: hidden; width: 80px; @@ -20,6 +24,8 @@ export const Wrapper = styled.div` margin-right: ${({ right }) => `${right}px` || 0}; margin-top: ${({ top }) => `${top || 0}px`}; margin-bottom: ${({ bottom }) => `${bottom || 0}px`}; + + transform: ${({ size }) => getLavaLampScale(size)}; ` export const Container = styled.div` ${css.flex()}; diff --git a/src/components/Loading/styles/metric.ts b/src/components/Loading/styles/metric.ts new file mode 100644 index 000000000..2884d0487 --- /dev/null +++ b/src/components/Loading/styles/metric.ts @@ -0,0 +1,20 @@ +import type { TSIZE_TSM } from '@/spec' +import { SIZE } from '@/constant' + +export const getLavaLampScale = (size: TSIZE_TSM): string => { + switch (size) { + case SIZE.SMALL: { + return 'scale(0.5);' + } + + case SIZE.MEDIUM: { + return 'scale(0.8);' + } + + default: { + return 'scale(1);' + } + } +} + +export const holder = 1 diff --git a/src/components/Upvote/styles/upvote_btn.ts b/src/components/Upvote/styles/upvote_btn.ts index 09b0e03ac..d2301c6f5 100644 --- a/src/components/Upvote/styles/upvote_btn.ts +++ b/src/components/Upvote/styles/upvote_btn.ts @@ -50,7 +50,7 @@ export const Wrapper = styled.div` display: inline-block; color: ${theme('thread.articleTitle')}; font-size: 15px; - padding: 5px 0; + /* padding: 5px 0; */ margin-top: ${({ type }) => (type === UPVOTE_LAYOUT.DEFAULT ? '4px' : 0)}; appearance: none; background-color: transparent; @@ -164,7 +164,7 @@ export const IconShadow = styled.div<{ type: TUpvoteLayout }>` border-radius: 100%; background: #0f4052; z-index: -1; - opacity: ${({ type }) => (type !== UPVOTE_LAYOUT.ARTICLE ? 0 : 0.6)}; + opacity: 0; ${IconWrapper}:hover & { opacity: 1; diff --git a/src/containers/digest/ArticleDigest/DesktopView/PostLayout/SubCommunity.tsx b/src/containers/digest/ArticleDigest/DesktopView/PostLayout/SubCommunity.tsx index 98ac68e06..c4179e6e1 100644 --- a/src/containers/digest/ArticleDigest/DesktopView/PostLayout/SubCommunity.tsx +++ b/src/containers/digest/ArticleDigest/DesktopView/PostLayout/SubCommunity.tsx @@ -2,7 +2,7 @@ import { FC, memo } from 'react' import { ICON_BASE } from '@/config' -import { Button } from '@/components/Buttons' +import { FollowButton } from '@/components/Buttons' import { Wrapper, @@ -20,9 +20,7 @@ const SubCommunity: FC = () => { javascript 34 关注者 - + ) } diff --git a/src/containers/digest/ArticleDigest/styles/desktop_view/post_layout/sub_community.ts b/src/containers/digest/ArticleDigest/styles/desktop_view/post_layout/sub_community.ts index 8132cc442..8493b2d39 100644 --- a/src/containers/digest/ArticleDigest/styles/desktop_view/post_layout/sub_community.ts +++ b/src/containers/digest/ArticleDigest/styles/desktop_view/post_layout/sub_community.ts @@ -5,6 +5,7 @@ import { theme, css } from '@/utils' export const Wrapper = styled.nav` ${css.flexColumn('align-both')}; + margin-top: 2px; /* margin-left: 8px; ${css.media.laptopL` diff --git a/src/containers/thread/ThreadSidebar/HolyGrailView/CommunityBrief.tsx b/src/containers/thread/ThreadSidebar/HolyGrailView/CommunityBrief.tsx index f4896ed1d..8b219b0c3 100644 --- a/src/containers/thread/ThreadSidebar/HolyGrailView/CommunityBrief.tsx +++ b/src/containers/thread/ThreadSidebar/HolyGrailView/CommunityBrief.tsx @@ -35,7 +35,6 @@ const CommunityBrief: FC = ({ community }) => { onFollow={console.log} onUndoFollow={console.log} size="tiny" - noBorderWhenFollowed /> diff --git a/src/containers/tool/ArticleSticker/RightSticker/DefaultSticker.tsx b/src/containers/tool/ArticleSticker/RightSticker/DefaultSticker.tsx index e404d7c76..a35fcc122 100644 --- a/src/containers/tool/ArticleSticker/RightSticker/DefaultSticker.tsx +++ b/src/containers/tool/ArticleSticker/RightSticker/DefaultSticker.tsx @@ -19,17 +19,17 @@ const ArticleSticker: FC = ({ show, article }) => { shareTo()} size={20} - mLeft={5} - mTop={15} + mLeft={4} + mTop={12} mRight={0} /> diff --git a/src/containers/unit/ArticleFooter/AuthorInfo/index.tsx b/src/containers/unit/ArticleFooter/AuthorInfo/index.tsx index d39c78ed7..a7a43a5fd 100644 --- a/src/containers/unit/ArticleFooter/AuthorInfo/index.tsx +++ b/src/containers/unit/ArticleFooter/AuthorInfo/index.tsx @@ -10,7 +10,7 @@ import { isEmpty, pickBy } from 'ramda' import type { TAccount } from '@/spec' import { buildLog } from '@/utils' -import { Button } from '@/components/Buttons' +import { FollowButton } from '@/components/Buttons' import ImgFallback from '@/components/ImgFallback' import SocialList from './SocialList' @@ -55,9 +55,7 @@ const AuthorInfo: FC = ({ testid = 'author-info', author }) => { src={author.avatar} fallback={} /> - + )