|
1 | 1 | import type { PayloadAction } from '@reduxjs/toolkit';
|
2 | 2 | import { createSlice } from '@reduxjs/toolkit';
|
3 | 3 | import type { PersistConfig, RootState } from 'app/store/store';
|
4 |
| -import { uniqBy } from 'lodash-es'; |
| 4 | +import { isEqual, uniqBy } from 'lodash-es'; |
5 | 5 | import type { ImageDTO } from 'services/api/types';
|
6 | 6 |
|
7 | 7 | import type { BoardId, ComparisonMode, GalleryState, GalleryView, OrderDir } from './types';
|
@@ -32,10 +32,54 @@ export const gallerySlice = createSlice({
|
32 | 32 | initialState: initialGalleryState,
|
33 | 33 | reducers: {
|
34 | 34 | imageSelected: (state, action: PayloadAction<ImageDTO | null>) => {
|
35 |
| - state.selection = action.payload ? [action.payload] : []; |
| 35 | + // Let's be efficient here and not update the selection unless it has actually changed. This helps to prevent |
| 36 | + // unnecessary re-renders of the gallery. |
| 37 | + |
| 38 | + const selectedImage = action.payload; |
| 39 | + |
| 40 | + // If we got `null`, clear the selection |
| 41 | + if (!selectedImage) { |
| 42 | + // But only if we have images selected |
| 43 | + if (state.selection.length > 0) { |
| 44 | + state.selection = []; |
| 45 | + } |
| 46 | + return; |
| 47 | + } |
| 48 | + |
| 49 | + // If we have multiple images selected, clear the selection and select the new image |
| 50 | + if (state.selection.length !== 1) { |
| 51 | + state.selection = [selectedImage]; |
| 52 | + return; |
| 53 | + } |
| 54 | + |
| 55 | + // If the selected image is different from the current selection, clear the selection and select the new image |
| 56 | + if (isEqual(state.selection[0], selectedImage)) { |
| 57 | + state.selection = [selectedImage]; |
| 58 | + return; |
| 59 | + } |
| 60 | + |
| 61 | + // Else we have the same image selected, do nothing |
36 | 62 | },
|
37 | 63 | selectionChanged: (state, action: PayloadAction<ImageDTO[]>) => {
|
38 |
| - state.selection = uniqBy(action.payload, (i) => i.image_name); |
| 64 | + // Let's be efficient here and not update the selection unless it has actually changed. This helps to prevent |
| 65 | + // unnecessary re-renders of the gallery. |
| 66 | + |
| 67 | + // Remove duplicates from the selection |
| 68 | + const newSelection = uniqBy(action.payload, (i) => i.image_name); |
| 69 | + |
| 70 | + // If the new selection has a different length, update the selection |
| 71 | + if (newSelection.length !== state.selection.length) { |
| 72 | + state.selection = newSelection; |
| 73 | + return; |
| 74 | + } |
| 75 | + |
| 76 | + // If the new selection is different, update the selection |
| 77 | + if (!isEqual(newSelection, state.selection)) { |
| 78 | + state.selection = newSelection; |
| 79 | + return; |
| 80 | + } |
| 81 | + |
| 82 | + // Else we have the same selection, do nothing |
39 | 83 | },
|
40 | 84 | imageToCompareChanged: (state, action: PayloadAction<ImageDTO | null>) => {
|
41 | 85 | state.imageToCompare = action.payload;
|
|
0 commit comments