From 1948f9e767c5c8f7cb52337ce777a61b5ad1a599 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Sat, 22 Apr 2017 03:05:35 +0900 Subject: Remove deprecated features at React v15.5 (#1905) * Remove deprecated features at React v15.5 - [x] React.PropTypes - [x] react-addons-pure-render-mixin - [x] react-addons-test-utils * Uncommented out & Add browserify_rails options * re-add react-addons-shallow * Fix syntax error from resolve conflicts * follow up 59a77923b368d48c590cd9f4a0c6b73ce972d33f --- .../features/ui/components/boost_modal.jsx | 37 +++++++++------- .../components/features/ui/components/column.jsx | 32 ++++++++------ .../features/ui/components/column_header.jsx | 29 +++++++------ .../features/ui/components/column_link.jsx | 13 +++--- .../features/ui/components/columns_area.jsx | 16 +++---- .../features/ui/components/media_modal.jsx | 44 ++++++++++--------- .../features/ui/components/modal_root.jsx | 33 +++++++------- .../features/ui/components/onboarding_modal.jsx | 50 +++++++++++----------- .../components/features/ui/components/tabs_bar.jsx | 4 +- .../features/ui/components/upload_area.jsx | 16 +++---- .../features/ui/components/video_modal.jsx | 22 +++++----- .../javascripts/components/features/ui/index.jsx | 47 +++++++++++--------- 12 files changed, 181 insertions(+), 162 deletions(-) (limited to 'app/assets/javascripts/components/features/ui') diff --git a/app/assets/javascripts/components/features/ui/components/boost_modal.jsx b/app/assets/javascripts/components/features/ui/components/boost_modal.jsx index b54768631..e33239be7 100644 --- a/app/assets/javascripts/components/features/ui/components/boost_modal.jsx +++ b/app/assets/javascripts/components/features/ui/components/boost_modal.jsx @@ -1,5 +1,5 @@ -import PureRenderMixin from 'react-addons-pure-render-mixin'; 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 Button from '../../../components/button'; @@ -12,24 +12,18 @@ const messages = defineMessages({ reblog: { id: 'status.reblog', defaultMessage: 'Boost' } }); -const BoostModal = React.createClass({ - contextTypes: { - router: React.PropTypes.object - }, +class BoostModal extends React.PureComponent { - propTypes: { - status: ImmutablePropTypes.map.isRequired, - onReblog: React.PropTypes.func.isRequired, - onClose: React.PropTypes.func.isRequired, - intl: React.PropTypes.object.isRequired - }, - - mixins: [PureRenderMixin], + constructor (props, context) { + super(props, context); + this.handleReblog = this.handleReblog.bind(this); + this.handleAccountClick = this.handleAccountClick.bind(this); + } handleReblog() { this.props.onReblog(this.props.status); this.props.onClose(); - }, + } handleAccountClick (e) { if (e.button === 0) { @@ -37,7 +31,7 @@ const BoostModal = React.createClass({ this.props.onClose(); this.context.router.push(`/accounts/${this.props.status.getIn(['account', 'id'])}`); } - }, + } render () { const { status, intl, onClose } = this.props; @@ -72,6 +66,17 @@ const BoostModal = React.createClass({ ); } -}); +} + +BoostModal.contextTypes = { + router: PropTypes.object +}; + +BoostModal.propTypes = { + status: ImmutablePropTypes.map.isRequired, + onReblog: PropTypes.func.isRequired, + onClose: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired +}; export default injectIntl(BoostModal); diff --git a/app/assets/javascripts/components/features/ui/components/column.jsx b/app/assets/javascripts/components/features/ui/components/column.jsx index 977ea6059..4dad7f721 100644 --- a/app/assets/javascripts/components/features/ui/components/column.jsx +++ b/app/assets/javascripts/components/features/ui/components/column.jsx @@ -1,5 +1,5 @@ import ColumnHeader from './column_header'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; +import PropTypes from 'prop-types'; const easingOutQuint = (x, t, b, c, d) => c*((t=t/d-1)*t*t*t*t + 1) + b; @@ -29,17 +29,13 @@ const scrollTop = (node) => { }; }; -const Column = React.createClass({ +class Column extends React.PureComponent { - propTypes: { - heading: React.PropTypes.string, - icon: React.PropTypes.string, - children: React.PropTypes.node, - active: React.PropTypes.bool, - hideHeadingOnMobile: React.PropTypes.bool - }, - - mixins: [PureRenderMixin], + constructor (props, context) { + super(props, context); + this.handleHeaderClick = this.handleHeaderClick.bind(this); + this.handleWheel = this.handleWheel.bind(this); + } handleHeaderClick () { const scrollable = ReactDOM.findDOMNode(this).querySelector('.scrollable'); @@ -47,13 +43,13 @@ const Column = React.createClass({ return; } this._interruptScrollAnimation = scrollTop(scrollable); - }, + } handleWheel () { if (typeof this._interruptScrollAnimation !== 'undefined') { this._interruptScrollAnimation(); } - }, + } render () { const { heading, icon, children, active, hideHeadingOnMobile } = this.props; @@ -72,6 +68,14 @@ const Column = React.createClass({ ); } -}); +} + +Column.propTypes = { + heading: PropTypes.string, + icon: PropTypes.string, + children: PropTypes.node, + active: PropTypes.bool, + hideHeadingOnMobile: PropTypes.bool +}; export default Column; diff --git a/app/assets/javascripts/components/features/ui/components/column_header.jsx b/app/assets/javascripts/components/features/ui/components/column_header.jsx index 232db1e14..454cce9c2 100644 --- a/app/assets/javascripts/components/features/ui/components/column_header.jsx +++ b/app/assets/javascripts/components/features/ui/components/column_header.jsx @@ -1,20 +1,15 @@ -import PureRenderMixin from 'react-addons-pure-render-mixin'; +import PropTypes from 'prop-types' -const ColumnHeader = React.createClass({ +class ColumnHeader extends React.PureComponent { - propTypes: { - icon: React.PropTypes.string, - type: React.PropTypes.string, - active: React.PropTypes.bool, - onClick: React.PropTypes.func, - hideOnMobile: React.PropTypes.bool - }, - - mixins: [PureRenderMixin], + constructor (props, context) { + super(props, context); + this.handleClick = this.handleClick.bind(this); + } handleClick () { this.props.onClick(); - }, + } render () { const { type, active, hideOnMobile } = this.props; @@ -33,6 +28,14 @@ const ColumnHeader = React.createClass({ ); } -}); +} + +ColumnHeader.propTypes = { + icon: PropTypes.string, + type: PropTypes.string, + active: PropTypes.bool, + onClick: PropTypes.func, + hideOnMobile: PropTypes.bool +}; export default ColumnHeader; diff --git a/app/assets/javascripts/components/features/ui/components/column_link.jsx b/app/assets/javascripts/components/features/ui/components/column_link.jsx index 9ed34e85f..32fd329d4 100644 --- a/app/assets/javascripts/components/features/ui/components/column_link.jsx +++ b/app/assets/javascripts/components/features/ui/components/column_link.jsx @@ -1,3 +1,4 @@ +import PropTypes from 'prop-types'; import { Link } from 'react-router'; const outerStyle = { @@ -30,12 +31,12 @@ const ColumnLink = ({ icon, text, to, href, method, hideOnMobile }) => { }; ColumnLink.propTypes = { - icon: React.PropTypes.string.isRequired, - text: React.PropTypes.string.isRequired, - to: React.PropTypes.string, - href: React.PropTypes.string, - method: React.PropTypes.string, - hideOnMobile: React.PropTypes.bool + icon: PropTypes.string.isRequired, + text: PropTypes.string.isRequired, + to: PropTypes.string, + href: PropTypes.string, + method: PropTypes.string, + hideOnMobile: PropTypes.bool }; export default ColumnLink; diff --git a/app/assets/javascripts/components/features/ui/components/columns_area.jsx b/app/assets/javascripts/components/features/ui/components/columns_area.jsx index dd771900d..06f6427ab 100644 --- a/app/assets/javascripts/components/features/ui/components/columns_area.jsx +++ b/app/assets/javascripts/components/features/ui/components/columns_area.jsx @@ -1,4 +1,4 @@ -import PureRenderMixin from 'react-addons-pure-render-mixin'; +import PropTypes from 'prop-types'; const style = { display: 'flex', @@ -6,13 +6,7 @@ const style = { overflowX: 'auto' }; -const ColumnsArea = React.createClass({ - - propTypes: { - children: React.PropTypes.node - }, - - mixins: [PureRenderMixin], +class ColumnsArea extends React.PureComponent { render () { return ( @@ -22,6 +16,10 @@ const ColumnsArea = React.createClass({ ); } -}); +} + +ColumnsArea.propTypes = { + children: PropTypes.node +}; export default ColumnsArea; diff --git a/app/assets/javascripts/components/features/ui/components/media_modal.jsx b/app/assets/javascripts/components/features/ui/components/media_modal.jsx index 786b08152..8ed6afa6c 100644 --- a/app/assets/javascripts/components/features/ui/components/media_modal.jsx +++ b/app/assets/javascripts/components/features/ui/components/media_modal.jsx @@ -1,6 +1,6 @@ import LoadingIndicator from '../../../components/loading_indicator'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; import ImmutablePropTypes from 'react-immutable-proptypes'; +import PropTypes from 'prop-types'; import ExtendedVideoPlayer from '../../../components/extended_video_player'; import ImageLoader from 'react-imageloader'; import { defineMessages, injectIntl } from 'react-intl'; @@ -44,30 +44,25 @@ const closeStyle = { right: '4px' }; -const MediaModal = React.createClass({ +class MediaModal extends React.PureComponent { - propTypes: { - media: ImmutablePropTypes.list.isRequired, - index: React.PropTypes.number.isRequired, - onClose: React.PropTypes.func.isRequired, - intl: React.PropTypes.object.isRequired - }, - - getInitialState () { - return { + constructor (props, context) { + super(props, context); + this.state = { index: null }; - }, - - mixins: [PureRenderMixin], + this.handleNextClick = this.handleNextClick.bind(this); + this.handlePrevClick = this.handlePrevClick.bind(this); + this.handleKeyUp = this.handleKeyUp.bind(this); + } handleNextClick () { this.setState({ index: (this.getIndex() + 1) % this.props.media.size}); - }, + } handlePrevClick () { this.setState({ index: (this.getIndex() - 1) % this.props.media.size}); - }, + } handleKeyUp (e) { switch(e.key) { @@ -78,19 +73,19 @@ const MediaModal = React.createClass({ this.handleNextClick(); break; } - }, + } componentDidMount () { window.addEventListener('keyup', this.handleKeyUp, false); - }, + } componentWillUnmount () { window.removeEventListener('keyup', this.handleKeyUp); - }, + } getIndex () { return this.state.index !== null ? this.state.index : this.props.index; - }, + } render () { const { media, intl, onClose } = this.props; @@ -128,6 +123,13 @@ const MediaModal = React.createClass({ ); } -}); +} + +MediaModal.propTypes = { + media: ImmutablePropTypes.list.isRequired, + index: PropTypes.number.isRequired, + onClose: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired +}; export default injectIntl(MediaModal); diff --git a/app/assets/javascripts/components/features/ui/components/modal_root.jsx b/app/assets/javascripts/components/features/ui/components/modal_root.jsx index ace3e085f..7b84ef3c8 100644 --- a/app/assets/javascripts/components/features/ui/components/modal_root.jsx +++ b/app/assets/javascripts/components/features/ui/components/modal_root.jsx @@ -1,4 +1,4 @@ -import PureRenderMixin from 'react-addons-pure-render-mixin'; +import PropTypes from 'prop-types'; import MediaModal from './media_modal'; import OnboardingModal from './onboarding_modal'; import VideoModal from './video_modal'; @@ -12,37 +12,34 @@ const MODAL_COMPONENTS = { 'BOOST': BoostModal }; -const ModalRoot = React.createClass({ +class ModalRoot extends React.PureComponent { - propTypes: { - type: React.PropTypes.string, - props: React.PropTypes.object, - onClose: React.PropTypes.func.isRequired - }, - - mixins: [PureRenderMixin], + constructor (props, context) { + super(props, context); + this.handleKeyUp = this.handleKeyUp.bind(this); + } handleKeyUp (e) { if (e.key === 'Escape' && !!this.props.type) { this.props.onClose(); } - }, + } componentDidMount () { window.addEventListener('keyup', this.handleKeyUp, false); - }, + } componentWillUnmount () { window.removeEventListener('keyup', this.handleKeyUp); - }, + } willEnter () { return { opacity: 0, scale: 0.98 }; - }, + } willLeave () { return { opacity: spring(0), scale: spring(0.98) }; - }, + } render () { const { type, props, onClose } = this.props; @@ -81,6 +78,12 @@ const ModalRoot = React.createClass({ ); } -}); +} + +ModalRoot.propTypes = { + type: PropTypes.string, + props: PropTypes.object, + onClose: PropTypes.func.isRequired +}; export default ModalRoot; diff --git a/app/assets/javascripts/components/features/ui/components/onboarding_modal.jsx b/app/assets/javascripts/components/features/ui/components/onboarding_modal.jsx index 36e0d0c8a..e39eaf8de 100644 --- a/app/assets/javascripts/components/features/ui/components/onboarding_modal.jsx +++ b/app/assets/javascripts/components/features/ui/components/onboarding_modal.jsx @@ -1,5 +1,5 @@ import { connect } from 'react-redux'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; +import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import Permalink from '../../../components/permalink'; @@ -32,8 +32,8 @@ const PageOne = ({ acct, domain }) => ( ); PageOne.propTypes = { - acct: React.PropTypes.string.isRequired, - domain: React.PropTypes.string.isRequired + acct: PropTypes.string.isRequired, + domain: PropTypes.string.isRequired }; const PageTwo = () => ( @@ -85,7 +85,7 @@ const PageThree = ({ me, domain }) => ( PageThree.propTypes = { me: ImmutablePropTypes.map.isRequired, - domain: React.PropTypes.string.isRequired + domain: PropTypes.string.isRequired }; const PageFour = ({ domain, intl }) => ( @@ -119,8 +119,8 @@ const PageFour = ({ domain, intl }) => ( ); PageFour.propTypes = { - domain: React.PropTypes.string.isRequired, - intl: React.PropTypes.object.isRequired + domain: PropTypes.string.isRequired, + intl: PropTypes.object.isRequired }; const PageSix = ({ admin }) => { @@ -157,33 +157,27 @@ const mapStateToProps = state => ({ domain: state.getIn(['meta', 'domain']) }); -const OnboardingModal = React.createClass({ +class OnboardingModal extends React.PureComponent { - propTypes: { - onClose: React.PropTypes.func.isRequired, - intl: React.PropTypes.object.isRequired, - me: ImmutablePropTypes.map.isRequired, - domain: React.PropTypes.string.isRequired, - admin: ImmutablePropTypes.map - }, - - getInitialState () { - return { + constructor (props, context) { + super(props, context); + this.state = { currentIndex: 0 }; - }, - - mixins: [PureRenderMixin], + this.handleSkip = this.handleSkip.bind(this); + this.handleDot = this.handleDot.bind(this); + this.handleNext = this.handleNext.bind(this); + } handleSkip (e) { e.preventDefault(); this.props.onClose(); - }, + } handleDot (i, e) { e.preventDefault(); this.setState({ currentIndex: i }); - }, + } handleNext (maxNum, e) { e.preventDefault(); @@ -193,7 +187,7 @@ const OnboardingModal = React.createClass({ } else { this.props.onClose(); } - }, + } render () { const { me, admin, domain, intl } = this.props; @@ -251,6 +245,14 @@ const OnboardingModal = React.createClass({ ); } -}); +} + +OnboardingModal.propTypes = { + onClose: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired, + me: ImmutablePropTypes.map.isRequired, + domain: PropTypes.string.isRequired, + admin: ImmutablePropTypes.map +} export default connect(mapStateToProps)(injectIntl(OnboardingModal)); diff --git a/app/assets/javascripts/components/features/ui/components/tabs_bar.jsx b/app/assets/javascripts/components/features/ui/components/tabs_bar.jsx index 68002840f..93c7441de 100644 --- a/app/assets/javascripts/components/features/ui/components/tabs_bar.jsx +++ b/app/assets/javascripts/components/features/ui/components/tabs_bar.jsx @@ -1,7 +1,7 @@ import { Link } from 'react-router'; import { FormattedMessage } from 'react-intl'; -const TabsBar = React.createClass({ +class TabsBar extends React.PureComponent { render () { return ( @@ -18,6 +18,6 @@ const TabsBar = React.createClass({ ); } -}); +} export default TabsBar; diff --git a/app/assets/javascripts/components/features/ui/components/upload_area.jsx b/app/assets/javascripts/components/features/ui/components/upload_area.jsx index 70b687019..38c2ad904 100644 --- a/app/assets/javascripts/components/features/ui/components/upload_area.jsx +++ b/app/assets/javascripts/components/features/ui/components/upload_area.jsx @@ -1,14 +1,8 @@ -import PureRenderMixin from 'react-addons-pure-render-mixin'; +import PropTypes from 'prop-types'; import { Motion, spring } from 'react-motion'; import { FormattedMessage } from 'react-intl'; -const UploadArea = React.createClass({ - - propTypes: { - active: React.PropTypes.bool - }, - - mixins: [PureRenderMixin], +class UploadArea extends React.PureComponent { render () { const { active } = this.props; @@ -27,6 +21,10 @@ const UploadArea = React.createClass({ ); } -}); +} + +UploadArea.propTypes = { + active: PropTypes.bool +}; export default UploadArea; diff --git a/app/assets/javascripts/components/features/ui/components/video_modal.jsx b/app/assets/javascripts/components/features/ui/components/video_modal.jsx index 1c3519bd3..adbab0494 100644 --- a/app/assets/javascripts/components/features/ui/components/video_modal.jsx +++ b/app/assets/javascripts/components/features/ui/components/video_modal.jsx @@ -1,6 +1,6 @@ import LoadingIndicator from '../../../components/loading_indicator'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; import ImmutablePropTypes from 'react-immutable-proptypes'; +import PropTypes from 'prop-types'; import ExtendedVideoPlayer from '../../../components/extended_video_player'; import { defineMessages, injectIntl } from 'react-intl'; import IconButton from '../../../components/icon_button'; @@ -16,16 +16,7 @@ const closeStyle = { right: '4px' }; -const VideoModal = React.createClass({ - - propTypes: { - media: ImmutablePropTypes.map.isRequired, - time: React.PropTypes.number, - onClose: React.PropTypes.func.isRequired, - intl: React.PropTypes.object.isRequired - }, - - mixins: [PureRenderMixin], +class VideoModal extends React.PureComponent { render () { const { media, intl, time, onClose } = this.props; @@ -42,6 +33,13 @@ const VideoModal = React.createClass({ ); } -}); +} + +VideoModal.propTypes = { + media: ImmutablePropTypes.map.isRequired, + time: PropTypes.number, + onClose: PropTypes.func.isRequired, + intl: PropTypes.object.isRequired +}; export default injectIntl(VideoModal); diff --git a/app/assets/javascripts/components/features/ui/index.jsx b/app/assets/javascripts/components/features/ui/index.jsx index d3090ae9b..1f35842d9 100644 --- a/app/assets/javascripts/components/features/ui/index.jsx +++ b/app/assets/javascripts/components/features/ui/index.jsx @@ -1,6 +1,6 @@ import ColumnsArea from './components/columns_area'; import NotificationsContainer from './containers/notifications_container'; -import PureRenderMixin from 'react-addons-pure-render-mixin'; +import PropTypes from 'prop-types'; import LoadingBarContainer from './containers/loading_bar_container'; import HomeTimeline from '../home_timeline'; import Compose from '../compose'; @@ -15,26 +15,26 @@ import { refreshTimeline } from '../../actions/timelines'; import { refreshNotifications } from '../../actions/notifications'; import UploadArea from './components/upload_area'; -const UI = React.createClass({ +class UI extends React.PureComponent { - propTypes: { - dispatch: React.PropTypes.func.isRequired, - children: React.PropTypes.node - }, - - getInitialState () { - return { + constructor (props, context) { + super(props, context); + this.state = { width: window.innerWidth, draggingOver: false }; - }, - - mixins: [PureRenderMixin], + this.handleResize = this.handleResize.bind(this); + this.handleDragEnter = this.handleDragEnter.bind(this); + this.handleDragOver = this.handleDragOver.bind(this); + this.handleDrop = this.handleDrop.bind(this); + this.handleDragLeave = this.handleDragLeave.bind(this); + this.setRef = this.setRef.bind(this); + } @debounce(500) handleResize () { this.setState({ width: window.innerWidth }); - }, + } handleDragEnter (e) { e.preventDefault(); @@ -50,7 +50,7 @@ const UI = React.createClass({ if (e.dataTransfer && e.dataTransfer.items.length > 0) { this.setState({ draggingOver: true }); } - }, + } handleDragOver (e) { e.preventDefault(); @@ -63,7 +63,7 @@ const UI = React.createClass({ } return false; - }, + } handleDrop (e) { e.preventDefault(); @@ -73,7 +73,7 @@ const UI = React.createClass({ if (e.dataTransfer && e.dataTransfer.files.length === 1) { this.props.dispatch(uploadCompose(e.dataTransfer.files)); } - }, + } handleDragLeave (e) { e.preventDefault(); @@ -86,7 +86,7 @@ const UI = React.createClass({ } this.setState({ draggingOver: false }); - }, + } componentWillMount () { window.addEventListener('resize', this.handleResize, { passive: true }); @@ -97,7 +97,7 @@ const UI = React.createClass({ this.props.dispatch(refreshTimeline('home')); this.props.dispatch(refreshNotifications()); - }, + } componentWillUnmount () { window.removeEventListener('resize', this.handleResize); @@ -105,11 +105,11 @@ const UI = React.createClass({ document.removeEventListener('dragover', this.handleDragOver); document.removeEventListener('drop', this.handleDrop); document.removeEventListener('dragleave', this.handleDragLeave); - }, + } setRef (c) { this.node = c; - }, + } render () { const { width, draggingOver } = this.state; @@ -148,6 +148,11 @@ const UI = React.createClass({ ); } -}); +} + +UI.propTypes = { + dispatch: PropTypes.func.isRequired, + children: PropTypes.node +}; export default connect()(UI); -- cgit