Use upstream's settings for CW auto-expand and column swiping (#1770)
* Use Mastodon server-side settings for automatically expanding toots with CWs * Add modal warning about settings changes * Use Mastodon server-side settings for disabling swiping
This commit is contained in:
		
							parent
							
								
									205f6b815c
								
							
						
					
					
						commit
						e6af69d56b
					
				
					 20 changed files with 396 additions and 24 deletions
				
			
		| 
						 | 
				
			
			@ -1,7 +1,6 @@
 | 
			
		|||
import escapeTextContentForBrowser from 'escape-html';
 | 
			
		||||
import emojify from 'flavours/glitch/util/emoji';
 | 
			
		||||
import { unescapeHTML } from 'flavours/glitch/util/html';
 | 
			
		||||
import { expandSpoilers } from 'flavours/glitch/util/initial_state';
 | 
			
		||||
 | 
			
		||||
const domParser = new DOMParser();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,46 @@
 | 
			
		|||
import { expandSpoilers, disableSwiping } from 'flavours/glitch/util/initial_state';
 | 
			
		||||
import { openModal } from './modal';
 | 
			
		||||
 | 
			
		||||
export const LOCAL_SETTING_CHANGE = 'LOCAL_SETTING_CHANGE';
 | 
			
		||||
export const LOCAL_SETTING_DELETE = 'LOCAL_SETTING_DELETE';
 | 
			
		||||
 | 
			
		||||
