Commit 4e553155 authored by Lyza Danger Gardner's avatar Lyza Danger Gardner Committed by Lyza Gardner

Convert internal representation of `focusedAnnotations` to a maplike object

- Make internals of store state more consistent
- Prevent duplicate entries
- Allow for potential explicit `false` entries
parent 86382c83
/** /**
* This module handles state related to the current sort, search and filter * This module handles the state affecting the visibility and presence of
* settings in the UI, including: * annotations and threads in the UI.
*
* - The set of annotations that are currently focused (hovered) or selected
* - The selected tab
* - The current sort order
* - The current filter query
*/ */
/** /**
...@@ -92,8 +87,17 @@ const setTab = (selectedTab, newTab) => { ...@@ -92,8 +87,17 @@ const setTab = (selectedTab, newTab) => {
function init(settings) { function init(settings) {
return { return {
// An array of annotation `$tag`s representing annotations that are focused /**
focusedAnnotations: [], * The following objects map annotation identifiers to a boolean
* (typically `true`). They are objects (i.e. instead of Arrays) for two
* reasons:
* - Allows explicit setting of `false`
* - Prevents duplicate entries for a single annotation
*/
// A set of annotations that are currently "focused" — hovered over in
// the UI, e.g.
focused: {},
// Contains a map of annotation id:true pairs. // Contains a map of annotation id:true pairs.
selectedAnnotationMap: initialSelection(settings), selectedAnnotationMap: initialSelection(settings),
...@@ -153,7 +157,9 @@ const update = { ...@@ -153,7 +157,9 @@ const update = {
}, },
FOCUS_ANNOTATIONS: function (state, action) { FOCUS_ANNOTATIONS: function (state, action) {
return { focusedAnnotations: [...action.focusedTags] }; const focused = {};
action.focusedTags.forEach(tag => (focused[tag] = true));
return { focused };
}, },
SET_FOCUS_MODE_FOCUSED: function (state, action) { SET_FOCUS_MODE_FOCUSED: function (state, action) {
...@@ -311,9 +317,10 @@ function setForceVisible(id, visible) { ...@@ -311,9 +317,10 @@ function setForceVisible(id, visible) {
} }
/** /**
* Sets which annotations are currently focused. * Replace the current set of focused annotations with the annotations
* identified by `tags`
* *
* @param {string[]} tags - Tags of annotations to focus * @param {string[]} tags - Identifiers of annotations to focus
*/ */
function focusAnnotations(tags) { function focusAnnotations(tags) {
return { return {
...@@ -395,11 +402,17 @@ function setSortKey(key) { ...@@ -395,11 +402,17 @@ function setSortKey(key) {
}; };
} }
/* Selectors */
function focusedAnnotations(state) {
return Object.keys(state.selection.focused).filter(
id => state.selection.focused[id] === true
);
}
/** Is the annotation referenced by `$tag` currently focused? */ /** Is the annotation referenced by `$tag` currently focused? */
function isAnnotationFocused(state, $tag) { function isAnnotationFocused(state, $tag) {
return state.selection.focusedAnnotations.some( return state.selection.focused[$tag] === true;
focusedAnn => $tag && focusedAnn === $tag
);
} }
/** /**
...@@ -563,6 +576,7 @@ export default { ...@@ -563,6 +576,7 @@ export default {
focusModeHasUser, focusModeHasUser,
focusModeUserId, focusModeUserId,
focusModeUserPrettyName, focusModeUserPrettyName,
focusedAnnotations,
isAnnotationFocused, isAnnotationFocused,
isAnnotationSelected, isAnnotationSelected,
getFirstSelectedAnnotationId, getFirstSelectedAnnotationId,
......
...@@ -44,21 +44,21 @@ describe('sidebar/store/modules/selection', () => { ...@@ -44,21 +44,21 @@ describe('sidebar/store/modules/selection', () => {
describe('focusAnnotations()', function () { describe('focusAnnotations()', function () {
it('adds the provided annotation IDs to the focused annotations', function () { it('adds the provided annotation IDs to the focused annotations', function () {
store.focusAnnotations([1, 2, 3]); store.focusAnnotations(['1', '2', '3']);
assert.deepEqual(getSelectionState().focusedAnnotations, [1, 2, 3]); assert.deepEqual(store.focusedAnnotations(), ['1', '2', '3']);
}); });
it('replaces any other focused annotation IDs', function () { it('replaces any other focused annotation IDs', function () {
store.focusAnnotations([1]); store.focusAnnotations(['1']);
store.focusAnnotations([2, 3]); store.focusAnnotations(['2', '3']);
assert.deepEqual(getSelectionState().focusedAnnotations, [2, 3]); assert.deepEqual(store.focusedAnnotations(), ['2', '3']);
}); });
it('sets focused annotations to an empty array if no IDs provided', function () { it('sets focused annotations to an empty object if no IDs provided', function () {
store.focusAnnotations([1]); store.focusAnnotations(['1']);
store.focusAnnotations([]); store.focusAnnotations([]);
assert.isArray(getSelectionState().focusedAnnotations); assert.isObject(getSelectionState().focused);
assert.isEmpty(getSelectionState().focusedAnnotations); assert.isEmpty(getSelectionState().focused);
}); });
}); });
......
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