diff options
author | Starfall <root@starfall.blue> | 2019-12-09 19:07:33 -0600 |
---|---|---|
committer | Starfall <root@starfall.blue> | 2019-12-09 19:09:31 -0600 |
commit | 6b34fcfef7566105e8d80ab5fee0a539c06cddbf (patch) | |
tree | 8fad2d47bf8be255d3c671c40cbfd04c2f55ed03 /app/javascript/flavours/glitch/containers | |
parent | 9fbb4af7611aa7836e65ef9f544d341423c15685 (diff) | |
parent | 246addd5b33a172600342af3fb6fb5e4c80ad95e (diff) |
Merge branch 'glitch'`
Diffstat (limited to 'app/javascript/flavours/glitch/containers')
4 files changed, 82 insertions, 27 deletions
diff --git a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js index b2419a0fd..1378e75fe 100644 --- a/app/javascript/flavours/glitch/containers/dropdown_menu_container.js +++ b/app/javascript/flavours/glitch/containers/dropdown_menu_container.js @@ -25,7 +25,7 @@ const mapDispatchToProps = (dispatch, { status, items }) => ({ }) : openDropdownMenu(id, dropdownPlacement, keyboard)); }, onClose(id) { - dispatch(closeModal()); + dispatch(closeModal('ACTIONS')); dispatch(closeDropdownMenu(id)); }, }); diff --git a/app/javascript/flavours/glitch/containers/mastodon.js b/app/javascript/flavours/glitch/containers/mastodon.js index 59eef6636..8101be87e 100644 --- a/app/javascript/flavours/glitch/containers/mastodon.js +++ b/app/javascript/flavours/glitch/containers/mastodon.js @@ -49,6 +49,10 @@ export default class Mastodon extends React.PureComponent { } } + shouldUpdateScroll (_, { location }) { + return !(location.state && location.state.mastodonModalOpen); + } + render () { const { locale } = this.props; @@ -57,7 +61,7 @@ export default class Mastodon extends React.PureComponent { <Provider store={store}> <ErrorBoundary> <BrowserRouter basename='/web'> - <ScrollContext> + <ScrollContext shouldUpdateScroll={this.shouldUpdateScroll}> <Route path='/' component={UI} /> </ScrollContext> </BrowserRouter> diff --git a/app/javascript/flavours/glitch/containers/media_container.js b/app/javascript/flavours/glitch/containers/media_container.js index 1b480658f..a483510b0 100644 --- a/app/javascript/flavours/glitch/containers/media_container.js +++ b/app/javascript/flavours/glitch/containers/media_container.js @@ -2,19 +2,22 @@ import React, { PureComponent, Fragment } from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import { IntlProvider, addLocaleData } from 'react-intl'; +import { List as ImmutableList, fromJS } from 'immutable'; import { getLocale } from 'mastodon/locales'; +import { getScrollbarWidth } from 'flavours/glitch/util/scrollbar'; import MediaGallery from 'flavours/glitch/components/media_gallery'; -import Video from 'flavours/glitch/features/video'; -import Card from 'flavours/glitch/features/status/components/card'; import Poll from 'flavours/glitch/components/poll'; +import Hashtag from 'flavours/glitch/components/hashtag'; import ModalRoot from 'flavours/glitch/components/modal_root'; import MediaModal from 'flavours/glitch/features/ui/components/media_modal'; -import { List as ImmutableList, fromJS } from 'immutable'; +import Video from 'flavours/glitch/features/video'; +import Card from 'flavours/glitch/features/status/components/card'; +import Audio from 'flavours/glitch/features/audio'; const { localeData, messages } = getLocale(); addLocaleData(localeData); -const MEDIA_COMPONENTS = { MediaGallery, Video, Card, Poll }; +const MEDIA_COMPONENTS = { MediaGallery, Video, Card, Poll, Hashtag, Audio }; export default class MediaContainer extends PureComponent { @@ -31,6 +34,8 @@ export default class MediaContainer extends PureComponent { handleOpenMedia = (media, index) => { document.body.classList.add('with-modals--active'); + document.documentElement.style.marginRight = `${getScrollbarWidth()}px`; + this.setState({ media, index }); } @@ -38,11 +43,15 @@ export default class MediaContainer extends PureComponent { const media = ImmutableList([video]); document.body.classList.add('with-modals--active'); + document.documentElement.style.marginRight = `${getScrollbarWidth()}px`; + this.setState({ media, time }); } handleCloseMedia = () => { document.body.classList.remove('with-modals--active'); + document.documentElement.style.marginRight = 0; + this.setState({ media: null, index: null, time: null }); } @@ -55,12 +64,13 @@ export default class MediaContainer extends PureComponent { {[].map.call(components, (component, i) => { const componentName = component.getAttribute('data-component'); const Component = MEDIA_COMPONENTS[componentName]; - const { media, card, poll, ...props } = JSON.parse(component.getAttribute('data-props')); + const { media, card, poll, hashtag, ...props } = JSON.parse(component.getAttribute('data-props')); Object.assign(props, { - ...(media ? { media: fromJS(media) } : {}), - ...(card ? { card: fromJS(card) } : {}), - ...(poll ? { poll: fromJS(poll) } : {}), + ...(media ? { media: fromJS(media) } : {}), + ...(card ? { card: fromJS(card) } : {}), + ...(poll ? { poll: fromJS(poll) } : {}), + ...(hashtag ? { hashtag: fromJS(hashtag) } : {}), ...(componentName === 'Video' ? { onOpenVideo: this.handleOpenVideo, @@ -74,6 +84,7 @@ export default class MediaContainer extends PureComponent { component, ); })} + <ModalRoot onClose={this.handleCloseMedia}> {this.state.media && ( <MediaModal diff --git a/app/javascript/flavours/glitch/containers/status_container.js b/app/javascript/flavours/glitch/containers/status_container.js index a6069cb90..4c3555dea 100644 --- a/app/javascript/flavours/glitch/containers/status_container.js +++ b/app/javascript/flavours/glitch/containers/status_container.js @@ -1,7 +1,7 @@ -import React from 'react'; import { connect } from 'react-redux'; import Status from 'flavours/glitch/components/status'; -import { makeGetStatus } from 'flavours/glitch/selectors'; +import { List as ImmutableList } from 'immutable'; +import { makeGetStatus, regexFromFilters, toServerSideType } from 'flavours/glitch/selectors'; import { replyCompose, mentionCompose, @@ -17,25 +17,31 @@ import { pin, unpin, } from 'flavours/glitch/actions/interactions'; -import { blockAccount } from 'flavours/glitch/actions/accounts'; import { muteStatus, unmuteStatus, deleteStatus } from 'flavours/glitch/actions/statuses'; import { initMuteModal } from 'flavours/glitch/actions/mutes'; +import { initBlockModal } from 'flavours/glitch/actions/blocks'; import { initReport } from 'flavours/glitch/actions/reports'; import { openModal } from 'flavours/glitch/actions/modal'; import { changeLocalSetting } from 'flavours/glitch/actions/local_settings'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import { boostModal, favouriteModal, deleteModal } from 'flavours/glitch/util/initial_state'; +import { filterEditLink } from 'flavours/glitch/util/backend_links'; import { showAlertForError } from '../actions/alerts'; +import AccountContainer from 'flavours/glitch/containers/account_container'; +import Spoilers from '../components/spoilers'; +import Icon from 'flavours/glitch/components/icon'; const messages = defineMessages({ deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' }, deleteMessage: { id: 'confirmations.delete.message', defaultMessage: 'Are you sure you want to delete this status?' }, redraftConfirm: { id: 'confirmations.redraft.confirm', defaultMessage: 'Delete & redraft' }, redraftMessage: { id: 'confirmations.redraft.message', defaultMessage: 'Are you sure you want to delete this status and re-draft it? You will lose all replies, boosts and favourites to it.' }, - blockConfirm: { id: 'confirmations.block.confirm', defaultMessage: 'Block' }, replyConfirm: { id: 'confirmations.reply.confirm', defaultMessage: 'Reply' }, replyMessage: { id: 'confirmations.reply.message', defaultMessage: 'Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?' }, - blockAndReport: { id: 'confirmations.block.block_and_report', defaultMessage: 'Block & Report' }, + unfilterConfirm: { id: 'confirmations.unfilter.confirm', defaultMessage: 'Show' }, + author: { id: 'confirmations.unfilter.author', defaultMessage: 'Author' }, + matchingFilters: { id: 'confirmations.unfilter.filters', defaultMessage: 'Matching {count, plural, one {filter} other {filters}}' }, + editFilter: { id: 'confirmations.unfilter.edit_filter', defaultMessage: 'Edit filter' }, }); const makeMapStateToProps = () => { @@ -69,11 +75,12 @@ const makeMapStateToProps = () => { return mapStateToProps; }; -const mapDispatchToProps = (dispatch, { intl }) => ({ +const mapDispatchToProps = (dispatch, { intl, contextType }) => ({ onReply (status, router) { dispatch((_, getState) => { let state = getState(); + if (state.getIn(['local_settings', 'confirm_before_clearing_draft']) && state.getIn(['compose', 'text']).trim().length !== 0) { dispatch(openModal('CONFIRM', { message: intl.formatMessage(messages.replyMessage), @@ -99,7 +106,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ dispatch((_, getState) => { let state = getState(); if (state.getIn(['local_settings', 'confirm_boost_missing_media_description']) && status.get('media_attachments').some(item => !item.get('description')) && !status.get('reblogged')) { - dispatch(openModal('BOOST', { status, onReblog: this.handleModalReblog, missingMediaDescription: true })); + dispatch(openModal('BOOST', { status, onReblog: this.onModalReblog, missingMediaDescription: true })); } else if (e.shiftKey || !boostModal) { this.onModalReblog(status); } else { @@ -177,16 +184,49 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ onBlock (status) { const account = status.get('account'); - dispatch(openModal('CONFIRM', { - message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong>@{account.get('acct')}</strong> }} />, - confirm: intl.formatMessage(messages.blockConfirm), - onConfirm: () => dispatch(blockAccount(account.get('id'))), - secondary: intl.formatMessage(messages.blockAndReport), - onSecondary: () => { - dispatch(blockAccount(account.get('id'))); - dispatch(initReport(account, status)); - }, - })); + dispatch(initBlockModal(account)); + }, + + onUnfilter (status, onConfirm) { + dispatch((_, getState) => { + let state = getState(); + const serverSideType = toServerSideType(contextType); + const enabledFilters = state.get('filters', ImmutableList()).filter(filter => filter.get('context').includes(serverSideType) && (filter.get('expires_at') === null || Date.parse(filter.get('expires_at')) > (new Date()))).toArray(); + const searchIndex = status.get('search_index'); + const matchingFilters = enabledFilters.filter(filter => regexFromFilters([filter]).test(searchIndex)); + dispatch(openModal('CONFIRM', { + message: [ + <FormattedMessage id='confirmations.unfilter' defaultMessage='Information about this filtered toot' />, + <div className='filtered-status-info'> + <Spoilers spoilerText={intl.formatMessage(messages.author)}> + <AccountContainer id={status.getIn(['account', 'id'])} /> + </Spoilers> + <Spoilers spoilerText={intl.formatMessage(messages.matchingFilters, {count: matchingFilters.size})}> + <ul> + {matchingFilters.map(filter => ( + <li> + {filter.get('phrase')} + {!!filterEditLink && ' '} + {!!filterEditLink && ( + <a + target='_blank' + className='filtered-status-edit-link' + title={intl.formatMessage(messages.editFilter)} + href={filterEditLink(filter.get('id'))} + > + <Icon icon='pencil' /> + </a> + )} + </li> + ))} + </ul> + </Spoilers> + </div> + ], + confirm: intl.formatMessage(messages.unfilterConfirm), + onConfirm: onConfirm, + })); + }); }, onReport (status) { |