about summary refs log tree commit diff
path: root/app/assets/javascripts/components/features/ui
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/components/features/ui')
-rw-r--r--app/assets/javascripts/components/features/ui/components/column.jsx10
-rw-r--r--app/assets/javascripts/components/features/ui/containers/modal_container.jsx112
-rw-r--r--app/assets/javascripts/components/features/ui/containers/status_list_container.jsx7
3 files changed, 117 insertions, 12 deletions
diff --git a/app/assets/javascripts/components/features/ui/components/column.jsx b/app/assets/javascripts/components/features/ui/components/column.jsx
index c382e108d..2eafe5a8f 100644
--- a/app/assets/javascripts/components/features/ui/components/column.jsx
+++ b/app/assets/javascripts/components/features/ui/components/column.jsx
@@ -1,4 +1,4 @@
-import ColumnHeader    from './column_header';
+import ColumnHeader from './column_header';
 import PureRenderMixin from 'react-addons-pure-render-mixin';
 
 const easingOutQuint = (x, t, b, c, d) => c*((t=t/d-1)*t*t*t*t + 1) + b;
@@ -58,16 +58,18 @@ const Column = React.createClass({
   },
 
   render () {
+    const { heading, icon, children } = this.props;
+
     let header = '';
 
-    if (this.props.heading) {
-      header = <ColumnHeader icon={this.props.icon} type={this.props.heading} onClick={this.handleHeaderClick} />;
+    if (heading) {
+      header = <ColumnHeader icon={icon} type={heading} onClick={this.handleHeaderClick} />;
     }
 
     return (
       <div className='column' style={style} onWheel={this.handleWheel}>
         {header}
-        {this.props.children}
+        {children}
       </div>
     );
   }
diff --git a/app/assets/javascripts/components/features/ui/containers/modal_container.jsx b/app/assets/javascripts/components/features/ui/containers/modal_container.jsx
index 53d162462..334e5c199 100644
--- a/app/assets/javascripts/components/features/ui/containers/modal_container.jsx
+++ b/app/assets/javascripts/components/features/ui/containers/modal_container.jsx
@@ -1,12 +1,18 @@
 import { connect } from 'react-redux';
-import { closeModal } from '../../../actions/modal';
+import {
+  closeModal,
+  decreaseIndexInModal,
+  increaseIndexInModal
+} from '../../../actions/modal';
 import Lightbox from '../../../components/lightbox';
 import ImageLoader from 'react-imageloader';
 import LoadingIndicator from '../../../components/loading_indicator';
 import PureRenderMixin from 'react-addons-pure-render-mixin';
+import ImmutablePropTypes from 'react-immutable-proptypes';
 
 const mapStateToProps = state => ({
-  url: state.getIn(['modal', 'url']),
+  media: state.getIn(['modal', 'media']),
+  index: state.getIn(['modal', 'index']),
   isVisible: state.getIn(['modal', 'open'])
 });
 
@@ -17,6 +23,14 @@ const mapDispatchToProps = dispatch => ({
 
   onOverlayClicked () {
     dispatch(closeModal());
+  },
+
+  onNextClicked () {
+    dispatch(increaseIndexInModal());
+  },
+
+  onPrevClicked () {
+    dispatch(decreaseIndexInModal());
   }
 });
 
@@ -38,27 +52,115 @@ const preloader = () => (
   </div>
 );
 
+const leftNavStyle = {
+  position: 'absolute',
+  background: 'rgba(0, 0, 0, 0.5)',
+  padding: '30px 15px',
+  cursor: 'pointer',
+  color: '#fff',
+  fontSize: '24px',
+  top: '0',
+  left: '-61px',
+  boxSizing: 'border-box',
+  height: '100%',
+  display: 'flex',
+  alignItems: 'center'
+};
+
+const rightNavStyle = {
+  position: 'absolute',
+  background: 'rgba(0, 0, 0, 0.5)',
+  padding: '30px 15px',
+  cursor: 'pointer',
+  color: '#fff',
+  fontSize: '24px',
+  top: '0',
+  right: '-61px',
+  boxSizing: 'border-box',
+  height: '100%',
+  display: 'flex',
+  alignItems: 'center'
+};
+
 const Modal = React.createClass({
 
   propTypes: {
-    url: React.PropTypes.string,
+    media: ImmutablePropTypes.list,
+    index: React.PropTypes.number.isRequired,
     isVisible: React.PropTypes.bool,
     onCloseClicked: React.PropTypes.func,
-    onOverlayClicked: React.PropTypes.func
+    onOverlayClicked: React.PropTypes.func,
+    onNextClicked: React.PropTypes.func,
+    onPrevClicked: React.PropTypes.func
   },
 
   mixins: [PureRenderMixin],
 
+  handleNextClick () {
+    this.props.onNextClicked();
+  },
+
+  handlePrevClick () {
+    this.props.onPrevClicked();
+  },
+
+  componentDidMount () {
+    this._listener = e => {
+      if (!this.props.isVisible) {
+        return;
+      }
+
+      switch(e.key) {
+      case 'ArrowLeft':
+        this.props.onPrevClicked();
+        break;
+      case 'ArrowRight':
+        this.props.onNextClicked();
+        break;
+      }
+    };
+
+    window.addEventListener('keyup', this._listener);
+  },
+
+  componentWillUnmount () {
+    window.removeEventListener('keyup', this._listener);
+  },
+
   render () {
-    const { url, ...other } = this.props;
+    const { media, index, ...other } = this.props;
+
+    if (!media) {
+      return null;
+    }
+
+    const url      = media.get(index).get('url');
+    const hasLeft  = index > 0;
+    const hasRight = index + 1 < media.size;
+
+    let leftNav, rightNav;
+
+    leftNav = rightNav = '';
+
+    if (hasLeft) {
+      leftNav = <div style={leftNavStyle} onClick={this.handlePrevClick}><i className='fa fa-fw fa-chevron-left' /></div>;
+    }
+
+    if (hasRight) {
+      rightNav = <div style={rightNavStyle} onClick={this.handleNextClick}><i className='fa fa-fw fa-chevron-right' /></div>;
+    }
 
     return (
       <Lightbox {...other}>
+        {leftNav}
+
         <ImageLoader
           src={url}
           preloader={preloader}
           imgProps={{ style: imageStyle }}
         />
+
+        {rightNav}
       </Lightbox>
     );
   }
diff --git a/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx b/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx
index 8af7b0c3c..100989d22 100644
--- a/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx
+++ b/app/assets/javascripts/components/features/ui/containers/status_list_container.jsx
@@ -7,8 +7,9 @@ import { createSelector } from 'reselect';
 const getStatusIds = createSelector([
   (state, { type }) => state.getIn(['settings', type], Immutable.Map()),
   (state, { type }) => state.getIn(['timelines', type, 'items'], Immutable.List()),
-  (state)           => state.get('statuses')
-], (columnSettings, statusIds, statuses) => statusIds.filter(id => {
+  (state)           => state.get('statuses'),
+  (state)           => state.getIn(['meta', 'me'])
+], (columnSettings, statusIds, statuses, me) => statusIds.filter(id => {
   const statusForId = statuses.get(id);
   let showStatus    = true;
 
@@ -17,7 +18,7 @@ const getStatusIds = createSelector([
   }
 
   if (columnSettings.getIn(['shows', 'reply']) === false) {
-    showStatus = showStatus && statusForId.get('in_reply_to_id') === null;
+    showStatus = showStatus && (statusForId.get('in_reply_to_id') === null || statusForId.get('in_reply_to_account_id') === me);
   }
 
   if (columnSettings.getIn(['regex', 'body'], '').trim().length > 0) {