mirror of
https://github.com/SPLURT-Station/S.P.L.U.R.T-Station-13.git
synced 2025-12-10 18:02:57 +00:00
120 lines
3.6 KiB
JavaScript
120 lines
3.6 KiB
JavaScript
/**
|
|
* @file
|
|
* @copyright 2020 Aleksej Komarov
|
|
* @license MIT
|
|
*/
|
|
|
|
import { storage } from 'common/storage';
|
|
import { loadSettings, updateSettings } from '../settings/actions';
|
|
import { selectSettings } from '../settings/selectors';
|
|
import { addChatPage, changeChatPage, changeScrollTracking, loadChat, rebuildChat, toggleAcceptedType, updateMessageCount, removeChatPage, saveChatToDisk } from './actions';
|
|
import { MAX_PERSISTED_MESSAGES, MESSAGE_SAVE_INTERVAL } from './constants';
|
|
import { createMessage, serializeMessage } from './model';
|
|
import { chatRenderer } from './renderer';
|
|
import { selectChat, selectCurrentChatPage } from './selectors';
|
|
import { logger } from 'tgui/logging';
|
|
|
|
const saveChatToStorage = async store => {
|
|
const state = selectChat(store.getState());
|
|
const fromIndex = Math.max(0,
|
|
chatRenderer.messages.length - MAX_PERSISTED_MESSAGES);
|
|
const messages = chatRenderer.messages
|
|
.slice(fromIndex)
|
|
.map(message => serializeMessage(message));
|
|
storage.set('chat-state', state);
|
|
storage.set('chat-messages', messages);
|
|
};
|
|
|
|
const loadChatFromStorage = async store => {
|
|
const [state, messages] = await Promise.all([
|
|
storage.get('chat-state'),
|
|
storage.get('chat-messages'),
|
|
]);
|
|
// Discard incompatible versions
|
|
if (state && state.version <= 4) {
|
|
store.dispatch(loadChat());
|
|
return;
|
|
}
|
|
if (messages) {
|
|
const batch = [
|
|
...messages,
|
|
createMessage({
|
|
type: 'internal/reconnected',
|
|
}),
|
|
];
|
|
chatRenderer.processBatch(batch, {
|
|
prepend: true,
|
|
});
|
|
}
|
|
store.dispatch(loadChat(state));
|
|
};
|
|
|
|
export const chatMiddleware = store => {
|
|
let initialized = false;
|
|
let loaded = false;
|
|
chatRenderer.events.on('batchProcessed', countByType => {
|
|
// Use this flag to workaround unread messages caused by
|
|
// loading them from storage. Side effect of that, is that
|
|
// message count can not be trusted, only unread count.
|
|
if (loaded) {
|
|
store.dispatch(updateMessageCount(countByType));
|
|
}
|
|
});
|
|
chatRenderer.events.on('scrollTrackingChanged', scrollTracking => {
|
|
store.dispatch(changeScrollTracking(scrollTracking));
|
|
});
|
|
setInterval(() => saveChatToStorage(store), MESSAGE_SAVE_INTERVAL);
|
|
return next => action => {
|
|
const { type, payload } = action;
|
|
if (!initialized) {
|
|
initialized = true;
|
|
loadChatFromStorage(store);
|
|
}
|
|
if (type === 'chat/message') {
|
|
// Normalize the payload
|
|
const batch = Array.isArray(payload) ? payload : [payload];
|
|
chatRenderer.processBatch(batch);
|
|
return;
|
|
}
|
|
if (type === loadChat.type) {
|
|
next(action);
|
|
const page = selectCurrentChatPage(store.getState());
|
|
chatRenderer.changePage(page);
|
|
chatRenderer.onStateLoaded();
|
|
loaded = true;
|
|
return;
|
|
}
|
|
if (type === changeChatPage.type
|
|
|| type === addChatPage.type
|
|
|| type === removeChatPage.type
|
|
|| type === toggleAcceptedType.type) {
|
|
next(action);
|
|
const page = selectCurrentChatPage(store.getState());
|
|
chatRenderer.changePage(page);
|
|
return;
|
|
}
|
|
if (type === rebuildChat.type) {
|
|
chatRenderer.rebuildChat();
|
|
return next(action);
|
|
}
|
|
if (type === updateSettings.type || type === loadSettings.type) {
|
|
next(action);
|
|
const settings = selectSettings(store.getState());
|
|
chatRenderer.setHighlight(
|
|
settings.highlightText,
|
|
settings.highlightColor);
|
|
return;
|
|
}
|
|
if (type === 'roundrestart') {
|
|
// Save chat as soon as possible
|
|
saveChatToStorage(store);
|
|
return next(action);
|
|
}
|
|
if (type === saveChatToDisk.type) {
|
|
chatRenderer.saveToDisk();
|
|
return;
|
|
}
|
|
return next(action);
|
|
};
|
|
};
|