about summary refs log tree commit diff
path: root/app/javascript/mastodon/actions
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/mastodon/actions')
-rw-r--r--app/javascript/mastodon/actions/accounts.js10
-rw-r--r--app/javascript/mastodon/actions/compose.js26
-rw-r--r--app/javascript/mastodon/actions/notifications.js75
-rw-r--r--app/javascript/mastodon/actions/streaming.js1
-rw-r--r--app/javascript/mastodon/actions/timelines.js2
5 files changed, 108 insertions, 6 deletions
diff --git a/app/javascript/mastodon/actions/accounts.js b/app/javascript/mastodon/actions/accounts.js
index fbaebf786..f63325658 100644
--- a/app/javascript/mastodon/actions/accounts.js
+++ b/app/javascript/mastodon/actions/accounts.js
@@ -105,12 +105,13 @@ export function fetchAccountFail(id, error) {
   };
 };
 
-export function followAccount(id) {
+export function followAccount(id, reblogs = true) {
   return (dispatch, getState) => {
+    const alreadyFollowing = getState().getIn(['relationships', id, 'following']);
     dispatch(followAccountRequest(id));
 
-    api(getState).post(`/api/v1/accounts/${id}/follow`).then(response => {
-      dispatch(followAccountSuccess(response.data));
+    api(getState).post(`/api/v1/accounts/${id}/follow`, { reblogs }).then(response => {
+      dispatch(followAccountSuccess(response.data, alreadyFollowing));
     }).catch(error => {
       dispatch(followAccountFail(error));
     });
@@ -136,10 +137,11 @@ export function followAccountRequest(id) {
   };
 };
 
-export function followAccountSuccess(relationship) {
+export function followAccountSuccess(relationship, alreadyFollowing) {
   return {
     type: ACCOUNT_FOLLOW_SUCCESS,
     relationship,
+    alreadyFollowing,
   };
 };
 
diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js
index 8a35049b3..3ee9e1e7b 100644
--- a/app/javascript/mastodon/actions/compose.js
+++ b/app/javascript/mastodon/actions/compose.js
@@ -8,6 +8,7 @@ import {
   refreshHomeTimeline,
   refreshCommunityTimeline,
   refreshPublicTimeline,
+  refreshDirectTimeline,
 } from './timelines';
 
 export const COMPOSE_CHANGE          = 'COMPOSE_CHANGE';
@@ -31,6 +32,7 @@ export const COMPOSE_SUGGESTION_SELECT = 'COMPOSE_SUGGESTION_SELECT';
 export const COMPOSE_MOUNT   = 'COMPOSE_MOUNT';
 export const COMPOSE_UNMOUNT = 'COMPOSE_UNMOUNT';
 
+export const COMPOSE_ADVANCED_OPTIONS_CHANGE = 'COMPOSE_ADVANCED_OPTIONS_CHANGE';
 export const COMPOSE_SENSITIVITY_CHANGE = 'COMPOSE_SENSITIVITY_CHANGE';
 export const COMPOSE_SPOILERNESS_CHANGE = 'COMPOSE_SPOILERNESS_CHANGE';
 export const COMPOSE_SPOILER_TEXT_CHANGE = 'COMPOSE_SPOILER_TEXT_CHANGE';
@@ -44,6 +46,8 @@ export const COMPOSE_UPLOAD_CHANGE_REQUEST     = 'COMPOSE_UPLOAD_UPDATE_REQUEST'
 export const COMPOSE_UPLOAD_CHANGE_SUCCESS     = 'COMPOSE_UPLOAD_UPDATE_SUCCESS';
 export const COMPOSE_UPLOAD_CHANGE_FAIL        = 'COMPOSE_UPLOAD_UPDATE_FAIL';
 
+export const COMPOSE_DOODLE_SET        = 'COMPOSE_DOODLE_SET';
+
 export function changeCompose(text) {
   return {
     type: COMPOSE_CHANGE,
@@ -91,14 +95,16 @@ export function mentionCompose(account, router) {
 
 export function submitCompose() {
   return function (dispatch, getState) {
-    const status = getState().getIn(['compose', 'text'], '');
+    let status = getState().getIn(['compose', 'text'], '');
 
     if (!status || !status.length) {
       return;
     }
 
     dispatch(submitComposeRequest());
-
+    if (getState().getIn(['compose', 'advanced_options', 'do_not_federate'])) {
+      status = status + ' 👁️';
+    }
     api(getState).post('/api/v1/statuses', {
       status,
       in_reply_to_id: getState().getIn(['compose', 'in_reply_to'], null),
@@ -128,6 +134,8 @@ export function submitCompose() {
       if (response.data.in_reply_to_id === null && response.data.visibility === 'public') {
         insertOrRefresh('community', refreshCommunityTimeline);
         insertOrRefresh('public', refreshPublicTimeline);
+      } else if (response.data.visibility === 'direct') {
+        insertOrRefresh('direct', refreshDirectTimeline);
       }
     }).catch(function (error) {
       dispatch(submitComposeFail(error));
@@ -155,6 +163,13 @@ export function submitComposeFail(error) {
   };
 };
 
+export function doodleSet(options) {
+  return {
+    type: COMPOSE_DOODLE_SET,
+    options: options,
+  };
+};
+
 export function uploadCompose(files) {
   return function (dispatch, getState) {
     if (getState().getIn(['compose', 'media_attachments']).size > 3) {
@@ -334,6 +349,13 @@ export function unmountCompose() {
   };
 };
 
+export function toggleComposeAdvancedOption(option) {
+  return {
+    type: COMPOSE_ADVANCED_OPTIONS_CHANGE,
+    option: option,
+  };
+}
+
 export function changeComposeSensitivity() {
   return {
     type: COMPOSE_SENSITIVITY_CHANGE,
diff --git a/app/javascript/mastodon/actions/notifications.js b/app/javascript/mastodon/actions/notifications.js
index b24ac8b73..4a4462e1d 100644
--- a/app/javascript/mastodon/actions/notifications.js
+++ b/app/javascript/mastodon/actions/notifications.js
@@ -6,6 +6,17 @@ import { defineMessages } from 'react-intl';
 
 export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE';
 
+// tracking the notif cleaning request
+export const NOTIFICATIONS_DELETE_MARKED_REQUEST = 'NOTIFICATIONS_DELETE_MARKED_REQUEST';
+export const NOTIFICATIONS_DELETE_MARKED_SUCCESS = 'NOTIFICATIONS_DELETE_MARKED_SUCCESS';
+export const NOTIFICATIONS_DELETE_MARKED_FAIL = 'NOTIFICATIONS_DELETE_MARKED_FAIL';
+export const NOTIFICATIONS_MARK_ALL_FOR_DELETE = 'NOTIFICATIONS_MARK_ALL_FOR_DELETE';
+export const NOTIFICATIONS_ENTER_CLEARING_MODE = 'NOTIFICATIONS_ENTER_CLEARING_MODE'; // arg: yes
+// Unmark notifications (when the cleaning mode is left)
+export const NOTIFICATIONS_UNMARK_ALL_FOR_DELETE = 'NOTIFICATIONS_UNMARK_ALL_FOR_DELETE';
+// Mark one for delete
+export const NOTIFICATION_MARK_FOR_DELETE = 'NOTIFICATION_MARK_FOR_DELETE';
+
 export const NOTIFICATIONS_REFRESH_REQUEST = 'NOTIFICATIONS_REFRESH_REQUEST';
 export const NOTIFICATIONS_REFRESH_SUCCESS = 'NOTIFICATIONS_REFRESH_SUCCESS';
 export const NOTIFICATIONS_REFRESH_FAIL    = 'NOTIFICATIONS_REFRESH_FAIL';
@@ -188,3 +199,67 @@ export function scrollTopNotifications(top) {
     top,
   };
 };
+
+export function deleteMarkedNotifications() {
+  return (dispatch, getState) => {
+    dispatch(deleteMarkedNotificationsRequest());
+
+    let ids = [];
+    getState().getIn(['notifications', 'items']).forEach((n) => {
+      if (n.get('markedForDelete')) {
+        ids.push(n.get('id'));
+      }
+    });
+
+    if (ids.length === 0) {
+      return;
+    }
+
+    api(getState).delete(`/api/v1/notifications/destroy_multiple?ids[]=${ids.join('&ids[]=')}`).then(() => {
+      dispatch(deleteMarkedNotificationsSuccess());
+    }).catch(error => {
+      console.error(error);
+      dispatch(deleteMarkedNotificationsFail(error));
+    });
+  };
+};
+
+export function enterNotificationClearingMode(yes) {
+  return {
+    type: NOTIFICATIONS_ENTER_CLEARING_MODE,
+    yes: yes,
+  };
+};
+
+export function markAllNotifications(yes) {
+  return {
+    type: NOTIFICATIONS_MARK_ALL_FOR_DELETE,
+    yes: yes, // true, false or null. null = invert
+  };
+};
+
+export function deleteMarkedNotificationsRequest() {
+  return {
+    type: NOTIFICATIONS_DELETE_MARKED_REQUEST,
+  };
+};
+
+export function deleteMarkedNotificationsFail() {
+  return {
+    type: NOTIFICATIONS_DELETE_MARKED_FAIL,
+  };
+};
+
+export function markNotificationForDelete(id, yes) {
+  return {
+    type: NOTIFICATION_MARK_FOR_DELETE,
+    id: id,
+    yes: yes,
+  };
+};
+
+export function deleteMarkedNotificationsSuccess() {
+  return {
+    type: NOTIFICATIONS_DELETE_MARKED_SUCCESS,
+  };
+};
diff --git a/app/javascript/mastodon/actions/streaming.js b/app/javascript/mastodon/actions/streaming.js
index dcce048ca..e60ddacd9 100644
--- a/app/javascript/mastodon/actions/streaming.js
+++ b/app/javascript/mastodon/actions/streaming.js
@@ -51,3 +51,4 @@ export const connectCommunityStream = () => connectTimelineStream('community', '
 export const connectMediaStream = () => connectTimelineStream('community', 'public:local');
 export const connectPublicStream = () => connectTimelineStream('public', 'public');
 export const connectHashtagStream = (tag) => connectTimelineStream(`hashtag:${tag}`, `hashtag&tag=${tag}`);
+export const connectDirectStream = () => connectTimelineStream('direct', 'direct');
diff --git a/app/javascript/mastodon/actions/timelines.js b/app/javascript/mastodon/actions/timelines.js
index 09abe2702..935bbb6f0 100644
--- a/app/javascript/mastodon/actions/timelines.js
+++ b/app/javascript/mastodon/actions/timelines.js
@@ -115,6 +115,7 @@ export function refreshTimeline(timelineId, path, params = {}) {
 export const refreshHomeTimeline         = () => refreshTimeline('home', '/api/v1/timelines/home');
 export const refreshPublicTimeline       = () => refreshTimeline('public', '/api/v1/timelines/public');
 export const refreshCommunityTimeline    = () => refreshTimeline('community', '/api/v1/timelines/public', { local: true });
+export const refreshDirectTimeline       = () => refreshTimeline('direct', '/api/v1/timelines/direct');
 export const refreshAccountTimeline      = accountId => refreshTimeline(`account:${accountId}`, `/api/v1/accounts/${accountId}/statuses`);
 export const refreshAccountMediaTimeline = accountId => refreshTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { only_media: true });
 export const refreshHashtagTimeline      = hashtag => refreshTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`);
@@ -155,6 +156,7 @@ export function expandTimeline(timelineId, path, params = {}) {
 export const expandHomeTimeline         = () => expandTimeline('home', '/api/v1/timelines/home');
 export const expandPublicTimeline       = () => expandTimeline('public', '/api/v1/timelines/public');
 export const expandCommunityTimeline    = () => expandTimeline('community', '/api/v1/timelines/public', { local: true });
+export const expandDirectTimeline       = () => expandTimeline('direct', '/api/v1/timelines/direct');
 export const expandAccountTimeline      = accountId => expandTimeline(`account:${accountId}`, `/api/v1/accounts/${accountId}/statuses`);
 export const expandAccountMediaTimeline = accountId => expandTimeline(`account:${accountId}:media`, `/api/v1/accounts/${accountId}/statuses`, { only_media: true });
 export const expandHashtagTimeline      = hashtag => expandTimeline(`hashtag:${hashtag}`, `/api/v1/timelines/tag/${hashtag}`);