export function checkDeprecatedLocalSettings() {
 | 
			
		||||
  return (dispatch, getState) => {
 | 
			
		||||
    const local_auto_unfold = getState().getIn(['local_settings', 'content_warnings', 'auto_unfold']);
 | 
			
		||||
    const local_swipe_to_change_columns = getState().getIn(['local_settings', 'swipe_to_change_columns']);
 | 
			
		||||
    let changed_settings = [];
 | 
			
		||||
 | 
			
		||||
    if (local_auto_unfold !== null && local_auto_unfold !== undefined) {
 | 
			
		||||
      if (local_auto_unfold === expandSpoilers) {
 | 
			
		||||
        dispatch(deleteLocalSetting(['content_warnings', 'auto_unfold']));
 | 
			
		||||
      } else {
 | 
			
		||||
        changed_settings.push('user_setting_expand_spoilers');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (local_swipe_to_change_columns !== null && local_swipe_to_change_columns !== undefined) {
 | 
			
		||||
      if (local_swipe_to_change_columns === !disableSwiping) {
 | 
			
		||||
        dispatch(deleteLocalSetting(['swipe_to_change_columns']));
 | 
			
		||||
      } else {
 | 
			
		||||
        changed_settings.push('user_setting_disable_swiping');
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (changed_settings.length > 0) {
 | 
			
		||||
      dispatch(openModal('DEPRECATED_SETTINGS', {
 | 
			
		||||
        settings: changed_settings,
 | 
			
		||||
        onConfirm: () => dispatch(clearDeprecatedLocalSettings()),
 | 
			
		||||
      }));
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function clearDeprecatedLocalSettings() {
 | 
			
		||||
  return (dispatch) => {
 | 
			
		||||
    dispatch(deleteLocalSetting(['content_warnings', 'auto_unfold']));
 | 
			
		||||
    dispatch(deleteLocalSetting(['swipe_to_change_columns']));
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function changeLocalSetting(key, value) {
 | 
			
		||||
  return dispatch => {
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +54,17 @@ export function changeLocalSetting(key, value) {
 | 
			
		|||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function deleteLocalSetting(key) {
 | 
			
		||||
  return dispatch => {
 | 
			
		||||
    dispatch({
 | 
			
		||||
      type: LOCAL_SETTING_DELETE,
 | 
			
		||||
      key,
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    dispatch(saveLocalSettings());
 | 
			
		||||
  };
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
//  __TODO :__
 | 
			
		||||
//  Right now `saveLocalSettings()` doesn't keep track of which user
 | 
			
		||||
//  is currently signed in, but it might be better to give each user
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,6 +55,10 @@ export default class ModalRoot extends React.PureComponent {
 | 
			
		|||
    window.addEventListener('keyup', this.handleKeyUp, false);
 | 
			
		||||
    window.addEventListener('keydown', this.handleKeyDown, false);
 | 
			
		||||
    this.history = this.context.router ? this.context.router.history : createBrowserHistory();
 | 
			
		||||
 | 
			
		||||
    if (this.props.children) {
 | 
			
		||||
      this._handleModalOpen();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  componentWillReceiveProps (nextProps) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,7 @@ import UI from 'flavours/glitch/features/ui';
 | 
			
		|||
import { fetchCustomEmojis } from 'flavours/glitch/actions/custom_emojis';
 | 
			
		||||
import { hydrateStore } from 'flavours/glitch/actions/store';
 | 
			
		||||
import { connectUserStream } from 'flavours/glitch/actions/streaming';
 | 
			
		||||
import { checkDeprecatedLocalSettings } from 'flavours/glitch/actions/local_settings';
 | 
			
		||||
import { IntlProvider, addLocaleData } from 'react-intl';
 | 
			
		||||
import { getLocale } from 'locales';
 | 
			
		||||
import initialState from 'flavours/glitch/util/initial_state';
 | 
			
		||||
| 
						 | 
				
			
			@ -20,6 +21,9 @@ export const store = configureStore();
 | 
			
		|||
const hydrateAction = hydrateStore(initialState);
 | 
			
		||||
store.dispatch(hydrateAction);
 | 
			
		||||
 | 
			
		||||
// check for deprecated local settings
 | 
			
		||||
store.dispatch(checkDeprecatedLocalSettings());
 | 
			
		||||
 | 
			
		||||
// load custom emojis
 | 
			
		||||
store.dispatch(fetchCustomEmojis());
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
 | 
			
		|||
import IconButton from 'flavours/glitch/components/icon_button';
 | 
			
		||||
import Icon from 'flavours/glitch/components/icon';
 | 
			
		||||
import { defineMessages, injectIntl, FormattedMessage, FormattedDate } from 'react-intl';
 | 
			
		||||
import { autoPlayGif, reduceMotion } from 'flavours/glitch/util/initial_state';
 | 
			
		||||
import { autoPlayGif, reduceMotion, disableSwiping } from 'flavours/glitch/util/initial_state';
 | 
			
		||||
import elephantUIPlane from 'mastodon/../images/elephant_ui_plane.svg';
 | 
			
		||||
import { mascot } from 'flavours/glitch/util/initial_state';
 | 
			
		||||
import unicodeMapping from 'flavours/glitch/util/emoji/emoji_unicode_mapping_light';
 | 
			
		||||
| 
						 | 
				
			
			@ -430,6 +430,7 @@ class Announcements extends ImmutablePureComponent {
 | 
			
		|||
                removeReaction={this.props.removeReaction}
 | 
			
		||||
                intl={intl}
 | 
			
		||||
                selected={index === idx}
 | 
			
		||||
                disabled={disableSwiping}
 | 
			
		||||
              />
 | 
			
		||||
            ))}
 | 
			
		||||
          </ReactSwipeableViews>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,83 @@
 | 
			
		|||
//  Package imports
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
 | 
			
		||||
//  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 | 
			
		||||
 | 
			
		||||
export default class LocalSettingsPageItem extends React.PureComponent {
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    children: PropTypes.node.isRequired,
 | 
			
		||||
    id: PropTypes.string.isRequired,
 | 
			
		||||
    options: PropTypes.arrayOf(PropTypes.shape({
 | 
			
		||||
      value: PropTypes.string.isRequired,
 | 
			
		||||
      message: PropTypes.string.isRequired,
 | 
			
		||||
      hint: PropTypes.string,
 | 
			
		||||
    })),
 | 
			
		||||
    value: PropTypes.any,
 | 
			
		||||
    placeholder: PropTypes.string,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    const { id, options, children, placeholder, value } = this.props;
 | 
			
		||||
 | 
			
		||||
    if (options && options.length > 0) {
 | 
			
		||||
      const currentValue = value;
 | 
			
		||||
      const optionElems = options && options.length > 0 && options.map((opt) => {
 | 
			
		||||
        let optionId = `${id}--${opt.value}`;
 | 
			
		||||
        return (
 | 
			
		||||
          <label htmlFor={optionId}>
 | 
			
		||||
            <input
 | 
			
		||||
              type='radio'
 | 
			
		||||
              name={id}
 | 
			
		||||
              id={optionId}
 | 
			
		||||
              value={opt.value}
 | 
			
		||||
              checked={currentValue === opt.value}
 | 
			
		||||
              disabled
 | 
			
		||||
            />
 | 
			
		||||
            {opt.message}
 | 
			
		||||
            {opt.hint && <span className='hint'>{opt.hint}</span>}
 | 
			
		||||
          </label>
 | 
			
		||||
        );
 | 
			
		||||
      });
 | 
			
		||||
      return (
 | 
			
		||||
        <div className='glitch local-settings__page__item radio_buttons'>
 | 
			
		||||
          <fieldset>
 | 
			
		||||
            <legend>{children}</legend>
 | 
			
		||||
            {optionElems}
 | 
			
		||||
          </fieldset>
 | 
			
		||||
        </div>
 | 
			
		||||
      );
 | 
			
		||||
    } else if (placeholder) {
 | 
			
		||||
      return (
 | 
			
		||||
        <div className='glitch local-settings__page__item string'>
 | 
			
		||||
          <label htmlFor={id}>
 | 
			
		||||
            <p>{children}</p>
 | 
			
		||||
            <p>
 | 
			
		||||
              <input
 | 
			
		||||
                id={id}
 | 
			
		||||
                type='text'
 | 
			
		||||
                value={value}
 | 
			
		||||
                placeholder={placeholder}
 | 
			
		||||
                disabled
 | 
			
		||||
              />
 | 
			
		||||
            </p>
 | 
			
		||||
          </label>
 | 
			
		||||
        </div>
 | 
			
		||||
      );
 | 
			
		||||
    } else return (
 | 
			
		||||
      <div className='glitch local-settings__page__item boolean'>
 | 
			
		||||
        <label htmlFor={id}>
 | 
			
		||||
          <input
 | 
			
		||||
            id={id}
 | 
			
		||||
            type='checkbox'
 | 
			
		||||
            checked={value}
 | 
			
		||||
            disabled
 | 
			
		||||
          />
 | 
			
		||||
          {children}
 | 
			
		||||
        </label>
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5,7 +5,10 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
 | 
			
		|||
import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
 | 
			
		||||
 | 
			
		||||
//  Our imports
 | 
			
		||||
import { expandSpoilers, disableSwiping } from 'flavours/glitch/util/initial_state';
 | 
			
		||||
import { preferenceLink } from 'flavours/glitch/util/backend_links';
 | 
			
		||||
import LocalSettingsPageItem from './item';
 | 
			
		||||
import DeprecatedLocalSettingsPageItem from './deprecated_item';
 | 
			
		||||
 | 
			
		||||
//  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -146,14 +149,28 @@ class LocalSettingsPage extends React.PureComponent {
 | 
			
		|||
          >
 | 
			
		||||
            <FormattedMessage id='settings.navbar_under' defaultMessage='Navbar at the bottom (Mobile only)' />
 | 
			
		||||
          </LocalSettingsPageItem>
 | 
			
		||||
          <LocalSettingsPageItem
 | 
			
		||||
            settings={settings}
 | 
			
		||||
            item={['swipe_to_change_columns']}
 | 
			
		||||
          <DeprecatedLocalSettingsPageItem
 | 
			
		||||
            id='mastodon-settings--swipe_to_change_columns'
 | 
			
		||||
            onChange={onChange}
 | 
			
		||||
            value={!disableSwiping}
 | 
			
		||||
          >
 | 
			
		||||
            <FormattedMessage id='settings.swipe_to_change_columns' defaultMessage='Allow swiping to change columns (Mobile only)' />
 | 
			
		||||
          </LocalSettingsPageItem>
 | 
			
		||||
            <span className='hint'>
 | 
			
		||||
              <FormattedMessage
 | 
			
		||||
                id='settings.deprecated_setting'
 | 
			
		||||
                defaultMessage="This setting is now controlled from Mastodon's {settings_page_link}"
 | 
			
		||||
                values={{
 | 
			
		||||
                  settings_page_link: (
 | 
			
		||||
                    <a href={preferenceLink('user_setting_disable_swiping')}>
 | 
			
		||||
                      <FormattedMessage
 | 
			
		||||
                        id='settings.shared_settings_link'
 | 
			
		||||
                        defaultMessage='user preferences'
 | 
			
		||||
                      />
 | 
			
		||||
                    </a>
 | 
			
		||||
                  )
 | 
			
		||||
                }}
 | 
			
		||||
              />
 | 
			
		||||
            </span>
 | 
			
		||||
          </DeprecatedLocalSettingsPageItem>
 | 
			
		||||
        </section>
 | 
			
		||||
      </div>
 | 
			
		||||
    ),
 | 
			
		||||
| 
						 | 
				
			
			@ -242,21 +259,35 @@ class LocalSettingsPage extends React.PureComponent {
 | 
			
		|||
    ({ intl, onChange, settings }) => (
 | 
			
		||||
      <div className='glitch local-settings__page content_warnings'>
 | 
			
		||||
        <h1><FormattedMessage id='settings.content_warnings' defaultMessage='Content warnings' /></h1>
 | 
			
		||||
        <LocalSettingsPageItem
 | 
			
		||||
          settings={settings}
 | 
			
		||||
          item={['content_warnings', 'auto_unfold']}
 | 
			
		||||
        <DeprecatedLocalSettingsPageItem
 | 
			
		||||
          id='mastodon-settings--content_warnings-auto_unfold'
 | 
			
		||||
          onChange={onChange}
 | 
			
		||||
          value={expandSpoilers}
 | 
			
		||||
        >
 | 
			
		||||
          <FormattedMessage id='settings.enable_content_warnings_auto_unfold' defaultMessage='Automatically unfold content-warnings' />
 | 
			
		||||
        </LocalSettingsPageItem>
 | 
			
		||||
          <span className='hint'>
 | 
			
		||||
            <FormattedMessage
 | 
			
		||||
              id='settings.deprecated_setting'
 | 
			
		||||
              defaultMessage="This setting is now controlled from Mastodon's {settings_page_link}"
 | 
			
		||||
              values={{
 | 
			
		||||
                settings_page_link: (
 | 
			
		||||
                  <a href={preferenceLink('user_setting_expand_spoilers')}>
 | 
			
		||||
                    <FormattedMessage
 | 
			
		||||
                      id='settings.shared_settings_link'
 | 
			
		||||
                      defaultMessage='user preferences'
 | 
			
		||||
                    />
 | 
			
		||||
                  </a>
 | 
			
		||||
                )
 | 
			
		||||
              }}
 | 
			
		||||
            />
 | 
			
		||||
          </span>
 | 
			
		||||
        </DeprecatedLocalSettingsPageItem>
 | 
			
		||||
        <LocalSettingsPageItem
 | 
			
		||||
          settings={settings}
 | 
			
		||||
          item={['content_warnings', 'filter']}
 | 
			
		||||
          id='mastodon-settings--content_warnings-auto_unfold'
 | 
			
		||||
          onChange={onChange}
 | 
			
		||||
          dependsOn={[['content_warnings', 'auto_unfold']]}
 | 
			
		||||
          placeholder={intl.formatMessage(messages.regexp)}
 | 
			
		||||
          disabled={!expandSpoilers}
 | 
			
		||||
        >
 | 
			
		||||
          <FormattedMessage id='settings.content_warnings_filter' defaultMessage='Content warnings to not automatically unfold:' />
 | 
			
		||||
        </LocalSettingsPageItem>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,6 +21,7 @@ export default class LocalSettingsPageItem extends React.PureComponent {
 | 
			
		|||
    })),
 | 
			
		||||
    settings: ImmutablePropTypes.map.isRequired,
 | 
			
		||||
    placeholder: PropTypes.string,
 | 
			
		||||
    disabled: PropTypes.bool,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  handleChange = e => {
 | 
			
		||||
| 
						 | 
				
			
			@ -33,8 +34,8 @@ export default class LocalSettingsPageItem extends React.PureComponent {
 | 
			
		|||
 | 
			
		||||
  render () {
 | 
			
		||||
    const { handleChange } = this;
 | 
			
		||||
    const { settings, item, id, options, children, dependsOn, dependsOnNot, placeholder } = this.props;
 | 
			
		||||
    let enabled = true;
 | 
			
		||||
    const { settings, item, id, options, children, dependsOn, dependsOnNot, placeholder, disabled } = this.props;
 | 
			
		||||
    let enabled = !disabled;
 | 
			
		||||
 | 
			
		||||
    if (dependsOn) {
 | 
			
		||||
      for (let i = 0; i < dependsOn.length; i++) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,6 +8,8 @@ import ReactSwipeableViews from 'react-swipeable-views';
 | 
			
		|||
import TabsBar, { links, getIndex, getLink } from './tabs_bar';
 | 
			
		||||
import { Link } from 'react-router-dom';
 | 
			
		||||
 | 
			
		||||
import { disableSwiping } from 'flavours/glitch/util/initial_state';
 | 
			
		||||
 | 
			
		||||
import BundleContainer from '../containers/bundle_container';
 | 
			
		||||
import ColumnLoading from './column_loading';
 | 
			
		||||
import DrawerLoading from './drawer_loading';
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +65,6 @@ class ColumnsArea extends ImmutablePureComponent {
 | 
			
		|||
  static propTypes = {
 | 
			
		||||
    intl: PropTypes.object.isRequired,
 | 
			
		||||
    columns: ImmutablePropTypes.list.isRequired,
 | 
			
		||||
    swipeToChangeColumns: PropTypes.bool,
 | 
			
		||||
    singleColumn: PropTypes.bool,
 | 
			
		||||
    children: PropTypes.node,
 | 
			
		||||
    navbarUnder: PropTypes.bool,
 | 
			
		||||
| 
						 | 
				
			
			@ -210,7 +211,7 @@ class ColumnsArea extends ImmutablePureComponent {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    const { columns, children, singleColumn, swipeToChangeColumns, intl, navbarUnder, openSettings } = this.props;
 | 
			
		||||
    const { columns, children, singleColumn, intl, navbarUnder, openSettings } = this.props;
 | 
			
		||||
    const { shouldAnimate, renderComposePanel } = this.state;
 | 
			
		||||
 | 
			
		||||
    const columnIndex = getIndex(this.context.router.history.location.pathname);
 | 
			
		||||
| 
						 | 
				
			
			@ -219,7 +220,7 @@ class ColumnsArea extends ImmutablePureComponent {
 | 
			
		|||
      const floatingActionButton = shouldHideFAB(this.context.router.history.location.pathname) ? null : <Link key='floating-action-button' to='/publish' className='floating-action-button' aria-label={intl.formatMessage(messages.publish)}><Icon id='pencil' /></Link>;
 | 
			
		||||
 | 
			
		||||
      const content = columnIndex !== -1 ? (
 | 
			
		||||
        <ReactSwipeableViews key='content' hysteresis={0.2} threshold={15} index={columnIndex} onChangeIndex={this.handleSwipe} onTransitionEnd={this.handleAnimationEnd} animateTransitions={shouldAnimate} springConfig={{ duration: '400ms', delay: '0s', easeFunction: 'ease' }} style={{ height: '100%' }} disabled={!swipeToChangeColumns}>
 | 
			
		||||
        <ReactSwipeableViews key='content' hysteresis={0.2} threshold={15} index={columnIndex} onChangeIndex={this.handleSwipe} onTransitionEnd={this.handleAnimationEnd} animateTransitions={shouldAnimate} springConfig={{ duration: '400ms', delay: '0s', easeFunction: 'ease' }} style={{ height: '100%' }} disabled={disableSwiping}>
 | 
			
		||||
          {links.map(this.renderView)}
 | 
			
		||||
        </ReactSwipeableViews>
 | 
			
		||||
      ) : (
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
import React from 'react';
 | 
			
		||||
import PropTypes from 'prop-types';
 | 
			
		||||
import ImmutablePropTypes from 'react-immutable-proptypes';
 | 
			
		||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 | 
			
		||||
import { preferenceLink } from 'flavours/glitch/util/backend_links';
 | 
			
		||||
import Button from 'flavours/glitch/components/button';
 | 
			
		||||
import Icon from 'flavours/glitch/components/icon';
 | 
			
		||||
import illustration from 'flavours/glitch/images/logo_warn_glitch.svg';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  discardChanges: { id: 'confirmations.deprecated_settings.confirm', defaultMessage: 'Use Mastodon preferences' },
 | 
			
		||||
  user_setting_expand_spoilers: { id: 'settings.enable_content_warnings_auto_unfold', defaultMessage: 'Automatically unfold content-warnings' },
 | 
			
		||||
  user_setting_disable_swiping: { id: 'settings.swipe_to_change_columns', defaultMessage: 'Allow swiping to change columns (Mobile only)' },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default @injectIntl
 | 
			
		||||
class DeprecatedSettingsModal extends React.PureComponent {
 | 
			
		||||
 | 
			
		||||
  static propTypes = {
 | 
			
		||||
    settings: ImmutablePropTypes.list.isRequired,
 | 
			
		||||
    onClose: PropTypes.func.isRequired,
 | 
			
		||||
    onConfirm: PropTypes.func.isRequired,
 | 
			
		||||
    intl: PropTypes.object.isRequired,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  componentDidMount() {
 | 
			
		||||
    this.button.focus();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  handleClick = () => {
 | 
			
		||||
    this.props.onConfirm();
 | 
			
		||||
    this.props.onClose();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  setRef = (c) => {
 | 
			
		||||
    this.button = c;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  render () {
 | 
			
		||||
    const { settings, intl } = this.props;
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
      <div className='modal-root__modal confirmation-modal'>
 | 
			
		||||
        <div className='confirmation-modal__container'>
 | 
			
		||||
 | 
			
		||||
          <img src={illustration} className='modal-warning' alt='' />
 | 
			
		||||
 | 
			
		||||
          <FormattedMessage
 | 
			
		||||
            id='confirmations.deprecated_settings.message'
 | 
			
		||||
            defaultMessage='Some of the glitch-soc device-specific {app_settings} you are using have been replaced by Mastodon {preferences} and will be overriden:'
 | 
			
		||||
            values={{
 | 
			
		||||
              app_settings: (
 | 
			
		||||
                <strong className='deprecated-settings-label'>
 | 
			
		||||
                  <Icon id='cogs' /> <FormattedMessage id='navigation_bar.app_settings' defaultMessage='App settings' />
 | 
			
		||||
                </strong>
 | 
			
		||||
              ),
 | 
			
		||||
              preferences: (
 | 
			
		||||
                <strong className='deprecated-settings-label'>
 | 
			
		||||
                  <Icon id='cog' /> <FormattedMessage id='navigation_bar.preferences' defaultMessage='Preferences' />
 | 
			
		||||
                </strong>
 | 
			
		||||
              ),
 | 
			
		||||
            }}
 | 
			
		||||
          />
 | 
			
		||||
 | 
			
		||||
          <div className='deprecated-settings-info'>
 | 
			
		||||
            <ul>
 | 
			
		||||
              { settings.map((setting_name) => (
 | 
			
		||||
                <li>
 | 
			
		||||
                  <a href={preferenceLink(setting_name)}><FormattedMessage {...messages[setting_name]} /></a>
 | 
			
		||||
                </li>
 | 
			
		||||
              )) }
 | 
			
		||||
            </ul>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div>
 | 
			
		||||
          <div className='confirmation-modal__action-bar'>
 | 
			
		||||
            <div />
 | 
			
		||||
            <Button text={intl.formatMessage(messages.discardChanges)} onClick={this.handleClick} ref={this.setRef} />
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -12,6 +12,7 @@ import Icon from 'flavours/glitch/components/icon';
 | 
			
		|||
import GIFV from 'flavours/glitch/components/gifv';
 | 
			
		||||
import Footer from 'flavours/glitch/features/picture_in_picture/components/footer';
 | 
			
		||||
import { getAverageFromBlurhash } from 'flavours/glitch/blurhash';
 | 
			
		||||
import { disableSwiping } from 'flavours/glitch/util/initial_state';
 | 
			
		||||
 | 
			
		||||
const messages = defineMessages({
 | 
			
		||||
  close: { id: 'lightbox.close', defaultMessage: 'Close' },
 | 
			
		||||
| 
						 | 
				
			
			@ -227,6 +228,7 @@ class MediaModal extends ImmutablePureComponent {
 | 
			
		|||
            onChangeIndex={this.handleSwipe}
 | 
			
		||||
            onTransitionEnd={this.handleTransitionEnd}
 | 
			
		||||
            index={index}
 | 
			
		||||
            disabled={disableSwiping}
 | 
			
		||||
          >
 | 
			
		||||
            {content}
 | 
			
		||||
          </ReactSwipeableViews>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ import AudioModal from './audio_modal';
 | 
			
		|||
import DoodleModal from './doodle_modal';
 | 
			
		||||
import ConfirmationModal from './confirmation_modal';
 | 
			
		||||
import FocalPointModal from './focal_point_modal';
 | 
			
		||||
import DeprecatedSettingsModal from './deprecated_settings_modal';
 | 
			
		||||
import {
 | 
			
		||||
  OnboardingModal,
 | 
			
		||||
  MuteModal,
 | 
			
		||||
| 
						 | 
				
			
			@ -40,6 +41,7 @@ const MODAL_COMPONENTS = {
 | 
			
		|||
  'BLOCK': BlockModal,
 | 
			
		||||
  'REPORT': ReportModal,
 | 
			
		||||
  'SETTINGS': SettingsModal,
 | 
			
		||||
  'DEPRECATED_SETTINGS': () => Promise.resolve({ default: DeprecatedSettingsModal }),
 | 
			
		||||
  'ACTIONS': () => Promise.resolve({ default: ActionsModal }),
 | 
			
		||||
  'EMBED': EmbedModal,
 | 
			
		||||
  'LIST_EDITOR': ListEditor,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,6 @@ import { openModal } from 'flavours/glitch/actions/modal';
 | 
			
		|||
 | 
			
		||||
const mapStateToProps = state => ({
 | 
			
		||||
  columns: state.getIn(['settings', 'columns']),
 | 
			
		||||
  swipeToChangeColumns: state.getIn(['local_settings', 'swipe_to_change_columns']),
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
const mapDispatchToProps = dispatch => ({
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										49
									
								
								app/javascript/flavours/glitch/images/logo_warn_glitch.svg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								app/javascript/flavours/glitch/images/logo_warn_glitch.svg
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,49 @@
 | 
			
		|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<svg
 | 
			
		||||
   viewBox="0 0 216.41507 232.00976"
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   id="svg6"
 | 
			
		||||
   sodipodi:docname="logo_warn_glitch.svg"
 | 
			
		||||
   inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
 | 
			
		||||
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
 | 
			
		||||
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
 | 
			
		||||
   xmlns="http://www.w3.org/2000/svg"
 | 
			
		||||
   xmlns:svg="http://www.w3.org/2000/svg">
 | 
			
		||||
  <defs
 | 
			
		||||
     id="defs10" />
 | 
			
		||||
  <sodipodi:namedview
 | 
			
		||||
     id="namedview8"
 | 
			
		||||
     pagecolor="#ffffff"
 | 
			
		||||
     bordercolor="#666666"
 | 
			
		||||
     borderopacity="1.0"
 | 
			
		||||
     inkscape:pageshadow="2"
 | 
			
		||||
     inkscape:pageopacity="0.0"
 | 
			
		||||
     inkscape:pagecheckerboard="0"
 | 
			
		||||
     showgrid="false"
 | 
			
		||||
     inkscape:zoom="1.7951831"
 | 
			
		||||
     inkscape:cx="-30.916067"
 | 
			
		||||
     inkscape:cy="90.241493"
 | 
			
		||||
     inkscape:window-width="1920"
 | 
			
		||||
     inkscape:window-height="1011"
 | 
			
		||||
     inkscape:window-x="0"
 | 
			
		||||
     inkscape:window-y="32"
 | 
			
		||||
     inkscape:window-maximized="1"
 | 
			
		||||
     inkscape:current-layer="svg6" />
 | 
			
		||||
  <g
 | 
			
		||||
     id="g2025">
 | 
			
		||||
    <path
 | 
			
		||||
       d="M211.80683 139.0875c-3.1825 16.36625-28.4925 34.2775-57.5625 37.74875-15.16 1.80875-30.0825 3.47125-45.99875 2.74125-26.0275-1.1925-46.565-6.2125-46.565-6.2125 0 2.53375.15625 4.94625.46875 7.2025 3.38375 25.68625 25.47 27.225 46.3925 27.9425 21.115.7225 39.91625-5.20625 39.91625-5.20625l.86875 19.09s-14.77 7.93125-41.08125 9.39c-14.50875.7975-32.52375-.365-53.50625-5.91875C9.23183 213.82 1.40558 165.31125.20808 116.09125c-.36375-14.61375-.14-28.39375-.14-39.91875 0-50.33 32.97625-65.0825 32.97625-65.0825C49.67058 3.45375 78.20308.2425 107.86433 0h.72875c29.66125.2425 58.21125 3.45375 74.8375 11.09 0 0 32.97625 14.7525 32.97625 65.0825 0 0 .4125 37.13375-4.6 62.915"
 | 
			
		||||
       fill="#3088d4"
 | 
			
		||||
       id="path2" />
 | 
			
		||||
    <path
 | 
			
		||||
       d="m 124.52893,137.75645 c 0,9.01375 -7.30875,16.32125 -16.3225,16.32125 -9.01375,0 -16.32125,-7.3075 -16.32125,-16.32125 0,-9.01375 7.3075,-16.3225 16.32125,-16.3225 9.01375,0 16.3225,7.30875 16.3225,16.3225"
 | 
			
		||||
       fill="#ffffff"
 | 
			
		||||
       id="path4"
 | 
			
		||||
       sodipodi:nodetypes="csssc" />
 | 
			
		||||
    <path
 | 
			
		||||
       id="path1121"
 | 
			
		||||
       d="m 108.20703,25.453125 c -9.013749,0 -16.322264,7.308516 -16.322264,16.322266 0,5.31808 2.555126,37.386806 6.492187,67.763669 4.100497,4.20028 15.890147,3.77063 19.660157,-0.01 3.9367,-30.375272 6.49219,-62.4364 6.49219,-67.753909 0,-9.01375 -7.30852,-16.322266 -16.32227,-16.322266 z"
 | 
			
		||||
       style="fill:#ffffff"
 | 
			
		||||
       sodipodi:nodetypes="ssccsss" />
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>
 | 
			
		||||
| 
		 After Width: | Height: | Size: 2.4 KiB  | 
| 
						 | 
				
			
			@ -3,13 +3,12 @@ import { Map as ImmutableMap } from 'immutable';
 | 
			
		|||
 | 
			
		||||
//  Our imports.
 | 
			
		||||
import { STORE_HYDRATE } from 'flavours/glitch/actions/store';
 | 
			
		||||
import { LOCAL_SETTING_CHANGE } from 'flavours/glitch/actions/local_settings';
 | 
			
		||||
import { LOCAL_SETTING_CHANGE, LOCAL_SETTING_DELETE } from 'flavours/glitch/actions/local_settings';
 | 
			
		||||
 | 
			
		||||
const initialState = ImmutableMap({
 | 
			
		||||
  layout    : 'auto',
 | 
			
		||||
  stretch   : true,
 | 
			
		||||
  navbar_under : false,
 | 
			
		||||
  swipe_to_change_columns: true,
 | 
			
		||||
  side_arm  : 'none',
 | 
			
		||||
  side_arm_reply_mode : 'keep',
 | 
			
		||||
  show_reply_count : false,
 | 
			
		||||
| 
						 | 
				
			
			@ -26,7 +25,6 @@ const initialState = ImmutableMap({
 | 
			
		|||
  tag_misleading_links: true,
 | 
			
		||||
  rewrite_mentions: 'no',
 | 
			
		||||
  content_warnings : ImmutableMap({
 | 
			
		||||
    auto_unfold : false,
 | 
			
		||||
    filter      : null,
 | 
			
		||||
  }),
 | 
			
		||||
  collapsed : ImmutableMap({
 | 
			
		||||
| 
						 | 
				
			
			@ -66,6 +64,8 @@ export default function localSettings(state = initialState, action) {
 | 
			
		|||
    return hydrate(state, action.state.get('local_settings'));
 | 
			
		||||
  case LOCAL_SETTING_CHANGE:
 | 
			
		||||
    return state.setIn(action.key, action.value);
 | 
			
		||||
  case LOCAL_SETTING_DELETE:
 | 
			
		||||
    return state.deleteIn(action.key);
 | 
			
		||||
  default:
 | 
			
		||||
    return state;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,6 +98,18 @@
 | 
			
		|||
 | 
			
		||||
.glitch.local-settings__page__item {
 | 
			
		||||
  margin-bottom: 2px;
 | 
			
		||||
 | 
			
		||||
  .hint a {
 | 
			
		||||
    color: $lighter-text-color;
 | 
			
		||||
    font-weight: 500;
 | 
			
		||||
    text-decoration: underline;
 | 
			
		||||
 | 
			
		||||
    &:active,
 | 
			
		||||
    &:focus,
 | 
			
		||||
    &:hover {
 | 
			
		||||
      text-decoration: none;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.glitch.local-settings__page__item.string,
 | 
			
		||||
| 
						 | 
				
			
			@ -120,3 +132,29 @@
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.deprecated-settings-label {
 | 
			
		||||
  white-space: nowrap;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.deprecated-settings-info {
 | 
			
		||||
  text-align: start;
 | 
			
		||||
 | 
			
		||||
  ul {
 | 
			
		||||
    padding: 10px;
 | 
			
		||||
    margin-left: 12px;
 | 
			
		||||
    list-style: disc inside;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  a {
 | 
			
		||||
    color: $lighter-text-color;
 | 
			
		||||
    font-weight: 500;
 | 
			
		||||
    text-decoration: underline;
 | 
			
		||||
 | 
			
		||||
    &:active,
 | 
			
		||||
    &:focus,
 | 
			
		||||
    &:hover {
 | 
			
		||||
      text-decoration: none;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1279,3 +1279,10 @@
 | 
			
		|||
  pointer-events: auto;
 | 
			
		||||
  z-index: 9999;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
img.modal-warning {
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin: auto;
 | 
			
		||||
  margin-bottom: 15px;
 | 
			
		||||
  width: 60px;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,3 +7,12 @@ export const statusAdminLink = (account_id, status_id) => `/admin/accounts/${acc
 | 
			
		|||
export const filterEditLink = (id) => `/filters/${id}/edit`;
 | 
			
		||||
export const relationshipsLink = '/relationships';
 | 
			
		||||
export const securityLink = '/auth/edit';
 | 
			
		||||
export const preferenceLink = (setting_name) => {
 | 
			
		||||
  switch (setting_name) {
 | 
			
		||||
  case 'user_setting_expand_spoilers':
 | 
			
		||||
  case 'user_setting_disable_swiping':
 | 
			
		||||
    return `/settings/preferences/appearance#${setting_name}`;
 | 
			
		||||
  default:
 | 
			
		||||
    return preferencesLink;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,7 @@
 | 
			
		|||
import { expandSpoilers } from 'flavours/glitch/util/initial_state';
 | 
			
		||||
 | 
			
		||||
export function autoUnfoldCW (settings, status) {
 | 
			
		||||
  if (!settings.getIn(['content_warnings', 'auto_unfold'])) {
 | 
			
		||||
  if (!expandSpoilers) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,8 +13,8 @@ const getMeta = (prop) => initialState && initialState.meta && initialState.meta
 | 
			
		|||
 | 
			
		||||
export const reduceMotion = getMeta('reduce_motion');
 | 
			
		||||
export const autoPlayGif = getMeta('auto_play_gif');
 | 
			
		||||
export const displaySensitiveMedia = getMeta('display_sensitive_media');
 | 
			
		||||
export const displayMedia = getMeta('display_media') || (getMeta('display_sensitive_media') ? 'show_all' : 'default');
 | 
			
		||||
export const expandSpoilers = getMeta('expand_spoilers');
 | 
			
		||||
export const unfollowModal = getMeta('unfollow_modal');
 | 
			
		||||
export const boostModal = getMeta('boost_modal');
 | 
			
		||||
export const favouriteModal = getMeta('favourite_modal');
 | 
			
		||||
| 
						 | 
				
			
			@ -37,5 +37,6 @@ export const useBlurhash = getMeta('use_blurhash');
 | 
			
		|||
export const usePendingItems = getMeta('use_pending_items');
 | 
			
		||||
export const useSystemEmojiFont = getMeta('system_emoji_font');
 | 
			
		||||
export const showTrends = getMeta('trends');
 | 
			
		||||
export const disableSwiping = getMeta('disable_swiping');
 | 
			
		||||
 | 
			
		||||
export default initialState;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue