This commit is contained in:
mgabdev 2020-04-06 21:53:23 -04:00
parent e485e2f955
commit b5e3c2a94f
58 changed files with 482 additions and 229 deletions

View File

@ -168,6 +168,12 @@ export function expandNotifications({ maxId } = {}, done = noOp) {
return;
}
console.log("activeFilter:", activeFilter)
console.log("excludeTypesFromSettings(getState()):", excludeTypesFromSettings(getState()))
console.log("excludeTypesFromFilter(activeFilter):", excludeTypesFromFilter(activeFilter))
// : todo :
// filter verified and following here too
const params = {
max_id: maxId,
exclude_types: activeFilter === 'all'

View File

@ -0,0 +1,28 @@
const CodeIcon = ({
className = '',
width = '24px',
height = '24px',
viewBox = '0 0 48 48',
title = 'Code',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d='M 47.507812 22.765625 L 36.410156 11.003906 C 35.726562 10.28125 34.589844 10.25 33.863281 10.929688 C 33.140625 11.613281 33.109375 12.753906 33.792969 13.476562 L 43.726562 24 L 33.792969 34.523438 C 33.109375 35.25 33.140625 36.386719 33.863281 37.070312 C 34.210938 37.398438 34.65625 37.5625 35.101562 37.5625 C 35.578125 37.5625 36.054688 37.371094 36.410156 36.996094 L 47.507812 25.238281 C 48.164062 24.542969 48.164062 23.457031 47.507812 22.765625 Z M 47.507812 22.765625' />
<path d='M 14.210938 34.523438 L 4.277344 24 L 14.210938 13.476562 C 14.890625 12.753906 14.859375 11.613281 14.136719 10.929688 C 13.414062 10.25 12.273438 10.28125 11.589844 11.003906 L 0.492188 22.765625 C -0.164062 23.457031 -0.164062 24.542969 0.492188 25.234375 L 11.589844 36.996094 C 11.945312 37.371094 12.421875 37.5625 12.902344 37.5625 C 13.34375 37.5625 13.789062 37.398438 14.136719 37.070312 C 14.859375 36.386719 14.890625 35.246094 14.210938 34.523438 Z M 14.210938 34.523438' />
<path d='M 26.914062 4.941406 C 25.929688 4.792969 25.011719 5.464844 24.859375 6.449219 L 19.582031 41.007812 C 19.429688 41.992188 20.105469 42.910156 21.089844 43.058594 C 21.179688 43.074219 21.273438 43.082031 21.363281 43.082031 C 22.238281 43.082031 23.003906 42.441406 23.140625 41.550781 L 28.417969 6.992188 C 28.570312 6.007812 27.894531 5.089844 26.914062 4.941406 Z M 26.914062 4.941406' />
</g>
</svg>
)
export default CodeIcon

View File

@ -0,0 +1,27 @@
const CopyIcon = ({
className = '',
width = '24px',
height = '24px',
viewBox = '0 0 48 48',
title = 'Copy',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d='M 34.285156 8.570312 L 5.144531 8.570312 C 2.300781 8.570312 0 10.875 0 13.714844 L 0 42.855469 C 0 45.699219 2.300781 48 5.144531 48 L 34.285156 48 C 37.125 48 39.429688 45.699219 39.429688 42.855469 L 39.429688 13.714844 C 39.429688 10.875 37.125 8.570312 34.285156 8.570312 Z M 36 42.855469 C 36 43.804688 35.234375 44.570312 34.285156 44.570312 L 5.144531 44.570312 C 4.195312 44.570312 3.429688 43.804688 3.429688 42.855469 L 3.429688 13.714844 C 3.429688 12.765625 4.195312 12 5.144531 12 L 34.285156 12 C 35.234375 12 36 12.765625 36 13.714844 Z M 36 42.855469' />
<path d='M 42.855469 0 L 12 0 C 9.160156 0 6.855469 2.300781 6.855469 5.144531 C 6.855469 6.089844 7.625 6.855469 8.570312 6.855469 C 9.519531 6.855469 10.285156 6.089844 10.285156 5.144531 C 10.285156 4.195312 11.054688 3.429688 12 3.429688 L 42.855469 3.429688 C 43.804688 3.429688 44.570312 4.195312 44.570312 5.144531 L 44.570312 36 C 44.570312 36.945312 43.804688 37.714844 42.855469 37.714844 C 41.910156 37.714844 41.144531 38.480469 41.144531 39.429688 C 41.144531 40.375 41.910156 41.144531 42.855469 41.144531 C 45.699219 41.144531 48 38.839844 48 36 L 48 5.144531 C 48 2.300781 45.699219 0 42.855469 0 Z M 42.855469 0' />
</g>
</svg>
)
export default CopyIcon

View File

@ -0,0 +1,26 @@
const EmailIcon = ({
className = '',
width = '24px',
height = '24px',
viewBox = '0 0 48 48',
title = 'Email',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d='M 43.5 6 L 4.5 6 C 2.019531 6 0 8.019531 0 10.5 L 0 37.5 C 0 39.980469 2.019531 42 4.5 42 L 43.5 42 C 45.980469 42 48 39.980469 48 37.5 L 48 10.5 C 48 8.019531 45.980469 6 43.5 6 Z M 43.5 9 C 43.703125 9 43.898438 9.042969 44.074219 9.117188 L 24 26.515625 L 3.925781 9.117188 C 4.101562 9.042969 4.296875 9 4.5 9 Z M 43.5 39 L 4.5 39 C 3.671875 39 3 38.328125 3 37.5 L 3 12.285156 L 23.015625 29.632812 C 23.300781 29.878906 23.648438 30 24 30 C 24.351562 30 24.699219 29.878906 24.984375 29.632812 L 45 12.285156 L 45 37.5 C 45 38.328125 44.328125 39 43.5 39 Z M 43.5 39 '/>
</g>
</svg>
)
export default EmailIcon

View File

@ -0,0 +1,26 @@
const LockFilledIcon = ({
className = '',
width = '24px',
height = '24px',
viewBox = '0 0 48 48',
title = 'Lock',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d='M 21.246094 0.3125 C 17.761719 0.753906 14.890625 1.9375 13.246094 3.589844 C 12.570312 4.265625 12.160156 4.90625 11.867188 5.75 L 11.644531 6.355469 L 11.644531 18.84375 L 9.21875 18.84375 C 6.460938 18.84375 6.195312 18.890625 5.03125 19.484375 C 4.054688 19.992188 3.191406 20.851562 2.683594 21.832031 C 2.007812 23.15625 2.042969 22.453125 2.042969 33.316406 C 2.042969 44.195312 2.007812 43.511719 2.691406 44.84375 C 3.183594 45.796875 4.054688 46.667969 5.023438 47.171875 C 6.382812 47.875 4.792969 47.820312 24.027344 47.820312 C 36.042969 47.820312 41.378906 47.796875 41.707031 47.722656 C 41.964844 47.671875 42.550781 47.449219 43.011719 47.226562 C 44.1875 46.667969 44.976562 45.867188 45.539062 44.703125 C 45.761719 44.238281 45.980469 43.679688 46.035156 43.449219 C 46.179688 42.863281 46.179688 23.804688 46.035156 23.21875 C 45.980469 22.988281 45.761719 22.425781 45.539062 21.972656 C 45.023438 20.878906 44.195312 20.027344 43.15625 19.492188 C 41.980469 18.890625 41.679688 18.84375 38.941406 18.84375 L 36.535156 18.84375 L 36.535156 12.621094 C 36.535156 6.558594 36.523438 6.382812 36.347656 5.839844 C 36.070312 4.996094 35.546875 4.195312 34.828125 3.503906 C 33.253906 1.972656 30.871094 0.960938 27.554688 0.390625 C 26.390625 0.195312 22.523438 0.140625 21.246094 0.3125 Z M 26.753906 4.496094 C 29.554688 4.890625 31.945312 5.980469 32.347656 7.050781 C 32.410156 7.21875 32.445312 9.207031 32.445312 13.074219 L 32.445312 18.84375 L 15.734375 18.84375 L 15.734375 13.023438 C 15.734375 6.496094 15.6875 6.960938 16.398438 6.328125 C 17.574219 5.296875 20.167969 4.515625 23.023438 4.320312 C 23.839844 4.265625 25.769531 4.363281 26.753906 4.496094 Z M 26.753906 4.496094' />
</g>
</svg>
)
export default LockFilledIcon

View File

@ -0,0 +1,26 @@
const LockIcon = ({
className = '',
width = '24px',
height = '24px',
viewBox = '0 0 48 48',
title = 'Lock',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d='M 21.246094 0.3125 C 17.761719 0.753906 14.890625 1.9375 13.246094 3.589844 C 12.570312 4.265625 12.160156 4.90625 11.867188 5.75 L 11.644531 6.355469 L 11.644531 18.84375 L 9.234375 18.84375 C 6.496094 18.84375 6.195312 18.890625 5.023438 19.492188 C 4.0625 19.992188 3.191406 20.863281 2.691406 21.820312 C 2.007812 23.15625 2.042969 22.472656 2.042969 33.351562 C 2.042969 44.214844 2.007812 43.511719 2.683594 44.835938 C 3.191406 45.8125 4.054688 46.675781 5.03125 47.183594 C 6.363281 47.867188 4.898438 47.820312 24.0625 47.820312 C 36.054688 47.820312 41.378906 47.796875 41.707031 47.722656 C 41.964844 47.671875 42.550781 47.449219 43.011719 47.226562 C 44.1875 46.667969 44.976562 45.867188 45.539062 44.703125 C 45.761719 44.238281 45.980469 43.679688 46.035156 43.449219 C 46.179688 42.863281 46.179688 23.804688 46.035156 23.21875 C 45.980469 22.988281 45.761719 22.425781 45.539062 21.972656 C 45.023438 20.878906 44.195312 20.027344 43.15625 19.492188 C 41.980469 18.890625 41.679688 18.84375 38.941406 18.84375 L 36.535156 18.84375 L 36.535156 12.621094 C 36.535156 6.558594 36.523438 6.382812 36.347656 5.839844 C 36.070312 4.996094 35.546875 4.195312 34.828125 3.503906 C 33.253906 1.972656 30.871094 0.960938 27.554688 0.390625 C 26.390625 0.195312 22.523438 0.140625 21.246094 0.3125 Z M 26.753906 4.496094 C 29.554688 4.890625 31.945312 5.980469 32.347656 7.050781 C 32.410156 7.21875 32.445312 9.207031 32.445312 13.074219 L 32.445312 18.84375 L 15.734375 18.84375 L 15.734375 13.023438 C 15.734375 6.496094 15.6875 6.960938 16.398438 6.328125 C 17.574219 5.296875 20.167969 4.515625 23.023438 4.320312 C 23.839844 4.265625 25.769531 4.363281 26.753906 4.496094 Z M 40.835938 23.023438 C 41.269531 23.121094 41.589844 23.351562 41.820312 23.742188 C 42 24.035156 42 24.203125 42 33.332031 L 42 42.621094 L 41.796875 42.949219 C 41.679688 43.128906 41.441406 43.367188 41.261719 43.484375 L 40.933594 43.6875 L 24.488281 43.714844 C 15.449219 43.734375 7.839844 43.714844 7.582031 43.6875 C 7.03125 43.625 6.613281 43.359375 6.363281 42.933594 C 6.179688 42.621094 6.179688 42.542969 6.179688 33.332031 C 6.179688 24.203125 6.179688 24.035156 6.355469 23.742188 C 6.578125 23.367188 6.90625 23.109375 7.296875 23.023438 C 7.722656 22.925781 40.410156 22.914062 40.835938 23.023438 Z M 40.835938 23.023438' />
</g>
</svg>
)
export default LockIcon

View File

@ -0,0 +1,26 @@
const UnlockFilledIcon = ({
className = '',
width = '24px',
height = '24px',
viewBox = '0 0 48 48',
title = 'Unlock',
}) => (
<svg
className={className}
version='1.1'
xmlns='http://www.w3.org/2000/svg'
x='0px'
y='0px'
width={width}
height={height}
viewBox={viewBox}
xmlSpace='preserve'
aria-label={title}
>
<g>
<path d='M 21.246094 0.3125 C 17.761719 0.753906 14.890625 1.9375 13.246094 3.589844 C 12.570312 4.265625 12.160156 4.90625 11.867188 5.75 L 11.644531 6.355469 L 11.644531 18.84375 L 9.21875 18.84375 C 6.460938 18.84375 6.195312 18.890625 5.03125 19.484375 C 4.054688 19.992188 3.191406 20.851562 2.683594 21.832031 C 2.007812 23.15625 2.042969 22.453125 2.042969 33.316406 C 2.042969 44.195312 2.007812 43.511719 2.691406 44.84375 C 3.183594 45.796875 4.054688 46.667969 5.023438 47.171875 C 6.382812 47.875 4.792969 47.820312 24.027344 47.820312 C 36.042969 47.820312 41.378906 47.796875 41.707031 47.722656 C 41.964844 47.671875 42.550781 47.449219 43.011719 47.226562 C 44.1875 46.667969 44.976562 45.867188 45.539062 44.703125 C 45.761719 44.238281 45.980469 43.679688 46.035156 43.449219 C 46.179688 42.863281 46.179688 23.804688 46.035156 23.21875 C 45.980469 22.988281 45.761719 22.425781 45.539062 21.972656 C 45.023438 20.878906 44.195312 20.027344 43.15625 19.492188 C 41.804688 18.800781 42.863281 18.84375 28.542969 18.84375 L 15.734375 18.84375 L 15.734375 13.023438 C 15.734375 6.496094 15.6875 6.960938 16.398438 6.328125 C 17.796875 5.101562 20.765625 4.328125 24.089844 4.335938 C 26.4375 4.335938 28.230469 4.640625 30.027344 5.332031 C 31.367188 5.847656 32.117188 6.460938 32.621094 7.476562 C 33.28125 8.765625 34.054688 9.191406 35.148438 8.871094 C 35.625 8.730469 36.3125 8.042969 36.4375 7.589844 C 36.773438 6.375 36.140625 4.773438 34.828125 3.503906 C 33.253906 1.972656 30.871094 0.960938 27.554688 0.390625 C 26.390625 0.195312 22.523438 0.140625 21.246094 0.3125 Z M 21.246094 0.3125' />
</g>
</svg>
)
export default UnlockFilledIcon

View File

@ -10,10 +10,13 @@ import CalendarIcon from '../assets/calendar_icon'
import ChatIcon from '../assets/chat_icon'
import CircleIcon from '../assets/circle_icon'
import CloseIcon from '../assets/close_icon'
import CodeIcon from '../assets/code_icon'
import CommentIcon from '../assets/comment_icon'
import CopyIcon from '../assets/copy_icon'
import DissenterIcon from '../assets/dissenter_icon'
import DonorIcon from '../assets/donor_icon'
import EllipsisIcon from '../assets/ellipsis_icon'
import EmailIcon from '../assets/email_icon'
import ErrorIcon from '../assets/error_icon'
import FullscreenIcon from '../assets/fullscreen_icon'
import GabLogoIcon from '../assets/gab_logo'
@ -31,6 +34,8 @@ import LinkIcon from '../assets/link_icon'
import ListIcon from '../assets/list_icon'
import ListAddIcon from '../assets/list_add_icon'
import LoadingIcon from '../assets/loading_icon'
import LockIcon from '../assets/lock_icon'
import LockFilledIcon from '../assets/lock_filled_icon'
import MediaIcon from '../assets/media_icon'
import MinimizeFullscreenIcon from '../assets/minimize_fullscreen_icon'
import MissingIcon from '../assets/missing_icon'
@ -54,6 +59,7 @@ import TextSizeIcon from '../assets/text_size_icon'
import TrendsIcon from '../assets/trends_icon'
import ULListIcon from '../assets/ul_list_icon'
import UnderlineIcon from '../assets/underline_icon'
import UnlockFilledIcon from '../assets/unlock_filled_icon'
import VerifiedIcon from '../assets/verified_icon'
import WarningIcon from '../assets/warning_icon'
@ -69,10 +75,13 @@ const ICONS = {
'calendar': CalendarIcon,
'chat': ChatIcon,
'close': CloseIcon,
'code': CodeIcon,
'comment': CommentIcon,
'copy': CopyIcon,
'dissenter': DissenterIcon,
'donor': DonorIcon,
'ellipsis': EllipsisIcon,
'email': EmailIcon,
'error': ErrorIcon,
'fullscreen': FullscreenIcon,
'gab-logo': GabLogoIcon,
@ -90,6 +99,8 @@ const ICONS = {
'list': ListIcon,
'list-add': ListAddIcon,
'loading': LoadingIcon,
'lock': LockIcon,
'lock-filled': LockFilledIcon,
'media': MediaIcon,
'minimize-fullscreen': MinimizeFullscreenIcon,
'missing': MissingIcon,
@ -113,6 +124,7 @@ const ICONS = {
'trends': TrendsIcon,
'ul-list': ULListIcon,
'underline': UnderlineIcon,
'unlock-filled': UnlockFilledIcon,
'verified': VerifiedIcon,
'warning': WarningIcon,
'': CircleIcon,

View File

@ -9,7 +9,10 @@ export default class List extends ImmutablePureComponent {
items: PropTypes.array,
scrollKey: PropTypes.string,
emptyMessage: PropTypes.any,
small: PropTypes.bool,
size: PropTypes.oneOf([
'small',
'large'
]),
onLoadMore: PropTypes.func,
hasMore: PropTypes.bool,
}
@ -20,7 +23,7 @@ export default class List extends ImmutablePureComponent {
scrollKey,
emptyMessage,
hasMore,
small,
size,
onLoadMore
} = this.props
@ -35,7 +38,7 @@ export default class List extends ImmutablePureComponent {
{
items.map((item, i) => (
<ListItem
small={small}
size={size}
key={`list-item-${i}`}
isLast={items.size - 1 === i}
{...item}

View File

@ -13,7 +13,9 @@ export default class ListItem extends PureComponent {
href: PropTypes.string,
title: PropTypes.string,
onClick: PropTypes.func,
small: PropTypes.bool,
size: PropTypes.oneOf([
'small', 'large'
]),
hideArrow: PropTypes.bool,
}
@ -24,11 +26,14 @@ export default class ListItem extends PureComponent {
to,
href,
onClick,
small,
size,
icon,
hideArrow,
} = this.props
const small = size === 'small'
const large = size === 'large'
const containerClasses = cx({
default: 1,
cursorPointer: 1,
@ -45,7 +50,14 @@ export default class ListItem extends PureComponent {
borderBottom1PX: !isLast,
})
const textSize = small ? 'small' : 'normal'
const iconClasses = cx({
mr10: !large,
mr15: large,
fillColorBlack: 1,
})
const textSize = small ? 'small' : large ? 'medium' : 'normal'
const iconSize = large ? '14px' : '10px'
return (
<Button
@ -60,9 +72,9 @@ export default class ListItem extends PureComponent {
!!icon &&
<Icon
id={icon}
width='10px'
height='10px'
className={[_s.mr10, _s.fillColorBlack].join(' ')}
width={iconSize}
height={iconSize}
className={iconClasses}
/>
}

View File

@ -33,6 +33,7 @@ class BlockAccountModal extends PureComponent {
static propTypes = {
account: PropTypes.object.isRequired,
onConfirm: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
}
@ -41,7 +42,7 @@ class BlockAccountModal extends PureComponent {
}
render() {
const { account, intl } = this.props
const { account, intl, onClose } = this.props
const title = intl.formatMessage(messages.title, {
name: !!account ? account.get('acct') : '',
@ -56,6 +57,7 @@ class BlockAccountModal extends PureComponent {
message={message}
confirm={intl.formatMessage(messages.block)}
onConfirm={this.handleClick}
onClose={onClose}
/>
)
}

View File

@ -1,7 +1,6 @@
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { closeModal } from '../../actions/modal'
import { changeSetting, saveSettings } from '../../actions/settings'
import ModalLayout from './modal_layout'
import Button from '../button'
@ -19,14 +18,14 @@ const mapStateToProps = state => ({
settings: state.getIn(['settings', 'community']),
})
const mapDispatchToProps = dispatch => {
const mapDispatchToProps = (dispatch, { onClose }) => {
return {
onChange(key, checked) {
dispatch(changeSetting(['community', ...key], checked))
},
onSave() {
dispatch(saveSettings())
dispatch(closeModal())
onClose()
},
}
}
@ -48,7 +47,7 @@ class CommunityTimelineSettingsModal extends ImmutablePureComponent {
}
render() {
const { intl, settings, onChange } = this.props
const { intl, settings, onChange, onClose } = this.props
return (
<ModalLayout

View File

@ -60,11 +60,14 @@ class EmbedModal extends ImmutablePureComponent {
}
render() {
const { intl } = this.props
const { intl, onClose } = this.props
const { oembed } = this.state
return (
<ModalLayout title={intl.formatMessage(messages.embed)}>
<ModalLayout
title={intl.formatMessage(messages.embed)}
onClose={onClose}
>
<div className={_s.default}>
<Text className={_s.my10}>
{intl.formatMessage(messages.instructions)}

View File

@ -6,7 +6,6 @@ import {
setSelectedGif,
changeGifSearchText
} from '../../actions/tenor'
import { closeModal } from '../../actions/modal'
import Block from '../block'
import Button from '../button'
import ColumnIndicator from '../column_indicator'
@ -29,12 +28,12 @@ const mapStateToProps = (state) => ({
searchText: state.getIn(['tenor', 'searchText']),
})
export const mapDispatchToProps = (dispatch) => ({
export const mapDispatchToProps = (dispatch, { onClose }) => ({
handleCloseModal() {
dispatch(changeGifSearchText(''))
dispatch(clearGifResults())
dispatch(closeModal())
onClose()
},
handleFetchCategories: () => {

View File

@ -13,15 +13,17 @@ class GroupCreateModal extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired,
}
render() {
const { intl } = this.props
const { intl, onClose } = this.props
return (
<ModalLayout
title={intl.formatMessage(messages.title)}
width='440'
onClose={onClose}
>
<GroupCreate />
</ModalLayout>

View File

@ -25,6 +25,7 @@ class GroupDeleteModal extends PureComponent {
static propTypes = {
group: PropTypes.object.isRequired,
onConfirm: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
}
@ -33,7 +34,7 @@ class GroupDeleteModal extends PureComponent {
}
render() {
const { group, intl } = this.props
const { group, intl, onClose } = this.props
const title = intl.formatMessage(messages.title, {
group: !!group ? account.get('title') : '',
@ -48,6 +49,7 @@ class GroupDeleteModal extends PureComponent {
message={message}
confirm={intl.formatMessage(messages.delete)}
onConfirm={this.handleClick}
onClose={onClose}
/>
)
}

View File

@ -1,7 +1,6 @@
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { closeModal } from '../../actions/modal'
import { changeSetting, saveSettings } from '../../actions/settings'
import ModalLayout from './modal_layout'
import Button from '../button'
@ -19,14 +18,14 @@ const mapStateToProps = state => ({
settings: state.getIn(['settings', 'community']),
})
const mapDispatchToProps = dispatch => {
const mapDispatchToProps = (dispatch, { onClose }) => {
return {
onChange(key, checked) {
dispatch(changeSetting(['community', ...key], checked))
},
onSave() {
dispatch(saveSettings())
dispatch(closeModal())
onClose()
},
}
}
@ -41,6 +40,7 @@ class HashtagTimelineSettingsModal extends ImmutablePureComponent {
settings: ImmutablePropTypes.map.isRequired,
onChange: PropTypes.func.isRequired,
onSave: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
}
handleSaveAndClose = () => {
@ -48,7 +48,7 @@ class HashtagTimelineSettingsModal extends ImmutablePureComponent {
}
render() {
const { intl, settings, onChange } = this.props
const { intl, settings, onChange, onClose } = this.props
// : todo :
@ -56,6 +56,7 @@ class HashtagTimelineSettingsModal extends ImmutablePureComponent {
<ModalLayout
width='320'
title={intl.formatMessage(messages.title)}
onClose={onClose}
>
<div className={[_s.default, _s.pb10].join(' ')}>

View File

@ -1,7 +1,6 @@
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { closeModal } from '../../actions/modal'
import { changeSetting, saveSettings } from '../../actions/settings'
import ModalLayout from './modal_layout'
import Button from '../button'
@ -22,14 +21,14 @@ const mapStateToProps = state => ({
settings: state.getIn(['settings', 'home']),
})
const mapDispatchToProps = dispatch => {
const mapDispatchToProps = (dispatch, {onClose}) => {
return {
onChange(key, checked) {
dispatch(changeSetting(['home', ...key], checked))
},
onSave() {
dispatch(saveSettings())
dispatch(closeModal())
onClose()
},
}
}
@ -43,6 +42,7 @@ class HomeTimelineSettingsModal extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
settings: ImmutablePropTypes.map.isRequired,
onChange: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
onSave: PropTypes.func.isRequired,
}
@ -51,12 +51,13 @@ class HomeTimelineSettingsModal extends ImmutablePureComponent {
}
render() {
const { intl, settings, onChange } = this.props
const { intl, settings, onChange, onClose } = this.props
return (
<ModalLayout
width='320'
title={intl.formatMessage(messages.title)}
onClose={onClose}
>
<div className={[_s.default, _s.pb10].join(' ')}>

View File

@ -42,13 +42,17 @@ class HotkeysModal extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired,
}
render() {
const { intl } = this.props
const { intl, onClose } = this.props
return (
<ModalLayout title={intl.formatMessage(messages.heading)}>
<ModalLayout
title={intl.formatMessage(messages.heading)}
onClose={onClose}
>
<div className={[_s.default, _s.flexRow].join(' ')}>
<table>
<thead>

View File

@ -13,15 +13,17 @@ class ListCreateModal extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired,
}
render() {
const { intl } = this.props
const { intl, onClose } = this.props
return (
<ModalLayout
title={intl.formatMessage(messages.title)}
width='500'
onClose={onClose}
>
<ListCreate />
</ModalLayout>

View File

@ -33,7 +33,7 @@ class ListDeleteModal extends PureComponent {
}
render() {
const { list, intl } = this.props
const { list, intl, onClose } = this.props
const title = intl.formatMessage(messages.title, {
list: !!list ? account.get('title') : '',
@ -48,6 +48,7 @@ class ListDeleteModal extends PureComponent {
message={message}
confirm={intl.formatMessage(messages.delete)}
onConfirm={this.handleClick}
onClose={onClose}
/>
)
}

View File

@ -1,7 +1,6 @@
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { closeModal } from '../../actions/modal'
import { changeSetting, saveSettings } from '../../actions/settings'
import ModalLayout from './modal_layout'
import Button from '../button'
@ -22,14 +21,14 @@ const mapStateToProps = state => ({
settings: state.getIn(['settings', 'list']),
})
const mapDispatchToProps = dispatch => {
const mapDispatchToProps = (dispatch, { onClose }) => {
return {
onChange(key, checked) {
dispatch(changeSetting(['list', ...key], checked))
},
onSave() {
dispatch(saveSettings())
dispatch(closeModal())
onClose()
},
}
}
@ -43,6 +42,7 @@ class ListTimelineSettingsModal extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
settings: ImmutablePropTypes.map.isRequired,
onChange: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
onSave: PropTypes.func.isRequired,
}
@ -51,12 +51,13 @@ class ListTimelineSettingsModal extends ImmutablePureComponent {
}
render() {
const { intl, settings, onChange } = this.props
const { intl, settings, onChange, onClose } = this.props
return (
<ModalLayout
width='320'
title={intl.formatMessage(messages.title)}
onClose={onClose}
>
<div className={[_s.default, _s.pb10].join(' ')}>

View File

@ -54,9 +54,11 @@ class ModalBase extends PureComponent {
}
}
handleOnClose = () => {
handleOnClose = (e) => {
const { onOpenModal, composeText, composeId, onClose, intl, type, onCancelReplyCompose } = this.props
if (this.dialog !== e.target) return
if (!composeId && composeText && type == 'COMPOSE') {
onOpenModal('CONFIRM', {
message: intl.formatMessage(messages.delete),
@ -108,8 +110,12 @@ class ModalBase extends PureComponent {
return Array(...this.node.parentElement.childNodes).filter(node => node !== this.node)
}
setRef = ref => {
this.node = ref
setRef = (n) => {
this.node = n
}
setDialog = (n) => {
this.dialog = n
}
render () {
@ -133,10 +139,11 @@ class ModalBase extends PureComponent {
<div
role='presentation'
className={[_s.default, _s.backgroundColorOpaque, _s.positionFixed, _s.z3, _s.top0, _s.right0, _s.bottom0, _s.left0].join(' ')}
onClick={this.handleOnClose}
/>
<div
ref={this.setDialog}
role='dialog'
onClick={this.handleOnClose}
className={[_s.default, _s.positionFixed, _s.alignItemsCenter, _s.justifyContentCenter, _s.z4, _s.width100PC, _s.height100PC, _s.top0, _s.rightAuto, _s.bottomAuto, _s.left0].join(' ')}
>
{children}

View File

@ -1,6 +1,5 @@
import { defineMessages, injectIntl } from 'react-intl'
import classNames from 'classnames/bind'
import { closeModal } from '../../actions/modal'
import Button from '../button'
import Block from '../block'
import Heading from '../heading'
@ -11,16 +10,7 @@ const messages = defineMessages({
close: { id: 'lightbox.close', defaultMessage: 'Close' },
})
const mapDispatchToProps = dispatch => {
return {
handleCloseModal() {
dispatch(closeModal())
},
}
}
export default
@connect(null, mapDispatchToProps)
@injectIntl
class ModalLayout extends PureComponent {
static propTypes = {
@ -38,11 +28,7 @@ class ModalLayout extends PureComponent {
}
onHandleCloseModal = () => {
if (this.props.onClose) {
this.props.onClose();
} else {
this.props.handleCloseModal()
}
this.props.onClose()
}
render() {

View File

@ -114,8 +114,7 @@ class ModalRoot extends PureComponent {
}
onClickClose = () => {
const { onClose, type } = this.props
onClose(type)
this.props.onClose(this.props.type)
}
render() {

View File

@ -34,6 +34,7 @@ class MuteModal extends PureComponent {
account: PropTypes.object.isRequired,
onConfirm: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired,
}
handleClick = () => {
@ -41,7 +42,7 @@ class MuteModal extends PureComponent {
}
render() {
const { account, intl } = this.props
const { account, intl, onClose } = this.props
const title = intl.formatMessage(messages.title, {
name: !!account ? account.get('acct') : '',
@ -56,6 +57,7 @@ class MuteModal extends PureComponent {
message={message}
confirm={intl.formatMessage(messages.mute)}
onConfirm={this.handleClick}
onClose={onClose}
/>
)
}

View File

@ -16,13 +16,18 @@ class ProUpgradeModal extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired,
}
render() {
const { intl } = this.props
const { intl, onClose } = this.props
return (
<ModalLayout title={intl.formatMessage(messages.title)} width='460'>
<ModalLayout
title={intl.formatMessage(messages.title)}
width='460'
onClose={onClose}
>
<Text>
{intl.formatMessage(messages.text)}
</Text>

View File

@ -20,13 +20,13 @@ const messages = defineMessages({
forwardHint: { id: 'report.forward_hint', defaultMessage: 'The account is from another server. Send an anonymized copy of the report there as well?' },
forward: { id: 'report.forward', defaultMessage: 'Forward to {target}' },
target: { id: 'report.target', defaultMessage: 'Report {target}' },
});
})
const makeMapStateToProps = () => {
const getAccount = makeGetAccount();
const getAccount = makeGetAccount()
const mapStateToProps = state => {
const accountId = state.getIn(['reports', 'new', 'account_id']);
const accountId = state.getIn(['reports', 'new', 'account_id'])
return {
isSubmitting: state.getIn(['reports', 'new', 'isSubmitting']),
@ -34,11 +34,11 @@ const makeMapStateToProps = () => {
comment: state.getIn(['reports', 'new', 'comment']),
forward: state.getIn(['reports', 'new', 'forward']),
statusIds: OrderedSet(state.getIn(['timelines', `account:${accountId}:with_replies`, 'items'])).union(state.getIn(['reports', 'new', 'status_ids'])),
};
};
}
}
return mapStateToProps;
};
return mapStateToProps
}
export default
@connect(makeMapStateToProps)
@ -53,33 +53,34 @@ class ReportModal extends ImmutablePureComponent {
forward: PropTypes.bool,
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
};
onClose: PropTypes.func.isRequired,
}
handleCommentChange = e => {
this.props.dispatch(changeReportComment(e.target.value));
this.props.dispatch(changeReportComment(e.target.value))
}
handleForwardChange = e => {
this.props.dispatch(changeReportForward(e.target.checked));
this.props.dispatch(changeReportForward(e.target.checked))
}
handleSubmit = () => {
this.props.dispatch(submitReport());
this.props.dispatch(submitReport())
}
handleKeyDown = e => {
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
this.handleSubmit();
this.handleSubmit()
}
}
componentDidMount () {
this.props.dispatch(expandAccountTimeline(this.props.account.get('id'), { withReplies: true }));
this.props.dispatch(expandAccountTimeline(this.props.account.get('id'), { withReplies: true }))
}
componentWillReceiveProps (nextProps) {
if (this.props.account !== nextProps.account && nextProps.account) {
this.props.dispatch(expandAccountTimeline(nextProps.account.get('id'), { withReplies: true }));
this.props.dispatch(expandAccountTimeline(nextProps.account.get('id'), { withReplies: true }))
}
}
@ -96,7 +97,7 @@ class ReportModal extends ImmutablePureComponent {
if (!account) return null
const domain = account.get('acct').split('@')[1];
const domain = account.get('acct').split('@')[1]
return (
<ModalLayout
@ -104,6 +105,7 @@ class ReportModal extends ImmutablePureComponent {
title={intl.formatMessage(messages.target, {
target: account.get('acct')
})}
onClose={onClose}
>
<div className={[_s.default, _s.flexRow].join(' ')}>
@ -168,7 +170,7 @@ class ReportModal extends ImmutablePureComponent {
</div>
</div>
</ModalLayout>
);
)
}
}

View File

@ -39,6 +39,7 @@ class StatusRevisionsModal extends ImmutablePureComponent {
loading: PropTypes.bool.isRequired,
error: PropTypes.bool,
revisions: ImmutablePropTypes.list.isRequired,
onClose: PropTypes.func.isRequired,
}
componentDidMount() {
@ -49,14 +50,16 @@ class StatusRevisionsModal extends ImmutablePureComponent {
const {
intl,
status,
revisions
revisions,
onClose
} = this.props
console.log("revisions:", revisions)
console.log("revisions.size:", revisions.size)
return (
<ModalLayout title={intl.formatMessage(messages.title)} width='480'>
<ModalLayout
title={intl.formatMessage(messages.title)}
width='480'
onClose={onClose}
>
<div className={[_s.default]}>
<ScrollableList>
{

View File

@ -19,13 +19,17 @@ class UnauthorizedModal extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired,
}
render() {
const { intl } = this.props
return (
<ModalLayout title={intl.formatMessage(messages.signup)}>
<ModalLayout
title={intl.formatMessage(messages.signup)}
onClose={onClose}
>
<div className={[_s.default, _s.px10, _s.py10].join(' ')}>
<Text className={_s.mb15}>
{intl.formatMessage(messages.text)}

View File

@ -31,6 +31,7 @@ class UnfollowModal extends PureComponent {
isSubmitting: PropTypes.bool.isRequired,
account: PropTypes.object.isRequired,
onConfirm: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
}
@ -61,6 +62,7 @@ class UnfollowModal extends PureComponent {
title={`Mute @${account.get('acct')}`}
message={<FormattedMessage id='confirmations.mute.message' defaultMessage='Are you sure you want to mute @{name}?' values={{ name: account.get('acct') }} />}
confirm={<FormattedMessage id='mute' defaultMessage='Mute' />}
onClose={onClose}
onConfirm={() => {
// dispatch(blockDomain(domain))
// dispatch(blockDomain(domain))

View File

@ -37,13 +37,13 @@ class MediaGalleryPanel extends ImmutablePureComponent {
const { accountId } = this.props
if (accountId) {
this.props.dispatch(expandAccountMediaTimeline(accountId, {limit: 8}))
this.props.dispatch(expandAccountMediaTimeline(accountId, { limit: 8 }))
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.accountId && nextProps.accountId !== this.props.accountId) {
this.props.dispatch(expandAccountMediaTimeline(nextProps.accountId, {limit: 8}))
this.props.dispatch(expandAccountMediaTimeline(nextProps.accountId, { limit: 8 }))
}
}

View File

@ -1,33 +1,59 @@
import { defineMessages, injectIntl } from 'react-intl'
import ImmutablePureComponent from 'react-immutable-pure-component'
import ImmutablePropTypes from 'react-immutable-proptypes'
import { changeSetting, saveSettings } from '../../actions/settings'
import PanelLayout from './panel_layout'
import Switch from '../switch'
import SettingSwitch from '../setting_switch'
const messages = defineMessages({
title: { id: 'notification_filters', defaultMessage: 'Notification Filters' },
onlyVerified: { id: 'notification_only_verified', defaultMessage: 'Only Verified Users' },
onlyFollowing: { id: 'notification_only_following', defaultMessage: 'Only People I Follow' },
})
const mapStateToProps = state => ({
settings: state.getIn(['settings', 'notifications']),
})
const mapDispatchToProps = (dispatch) => {
return {
onChange(key, checked) {
dispatch(changeSetting(['notifications', ...key], checked))
dispatch(saveSettings())
},
}
}
export default
@injectIntl
@connect(mapStateToProps, mapDispatchToProps)
class NotificationFilterPanel extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired,
settings: ImmutablePropTypes.map.isRequired,
}
render() {
const { intl } = this.props
const { intl, onChange, settings } = this.props
return (
<PanelLayout title={intl.formatMessage(messages.title)}>
<Switch
id='notifications-verified'
label='Only Verified Users'
<SettingSwitch
prefix='notification'
settings={settings}
settingPath={['quickFilter', 'onlyVerifed']}
onChange={onChange}
label={intl.formatMessage(messages.onlyVerified)}
/>
<Switch
id='notifications-verified'
label='Only People I Follow'
<SettingSwitch
prefix='notification'
settings={settings}
settingPath={['quickFilter', 'onlyFollowing']}
onChange={onChange}
label={intl.formatMessage(messages.onlyFollowing)}
/>
</PanelLayout>
)

View File

@ -7,7 +7,7 @@ import ColumnIndicator from '../column_indicator'
import TrendingItem from '../trends_item'
const messages = defineMessages({
title: { id:'trends.title', defaultMessage: 'Trending right now' },
title: { id: 'trends.title', defaultMessage: 'Trending right now' },
})
const mapStateToProps = state => ({
@ -31,7 +31,7 @@ class TrendsPanel extends ImmutablePureComponent {
onFetchGabTrends: PropTypes.func.isRequired,
}
componentWillMount () {
componentWillMount() {
this.props.onFetchGabTrends()
}
@ -52,7 +52,7 @@ class TrendsPanel extends ImmutablePureComponent {
gabtrends && gabtrends.slice(0, 8).map((trend, i) => (
<TrendingItem
key={`gab-trend-${i}`}
index={i+1}
index={i + 1}
isLast={i === 7}
url={trend.get('url')}
title={trend.get('title')}

View File

@ -4,13 +4,18 @@ export default class PopoverLayout extends PureComponent {
static propTypes = {
children: PropTypes.node,
className: PropTypes.string,
width: PropTypes.number,
}
static defaultProps = {
width: 250,
}
render() {
const { children, className } = this.props
const { children, className, width } = this.props
return (
<div className={className}>
<div className={className} style={{width: `${width}px`}}>
<Block>
{children}
</Block>

View File

@ -310,7 +310,7 @@ class ProfileOptionsPopover extends PureComponent {
<List
scrollKey='profile_options'
items={listItems}
small
size='large'
/>
</PopoverLayout>
)

View File

@ -6,6 +6,7 @@ export default class SidebarMorePopover extends PureComponent {
return (
<PopoverLayout className={_s.width240PX}>
<List
size='large'
scrollKey='profile_options'
items={[
{
@ -21,7 +22,6 @@ export default class SidebarMorePopover extends PureComponent {
href: '/auth/log_out',
},
]}
small
/>
</PopoverLayout>
)

View File

@ -142,9 +142,9 @@ class StatusOptionsPopover extends ImmutablePureComponent {
return (
<PopoverLayout className={_s.width240PX}>
<List
size='large'
scrollKey='profile_options'
items={items}
small
/>
</PopoverLayout>
)

View File

@ -24,6 +24,8 @@ const messages = defineMessages({
// });
// : todo :
export default
@injectIntl
// @connect(makeMapStateToProps, mapDispatchToProps)
@ -60,8 +62,9 @@ class StatusSharePopover extends ImmutablePureComponent {
const { intl } = this.props
return (
<PopoverLayout className={_s.width250PX}>
<PopoverLayout width={220}>
<List
size='large'
scrollKey='status_share_options'
items={[
{
@ -71,13 +74,13 @@ class StatusSharePopover extends ImmutablePureComponent {
onClick: this.handleCopy,
},
{
icon: 'envelope',
icon: 'email',
hideArrow: true,
title: intl.formatMessage(messages.email),
href: 'mailto:',
},
{
icon: 'embed',
icon: 'code',
hideArrow: true,
title: intl.formatMessage(messages.embed),
onClick: this.handleEmbed,

View File

@ -58,13 +58,13 @@ class StatusVisibilityDropdown extends PureComponent {
subtitle: intl.formatMessage(messages.public_long)
},
{
icon: 'unlock',
icon: 'unlock-filled',
value: 'unlisted',
title: intl.formatMessage(messages.unlisted_short),
subtitle: intl.formatMessage(messages.unlisted_long)
},
{
icon: 'lock',
icon: 'lock-filled',
value: 'private',
title: intl.formatMessage(messages.private_short),
subtitle: intl.formatMessage(messages.private_long)

View File

@ -14,11 +14,12 @@ import { initReport } from '../actions/reports'
import { openModal } from '../actions/modal'
import { unfollowModal, me } from '../initial_state'
import Avatar from './avatar'
import Image from './image'
import Text from './text'
import Button from './button'
import DisplayName from './display_name'
import Icon from './icon'
import Image from './image'
import TabBar from './tab_bar'
import Text from './text'
const cx = classNames.bind(_s)
@ -240,6 +241,7 @@ class ProfileHeader extends ImmutablePureComponent {
}
console.log("buttonOptions:", buttonText, buttonOptions)
console.log("account: ", account)
// : todo : "follows you", "mutual follow"
@ -264,8 +266,12 @@ class ProfileHeader extends ImmutablePureComponent {
<Avatar size={avatarSize} account={account} />
</div>
<div className={[_s.default, _s.px15, _s.py10].join(' ')}>
<div className={[_s.default, _s.flexRow, _s.px15, _s.py10].join(' ')}>
<DisplayName account={account} multiline large />
{
account && account.get('locked') &&
<Icon id='lock-filled' height='14px' width='14px' className={[_s.mt10, _s.ml10].join(' ')} />
}
</div>
</div>

View File

@ -37,7 +37,7 @@ const mapStateToProps = state => {
return {
account: getAccount(state, me),
sidebarOpen: state.get('sidebar').sidebarOpen,
moreOpen: state.get('popover').popoverType === 'SIDEBAR_MORE',
notificationCount: state.getIn(['notifications', 'unread']),
homeItemsQueueCount: state.getIn(['timelines', 'home', 'totalQueuedItemsCount']),
showCommunityTimeline: state.getIn(['settings', 'community', 'shows', 'inSidebar']),
@ -64,8 +64,8 @@ class Sidebar extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map,
sidebarOpen: PropTypes.bool,
showCommunityTimeline: PropTypes.bool,
moreOpen: PropTypes.bool,
onClose: PropTypes.func.isRequired,
onOpenComposeModal: PropTypes.func.isRequired,
openSidebarMorePopover: PropTypes.func.isRequired,
@ -73,39 +73,11 @@ class Sidebar extends ImmutablePureComponent {
homeItemsQueueCount: PropTypes.number.isRequired,
}
state = {
moreOpen: false,
}
componentDidUpdate() {
if (!me) return
if (this.props.sidebarOpen) {
document.body.classList.add('with-modals--active')
} else {
document.body.classList.remove('with-modals--active')
}
}
toggleMore = () => {
this.setState({
moreOpen: !this.state.moreOpen
})
}
handleSidebarClose = () => {
this.props.onClose()
this.setState({
moreOpen: false,
})
}
handleOpenComposeModal = () => {
this.props.onOpenComposeModal()
}
handleOpenSidebarMorePopover =() => {
console.log("handleOpenSidebarMorePopover")
this.props.openSidebarMorePopover({
targetRef: this.moreBtnRef,
position: 'top',
@ -118,14 +90,13 @@ class Sidebar extends ImmutablePureComponent {
render() {
const {
sidebarOpen,
intl,
account,
notificationCount,
homeItemsQueueCount,
showCommunityTimeline
showCommunityTimeline,
moreOpen
} = this.props
const { moreOpen } = this.state
// : todo :
if (!me || !account) return null
@ -133,9 +104,6 @@ class Sidebar extends ImmutablePureComponent {
const acct = account.get('acct')
const isPro = account.get('is_pro')
const moreIcon = moreOpen ? 'minus' : 'plus'
const moreContainerStyle = { display: moreOpen ? 'block' : 'none' }
console.log("showCommunityTimeline:", showCommunityTimeline)
const menuItems = [
@ -182,7 +150,8 @@ class Sidebar extends ImmutablePureComponent {
title: 'More',
icon: 'more',
onClick: this.handleOpenSidebarMorePopover,
buttonRef: this.setMoreButtonRef
buttonRef: this.setMoreButtonRef,
active: moreOpen,
},
]
@ -243,7 +212,7 @@ class Sidebar extends ImmutablePureComponent {
)
})
}
<SidebarSectionTitle>Shortcuts</SidebarSectionTitle>
{ /* <SidebarSectionTitle>Shortcuts</SidebarSectionTitle> */ }
{
shortcutItems.map((shortcutItem, i) => (
<SidebarSectionItem {...shortcutItem} key={`sidebar-item-shortcut-${i}`} />

View File

@ -28,16 +28,15 @@ class SidebarHeader extends ImmutablePureComponent {
const { account } = this.props
const isPro = account.get('is_pro')
const gabLogoClasses = isPro ? _s.fillColorGabPro : _s.fillColorBrand
return (
<Fragment>
<h1 className={[_s.default].join(' ')}>
<NavLink to='/' aria-label='Gab' className={[_s.default, _s.flexRow, _s.noSelect, _s.noUnderline, _s.height50PX, _s.cursorPointer, _s.px10].join(' ')}>
<Icon id='gab-logo' className={gabLogoClasses} />
<Icon id='gab-logo' className={_s.fillColorBrand} />
{
isPro &&
<Text weight='bold' color='pro' size='extraSmall' className={[_s.pb5].join(' ')}>
<Text weight='bold' color='brand' size='extraSmall' className={[_s.pb5].join(' ')}>
PRO
</Text>
}

View File

@ -77,6 +77,7 @@ export default class SidebarSectionItem extends PureComponent {
fontSize15PX: 1,
text: 1,
textOverflowEllipsis: 1,
outlineNone: 1,
colorSecondary: !hovering && !active && !me && !shouldShowActive,
colorPrimary: shouldShowActive || me,
})

View File

@ -144,17 +144,8 @@ class StatusActionBar extends ImmutablePureComponent {
const publicStatus = ['public', 'unlisted'].includes(status.get('visibility'))
const replyCount = status.get('replies_count')
const replyIcon = (status.get('in_reply_to_id', null) === null) ? 'reply' : 'reply-all'
const replyTitle = (status.get('in_reply_to_id', null) === null) ? formatMessage(messages.reply) : formatMessage(messages.replyAll)
const repostCount = status.get('reblogs_count')
const repostTitle = !publicStatus ? formatMessage(messages.cannot_repost) : formatMessage(messages.repost)
const favoriteCount = status.get('favourites_count') // : todo :
const shareButton = ('share' in navigator) && status.get('visibility') === 'public' && (
<Button className='status-action-bar-button' title={formatMessage(messages.share)} icon='share-alt' onClick={this.handleShareClick} />
)
const favoriteCount = status.get('favourites_count')
const hasInteractions = favoriteCount > 0 || replyCount > 0 || repostCount > 0
const shouldCondense = (
@ -240,8 +231,9 @@ class StatusActionBar extends ImmutablePureComponent {
onClick={this.handleReplyClick}
/>
<StatusActionBarItem
title={repostTitle}
icon={(status.get('visibility') === 'private') ? 'lock' : 'repost'}
title={formatMessage(messages.repost)}
altTitle={!publicStatus ? formatMessage(messages.cannot_repost) : ''}
icon={!publicStatus ? 'lock' : 'repost'}
disabled={!publicStatus}
active={!!status.get('reblogged')}
onClick={this.handleRepostClick}

View File

@ -8,6 +8,7 @@ const cx = classNames.bind(_s)
export default class StatusActionBarItem extends PureComponent {
static propTypes = {
title: PropTypes.string.isRequired,
altTitle: PropTypes.string,
onClick: PropTypes.func.isRequired,
icon: PropTypes.string.isRequired,
active: PropTypes.bool,
@ -22,14 +23,15 @@ export default class StatusActionBarItem extends PureComponent {
icon,
active,
disabled,
buttonRef
buttonRef,
altTitle
} = this.props
const btnClasses = cx({
justifyContentCenter: 1,
alignItemsCenter: 1,
px10: 1,
backgroundSubtle_onHover: 1,
backgroundSubtle_onHover: !disabled,
})
const color = active ? 'brand' : 'secondary'
@ -41,6 +43,7 @@ export default class StatusActionBarItem extends PureComponent {
block
radiusSmall
backgroundColor='none'
title={altTitle}
color={color}
buttonRef={buttonRef}
className={btnClasses}

View File

@ -138,6 +138,7 @@ class StatusHeader extends ImmutablePureComponent {
})
const avatarSize = reduced ? 20 : 46
const visibilityIcon = 'globe'
return (
<div className={containerClasses}>
@ -197,7 +198,7 @@ class StatusHeader extends ImmutablePureComponent {
<DotTextSeperator />
<Icon id='globe' width='12px' height='12px' className={[_s.default, _s.displayInline, _s.ml5, _s.fillColorSecondary].join(' ')} />
<Icon id={visibilityIcon} width='12px' height='12px' className={[_s.default, _s.displayInline, _s.ml5, _s.fillColorSecondary].join(' ')} />
{
!!status.get('group') &&

View File

@ -20,17 +20,15 @@ class TabBarItem extends PureComponent {
}
state = {
active: -1,
isCurrent: -1,
}
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
const isCurrent = this.props.to === this.props.location.pathname
if (this.state.active !== isCurrent) {
this.setState({
active: isCurrent,
})
if (this.state.isCurrent !== isCurrent) {
this.setState({ isCurrent })
}
}
}
@ -43,11 +41,11 @@ class TabBarItem extends PureComponent {
location,
large,
icon,
// active
active
} = this.props
const { active } = this.state
const { isCurrent } = this.state
const isCurrent = active === -1 ? to === location.pathname : active
const isActive = active || (isCurrent === -1 ? to === location.pathname : false)
const containerClasses = cx({
default: 1,
@ -61,8 +59,8 @@ class TabBarItem extends PureComponent {
py5: 1,
cursorPointer: 1,
backgroundTransparent: 1,
borderColorTransparent: !isCurrent,
borderColorBrand: isCurrent,
borderColorTransparent: !isActive,
borderColorBrand: isActive,
mr5: large,
})
@ -74,13 +72,13 @@ class TabBarItem extends PureComponent {
radiusSmall: 1,
px10: !large,
px15: large,
backgroundSubtle2Dark_onHover: !isCurrent,
backgroundSubtle2Dark_onHover: !isActive,
})
const textOptions = {
size: !!large ? 'normal' : 'small',
color: isCurrent ? 'brand' : large ? 'secondary' : 'primary',
weight: isCurrent ? 'bold' : large ? 'medium' : 'normal',
color: isActive ? 'brand' : large ? 'secondary' : 'primary',
weight: isActive ? 'bold' : large ? 'medium' : 'normal',
}
const iconOptions = {
@ -92,8 +90,8 @@ class TabBarItem extends PureComponent {
return (
<Button
onClick={onClick}
to={to}
className={containerClasses}
to={to || undefined}
noClasses
>
<span className={textParentClasses}>

View File

@ -18,6 +18,13 @@ export default class TrendingItem extends PureComponent {
author: PropTypes.string,
publishDate: PropTypes.string,
isLast: PropTypes.bool,
wide: PropTypes.bool,
}
static defaultProps = {
title: '',
description: '',
author: '',
}
state = {
@ -41,7 +48,8 @@ export default class TrendingItem extends PureComponent {
imageUrl,
author,
publishDate,
isLast
isLast,
wide
} = this.props
const { hovering } = this.state
@ -62,23 +70,31 @@ export default class TrendingItem extends PureComponent {
})
const correctedAuthor = author.replace('www.', '')
const correctedDescription = description.length > 120 ? `${description.substring(0, 120)}...` : description
const correctedDescription = description.length > 120 ? `${description.substring(0, 120).trim()}...` : description
const image = (
<Image
nullable
width='116px'
height='78px'
src={imageUrl}
className={[_s.radiusSmall, _s.overflowHidden, _s.mb10].join(' ')}
/>
)
return (
<Button
noClasses
href={url}
target='_blank'
className={containerClasses}
onMouseEnter={() => this.handleOnMouseEnter()}
onMouseLeave={() => this.handleOnMouseLeave()}
>
<Image
nullable
width='116px'
height='78px'
src={imageUrl}
className={[_s.radiusSmall, _s.overflowHidden, _s.mb10].join(' ')}
/>
{
!wide && image
}
<div className={[_s.default, _s.flexNormal, _s.pb5].join(' ')}>
<div className={_s.default}>
<Text size='medium' color='primary' weight='bold'>
@ -86,11 +102,14 @@ export default class TrendingItem extends PureComponent {
</Text>
</div>
<div className={[_s.default, _s.heightMax56PX, _s.overflowHidden, _s.py5].join(' ')}>
<Text size='small' color='secondary'>
{correctedDescription}
</Text>
</div>
{
!!correctedDescription &&
<div className={[_s.default, _s.heightMax60PX, _s.overflowHidden, _s.py5].join(' ')}>
<Text size='small' color='secondary'>
{correctedDescription}
</Text>
</div>
}
<div className={[_s.default, _s.flexRow].join(' ')}>
<Text color='secondary' size='small'>
{index}
@ -103,8 +122,10 @@ export default class TrendingItem extends PureComponent {
<Text color='secondary' size='small' className={subtitleClasses}>
<RelativeTimestamp timestamp={publishDate} />
</Text>
<DotTextSeperator />
<Text color='secondary' size='small' className={_s.ml5}></Text>
{
hovering &&
<Text color='secondary' size='small' className={_s.ml10}></Text>
}
</div>
</div>
</Button>

View File

@ -124,11 +124,11 @@ class ComposeForm extends ImmutablePureComponent {
}
handleSubmit = () => {
if (this.props.text !== this.autosuggestTextarea.textbox.value) {
// Something changed the text inside the textarea (e.g. browser extensions like Grammarly)
// Update the state to match the current text
this.props.onChange(this.autosuggestTextarea.textbox.value);
}
// if (this.props.text !== this.autosuggestTextarea.textbox.value) {
// // Something changed the text inside the textarea (e.g. browser extensions like Grammarly)
// // Update the state to match the current text
// this.props.onChange(this.autosuggestTextarea.textbox.value);
// }
// Submit disabled:
const { isSubmitting, isChangingUpload, isUploading, anyMedia } = this.props;

View File

@ -1,7 +1,7 @@
import ImmutablePropTypes from 'react-immutable-proptypes'
import ImmutablePureComponent from 'react-immutable-pure-component'
import { FormattedMessage } from 'react-intl'
import TrendingItem from '../../../../components/trends_item'
import HashtagItem from '../../../../components/hashtag_item'
import Icon from '../../../../components/icon'
import { WhoToFollowPanel } from '../../../../components/panel'
// import TrendsPanel from '../../ui/components/trends_panel'
@ -86,7 +86,7 @@ export default class SearchResults extends ImmutablePureComponent {
hashtags = (
<div className='search-results__section'>
<h5><Icon id='hashtag' fixedWidth /><FormattedMessage id='search_results.hashtags' defaultMessage='Hashtags' /></h5>
{results.get('hashtags').slice(0, size).map(hashtag => <TrendingItem key={hashtag.get('name')} hashtag={hashtag} />)}
{results.get('hashtags').slice(0, size).map(hashtag => <HashtagItem key={hashtag.get('name')} hashtag={hashtag} />)}
</div>
);
}

View File

@ -48,10 +48,10 @@ class StatusVisibilityButton extends PureComponent {
let icon;
switch (value) {
case 'unlisted':
icon = 'unlock'
icon = 'unlock-filled'
break;
case 'private':
icon = 'lock'
icon = 'lock-filled'
break;
default:
icon = 'globe'

View File

@ -57,7 +57,6 @@ export default class GroupLayout extends ImmutablePureComponent {
title={title}
showBackBtn={showBackBtn}
actions={actions}
tabs={tabs}
/>
</div>
<div className={[_s.default, _s.width340PX].join(' ')}>

View File

@ -22,8 +22,9 @@ const makeMapStateToProps = state => ({
});
const mapDispatchToProps = (dispatch) => ({
selectFilter (newActiveFilter) {
dispatch(setFilter(newActiveFilter));
selectFilter(newActiveFilter) {
console.log("newActiveFilter:", newActiveFilter)
dispatch(setFilter(newActiveFilter))
},
});
@ -42,43 +43,45 @@ class NotificationsPage extends PureComponent {
document.title = 'Notifications - Gab'
}
onClick (notificationType) {
return () => this.props.selectFilter(notificationType);
onClick(notificationType) {
this.props.selectFilter(notificationType);
}
render() {
const { children } = this.props
const { children, selectedFilter } = this.props
console.log("selectedFilter:", selectedFilter)
const tabs = [
{
title: 'All',
onClick: null,
active: false,
onClick: () => this.onClick('all'),
active: selectedFilter === 'all',
},
{
title: 'Mentions',
onClick: null,
active: false,
onClick: () => this.onClick('mention'),
active: selectedFilter === 'mention',
},
{
title: 'Likes',
onClick: null,
active: false,
onClick: () => this.onClick('favourite'),
active: selectedFilter === 'favourite',
},
{
title: 'Reposts',
onClick: null,
active: false,
onClick: () => this.onClick('reblog'),
active: selectedFilter === 'reblog',
},
{
title: 'Polls',
onClick: null,
active: false,
onClick: () => this.onClick('poll'),
active: selectedFilter === 'poll',
},
{
title: 'Follows',
onClick: null,
active: false,
onClick: () => this.onClick('follow'),
active: selectedFilter === 'follow',
},
]

View File

@ -69,7 +69,7 @@ class ProfilePage extends ImmutablePureComponent {
<Fragment>
<ProfileStatsPanel account={account} />
<ProfileInfoPanel account={account} />
<MediaGalleryPanel account={account} />
{ !unavailable && <MediaGalleryPanel account={account} /> }
<LinkFooter />
</Fragment>
)}

View File

@ -64,7 +64,7 @@ const expandNormalizedNotifications = (state, notifications, next) => {
let items = ImmutableList()
// : todo filter notiications here:
console.log("notifications:", notificationss)
notifications.forEach((n) => {
const notification = notificationToMap(n)
@ -131,6 +131,8 @@ const expandNormalizedNotifications = (state, notifications, next) => {
}
}
console.log("final items: ", items)
return state.withMutations(mutable => {
if (!items.isEmpty()) {
mutable.update('items', list => {

View File

@ -47,6 +47,8 @@ const initialState = ImmutableMap({
// : todo : put all notification settings actually IN settings
quickFilter: ImmutableMap({
active: 'all',
onlyVerifed: false,
onlyFollowing: false,
}),
}),

View File

@ -472,8 +472,8 @@ body {
max-height: 80vh;
}
.heightMax56PX {
max-height: 56px;
.heightMax60PX {
max-height: 60px;
}
.heightMin50VH {
@ -830,6 +830,10 @@ body {
margin-right: 10px;
}
.mr15 {
margin-right: 15px;
}
.ml15 {
margin-left: 15px;
}