Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

feat(comment): actions menu button#1127

Merged
mydearxym merged 10 commits intodevfrommenu-button
Jul 26, 2021
Merged
Show file tree
Hide file tree
Changes fromall 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: 0 additions & 1 deletionsrc/components/Buttons/DropdownButton/OptionPanel.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import { FC, memo } from 'react'
import T from 'prop-types'

import { ICON } from '@/config'
import { cutRest } from '@/utils'
Expand Down
76 changes: 76 additions & 0 deletionssrc/components/Buttons/MenuButton/Menu.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
import { FC, memo } from 'react'
import { isEmpty } from 'ramda'

import { ICON } from '@/config'
import { cutRest } from '@/utils'
import type { TOption } from './index'

import {
Wrapper,
Block,
BlockA,
Item,
Icon,
Title,
LinkIcon,
Divider,
} from '../styles/menu_button/menu'

// there is two types of block, normal block and link
const OptionBlock = ({ item, onClick }) => {
if (item.link) {
return (
<BlockA as="a" href={item.link}>
<Item>
<Icon src={item.icon} />
<Title>{cutRest(item.title, 50)}</Title>
<LinkIcon src={`${ICON}/shape/link-hint.svg`} />
</Item>
</BlockA>
)
}
return (
<Block onClick={onClick}>
<Item>
<Icon src={item.icon} />
<Title>{cutRest(item.title, 50)}</Title>
</Item>
</Block>
)
}

type TProps = {
options: TOption[]
extraOptions: TOption[]
panelMinWidth: string
onClick?: (key?: string) => void
}

const Menu: FC<TProps> = ({
options,
extraOptions,
onClick,
panelMinWidth,
}) => {
return (
<Wrapper panelMinWidth={panelMinWidth}>
{options.map((item) => (
<OptionBlock
key={item.key}
item={item}
onClick={() => onClick(item.key)}
/>
))}
{!isEmpty(extraOptions) && <Divider />}
{extraOptions.map((item) => (
<OptionBlock
key={item.key}
item={item}
onClick={() => onClick(item.key)}
/>
))}
</Wrapper>
)
}

export default memo(Menu)
59 changes: 59 additions & 0 deletionssrc/components/Buttons/MenuButton/index.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
import { FC, ReactNode, memo } from 'react'

import { buildLog } from '@/utils'

import type { TTooltipPlacement } from '@/spec'

import Tooltip from '@/components/Tooltip'

import Menu from './Menu'

// import { Wrapper } from '../styles/menu_button'

const log = buildLog('C:MenuButton')

export type TOption = {
title: string
key: string
icon?: string
link?: string
}

type TProps = {
children: ReactNode
options: TOption[]
extraOptions: TOption[]
placement?: TTooltipPlacement
panelMinWidth?: string
onClick: (key?: string) => void
}

const MenuButton: FC<TProps> = ({
children,
options,
extraOptions = [],
onClick = log,
placement = 'top-end',
panelMinWidth = '100px',
}) => {
return (
<Tooltip
placement={placement}
trigger="click"
hideOnClick
content={
<Menu
options={options}
extraOptions={extraOptions}
onClick={onClick}
panelMinWidth={panelMinWidth}
/>
}
noPadding
>
{children}
</Tooltip>
)
}

export default memo(MenuButton)
1 change: 1 addition & 0 deletionssrc/components/Buttons/index.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,6 +5,7 @@ export { default as ArrowLink } from './ArrowLink'
export { default as PublishButton } from './PublishButton'
export { default as OrButton } from './OrButton'
export { default as DropdownButton } from './DropdownButton'
export { default as MenuButton } from './MenuButton'
export { default as NotifyButton } from './NotifyButton'
export { default as FollowButton } from './FollowButton'
export { default as YesOrNoButtons } from './YesOrNoButtons'
Expand Down
10 changes: 10 additions & 0 deletionssrc/components/Buttons/styles/menu_button/index.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
import styled from 'styled-components'

import { css } from '@/utils'

export const Wrapper = styled.div`
${css.flex('align-center')};
width: 100%;
position: relative;
`
export const Holder = 1
60 changes: 60 additions & 0 deletionssrc/components/Buttons/styles/menu_button/menu.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
import styled from 'styled-components'

import Img from '@/Img'
import { css, theme } from '@/utils'

