Skip to content

Commit 5d6f263

Browse files
committed
handle sideeffects
1 parent 9e5e69e commit 5d6f263

File tree

1 file changed

+36
-30
lines changed

1 file changed

+36
-30
lines changed

special-pages/pages/history/app/global/Providers/SelectionProvider.js

Lines changed: 36 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { useHistoryServiceDispatch, useResultsData } from './HistoryServiceProvi
1717
* | {kind: 'toggle-index'; index: number; reason?: string}
1818
* | {kind: 'expand-selected-to-index'; index: number; reason?: string}
1919
* | {kind: 'inc-or-dec-selected'; nextIndex: number; reason?: string}
20-
* | {kind: 'select-next-or-prev'; index: number; reason?: string}
20+
* | {kind: 'move-selection'; direction: 'up' | 'down'; total: number; reason?: string}
2121
* | {kind: 'increment-selection'; direction: 'up' | 'down'; total: number; reason?: string}
2222
* | {kind: 'reset'; reason?: string}
2323
* } Action
@@ -40,11 +40,18 @@ export function SelectionProvider({ children }) {
4040
* @param {Action} evt
4141
*/
4242
function dispatch(evt) {
43-
console.log(JSON.stringify(evt));
43+
console.log(evt);
4444
const next = reducer(state.value, evt);
4545
state.value = next;
46+
47+
// after-effects?
48+
if (evt.kind === 'move-selection' || evt.kind === 'increment-selection') {
49+
const match = document.querySelector(`[aria-selected][data-index="${state.value.focusedIndex}"]`);
50+
match?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
51+
}
4652
}
4753
const dispatcher = useCallback(dispatch, [state, selected]);
54+
4855
return (
4956
<SelectionContext.Provider value={selected}>
5057
<FocussedContext.Provider value={focussed}>
@@ -59,7 +66,7 @@ export function useSelected() {
5966
return useContext(SelectionContext);
6067
}
6168

62-
export function useFocussedIndex() {
69+
function useFocussedIndex() {
6370
return useContext(FocussedContext);
6471
}
6572

@@ -88,7 +95,21 @@ function reducer(prev, evt) {
8895
case 'reset': {
8996
return { ...defaultState };
9097
}
91-
case 'select-next-or-prev':
98+
case 'move-selection': {
99+
const { focusedIndex } = prev;
100+
invariant(focusedIndex !== null);
101+
const delta = evt.direction === 'up' ? -1 : 1;
102+
// either the last item, or current + 1
103+
const max = Math.min(evt.total - 1, focusedIndex + delta);
104+
const newIndex = Math.max(0, max);
105+
const newSelected = new Set([newIndex]);
106+
return {
107+
anchorIndex: newIndex,
108+
focusedIndex: newIndex,
109+
lastShiftRange: { start: null, end: null },
110+
selected: newSelected,
111+
};
112+
}
92113
case 'select-index': {
93114
const newSelected = new Set([evt.index]);
94115
return {
@@ -167,11 +188,11 @@ function reducer(prev, evt) {
167188
};
168189
}
169190
case 'increment-selection': {
170-
const { focusedIndex } = prev;
191+
const { focusedIndex, anchorIndex, lastShiftRange } = prev;
171192
invariant(focusedIndex !== null);
172193
const delta = evt.direction === 'up' ? -1 : 1;
173194
const newIndex = Math.max(0, Math.min(evt.total - 1, focusedIndex + delta));
174-
const { anchorIndex, lastShiftRange } = prev;
195+
175196
// Handle shift+arrow selection
176197
const newSelected = new Set(prev.selected);
177198

@@ -263,54 +284,39 @@ export function useRowInteractions(mainRef) {
263284
* @return {boolean} true if we handled this event
264285
*/
265286
function handleKeyIntention(intention) {
266-
// prettier-ignore
267-
const direction = intention === 'shift+up' || intention === 'up'
268-
? -1
269-
: 1;
270-
287+
const total = results.value.items.length;
271288
if (focusedIndex.value === null) return false;
272-
const newIndex = Math.max(0, Math.min(results.value.items.length - 1, focusedIndex.value + direction));
273289

274290
switch (intention) {
275291
case 'shift+down': {
276292
dispatch({
277293
kind: 'increment-selection',
278294
direction: 'down',
279-
total: results.value.items.length,
295+
total,
280296
});
281-
break;
297+
return true;
282298
}
283299
case 'shift+up': {
284300
dispatch({
285301
kind: 'increment-selection',
286302
direction: 'up',
287-
total: results.value.items.length,
303+
total,
288304
});
289-
break;
305+
return true;
290306
}
291307
case 'up':
308+
dispatch({ kind: 'move-selection', direction: 'up', total });
309+
return true;
292310
case 'down': {
293-
dispatch({ kind: 'select-next-or-prev', index: newIndex });
294-
break;
311+
dispatch({ kind: 'move-selection', direction: 'down', total });
312+
return true;
295313
}
296314
case 'delete': {
297315
if (selected.value.size === 0) break;
298316
historyDispatch({ kind: 'delete-entries-by-index', value: [...selected.value] });
299317
break;
300318
}
301319
}
302-
303-
switch (intention) {
304-
case 'shift+down':
305-
case 'shift+up':
306-
case 'up':
307-
case 'down': {
308-
const match = document.querySelector(`[aria-selected][data-index="${newIndex}"]`);
309-
match?.scrollIntoView({ block: 'nearest', inline: 'nearest' });
310-
return true;
311-
}
312-
}
313-
314320
return false;
315321
}
316322
/**

0 commit comments

Comments
 (0)