Unverified Commit e3945627 authored by Kyle Keating's avatar Kyle Keating Committed by GitHub

Merge pull request #1327 from hypothesis/namespace-realtimeupdates-module

Namespace realtimeupdates module
parents 8017d7c1 7f3b8672
...@@ -26,42 +26,11 @@ function init() { ...@@ -26,42 +26,11 @@ function init() {
} }
const update = { const update = {
RECEIVE_REAL_TIME_UPDATES( RECEIVE_REAL_TIME_UPDATES(state, action) {
state, return {
{ updatedAnnotations = [], deletedAnnotations = [] } pendingUpdates: { ...action.pendingUpdates },
) { pendingDeletions: { ...action.pendingDeletions },
const pendingUpdates = { ...state.pendingUpdates }; };
const pendingDeletions = { ...state.pendingDeletions };
updatedAnnotations.forEach(ann => {
// In the sidebar, only save pending updates for annotations in the
// focused group, since we only display annotations from the focused
// group and reload all annotations and discard pending updates
// when switching groups.
if (
ann.group === groupSelectors.focusedGroupId(state) ||
!viewerSelectors.isSidebar(state)
) {
pendingUpdates[ann.id] = ann;
}
});
deletedAnnotations.forEach(ann => {
// Discard any pending but not-yet-applied updates for this annotation
delete pendingUpdates[ann.id];
// If we already have this annotation loaded, then record a pending
// deletion. We do not check the group of the annotation here because a)
// that information is not included with deletion notifications and b)
// even if the annotation is from the current group, it might be for a
// new annotation (saved in pendingUpdates and removed above), that has
// not yet been loaded.
if (annotationSelectors.annotationExists(state, ann.id)) {
pendingDeletions[ann.id] = true;
}
});
return { pendingUpdates, pendingDeletions };
}, },
CLEAR_PENDING_UPDATES() { CLEAR_PENDING_UPDATES() {
...@@ -114,11 +83,45 @@ const actions = actionTypes(update); ...@@ -114,11 +83,45 @@ const actions = actionTypes(update);
* @param {Annotation[]} args.updatedAnnotations * @param {Annotation[]} args.updatedAnnotations
* @param {Annotation[]} args.deletedAnnotations * @param {Annotation[]} args.deletedAnnotations
*/ */
function receiveRealTimeUpdates({ updatedAnnotations, deletedAnnotations }) { function receiveRealTimeUpdates({
return { updatedAnnotations = [],
deletedAnnotations = [],
}) {
return (dispatch, getState) => {
const pendingUpdates = { ...getState().realTimeUpdates.pendingUpdates };
const pendingDeletions = { ...getState().realTimeUpdates.pendingDeletions };
updatedAnnotations.forEach(ann => {
// In the sidebar, only save pending updates for annotations in the
// focused group, since we only display annotations from the focused
// group and reload all annotations and discard pending updates
// when switching groups.
if (
ann.group === groupSelectors.focusedGroupId(getState().base) ||
!viewerSelectors.isSidebar(getState().base)
) {
pendingUpdates[ann.id] = ann;
}
});
deletedAnnotations.forEach(ann => {
// Discard any pending but not-yet-applied updates for this annotation
delete pendingUpdates[ann.id];
// If we already have this annotation loaded, then record a pending
// deletion. We do not check the group of the annotation here because a)
// that information is not included with deletion notifications and b)
// even if the annotation is from the current group, it might be for a
// new annotation (saved in pendingUpdates and removed above), that has
// not yet been loaded.
if (annotationSelectors.annotationExists(getState().base, ann.id)) {
pendingDeletions[ann.id] = true;
}
});
dispatch({
type: actions.RECEIVE_REAL_TIME_UPDATES, type: actions.RECEIVE_REAL_TIME_UPDATES,
updatedAnnotations, pendingUpdates,
deletedAnnotations, pendingDeletions,
});
}; };
} }
...@@ -138,7 +141,7 @@ function clearPendingUpdates() { ...@@ -138,7 +141,7 @@ function clearPendingUpdates() {
* @return {{[id: string]: Annotation}} * @return {{[id: string]: Annotation}}
*/ */
function pendingUpdates(state) { function pendingUpdates(state) {
return state.pendingUpdates; return state.realTimeUpdates.pendingUpdates;
} }
/** /**
...@@ -148,14 +151,17 @@ function pendingUpdates(state) { ...@@ -148,14 +151,17 @@ function pendingUpdates(state) {
* @return {{[id: string]: boolean}} * @return {{[id: string]: boolean}}
*/ */
function pendingDeletions(state) { function pendingDeletions(state) {
return state.pendingDeletions; return state.realTimeUpdates.pendingDeletions;
} }
/** /**
* Return a total count of pending updates and deletions. * Return a total count of pending updates and deletions.
*/ */
const pendingUpdateCount = createSelector( const pendingUpdateCount = createSelector(
state => [state.pendingUpdates, state.pendingDeletions], state => [
state.realTimeUpdates.pendingUpdates,
state.realTimeUpdates.pendingDeletions,
],
([pendingUpdates, pendingDeletions]) => ([pendingUpdates, pendingDeletions]) =>
Object.keys(pendingUpdates).length + Object.keys(pendingDeletions).length Object.keys(pendingUpdates).length + Object.keys(pendingDeletions).length
); );
...@@ -165,11 +171,12 @@ const pendingUpdateCount = createSelector( ...@@ -165,11 +171,12 @@ const pendingUpdateCount = createSelector(
* has not yet been applied. * has not yet been applied.
*/ */
function hasPendingDeletion(state, id) { function hasPendingDeletion(state, id) {
return state.pendingDeletions.hasOwnProperty(id); return state.realTimeUpdates.pendingDeletions.hasOwnProperty(id);
} }
module.exports = { module.exports = {
init, init,
namespace: 'realTimeUpdates',
update, update,
actions: { actions: {
receiveRealTimeUpdates, receiveRealTimeUpdates,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment