about summary refs log tree commit diff
path: root/app/javascript/mastodon/actions/notifications.js
diff options
context:
space:
mode:
authorEugen Rochko <eugen@zeonfederated.com>2017-05-03 02:04:16 +0200
committerGitHub <noreply@github.com>2017-05-03 02:04:16 +0200
commitf5bf5ebb82e3af420dcd23d602b1be6cc86838e1 (patch)
tree92eef08642a038cf44ccbc6d16a884293e7a0814 /app/javascript/mastodon/actions/notifications.js
parent26bc5915727e0a0173c03cb49f5193dd612fb888 (diff)
Replace sprockets/browserify with Webpack (#2617)
* Replace browserify with webpack

* Add react-intl-translations-manager

* Do not minify in development, add offline-plugin for ServiceWorker background cache updates

* Adjust tests and dependencies

* Fix production deployments

* Fix tests

* More optimizations

* Improve travis cache for npm stuff

* Re-run travis

* Add back support for custom.scss as before

* Remove offline-plugin and babili

* Fix issue with Immutable.List().unshift(...values) not working as expected

* Make travis load schema instead of running all migrations in sequence

* Fix missing React import in WarningContainer. Optimize rendering performance by using ImmutablePureComponent instead of
React.PureComponent. ImmutablePureComponent uses Immutable.is() to compare props. Replace dynamic callback bindings in
<UI />

* Add react definitions to places that use JSX

* Add Procfile.dev for running rails, webpack and streaming API at the same time
Diffstat (limited to 'app/javascript/mastodon/actions/notifications.js')
-rw-r--r--app/javascript/mastodon/actions/notifications.js165
1 files changed, 165 insertions, 0 deletions
diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js
new file mode 100644
index 000000000..b09ca0854
--- /dev/null
+++ b/app/javascript/mastodon/actions/notifications.js
@@ -0,0 +1,165 @@
+import api, { getLinks } from '../api'
+import Immutable from 'immutable';
+import IntlMessageFormat from 'intl-messageformat';
+
+import { fetchRelationships } from './accounts';
+
+export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE';
+
+export const NOTIFICATIONS_REFRESH_REQUEST = 'NOTIFICATIONS_REFRESH_REQUEST';
+export const NOTIFICATIONS_REFRESH_SUCCESS = 'NOTIFICATIONS_REFRESH_SUCCESS';
+export const NOTIFICATIONS_REFRESH_FAIL    = 'NOTIFICATIONS_REFRESH_FAIL';
+
+export const NOTIFICATIONS_EXPAND_REQUEST = 'NOTIFICATIONS_EXPAND_REQUEST';
+export const NOTIFICATIONS_EXPAND_SUCCESS = 'NOTIFICATIONS_EXPAND_SUCCESS';
+export const NOTIFICATIONS_EXPAND_FAIL    = 'NOTIFICATIONS_EXPAND_FAIL';
+
+export const NOTIFICATIONS_CLEAR      = 'NOTIFICATIONS_CLEAR';
+export const NOTIFICATIONS_SCROLL_TOP = 'NOTIFICATIONS_SCROLL_TOP';
+
+const fetchRelatedRelationships = (dispatch, notifications) => {
+  const accountIds = notifications.filter(item => item.type === 'follow').map(item => item.account.id);
+
+  if (accountIds > 0) {
+    dispatch(fetchRelationships(accountIds));
+  }
+};
+
+export function updateNotifications(notification, intlMessages, intlLocale) {
+  return (dispatch, getState) => {
+    const showAlert = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true);
+    const playSound = getState().getIn(['settings', 'notifications', 'sounds', notification.type], true);
+
+    dispatch({
+      type: NOTIFICATIONS_UPDATE,
+      notification,
+      account: notification.account,
+      status: notification.status,
+      meta: playSound ? { sound: 'boop' } : undefined
+    });
+
+    fetchRelatedRelationships(dispatch, [notification]);
+
+    // Desktop notifications
+    if (typeof window.Notification !== 'undefined' && showAlert) {
+      const title = new IntlMessageFormat(intlMessages[`notification.${notification.type}`], intlLocale).format({ name: notification.account.display_name.length > 0 ? notification.account.display_name : notification.account.username });
+      const body  = (notification.status && notification.status.spoiler_text.length > 0) ? notification.status.spoiler_text : $('<p>').html(notification.status ? notification.status.content : '').text();
+
+      new Notification(title, { body, icon: notification.account.avatar, tag: notification.id });
+    }
+  };
+};
+
+const excludeTypesFromSettings = state => state.getIn(['settings', 'notifications', 'shows']).filter(enabled => !enabled).keySeq().toJS();
+
+export function refreshNotifications() {
+  return (dispatch, getState) => {
+    dispatch(refreshNotificationsRequest());
+
+    const params = {};
+    const ids    = getState().getIn(['notifications', 'items']);
+
+    if (ids.size > 0) {
+      params.since_id = ids.first().get('id');
+    }
+
+    params.exclude_types = excludeTypesFromSettings(getState());
+
+    api(getState).get('/api/v1/notifications', { params }).then(response => {
+      const next = getLinks(response).refs.find(link => link.rel === 'next');
+
+      dispatch(refreshNotificationsSuccess(response.data, next ? next.uri : null));
+      fetchRelatedRelationships(dispatch, response.data);
+    }).catch(error => {
+      dispatch(refreshNotificationsFail(error));
+    });
+  };
+};
+
+export function refreshNotificationsRequest() {
+  return {
+    type: NOTIFICATIONS_REFRESH_REQUEST
+  };
+};
+
+export function refreshNotificationsSuccess(notifications, next) {
+  return {
+    type: NOTIFICATIONS_REFRESH_SUCCESS,
+    notifications,
+    accounts: notifications.map(item => item.account),
+    statuses: notifications.map(item => item.status).filter(status => !!status),
+    next
+  };
+};
+
+export function refreshNotificationsFail(error) {
+  return {
+    type: NOTIFICATIONS_REFRESH_FAIL,
+    error
+  };
+};
+
+export function expandNotifications() {
+  return (dispatch, getState) => {
+    const url = getState().getIn(['notifications', 'next'], null);
+
+    if (url === null || getState().getIn(['notifications', 'isLoading'])) {
+      return;
+    }
+
+    dispatch(expandNotificationsRequest());
+
+    const params = {};
+
+    params.exclude_types = excludeTypesFromSettings(getState());
+
+    api(getState).get(url, params).then(response => {
+      const next = getLinks(response).refs.find(link => link.rel === 'next');
+
+      dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null));
+      fetchRelatedRelationships(dispatch, response.data);
+    }).catch(error => {
+      dispatch(expandNotificationsFail(error));
+    });
+  };
+};
+
+export function expandNotificationsRequest() {
+  return {
+    type: NOTIFICATIONS_EXPAND_REQUEST
+  };
+};
+
+export function expandNotificationsSuccess(notifications, next) {
+  return {
+    type: NOTIFICATIONS_EXPAND_SUCCESS,
+    notifications,
+    accounts: notifications.map(item => item.account),
+    statuses: notifications.map(item => item.status).filter(status => !!status),
+    next
+  };
+};
+
+export function expandNotificationsFail(error) {
+  return {
+    type: NOTIFICATIONS_EXPAND_FAIL,
+    error
+  };
+};
+
+export function clearNotifications() {
+  return (dispatch, getState) => {
+    dispatch({
+      type: NOTIFICATIONS_CLEAR
+    });
+
+    api(getState).post('/api/v1/notifications/clear');
+  };
+};
+
+export function scrollTopNotifications(top) {
+  return {
+    type: NOTIFICATIONS_SCROLL_TOP,
+    top
+  };
+};