Uodated popover components mobile design
• Updated: - popover components mobile design with cancel button at the bottom • Added: -CommentSortingOptionsPopover subtitles for options for more clarity
This commit is contained in:
parent
4fbd606a44
commit
7e3d4d009d
|
@ -11,8 +11,15 @@ import List from '../list'
|
|||
|
||||
const messages = defineMessages({
|
||||
oldest: { id: 'comment_sort.oldest', defaultMessage: 'Oldest' },
|
||||
oldestSubtitle: { id: 'comment_sort.oldest.subtitle', defaultMessage: 'Show all comments, with the oldest comments first.' },
|
||||
newest: { id: 'comment_sort.newest', defaultMessage: 'Recent' },
|
||||
newestSubtitle: { id: 'comment_sort.newest.subtitle', defaultMessage: 'Show all comments, with the newest comments first.' },
|
||||
top: { id: 'comment_sort.top', defaultMessage: 'Most Liked' },
|
||||
topSubtitle: { id: 'comment_sort.top.subtitle', defaultMessage: 'Show all comments, with the most liked top-level comments first.' },
|
||||
})
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
commentSorting: state.getIn(['settings', 'commentSorting']),
|
||||
})
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
|
@ -21,48 +28,71 @@ const mapDispatchToProps = (dispatch) => ({
|
|||
dispatch(saveSettings())
|
||||
dispatch(closePopover())
|
||||
},
|
||||
onClosePopover: () => dispatch(closePopover()),
|
||||
})
|
||||
|
||||
export default
|
||||
@injectIntl
|
||||
@connect(null, mapDispatchToProps)
|
||||
@connect(mapStateToProps, mapDispatchToProps)
|
||||
class CommentSortingOptionsPopover extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
commentSorting: PropTypes.string.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
onSetCommentSortingSetting: PropTypes.func.isRequired,
|
||||
isXS: PropTypes.bool,
|
||||
onClosePopover: PropTypes.func.isRequired,
|
||||
onSetCommentSortingSetting: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
handleOnClick = (type) => {
|
||||
this.props.onSetCommentSortingSetting(type)
|
||||
}
|
||||
|
||||
handleOnClosePopover = () => {
|
||||
this.props.onClosePopover()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl, isXS } = this.props
|
||||
const {
|
||||
commentSorting,
|
||||
intl,
|
||||
isXS,
|
||||
} = this.props
|
||||
|
||||
const items = [
|
||||
{
|
||||
hideArrow: true,
|
||||
isActive: commentSorting === COMMENT_SORTING_TYPE_NEWEST,
|
||||
title: intl.formatMessage(messages.newest),
|
||||
subtitle: intl.formatMessage(messages.newestSubtitle),
|
||||
onClick: () => this.handleOnClick(COMMENT_SORTING_TYPE_NEWEST),
|
||||
},
|
||||
{
|
||||
hideArrow: true,
|
||||
isActive: commentSorting === COMMENT_SORTING_TYPE_OLDEST,
|
||||
title: intl.formatMessage(messages.oldest),
|
||||
subtitle: intl.formatMessage(messages.oldestSubtitle),
|
||||
onClick: () => this.handleOnClick(COMMENT_SORTING_TYPE_OLDEST),
|
||||
},
|
||||
{
|
||||
hideArrow: true,
|
||||
isActive: commentSorting === COMMENT_SORTING_TYPE_TOP,
|
||||
title: intl.formatMessage(messages.top),
|
||||
subtitle: intl.formatMessage(messages.topSubtitle),
|
||||
onClick: () => this.handleOnClick(COMMENT_SORTING_TYPE_TOP),
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<PopoverLayout width={180} isXS={isXS}>
|
||||
<PopoverLayout
|
||||
width={180}
|
||||
isXS={isXS}
|
||||
onClose={this.handleOnClosePopover}
|
||||
>
|
||||
<List
|
||||
size='large'
|
||||
scrollKey='comment_sorting_options'
|
||||
items={[
|
||||
{
|
||||
hideArrow: true,
|
||||
title: intl.formatMessage(messages.newest),
|
||||
onClick: () => this.handleOnClick(COMMENT_SORTING_TYPE_NEWEST),
|
||||
},
|
||||
{
|
||||
hideArrow: true,
|
||||
title: intl.formatMessage(messages.oldest),
|
||||
onClick: () => this.handleOnClick(COMMENT_SORTING_TYPE_OLDEST),
|
||||
},
|
||||
{
|
||||
hideArrow: true,
|
||||
title: intl.formatMessage(messages.top),
|
||||
onClick: () => this.handleOnClick(COMMENT_SORTING_TYPE_TOP),
|
||||
},
|
||||
]}
|
||||
items={items}
|
||||
small
|
||||
/>
|
||||
</PopoverLayout>
|
||||
|
|
|
@ -5,10 +5,7 @@ import { changeScheduledAt } from '../../actions/compose'
|
|||
import { openModal } from '../../actions/modal'
|
||||
import { closePopover } from '../../actions/popover'
|
||||
import { me } from '../../initial_state'
|
||||
import {
|
||||
MODAL_PRO_UPGRADE,
|
||||
} from '../../constants'
|
||||
import { isMobile } from '../../utils/is_mobile'
|
||||
import { MODAL_PRO_UPGRADE } from '../../constants'
|
||||
import PopoverLayout from './popover_layout'
|
||||
import Button from '../button'
|
||||
import Text from '../text'
|
||||
|
@ -33,6 +30,8 @@ const mapDispatchToProps = (dispatch) => ({
|
|||
dispatch(closePopover())
|
||||
}
|
||||
},
|
||||
|
||||
onClosePopover: () => dispatch(closePopover())
|
||||
})
|
||||
|
||||
export default
|
||||
|
@ -46,6 +45,7 @@ class DatePickerPopover extends PureComponent {
|
|||
position: PropTypes.string,
|
||||
small: PropTypes.bool,
|
||||
isXS: PropTypes.bool,
|
||||
onClosePopover: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
handleSetDate = (date) => {
|
||||
|
@ -56,13 +56,20 @@ class DatePickerPopover extends PureComponent {
|
|||
this.props.setScheduledAt(null, this.props.isPro)
|
||||
}
|
||||
|
||||
handleOnClosePopover = () => {
|
||||
this.props.onClosePopover()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { date, isPro, isXS } = this.props
|
||||
|
||||
const datePickerDisabled = !isPro
|
||||
|
||||
return (
|
||||
<PopoverLayout width={331} isXS={isXS}>
|
||||
<PopoverLayout
|
||||
width={360}
|
||||
isXS={isXS}
|
||||
onClose={this.handleOnClosePopover}
|
||||
>
|
||||
<div className={[_s.default, _s.bgSubtle].join(' ')}>
|
||||
<DatePicker
|
||||
inline
|
||||
|
|
|
@ -278,7 +278,11 @@ class EmojiPickerPopover extends ImmutablePureComponent {
|
|||
const { loading } = this.state
|
||||
|
||||
return (
|
||||
<PopoverLayout width={340} isXS={isXS}>
|
||||
<PopoverLayout
|
||||
width={340}
|
||||
isXS={isXS}
|
||||
onClose={this.onHideDropdown}
|
||||
>
|
||||
<EmojiPickerMenu
|
||||
customEmojis={customEmojis}
|
||||
loading={loading}
|
||||
|
|
|
@ -15,6 +15,7 @@ const mapDispatchToProps = (dispatch) => ({
|
|||
dispatch(closePopover())
|
||||
dispatch(createRemovedAccount(groupId, accountId))
|
||||
},
|
||||
onClosePopover:() => dispatch(closePopover()),
|
||||
})
|
||||
|
||||
export default
|
||||
|
@ -25,8 +26,9 @@ class GroupMemberOptionsPopover extends PureComponent {
|
|||
accountId: PropTypes.string.isRequired,
|
||||
groupId: PropTypes.string.isRequired,
|
||||
isXS: PropTypes.bool,
|
||||
onUpdateRole: PropTypes.func.isRequired,
|
||||
onClosePopover: PropTypes.func.isRequired,
|
||||
onCreateRemovedAccount: PropTypes.func.isRequired,
|
||||
onUpdateRole: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
handleOnRemoveFromGroup = () => {
|
||||
|
@ -37,6 +39,10 @@ class GroupMemberOptionsPopover extends PureComponent {
|
|||
this.props.onUpdateRole(this.props.groupId, this.props.accountId, 'admin')
|
||||
}
|
||||
|
||||
handleOnClosePopover = () => {
|
||||
this.props.onClosePopover()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isXS } = this.props
|
||||
|
||||
|
@ -56,7 +62,11 @@ class GroupMemberOptionsPopover extends PureComponent {
|
|||
]
|
||||
|
||||
return (
|
||||
<PopoverLayout width={210} isXS={isXS}>
|
||||
<PopoverLayout
|
||||
width={210}
|
||||
isXS={isXS}
|
||||
onClose={this.handleOnClosePopover}
|
||||
>
|
||||
<List
|
||||
scrollKey='group_options'
|
||||
items={listItems}
|
||||
|
|
|
@ -35,6 +35,8 @@ const mapDispatchToProps = (dispatch) => ({
|
|||
dispatch(openModal(MODAL_GROUP_MEMBERS, { groupId }))
|
||||
},
|
||||
|
||||
onClosePopover: () => dispatch(closePopover())
|
||||
|
||||
});
|
||||
|
||||
export default
|
||||
|
@ -43,12 +45,13 @@ export default
|
|||
class GroupOptionsPopover extends ImmutablePureComponent {
|
||||
|
||||
static defaultProps = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
group: ImmutablePropTypes.map.isRequired,
|
||||
onOpenEditGroup: PropTypes.func.isRequired,
|
||||
onOpenRemovedMembers: PropTypes.func.isRequired,
|
||||
onOpenGroupMembers: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
isXS: PropTypes.bool,
|
||||
onClosePopover: PropTypes.func.isRequired,
|
||||
onOpenEditGroup: PropTypes.func.isRequired,
|
||||
onOpenGroupMembers: PropTypes.func.isRequired,
|
||||
onOpenRemovedMembers: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
updateOnProps = ['group']
|
||||
|
@ -65,6 +68,10 @@ class GroupOptionsPopover extends ImmutablePureComponent {
|
|||
this.props.onOpenGroupMembers(this.props.group.get('id'))
|
||||
}
|
||||
|
||||
handleOnClosePopover = () => {
|
||||
this.props.onClosePopover()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl, isXS } = this.props
|
||||
|
||||
|
@ -90,7 +97,11 @@ class GroupOptionsPopover extends ImmutablePureComponent {
|
|||
]
|
||||
|
||||
return (
|
||||
<PopoverLayout width={210} isXS={isXS}>
|
||||
<PopoverLayout
|
||||
width={210}
|
||||
isXS={isXS}
|
||||
onClose={this.handleOnClosePopover}
|
||||
>
|
||||
<List
|
||||
scrollKey='group_options'
|
||||
items={listItems}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import Block from '../block'
|
||||
import Button from '../button'
|
||||
import Heading from '../heading'
|
||||
import Text from '../text'
|
||||
|
||||
export default class PopoverLayout extends PureComponent {
|
||||
|
||||
|
@ -8,12 +10,17 @@ export default class PopoverLayout extends PureComponent {
|
|||
width: PropTypes.number,
|
||||
isXS: PropTypes.bool,
|
||||
title: PropTypes.string,
|
||||
onClose: PropTypes.func,
|
||||
}
|
||||
|
||||
static defaultProps = {
|
||||
width: 250,
|
||||
}
|
||||
|
||||
handleOnClose = () => {
|
||||
this.props.onClose()
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
children,
|
||||
|
@ -22,20 +29,35 @@ export default class PopoverLayout extends PureComponent {
|
|||
title,
|
||||
} = this.props
|
||||
|
||||
console.log("popoverlayout props:", this.props)
|
||||
|
||||
if (isXS) {
|
||||
return (
|
||||
<div className={[_s.default, _s.bgPrimary, _s.modal, _s.topRightRadiusSmall, _s.topLeftRadiusSmall].join(' ')}>
|
||||
{
|
||||
!!title &&
|
||||
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.justifyContentCenter, _s.borderBottom1PX, _s.borderColorSecondary, _s.height53PX, _s.px15].join(' ')}>
|
||||
<Heading size='h2'>
|
||||
{title}
|
||||
</Heading>
|
||||
<div className={[_s.default, _s.modal, _s.px10, _s.pb10].join(' ')}>
|
||||
<div className={[_s.default, _s.bgPrimary, _s.radiusSmall, _s.overflowHidden, _s.mb10].join(' ')}>
|
||||
{
|
||||
!!title &&
|
||||
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter, _s.justifyContentCenter, _s.borderBottom1PX, _s.borderColorSecondary, _s.height53PX, _s.px15].join(' ')}>
|
||||
<Heading size='2'>
|
||||
{title}
|
||||
</Heading>
|
||||
</div>
|
||||
}
|
||||
<div className={[_s.default, _s.heightMax80VH, _s.radiusSmall, _s.overflowYScroll].join(' ')}>
|
||||
{children}
|
||||
</div>
|
||||
}
|
||||
<div className={[_s.default, _s.heightMax80VH, _s.topRightRadiusSmall, _s.topLeftRadiusSmall, _s.overflowYScroll].join(' ')}>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
<Button
|
||||
backgroundColor='primary'
|
||||
color='primary'
|
||||
onClick={this.handleOnClose}
|
||||
radiusSmall
|
||||
>
|
||||
<Text color='inherit' size='large' align='center'>
|
||||
Cancel
|
||||
</Text>
|
||||
</Button>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -124,6 +124,8 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
|
|||
}));
|
||||
},
|
||||
|
||||
onClosePopover: () => dispatch(closePopover()),
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
@ -261,12 +263,20 @@ class ProfileOptionsPopover extends PureComponent {
|
|||
// : todo :
|
||||
}
|
||||
|
||||
handleOnClosePopover = () => {
|
||||
this.props.onClosePopover()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isXS } = this.props
|
||||
const listItems = this.makeMenu()
|
||||
|
||||
return (
|
||||
<PopoverLayout width={250} isXS={isXS}>
|
||||
<PopoverLayout
|
||||
width={250}
|
||||
isXS={isXS}
|
||||
onClose={this.handleOnClosePopover}
|
||||
>
|
||||
<List
|
||||
scrollKey='profile_options'
|
||||
items={listItems}
|
||||
|
|
|
@ -298,6 +298,10 @@ class StatusOptionsPopover extends ImmutablePureComponent {
|
|||
}
|
||||
|
||||
document.body.removeChild(textarea);
|
||||
this.handleClosePopover()
|
||||
}
|
||||
|
||||
handleClosePopover = () => {
|
||||
this.props.onClosePopover()
|
||||
}
|
||||
|
||||
|
@ -383,35 +387,10 @@ class StatusOptionsPopover extends ImmutablePureComponent {
|
|||
title: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }),
|
||||
onClick: this.handleReport,
|
||||
})
|
||||
|
||||
if (withGroupAdmin) {
|
||||
menu.push({
|
||||
icon: 'trash',
|
||||
hideArrow: true,
|
||||
title: intl.formatMessage(messages.group_remove_account),
|
||||
onClick: this.handleGroupRemoveAccount,
|
||||
})
|
||||
menu.push({
|
||||
icon: 'trash',
|
||||
hideArrow: true,
|
||||
title: intl.formatMessage(messages.group_remove_post),
|
||||
onClick: this.handleGroupRemovePost,
|
||||
})
|
||||
}
|
||||
|
||||
if (isStaff) {
|
||||
menu.push({
|
||||
title: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }),
|
||||
href: `/admin/accounts/${status.getIn(['account', 'id'])}`
|
||||
})
|
||||
menu.push({
|
||||
title: intl.formatMessage(messages.admin_status),
|
||||
href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
menu.push(null)
|
||||
menu.push({
|
||||
icon: 'copy',
|
||||
hideArrow: true,
|
||||
|
@ -431,8 +410,40 @@ class StatusOptionsPopover extends ImmutablePureComponent {
|
|||
onClick: this.handleOnOpenEmbedModal,
|
||||
})
|
||||
|
||||
if (withGroupAdmin) {
|
||||
menu.push(null)
|
||||
menu.push({
|
||||
icon: 'trash',
|
||||
hideArrow: true,
|
||||
title: intl.formatMessage(messages.group_remove_account),
|
||||
onClick: this.handleGroupRemoveAccount,
|
||||
})
|
||||
menu.push({
|
||||
icon: 'trash',
|
||||
hideArrow: true,
|
||||
title: intl.formatMessage(messages.group_remove_post),
|
||||
onClick: this.handleGroupRemovePost,
|
||||
})
|
||||
}
|
||||
|
||||
if (isStaff) {
|
||||
menu.push(null)
|
||||
|
||||
menu.push({
|
||||
title: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }),
|
||||
href: `/admin/accounts/${status.getIn(['account', 'id'])}`
|
||||
})
|
||||
menu.push({
|
||||
title: intl.formatMessage(messages.admin_status),
|
||||
href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}`
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<PopoverLayout isXS={isXS}>
|
||||
<PopoverLayout
|
||||
isXS={isXS}
|
||||
onClose={this.handleClosePopover}
|
||||
>
|
||||
<List
|
||||
size='large'
|
||||
scrollKey='profile_options'
|
||||
|
|
|
@ -24,12 +24,11 @@ const mapStateToProps = (state) => ({
|
|||
})
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
onChange (value) {
|
||||
dispatch(changeComposeVisibility(value))
|
||||
dispatch(closePopover())
|
||||
},
|
||||
|
||||
onClosePopover: () => dispatch(closePopover()),
|
||||
})
|
||||
|
||||
export default
|
||||
|
@ -38,16 +37,21 @@ export default
|
|||
class StatusVisibilityDropdown extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
value: PropTypes.string.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
isXS: PropTypes.bool,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onClosePopover: PropTypes.func.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
handleChange = (value) => {
|
||||
this.props.onChange(value)
|
||||
}
|
||||
|
||||
handleOnClosePopover = () => {
|
||||
this.props.onClosePopover()
|
||||
}
|
||||
|
||||
render () {
|
||||
const { intl, value, isXS } = this.props
|
||||
|
||||
|
@ -73,7 +77,11 @@ class StatusVisibilityDropdown extends PureComponent {
|
|||
]
|
||||
|
||||
return (
|
||||
<PopoverLayout width={300} isXS={isXS}>
|
||||
<PopoverLayout
|
||||
width={300}
|
||||
isXS={isXS}
|
||||
onClose={this.handleOnClosePopover}
|
||||
>
|
||||
<div className={[_s.default].join(' ')}>
|
||||
{
|
||||
options.map((option, i) => {
|
||||
|
|
|
@ -2,6 +2,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'
|
|||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import { closePopover } from '../../actions/popover'
|
||||
import { CX } from '../../constants'
|
||||
import PopoverLayout from './popover_layout'
|
||||
import Button from '../button'
|
||||
import Text from '../text'
|
||||
|
@ -67,9 +68,21 @@ class VideoStatsPopover extends ImmutablePureComponent {
|
|||
'bitrate',
|
||||
]
|
||||
|
||||
const containerClasses = CX({
|
||||
default: 1,
|
||||
bgBlack: !isXS,
|
||||
bgPrimary: !isXS,
|
||||
px10: 1,
|
||||
py10: 1,
|
||||
})
|
||||
|
||||
return (
|
||||
<PopoverLayout isXS={isXS} width={320}>
|
||||
<div className={[_s.default, _s.bgBlack, _s.px10, _s.py10].join(' ')}>
|
||||
<PopoverLayout
|
||||
isXS={isXS}
|
||||
width={320}
|
||||
onClose={this.handleOnClosePopover}
|
||||
>
|
||||
<div className={containerClasses}>
|
||||
<Button
|
||||
icon='close'
|
||||
iconSize='8px'
|
||||
|
@ -85,6 +98,7 @@ class VideoStatsPopover extends ImmutablePureComponent {
|
|||
key={`video-stat-${key}`}
|
||||
title={intl.formatMessage(messages[key])}
|
||||
value={meta.get(key)}
|
||||
isXS={isXS}
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
@ -94,6 +108,7 @@ class VideoStatsPopover extends ImmutablePureComponent {
|
|||
key={`video-stat-o-${key}`}
|
||||
title={intl.formatMessage(messages[`original_${key}`])}
|
||||
value={meta.getIn(['original', key])}
|
||||
isXS={isXS}
|
||||
/>
|
||||
))
|
||||
}
|
||||
|
@ -108,21 +123,26 @@ class VideoStatsPopover extends ImmutablePureComponent {
|
|||
class VideoStatLine extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
isXS: PropTypes.bool.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { title, value } = this.props
|
||||
const { isXS, title, value } = this.props
|
||||
|
||||
const color = isXS ? 'primary' : 'white'
|
||||
|
||||
return (
|
||||
<div className={[_s.default, _s.flexRow, _s.pt2].join(' ')}>
|
||||
<div className={[_s.default, _s.width115PX, _s.alignItemsEnd, _s.mr5].join(' ')}>
|
||||
<Text size='extraSmall' weight='medium' color='white'>
|
||||
<Text size='extraSmall' weight='medium' color={color}>
|
||||
{title}
|
||||
</Text>
|
||||
</div>
|
||||
<Text size='extraSmall' color='white'>{value}</Text>
|
||||
<Text size='extraSmall' color={color}>
|
||||
{value}
|
||||
</Text>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue