Skip to content

Commit bc60f19

Browse files
committed
feat: Only sync when online
1 parent f4758e1 commit bc60f19

File tree

6 files changed

+56
-12
lines changed

6 files changed

+56
-12
lines changed

src/App.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ import './base.css';
2828

2929
import Entry from './components/Entry';
3030

31-
import { listenToBrowserButtons, syncOnBecomingVisible } from './lib/initial_setup';
31+
import {
32+
listenToBrowserButtons,
33+
syncOnBecomingVisible,
34+
listenToNetworkConnectionEvents,
35+
} from './lib/initial_setup';
3236

3337
import _ from 'lodash';
3438
import { Map } from 'immutable';
@@ -145,6 +149,7 @@ export default class App extends PureComponent {
145149

146150
listenToBrowserButtons(this.store);
147151
syncOnBecomingVisible(this.store);
152+
listenToNetworkConnectionEvents(this.store);
148153

149154
_.bindAll(this, ['handleDragEnd']);
150155
}

src/actions/base.js

+5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ export const setIsLoading = (isLoading, path) => ({
1818
path,
1919
});
2020

21+
export const setIsOnline = (online) => ({
22+
type: 'SET_IS_ONLINE',
23+
online,
24+
});
25+
2126
export const setDisappearingLoadingMessage = (loadingMessage, delay) => (dispatch) => {
2227
dispatch(setLoadingMessage(loadingMessage));
2328
setTimeout(() => dispatch(hideLoadingMessage()), delay);

src/actions/org.js

+14-10
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,20 @@ const syncDebounced = (dispatch, getState, options) => {
7979
};
8080

8181
export const sync = (options) => (dispatch, getState) => {
82-
// If the user hits the 'sync' button, no matter if there's a sync
83-
// in progress or if the sync 'should' be debounced, listen to the
84-
// user and start a sync.
85-
if (options.forceAction === 'manual') {
86-
console.log('forcing sync');
87-
const files = getState().org.present.get('files');
88-
// sync all files on manual sync
89-
files.keySeq().forEach((path) => dispatch(doSync({ ...options, path })));
90-
} else {
91-
syncDebounced(dispatch, getState, options);
82+
// Don't do anything if the browser is not online. When it gets back
83+
// from an offline state, a new `sync`action will be triggered then.
84+
if (getState().base.get('online')) {
85+
// If the user hits the 'sync' button, no matter if there's a sync
86+
// in progress or if the sync 'should' be debounced, listen to the
87+
// user and start a sync.
88+
if (options.forceAction === 'manual') {
89+
console.log('forcing sync');
90+
const files = getState().org.present.get('files');
91+
// sync all files on manual sync
92+
files.keySeq().forEach((path) => dispatch(doSync({ ...options, path })));
93+
} else {
94+
syncDebounced(dispatch, getState, options);
95+
}
9296
}
9397
};
9498

src/components/OrgFile/components/ActionDrawer/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const ActionDrawer = ({
2626
selectedTableCellId,
2727
inEditMode,
2828
isLoading,
29+
online,
2930
shouldDisableSyncButtons,
3031
}) => {
3132
const [isDisplayingArrowButtons, setIsDisplayingArrowButtons] = useState(false);
@@ -354,7 +355,7 @@ const ActionDrawer = ({
354355
iconName="cloud"
355356
subIconName="sync-alt"
356357
shouldSpinSubIcon={isLoading}
357-
isDisabled={shouldDisableSyncButtons}
358+
isDisabled={shouldDisableSyncButtons || !online}
358359
onClick={handleSync}
359360
style={{
360361
opacity:
@@ -400,6 +401,7 @@ const mapStateToProps = (state) => {
400401
captureTemplates: state.capture.get('captureTemplates', List()),
401402
path,
402403
isLoading: !state.base.get('isLoading').isEmpty(),
404+
online: state.base.get('online'),
403405
};
404406
};
405407

src/lib/initial_setup.js

+22
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,30 @@
11
import { debounce } from 'lodash';
22

33
import { setPath, sync } from '../actions/org';
4+
import { setIsOnline } from '../actions/base';
45
import { STATIC_FILE_PREFIX } from './org_utils';
56

7+
// When offline, don't sync and don't enable sync button. When online,
8+
// enable sync button. When newly online, force sync of all things
9+
// possibly dirty.
10+
export function listenToNetworkConnectionEvents(store) {
11+
// Is the user online when starting up the application?
12+
store.dispatch(setIsOnline(navigator.onLine));
13+
14+
window.onoffline = function () {
15+
store.dispatch(setIsOnline(false));
16+
};
17+
18+
window.ononline = function () {
19+
store.dispatch(setIsOnline(true));
20+
// Add grace period, because browsers might get the event `onLine`
21+
// too soon to actually do network requests.
22+
setTimeout(() => {
23+
sync({ shouldSuppressMessages: true, forceAction: 'manual' })(store.dispatch, store.getState);
24+
}, 2000);
25+
};
26+
}
27+
628
// Generally, opening files and other routing is done with the
729
// `react-router-dom` package (i.e. `<Link/ > tags). However, organice
830
// also should react to browser buttons.

src/reducers/base.js

+6
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ const setIsLoading = (state, action) => {
114114
}
115115
};
116116

117+
const setIsOnline = (state, action) => {
118+
return state.set('online', action.online);
119+
};
120+
117121
const setAgendaTimeframe = (state, action) => state.set('agendaTimeframe', action.agendaTimeframe);
118122

119123
const setColorScheme = (state, action) => {
@@ -183,6 +187,8 @@ export default (state = Map(), action) => {
183187
return closePopup(state, action);
184188
case 'SET_IS_LOADING':
185189
return setIsLoading(state, action);
190+
case 'SET_IS_ONLINE':
191+
return setIsOnline(state, action);
186192
case 'SET_AGENDA_TIMEFRAME':
187193
return setAgendaTimeframe(state, action);
188194
default:

0 commit comments

Comments
 (0)