From 1f650d327d35bc48b897da99914c43750d8e5fd3 Mon Sep 17 00:00:00 2001
From: Eugen Rochko <eugen@zeonfederated.com>
Date: Fri, 7 Oct 2016 16:00:11 +0200
Subject: Adding public timeline

---
 .../components/features/public_timeline/index.jsx  | 103 +++++++++++++++++++++
 1 file changed, 103 insertions(+)
 create mode 100644 app/assets/javascripts/components/features/public_timeline/index.jsx

(limited to 'app/assets/javascripts/components/features/public_timeline/index.jsx')

diff --git a/app/assets/javascripts/components/features/public_timeline/index.jsx b/app/assets/javascripts/components/features/public_timeline/index.jsx
new file mode 100644
index 000000000..dd31dc115
--- /dev/null
+++ b/app/assets/javascripts/components/features/public_timeline/index.jsx
@@ -0,0 +1,103 @@
+import { connect }        from 'react-redux';
+import PureRenderMixin    from 'react-addons-pure-render-mixin';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import StatusList         from '../../components/status_list';
+import Column             from '../ui/components/column';
+import Immutable          from 'immutable';
+import { selectStatus }   from '../../reducers/timelines';
+import {
+  updateTimeline,
+  refreshTimeline,
+  expandTimeline
+}                         from '../../actions/timelines';
+import { deleteStatus }   from '../../actions/statuses';
+import { replyCompose }   from '../../actions/compose';
+import {
+  favourite,
+  reblog,
+  unreblog,
+  unfavourite
+}                         from '../../actions/interactions';
+
+function selectStatuses(state) {
+  return state.getIn(['timelines', 'public'], Immutable.List()).map(id => selectStatus(state, id)).filterNot(status => status === null);
+};
+
+const mapStateToProps = (state) => ({
+  statuses: selectStatuses(state),
+  me: state.getIn(['timelines', 'me'])
+});
+
+const PublicTimeline = React.createClass({
+
+  propTypes: {
+    statuses: ImmutablePropTypes.list.isRequired,
+    me: React.PropTypes.number.isRequired,
+    dispatch: React.PropTypes.func.isRequired
+  },
+
+  mixins: [PureRenderMixin],
+
+  componentWillMount () {
+    const { dispatch } = this.props;
+
+    dispatch(refreshTimeline('public'));
+
+    if (typeof App !== 'undefined') {
+      this.subscription = App.cable.subscriptions.create('PublicChannel', {
+
+        received (data) {
+          dispatch(updateTimeline('public', JSON.parse(data.message)));
+        }
+
+      });
+    }
+  },
+
+  componentWillUnmount () {
+    if (typeof this.subscription !== 'undefined') {
+      this.subscription.unsubscribe();
+    }
+  },
+
+  handleReply (status) {
+    this.props.dispatch(replyCompose(status));
+  },
+
+  handleReblog (status) {
+    if (status.get('reblogged')) {
+      this.props.dispatch(unreblog(status));
+    } else {
+      this.props.dispatch(reblog(status));
+    }
+  },
+
+  handleFavourite (status) {
+    if (status.get('favourited')) {
+      this.props.dispatch(unfavourite(status));
+    } else {
+      this.props.dispatch(favourite(status));
+    }
+  },
+
+  handleDelete (status) {
+    this.props.dispatch(deleteStatus(status.get('id')));
+  },
+
+  handleScrollToBottom () {
+    this.props.dispatch(expandTimeline('public'));
+  },
+
+  render () {
+    const { statuses, me } = this.props;
+
+    return (
+      <Column icon='globe' heading='Public'>
+        <StatusList statuses={statuses} me={me} onScrollToBottom={this.handleScrollToBottom} onReply={this.handleReply} onReblog={this.handleReblog} onFavourite={this.handleFavourite} onDelete={this.handleDelete} />
+      </Column>
+    );
+  },
+
+});
+
+export default connect(mapStateToProps)(PublicTimeline);
-- 
cgit 

