Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions public/icons/static/emotion/emotion.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 8 additions & 9 deletions src/components/Buttons/CopyButton/Animate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,11 @@ import { FC, memo, useEffect, useState } from 'react'

import { ICON } from '@/config'
import { IconButton } from '@/components/Buttons'
import { CopyToClipboard } from 'react-copy-to-clipboard'

import { AnimateOnChange } from 'react-animation'
import { CopyedHintIcon } from '../styles/copy_button'

type TProps = {
value: string
}

const CopyButton: FC<TProps> = ({ value }) => {
const CopyButton: FC = () => {
const [done, setDone] = useState(false)

useEffect(() => {
Expand All @@ -28,9 +23,13 @@ const CopyButton: FC<TProps> = ({ value }) => {
durationOut={100}
>
{!done && (
<CopyToClipboard text={value} onCopy={() => setDone(true)}>
<IconButton path="article/clipboard.svg" mRight={5} />
</CopyToClipboard>
<IconButton
path="article/clipboard.svg"
mRight={5}
onClick={() => {
setDone(true)
}}
/>
)}
{done && <CopyedHintIcon src={`${ICON}/shape/checked.svg`} />}
</AnimateOnChange>
Expand Down
6 changes: 5 additions & 1 deletion src/components/Buttons/CopyButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { FC, memo } from 'react'
import dynamic from 'next/dynamic'

import { CopyToClipboard } from 'react-copy-to-clipboard'

import IconButton from '../IconButton'
import { Wrapper } from '../styles/copy_button'

Expand All @@ -19,7 +21,9 @@ type TProps = {
const CopyButton: FC<TProps> = ({ value }) => {
return (
<Wrapper>
<AnimatedCopyButton value={value} />
<CopyToClipboard text={value}>
<AnimatedCopyButton />
</CopyToClipboard>
</Wrapper>
)
}
Expand Down
33 changes: 15 additions & 18 deletions src/components/Switcher/IconSwitcher.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,19 +49,12 @@ const TabLabel: React.FC<TTabLabel> = ({ item, activeKey, onChange }) => {
}

return (
<Tooltip
content={<DescText>{item.desc}</DescText>}
placement="bottom"
delay={500}
noPadding
>
<Label onClick={() => onChange(item)}>
{!nilOrEmpty(item.localIcon) && <>{item.localIcon}</>}
{!nilOrEmpty(item.iconSrc) && (
<Icon src={item.iconSrc} checked={activeKey === item.key} />
)}
</Label>
</Tooltip>
<Label onClick={() => onChange(item)}>
{!nilOrEmpty(item.localIcon) && <>{item.localIcon}</>}
{!nilOrEmpty(item.iconSrc) && (
<Icon src={item.iconSrc} checked={activeKey === item.key} />
)}
</Label>
)
}

Expand All @@ -79,12 +72,16 @@ const IconSwitcher: FC<TProps> = ({ items, activeKey, onChange }) => {
<AccessZone />
<Tabs>
{items.map((item) => (
<TabLabel
<Tooltip
key={item.key}
item={item}
activeKey={activeKey}
onChange={onChange}
/>
content={<DescText>{item.desc}</DescText>}
placement="top"
delay={500}
forceZIndex
noPadding
>
<TabLabel item={item} activeKey={activeKey} onChange={onChange} />
</Tooltip>
))}
<Slider index={slideIndex} />
</Tabs>
Expand Down
7 changes: 5 additions & 2 deletions src/components/Switcher/styles/icon_selector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ export const Label = styled.label`
width: ${width};
height: ${height};
font-size: 15px;
z-index: 2;
transition: color 0.15s ease-in;

&:hover {
Expand All @@ -57,11 +56,15 @@ export const DescText = styled.div`
`
export const Icon = styled(Img)<{ checked: boolean }>`
fill: ${({ checked }) =>
checked ? '#66b5e8' : theme('thread.articleDigest')};
checked ? theme('thread.articleTitle') : theme('thread.articleDigest')};
width: ${({ checked }) => (checked ? '14px' : '12px')};
height: ${({ checked }) => (checked ? '14px' : '12px')};
display: block;
transition: all 0.25s;

&:hover {
fill: #66b5e8;
}
`
export const Slider = styled.span<{ index: number }>`
${css.flex()};
Expand Down
16 changes: 14 additions & 2 deletions src/components/Tooltip/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,17 @@ type TProps = {
// for same reason, figure out later
contentHeight?: string

/**
* z-index is a magic number for IconSwitcher's mask situation,
* DO NOT USE unless you know what you are doing
* 在类似 IconSwitcher 的场景下(有一个基于 positon: absolute 的滑动遮罩)的场景下,需要将外层
* 的 ContentWrapper z-index 置为 1, 否则滑动遮罩会在最外面。
*
* 理论上 zIndex 一直设置为 1,也没问题,但是会导致某些使用了 Tooltip 的地方有严重的粘滞感,比如 “CopyRight” 那里。
* 暂时没有精力看 Tippy 的具体实现,小心使用。
*/
forceZIndex?: boolean

onShow?: () => void
onHide?: () => void
onConfirm?: () => void
Expand All @@ -57,6 +68,7 @@ const Tooltip: FC<TProps> = ({
content,
hideOnClick = true,
showArrow = false,
forceZIndex = false,
footerBehavior = 'default',
trigger = 'mouseenter focus',
onConfirm,
Expand All @@ -66,15 +78,15 @@ const Tooltip: FC<TProps> = ({
const [active, setActive] = useState(false)

const ContentComp = showArrow ? (
<ContentWrapper contentHeight={contentHeight}>
<ContentWrapper contentHeight={contentHeight} forceZIndex={forceZIndex}>
{active && placement === 'bottom' && <TopArrow />}
{active && placement === 'top' && <BottomArrow />}
{active && placement === 'right' && <LeftArrow />}

<div>{children}</div>
</ContentWrapper>
) : (
<ContentWrapper contentHeight={contentHeight}>
<ContentWrapper contentHeight={contentHeight} forceZIndex={forceZIndex}>
<div>{children}</div>
</ContentWrapper>
)
Expand Down
5 changes: 3 additions & 2 deletions src/components/Tooltip/styles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ export const NoPaddingStyledTippy = styled(StyledTippy)`
padding: 0;
}
`
export const ContentWrapper = styled.div<{ contentHeight: string }>`
type TContentWrapper = { contentHeight: string; forceZIndex: boolean }
export const ContentWrapper = styled.div<TContentWrapper>`
position: relative;
height: ${({ contentHeight }) => contentHeight};
/* z-index: 1; */
z-index: ${({ forceZIndex }) => (forceZIndex ? 1 : 0)};
`
const Arrow = styled.div`
position: absolute;
Expand Down
1 change: 1 addition & 0 deletions src/components/Upvote/styles/comment_layout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export const UpWrapper = styled.div`
`
export const CountWrapper = styled.div`
margin-top: -4px;
margin-left: 1px;
`
2 changes: 1 addition & 1 deletion src/containers/tool/AbuseReport/logic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export const selectItem = (checkedItemRaw: string): void => {
store.mark({ checkedItemRaw, view: 'detail' })
}

export const close = (): void => store.mark({ show: false })
export const close = (): void => store.mark({ show: false, view: 'main' })

const DataResolver = [
{
Expand Down
2 changes: 1 addition & 1 deletion src/containers/tool/Share/styles/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const LogoWrapper = styled.div<{ noBg: boolean }>`
margin-bottom: 5px;
`
export const Logo = styled(Img)<{ small: boolean }>`
fill: #e7f2f7; // ${theme('thread.articleTitle')};
fill: ${theme('thread.articleTitle')};
${({ small }) => (small ? css.circle('24px') : css.circle('38px'))};
filter: saturate(0.6);
opacity: 0.8;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import MarkDownRender from '@/components/MarkDownRender'
import Tooltip from '@/components/Tooltip'
import Upvote from '@/components/Upvote'

import Header from './Header'
import ReplyBar from './ReplyBar'
import DeleteMask from './DeleteMask'
import Footer from './Footer'
import Header from '../Header'
import ReplyBar from '../ReplyBar'
import DeleteMask from '../DeleteMask'
import Footer from '../Footer'

import {
Wrapper,
Expand All @@ -27,7 +27,8 @@ import {
SolutionIcon,
BadgePopContent,
RangeLine,
} from '../styles/comment/desktop_view'
} from '../../styles/comment/desktop_view'
import { foldComment } from '../../logic'

const getSelection = () => {
const selectText = Global.getSelection().toString()
Expand All @@ -42,14 +43,16 @@ type TProps = {
tobeDeleteId: string
hasReplies?: boolean
withoutBottomDivider?: boolean
isReply?: boolean
}

const Comment: FC<TProps> = ({
const DefaultLayout: FC<TProps> = ({
data,
tobeDeleteId,
accountInfo,
hasReplies = false,
withoutBottomDivider = false,
isReply = false,
}) => {
const pined = data.id === '360' || data.id === '377'
const isAuthorUpvoted =
Expand Down Expand Up @@ -89,7 +92,7 @@ const Comment: FC<TProps> = ({
/>
</Tooltip>
)}
<RangeLine hasReplies={hasReplies} />
{isReply && <RangeLine onClick={() => foldComment(data.id)} />}
</SidebarWrapper>

<CommentBodyInfo onMouseUp={getSelection}>
Expand All @@ -110,4 +113,4 @@ const Comment: FC<TProps> = ({
)
}

export default memo(Comment)
export default memo(DefaultLayout)
59 changes: 59 additions & 0 deletions src/containers/unit/Comments/Comment/DesktopView/FoldLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { FC, memo } from 'react'
import TimeAgo from 'timeago-react'

import type { TComment } from '@/spec'
import { cutRest } from '@/utils'
import { ICON } from '@/config'

import ImgFallback from '@/components/ImgFallback'
import { IconButton } from '@/components/Buttons'
import { SpaceGrow } from '@/components/Common'

import {
Wrapper,
Avatar,
CommentBody,
SolutionIcon,
CreateDate,
} from '../../styles/comment/desktop_view/fold_layout'
import { expandComment } from '../../logic'

type TProps = {
data: TComment
}

const FoldLayout: FC<TProps> = ({ data }) => {
const pined = data.id === '360' || data.id === '377'
const isAuthorUpvoted =
data.id === '377' || data.id === '355' || data.id === '359'
const isSolution = data.id === '358' || data.id === '355'

return (
<Wrapper pined={pined}>
<IconButton
path="shape/expand-all.svg"
hint="展开评论"
mLeft={-1}
mRight={12}
onClick={() => expandComment(data.id)}
/>
<Avatar
src={data.author.avatar}
fallback={<ImgFallback user={data.author} size={16} right={10} />}
/>
<CommentBody>{cutRest(data.body, 30)}</CommentBody>
<SpaceGrow />
{isSolution && (
<SolutionIcon
isAuthorUpvoted={isAuthorUpvoted}
src={`${ICON}/shape/solution-check.svg`}
/>
)}
<CreateDate>
<TimeAgo datetime={data.insertedAt} locale="zh_CN" />
</CreateDate>
</Wrapper>
)
}

export default memo(FoldLayout)
30 changes: 30 additions & 0 deletions src/containers/unit/Comments/Comment/DesktopView/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { FC, memo, Fragment } from 'react'
import { contains } from 'ramda'
import { TID } from '@/spec'

import type { TAccount, TComment } from '@/spec'

import DefaultLayout from './DefaultLayout'
import FoldLayout from './FoldLayout'

type TProps = {
data: TComment
accountInfo: TAccount
tobeDeleteId: string
hasReplies?: boolean
withoutBottomDivider?: boolean
foldedIds: TID[]
}

const Comment: FC<TProps> = (props) => {
const { foldedIds, data } = props
const isFolded = contains(data.id, foldedIds)

return (
<Fragment>
{isFolded ? <FoldLayout {...props} /> : <DefaultLayout {...props} />}
</Fragment>
)
}

export default memo(Comment)
2 changes: 1 addition & 1 deletion src/containers/unit/Comments/Comment/Emotion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { Wrapper } from '../styles/comment/emotion'

const Emotion: FC = () => (
<Wrapper>
<IconButton path="emotion/alien-fill.svg" mRight={0} />
<IconButton path="emotion/emotion.svg" mRight={0} mTop={1} />
</Wrapper>
)

Expand Down
Loading