Progress
This commit is contained in:
@@ -109,6 +109,9 @@ class Account extends ImmutablePureComponent {
|
||||
const requested = account.getIn(['relationship', 'requested'])
|
||||
const blocking = account.getIn(['relationship', 'blocking'])
|
||||
|
||||
// : todo :
|
||||
// unmute
|
||||
|
||||
if (requested || blocking) {
|
||||
buttonText = intl.formatMessage(requested ? messages.requested : messages.unblock)
|
||||
buttonOptions = {
|
||||
|
||||
@@ -9,6 +9,7 @@ import { textAtCursorMatchesToken } from '../../utils/cursor_token_match'
|
||||
import AutosuggestAccount from '../autosuggest_account'
|
||||
import AutosuggestEmoji from '../autosuggest_emoji'
|
||||
import Input from '../input'
|
||||
import Composer from '../composer'
|
||||
|
||||
const cx = classNames.bind(_s)
|
||||
|
||||
@@ -52,9 +53,9 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
onChange = (e) => {
|
||||
const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart, this.props.searchTokens);
|
||||
const [tokenStart, token] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart, this.props.searchTokens);
|
||||
|
||||
console.log('onChange', e.target.value, e.target, this.textbox, tokenStart, token)
|
||||
// console.log('onChange', e.target.value, e.target, this.textbox, tokenStart, token)
|
||||
|
||||
if (token !== null && this.state.lastToken !== token) {
|
||||
this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart });
|
||||
@@ -80,40 +81,40 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
|
||||
// e.key may be a name of the physical key even in this case (e.x. Safari / Chrome on Mac)
|
||||
if (e.which === 229 || e.isComposing) return;
|
||||
|
||||
switch(e.key) {
|
||||
case 'Escape':
|
||||
if (suggestions.size === 0 || suggestionsHidden) {
|
||||
document.querySelector('.ui').parentElement.focus();
|
||||
} else {
|
||||
e.preventDefault();
|
||||
this.setState({ suggestionsHidden: true });
|
||||
}
|
||||
switch (e.key) {
|
||||
case 'Escape':
|
||||
if (suggestions.size === 0 || suggestionsHidden) {
|
||||
document.querySelector('.ui').parentElement.focus();
|
||||
} else {
|
||||
e.preventDefault();
|
||||
this.setState({ suggestionsHidden: true });
|
||||
}
|
||||
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
if (suggestions.size > 0 && !suggestionsHidden) {
|
||||
e.preventDefault();
|
||||
this.setState({ selectedSuggestion: Math.min(selectedSuggestion + 1, suggestions.size - 1) });
|
||||
}
|
||||
break;
|
||||
case 'ArrowDown':
|
||||
if (suggestions.size > 0 && !suggestionsHidden) {
|
||||
e.preventDefault();
|
||||
this.setState({ selectedSuggestion: Math.min(selectedSuggestion + 1, suggestions.size - 1) });
|
||||
}
|
||||
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
if (suggestions.size > 0 && !suggestionsHidden) {
|
||||
e.preventDefault();
|
||||
this.setState({ selectedSuggestion: Math.max(selectedSuggestion - 1, 0) });
|
||||
}
|
||||
break;
|
||||
case 'ArrowUp':
|
||||
if (suggestions.size > 0 && !suggestionsHidden) {
|
||||
e.preventDefault();
|
||||
this.setState({ selectedSuggestion: Math.max(selectedSuggestion - 1, 0) });
|
||||
}
|
||||
|
||||
break;
|
||||
case 'Enter':
|
||||
case 'Tab':
|
||||
// Select suggestion
|
||||
if (this.state.lastToken !== null && suggestions.size > 0 && !suggestionsHidden) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion));
|
||||
}
|
||||
break;
|
||||
case 'Enter':
|
||||
case 'Tab':
|
||||
// Select suggestion
|
||||
if (this.state.lastToken !== null && suggestions.size > 0 && !suggestionsHidden) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion));
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (e.defaultPrevented || !this.props.onKeyDown) return;
|
||||
@@ -151,7 +152,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
|
||||
this.textbox.focus();
|
||||
}
|
||||
|
||||
componentWillReceiveProps (nextProps) {
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) {
|
||||
this.setState({ suggestionsHidden: false });
|
||||
}
|
||||
@@ -194,7 +195,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
|
||||
this.textbox = c;
|
||||
}
|
||||
|
||||
render () {
|
||||
render() {
|
||||
const {
|
||||
value,
|
||||
small,
|
||||
@@ -245,13 +246,18 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
|
||||
// tabindex="0"
|
||||
// no-focuscontainer-refocus="true"
|
||||
// style="outline: none; user-select: text; white-space: pre-wrap; overflow-wrap: break-word;">
|
||||
|
||||
|
||||
if (textarea) {
|
||||
return (
|
||||
<Fragment>
|
||||
<Fragment>
|
||||
<div className={[_s.default, _s.flexGrow1].join(' ')}>
|
||||
<div className={[_s.default, _s.ml5].join(' ')}>
|
||||
<Textarea
|
||||
|
||||
<Composer
|
||||
/>
|
||||
|
||||
{ /*
|
||||
<Textarea
|
||||
className={_s.default}
|
||||
inputRef={this.setTextbox}
|
||||
disabled={disabled}
|
||||
@@ -282,6 +288,7 @@ export default class AutosuggestTextbox extends ImmutablePureComponent {
|
||||
onBlur={this.onBlur}
|
||||
onPaste={this.onPaste}
|
||||
/>
|
||||
*/ }
|
||||
</div>
|
||||
{children}
|
||||
</div>
|
||||
|
||||
36
app/javascript/gabsocial/components/composer.js
Normal file
36
app/javascript/gabsocial/components/composer.js
Normal file
@@ -0,0 +1,36 @@
|
||||
import {
|
||||
Editor,
|
||||
EditorState,
|
||||
RichUtils
|
||||
} from 'draft-js'
|
||||
|
||||
export default class Composer extends PureComponent {
|
||||
|
||||
state = {
|
||||
editorState: EditorState.createEmpty(),
|
||||
}
|
||||
|
||||
onChange = (editorState) => {
|
||||
this.setState({ editorState })
|
||||
}
|
||||
|
||||
onBoldClick() {
|
||||
this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD'));
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
|
||||
{/*<button onClick={this.onBoldClick.bind(this)}>Bold</button>*/}
|
||||
|
||||
<Editor
|
||||
editorState={this.state.editorState}
|
||||
onChange={this.onChange}
|
||||
/>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
import { NavLink, withRouter } from 'react-router-dom';
|
||||
import { FormattedMessage, injectIntl } from 'react-intl';
|
||||
import NotificationCounter from '../notification_counter';
|
||||
import { me } from '../../initial_state';
|
||||
|
||||
const links = [
|
||||
<NavLink key='pr1' className='footer-bar__link' to='/home' data-preview-title-id='column.home'>
|
||||
@@ -39,8 +38,6 @@ class FooterBar extends PureComponent {
|
||||
render() {
|
||||
const { intl: { formatMessage } } = this.props;
|
||||
|
||||
if (!me) return null;
|
||||
|
||||
return (
|
||||
<div className='footer-bar'>
|
||||
<div className='footer-bar__container'>
|
||||
@@ -1,45 +0,0 @@
|
||||
.footer-bar {
|
||||
display: block;
|
||||
position: fixed;
|
||||
background: #000;
|
||||
height: 58px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 1000;
|
||||
transition: transform 0.2s ease;
|
||||
overflow: hidden;
|
||||
padding-bottom: 0;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
|
||||
@media screen and (min-width: 895px) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
&__container {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
&__link {
|
||||
display: flex;
|
||||
flex: 1 1 auto;
|
||||
margin: 0;
|
||||
min-width: 36px;
|
||||
height: 58px;
|
||||
padding-top: 4px;
|
||||
justify-content: center;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
border-top: 2px solid transparent;
|
||||
|
||||
&.active {
|
||||
border-top-color: $gab-brand-default;
|
||||
}
|
||||
|
||||
& > span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './footer_bar'
|
||||
@@ -45,6 +45,8 @@ export default class Icon extends PureComponent {
|
||||
return <I.GlobeIcon {...options} />
|
||||
case 'group':
|
||||
return <I.GroupIcon {...options} />
|
||||
case 'group-add':
|
||||
return <I.GroupAddIcon {...options} />
|
||||
case 'happy':
|
||||
return <I.HappyIcon {...options} />
|
||||
case 'home':
|
||||
@@ -55,6 +57,8 @@ export default class Icon extends PureComponent {
|
||||
return <I.LinkIcon {...options} />
|
||||
case 'list':
|
||||
return <I.ListIcon {...options} />
|
||||
case 'list-add':
|
||||
return <I.ListAddIcon {...options} />
|
||||
case 'loading':
|
||||
return <I.LoadingIcon {...options} />
|
||||
case 'media':
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import Block from './block'
|
||||
import ScrollableList from './scrollable_list'
|
||||
import ListItem from './list_item'
|
||||
|
||||
export default class List extends PureComponent {
|
||||
export default class List extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
items: PropTypes.array,
|
||||
@@ -21,16 +22,14 @@ export default class List extends PureComponent {
|
||||
emptyMessage={emptyMessage}
|
||||
>
|
||||
{
|
||||
items.map((item, i) => {
|
||||
return (
|
||||
<ListItem
|
||||
small={small}
|
||||
key={`list-item-${i}`}
|
||||
isLast={items.length - 1 === i}
|
||||
{...item}
|
||||
/>
|
||||
)
|
||||
})
|
||||
items.map((item, i) => (
|
||||
<ListItem
|
||||
small={small}
|
||||
key={`list-item-${i}`}
|
||||
isLast={items.size - 1 === i}
|
||||
{...item}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</ScrollableList>
|
||||
</Block>
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import Button from '../button'
|
||||
import Text from '../text'
|
||||
import ModalLayout from './modal_layout'
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'promo.gab_pro', defaultMessage: 'Upgrade to GabPRO' },
|
||||
text: { id: 'pro_upgrade_modal.text', defaultMessage: 'Gab is fully funded by people like you. Please consider supporting us on our mission to defend free expression online for all people.' },
|
||||
benefits: { id: 'pro_upgrade_modal.benefits', defaultMessage: 'Here are just some of the benefits that thousands of GabPRO members receive:' },
|
||||
})
|
||||
|
||||
export default
|
||||
@injectIntl
|
||||
class HomeTimelineSettingsModal extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl } = this.props
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Text>
|
||||
{intl.formatMessage(messages.text)}
|
||||
</Text>
|
||||
<Text>
|
||||
{intl.formatMessage(messages.benefits)}
|
||||
</Text>
|
||||
|
||||
<div className={[_s.default, _s.my10].join(' ')}>
|
||||
<Text>• Schedule Posts</Text>
|
||||
<Text>• Get Verified</Text>
|
||||
<Text>• Create Groups</Text>
|
||||
<Text>• Larger Video and Image Uploads</Text>
|
||||
<Text>• Receive the PRO Badge</Text>
|
||||
<Text>• Remove in-feed promotions</Text>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
centered
|
||||
backgroundColor='brand'
|
||||
color='white'
|
||||
icon='pro'
|
||||
href='https://pro.gab.com'
|
||||
className={_s.justifyContentCenter}
|
||||
iconClassName={[_s.mr5, _s.fillColorWhite].join(' ')}
|
||||
>
|
||||
<Text color='inherit' weight='bold' align='center'>
|
||||
{intl.formatMessage(messages.title)}
|
||||
</Text>
|
||||
</Button>
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { injectIntl, defineMessages } from 'react-intl'
|
||||
import { makeGetAccount } from '../../selectors'
|
||||
import { closeModal } from '../../actions/modal'
|
||||
import { blockAccount } from '../../actions/accounts'
|
||||
import ConfirmationModal from './confirmation_modal'
|
||||
|
||||
@@ -23,9 +22,6 @@ const mapDispatchToProps = dispatch => {
|
||||
onConfirm(account) {
|
||||
dispatch(blockAccount(account.get('id')))
|
||||
},
|
||||
onClose() {
|
||||
dispatch(closeModal())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +33,6 @@ class BlockAccountModal extends PureComponent {
|
||||
static propTypes = {
|
||||
account: PropTypes.object.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
@@ -45,10 +40,6 @@ class BlockAccountModal extends PureComponent {
|
||||
this.props.onConfirm(this.props.account)
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
this.props.onClose()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { account, intl } = this.props
|
||||
|
||||
@@ -64,7 +55,6 @@ class BlockAccountModal extends PureComponent {
|
||||
title={title}
|
||||
message={message}
|
||||
confirm={intl.formatMessage(messages.block)}
|
||||
onClose={this.handleClose}
|
||||
onConfirm={this.handleClick}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
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'
|
||||
import SettingSwitch from '../setting_switch'
|
||||
import Text from '../text'
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'community_timeline_settings', defaultMessage: 'Community Timeline Settings' },
|
||||
saveAndClose: { id: 'saveClose', defaultMessage: 'Save & Close' },
|
||||
onlyMedia: { id: 'community.column_settings.media_only', defaultMessage: 'Media Only' },
|
||||
showInSidebar: { id: 'show_in_sidebar', defaultMessage: 'Show in Sidebar' },
|
||||
})
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
settings: state.getIn(['settings', 'community']),
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
onChange(key, checked) {
|
||||
dispatch(changeSetting(['community', ...key], checked))
|
||||
},
|
||||
onSave() {
|
||||
dispatch(saveSettings())
|
||||
dispatch(closeModal())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps, mapDispatchToProps)
|
||||
@injectIntl
|
||||
class CommunityTimelineSettingsModal extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
settings: ImmutablePropTypes.map.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onSave: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
handleSaveAndClose = () => {
|
||||
this.props.onSave()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl, settings, onChange } = this.props
|
||||
|
||||
return (
|
||||
<ModalLayout
|
||||
width='320'
|
||||
title={intl.formatMessage(messages.title)}
|
||||
>
|
||||
|
||||
<div className={[_s.default, _s.pb10].join(' ')}>
|
||||
<SettingSwitch
|
||||
prefix='community_timeline'
|
||||
settings={settings}
|
||||
settingPath={['shows', 'inSidebar']}
|
||||
onChange={onChange}
|
||||
label={intl.formatMessage(messages.showInSidebar)}
|
||||
/>
|
||||
|
||||
<SettingSwitch
|
||||
prefix='community_timeline'
|
||||
settings={settings}
|
||||
settingPath={['shows', 'onlyMedia']}
|
||||
onChange={onChange}
|
||||
label={intl.formatMessage(messages.onlyMedia)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
centered
|
||||
backgroundColor='brand'
|
||||
color='white'
|
||||
className={_s.justifyContentCenter}
|
||||
onClick={this.handleSaveAndClose}
|
||||
>
|
||||
<Text color='inherit' weight='bold' align='center'>
|
||||
{intl.formatMessage(messages.saveAndClose)}
|
||||
</Text>
|
||||
</Button>
|
||||
|
||||
</ModalLayout>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
import { injectIntl, defineMessages } from 'react-intl'
|
||||
import { muteAccount } from '../../actions/accounts'
|
||||
|
||||
const messages = defineMessages({
|
||||
muteMessage: { id: 'confirmations.mute.message', defaultMessage: 'Are you sure you want to mute {name}?' },
|
||||
cancel: { id: 'confirmation_modal.cancel', defaultMessage: 'Cancel' },
|
||||
confirm: { id: 'confirmations.mute.confirm', defaultMessage: 'Mute' },
|
||||
})
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
isSubmitting: state.getIn(['reports', 'new', 'isSubmitting']),
|
||||
account: state.getIn(['mutes', 'new', 'account']),
|
||||
}
|
||||
}
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
onConfirm(account, notifications) {
|
||||
dispatch(muteAccount(account.get('id'), notifications))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps, mapDispatchToProps)
|
||||
@injectIntl
|
||||
class UnfollowModal extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
isSubmitting: PropTypes.bool.isRequired,
|
||||
account: PropTypes.object.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.button.focus()
|
||||
}
|
||||
|
||||
handleClick = () => {
|
||||
this.props.onClose()
|
||||
this.props.onConfirm(this.props.account, this.props.notifications)
|
||||
}
|
||||
|
||||
handleCancel = () => {
|
||||
this.props.onClose()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { account, intl } = this.props
|
||||
|
||||
// , {
|
||||
// message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
|
||||
// confirm: intl.formatMessage(messages.unfollowConfirm),
|
||||
// onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
|
||||
// }));
|
||||
|
||||
return (
|
||||
<ConfirmationModal
|
||||
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' />}
|
||||
onConfirm={() => {
|
||||
// dispatch(blockDomain(domain))
|
||||
// dispatch(blockDomain(domain))
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ModalLayout from './modal_layout'
|
||||
import GroupCreate from '../../features/group_create'
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'create_group', defaultMessage: 'Create Group' },
|
||||
})
|
||||
|
||||
export default
|
||||
@injectIntl
|
||||
class GroupCreateModal extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl } = this.props
|
||||
|
||||
return (
|
||||
<ModalLayout
|
||||
title={intl.formatMessage(messages.title)}
|
||||
width='440'
|
||||
>
|
||||
<GroupCreate />
|
||||
</ModalLayout>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { injectIntl, defineMessages } from 'react-intl'
|
||||
import { makeGetAccount } from '../../selectors'
|
||||
import { blockAccount } from '../../actions/accounts'
|
||||
import ConfirmationModal from './confirmation_modal'
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'group_delete_title', defaultMessage: 'Delete "{group}"' },
|
||||
groupMessage: { id: 'confirmations.group_delete.message', defaultMessage: 'Are you sure you want to delete "{group}"?' },
|
||||
delete: { id: 'delete', defaultMessage: 'Delete' },
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
onConfirm(account) {
|
||||
// dispatch(blockAccount(account.get('id')))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default
|
||||
@connect(null, mapDispatchToProps)
|
||||
@injectIntl
|
||||
class GroupDeleteModal extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
group: PropTypes.object.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
handleClick = () => {
|
||||
this.props.onConfirm(this.props.account)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { group, intl } = this.props
|
||||
|
||||
const title = intl.formatMessage(messages.title, {
|
||||
group: !!group ? account.get('title') : '',
|
||||
})
|
||||
const message = intl.formatMessage(messages.groupMessage, {
|
||||
group: !!group ? account.get('title') : '',
|
||||
})
|
||||
|
||||
return (
|
||||
<ConfirmationModal
|
||||
title={title}
|
||||
message={message}
|
||||
confirm={intl.formatMessage(messages.delete)}
|
||||
onConfirm={this.handleClick}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -59,7 +59,7 @@ class HomeTimelineSettingsModal extends ImmutablePureComponent {
|
||||
title={intl.formatMessage(messages.title)}
|
||||
>
|
||||
|
||||
<div className={[_s.default, _s.my10, _s.pb10].join(' ')}>
|
||||
<div className={[_s.default, _s.pb10].join(' ')}>
|
||||
<SettingSwitch
|
||||
prefix='home_timeline'
|
||||
settings={settings}
|
||||
|
||||
@@ -26,7 +26,6 @@ const messages = defineMessages({
|
||||
unfocus: { id: 'keyboard_shortcuts.unfocus', defaultMessage: 'un-focus compose textarea/search' },
|
||||
home: { id: 'keyboard_shortcuts.home', defaultMessage: 'open home timeline' },
|
||||
notifications: { id: 'keyboard_shortcuts.notifications', defaultMessage: 'open notifications column' },
|
||||
direct: { id: 'keyboard_shortcuts.direct', defaultMessage: 'open direct messages column' },
|
||||
start: { id: 'keyboard_shortcuts.start', defaultMessage: 'open "get started" column' },
|
||||
favorites: { id: 'keyboard_shortcuts.favorites', defaultMessage: 'open favorites list' },
|
||||
pinned: { id: 'keyboard_shortcuts.pinned', defaultMessage: 'open pinned gabs list' },
|
||||
@@ -93,7 +92,6 @@ class HotkeysModal extends ImmutablePureComponent {
|
||||
<HotKeysModalRow hotkey='esc' action={intl.formatMessage(messages.unfocus)} />
|
||||
<HotKeysModalRow hotkey='g + h' action={intl.formatMessage(messages.home)} />
|
||||
<HotKeysModalRow hotkey='g + n' action={intl.formatMessage(messages.notifications)} />
|
||||
<HotKeysModalRow hotkey='g + d' action={intl.formatMessage(messages.direct)} />
|
||||
</tbody>
|
||||
</table>
|
||||
<table>
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
import { injectIntl, defineMessages } from 'react-intl'
|
||||
import { muteAccount } from '../../actions/accounts'
|
||||
|
||||
const messages = defineMessages({
|
||||
muteMessage: { id: 'confirmations.mute.message', defaultMessage: 'Are you sure you want to mute {name}?' },
|
||||
cancel: { id: 'confirmation_modal.cancel', defaultMessage: 'Cancel' },
|
||||
confirm: { id: 'confirmations.mute.confirm', defaultMessage: 'Mute' },
|
||||
})
|
||||
|
||||
const mapStateToProps = state => {
|
||||
return {
|
||||
isSubmitting: state.getIn(['reports', 'new', 'isSubmitting']),
|
||||
account: state.getIn(['mutes', 'new', 'account']),
|
||||
}
|
||||
}
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
onConfirm(account, notifications) {
|
||||
dispatch(muteAccount(account.get('id'), notifications))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps, mapDispatchToProps)
|
||||
@injectIntl
|
||||
class UnfollowModal extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
isSubmitting: PropTypes.bool.isRequired,
|
||||
account: PropTypes.object.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.button.focus()
|
||||
}
|
||||
|
||||
handleClick = () => {
|
||||
this.props.onClose()
|
||||
this.props.onConfirm(this.props.account, this.props.notifications)
|
||||
}
|
||||
|
||||
handleCancel = () => {
|
||||
this.props.onClose()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { account, intl } = this.props
|
||||
|
||||
// , {
|
||||
// message: <FormattedMessage id='confirmations.unfollow.message' defaultMessage='Are you sure you want to unfollow {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />,
|
||||
// confirm: intl.formatMessage(messages.unfollowConfirm),
|
||||
// onConfirm: () => dispatch(unfollowAccount(account.get('id'))),
|
||||
// }));
|
||||
|
||||
return (
|
||||
<ConfirmationModal
|
||||
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' />}
|
||||
onConfirm={() => {
|
||||
// dispatch(blockDomain(domain))
|
||||
// dispatch(blockDomain(domain))
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ModalLayout from './modal_layout'
|
||||
import ListCreate from '../../features/list_create'
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'create_list', defaultMessage: 'Create List' },
|
||||
})
|
||||
|
||||
export default
|
||||
@injectIntl
|
||||
class ListCreateModal extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl } = this.props
|
||||
|
||||
return (
|
||||
<ModalLayout
|
||||
title={intl.formatMessage(messages.title)}
|
||||
width='500'
|
||||
>
|
||||
<ListCreate />
|
||||
</ModalLayout>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
import { injectIntl, defineMessages } from 'react-intl'
|
||||
import { makeGetAccount } from '../../selectors'
|
||||
import { blockAccount } from '../../actions/accounts'
|
||||
import ConfirmationModal from './confirmation_modal'
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'list_delete_title', defaultMessage: 'Delete "{list}"' },
|
||||
listMessage: { id: 'confirmations.list_delete.message', defaultMessage: 'Are you sure you want to delete "{list}"?' },
|
||||
delete: { id: 'delete', defaultMessage: 'Delete' },
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
onConfirm(account) {
|
||||
// dispatch(blockAccount(account.get('id')))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default
|
||||
@connect(null, mapDispatchToProps)
|
||||
@injectIntl
|
||||
class ListDeleteModal extends PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
list: PropTypes.object.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
handleClick = () => {
|
||||
this.props.onConfirm(this.props.account)
|
||||
}
|
||||
|
||||
render() {
|
||||
const { list, intl } = this.props
|
||||
|
||||
const title = intl.formatMessage(messages.title, {
|
||||
list: !!list ? account.get('title') : '',
|
||||
})
|
||||
const message = intl.formatMessage(messages.listMessage, {
|
||||
list: !!list ? account.get('title') : '',
|
||||
})
|
||||
|
||||
return (
|
||||
<ConfirmationModal
|
||||
title={title}
|
||||
message={message}
|
||||
confirm={intl.formatMessage(messages.delete)}
|
||||
onConfirm={this.handleClick}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
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'
|
||||
import SettingSwitch from '../setting_switch'
|
||||
import Text from '../text'
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'list_timeline_settings', defaultMessage: 'List Timeline Settings' },
|
||||
saveAndClose: { id: 'saveClose', defaultMessage: 'Save & Close' },
|
||||
showVideos: { id: 'home.column_settings.show_videos', defaultMessage: 'Show videos' },
|
||||
showPhotos: { id: 'home.column_settings.show_photos', defaultMessage: 'Show photos' },
|
||||
showPolls: { id: 'home.column_settings.show_polls', defaultMessage: 'Show polls' },
|
||||
showReposts: { id: 'home.column_settings.show_reposts', defaultMessage: 'Show comments' },
|
||||
showReplies: { id: 'home.column_settings.show_replies', defaultMessage: 'Show replies' },
|
||||
})
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
settings: state.getIn(['settings', 'list']),
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
onChange(key, checked) {
|
||||
dispatch(changeSetting(['list', ...key], checked))
|
||||
},
|
||||
onSave() {
|
||||
dispatch(saveSettings())
|
||||
dispatch(closeModal())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps, mapDispatchToProps)
|
||||
@injectIntl
|
||||
class ListTimelineSettingsModal extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
settings: ImmutablePropTypes.map.isRequired,
|
||||
onChange: PropTypes.func.isRequired,
|
||||
onSave: PropTypes.func.isRequired,
|
||||
}
|
||||
|
||||
handleSaveAndClose = () => {
|
||||
this.props.onSave()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl, settings, onChange } = this.props
|
||||
|
||||
return (
|
||||
<ModalLayout
|
||||
width='320'
|
||||
title={intl.formatMessage(messages.title)}
|
||||
>
|
||||
|
||||
<div className={[_s.default, _s.pb10].join(' ')}>
|
||||
<SettingSwitch
|
||||
prefix='list_timeline'
|
||||
settings={settings}
|
||||
settingPath={['shows', 'polls']}
|
||||
onChange={onChange}
|
||||
label={intl.formatMessage(messages.showPolls)}
|
||||
/>
|
||||
|
||||
<SettingSwitch
|
||||
prefix='list_timeline'
|
||||
settings={settings}
|
||||
settingPath={['shows', 'photos']}
|
||||
onChange={onChange}
|
||||
label={intl.formatMessage(messages.showPhotos)}
|
||||
/>
|
||||
|
||||
<SettingSwitch
|
||||
prefix='list_timeline'
|
||||
settings={settings}
|
||||
settingPath={['shows', 'videos']}
|
||||
onChange={onChange}
|
||||
label={intl.formatMessage(messages.showVideos)}
|
||||
/>
|
||||
|
||||
<SettingSwitch
|
||||
prefix='list_timeline'
|
||||
settings={settings}
|
||||
settingPath={['shows', 'repost']}
|
||||
onChange={onChange}
|
||||
label={intl.formatMessage(messages.showReposts)}
|
||||
/>
|
||||
|
||||
<SettingSwitch
|
||||
prefix='list_timeline'
|
||||
settings={settings}
|
||||
settingPath={['shows', 'reply']}
|
||||
onChange={onChange}
|
||||
label={intl.formatMessage(messages.showReplies)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<Button
|
||||
centered
|
||||
backgroundColor='brand'
|
||||
color='white'
|
||||
className={_s.justifyContentCenter}
|
||||
onClick={this.handleSaveAndClose}
|
||||
>
|
||||
<Text color='inherit' weight='bold' align='center'>
|
||||
{intl.formatMessage(messages.saveAndClose)}
|
||||
</Text>
|
||||
</Button>
|
||||
|
||||
</ModalLayout>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
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'
|
||||
@@ -10,13 +11,23 @@ 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 = {
|
||||
title: PropTypes.string,
|
||||
children: PropTypes.node,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
handleCloseModal: PropTypes.func.isRequired,
|
||||
width: PropTypes.number,
|
||||
hideClose: PropTypes.bool,
|
||||
noPadding: PropTypes.bool,
|
||||
@@ -26,12 +37,19 @@ class ModalLayout extends PureComponent {
|
||||
width: 600,
|
||||
}
|
||||
|
||||
onHandleCloseModal = () => {
|
||||
if (this.props.onClose) {
|
||||
this.props.onClose();
|
||||
} else {
|
||||
this.props.handleCloseModal()
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const {
|
||||
title,
|
||||
children,
|
||||
intl,
|
||||
onClose,
|
||||
width,
|
||||
hideClose,
|
||||
noPadding
|
||||
@@ -39,6 +57,8 @@ class ModalLayout extends PureComponent {
|
||||
|
||||
const childrenContainerClasses = cx({
|
||||
default: 1,
|
||||
heightMax80VH: 1,
|
||||
overflowScroll: 1,
|
||||
px15: !noPadding,
|
||||
py10: !noPadding,
|
||||
})
|
||||
@@ -56,7 +76,7 @@ class ModalLayout extends PureComponent {
|
||||
backgroundColor='none'
|
||||
title={intl.formatMessage(messages.close)}
|
||||
className={_s.marginLeftAuto}
|
||||
onClick={onClose}
|
||||
onClick={this.onHandleCloseModal}
|
||||
icon='close'
|
||||
iconWidth='10px'
|
||||
iconWidth='10px'
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
// ListEditor,
|
||||
// ListAdder,
|
||||
StatusRevisionModal,
|
||||
} from '../../features/ui/util/async-components'
|
||||
} from '../../features/ui/util/async_components'
|
||||
|
||||
import ModalBase from './modal_base'
|
||||
import BundleModalError from '../bundle_modal_error'
|
||||
@@ -17,14 +17,18 @@ import ActionsModal from './actions_modal'
|
||||
import BlockAccountModal from './block_account_modal'
|
||||
import BlockDomainModal from './block_domain_modal'
|
||||
import BoostModal from './boost_modal'
|
||||
import CommunityTimelineSettingsModal from './community_timeline_settings_modal'
|
||||
import ComposeModal from './compose_modal'
|
||||
import ConfirmationModal from './confirmation_modal'
|
||||
import GroupAdderModal from './group_adder_modal'
|
||||
import GroupCreateModal from './group_create_modal'
|
||||
import GroupDeleteModal from './group_delete_modal'
|
||||
import GroupEditorModal from './group_editor_modal'
|
||||
import HomeTimelineSettingsModal from './home_timeline_settings_modal'
|
||||
import HotkeysModal from './hotkeys_modal'
|
||||
import ListAdderModal from './list_adder_modal'
|
||||
import ListCreateModal from './list_create_modal'
|
||||
import ListDeleteModal from './list_delete_modal'
|
||||
import ListEditorModal from './list_editor_modal'
|
||||
import ListTimelineSettingsModal from './list_timeline_settings_modal'
|
||||
import MediaModal from './media_modal'
|
||||
import ModalLoading from './modal_loading'
|
||||
import ProUpgradeModal from './pro_upgrade_modal'
|
||||
@@ -37,15 +41,19 @@ const MODAL_COMPONENTS = {
|
||||
BLOCK_ACCOUNT: () => Promise.resolve({ default: BlockAccountModal }),
|
||||
BLOCK_DOMAIN: () => Promise.resolve({ default: BlockDomainModal }),
|
||||
BOOST: () => Promise.resolve({ default: BoostModal }),
|
||||
COMMUNITY_TIMELINE_SETTINGS: () => Promise.resolve({ default: CommunityTimelineSettingsModal }),
|
||||
COMPOSE: () => Promise.resolve({ default: ComposeModal }),
|
||||
CONFIRM: () => Promise.resolve({ default: ConfirmationModal }),
|
||||
EMBED: () => Promise.resolve({ default: EmbedModal }),
|
||||
GROUP_CREATE: () => Promise.resolve({ default: GroupCreateModal }),
|
||||
GROUP_DELETE: () => Promise.resolve({ default: GroupDeleteModal }),
|
||||
GROUP_EDITOR: () => Promise.resolve({ default: GroupEditorModal }),
|
||||
GROUP_ADDER: () => Promise.resolve({ default: GroupAdderModal }),
|
||||
HOME_TIMELINE_SETTINGS: () => Promise.resolve({ default: HomeTimelineSettingsModal }),
|
||||
HOTKEYS: () => Promise.resolve({ default: HotkeysModal }),
|
||||
LIST_CREATE: () => Promise.resolve({ default: ListCreateModal }),
|
||||
LIST_DELETE: () => Promise.resolve({ default: ListDeleteModal }),
|
||||
LIST_EDITOR: () => Promise.resolve({ default: ListEditorModal }),
|
||||
LIST_ADDER: () => Promise.resolve({ default: ListAdderModal }),
|
||||
LIST_TIMELINE_SETTINGS: () => Promise.resolve({ default: ListTimelineSettingsModal }),
|
||||
MEDIA: () => Promise.resolve({ default: MediaModal }),
|
||||
'MUTE': MuteModal,
|
||||
PRO_UPGRADE: () => Promise.resolve({ default: ProUpgradeModal }),
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { injectIntl, defineMessages } from 'react-intl'
|
||||
import { makeGetAccount } from '../../selectors'
|
||||
import { closeModal } from '../../actions/modal'
|
||||
import { muteAccount } from '../../actions/accounts'
|
||||
import ConfirmationModal from './confirmation_modal'
|
||||
|
||||
@@ -21,12 +20,8 @@ const mapStateToProps = (state, { accountId }) => {
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
onConfirm(account, notifications) {
|
||||
dispatch(closeModal())
|
||||
dispatch(muteAccount(account.get('id'), notifications))
|
||||
},
|
||||
onClose() {
|
||||
dispatch(closeModal())
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,7 +33,6 @@ class MuteModal extends PureComponent {
|
||||
static propTypes = {
|
||||
account: PropTypes.object.isRequired,
|
||||
onConfirm: PropTypes.func.isRequired,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
@@ -46,10 +40,6 @@ class MuteModal extends PureComponent {
|
||||
this.props.onConfirm(this.props.account)
|
||||
}
|
||||
|
||||
handleClose = () => {
|
||||
this.props.onClose()
|
||||
}
|
||||
|
||||
render() {
|
||||
const { account, intl } = this.props
|
||||
|
||||
@@ -65,7 +55,6 @@ class MuteModal extends PureComponent {
|
||||
title={title}
|
||||
message={message}
|
||||
confirm={intl.formatMessage(messages.mute)}
|
||||
onClose={this.handleClose}
|
||||
onConfirm={this.handleClick}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -22,7 +22,7 @@ class ProUpgradeModal extends ImmutablePureComponent {
|
||||
const { intl } = this.props
|
||||
|
||||
return (
|
||||
<ModalLayout title={intl.formatMessage(messages.title)}>
|
||||
<ModalLayout title={intl.formatMessage(messages.title)} width='460'>
|
||||
<Text>
|
||||
{intl.formatMessage(messages.text)}
|
||||
</Text>
|
||||
|
||||
@@ -1,24 +1,31 @@
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
import { fetchSuggestions, dismissSuggestion } from '../../actions/suggestions';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import PanelLayout from './panel_layout';
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import { fetchSuggestions, dismissSuggestion } from '../../actions/suggestions'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import PanelLayout from './panel_layout'
|
||||
import Avatar from '../avatar'
|
||||
import Divider from '../divider'
|
||||
import Icon from '../icon'
|
||||
import Heading from '../heading'
|
||||
import Text from '../text'
|
||||
|
||||
const messages = defineMessages({
|
||||
dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
|
||||
title: { id: 'lists.panel_title', defaultMessage: 'On This List ({count})' },
|
||||
show_all: { id: 'groups.sidebar-panel.show_all', defaultMessage: 'Show all' },
|
||||
});
|
||||
memberCount: { id: 'lists.panel_members', defaultMessage: 'Members: {count}' },
|
||||
createdAt: { id: 'lists.panel_created', defaultMessage: 'Created: {date}' },
|
||||
title: { id: 'lists_information', defaultMessage: 'List Information' },
|
||||
edit: { id: 'edit', defaultMessage: 'Edit' },
|
||||
})
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
// accountIds: state.getIn(['listEditor', 'accounts', 'items']),
|
||||
});
|
||||
})
|
||||
|
||||
const mapDispatchToProps = dispatch => {
|
||||
return {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export default
|
||||
@connect(mapStateToProps, mapDispatchToProps)
|
||||
@@ -27,27 +34,77 @@ class ListDetailsPanel extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
};
|
||||
}
|
||||
|
||||
handleShowAllLists() {
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl } = this.props;
|
||||
|
||||
const count = 10
|
||||
const { intl } = this.props
|
||||
|
||||
return (
|
||||
<PanelLayout
|
||||
title={intl.formatMessage(messages.title, { count })}
|
||||
headerButtonTitle={intl.formatMessage(messages.show_all)}
|
||||
title={intl.formatMessage(messages.title)}
|
||||
headerButtonTitle={intl.formatMessage(messages.edit)}
|
||||
headerButtonAction={this.handleShowAllLists}
|
||||
>
|
||||
<div className={_s.default}>
|
||||
|
||||
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter,].join(' ')}>
|
||||
<Text weight='medium'>
|
||||
Some List Title
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Divider small />
|
||||
|
||||
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter].join(' ')}>
|
||||
<Icon id='calendar' width='12px' height='12px' className={_s.fillColorSecondary} />
|
||||
<Text
|
||||
size='small'
|
||||
color='secondary'
|
||||
className={_s.ml5}
|
||||
>
|
||||
{
|
||||
intl.formatMessage(messages.createdAt, {
|
||||
date: '12-25-2019'
|
||||
})
|
||||
}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<Divider small />
|
||||
|
||||
<div className={[_s.default].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow, _s.alignItemsCenter].join(' ')}>
|
||||
<Icon id='group' width='12px' height='12px' className={_s.fillColorSecondary} />
|
||||
<Text
|
||||
size='small'
|
||||
color='secondary'
|
||||
className={_s.ml5}
|
||||
>
|
||||
{
|
||||
intl.formatMessage(messages.memberCount, {
|
||||
count: 10
|
||||
})
|
||||
}
|
||||
</Text>
|
||||
</div>
|
||||
<div className={[_s.default, _s.flexRow, _s.flexWrap, _s.pt10].join(' ')}>
|
||||
|
||||
{
|
||||
[1, 2, 3, 4, 5, 6, 7, 8, 9].map(item => (
|
||||
<div className={[_s.default, _s.mr5].join(' ')}>
|
||||
<Avatar size='26' />
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</PanelLayout>
|
||||
);
|
||||
};
|
||||
};
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,9 @@ class PopoverBase extends ImmutablePureComponent {
|
||||
displayNone: !visible,
|
||||
})
|
||||
|
||||
console.log("targetRef:", targetRef)
|
||||
|
||||
|
||||
return (
|
||||
<Manager>
|
||||
<Popper
|
||||
|
||||
@@ -10,8 +10,9 @@ import ProfileOptionsPopover from './profile_options_popover'
|
||||
import SearchPopover from './search_popover'
|
||||
import SidebarMorePopover from './sidebar_more_popover'
|
||||
import StatusOptionsPopover from './status_options_popover'
|
||||
import UserInfoPopover from './user_info_popover'
|
||||
import StatusSharePopover from './status_share_popover'
|
||||
import StatusVisibilityPopover from './status_visibility_popover'
|
||||
import UserInfoPopover from './user_info_popover'
|
||||
|
||||
const listenerOptions = detectPassiveEvents.hasSupport ? { passive: true } : false
|
||||
|
||||
@@ -23,6 +24,7 @@ const POPOVER_COMPONENTS = {
|
||||
SEARCH: () => Promise.resolve({ default: SearchPopover }),
|
||||
SIDEBAR_MORE: () => Promise.resolve({ default: SidebarMorePopover }),
|
||||
STATUS_OPTIONS: () => Promise.resolve({ default: StatusOptionsPopover }),
|
||||
STATUS_SHARE: () => Promise.resolve({ default: StatusSharePopover }),
|
||||
STATUS_VISIBILITY: () => Promise.resolve({ default: StatusVisibilityPopover }),
|
||||
USER_INFO: () => Promise.resolve({ default: UserInfoPopover }),
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import {
|
||||
followAccount,
|
||||
unfollowAccount,
|
||||
|
||||
@@ -1,43 +1,84 @@
|
||||
import PopoverLayout from './popover_layout'
|
||||
import List from '../list'
|
||||
|
||||
export default class StatusOptionsPopover extends PureComponent {
|
||||
render() {
|
||||
_makeMenu = (publicStatus) => {
|
||||
// const { status, intl: { formatMessage }, withDismiss, withGroupAdmin } = this.props
|
||||
// const mutingConversation = status.get('muted')
|
||||
|
||||
let menu = [];
|
||||
|
||||
// menu.push({ text: formatMessage(messages.open), action: this.handleOpen });
|
||||
|
||||
// if (publicStatus) {
|
||||
// menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy });
|
||||
// menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed });
|
||||
// menu.push({ text: formatMessage(messages.copy), action: this.handleCopy });
|
||||
// menu.push({ text: formatMessage(messages.embed), action: this.handleEmbed });
|
||||
// }
|
||||
|
||||
// if (!me) return menu
|
||||
|
||||
// menu.push(null);
|
||||
|
||||
// if (status.getIn(['account', 'id']) === me || withDismiss) {
|
||||
// menu.push({ text: formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
||||
// menu.push(null);
|
||||
// }
|
||||
|
||||
// if (me === status.getIn(['account', 'id'])) {
|
||||
// if (status.getIn(['account', 'id']) === me) {
|
||||
// if (publicStatus) {
|
||||
// menu.push({ text: intl.formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
|
||||
// menu.push({ text: formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
|
||||
// } else {
|
||||
// if (status.get('visibility') === 'private') {
|
||||
// menu.push({ text: intl.formatMessage(status.get('reblogged') ? messages.cancel_repost_private : messages.repost_private), action: this.handleRepostClick });
|
||||
// menu.push({ text: formatMessage(status.get('reblogged') ? messages.cancel_repost_private : messages.repost_private), action: this.handleRepostClick });
|
||||
// }
|
||||
// }
|
||||
|
||||
// menu.push(null);
|
||||
// menu.push({ text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
||||
// menu.push(null);
|
||||
// menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick });
|
||||
// menu.push({ text: intl.formatMessage(messages.edit), action: this.handleEditClick });
|
||||
// menu.push({ text: formatMessage(messages.delete), action: this.handleDeleteClick });
|
||||
// menu.push({ text: formatMessage(messages.edit), action: this.handleEditClick });
|
||||
// } else {
|
||||
// menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick });
|
||||
// menu.push({ text: formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick });
|
||||
// menu.push(null);
|
||||
// menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
|
||||
// menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
|
||||
// menu.push({ text: intl.formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
|
||||
// menu.push({ text: formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
|
||||
// menu.push({ text: formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
|
||||
// menu.push({ text: formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
|
||||
|
||||
// if (isStaff) {
|
||||
// menu.push(null);
|
||||
// menu.push({ text: intl.formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
|
||||
// menu.push({ text: intl.formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
|
||||
// menu.push({ text: formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
|
||||
// menu.push({ text: formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
|
||||
// }
|
||||
|
||||
// if (withGroupAdmin) {
|
||||
// menu.push(null);
|
||||
// menu.push({ text: formatMessage(messages.group_remove_account), action: this.handleGroupRemoveAccount });
|
||||
// menu.push({ text: formatMessage(messages.group_remove_post), action: this.handleGroupRemovePost });
|
||||
// }
|
||||
// }
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{ /* */ }
|
||||
</div>
|
||||
<PopoverLayout className={_s.width240PX}>
|
||||
<List
|
||||
scrollKey='profile_options'
|
||||
items={[
|
||||
{
|
||||
title: 'Help',
|
||||
href: 'https://help.gab.com',
|
||||
},
|
||||
{
|
||||
title: 'Settings',
|
||||
href: '/settings',
|
||||
},
|
||||
{
|
||||
title: 'Log Out',
|
||||
href: '/auth/log_out',
|
||||
},
|
||||
]}
|
||||
small
|
||||
/>
|
||||
</PopoverLayout>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import PopoverLayout from './popover_layout'
|
||||
import List from '../list'
|
||||
|
||||
const messages = defineMessages({
|
||||
embed: { id: 'status.embed', defaultMessage: 'Embed gab' },
|
||||
email: { id: 'status.email', defaultMessage: 'Email gab' },
|
||||
copy: { id: 'status.copy', defaultMessage: 'Copy link to gab' },
|
||||
});
|
||||
|
||||
// const makeMapStateToProps = () => {
|
||||
// const getAccount = makeGetAccount();
|
||||
|
||||
// const mapStateToProps = (state, { account }) => ({
|
||||
|
||||
// });
|
||||
|
||||
// return mapStateToProps;
|
||||
// };
|
||||
|
||||
// const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||
|
||||
// });
|
||||
|
||||
export default
|
||||
@injectIntl
|
||||
// @connect(makeMapStateToProps, mapDispatchToProps)
|
||||
class StatusSharePopover extends ImmutablePureComponent {
|
||||
static propTypes = {
|
||||
status: ImmutablePropTypes.map,
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
handleEmbed = () => {
|
||||
// this.props.onEmbed(this.props.status);
|
||||
}
|
||||
|
||||
handleCopy = () => {
|
||||
// const url = this.props.status.get('url');
|
||||
// const textarea = document.createElement('textarea');
|
||||
|
||||
// textarea.textContent = url;
|
||||
// textarea.style.position = 'fixed';
|
||||
|
||||
// document.body.appendChild(textarea);
|
||||
|
||||
// try {
|
||||
// textarea.select();
|
||||
// document.execCommand('copy');
|
||||
// } catch (e) {
|
||||
// //
|
||||
// } finally {
|
||||
// document.body.removeChild(textarea);
|
||||
// }
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl } = this.props
|
||||
|
||||
return (
|
||||
<PopoverLayout className={_s.width250PX}>
|
||||
<List
|
||||
scrollKey='status_share_options'
|
||||
items={[
|
||||
{
|
||||
icon: 'copy',
|
||||
hideArrow: true,
|
||||
title: intl.formatMessage(messages.copy),
|
||||
onClick: this.handleCopy,
|
||||
},
|
||||
{
|
||||
icon: 'envelope',
|
||||
hideArrow: true,
|
||||
title: intl.formatMessage(messages.email),
|
||||
href: 'mailto:',
|
||||
},
|
||||
{
|
||||
icon: 'embed',
|
||||
hideArrow: true,
|
||||
title: intl.formatMessage(messages.embed),
|
||||
onClick: this.handleEmbed,
|
||||
},
|
||||
]}
|
||||
small
|
||||
/>
|
||||
</PopoverLayout>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,7 @@ const mapStateToProps = state => {
|
||||
sidebarOpen: state.get('sidebar').sidebarOpen,
|
||||
notificationCount: state.getIn(['notifications', 'unread']),
|
||||
homeItemsQueueCount: state.getIn(['timelines', 'home', 'totalQueuedItemsCount']),
|
||||
showCommunityTimeline: state.getIn(['settings', 'community', 'shows', 'inSidebar']),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +65,7 @@ class Sidebar extends ImmutablePureComponent {
|
||||
intl: PropTypes.object.isRequired,
|
||||
account: ImmutablePropTypes.map,
|
||||
sidebarOpen: PropTypes.bool,
|
||||
showCommunityTimeline: PropTypes.bool,
|
||||
onClose: PropTypes.func.isRequired,
|
||||
onOpenComposeModal: PropTypes.func.isRequired,
|
||||
openSidebarMorePopover: PropTypes.func.isRequired,
|
||||
@@ -115,7 +117,14 @@ class Sidebar extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { sidebarOpen, intl, account, notificationCount, homeItemsQueueCount } = this.props
|
||||
const {
|
||||
sidebarOpen,
|
||||
intl,
|
||||
account,
|
||||
notificationCount,
|
||||
homeItemsQueueCount,
|
||||
showCommunityTimeline
|
||||
} = this.props
|
||||
const { moreOpen } = this.state
|
||||
|
||||
// : todo :
|
||||
@@ -127,6 +136,8 @@ class Sidebar extends ImmutablePureComponent {
|
||||
const moreIcon = moreOpen ? 'minus' : 'plus'
|
||||
const moreContainerStyle = { display: moreOpen ? 'block' : 'none' }
|
||||
|
||||
console.log("showCommunityTimeline:", showCommunityTimeline)
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
title: 'Home',
|
||||
@@ -134,18 +145,24 @@ class Sidebar extends ImmutablePureComponent {
|
||||
to: '/',
|
||||
count: homeItemsQueueCount,
|
||||
},
|
||||
{
|
||||
title: 'Community',
|
||||
icon: 'community',
|
||||
to: '/timeline/all',
|
||||
hidden: !showCommunityTimeline,
|
||||
},
|
||||
{
|
||||
title: 'Notifications',
|
||||
icon: 'notifications',
|
||||
to: '/notifications',
|
||||
count: notificationCount,
|
||||
},
|
||||
// : todo : show only when search on top is not visible
|
||||
// {
|
||||
// title: 'Search',
|
||||
// icon: 'search-alt',
|
||||
// to: '/search',
|
||||
// },
|
||||
{
|
||||
title: 'Search',
|
||||
icon: 'search-alt',
|
||||
to: '/search',
|
||||
hidden: true, // : todo : show only when search on top is not visible
|
||||
},
|
||||
{
|
||||
title: 'Groups',
|
||||
icon: 'group',
|
||||
@@ -169,11 +186,6 @@ class Sidebar extends ImmutablePureComponent {
|
||||
},
|
||||
]
|
||||
|
||||
// more modal:
|
||||
// settings/preferences
|
||||
// help
|
||||
// logout
|
||||
|
||||
const shortcutItems = [
|
||||
{
|
||||
title: 'Meme Group',
|
||||
@@ -223,9 +235,13 @@ class Sidebar extends ImmutablePureComponent {
|
||||
<nav aria-label='Primary' role='navigation' className={[_s.default, _s.width100PC, _s.mb15].join(' ')}>
|
||||
<SidebarSectionTitle>Menu</SidebarSectionTitle>
|
||||
{
|
||||
menuItems.map((menuItem, i) => (
|
||||
<SidebarSectionItem {...menuItem} key={`sidebar-item-menu-${i}`} />
|
||||
))
|
||||
menuItems.map((menuItem, i) => {
|
||||
if (menuItem.hidden) return null
|
||||
|
||||
return (
|
||||
<SidebarSectionItem {...menuItem} key={`sidebar-item-menu-${i}`} />
|
||||
)
|
||||
})
|
||||
}
|
||||
<SidebarSectionTitle>Shortcuts</SidebarSectionTitle>
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@ import { HotKeys } from 'react-hotkeys';
|
||||
import classNames from 'classnames/bind'
|
||||
import { displayMedia } from '../../initial_state';
|
||||
import Card from '../../features/status/components/card';
|
||||
import { MediaGallery, Video } from '../../features/ui/util/async-components';
|
||||
import { MediaGallery, Video } from '../../features/ui/util/async_components';
|
||||
import ComposeFormContainer from '../../features/compose/containers/compose_form_container'
|
||||
import Avatar from '../avatar';
|
||||
import StatusQuote from '../status_quote';
|
||||
@@ -81,7 +81,6 @@ class Status extends ImmutablePureComponent {
|
||||
onRepost: PropTypes.func,
|
||||
onDelete: PropTypes.func,
|
||||
onEdit: PropTypes.func,
|
||||
onDirect: PropTypes.func,
|
||||
onMention: PropTypes.func,
|
||||
onPin: PropTypes.func,
|
||||
onOpenMedia: PropTypes.func,
|
||||
|
||||
@@ -3,14 +3,14 @@ import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { defineMessages, injectIntl } from 'react-intl'
|
||||
import classNames from 'classnames/bind'
|
||||
import { openModal } from '../actions/modal'
|
||||
import { me, isStaff } from '../initial_state'
|
||||
import { openPopover } from '../actions/popover'
|
||||
import { me } from '../initial_state'
|
||||
import Text from './text'
|
||||
import StatusActionBarItem from './status_action_bar_item'
|
||||
|
||||
const messages = defineMessages({
|
||||
delete: { id: 'status.delete', defaultMessage: 'Delete' },
|
||||
edit: { id: 'status.edit', defaultMessage: 'Edit' },
|
||||
direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' },
|
||||
mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' },
|
||||
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
|
||||
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
|
||||
@@ -44,6 +44,14 @@ const mapDispatchToProps = (dispatch) => ({
|
||||
onOpenUnauthorizedModal() {
|
||||
dispatch(openModal('UNAUTHORIZED'))
|
||||
},
|
||||
onOpenStatusSharePopover(targetRef, status) {
|
||||
console.log("targetRef, status:", targetRef, status)
|
||||
dispatch(openPopover('STATUS_SHARE', {
|
||||
status,
|
||||
targetRef,
|
||||
position: 'top',
|
||||
}))
|
||||
},
|
||||
})
|
||||
|
||||
const cx = classNames.bind(_s)
|
||||
@@ -60,6 +68,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
static propTypes = {
|
||||
status: ImmutablePropTypes.map.isRequired,
|
||||
onOpenUnauthorizedModal: PropTypes.func.isRequired,
|
||||
onOpenStatusSharePopover: PropTypes.func.isRequired,
|
||||
onReply: PropTypes.func,
|
||||
onQuote: PropTypes.func,
|
||||
onFavorite: PropTypes.func,
|
||||
@@ -117,7 +126,12 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
}
|
||||
|
||||
handleShareClick = () => {
|
||||
//
|
||||
console.log("handleShareClick:", this.shareButton, this.props.status)
|
||||
this.props.onOpenStatusSharePopover(this.shareButton, this.props.status)
|
||||
}
|
||||
|
||||
setShareButton = (n) => {
|
||||
this.shareButton = n
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -222,6 +236,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||
onClick={this.handleRepostClick}
|
||||
/>
|
||||
<StatusActionBarItem
|
||||
buttonRef={this.setShareButton}
|
||||
title={formatMessage(messages.share)}
|
||||
icon='share'
|
||||
onClick={this.handleShareClick}
|
||||
|
||||
@@ -10,10 +10,18 @@ export default class StatusActionBarItem extends PureComponent {
|
||||
icon: PropTypes.string.isRequired,
|
||||
active: PropTypes.bool,
|
||||
disabled: PropTypes.bool,
|
||||
buttonRef: PropTypes.node,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { title, onClick, icon, active, disabled } = this.props
|
||||
const {
|
||||
title,
|
||||
onClick,
|
||||
icon,
|
||||
active,
|
||||
disabled,
|
||||
buttonRef
|
||||
} = this.props
|
||||
|
||||
const btnClasses = cx({
|
||||
default: 1,
|
||||
@@ -38,6 +46,7 @@ export default class StatusActionBarItem extends PureComponent {
|
||||
return (
|
||||
<div className={[_s.default, _s.flexGrow1, _s.px10].join(' ')}>
|
||||
<button
|
||||
ref={buttonRef}
|
||||
className={btnClasses}
|
||||
onClick={onClick}
|
||||
active={active}
|
||||
|
||||
@@ -3,7 +3,7 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
import { Set as ImmutableSet } from 'immutable';
|
||||
import noop from 'lodash/noop';
|
||||
import { toggleStatusReport } from '../actions/reports';
|
||||
import { MediaGallery, Video } from '../features/ui/util/async-components';
|
||||
import { MediaGallery, Video } from '../features/ui/util/async_components';
|
||||
import Bundle from '../features/ui/util/bundle';
|
||||
import StatusContent from './status_content';
|
||||
import Switch from './switch';
|
||||
|
||||
@@ -159,6 +159,8 @@ class StatusContent extends ImmutablePureComponent {
|
||||
const { status, intl, isComment } = this.props
|
||||
const { collapsed } = this.state
|
||||
|
||||
console.log("status content", status.get('content'))
|
||||
|
||||
if (status.get('content').length === 0) return null;
|
||||
|
||||
const hidden = this.props.onExpandedToggle ? !this.props.expanded : this.state.hidden;
|
||||
|
||||
@@ -2,6 +2,8 @@ import { Fragment } from 'react'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component'
|
||||
import { openPopover } from '../actions/popover'
|
||||
import { openModal } from '../actions/modal'
|
||||
import RelativeTimestamp from './relative_timestamp'
|
||||
import DisplayName from './display_name'
|
||||
import Text from './text'
|
||||
@@ -10,18 +12,30 @@ import Icon from './icon'
|
||||
import Button from './button'
|
||||
import Avatar from './avatar'
|
||||
|
||||
export default class StatusHeader extends ImmutablePureComponent {
|
||||
export default
|
||||
@connect(null, null)
|
||||
class StatusHeader extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
status: ImmutablePropTypes.map,
|
||||
}
|
||||
|
||||
handleStatusOptionsClick() {
|
||||
console.log("handleStatusOptionsClick")
|
||||
console.log("handleStatusOptionsClick:", this.props)
|
||||
this.props.dispatch(openPopover('STATUS_OPTIONS', {
|
||||
targetRef: this.statusOptionsButton,
|
||||
position: 'top',
|
||||
status: this.props.status,
|
||||
}))
|
||||
}
|
||||
|
||||
handleOpenStatusEdits() {
|
||||
console.log("handleOpenStatusEdits")
|
||||
// : todo :
|
||||
this.props.dispatch(openPopover('REPOST', {
|
||||
targetRef: this.statusOptionsButton,
|
||||
position: 'top',
|
||||
status: this.props.status,
|
||||
}))
|
||||
}
|
||||
|
||||
handleDeleteClick = () => {
|
||||
@@ -95,59 +109,8 @@ export default class StatusHeader extends ImmutablePureComponent {
|
||||
this.props.onGroupRemoveStatus(status.getIn(['group', 'id']), status.get('id'));
|
||||
}
|
||||
|
||||
_makeMenu = (publicStatus) => {
|
||||
const { status, intl: { formatMessage }, withDismiss, withGroupAdmin } = this.props;
|
||||
const mutingConversation = status.get('muted');
|
||||
|
||||
let menu = [];
|
||||
|
||||
menu.push({ text: formatMessage(messages.open), action: this.handleOpen });
|
||||
|
||||
if (publicStatus) {
|
||||
menu.push({ text: formatMessage(messages.copy), action: this.handleCopy });
|
||||
menu.push({ text: formatMessage(messages.embed), action: this.handleEmbed });
|
||||
}
|
||||
|
||||
if (!me) return menu
|
||||
|
||||
menu.push(null);
|
||||
|
||||
if (status.getIn(['account', 'id']) === me || withDismiss) {
|
||||
menu.push({ text: formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation), action: this.handleConversationMuteClick });
|
||||
menu.push(null);
|
||||
}
|
||||
|
||||
if (status.getIn(['account', 'id']) === me) {
|
||||
if (publicStatus) {
|
||||
menu.push({ text: formatMessage(status.get('pinned') ? messages.unpin : messages.pin), action: this.handlePinClick });
|
||||
} else {
|
||||
if (status.get('visibility') === 'private') {
|
||||
menu.push({ text: formatMessage(status.get('reblogged') ? messages.cancel_repost_private : messages.repost_private), action: this.handleRepostClick });
|
||||
}
|
||||
}
|
||||
menu.push({ text: formatMessage(messages.delete), action: this.handleDeleteClick });
|
||||
menu.push({ text: formatMessage(messages.edit), action: this.handleEditClick });
|
||||
} else {
|
||||
menu.push({ text: formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick });
|
||||
menu.push(null);
|
||||
menu.push({ text: formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick });
|
||||
menu.push({ text: formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick });
|
||||
menu.push({ text: formatMessage(messages.report, { name: status.getIn(['account', 'username']) }), action: this.handleReport });
|
||||
|
||||
if (isStaff) {
|
||||
menu.push(null);
|
||||
menu.push({ text: formatMessage(messages.admin_account, { name: status.getIn(['account', 'username']) }), href: `/admin/accounts/${status.getIn(['account', 'id'])}` });
|
||||
menu.push({ text: formatMessage(messages.admin_status), href: `/admin/accounts/${status.getIn(['account', 'id'])}/statuses/${status.get('id')}` });
|
||||
}
|
||||
|
||||
if (withGroupAdmin) {
|
||||
menu.push(null);
|
||||
menu.push({ text: formatMessage(messages.group_remove_account), action: this.handleGroupRemoveAccount });
|
||||
menu.push({ text: formatMessage(messages.group_remove_post), action: this.handleGroupRemovePost });
|
||||
}
|
||||
}
|
||||
|
||||
return menu;
|
||||
setStatusOptionsButton = n => {
|
||||
this.statusOptionsButton = n
|
||||
}
|
||||
|
||||
render() {
|
||||
@@ -155,18 +118,6 @@ export default class StatusHeader extends ImmutablePureComponent {
|
||||
|
||||
const statusUrl = `/${status.getIn(['account', 'acct'])}/posts/${status.get('id')}`;
|
||||
|
||||
// const menu = this._makeMenu(publicStatus);
|
||||
// <div className='status-action-bar__dropdown'>
|
||||
// <DropdownMenuContainer
|
||||
// status={status}
|
||||
// items={menu}
|
||||
// icon='ellipsis-h'
|
||||
// size={18}
|
||||
// direction='right'
|
||||
// title={formatMessage(messages.more)}
|
||||
// />
|
||||
// </div>
|
||||
|
||||
return (
|
||||
<div className={[_s.default, _s.px15, _s.py10].join(' ')}>
|
||||
<div className={[_s.default, _s.flexRow, _s.mt5].join(' ')}>
|
||||
@@ -200,6 +151,7 @@ export default class StatusHeader extends ImmutablePureComponent {
|
||||
iconClassName={_s.fillColorSecondary}
|
||||
className={_s.marginLeftAuto}
|
||||
onClick={this.handleStatusOptionsClick}
|
||||
buttonRef={this.setStatusOptionsButton}
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||
|
||||
let scrollableContent = (isLoading || statusIds.size > 0) ? (
|
||||
statusIds.map((statusId, index) => statusId === null ? (
|
||||
<LoadGap
|
||||
<div
|
||||
key={'gap:' + statusIds.get(index + 1)}
|
||||
disabled={isLoading}
|
||||
maxId={index > 0 ? statusIds.get(index - 1) : null}
|
||||
|
||||
Reference in New Issue
Block a user