Skip to content

Commit 3e17e6f

Browse files
shakyShaneShane Osbourne
andauthored
ntp: send source index in move action (#1250)
* ntp: send source index in move action * cleanup interface * linting --------- Co-authored-by: Shane Osbourne <[email protected]>
1 parent e891989 commit 3e17e6f

File tree

8 files changed

+45
-16
lines changed

8 files changed

+45
-16
lines changed

special-pages/messages/new-tab/favorites_move.notify.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"type": "object",
55
"required": [
66
"id",
7+
"fromIndex",
78
"targetIndex"
89
],
910
"properties": {
@@ -14,6 +15,10 @@
1415
"targetIndex": {
1516
"description": "zero-indexed target",
1617
"type": "number"
18+
},
19+
"fromIndex": {
20+
"description": "zero-indexed source",
21+
"type": "number"
1722
}
1823
}
1924
}

special-pages/pages/new-tab/app/favorites/components/FavoritesProvider.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ import { reducer, useConfigSubscription, useDataSubscription, useInitialDataAndC
1212
* @typedef {import('../../../../../types/new-tab.ts').FavoritesOpenAction['target']} OpenTarget
1313
* @typedef {import('../../service.hooks.js').State<FavoritesData, FavoritesConfig>} State
1414
* @typedef {import('../../service.hooks.js').Events<FavoritesData, FavoritesConfig>} Events
15+
* @typedef {{id: string; url: string}} BaseFavoriteType
16+
*/
17+
18+
/**
19+
* @template {BaseFavoriteType} ItemType - allow any type that extends BaseFavoriteType
20+
* @typedef {(params: { list: ItemType[], id: string, fromIndex: number, targetIndex: number }) => void} ReorderFn
1521
*/
1622

1723
/**
@@ -24,8 +30,8 @@ export const FavoritesContext = createContext({
2430
toggle: () => {
2531
throw new Error('must implement');
2632
},
27-
/** @type {(list: Favorite[], id: string, targetIndex: number) => void} */
28-
favoritesDidReOrder: (list, id, targetIndex) => {
33+
/** @type {ReorderFn<Favorite>} */
34+
favoritesDidReOrder: ({ list, id, fromIndex, targetIndex }) => {
2935
throw new Error('must implement');
3036
},
3137
/** @type {(id: string) => void} */
@@ -68,11 +74,11 @@ export function FavoritesProvider({ children }) {
6874
// subscribe to toggle + expose a fn for sync toggling
6975
const { toggle } = useConfigSubscription({ dispatch, service });
7076

71-
/** @type {(f: Favorite[], id: string, targetIndex: number) => void} */
77+
/** @type {ReorderFn<Favorite>} */
7278
const favoritesDidReOrder = useCallback(
73-
(favorites, id, targetIndex) => {
79+
({ list, id, fromIndex, targetIndex }) => {
7480
if (!service.current) return;
75-
service.current.setFavoritesOrder({ favorites }, id, targetIndex);
81+
service.current.setFavoritesOrder({ favorites: list }, id, fromIndex, targetIndex);
7682
},
7783
[service],
7884
);

special-pages/pages/new-tab/app/favorites/components/PragmaticDND.js

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const InstanceIdContext = createContext(getInstanceId());
2424
* @param {object} props
2525
* @param {import("preact").ComponentChild} props.children
2626
* @param {T[]} props.items
27-
* @param {(list: T[], id: string, index: number) => void} props.itemsDidReOrder
27+
* @param {import('./FavoritesProvider.js').ReorderFn<{id: string; url: string}>} props.itemsDidReOrder
2828
*/
2929
export function PragmaticDND({ children, items, itemsDidReOrder }) {
3030
/**
@@ -43,7 +43,7 @@ export function PragmaticDND({ children, items, itemsDidReOrder }) {
4343
/**
4444
* @template {{id: string; url: string}} T
4545
* @param {T[]} favorites
46-
* @param {(items: T[], id: string, target: number) => void} itemsDidReOrder
46+
* @param {import('./FavoritesProvider.js').ReorderFn<{id: string; url: string}>} itemsDidReOrder
4747
* @param {symbol} instanceId
4848
*/
4949
function useGridState(favorites, itemsDidReOrder, instanceId) {
@@ -89,7 +89,12 @@ function useGridState(favorites, itemsDidReOrder, instanceId) {
8989
axis: 'horizontal',
9090
});
9191

92-
itemsDidReOrder(favorites, id, targetIndex);
92+
itemsDidReOrder({
93+
list: favorites,
94+
id,
95+
fromIndex: favorites.length,
96+
targetIndex,
97+
});
9398
},
9499
}),
95100
monitorForElements({
@@ -147,7 +152,12 @@ function useGridState(favorites, itemsDidReOrder, instanceId) {
147152

148153
flushSync(() => {
149154
try {
150-
itemsDidReOrder(reorderedList, startId, targetIndex);
155+
itemsDidReOrder({
156+
list: reorderedList,
157+
id: startId,
158+
fromIndex: startIndex,
159+
targetIndex,
160+
});
151161
} catch (e) {
152162
console.error('did catch', e);
153163
}

special-pages/pages/new-tab/app/favorites/favorites.service.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,10 @@ export class FavoritesService {
8383
* @param {FavoritesData} data
8484
* @param {string} id - entity id to move
8585
* @param {number} targetIndex - target index
86+
* @param {number} fromIndex - from index
8687
* @internal
8788
*/
88-
setFavoritesOrder(data, id, targetIndex) {
89+
setFavoritesOrder(data, id, fromIndex, targetIndex) {
8990
// update in memory instantly - this will broadcast changes to all listeners
9091

9192
this.dataService.update((_old) => {
@@ -96,6 +97,7 @@ export class FavoritesService {
9697
this.ntp.messaging.notify('favorites_move', {
9798
id,
9899
targetIndex,
100+
fromIndex,
99101
});
100102
}
101103

special-pages/pages/new-tab/app/favorites/integration-tests/favorites.page.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,13 @@ export class FavoritesPage {
157157
return { id };
158158
}
159159

160-
async sent({ id, targetIndex }) {
160+
async sent({ id, fromIndex, targetIndex }) {
161161
const calls = await this.ntp.mocks.waitForCallCount({ method: 'favorites_move', count: 1 });
162162
expect(calls[0].payload).toStrictEqual({
163163
context: 'specialPages',
164164
featureName: 'newTabPage',
165165
method: 'favorites_move',
166-
params: { id, targetIndex },
166+
params: { id, fromIndex, targetIndex },
167167
});
168168
}
169169

@@ -259,6 +259,7 @@ export class FavoritesPage {
259259
params: {
260260
id: '3',
261261
targetIndex: index,
262+
fromIndex: 15, // this is the length of the list, and it gets dropped at the end in the test.
262263
},
263264
});
264265
}

special-pages/pages/new-tab/app/favorites/integration-tests/favorites.spec.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ test.describe('newtab favorites', () => {
7878
await ntp.reducedMotion();
7979
await ntp.openPage();
8080
const { id } = await favorites.drags({ index: 0, to: 2 });
81-
await favorites.sent({ id, targetIndex: 2 });
81+
await favorites.sent({ id, fromIndex: 0, targetIndex: 2 });
8282
});
8383
test('support drop on placeholders', async ({ page }, workerInfo) => {
8484
const ntp = NewtabPage.create(page, workerInfo);
@@ -93,7 +93,7 @@ test.describe('newtab favorites', () => {
9393
const PLACEHOLDER_INDEX = 4;
9494
const EXPECTED_TARGET_INDEX = 2;
9595
const { id } = await favorites.drags({ index: 0, to: PLACEHOLDER_INDEX });
96-
await favorites.sent({ id, targetIndex: EXPECTED_TARGET_INDEX });
96+
await favorites.sent({ id, fromIndex: 0, targetIndex: EXPECTED_TARGET_INDEX });
9797
});
9898
test('accepts external drag/drop', async ({ page }, workerInfo) => {
9999
const ntp = NewtabPage.create(page, workerInfo);

special-pages/pages/new-tab/app/favorites/mocks/MockFavoritesProvider.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,9 @@ export function MockFavoritesProvider({ data = favorites.many, config = DEFAULT_
4545
}
4646
}, [state.status, state.config?.expansion, isReducedMotion]);
4747

48-
const favoritesDidReOrder = useCallback((/** @type {Favorite[]} */ newList) => {
49-
dispatch({ kind: 'data', data: { favorites: newList } });
48+
/** @type {import('../components/FavoritesProvider.js').ReorderFn<Favorite>} */
49+
const favoritesDidReOrder = useCallback(({ list }) => {
50+
dispatch({ kind: 'data', data: { favorites: list } });
5051
}, []);
5152

5253
const openContextMenu = (...args) => {

special-pages/types/new-tab.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ export interface FavoritesMoveAction {
120120
* zero-indexed target
121121
*/
122122
targetIndex: number;
123+
/**
124+
* zero-indexed source
125+
*/
126+
fromIndex: number;
123127
}
124128
/**
125129
* Generated from @see "../messages/new-tab/favorites_open.notify.json"

0 commit comments

Comments
 (0)