diff --git a/app/javascript/flavours/glitch/actions/accounts.js b/app/javascript/flavours/glitch/actions/accounts.js
index d67ab112ed..b659e4ff39 100644
--- a/app/javascript/flavours/glitch/actions/accounts.js
+++ b/app/javascript/flavours/glitch/actions/accounts.js
@@ -1,4 +1,5 @@
import api, { getLinks } from 'flavours/glitch/util/api';
+import { importAccount, importFetchedAccount, importFetchedAccounts } from './importer';
export const ACCOUNT_FETCH_REQUEST = 'ACCOUNT_FETCH_REQUEST';
export const ACCOUNT_FETCH_SUCCESS = 'ACCOUNT_FETCH_SUCCESS';
@@ -94,7 +95,9 @@ export function fetchAccount(id) {
dispatch(fetchAccountRequest(id));
api(getState).get(`/api/v1/accounts/${id}`).then(response => {
- dispatch(fetchAccountSuccess(response.data));
+ dispatch(importFetchedAccount(response.data));
+ }).then(() => {
+ dispatch(fetchAccountSuccess());
}).catch(error => {
dispatch(fetchAccountFail(id, error));
});
@@ -108,10 +111,9 @@ export function fetchAccountRequest(id) {
};
};
-export function fetchAccountSuccess(account) {
+export function fetchAccountSuccess() {
return {
type: ACCOUNT_FETCH_SUCCESS,
- account,
};
};
@@ -338,6 +340,7 @@ export function fetchFollowers(id) {
api(getState).get(`/api/v1/accounts/${id}/followers`).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data));
dispatch(fetchFollowersSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => {
@@ -383,6 +386,7 @@ export function expandFollowers(id) {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data));
dispatch(expandFollowersSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => {
@@ -422,6 +426,7 @@ export function fetchFollowing(id) {
api(getState).get(`/api/v1/accounts/${id}/following`).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data));
dispatch(fetchFollowingSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => {
@@ -467,6 +472,7 @@ export function expandFollowing(id) {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data));
dispatch(expandFollowingSuccess(id, response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => {
@@ -548,6 +554,7 @@ export function fetchFollowRequests() {
api(getState).get('/api/v1/follow_requests').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data));
dispatch(fetchFollowRequestsSuccess(response.data, next ? next.uri : null));
}).catch(error => dispatch(fetchFollowRequestsFail(error)));
};
@@ -586,6 +593,7 @@ export function expandFollowRequests() {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data));
dispatch(expandFollowRequestsSuccess(response.data, next ? next.uri : null));
}).catch(error => dispatch(expandFollowRequestsFail(error)));
};
@@ -749,9 +757,10 @@ export function fetchPinnedAccounts() {
return (dispatch, getState) => {
dispatch(fetchPinnedAccountsRequest());
- api(getState).get(`/api/v1/endorsements`, { params: { limit: 0 } })
- .then(({ data }) => dispatch(fetchPinnedAccountsSuccess(data)))
- .catch(err => dispatch(fetchPinnedAccountsFail(err)));
+ api(getState).get(`/api/v1/endorsements`, { params: { limit: 0 } }).then(response => {
+ dispatch(importFetchedAccounts(response.data));
+ dispatch(fetchPinnedAccountsSuccess(response.data));
+ }).catch(err => dispatch(fetchPinnedAccountsFail(err)));
};
};
@@ -785,8 +794,10 @@ export function fetchPinnedAccountsSuggestions(q) {
following: true,
};
- api(getState).get('/api/v1/accounts/search', { params })
- .then(({ data }) => dispatch(fetchPinnedAccountsSuggestionsReady(q, data)));
+ api(getState).get('/api/v1/accounts/search', { params }).then(response => {
+ dispatch(importFetchedAccounts(response.data));
+ dispatch(fetchPinnedAccountsSuggestionsReady(q, response.data));
+ });
};
};
diff --git a/app/javascript/flavours/glitch/actions/blocks.js b/app/javascript/flavours/glitch/actions/blocks.js
index fe44ca19a0..498ce519fb 100644
--- a/app/javascript/flavours/glitch/actions/blocks.js
+++ b/app/javascript/flavours/glitch/actions/blocks.js
@@ -1,5 +1,6 @@
import api, { getLinks } from 'flavours/glitch/util/api';
import { fetchRelationships } from './accounts';
+import { importFetchedAccounts } from './importer';
export const BLOCKS_FETCH_REQUEST = 'BLOCKS_FETCH_REQUEST';
export const BLOCKS_FETCH_SUCCESS = 'BLOCKS_FETCH_SUCCESS';
@@ -15,6 +16,7 @@ export function fetchBlocks() {
api(getState).get('/api/v1/blocks').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data));
dispatch(fetchBlocksSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => dispatch(fetchBlocksFail(error)));
@@ -54,6 +56,7 @@ export function expandBlocks() {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data));
dispatch(expandBlocksSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => dispatch(expandBlocksFail(error)));
diff --git a/app/javascript/flavours/glitch/actions/bookmarks.js b/app/javascript/flavours/glitch/actions/bookmarks.js
index fb5d49ad38..83dbf5407c 100644
--- a/app/javascript/flavours/glitch/actions/bookmarks.js
+++ b/app/javascript/flavours/glitch/actions/bookmarks.js
@@ -1,4 +1,5 @@
import api, { getLinks } from 'flavours/glitch/util/api';
+import { importFetchedStatuses } from './importer';
export const BOOKMARKED_STATUSES_FETCH_REQUEST = 'BOOKMARKED_STATUSES_FETCH_REQUEST';
export const BOOKMARKED_STATUSES_FETCH_SUCCESS = 'BOOKMARKED_STATUSES_FETCH_SUCCESS';
@@ -18,6 +19,7 @@ export function fetchBookmarkedStatuses() {
api(getState).get('/api/v1/bookmarks').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedStatuses(response.data));
dispatch(fetchBookmarkedStatusesSuccess(response.data, next ? next.uri : null));
}).catch(error => {
dispatch(fetchBookmarkedStatusesFail(error));
@@ -58,6 +60,7 @@ export function expandBookmarkedStatuses() {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedStatuses(response.data));
dispatch(expandBookmarkedStatusesSuccess(response.data, next ? next.uri : null));
}).catch(error => {
dispatch(expandBookmarkedStatusesFail(error));
diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js
index 0dd1766bc7..fc32277b2a 100644
--- a/app/javascript/flavours/glitch/actions/compose.js
+++ b/app/javascript/flavours/glitch/actions/compose.js
@@ -6,7 +6,7 @@ import { useEmoji } from './emojis';
import { tagHistory } from 'flavours/glitch/util/settings';
import { recoverHashtags } from 'flavours/glitch/util/hashtag';
import resizeImage from 'flavours/glitch/util/resize_image';
-
+import { importFetchedAccounts } from './importer';
import { updateTimeline } from './timelines';
import { showAlertForError } from './alerts';
import { showAlert } from './alerts';
@@ -338,6 +338,7 @@ const fetchComposeSuggestionsAccounts = throttle((dispatch, getState, token) =>
limit: 4,
},
}).then(response => {
+ dispatch(importFetchedAccounts(response.data));
dispatch(readyComposeSuggestionsAccounts(token, response.data));
}).catch(error => {
if (!isCancel(error)) {
diff --git a/app/javascript/flavours/glitch/actions/favourites.js b/app/javascript/flavours/glitch/actions/favourites.js
index 28eca8e5ff..0d8bfb14d6 100644
--- a/app/javascript/flavours/glitch/actions/favourites.js
+++ b/app/javascript/flavours/glitch/actions/favourites.js
@@ -1,4 +1,5 @@
import api, { getLinks } from 'flavours/glitch/util/api';
+import { importFetchedStatuses } from './importer';
export const FAVOURITED_STATUSES_FETCH_REQUEST = 'FAVOURITED_STATUSES_FETCH_REQUEST';
export const FAVOURITED_STATUSES_FETCH_SUCCESS = 'FAVOURITED_STATUSES_FETCH_SUCCESS';
@@ -18,6 +19,7 @@ export function fetchFavouritedStatuses() {
api(getState).get('/api/v1/favourites').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedStatuses(response.data));
dispatch(fetchFavouritedStatusesSuccess(response.data, next ? next.uri : null));
}).catch(error => {
dispatch(fetchFavouritedStatusesFail(error));
@@ -61,6 +63,7 @@ export function expandFavouritedStatuses() {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedStatuses(response.data));
dispatch(expandFavouritedStatusesSuccess(response.data, next ? next.uri : null));
}).catch(error => {
dispatch(expandFavouritedStatusesFail(error));
diff --git a/app/javascript/flavours/glitch/actions/importer/index.js b/app/javascript/flavours/glitch/actions/importer/index.js
new file mode 100644
index 0000000000..735d1552cc
--- /dev/null
+++ b/app/javascript/flavours/glitch/actions/importer/index.js
@@ -0,0 +1,75 @@
+import { normalizeAccount, normalizeStatus } from './normalizer';
+
+export const ACCOUNT_IMPORT = 'ACCOUNT_IMPORT';
+export const ACCOUNTS_IMPORT = 'ACCOUNTS_IMPORT';
+export const STATUS_IMPORT = 'STATUS_IMPORT';
+export const STATUSES_IMPORT = 'STATUSES_IMPORT';
+
+function pushUnique(array, object) {
+ if (array.every(element => element.id !== object.id)) {
+ array.push(object);
+ }
+}
+
+export function importAccount(account) {
+ return { type: ACCOUNT_IMPORT, account };
+}
+
+export function importAccounts(accounts) {
+ return { type: ACCOUNTS_IMPORT, accounts };
+}
+
+export function importStatus(status) {
+ return { type: STATUS_IMPORT, status };
+}
+
+export function importStatuses(statuses) {
+ return { type: STATUSES_IMPORT, statuses };
+}
+
+export function importFetchedAccount(account) {
+ return importFetchedAccounts([account]);
+}
+
+export function importFetchedAccounts(accounts) {
+ const normalAccounts = [];
+
+ function processAccount(account) {
+ pushUnique(normalAccounts, normalizeAccount(account));
+
+ if (account.moved) {
+ processAccount(account.moved);
+ }
+ }
+
+ accounts.forEach(processAccount);
+ //putAccounts(normalAccounts, !autoPlayGif);
+
+ return importAccounts(normalAccounts);
+}
+
+export function importFetchedStatus(status) {
+ return importFetchedStatuses([status]);
+}
+
+export function importFetchedStatuses(statuses) {
+ return (dispatch, getState) => {
+ const accounts = [];
+ const normalStatuses = [];
+
+ function processStatus(status) {
+ pushUnique(normalStatuses, normalizeStatus(status, getState().getIn(['statuses', status.id])));
+ pushUnique(accounts, status.account);
+
+ if (status.reblog && status.reblog.id) {
+ processStatus(status.reblog);
+ }
+ }
+
+ statuses.forEach(processStatus);
+ //putStatuses(normalStatuses);
+
+ dispatch(importFetchedAccounts(accounts));
+ dispatch(importStatuses(normalStatuses));
+ };
+}
diff --git a/app/javascript/flavours/glitch/actions/importer/normalizer.js b/app/javascript/flavours/glitch/actions/importer/normalizer.js
new file mode 100644
index 0000000000..a2dabb5b2c
--- /dev/null
+++ b/app/javascript/flavours/glitch/actions/importer/normalizer.js
@@ -0,0 +1,63 @@
+import escapeTextContentForBrowser from 'escape-html';
+import emojify from 'flavours/glitch/util/emoji';
+import { unescapeHTML } from 'flavours/glitch/util/html';
+import { expandSpoilers } from 'flavours/glitch/util/initial_state';
+
+const domParser = new DOMParser();
+
+const makeEmojiMap = record => record.emojis.reduce((obj, emoji) => {
+ obj[`:${emoji.shortcode}:`] = emoji;
+ return obj;
+}, {});
+
+export function normalizeAccount(account) {
+ account = { ...account };
+
+ const emojiMap = makeEmojiMap(account);
+ const displayName = account.display_name.trim().length === 0 ? account.username : account.display_name;
+
+ account.display_name_html = emojify(escapeTextContentForBrowser(displayName), emojiMap);
+ account.note_emojified = emojify(account.note, emojiMap);
+
+ if (account.fields) {
+ account.fields = account.fields.map(pair => ({
+ ...pair,
+ name_emojified: emojify(escapeTextContentForBrowser(pair.name)),
+ value_emojified: emojify(pair.value, emojiMap),
+ value_plain: unescapeHTML(pair.value),
+ }));
+ }
+
+ if (account.moved) {
+ account.moved = account.moved.id;
+ }
+
+ return account;
+}
+
+export function normalizeStatus(status, normalOldStatus) {
+ const normalStatus = { ...status };
+ normalStatus.account = status.account.id;
+
+ if (status.reblog && status.reblog.id) {
+ normalStatus.reblog = status.reblog.id;
+ }
+
+ // Only calculate these values when status first encountered
+ // Otherwise keep the ones already in the reducer
+ if (normalOldStatus) {
+ normalStatus.search_index = normalOldStatus.get('search_index');
+ normalStatus.contentHtml = normalOldStatus.get('contentHtml');
+ normalStatus.spoilerHtml = normalOldStatus.get('spoilerHtml');
+ } else {
+ const spoilerText = normalStatus.spoiler_text || '';
+ const searchContent = [spoilerText, status.content].join('\n\n').replace(/
/g, '\n').replace(/<\/p>
/g, '\n\n');
+ const emojiMap = makeEmojiMap(normalStatus);
+
+ normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent;
+ normalStatus.contentHtml = emojify(normalStatus.content, emojiMap);
+ normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(spoilerText), emojiMap);
+ }
+
+ return normalStatus;
+}
diff --git a/app/javascript/flavours/glitch/actions/interactions.js b/app/javascript/flavours/glitch/actions/interactions.js
index edd8961f9d..4407f8b6ea 100644
--- a/app/javascript/flavours/glitch/actions/interactions.js
+++ b/app/javascript/flavours/glitch/actions/interactions.js
@@ -1,4 +1,5 @@
import api from 'flavours/glitch/util/api';
+import { importFetchedAccounts, importFetchedStatus } from './importer';
export const REBLOG_REQUEST = 'REBLOG_REQUEST';
export const REBLOG_SUCCESS = 'REBLOG_SUCCESS';
@@ -47,7 +48,8 @@ export function reblog(status) {
api(getState).post(`/api/v1/statuses/${status.get('id')}/reblog`).then(function (response) {
// The reblog API method returns a new status wrapped around the original. In this case we are only
// interested in how the original is modified, hence passing it skipping the wrapper
- dispatch(reblogSuccess(status, response.data.reblog));
+ dispatch(importFetchedStatus(response.data.reblog));
+ dispatch(reblogSuccess(status));
}).catch(function (error) {
dispatch(reblogFail(status, error));
});
@@ -59,7 +61,8 @@ export function unreblog(status) {
dispatch(unreblogRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/unreblog`).then(response => {
- dispatch(unreblogSuccess(status, response.data));
+ dispatch(importFetchedStatus(response.data));
+ dispatch(unreblogSuccess(status));
}).catch(error => {
dispatch(unreblogFail(status, error));
});
@@ -73,11 +76,10 @@ export function reblogRequest(status) {
};
};
-export function reblogSuccess(status, response) {
+export function reblogSuccess(status) {
return {
type: REBLOG_SUCCESS,
status: status,
- response: response,
};
};
@@ -96,11 +98,10 @@ export function unreblogRequest(status) {
};
};
-export function unreblogSuccess(status, response) {
+export function unreblogSuccess(status) {
return {
type: UNREBLOG_SUCCESS,
status: status,
- response: response,
};
};
@@ -117,7 +118,8 @@ export function favourite(status) {
dispatch(favouriteRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/favourite`).then(function (response) {
- dispatch(favouriteSuccess(status, response.data));
+ dispatch(importFetchedStatus(response.data));
+ dispatch(favouriteSuccess(status));
}).catch(function (error) {
dispatch(favouriteFail(status, error));
});
@@ -129,7 +131,8 @@ export function unfavourite(status) {
dispatch(unfavouriteRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/unfavourite`).then(response => {
- dispatch(unfavouriteSuccess(status, response.data));
+ dispatch(importFetchedStatus(response.data));
+ dispatch(unfavouriteSuccess(status));
}).catch(error => {
dispatch(unfavouriteFail(status, error));
});
@@ -143,11 +146,10 @@ export function favouriteRequest(status) {
};
};
-export function favouriteSuccess(status, response) {
+export function favouriteSuccess(status) {
return {
type: FAVOURITE_SUCCESS,
status: status,
- response: response,
};
};
@@ -166,11 +168,10 @@ export function unfavouriteRequest(status) {
};
};
-export function unfavouriteSuccess(status, response) {
+export function unfavouriteSuccess(status) {
return {
type: UNFAVOURITE_SUCCESS,
status: status,
- response: response,
};
};
@@ -187,7 +188,8 @@ export function bookmark(status) {
dispatch(bookmarkRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/bookmark`).then(function (response) {
- dispatch(bookmarkSuccess(status, response.data));
+ dispatch(importFetchedStatus(response.data));
+ dispatch(bookmarkSuccess(status));
}).catch(function (error) {
dispatch(bookmarkFail(status, error));
});
@@ -199,7 +201,8 @@ export function unbookmark(status) {
dispatch(unbookmarkRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/unbookmark`).then(response => {
- dispatch(unbookmarkSuccess(status, response.data));
+ dispatch(importFetchedStatus(response.data));
+ dispatch(unbookmarkSuccess(status));
}).catch(error => {
dispatch(unbookmarkFail(status, error));
});
@@ -213,11 +216,10 @@ export function bookmarkRequest(status) {
};
};
-export function bookmarkSuccess(status, response) {
+export function bookmarkSuccess(status) {
return {
type: BOOKMARK_SUCCESS,
status: status,
- response: response,
};
};
@@ -236,11 +238,10 @@ export function unbookmarkRequest(status) {
};
};
-export function unbookmarkSuccess(status, response) {
+export function unbookmarkSuccess(status) {
return {
type: UNBOOKMARK_SUCCESS,
status: status,
- response: response,
};
};
@@ -257,6 +258,7 @@ export function fetchReblogs(id) {
dispatch(fetchReblogsRequest(id));
api(getState).get(`/api/v1/statuses/${id}/reblogged_by`).then(response => {
+ dispatch(importFetchedAccounts(response.data));
dispatch(fetchReblogsSuccess(id, response.data));
}).catch(error => {
dispatch(fetchReblogsFail(id, error));
@@ -291,6 +293,7 @@ export function fetchFavourites(id) {
dispatch(fetchFavouritesRequest(id));
api(getState).get(`/api/v1/statuses/${id}/favourited_by`).then(response => {
+ dispatch(importFetchedAccounts(response.data));
dispatch(fetchFavouritesSuccess(id, response.data));
}).catch(error => {
dispatch(fetchFavouritesFail(id, error));
@@ -325,7 +328,8 @@ export function pin(status) {
dispatch(pinRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/pin`).then(response => {
- dispatch(pinSuccess(status, response.data));
+ dispatch(importFetchedStatus(response.data));
+ dispatch(pinSuccess(status));
}).catch(error => {
dispatch(pinFail(status, error));
});
@@ -339,11 +343,10 @@ export function pinRequest(status) {
};
};
-export function pinSuccess(status, response) {
+export function pinSuccess(status) {
return {
type: PIN_SUCCESS,
status,
- response,
};
};
@@ -360,7 +363,8 @@ export function unpin (status) {
dispatch(unpinRequest(status));
api(getState).post(`/api/v1/statuses/${status.get('id')}/unpin`).then(response => {
- dispatch(unpinSuccess(status, response.data));
+ dispatch(importFetchedStatus(response.data));
+ dispatch(unpinSuccess(status));
}).catch(error => {
dispatch(unpinFail(status, error));
});
@@ -374,11 +378,10 @@ export function unpinRequest(status) {
};
};
-export function unpinSuccess(status, response) {
+export function unpinSuccess(status) {
return {
type: UNPIN_SUCCESS,
status,
- response,
};
};
diff --git a/app/javascript/flavours/glitch/actions/lists.js b/app/javascript/flavours/glitch/actions/lists.js
index f29ca1e010..c2309b8c26 100644
--- a/app/javascript/flavours/glitch/actions/lists.js
+++ b/app/javascript/flavours/glitch/actions/lists.js
@@ -1,4 +1,5 @@
import api from 'flavours/glitch/util/api';
+import { importFetchedAccounts } from './importer';
import { showAlertForError } from './alerts';
export const LIST_FETCH_REQUEST = 'LIST_FETCH_REQUEST';
@@ -208,9 +209,10 @@ export const deleteListFail = (id, error) => ({
export const fetchListAccounts = listId => (dispatch, getState) => {
dispatch(fetchListAccountsRequest(listId));
- api(getState).get(`/api/v1/lists/${listId}/accounts`, { params: { limit: 0 } })
- .then(({ data }) => dispatch(fetchListAccountsSuccess(listId, data)))
- .catch(err => dispatch(fetchListAccountsFail(listId, err)));
+ api(getState).get(`/api/v1/lists/${listId}/accounts`, { params: { limit: 0 } }).then(({ data }) => {
+ dispatch(importFetchedAccounts(data));
+ dispatch(fetchListAccountsSuccess(listId, data));
+ }).catch(err => dispatch(fetchListAccountsFail(listId, err)));
};
export const fetchListAccountsRequest = id => ({
@@ -239,9 +241,10 @@ export const fetchListSuggestions = q => (dispatch, getState) => {
following: true,
};
- api(getState).get('/api/v1/accounts/search', { params })
- .then(({ data }) => dispatch(fetchListSuggestionsReady(q, data)))
- .catch(error => dispatch(showAlertForError(error)));
+ api(getState).get('/api/v1/accounts/search', { params }).then(({ data }) => {
+ dispatch(importFetchedAccounts(data));
+ dispatch(fetchListSuggestionsReady(q, data));
+ }).catch(error => dispatch(showAlertForError(error)));
};
export const fetchListSuggestionsReady = (query, accounts) => ({
diff --git a/app/javascript/flavours/glitch/actions/mutes.js b/app/javascript/flavours/glitch/actions/mutes.js
index e061305336..927fc7415e 100644
--- a/app/javascript/flavours/glitch/actions/mutes.js
+++ b/app/javascript/flavours/glitch/actions/mutes.js
@@ -1,5 +1,6 @@
import api, { getLinks } from 'flavours/glitch/util/api';
import { fetchRelationships } from './accounts';
+import { importFetchedAccounts } from './importer';
import { openModal } from 'flavours/glitch/actions/modal';
export const MUTES_FETCH_REQUEST = 'MUTES_FETCH_REQUEST';
@@ -19,6 +20,7 @@ export function fetchMutes() {
api(getState).get('/api/v1/mutes').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data));
dispatch(fetchMutesSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => dispatch(fetchMutesFail(error)));
@@ -58,6 +60,7 @@ export function expandMutes() {
api(getState).get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedAccounts(response.data));
dispatch(expandMutesSuccess(response.data, next ? next.uri : null));
dispatch(fetchRelationships(response.data.map(item => item.id)));
}).catch(error => dispatch(expandMutesFail(error)));
diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js
index 3cfad90a1c..f89b4cb361 100644
--- a/app/javascript/flavours/glitch/actions/notifications.js
+++ b/app/javascript/flavours/glitch/actions/notifications.js
@@ -1,6 +1,12 @@
import api, { getLinks } from 'flavours/glitch/util/api';
import IntlMessageFormat from 'intl-messageformat';
import { fetchRelationships } from './accounts';
+import {
+ importFetchedAccount,
+ importFetchedAccounts,
+ importFetchedStatus,
+ importFetchedStatuses,
+} from './importer';
import { defineMessages } from 'react-intl';
import { List as ImmutableList } from 'immutable';
import { unescapeHTML } from 'flavours/glitch/util/html';
@@ -47,9 +53,10 @@ const fetchRelatedRelationships = (dispatch, notifications) => {
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);
- const filters = getFilters(getState(), { contextType: 'notifications' });
+ const showInColumn = getState().getIn(['settings', 'notifications', 'shows', notification.type], true);
+ const showAlert = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true);
+ const playSound = getState().getIn(['settings', 'notifications', 'sounds', notification.type], true);
+ const filters = getFilters(getState(), { contextType: 'notifications' });
let filtered = false;
@@ -60,15 +67,26 @@ export function updateNotifications(notification, intlMessages, intlLocale) {
filtered = regex && regex.test(searchIndex);
}
- dispatch({
- type: NOTIFICATIONS_UPDATE,
- notification,
- account: notification.account,
- status: notification.status,
- meta: (playSound && !filtered) ? { sound: 'boop' } : undefined,
- });
+ if (showInColumn) {
+ dispatch(importFetchedAccount(notification.account));
- fetchRelatedRelationships(dispatch, [notification]);
+ if (notification.status) {
+ dispatch(importFetchedStatus(notification.status));
+ }
+
+ dispatch({
+ type: NOTIFICATIONS_UPDATE,
+ notification,
+ meta: (playSound && !filtered) ? { sound: 'boop' } : undefined,
+ });
+
+ fetchRelatedRelationships(dispatch, [notification]);
+ } else if (playSound && !filtered) {
+ dispatch({
+ type: NOTIFICATIONS_UPDATE_NOOP,
+ meta: { sound: 'boop' },
+ });
+ }
// Desktop notifications
if (typeof window.Notification !== 'undefined' && showAlert && !filtered) {
@@ -120,6 +138,10 @@ export function expandNotifications({ maxId } = {}, done = noOp) {
api(getState).get('/api/v1/notifications', { params }).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+
+ dispatch(importFetchedAccounts(response.data.map(item => item.account)));
+ dispatch(importFetchedStatuses(response.data.map(item => item.status).filter(status => !!status)));
+
dispatch(expandNotificationsSuccess(response.data, next ? next.uri : null, isLoadingMore));
fetchRelatedRelationships(dispatch, response.data);
done();
diff --git a/app/javascript/flavours/glitch/actions/pin_statuses.js b/app/javascript/flavours/glitch/actions/pin_statuses.js
index d3d1a154f6..77dfb9c7ff 100644
--- a/app/javascript/flavours/glitch/actions/pin_statuses.js
+++ b/app/javascript/flavours/glitch/actions/pin_statuses.js
@@ -1,4 +1,5 @@
import api from 'flavours/glitch/util/api';
+import { importFetchedStatuses } from './importer';
export const PINNED_STATUSES_FETCH_REQUEST = 'PINNED_STATUSES_FETCH_REQUEST';
export const PINNED_STATUSES_FETCH_SUCCESS = 'PINNED_STATUSES_FETCH_SUCCESS';
@@ -11,6 +12,7 @@ export function fetchPinnedStatuses() {
dispatch(fetchPinnedStatusesRequest());
api(getState).get(`/api/v1/accounts/${me}/statuses`, { params: { pinned: true } }).then(response => {
+ dispatch(importFetchedStatuses(response.data));
dispatch(fetchPinnedStatusesSuccess(response.data, null));
}).catch(error => {
dispatch(fetchPinnedStatusesFail(error));
diff --git a/app/javascript/flavours/glitch/actions/search.js b/app/javascript/flavours/glitch/actions/search.js
index ec65bdf28a..bc094eed5c 100644
--- a/app/javascript/flavours/glitch/actions/search.js
+++ b/app/javascript/flavours/glitch/actions/search.js
@@ -1,5 +1,6 @@
import api from 'flavours/glitch/util/api';
import { fetchRelationships } from './accounts';
+import { importFetchedAccounts, importFetchedStatuses } from './importer';
export const SEARCH_CHANGE = 'SEARCH_CHANGE';
export const SEARCH_CLEAR = 'SEARCH_CLEAR';
@@ -38,6 +39,14 @@ export function submitSearch() {
resolve: true,
},
}).then(response => {
+ if (response.data.accounts) {
+ dispatch(importFetchedAccounts(response.data.accounts));
+ }
+
+ if (response.data.statuses) {
+ dispatch(importFetchedStatuses(response.data.statuses));
+ }
+
dispatch(fetchSearchSuccess(response.data));
dispatch(fetchRelationships(response.data.accounts.map(item => item.id)));
}).catch(error => {
diff --git a/app/javascript/flavours/glitch/actions/statuses.js b/app/javascript/flavours/glitch/actions/statuses.js
index 6183f3c03d..13ce782e66 100644
--- a/app/javascript/flavours/glitch/actions/statuses.js
+++ b/app/javascript/flavours/glitch/actions/statuses.js
@@ -1,6 +1,7 @@
import api from 'flavours/glitch/util/api';
import { deleteFromTimelines } from './timelines';
+import { importFetchedStatus, importFetchedStatuses } from './importer';
export const STATUS_FETCH_REQUEST = 'STATUS_FETCH_REQUEST';
export const STATUS_FETCH_SUCCESS = 'STATUS_FETCH_SUCCESS';
@@ -45,17 +46,17 @@ export function fetchStatus(id) {
dispatch(fetchStatusRequest(id, skipLoading));
api(getState).get(`/api/v1/statuses/${id}`).then(response => {
- dispatch(fetchStatusSuccess(response.data, skipLoading));
+ dispatch(importFetchedStatus(response.data));
+ dispatch(fetchStatusSuccess(skipLoading));
}).catch(error => {
dispatch(fetchStatusFail(id, error, skipLoading));
});
};
};
-export function fetchStatusSuccess(status, skipLoading) {
+export function fetchStatusSuccess(skipLoading) {
return {
type: STATUS_FETCH_SUCCESS,
- status,
skipLoading,
};
};
@@ -127,6 +128,7 @@ export function fetchContext(id) {
dispatch(fetchContextRequest(id));
api(getState).get(`/api/v1/statuses/${id}/context`).then(response => {
+ dispatch(importFetchedStatuses(response.data.ancestors.concat(response.data.descendants)));
dispatch(fetchContextSuccess(id, response.data.ancestors, response.data.descendants));
}).catch(error => {
diff --git a/app/javascript/flavours/glitch/actions/store.js b/app/javascript/flavours/glitch/actions/store.js
index 2dd94a9983..34dcafc510 100644
--- a/app/javascript/flavours/glitch/actions/store.js
+++ b/app/javascript/flavours/glitch/actions/store.js
@@ -1,5 +1,6 @@
import { Iterable, fromJS } from 'immutable';
import { hydrateCompose } from './compose';
+import { importFetchedAccounts } from './importer';
export const STORE_HYDRATE = 'STORE_HYDRATE';
export const STORE_HYDRATE_LAZY = 'STORE_HYDRATE_LAZY';
@@ -18,5 +19,6 @@ export function hydrateStore(rawState) {
});
dispatch(hydrateCompose());
+ dispatch(importFetchedAccounts(Object.values(rawState.accounts)));
};
};
diff --git a/app/javascript/flavours/glitch/actions/timelines.js b/app/javascript/flavours/glitch/actions/timelines.js
index bc21b4d5e6..c6866f81fb 100644
--- a/app/javascript/flavours/glitch/actions/timelines.js
+++ b/app/javascript/flavours/glitch/actions/timelines.js
@@ -1,3 +1,4 @@
+import { importFetchedStatus, importFetchedStatuses } from './importer';
import api, { getLinks } from 'flavours/glitch/util/api';
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
@@ -14,11 +15,13 @@ export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP';
export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
export function updateTimeline(timeline, status, accept) {
- return (dispatch, getState) => {
+ return dispatch => {
if (typeof accept === 'function' && !accept(status)) {
return;
}
+ dispatch(importFetchedStatus(status));
+
dispatch({
type: TIMELINE_UPDATE,
timeline,
@@ -77,6 +80,7 @@ export function expandTimeline(timelineId, path, params = {}, done = noOp) {
api(getState).get(path, { params }).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
+ dispatch(importFetchedStatuses(response.data));
dispatch(expandTimelineSuccess(timelineId, response.data, next ? next.uri : null, response.code === 206, isLoadingRecent, isLoadingMore));
done();
}).catch(error => {
diff --git a/app/javascript/flavours/glitch/reducers/accounts.js b/app/javascript/flavours/glitch/reducers/accounts.js
index 860c13534d..530ed8e607 100644
--- a/app/javascript/flavours/glitch/reducers/accounts.js
+++ b/app/javascript/flavours/glitch/reducers/accounts.js
@@ -1,68 +1,7 @@
-import {
- ACCOUNT_FETCH_SUCCESS,
- FOLLOWERS_FETCH_SUCCESS,
- FOLLOWERS_EXPAND_SUCCESS,
- FOLLOWING_FETCH_SUCCESS,
- FOLLOWING_EXPAND_SUCCESS,
- FOLLOW_REQUESTS_FETCH_SUCCESS,
- FOLLOW_REQUESTS_EXPAND_SUCCESS,
- PINNED_ACCOUNTS_FETCH_SUCCESS,
- PINNED_ACCOUNTS_EDITOR_SUGGESTIONS_READY,
-} from 'flavours/glitch/actions/accounts';
-import {
- BLOCKS_FETCH_SUCCESS,
- BLOCKS_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/blocks';
-import {
- MUTES_FETCH_SUCCESS,
- MUTES_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/mutes';
-import { COMPOSE_SUGGESTIONS_READY } from 'flavours/glitch/actions/compose';
-import {
- REBLOG_SUCCESS,
- UNREBLOG_SUCCESS,
- FAVOURITE_SUCCESS,
- UNFAVOURITE_SUCCESS,
- BOOKMARK_SUCCESS,
- UNBOOKMARK_SUCCESS,
- REBLOGS_FETCH_SUCCESS,
- FAVOURITES_FETCH_SUCCESS,
-} from 'flavours/glitch/actions/interactions';
-import {
- TIMELINE_UPDATE,
- TIMELINE_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/timelines';
-import {
- STATUS_FETCH_SUCCESS,
- CONTEXT_FETCH_SUCCESS,
-} from 'flavours/glitch/actions/statuses';
-import { SEARCH_FETCH_SUCCESS } from 'flavours/glitch/actions/search';
-import {
- NOTIFICATIONS_UPDATE,
- NOTIFICATIONS_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/notifications';
-import {
- FAVOURITED_STATUSES_FETCH_SUCCESS,
- FAVOURITED_STATUSES_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/favourites';
-import {
- BOOKMARKED_STATUSES_FETCH_SUCCESS,
- BOOKMARKED_STATUSES_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/bookmarks';
-import {
- LIST_ACCOUNTS_FETCH_SUCCESS,
- LIST_EDITOR_SUGGESTIONS_READY,
-} from 'flavours/glitch/actions/lists';
-import { STORE_HYDRATE } from 'flavours/glitch/actions/store';
-import emojify from 'flavours/glitch/util/emoji';
+import { ACCOUNT_IMPORT, ACCOUNTS_IMPORT } from '../actions/importer';
import { Map as ImmutableMap, fromJS } from 'immutable';
-import escapeTextContentForBrowser from 'escape-html';
-import { unescapeHTML } from 'flavours/glitch/util/html';
-const makeEmojiMap = record => record.emojis.reduce((obj, emoji) => {
- obj[`:${emoji.shortcode}:`] = emoji;
- return obj;
-}, {});
+const initialState = ImmutableMap();
const normalizeAccount = (state, account) => {
account = { ...account };
@@ -71,25 +10,6 @@ const normalizeAccount = (state, account) => {
delete account.following_count;
delete account.statuses_count;
- const emojiMap = makeEmojiMap(account);
- const displayName = account.display_name.trim().length === 0 ? account.username : account.display_name;
- account.display_name_html = emojify(escapeTextContentForBrowser(displayName), emojiMap);
- account.note_emojified = emojify(account.note, emojiMap);
-
- if (account.fields) {
- account.fields = account.fields.map(pair => ({
- ...pair,
- name_emojified: emojify(escapeTextContentForBrowser(pair.name)),
- value_emojified: emojify(pair.value, emojiMap),
- value_plain: unescapeHTML(pair.value),
- }));
- }
-
- if (account.moved) {
- state = normalizeAccount(state, account.moved);
- account.moved = account.moved.id;
- }
-
return state.set(account.id, fromJS(account));
};
@@ -101,71 +21,12 @@ const normalizeAccounts = (state, accounts) => {
return state;
};
-const normalizeAccountFromStatus = (state, status) => {
- state = normalizeAccount(state, status.account);
-
- if (status.reblog && status.reblog.account) {
- state = normalizeAccount(state, status.reblog.account);
- }
-
- return state;
-};
-
-const normalizeAccountsFromStatuses = (state, statuses) => {
- statuses.forEach(status => {
- state = normalizeAccountFromStatus(state, status);
- });
-
- return state;
-};
-
-const initialState = ImmutableMap();
-
export default function accounts(state = initialState, action) {
switch(action.type) {
- case STORE_HYDRATE:
- return normalizeAccounts(state, Object.values(action.state.get('accounts').toJS()));
- case ACCOUNT_FETCH_SUCCESS:
- case NOTIFICATIONS_UPDATE:
+ case ACCOUNT_IMPORT:
return normalizeAccount(state, action.account);
- case FOLLOWERS_FETCH_SUCCESS:
- case FOLLOWERS_EXPAND_SUCCESS:
- case FOLLOWING_FETCH_SUCCESS:
- case FOLLOWING_EXPAND_SUCCESS:
- case REBLOGS_FETCH_SUCCESS:
- case FAVOURITES_FETCH_SUCCESS:
- case COMPOSE_SUGGESTIONS_READY:
- case FOLLOW_REQUESTS_FETCH_SUCCESS:
- case FOLLOW_REQUESTS_EXPAND_SUCCESS:
- case BLOCKS_FETCH_SUCCESS:
- case BLOCKS_EXPAND_SUCCESS:
- case MUTES_FETCH_SUCCESS:
- case MUTES_EXPAND_SUCCESS:
- case LIST_ACCOUNTS_FETCH_SUCCESS:
- case LIST_EDITOR_SUGGESTIONS_READY:
- case PINNED_ACCOUNTS_FETCH_SUCCESS:
- case PINNED_ACCOUNTS_EDITOR_SUGGESTIONS_READY:
- return action.accounts ? normalizeAccounts(state, action.accounts) : state;
- case NOTIFICATIONS_EXPAND_SUCCESS:
- case SEARCH_FETCH_SUCCESS:
- return normalizeAccountsFromStatuses(normalizeAccounts(state, action.accounts), action.statuses);
- case TIMELINE_EXPAND_SUCCESS:
- case CONTEXT_FETCH_SUCCESS:
- case FAVOURITED_STATUSES_FETCH_SUCCESS:
- case FAVOURITED_STATUSES_EXPAND_SUCCESS:
- case BOOKMARKED_STATUSES_FETCH_SUCCESS:
- case BOOKMARKED_STATUSES_EXPAND_SUCCESS:
- return normalizeAccountsFromStatuses(state, action.statuses);
- case REBLOG_SUCCESS:
- case FAVOURITE_SUCCESS:
- case UNREBLOG_SUCCESS:
- case UNFAVOURITE_SUCCESS:
- case BOOKMARK_SUCCESS:
- case UNBOOKMARK_SUCCESS:
- return normalizeAccountFromStatus(state, action.response);
- case TIMELINE_UPDATE:
- case STATUS_FETCH_SUCCESS:
- return normalizeAccountFromStatus(state, action.status);
+ case ACCOUNTS_IMPORT:
+ return normalizeAccounts(state, action.accounts);
default:
return state;
}
diff --git a/app/javascript/flavours/glitch/reducers/accounts_counters.js b/app/javascript/flavours/glitch/reducers/accounts_counters.js
index acf363ca53..9ebf72af9b 100644
--- a/app/javascript/flavours/glitch/reducers/accounts_counters.js
+++ b/app/javascript/flavours/glitch/reducers/accounts_counters.js
@@ -1,59 +1,8 @@
import {
- ACCOUNT_FETCH_SUCCESS,
- FOLLOWERS_FETCH_SUCCESS,
- FOLLOWERS_EXPAND_SUCCESS,
- FOLLOWING_FETCH_SUCCESS,
- FOLLOWING_EXPAND_SUCCESS,
- FOLLOW_REQUESTS_FETCH_SUCCESS,
- FOLLOW_REQUESTS_EXPAND_SUCCESS,
ACCOUNT_FOLLOW_SUCCESS,
ACCOUNT_UNFOLLOW_SUCCESS,
-} from 'flavours/glitch/actions/accounts';
-import {
- BLOCKS_FETCH_SUCCESS,
- BLOCKS_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/blocks';
-import {
- MUTES_FETCH_SUCCESS,
- MUTES_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/mutes';
-import { COMPOSE_SUGGESTIONS_READY } from 'flavours/glitch/actions/compose';
-import {
- REBLOG_SUCCESS,
- UNREBLOG_SUCCESS,
- FAVOURITE_SUCCESS,
- UNFAVOURITE_SUCCESS,
- BOOKMARK_SUCCESS,
- UNBOOKMARK_SUCCESS,
- REBLOGS_FETCH_SUCCESS,
- FAVOURITES_FETCH_SUCCESS,
-} from 'flavours/glitch/actions/interactions';
-import {
- TIMELINE_UPDATE,
- TIMELINE_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/timelines';
-import {
- STATUS_FETCH_SUCCESS,
- CONTEXT_FETCH_SUCCESS,
-} from 'flavours/glitch/actions/statuses';
-import { SEARCH_FETCH_SUCCESS } from 'flavours/glitch/actions/search';
-import {
- NOTIFICATIONS_UPDATE,
- NOTIFICATIONS_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/notifications';
-import {
- FAVOURITED_STATUSES_FETCH_SUCCESS,
- FAVOURITED_STATUSES_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/favourites';
-import {
- BOOKMARKED_STATUSES_FETCH_SUCCESS,
- BOOKMARKED_STATUSES_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/bookmarks';
-import {
- LIST_ACCOUNTS_FETCH_SUCCESS,
- LIST_EDITOR_SUGGESTIONS_READY,
-} from 'flavours/glitch/actions/lists';
-import { STORE_HYDRATE } from 'flavours/glitch/actions/store';
+} from '../actions/accounts';
+import { ACCOUNT_IMPORT, ACCOUNTS_IMPORT } from '../actions/importer';
import { Map as ImmutableMap, fromJS } from 'immutable';
const normalizeAccount = (state, account) => state.set(account.id, fromJS({
@@ -70,80 +19,19 @@ const normalizeAccounts = (state, accounts) => {
return state;
};
-const normalizeAccountFromStatus = (state, status) => {
- state = normalizeAccount(state, status.account);
-
- if (status.reblog && status.reblog.account) {
- state = normalizeAccount(state, status.reblog.account);
- }
-
- return state;
-};
-
-const normalizeAccountsFromStatuses = (state, statuses) => {
- statuses.forEach(status => {
- state = normalizeAccountFromStatus(state, status);
- });
-
- return state;
-};
-
const initialState = ImmutableMap();
export default function accountsCounters(state = initialState, action) {
switch(action.type) {
- case STORE_HYDRATE:
- return state.merge(action.state.get('accounts').map(item => fromJS({
- followers_count: item.get('followers_count'),
- following_count: item.get('following_count'),
- statuses_count: item.get('statuses_count'),
- })));
- case ACCOUNT_FETCH_SUCCESS:
- case NOTIFICATIONS_UPDATE:
+ case ACCOUNT_IMPORT:
return normalizeAccount(state, action.account);
- case FOLLOWERS_FETCH_SUCCESS:
- case FOLLOWERS_EXPAND_SUCCESS:
- case FOLLOWING_FETCH_SUCCESS:
- case FOLLOWING_EXPAND_SUCCESS:
- case REBLOGS_FETCH_SUCCESS:
- case FAVOURITES_FETCH_SUCCESS:
- case COMPOSE_SUGGESTIONS_READY:
- case FOLLOW_REQUESTS_FETCH_SUCCESS:
- case FOLLOW_REQUESTS_EXPAND_SUCCESS:
- case BLOCKS_FETCH_SUCCESS:
- case BLOCKS_EXPAND_SUCCESS:
- case MUTES_FETCH_SUCCESS:
- case MUTES_EXPAND_SUCCESS:
- case LIST_ACCOUNTS_FETCH_SUCCESS:
- case LIST_EDITOR_SUGGESTIONS_READY:
- return action.accounts ? normalizeAccounts(state, action.accounts) : state;
- case NOTIFICATIONS_EXPAND_SUCCESS:
- case SEARCH_FETCH_SUCCESS:
- return normalizeAccountsFromStatuses(normalizeAccounts(state, action.accounts), action.statuses);
- case TIMELINE_EXPAND_SUCCESS:
- case CONTEXT_FETCH_SUCCESS:
- case FAVOURITED_STATUSES_FETCH_SUCCESS:
- case FAVOURITED_STATUSES_EXPAND_SUCCESS:
- case BOOKMARKED_STATUSES_FETCH_SUCCESS:
- case BOOKMARKED_STATUSES_EXPAND_SUCCESS:
- return normalizeAccountsFromStatuses(state, action.statuses);
- case REBLOG_SUCCESS:
- case FAVOURITE_SUCCESS:
- case UNREBLOG_SUCCESS:
- case UNFAVOURITE_SUCCESS:
- case BOOKMARK_SUCCESS:
- case UNBOOKMARK_SUCCESS:
- return normalizeAccountFromStatus(state, action.response);
- case TIMELINE_UPDATE:
- case STATUS_FETCH_SUCCESS:
- return normalizeAccountFromStatus(state, action.status);
+ case ACCOUNTS_IMPORT:
+ return normalizeAccounts(state, action.accounts);
case ACCOUNT_FOLLOW_SUCCESS:
- if (action.alreadyFollowing) {
- return state;
- }
- return state.updateIn([action.relationship.id, 'followers_count'], num => num < 0 ? num : num + 1);
+ return action.alreadyFollowing ? state :
+ state.updateIn([action.relationship.id, 'followers_count'], num => num + 1);
case ACCOUNT_UNFOLLOW_SUCCESS:
- return state.updateIn([action.relationship.id, 'followers_count'], num => num < 0 ? num : Math.max(0, num - 1));
+ return state.updateIn([action.relationship.id, 'followers_count'], num => Math.max(0, num - 1));
default:
return state;
}
diff --git a/app/javascript/flavours/glitch/reducers/statuses.js b/app/javascript/flavours/glitch/reducers/statuses.js
index 1beaf73e1b..96c9c6d041 100644
--- a/app/javascript/flavours/glitch/reducers/statuses.js
+++ b/app/javascript/flavours/glitch/reducers/statuses.js
@@ -1,93 +1,25 @@
import {
REBLOG_REQUEST,
- REBLOG_SUCCESS,
REBLOG_FAIL,
- UNREBLOG_SUCCESS,
FAVOURITE_REQUEST,
- FAVOURITE_SUCCESS,
FAVOURITE_FAIL,
- UNFAVOURITE_SUCCESS,
BOOKMARK_REQUEST,
- BOOKMARK_SUCCESS,
BOOKMARK_FAIL,
- UNBOOKMARK_SUCCESS,
- PIN_SUCCESS,
- UNPIN_SUCCESS,
} from 'flavours/glitch/actions/interactions';
import {
- COMPOSE_SUBMIT_SUCCESS,
-} from 'flavours/glitch/actions/compose';
-import {
- STATUS_FETCH_SUCCESS,
- CONTEXT_FETCH_SUCCESS,
STATUS_MUTE_SUCCESS,
STATUS_UNMUTE_SUCCESS,
} from 'flavours/glitch/actions/statuses';
import {
- TIMELINE_UPDATE,
TIMELINE_DELETE,
- TIMELINE_EXPAND_SUCCESS,
} from 'flavours/glitch/actions/timelines';
-import {
- NOTIFICATIONS_UPDATE,
- NOTIFICATIONS_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/notifications';
-import {
- FAVOURITED_STATUSES_FETCH_SUCCESS,
- FAVOURITED_STATUSES_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/favourites';
-import {
- BOOKMARKED_STATUSES_FETCH_SUCCESS,
- BOOKMARKED_STATUSES_EXPAND_SUCCESS,
-} from 'flavours/glitch/actions/bookmarks';
-import {
- PINNED_STATUSES_FETCH_SUCCESS,
-} from 'flavours/glitch/actions/pin_statuses';
-import { SEARCH_FETCH_SUCCESS } from 'flavours/glitch/actions/search';
-import emojify from 'flavours/glitch/util/emoji';
+import { STATUS_IMPORT, STATUSES_IMPORT } from '../actions/importer';
import { Map as ImmutableMap, fromJS } from 'immutable';
-import escapeTextContentForBrowser from 'escape-html';
-const domParser = new DOMParser();
+const importStatus = (state, status) => state.set(status.id, fromJS(status));
-const normalizeStatus = (state, status) => {
- if (!status) {
- return state;
- }
-
- const normalStatus = { ...status };
- normalStatus.account = status.account.id;
-
- if (status.reblog && status.reblog.id) {
- state = normalizeStatus(state, status.reblog);
- normalStatus.reblog = status.reblog.id;
- }
-
- // Only calculate these values when status first encountered
- // Otherwise keep the ones already in the reducer
- if (!state.has(status.id)) {
- const searchContent = [status.spoiler_text, status.content].join('\n\n').replace(/
/g, '\n').replace(/<\/p>
/g, '\n\n'); - - const emojiMap = normalStatus.emojis.reduce((obj, emoji) => { - obj[`:${emoji.shortcode}:`] = emoji; - return obj; - }, {}); - - normalStatus.search_index = domParser.parseFromString(searchContent, 'text/html').documentElement.textContent; - normalStatus.contentHtml = emojify(normalStatus.content, emojiMap); - normalStatus.spoilerHtml = emojify(escapeTextContentForBrowser(normalStatus.spoiler_text || ''), emojiMap); - } - - return state.update(status.id, ImmutableMap(), map => map.mergeDeep(fromJS(normalStatus))); -}; - -const normalizeStatuses = (state, statuses) => { - statuses.forEach(status => { - state = normalizeStatus(state, status); - }); - - return state; -}; +const importStatuses = (state, statuses) => + state.withMutations(mutable => statuses.forEach(status => importStatus(mutable, status))); const deleteStatus = (state, id, references) => { references.forEach(ref => { @@ -101,20 +33,10 @@ const initialState = ImmutableMap(); export default function statuses(state = initialState, action) { switch(action.type) { - case TIMELINE_UPDATE: - case STATUS_FETCH_SUCCESS: - case NOTIFICATIONS_UPDATE: - case COMPOSE_SUBMIT_SUCCESS: - return normalizeStatus(state, action.status); - case REBLOG_SUCCESS: - case UNREBLOG_SUCCESS: - case FAVOURITE_SUCCESS: - case UNFAVOURITE_SUCCESS: - case BOOKMARK_SUCCESS: - case UNBOOKMARK_SUCCESS: - case PIN_SUCCESS: - case UNPIN_SUCCESS: - return normalizeStatus(state, action.response); + case STATUS_IMPORT: + return importStatus(state, action.status); + case STATUSES_IMPORT: + return importStatuses(state, action.statuses); case FAVOURITE_REQUEST: return state.setIn([action.status.get('id'), 'favourited'], true); case FAVOURITE_FAIL: @@ -131,16 +53,6 @@ export default function statuses(state = initialState, action) { return state.setIn([action.id, 'muted'], true); case STATUS_UNMUTE_SUCCESS: return state.setIn([action.id, 'muted'], false); - case TIMELINE_EXPAND_SUCCESS: - case CONTEXT_FETCH_SUCCESS: - case NOTIFICATIONS_EXPAND_SUCCESS: - case FAVOURITED_STATUSES_FETCH_SUCCESS: - case FAVOURITED_STATUSES_EXPAND_SUCCESS: - case BOOKMARKED_STATUSES_FETCH_SUCCESS: - case BOOKMARKED_STATUSES_EXPAND_SUCCESS: - case PINNED_STATUSES_FETCH_SUCCESS: - case SEARCH_FETCH_SUCCESS: - return normalizeStatuses(state, action.statuses); case TIMELINE_DELETE: return deleteStatus(state, action.id, action.references); default: