diff --git a/app/soapbox/actions/importer/index.js b/app/soapbox/actions/importer/index.js index a9c7cd9f6..7989b3ebe 100644 --- a/app/soapbox/actions/importer/index.js +++ b/app/soapbox/actions/importer/index.js @@ -12,8 +12,8 @@ export const STATUS_IMPORT = 'STATUS_IMPORT'; export const STATUSES_IMPORT = 'STATUSES_IMPORT'; export const POLLS_IMPORT = 'POLLS_IMPORT'; export const ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP = 'ACCOUNT_FETCH_FAIL_FOR_USERNAME_LOOKUP'; -export const CHAT_IMPORT = 'CHAT_IMPORT'; export const CHATS_IMPORT = 'CHATS_IMPORT'; +export const CHAT_MESSAGES_IMPORT = 'CHAT_MESSAGES_IMPORT'; function pushUnique(array, object) { if (array.every(element => element.id !== object.id)) { @@ -41,14 +41,14 @@ export function importPolls(polls) { return { type: POLLS_IMPORT, polls }; } -export function importChat(chat) { - return { type: CHAT_IMPORT, chat }; -} - export function importChats(chats) { return { type: CHATS_IMPORT, chats }; } +export function importChatMessages(chatMessages) { + return { type: CHAT_MESSAGES_IMPORT, chatMessages }; +} + export function importFetchedAccount(account) { return importFetchedAccounts([account]); } @@ -120,6 +120,7 @@ export function importFetchedChat(chat) { export function importFetchedChats(chats) { return (dispatch, getState) => { const accounts = []; + const chatMessages = []; const normalChats = []; function processChat(chat) { @@ -127,11 +128,13 @@ export function importFetchedChats(chats) { pushUnique(normalChats, normalizeChat(chat, normalOldChat)); pushUnique(accounts, chat.account); + pushUnique(chatMessages, chat.last_message); } chats.forEach(processChat); dispatch(importFetchedAccounts(accounts)); + dispatch(importChatMessages(chatMessages)); dispatch(importChats(normalChats)); }; } diff --git a/app/soapbox/reducers/chat_message_lists.js b/app/soapbox/reducers/chat_message_lists.js new file mode 100644 index 000000000..c05b4e85e --- /dev/null +++ b/app/soapbox/reducers/chat_message_lists.js @@ -0,0 +1,36 @@ +import { + CHAT_MESSAGES_FETCH_SUCCESS, + CHAT_MESSAGE_SEND_SUCCESS, +} from 'soapbox/actions/chats'; +import { CHAT_MESSAGES_IMPORT } from 'soapbox/actions/importer'; +import { Map as ImmutableMap, OrderedSet as ImmutableOrderedSet } from 'immutable'; + +const initialState = ImmutableMap(); + +const updateList = (state, chatId, messageIds) => { + const newIds = state.get(chatId, ImmutableOrderedSet()).union(messageIds); + return state.set(chatId, newIds); +}; + +const importMessage = (state, chatMessage) => { + return updateList(state, chatMessage.chat_id, [chatMessage.id]); +}; + +const importMessages = (state, chatMessages) => ( + state.withMutations(map => + chatMessages.forEach(chatMessage => + importMessage(map, chatMessage))) +); + +export default function chatMessageLists(state = initialState, action) { + switch(action.type) { + case CHAT_MESSAGES_IMPORT: + return importMessages(state, action.chatMessages); + case CHAT_MESSAGES_FETCH_SUCCESS: + return updateList(state, action.chatId, action.data.map(chat => chat.id)); + case CHAT_MESSAGE_SEND_SUCCESS: + return updateList(state, action.chatId, action.data.id); + default: + return state; + } +}; diff --git a/app/soapbox/reducers/chat_messages.js b/app/soapbox/reducers/chat_messages.js index b79ab2820..d7f9b3c29 100644 --- a/app/soapbox/reducers/chat_messages.js +++ b/app/soapbox/reducers/chat_messages.js @@ -2,20 +2,18 @@ import { CHAT_MESSAGES_FETCH_SUCCESS, CHAT_MESSAGE_SEND_SUCCESS, } from 'soapbox/actions/chats'; -import { CHAT_IMPORT, CHATS_IMPORT } from 'soapbox/actions/importer'; -import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable'; +import { CHATS_IMPORT } from 'soapbox/actions/importer'; +import { Map as ImmutableMap, fromJS } from 'immutable'; const initialState = ImmutableMap(); -const insertMessage = (state, chatId, message) => { - const newMessages = state.get(chatId, ImmutableList()).insert(0, message); - return state.set(chatId, newMessages); +const importMessage = (state, message) => { + return state.set(message.get('id'), message); }; -const importMessage = (state, message) => { - const chatId = message.get('chat_id'); - return insertMessage(state, chatId, message); -}; +const importMessages = (state, messages) => + state.withMutations(mutable => + messages.forEach(message => importMessage(mutable, message))); const importLastMessages = (state, chats) => state.withMutations(mutable => @@ -23,15 +21,12 @@ const importLastMessages = (state, chats) => export default function chatMessages(state = initialState, action) { switch(action.type) { - case CHAT_IMPORT: - return importMessage(state, fromJS(action.chat.last_message)); case CHATS_IMPORT: return importLastMessages(state, fromJS(action.chats)); case CHAT_MESSAGES_FETCH_SUCCESS: - return state.set(action.chatId, fromJS(action.data)); - // TODO: Prevent conflicts - // case CHAT_MESSAGE_SEND_SUCCESS: - // return insertMessage(state, action.chatId, fromJS(action.data)); + return importMessages(state, fromJS(action.data)); + case CHAT_MESSAGE_SEND_SUCCESS: + return importMessage(state, fromJS(action.data)); default: return state; } diff --git a/app/soapbox/reducers/chats.js b/app/soapbox/reducers/chats.js index 244c76b85..2930af578 100644 --- a/app/soapbox/reducers/chats.js +++ b/app/soapbox/reducers/chats.js @@ -1,4 +1,4 @@ -import { CHAT_IMPORT, CHATS_IMPORT } from 'soapbox/actions/importer'; +import { CHATS_IMPORT } from 'soapbox/actions/importer'; import { Map as ImmutableMap, fromJS } from 'immutable'; const importChat = (state, chat) => state.set(chat.id, fromJS(chat)); @@ -10,8 +10,6 @@ const initialState = ImmutableMap(); export default function chats(state = initialState, action) { switch(action.type) { - case CHAT_IMPORT: - return importChat(state, action.chat); case CHATS_IMPORT: return importChats(state, action.chats); default: diff --git a/app/soapbox/reducers/index.js b/app/soapbox/reducers/index.js index 320b78036..2caec469a 100644 --- a/app/soapbox/reducers/index.js +++ b/app/soapbox/reducers/index.js @@ -45,6 +45,7 @@ import auth from './auth'; import admin from './admin'; import chats from './chats'; import chat_messages from './chat_messages'; +import chat_message_lists from './chat_message_lists'; const reducers = { dropdown_menu, @@ -93,6 +94,7 @@ const reducers = { admin, chats, chat_messages, + chat_message_lists, }; export default combineReducers(reducers);