about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/features/ui/containers
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/flavours/glitch/features/ui/containers')
-rw-r--r--app/javascript/flavours/glitch/features/ui/containers/bundle_container.js19
-rw-r--r--app/javascript/flavours/glitch/features/ui/containers/columns_area_container.js18
-rw-r--r--app/javascript/flavours/glitch/features/ui/containers/loading_bar_container.js8
-rw-r--r--app/javascript/flavours/glitch/features/ui/containers/modal_container.js16
-rw-r--r--app/javascript/flavours/glitch/features/ui/containers/notifications_container.js29
-rw-r--r--app/javascript/flavours/glitch/features/ui/containers/status_list_container.js88
6 files changed, 178 insertions, 0 deletions
diff --git a/app/javascript/flavours/glitch/features/ui/containers/bundle_container.js b/app/javascript/flavours/glitch/features/ui/containers/bundle_container.js
new file mode 100644
index 000000000..c9086c9bc
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/ui/containers/bundle_container.js
@@ -0,0 +1,19 @@
+import { connect } from 'react-redux';
+
+import Bundle from '../components/bundle';
+
+import { fetchBundleRequest, fetchBundleSuccess, fetchBundleFail } from 'flavours/glitch/actions/bundles';
+
+const mapDispatchToProps = dispatch => ({
+  onFetch () {
+    dispatch(fetchBundleRequest());
+  },
+  onFetchSuccess () {
+    dispatch(fetchBundleSuccess());
+  },
+  onFetchFail (error) {
+    dispatch(fetchBundleFail(error));
+  },
+});
+
+export default connect(null, mapDispatchToProps)(Bundle);
diff --git a/app/javascript/flavours/glitch/features/ui/containers/columns_area_container.js b/app/javascript/flavours/glitch/features/ui/containers/columns_area_container.js
new file mode 100644
index 000000000..b69842cd6
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/ui/containers/columns_area_container.js
@@ -0,0 +1,18 @@
+import { connect } from 'react-redux';
+import ColumnsArea from '../components/columns_area';
+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 => ({
+  openSettings (e) {
+    e.preventDefault();
+    e.stopPropagation();
+    dispatch(openModal('SETTINGS', {}));
+  },
+});
+
+export default connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true })(ColumnsArea);
diff --git a/app/javascript/flavours/glitch/features/ui/containers/loading_bar_container.js b/app/javascript/flavours/glitch/features/ui/containers/loading_bar_container.js
new file mode 100644
index 000000000..63e994f92
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/ui/containers/loading_bar_container.js
@@ -0,0 +1,8 @@
+import { connect }    from 'react-redux';
+import LoadingBar from 'react-redux-loading-bar';
+
+const mapStateToProps = (state, ownProps) => ({
+  loading: state.get('loadingBar')[ownProps.scope || 'default'],
+});
+
+export default connect(mapStateToProps)(LoadingBar.WrappedComponent);
diff --git a/app/javascript/flavours/glitch/features/ui/containers/modal_container.js b/app/javascript/flavours/glitch/features/ui/containers/modal_container.js
new file mode 100644
index 000000000..f074002e4
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/ui/containers/modal_container.js
@@ -0,0 +1,16 @@
+import { connect } from 'react-redux';
+import { closeModal } from 'flavours/glitch/actions/modal';
+import ModalRoot from '../components/modal_root';
+
+const mapStateToProps = state => ({
+  type: state.get('modal').modalType,
+  props: state.get('modal').modalProps,
+});
+
+const mapDispatchToProps = dispatch => ({
+  onClose () {
+    dispatch(closeModal());
+  },
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(ModalRoot);
diff --git a/app/javascript/flavours/glitch/features/ui/containers/notifications_container.js b/app/javascript/flavours/glitch/features/ui/containers/notifications_container.js
new file mode 100644
index 000000000..82278a3be
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/ui/containers/notifications_container.js
@@ -0,0 +1,29 @@
+import { injectIntl } from 'react-intl';
+import { connect } from 'react-redux';
+import { NotificationStack } from 'react-notification';
+import { dismissAlert } from 'flavours/glitch/actions/alerts';
+import { getAlerts } from 'flavours/glitch/selectors';
+
+const mapStateToProps = (state, { intl }) => {
+  const notifications = getAlerts(state);
+
+  notifications.forEach(notification => ['title', 'message'].forEach(key => {
+    const value = notification[key];
+
+    if (typeof value === 'object') {
+      notification[key] = intl.formatMessage(value, notification[`${key}_values`]);
+    }
+  }));
+
+  return { notifications };
+};
+
+const mapDispatchToProps = (dispatch) => {
+  return {
+    onDismiss: alert => {
+      dispatch(dismissAlert(alert));
+    },
+  };
+};
+
+export default injectIntl(connect(mapStateToProps, mapDispatchToProps)(NotificationStack));
diff --git a/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js b/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js
new file mode 100644
index 000000000..bd2d2eb4e
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/ui/containers/status_list_container.js
@@ -0,0 +1,88 @@
+import { connect } from 'react-redux';
+import StatusList from 'flavours/glitch/components/status_list';
+import { scrollTopTimeline, loadPending } from 'flavours/glitch/actions/timelines';
+import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
+import { createSelector } from 'reselect';
+import { debounce } from 'lodash';
+import { me } from 'flavours/glitch/util/initial_state';
+
+const getRegex = createSelector([
+  (state, { type }) => state.getIn(['settings', type, 'regex', 'body']),
+], (rawRegex) => {
+  let regex = null;
+
+  try {
+    regex = rawRegex && new RegExp(rawRegex.trim(), 'i');
+  } catch (e) {
+    // Bad regex, don't affect filters
+  }
+  return regex;
+});
+
+const makeGetStatusIds = (pending = false) => createSelector([
+  (state, { type }) => state.getIn(['settings', type], ImmutableMap()),
+  (state, { type }) => state.getIn(['timelines', type, pending ? 'pendingItems' : 'items'], ImmutableList()),
+  (state)           => state.get('statuses'),
+  getRegex,
+], (columnSettings, statusIds, statuses, regex) => {
+  const rawRegex = columnSettings.getIn(['regex', 'body'], '').trim();
+
+  return statusIds.filter(id => {
+    if (id === null) return true;
+
+    const statusForId = statuses.get(id);
+    let showStatus    = true;
+
+    if (statusForId.get('account') === me) return true;
+
+    if (columnSettings.getIn(['shows', 'reblog']) === false) {
+      showStatus = showStatus && statusForId.get('reblog') === null;
+    }
+
+    if (columnSettings.getIn(['shows', 'reply']) === false) {
+      showStatus = showStatus && (statusForId.get('in_reply_to_id') === null || statusForId.get('in_reply_to_account_id') === me);
+    }
+
+    if (columnSettings.getIn(['shows', 'direct']) === false) {
+      showStatus = showStatus && statusForId.get('visibility') !== 'direct';
+    }
+
+    if (showStatus && regex) {
+      const searchIndex = statusForId.get('reblog') ? statuses.getIn([statusForId.get('reblog'), 'search_index']) : statusForId.get('search_index');
+      showStatus = !regex.test(searchIndex);
+    }
+
+    return showStatus;
+  });
+});
+
+const makeMapStateToProps = () => {
+  const getStatusIds = makeGetStatusIds();
+  const getPendingStatusIds = makeGetStatusIds(true);
+
+  const mapStateToProps = (state, { timelineId }) => ({
+    statusIds: getStatusIds(state, { type: timelineId }),
+    isLoading: state.getIn(['timelines', timelineId, 'isLoading'], true),
+    isPartial: state.getIn(['timelines', timelineId, 'isPartial'], false),
+    hasMore:   state.getIn(['timelines', timelineId, 'hasMore']),
+    numPending: getPendingStatusIds(state, { type: timelineId }).size,
+  });
+
+  return mapStateToProps;
+};
+
+const mapDispatchToProps = (dispatch, { timelineId }) => ({
+
+  onScrollToTop: debounce(() => {
+    dispatch(scrollTopTimeline(timelineId, true));
+  }, 100),
+
+  onScroll: debounce(() => {
+    dispatch(scrollTopTimeline(timelineId, false));
+  }, 100),
+
+  onLoadPending: () => dispatch(loadPending(timelineId)),
+
+});
+
+export default connect(makeMapStateToProps, mapDispatchToProps)(StatusList);