Просмотр исходного кода

Add option to reduce motion (#5393)

* Add option to reduce motion

* Use HOC to wrap all Motion calls

* fix case-sensitive issue

* Avoid updating too frequently

* Get rid of unnecessary change to _simple_status.html.haml
master
Nolan Lawson 6 лет назад
committed by Eugen Rochko
Родитель
Сommit
fa0be3f834
21 измененных файлов: 61 добавлений и 13 удалений
  1. +1
    -0
      app/controllers/settings/preferences_controller.rb
  2. +1
    -1
      app/javascript/mastodon/components/collapsable.js
  3. +1
    -1
      app/javascript/mastodon/components/dropdown_menu.js
  4. +1
    -1
      app/javascript/mastodon/components/icon_button.js
  5. +1
    -1
      app/javascript/mastodon/features/account/components/header.js
  6. +1
    -1
      app/javascript/mastodon/features/compose/components/privacy_dropdown.js
  7. +1
    -1
      app/javascript/mastodon/features/compose/components/search.js
  8. +1
    -1
      app/javascript/mastodon/features/compose/components/upload.js
  9. +1
    -1
      app/javascript/mastodon/features/compose/components/upload_progress.js
  10. +1
    -1
      app/javascript/mastodon/features/compose/components/warning.js
  11. +1
    -1
      app/javascript/mastodon/features/compose/containers/sensitive_button_container.js
  12. +1
    -1
      app/javascript/mastodon/features/compose/index.js
  13. +1
    -1
      app/javascript/mastodon/features/ui/components/upload_area.js
  14. +34
    -0
      app/javascript/mastodon/features/ui/util/optional_motion.js
  15. +5
    -0
      app/lib/user_settings_decorator.rb
  16. +4
    -0
      app/models/user.rb
  17. +1
    -0
      app/serializers/initial_state_serializer.rb
  18. +1
    -0
      app/views/settings/preferences/show.html.haml
  19. +1
    -1
      app/views/stream_entries/_detailed_status.html.haml
  20. +1
    -0
      config/locales/simple_form.en.yml
  21. +1
    -0
      config/settings.yml

+ 1
- 0
app/controllers/settings/preferences_controller.rb Просмотреть файл

@@ -39,6 +39,7 @@ class Settings::PreferencesController < ApplicationController
:setting_boost_modal,
:setting_delete_modal,
:setting_auto_play_gif,
:setting_reduce_motion,
:setting_system_font_ui,
:setting_noindex,
:setting_theme,


+ 1
- 1
app/javascript/mastodon/components/collapsable.js Просмотреть файл

@@ -1,5 +1,5 @@
import React from 'react';
import Motion from 'react-motion/lib/Motion';
import Motion from '../features/ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import PropTypes from 'prop-types';



+ 1
- 1
app/javascript/mastodon/components/dropdown_menu.js Просмотреть файл

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import IconButton from './icon_button';
import Overlay from 'react-overlays/lib/Overlay';
import Motion from 'react-motion/lib/Motion';
import Motion from '../features/ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import detectPassiveEvents from 'detect-passive-events';



+ 1
- 1
app/javascript/mastodon/components/icon_button.js Просмотреть файл

@@ -1,5 +1,5 @@
import React from 'react';
import Motion from 'react-motion/lib/Motion';
import Motion from '../features/ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import PropTypes from 'prop-types';
import classNames from 'classnames';


+ 1
- 1
app/javascript/mastodon/features/account/components/header.js Просмотреть файл

@@ -3,7 +3,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import IconButton from '../../../components/icon_button';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import { connect } from 'react-redux';
import ImmutablePureComponent from 'react-immutable-pure-component';


+ 1
- 1
app/javascript/mastodon/features/compose/components/privacy_dropdown.js Просмотреть файл

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
import { injectIntl, defineMessages } from 'react-intl';
import IconButton from '../../../components/icon_button';
import Overlay from 'react-overlays/lib/Overlay';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import detectPassiveEvents from 'detect-passive-events';
import classNames from 'classnames';


+ 1
- 1
app/javascript/mastodon/features/compose/components/search.js Просмотреть файл

@@ -2,7 +2,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import Overlay from 'react-overlays/lib/Overlay';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';

const messages = defineMessages({


+ 1
- 1
app/javascript/mastodon/features/compose/components/upload.js Просмотреть файл

@@ -2,7 +2,7 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import IconButton from '../../../components/icon_button';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { defineMessages, injectIntl } from 'react-intl';


+ 1
- 1
app/javascript/mastodon/features/compose/components/upload_progress.js Просмотреть файл

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import { FormattedMessage } from 'react-intl';



+ 1
- 1
app/javascript/mastodon/features/compose/components/warning.js Просмотреть файл

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';

export default class Warning extends React.PureComponent {


+ 1
- 1
app/javascript/mastodon/features/compose/containers/sensitive_button_container.js Просмотреть файл

@@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';
import IconButton from '../../../components/icon_button';
import { changeComposeSensitivity } from '../../../actions/compose';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import { injectIntl, defineMessages } from 'react-intl';



+ 1
- 1
app/javascript/mastodon/features/compose/index.js Просмотреть файл

@@ -8,7 +8,7 @@ import { mountCompose, unmountCompose } from '../../actions/compose';
import { Link } from 'react-router-dom';
import { injectIntl, defineMessages } from 'react-intl';
import SearchContainer from './containers/search_container';
import Motion from 'react-motion/lib/Motion';
import Motion from '../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import SearchResultsContainer from './containers/search_results_container';
import { changeComposing } from '../../actions/compose';


+ 1
- 1
app/javascript/mastodon/features/ui/components/upload_area.js Просмотреть файл

@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import Motion from 'react-motion/lib/Motion';
import Motion from '../../ui/util/optional_motion';
import spring from 'react-motion/lib/spring';
import { FormattedMessage } from 'react-intl';



+ 34
- 0
app/javascript/mastodon/features/ui/util/optional_motion.js Просмотреть файл

@@ -0,0 +1,34 @@
// Like react-motion's Motion, but checks to see if the user prefers
// reduced motion and uses a cross-fade in those cases.

import Motion from 'react-motion/lib/Motion';
import { connect } from 'react-redux';

const stylesToKeep = ['opacity', 'backgroundOpacity'];

const extractValue = (value) => {
// This is either an object with a "val" property or it's a number
return (typeof value === 'object' && value && 'val' in value) ? value.val : value;
};

const mapStateToProps = (state, ownProps) => {
const reduceMotion = state.getIn(['meta', 'reduce_motion']);

if (reduceMotion) {
const { style, defaultStyle } = ownProps;

Object.keys(style).forEach(key => {
if (stylesToKeep.includes(key)) {
return;
}
// If it's setting an x or height or scale or some other value, we need
// to preserve the end-state value without actually animating it
style[key] = defaultStyle[key] = extractValue(style[key]);
});

return { style, defaultStyle };
}
return {};
};

export default connect(mapStateToProps)(Motion);

+ 5
- 0
app/lib/user_settings_decorator.rb Просмотреть файл

@@ -23,6 +23,7 @@ class UserSettingsDecorator
user.settings['boost_modal'] = boost_modal_preference if change?('setting_boost_modal')
user.settings['delete_modal'] = delete_modal_preference if change?('setting_delete_modal')
user.settings['auto_play_gif'] = auto_play_gif_preference if change?('setting_auto_play_gif')
user.settings['reduce_motion'] = reduce_motion_preference if change?('setting_reduce_motion')
user.settings['system_font_ui'] = system_font_ui_preference if change?('setting_system_font_ui')
user.settings['noindex'] = noindex_preference if change?('setting_noindex')
user.settings['theme'] = theme_preference if change?('setting_theme')
@@ -64,6 +65,10 @@ class UserSettingsDecorator
boolean_cast_setting 'setting_auto_play_gif'
end

def reduce_motion_preference
boolean_cast_setting 'setting_reduce_motion'
end

def noindex_preference
boolean_cast_setting 'setting_noindex'
end


+ 4
- 0
app/models/user.rb Просмотреть файл

@@ -102,6 +102,10 @@ class User < ApplicationRecord
settings.auto_play_gif
end

def setting_reduce_motion
settings.reduce_motion
end

def setting_system_font_ui
settings.system_font_ui
end


+ 1
- 0
app/serializers/initial_state_serializer.rb Просмотреть файл

@@ -25,6 +25,7 @@ class InitialStateSerializer < ActiveModel::Serializer
store[:boost_modal] = object.current_account.user.setting_boost_modal
store[:delete_modal] = object.current_account.user.setting_delete_modal
store[:auto_play_gif] = object.current_account.user.setting_auto_play_gif
store[:reduce_motion] = object.current_account.user.setting_reduce_motion
end

store


+ 1
- 0
app/views/settings/preferences/show.html.haml Просмотреть файл

@@ -35,6 +35,7 @@

.fields-group
= f.input :setting_auto_play_gif, as: :boolean, wrapper: :with_label
= f.input :setting_reduce_motion, as: :boolean, wrapper: :with_label
= f.input :setting_system_font_ui, as: :boolean, wrapper: :with_label

.actions


+ 1
- 1
app/views/stream_entries/_detailed_status.html.haml Просмотреть файл

@@ -24,7 +24,7 @@
- video = status.media_attachments.first
%div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive?, width: 670, height: 380) }}
- else
%div{ data: { component: 'MediaGallery', props: Oj.dump(height: 380, sensitive: status.sensitive?, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }}
%div{ data: { component: 'MediaGallery', props: Oj.dump(height: 380, sensitive: status.sensitive?, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }}
- elsif status.preview_cards.first
%div{ data: { component: 'Card', props: Oj.dump('maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_cards.first, serializer: REST::PreviewCardSerializer).as_json) }}



+ 1
- 0
config/locales/simple_form.en.yml Просмотреть файл

@@ -39,6 +39,7 @@ en:
otp_attempt: Two-factor code
password: Password
setting_auto_play_gif: Auto-play animated GIFs
setting_reduce_motion: Reduce motion in animations
setting_boost_modal: Show confirmation dialog before boosting
setting_default_privacy: Post privacy
setting_default_sensitive: Always mark media as sensitive


+ 1
- 0
config/settings.yml Просмотреть файл

@@ -22,6 +22,7 @@ defaults: &defaults
boost_modal: false
delete_modal: true
auto_play_gif: false
reduce_motion: false
system_font_ui: false
noindex: false
theme: 'default'


Загрузка…
Отмена
Сохранить