Newer
Older
import * as sharedListeners from 'loot-core/src/client/shared-listeners';
import { listen } from 'loot-core/src/platform/client/fetch';
import * as undo from 'loot-core/src/platform/client/undo';
export function handleGlobalEvents(actions, store) {
global.Actual.onEventFromMain('update-downloaded', (event, info) => {
actions.setAppState({ updateInfo: info });
});
global.Actual.onEventFromMain('update-error', msg => {
// Ignore errors. We don't want to constantly bug the user if they
// always have a flaky connection or have intentionally disabled
// updates. They will see the error in the about page if they try
// to update.
});
listen('server-error', info => {
actions.addGenericErrorNotification();
});
listen('update-loading-status', status => {
switch (status) {
case 'updating':
actions.updateStatusText('Updating...');
break;
default:
}
});
listen('orphaned-payees', ({ orphanedIds, updatedPayeeIds }) => {
// Right now, it prompts to merge into the first payee
actions.pushModal('merge-unused-payees', {
payeeIds: orphanedIds,
targetPayeeId: updatedPayeeIds[0],
});
});
listen('schedules-offline', ({ payees }) => {
actions.pushModal(`schedule-posts-offline-notification`, { payees });
});
// This is experimental: we sync data locally automatically when
// data changes from the backend
listen('sync-event', async ({ type, tables }) => {
// We don't need to query anything until the file is loaded, and
// sync events might come in if the file is being synced before
// being loaded (happens when downloading)
let prefs = store.getState().prefs.local;
if (prefs && prefs.id) {
if (type === 'applied') {
if (tables.includes('payees') || tables.includes('payee_mapping')) {
actions.getPayees();
}
}
}
});
// TODO: Should this run on mobile too?
listen('sync-event', async ({ type }) => {
if (type === 'unauthorized') {
actions.addNotification({
type: 'warning',
message: 'Unable to authenticate with server',
sticky: true,
});
}
});
sharedListeners.listenForSyncEvent(actions, store);
listen('undo-event', undoState => {
let { tables, undoTag } = undoState;
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
let promises = [];
if (
tables.includes('categories') ||
tables.includes('category_groups') ||
tables.includes('category_mapping')
) {
promises.push(actions.getCategories());
}
if (tables.includes('accounts')) {
promises.push(actions.getAccounts());
}
let tagged = undo.getTaggedState(undoTag);
if (tagged) {
Promise.all(promises).then(() => {
actions.setLastUndoState(undoState);
// If a modal has been tagged, open it instead of navigating
if (tagged.openModal) {
let { modalStack } = store.getState().modals;
if (
modalStack.length === 0 ||
modalStack[modalStack.length - 1].name !== tagged.openModal
) {
actions.replaceModal(tagged.openModal);
}
} else {
actions.closeModal();
if (
window.location.href.replace(window.location.origin, '') !==
tagged.url
) {
window.__navigate(tagged.url);
// This stops propagation of the undo event, which is
// important because if we are changing URLs any existing
// undo listeners on the current page don't need to be run
return true;
}
}
});
}
});
listen('fallback-write-error', () => {
actions.addNotification({
type: 'error',
title: 'Unable to save changes',
sticky: true,
message:
'This browser only supports using the app in one tab at a time, ' +
'and another tab has opened the app. No changes will be saved ' +
'from this tab; please close it and continue working in the other one.',
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
});
});
listen('start-load', () => {
actions.closeBudgetUI();
actions.setAppState({ loadingText: '' });
});
listen('finish-load', () => {
actions.closeModal();
actions.setAppState({ loadingText: null });
actions.loadPrefs();
});
listen('start-import', () => {
actions.closeBudgetUI();
});
listen('finish-import', () => {
actions.closeModal();
actions.setAppState({ loadingText: null });
actions.loadPrefs();
});
listen('show-budgets', () => {
actions.closeBudgetUI();
actions.setAppState({ loadingText: null });
});
}