about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/actions
diff options
context:
space:
mode:
authorStarfall <root@starfall.blue>2020-02-04 17:44:29 -0600
committerStarfall <root@starfall.blue>2020-02-04 17:44:29 -0600
commit6d24d3bcb84abd04f31da95f97f6d60ef0afdc00 (patch)
treee7c38251a9e92bdf3a464b4aa7f1880aa5139bf0 /app/javascript/flavours/glitch/actions
parentc0c9529df269816f52915a9802e5e30fbce9576b (diff)
parent885e9227c6e8e1ce5e4a5625d5126ba76dce2c00 (diff)
Merge branch 'glitch'
Diffstat (limited to 'app/javascript/flavours/glitch/actions')
-rw-r--r--app/javascript/flavours/glitch/actions/announcements.js180
-rw-r--r--app/javascript/flavours/glitch/actions/compose.js2
-rw-r--r--app/javascript/flavours/glitch/actions/importer/normalizer.js10
-rw-r--r--app/javascript/flavours/glitch/actions/markers.js46
-rw-r--r--app/javascript/flavours/glitch/actions/notifications.js3
-rw-r--r--app/javascript/flavours/glitch/actions/streaming.js19
-rw-r--r--app/javascript/flavours/glitch/actions/timelines.js2
7 files changed, 256 insertions, 6 deletions
diff --git a/app/javascript/flavours/glitch/actions/announcements.js b/app/javascript/flavours/glitch/actions/announcements.js
new file mode 100644
index 000000000..871409d43
--- /dev/null
+++ b/app/javascript/flavours/glitch/actions/announcements.js
@@ -0,0 +1,180 @@
+import api from 'flavours/glitch/util/api';
+import { normalizeAnnouncement } from './importer/normalizer';
+
+export const ANNOUNCEMENTS_FETCH_REQUEST = 'ANNOUNCEMENTS_FETCH_REQUEST';
+export const ANNOUNCEMENTS_FETCH_SUCCESS = 'ANNOUNCEMENTS_FETCH_SUCCESS';
+export const ANNOUNCEMENTS_FETCH_FAIL    = 'ANNOUNCEMENTS_FETCH_FAIL';
+export const ANNOUNCEMENTS_UPDATE        = 'ANNOUNCEMENTS_UPDATE';
+export const ANNOUNCEMENTS_DELETE        = 'ANNOUNCEMENTS_DELETE';
+
+export const ANNOUNCEMENTS_DISMISS_REQUEST = 'ANNOUNCEMENTS_DISMISS_REQUEST';
+export const ANNOUNCEMENTS_DISMISS_SUCCESS = 'ANNOUNCEMENTS_DISMISS_SUCCESS';
+export const ANNOUNCEMENTS_DISMISS_FAIL    = 'ANNOUNCEMENTS_DISMISS_FAIL';
+
+export const ANNOUNCEMENTS_REACTION_ADD_REQUEST = 'ANNOUNCEMENTS_REACTION_ADD_REQUEST';
+export const ANNOUNCEMENTS_REACTION_ADD_SUCCESS = 'ANNOUNCEMENTS_REACTION_ADD_SUCCESS';
+export const ANNOUNCEMENTS_REACTION_ADD_FAIL    = 'ANNOUNCEMENTS_REACTION_ADD_FAIL';
+
+export const ANNOUNCEMENTS_REACTION_REMOVE_REQUEST = 'ANNOUNCEMENTS_REACTION_REMOVE_REQUEST';
+export const ANNOUNCEMENTS_REACTION_REMOVE_SUCCESS = 'ANNOUNCEMENTS_REACTION_REMOVE_SUCCESS';
+export const ANNOUNCEMENTS_REACTION_REMOVE_FAIL    = 'ANNOUNCEMENTS_REACTION_REMOVE_FAIL';
+
+export const ANNOUNCEMENTS_REACTION_UPDATE = 'ANNOUNCEMENTS_REACTION_UPDATE';
+
+export const ANNOUNCEMENTS_TOGGLE_SHOW = 'ANNOUNCEMENTS_TOGGLE_SHOW';
+
+const noOp = () => {};
+
+export const fetchAnnouncements = (done = noOp) => (dispatch, getState) => {
+  dispatch(fetchAnnouncementsRequest());
+
+  api(getState).get('/api/v1/announcements').then(response => {
+    dispatch(fetchAnnouncementsSuccess(response.data.map(x => normalizeAnnouncement(x))));
+  }).catch(error => {
+    dispatch(fetchAnnouncementsFail(error));
+  }).finally(() => {
+    done();
+  });
+};
+
+export const fetchAnnouncementsRequest = () => ({
+  type: ANNOUNCEMENTS_FETCH_REQUEST,
+  skipLoading: true,
+});
+
+export const fetchAnnouncementsSuccess = announcements => ({
+  type: ANNOUNCEMENTS_FETCH_SUCCESS,
+  announcements,
+  skipLoading: true,
+});
+
+export const fetchAnnouncementsFail= error => ({
+  type: ANNOUNCEMENTS_FETCH_FAIL,
+  error,
+  skipLoading: true,
+  skipAlert: true,
+});
+
+export const updateAnnouncements = announcement => ({
+  type: ANNOUNCEMENTS_UPDATE,
+  announcement: normalizeAnnouncement(announcement),
+});
+
+export const dismissAnnouncement = announcementId => (dispatch, getState) => {
+  dispatch(dismissAnnouncementRequest(announcementId));
+
+  api(getState).post(`/api/v1/announcements/${announcementId}/dismiss`).then(() => {
+    dispatch(dismissAnnouncementSuccess(announcementId));
+  }).catch(error => {
+    dispatch(dismissAnnouncementFail(announcementId, error));
+  });
+};
+
+export const dismissAnnouncementRequest = announcementId => ({
+  type: ANNOUNCEMENTS_DISMISS_REQUEST,
+  id: announcementId,
+});
+
+export const dismissAnnouncementSuccess = announcementId => ({
+  type: ANNOUNCEMENTS_DISMISS_SUCCESS,
+  id: announcementId,
+});
+
+export const dismissAnnouncementFail = (announcementId, error) => ({
+  type: ANNOUNCEMENTS_DISMISS_FAIL,
+  id: announcementId,
+  error,
+});
+
+export const addReaction = (announcementId, name) => (dispatch, getState) => {
+  const announcement = getState().getIn(['announcements', 'items']).find(x => x.get('id') === announcementId);
+
+  let alreadyAdded = false;
+
+  if (announcement) {
+    const reaction = announcement.get('reactions').find(x => x.get('name') === name);
+    if (reaction && reaction.get('me')) {
+      alreadyAdded = true;
+    }
+  }
+
+  if (!alreadyAdded) {
+    dispatch(addReactionRequest(announcementId, name, alreadyAdded));
+  }
+
+  api(getState).put(`/api/v1/announcements/${announcementId}/reactions/${name}`).then(() => {
+    dispatch(addReactionSuccess(announcementId, name, alreadyAdded));
+  }).catch(err => {
+    if (!alreadyAdded) {
+      dispatch(addReactionFail(announcementId, name, err));
+    }
+  });
+};
+
+export const addReactionRequest = (announcementId, name) => ({
+  type: ANNOUNCEMENTS_REACTION_ADD_REQUEST,
+  id: announcementId,
+  name,
+  skipLoading: true,
+});
+
+export const addReactionSuccess = (announcementId, name) => ({
+  type: ANNOUNCEMENTS_REACTION_ADD_SUCCESS,
+  id: announcementId,
+  name,
+  skipLoading: true,
+});
+
+export const addReactionFail = (announcementId, name, error) => ({
+  type: ANNOUNCEMENTS_REACTION_ADD_FAIL,
+  id: announcementId,
+  name,
+  error,
+  skipLoading: true,
+});
+
+export const removeReaction = (announcementId, name) => (dispatch, getState) => {
+  dispatch(removeReactionRequest(announcementId, name));
+
+  api(getState).delete(`/api/v1/announcements/${announcementId}/reactions/${name}`).then(() => {
+    dispatch(removeReactionSuccess(announcementId, name));
+  }).catch(err => {
+    dispatch(removeReactionFail(announcementId, name, err));
+  });
+};
+
+export const removeReactionRequest = (announcementId, name) => ({
+  type: ANNOUNCEMENTS_REACTION_REMOVE_REQUEST,
+  id: announcementId,
+  name,
+  skipLoading: true,
+});
+
+export const removeReactionSuccess = (announcementId, name) => ({
+  type: ANNOUNCEMENTS_REACTION_REMOVE_SUCCESS,
+  id: announcementId,
+  name,
+  skipLoading: true,
+});
+
+export const removeReactionFail = (announcementId, name, error) => ({
+  type: ANNOUNCEMENTS_REACTION_REMOVE_FAIL,
+  id: announcementId,
+  name,
+  error,
+  skipLoading: true,
+});
+
+export const updateReaction = reaction => ({
+  type: ANNOUNCEMENTS_REACTION_UPDATE,
+  reaction,
+});
+
+export const toggleShowAnnouncements = () => ({
+  type: ANNOUNCEMENTS_TOGGLE_SHOW,
+});
+
+export const deleteAnnouncement = id => ({
+  type: ANNOUNCEMENTS_DELETE,
+  id,
+});
diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js
index f80642bd8..0be746048 100644
--- a/app/javascript/flavours/glitch/actions/compose.js
+++ b/app/javascript/flavours/glitch/actions/compose.js
@@ -91,9 +91,11 @@ export function cycleElefriendCompose() {
 
 export function replyCompose(status, routerHistory) {
   return (dispatch, getState) => {
+    const prependCWRe = getState().getIn(['local_settings', 'prepend_cw_re']);
     dispatch({
       type: COMPOSE_REPLY,
       status: status,
+      prependCWRe: prependCWRe,
     });
 
     ensureComposeIsVisible(getState, routerHistory);
diff --git a/app/javascript/flavours/glitch/actions/importer/normalizer.js b/app/javascript/flavours/glitch/actions/importer/normalizer.js
index 2bc603930..52ad17779 100644
--- a/app/javascript/flavours/glitch/actions/importer/normalizer.js
+++ b/app/javascript/flavours/glitch/actions/importer/normalizer.js
@@ -74,7 +74,6 @@ export function normalizeStatus(status, normalOldStatus) {
 
 export function normalizePoll(poll) {
   const normalPoll = { ...poll };
-
   const emojiMap = makeEmojiMap(normalPoll);
 
   normalPoll.options = poll.options.map((option, index) => ({
@@ -85,3 +84,12 @@ export function normalizePoll(poll) {
 
   return normalPoll;
 }
+
+export function normalizeAnnouncement(announcement) {
+  const normalAnnouncement = { ...announcement };
+  const emojiMap = makeEmojiMap(normalAnnouncement);
+
+  normalAnnouncement.contentHtml = emojify(normalAnnouncement.content, emojiMap);
+
+  return normalAnnouncement;
+}
diff --git a/app/javascript/flavours/glitch/actions/markers.js b/app/javascript/flavours/glitch/actions/markers.js
index c3a5fe86f..7ffab404d 100644
--- a/app/javascript/flavours/glitch/actions/markers.js
+++ b/app/javascript/flavours/glitch/actions/markers.js
@@ -1,9 +1,15 @@
+import api from 'flavours/glitch/util/api';
+
+export const MARKERS_FETCH_REQUEST = 'MARKERS_FETCH_REQUEST';
+export const MARKERS_FETCH_SUCCESS = 'MARKERS_FETCH_SUCCESS';
+export const MARKERS_FETCH_FAIL    = 'MARKERS_FETCH_FAIL';
+
 export const submitMarkers = () => (dispatch, getState) => {
   const accessToken = getState().getIn(['meta', 'access_token'], '');
   const params      = {};
 
   const lastHomeId         = getState().getIn(['timelines', 'home', 'items', 0]);
-  const lastNotificationId = getState().getIn(['notifications', 'items', 0, 'id']);
+  const lastNotificationId = getState().getIn(['notifications', 'lastReadId']);
 
   if (lastHomeId) {
     params.home = {
@@ -11,7 +17,7 @@ export const submitMarkers = () => (dispatch, getState) => {
     };
   }
 
-  if (lastNotificationId) {
+  if (lastNotificationId && lastNotificationId !== '0') {
     params.notifications = {
       last_read_id: lastNotificationId,
     };
@@ -28,3 +34,39 @@ export const submitMarkers = () => (dispatch, getState) => {
   client.setRequestHeader('Authorization', `Bearer ${accessToken}`);
   client.send(JSON.stringify(params));
 };
+
+export const fetchMarkers = () => (dispatch, getState) => {
+    const params = { timeline: ['notifications'] };
+
+    dispatch(fetchMarkersRequest());
+
+    api(getState).get('/api/v1/markers', { params }).then(response => {
+      dispatch(fetchMarkersSuccess(response.data));
+    }).catch(error => {
+      dispatch(fetchMarkersFail(error));
+    });
+};
+
+export function fetchMarkersRequest() {
+  return {
+    type: MARKERS_FETCH_REQUEST,
+    skipLoading: true,
+  };
+};
+
+export function fetchMarkersSuccess(markers) {
+  return {
+    type: MARKERS_FETCH_SUCCESS,
+    markers,
+    skipLoading: true,
+  };
+};
+
+export function fetchMarkersFail(error) {
+  return {
+    type: MARKERS_FETCH_FAIL,
+    error,
+    skipLoading: true,
+    skipAlert: true,
+  };
+};
diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js
index 940f3c3d4..b3de7b5bf 100644
--- a/app/javascript/flavours/glitch/actions/notifications.js
+++ b/app/javascript/flavours/glitch/actions/notifications.js
@@ -168,9 +168,9 @@ export function expandNotifications({ maxId } = {}, done = noOp) {
 
       dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore, isLoadingRecent, isLoadingRecent && preferPendingItems));
       fetchRelatedRelationships(dispatch, response.data);
-      done();
     }).catch(error => {
       dispatch(expandNotificationsFail(error, isLoadingMore));
+    }).finally(() => {
       done();
     });
   };
@@ -199,6 +199,7 @@ export function expandNotificationsFail(error, isLoadingMore) {
     type: NOTIFICATIONS_EXPAND_FAIL,
     error,
     skipLoading: !isLoadingMore,
+    skipAlert: !isLoadingMore,
   };
 };
 
diff --git a/app/javascript/flavours/glitch/actions/streaming.js b/app/javascript/flavours/glitch/actions/streaming.js
index 21379f492..2f82ea805 100644
--- a/app/javascript/flavours/glitch/actions/streaming.js
+++ b/app/javascript/flavours/glitch/actions/streaming.js
@@ -8,6 +8,12 @@ import {
 } from './timelines';
 import { updateNotifications, expandNotifications } from './notifications';
 import { updateConversations } from './conversations';
+import {
+  fetchAnnouncements,
+  updateAnnouncements,
+  updateReaction as updateAnnouncementsReaction,
+  deleteAnnouncement,
+} from './announcements';
 import { fetchFilters } from './filters';
 import { getLocale } from 'mastodon/locales';
 
@@ -44,6 +50,15 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null,
         case 'filters_changed':
           dispatch(fetchFilters());
           break;
+        case 'announcement':
+          dispatch(updateAnnouncements(JSON.parse(data.payload)));
+          break;
+        case 'announcement.reaction':
+          dispatch(updateAnnouncementsReaction(JSON.parse(data.payload)));
+          break;
+        case 'announcement.delete':
+          dispatch(deleteAnnouncement(data.payload));
+          break;
         }
       },
     };
@@ -51,7 +66,9 @@ export function connectTimelineStream (timelineId, path, pollingRefresh = null,
 }
 
 const refreshHomeTimelineAndNotification = (dispatch, done) => {
-  dispatch(expandHomeTimeline({}, () => dispatch(expandNotifications({}, done))));
+  dispatch(expandHomeTimeline({}, () =>
+    dispatch(expandNotifications({}, () =>
+      dispatch(fetchAnnouncements(done))))));
 };
 
 export const connectUserStream      = () => connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification);
diff --git a/app/javascript/flavours/glitch/actions/timelines.js b/app/javascript/flavours/glitch/actions/timelines.js
index 097878c3b..2ef78025e 100644
--- a/app/javascript/flavours/glitch/actions/timelines.js
+++ b/app/javascript/flavours/glitch/actions/timelines.js
@@ -112,9 +112,9 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
 
       dispatch(importFetchedStatuses(response.data));
       dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.status === 206, isLoadingRecent, isLoadingMore, isLoadingRecent && preferPendingItems));
-      done();
     }).catch(error => {
       dispatch(expandTimelineFail(timelineId, error, isLoadingMore));
+    }).finally(() => {
       done();
     });
   };