export const Wrapper = styled.div<{ panelMinWidth: string }>`
${css.flexColumn('align-center')};
width: 100%;
min-width: ${({ panelMinWidth }) => panelMinWidth};
max-height: 300px;
overflow: hidden;
`
export const Block = styled.div`
${css.flex('align-start')};
width: 100%;
padding: 6px 10px;
padding-left: 15px;

&:hover {
background: #0d3e4e;
cursor: pointer;
}
`
export const Divider = styled.div`
width: 100%;
height: 1px;
background: #0d3e4e;
margin-top: 3px;
margin-bottom: 3px;
`
export const BlockA = styled(Block)`
text-decoration: none;
`
export const Item = styled.div`
${css.flex('align-center')};
`
export const Icon = styled(Img)`
fill: ${theme('thread.articleDigest')};
${css.size(12)};
margin-right: 10px;
opacity: 0.8;

${Item}:hover & {
opacity: 1;
}
`
export const Title = styled.div`
color: ${theme('thread.articleTitle')};
font-size: 13px;
`
export const LinkIcon = styled(Img)`
${css.size(10)};
fill: ${theme('thread.articleDigest')};
margin-left: 7px;
`
export const Desc = styled.div`
color: ${theme('thread.articleDigest')};
font-size: 11px;
margin-top: 4px;
`
80 changes: 69 additions & 11 deletionssrc/containers/unit/Comments/Comment/Actions.tsx
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
import { FC, memo } from 'react'
import { FC, memo, useCallback } from 'react'

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

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

import { Wrapper, ReplyAction } from '../styles/comment/actions'
Expand All@@ -13,23 +14,80 @@ type TProps = {
accountInfo: TAccount
}

const menuOptions = [
{
key: 'quote',
icon: `${ICON}/shape/quote.svg`,
title: '引用',
},
{
key: 'share',
icon: `${ICON}/article/share.svg`,
title: '分享',
},
{
key: 'report',
icon: `${ICON}/article/report.svg`,
title: '举报',
},
]

const Actions: FC<TProps> = ({ data, accountInfo }) => {
let extraOptions = []

if (String(data.author.id) === accountInfo.id) {
return (
<Wrapper>
<ReplyAction onClick={() => openUpdateEditor(data)}>编辑</ReplyAction>
<ReplyAction onClick={() => onDelete(data)}>删除</ReplyAction>
</Wrapper>
)
extraOptions = [
{
key: 'edit',
icon: `${ICON}/edit/publish-pen.svg`,
title: '编辑',
},
{
key: 'delete',
icon: `${ICON}/shape/delete.svg`,
title: '删除',
},
]
}

const handleAction = useCallback(
(key) => {
switch (key) {
case 'share': {
return console.log('todo: share')
}
case 'quote': {
return console.log('todo: quote')
}
case 'report': {
return console.log('todo: report')
}
case 'edit': {
return openUpdateEditor(data)
}
case 'delete': {
return onDelete(data)
}
default: {
// eslint-disable-next-line no-useless-return
return
}
}
},
[data],
)

return (
<Wrapper>
<ReplyAction onClick={() => openReplyEditor(data)}>回复</ReplyAction>
<SpaceGrow />
<IconButton path="article/share.svg" size={13} />
<IconButton path="shape/quote.svg" size={13} />
<IconButton path="article/report.svg" size={13} />
<MenuButton
options={menuOptions}
extraOptions={extraOptions}
onClick={handleAction}
>
<IconButton path="shape/more.svg" size={16} />
</MenuButton>
</Wrapper>
)
}
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,7 +26,7 @@ import {
AuthorUpvotedIcon,
SolutionIcon,
BadgePopContent,
RangeLine,
IndentLine,
} from '../../styles/comment/desktop_view'
import { foldComment } from '../../logic'

Expand All@@ -41,17 +41,13 @@ type TProps = {
data: TComment
accountInfo: TAccount
tobeDeleteId: string
hasReplies?: boolean
withoutBottomDivider?: boolean
isReply?: boolean
}

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

<CommentBodyInfo onMouseUp={getSelection}>
Expand All@@ -101,12 +97,7 @@ const DefaultLayout: FC<TProps> = ({
{data.replyTo && <ReplyBar data={data.replyTo} />}
<MarkDownRender body={data.body} />
</CommentContent>
<Footer
data={data}
accountInfo={accountInfo}
withoutBottomDivider={withoutBottomDivider}
hasReplies={hasReplies}
/>
<Footer data={data} accountInfo={accountInfo} />
</CommentBodyInfo>
</CommentWrapper>
</Wrapper>
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,13 +23,12 @@ type TProps = {
}

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}>
<Wrapper>
<IconButton
path="shape/expand-all.svg"
hint="展开评论"
Expand Down
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -12,7 +12,6 @@ type TProps = {
accountInfo: TAccount
tobeDeleteId: string
hasReplies?: boolean
withoutBottomDivider?: boolean
foldedIds: TID[]
}

Expand Down
Loading

[8]ページ先頭

©2009-2025 Movatter.jp