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.

Commit1b5fd6e

Browse files
authored
feat(comment): actions menu button (#1127)
* fix(copy-button): avoid un-expected animation with value change* fix(tooltip): z-index edge case* fix(switcher-icon): active style adjust* fix(report): reset view on close* feat(comment): basic fold/extand UI/UX* feat(comment): range bar wip* refactor(fold): UX & re-design looks* fix: mini* feat(comment): put action into menu
1 parentcb39a54 commit1b5fd6e

File tree

25 files changed

+328
-68
lines changed

25 files changed

+328
-68
lines changed

‎src/components/Buttons/DropdownButton/OptionPanel.tsx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import{FC,memo}from'react'
2-
importTfrom'prop-types'
32

43
import{ICON}from'@/config'
54
import{cutRest}from'@/utils'
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import{FC,memo}from'react'
2+
import{isEmpty}from'ramda'
3+
4+
import{ICON}from'@/config'
5+
import{cutRest}from'@/utils'
6+
importtype{TOption}from'./index'
7+
8+
import{
9+
Wrapper,
10+
Block,
11+
BlockA,
12+
Item,
13+
Icon,
14+
Title,
15+
LinkIcon,
16+
Divider,
17+
}from'../styles/menu_button/menu'
18+
19+
// there is two types of block, normal block and link
20+
constOptionBlock=({ item, onClick})=>{
21+
if(item.link){
22+
return(
23+
<BlockAas="a"href={item.link}>
24+
<Item>
25+
<Iconsrc={item.icon}/>
26+
<Title>{cutRest(item.title,50)}</Title>
27+
<LinkIconsrc={`${ICON}/shape/link-hint.svg`}/>
28+
</Item>
29+
</BlockA>
30+
)
31+
}
32+
return(
33+
<BlockonClick={onClick}>
34+
<Item>
35+
<Iconsrc={item.icon}/>
36+
<Title>{cutRest(item.title,50)}</Title>
37+
</Item>
38+
</Block>
39+
)
40+
}
41+
42+
typeTProps={
43+
options:TOption[]
44+
extraOptions:TOption[]
45+
panelMinWidth:string
46+
onClick?:(key?:string)=>void
47+
}
48+
49+
constMenu:FC<TProps>=({
50+
options,
51+
extraOptions,
52+
onClick,
53+
panelMinWidth,
54+
})=>{
55+
return(
56+
<WrapperpanelMinWidth={panelMinWidth}>
57+
{options.map((item)=>(
58+
<OptionBlock
59+
key={item.key}
60+
item={item}
61+
onClick={()=>onClick(item.key)}
62+
/>
63+
))}
64+
{!isEmpty(extraOptions)&&<Divider/>}
65+
{extraOptions.map((item)=>(
66+
<OptionBlock
67+
key={item.key}
68+
item={item}
69+
onClick={()=>onClick(item.key)}
70+
/>
71+
))}
72+
</Wrapper>
73+
)
74+
}
75+
76+
exportdefaultmemo(Menu)
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import{FC,ReactNode,memo}from'react'
2+
3+
import{buildLog}from'@/utils'
4+
5+
importtype{TTooltipPlacement}from'@/spec'
6+
7+
importTooltipfrom'@/components/Tooltip'
8+
9+
importMenufrom'./Menu'
10+
11+
// import { Wrapper } from '../styles/menu_button'
12+
13+
constlog=buildLog('C:MenuButton')
14+
15+
exporttypeTOption={
16+
title:string
17+
key:string
18+
icon?:string
19+
link?:string
20+
}
21+
22+
typeTProps={
23+
children:ReactNode
24+
options:TOption[]
25+
extraOptions:TOption[]
26+
placement?:TTooltipPlacement
27+
panelMinWidth?:string
28+
onClick:(key?:string)=>void
29+
}
30+
31+
constMenuButton:FC<TProps>=({
32+
children,
33+
options,
34+
extraOptions=[],
35+
onClick=log,
36+
placement='top-end',
37+
panelMinWidth='100px',
38+
})=>{
39+
return(
40+
<Tooltip
41+
placement={placement}
42+
trigger="click"
43+
hideOnClick
44+
content={
45+
<Menu
46+
options={options}
47+
extraOptions={extraOptions}
48+
onClick={onClick}
49+
panelMinWidth={panelMinWidth}
50+
/>
51+
}
52+
noPadding
53+
>
54+
{children}
55+
</Tooltip>
56+
)
57+
}
58+
59+
exportdefaultmemo(MenuButton)

‎src/components/Buttons/index.tsx‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export { default as ArrowLink } from './ArrowLink'
55
export{defaultasPublishButton}from'./PublishButton'
66
export{defaultasOrButton}from'./OrButton'
77
export{defaultasDropdownButton}from'./DropdownButton'
8+
export{defaultasMenuButton}from'./MenuButton'
89
export{defaultasNotifyButton}from'./NotifyButton'
910
export{defaultasFollowButton}from'./FollowButton'
1011
export{defaultasYesOrNoButtons}from'./YesOrNoButtons'
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
importstyledfrom'styled-components'
2+
3+
import{css}from'@/utils'
4+
5+
exportconstWrapper=styled.div`
6+
${css.flex('align-center')};
7+
width: 100%;
8+
position: relative;
9+
`
10+
exportconstHolder=1
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
importstyledfrom'styled-components'
2+
3+
importImgfrom'@/Img'
4+
import{css,theme}from'@/utils'
5+
6+
exportconstWrapper=styled.div<{panelMinWidth:string}>`
7+
${css.flexColumn('align-center')};
8+
width: 100%;
9+
min-width:${({ panelMinWidth})=>panelMinWidth};
10+
max-height: 300px;
11+
overflow: hidden;
12+
`
13+
exportconstBlock=styled.div`
14+
${css.flex('align-start')};
15+
width: 100%;
16+
padding: 6px 10px;
17+
padding-left: 15px;
18+
19+
&:hover {
20+
background: #0d3e4e;
21+
cursor: pointer;
22+
}
23+
`
24+
exportconstDivider=styled.div`
25+
width: 100%;
26+
height: 1px;
27+
background: #0d3e4e;
28+
margin-top: 3px;
29+
margin-bottom: 3px;
30+
`
31+
exportconstBlockA=styled(Block)`
32+
text-decoration: none;
33+
`
34+
exportconstItem=styled.div`
35+
${css.flex('align-center')};
36+
`
37+
exportconstIcon=styled(Img)`
38+
fill:${theme('thread.articleDigest')};
39+
${css.size(12)};
40+
margin-right: 10px;
41+
opacity: 0.8;
42+
43+
${Item}:hover & {
44+
opacity: 1;
45+
}
46+
`
47+
exportconstTitle=styled.div`
48+
color:${theme('thread.articleTitle')};
49+
font-size: 13px;
50+
`
51+
exportconstLinkIcon=styled(Img)`
52+
${css.size(10)};
53+
fill:${theme('thread.articleDigest')};
54+
margin-left: 7px;
55+
`
56+
exportconstDesc=styled.div`
57+
color:${theme('thread.articleDigest')};
58+
font-size: 11px;
59+
margin-top: 4px;
60+
`

‎src/containers/unit/Comments/Comment/Actions.tsx‎

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import{FC,memo}from'react'
1+
import{FC,memo,useCallback}from'react'
22

33
importtype{TAccount,TComment}from'@/spec'
4+
import{ICON}from'@/config'
45

5-
import{IconButton}from'@/components/Buttons'
6+
import{IconButton,MenuButton}from'@/components/Buttons'
67
import{SpaceGrow}from'@/components/Common'
78

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

17+
constmenuOptions=[
18+
{
19+
key:'quote',
20+
icon:`${ICON}/shape/quote.svg`,
21+
title:'引用',
22+
},
23+
{
24+
key:'share',
25+
icon:`${ICON}/article/share.svg`,
26+
title:'分享',
27+
},
28+
{
29+
key:'report',
30+
icon:`${ICON}/article/report.svg`,
31+
title:'举报',
32+
},
33+
]
34+
1635
constActions:FC<TProps>=({ data, accountInfo})=>{
36+
letextraOptions=[]
37+
1738
if(String(data.author.id)===accountInfo.id){
18-
return(
19-
<Wrapper>
20-
<ReplyActiononClick={()=>openUpdateEditor(data)}>编辑</ReplyAction>
21-
<ReplyActiononClick={()=>onDelete(data)}>删除</ReplyAction>
22-
</Wrapper>
23-
)
39+
extraOptions=[
40+
{
41+
key:'edit',
42+
icon:`${ICON}/edit/publish-pen.svg`,
43+
title:'编辑',
44+
},
45+
{
46+
key:'delete',
47+
icon:`${ICON}/shape/delete.svg`,
48+
title:'删除',
49+
},
50+
]
2451
}
2552

53+
consthandleAction=useCallback(
54+
(key)=>{
55+
switch(key){
56+
case'share':{
57+
returnconsole.log('todo: share')
58+
}
59+
case'quote':{
60+
returnconsole.log('todo: quote')
61+
}
62+
case'report':{
63+
returnconsole.log('todo: report')
64+
}
65+
case'edit':{
66+
returnopenUpdateEditor(data)
67+
}
68+
case'delete':{
69+
returnonDelete(data)
70+
}
71+
default:{
72+
// eslint-disable-next-line no-useless-return
73+
return
74+
}
75+
}
76+
},
77+
[data],
78+
)
79+
2680
return(
2781
<Wrapper>
2882
<ReplyActiononClick={()=>openReplyEditor(data)}>回复</ReplyAction>
2983
<SpaceGrow/>
30-
<IconButtonpath="article/share.svg"size={13}/>
31-
<IconButtonpath="shape/quote.svg"size={13}/>
32-
<IconButtonpath="article/report.svg"size={13}/>
84+
<MenuButton
85+
options={menuOptions}
86+
extraOptions={extraOptions}
87+
onClick={handleAction}
88+
>
89+
<IconButtonpath="shape/more.svg"size={16}/>
90+
</MenuButton>
3391
</Wrapper>
3492
)
3593
}

‎src/containers/unit/Comments/Comment/DesktopView/DefaultLayout.tsx‎

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import {
2626
AuthorUpvotedIcon,
2727
SolutionIcon,
2828
BadgePopContent,
29-
RangeLine,
29+
IndentLine,
3030
}from'../../styles/comment/desktop_view'
3131
import{foldComment}from'../../logic'
3232

@@ -41,17 +41,13 @@ type TProps = {
4141
data:TComment
4242
accountInfo:TAccount
4343
tobeDeleteId:string
44-
hasReplies?:boolean
45-
withoutBottomDivider?:boolean
4644
isReply?:boolean
4745
}
4846

4947
constDefaultLayout:FC<TProps>=({
5048
data,
5149
tobeDeleteId,
5250
accountInfo,
53-
hasReplies=false,
54-
withoutBottomDivider=false,
5551
isReply=false,
5652
})=>{
5753
constpined=data.id==='360'||data.id==='377'
@@ -92,7 +88,7 @@ const DefaultLayout: FC<TProps> = ({
9288
/>
9389
</Tooltip>
9490
)}
95-
{isReply&&<RangeLineonClick={()=>foldComment(data.id)}/>}
91+
{isReply&&<IndentLineonClick={()=>foldComment(data.id)}/>}
9692
</SidebarWrapper>
9793

9894
<CommentBodyInfoonMouseUp={getSelection}>
@@ -101,12 +97,7 @@ const DefaultLayout: FC<TProps> = ({
10197
{data.replyTo&&<ReplyBardata={data.replyTo}/>}
10298
<MarkDownRenderbody={data.body}/>
10399
</CommentContent>
104-
<Footer
105-
data={data}
106-
accountInfo={accountInfo}
107-
withoutBottomDivider={withoutBottomDivider}
108-
hasReplies={hasReplies}
109-
/>
100+
<Footerdata={data}accountInfo={accountInfo}/>
110101
</CommentBodyInfo>
111102
</CommentWrapper>
112103
</Wrapper>

‎src/containers/unit/Comments/Comment/DesktopView/FoldLayout.tsx‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,12 @@ type TProps = {
2323
}
2424

2525
constFoldLayout:FC<TProps>=({ data})=>{
26-
constpined=data.id==='360'||data.id==='377'
2726
constisAuthorUpvoted=
2827
data.id==='377'||data.id==='355'||data.id==='359'
2928
constisSolution=data.id==='358'||data.id==='355'
3029

3130
return(
32-
<Wrapperpined={pined}>
31+
<Wrapper>
3332
<IconButton
3433
path="shape/expand-all.svg"
3534
hint="展开评论"

‎src/containers/unit/Comments/Comment/DesktopView/index.tsx‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ type TProps = {
1212
accountInfo:TAccount
1313
tobeDeleteId:string
1414
hasReplies?:boolean
15-
withoutBottomDivider?:boolean
1615
foldedIds:TID[]
1716
}
1817

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp