From bcd60253c34f6494524e3764331a4d3d22635d9c Mon Sep 17 00:00:00 2001 From: Eugen Ciur Date: Wed, 11 Sep 2024 06:45:35 +0200 Subject: [PATCH] thumbnail selection --- ui2/src/components/Viewer/Page/Page.tsx | 11 +-- .../components/Viewer/Thumbnail/Thumbnail.tsx | 11 +-- ui2/src/features/ui/uiSlice.ts | 71 ++++++++++++++++--- ui2/src/slices/dualPanel/dualPanel.ts | 21 +----- ui2/src/slices/dualPanel/helpers.ts | 60 ++-------------- 5 files changed, 79 insertions(+), 95 deletions(-) diff --git a/ui2/src/components/Viewer/Page/Page.tsx b/ui2/src/components/Viewer/Page/Page.tsx index a69ba3769..680334c4e 100644 --- a/ui2/src/components/Viewer/Page/Page.tsx +++ b/ui2/src/components/Viewer/Page/Page.tsx @@ -1,4 +1,4 @@ -import {RootState} from "@/app/types" +import {useAppSelector} from "@/app/hooks" import PanelContext from "@/contexts/PanelContext" import {useGetPageImageQuery} from "@/features/pages/apiSlice" import {selectZoomFactor} from "@/features/ui/uiSlice" @@ -6,7 +6,6 @@ import {selectDocumentCurrentPage} from "@/slices/dualPanel/dualPanel" import {PageAndRotOp, PanelMode} from "@/types" import {Stack} from "@mantine/core" import {useContext, useEffect, useRef} from "react" -import {useSelector} from "react-redux" import classes from "./Page.module.css" type Args = { @@ -16,13 +15,9 @@ type Args = { export default function Page({page}: Args) { const {data} = useGetPageImageQuery(page.page.id) const mode: PanelMode = useContext(PanelContext) - const currentPage = useSelector((state: RootState) => - selectDocumentCurrentPage(state, mode) - ) + const currentPage = useAppSelector(s => selectDocumentCurrentPage(s, mode)) const targetRef = useRef(null) - const zoomFactor = useSelector((state: RootState) => - selectZoomFactor(state, mode) - ) + const zoomFactor = useAppSelector(s => selectZoomFactor(s, mode)) useEffect(() => { if (currentPage == page.page.number) { diff --git a/ui2/src/components/Viewer/Thumbnail/Thumbnail.tsx b/ui2/src/components/Viewer/Thumbnail/Thumbnail.tsx index 3d8c71a2c..72cff044b 100644 --- a/ui2/src/components/Viewer/Thumbnail/Thumbnail.tsx +++ b/ui2/src/components/Viewer/Thumbnail/Thumbnail.tsx @@ -13,12 +13,15 @@ import { dropThumbnailPage, selectSelectedPageIds, selectSelectedPages, - selectionAddPage, - selectionRemovePage, setCurrentPage } from "@/slices/dualPanel/dualPanel" import type {DroppedThumbnailPosition, PageAndRotOp, PanelMode} from "@/types" +import { + viewerSelectionPageAdded, + viewerSelectionPageRemoved +} from "@/features/ui/uiSlice" + import {RootState} from "@/app/types" import classes from "./Thumbnail.module.scss" @@ -157,9 +160,9 @@ export default function Thumbnail({page}: Args) { const onCheck = (e: React.ChangeEvent) => { if (e.currentTarget.checked) { - dispatch(selectionAddPage({selectionId: page.page.id, mode})) + dispatch(viewerSelectionPageAdded({itemID: page.page.id, mode})) } else { - dispatch(selectionRemovePage({selectionId: page.page.id, mode})) + dispatch(viewerSelectionPageRemoved({itemID: page.page.id, mode})) } } diff --git a/ui2/src/features/ui/uiSlice.ts b/ui2/src/features/ui/uiSlice.ts index 63b22c1d2..2b5fd112d 100644 --- a/ui2/src/features/ui/uiSlice.ts +++ b/ui2/src/features/ui/uiSlice.ts @@ -119,8 +119,10 @@ interface UIState { // 5 -> means 5% // 100 -> means 100% i.e exact fit mainViewerZoomFactor?: number + mainViewerSelectedIDs?: Array secondaryViewerThumbnailsPanelOpen?: boolean secondaryViewerZoomFactor?: number + secondaryViewerSelectedIDs?: Array } const initialState: UIState = { @@ -431,6 +433,57 @@ const uiSlice = createSlice({ if (mode == "secondary") { state.secondaryViewerZoomFactor = ZOOM_FACTOR_INIT } + }, + viewerSelectionPageAdded(state, action: PayloadAction) { + const mode = action.payload.mode + const itemID = action.payload.itemID + if (mode == "main") { + if (state.mainViewerSelectedIDs) { + state.mainViewerSelectedIDs.push(itemID) + } else { + state.mainViewerSelectedIDs = [itemID] + } + return + } + + // mode == secondary + if (state.secondaryViewerSelectedIDs) { + state.secondaryViewerSelectedIDs.push(itemID) + } else { + state.secondaryViewerSelectedIDs = [itemID] + } + }, + viewerSelectionPageRemoved( + state, + action: PayloadAction + ) { + const mode = action.payload.mode + const itemID = action.payload.itemID + if (mode == "main") { + if (state.mainViewerSelectedIDs) { + const newValues = state.mainViewerSelectedIDs.filter(i => i != itemID) + state.mainViewerSelectedIDs = newValues + } + + return + } + // secondary + if (state.secondaryViewerSelectedIDs) { + const newValues = state.secondaryViewerSelectedIDs.filter( + i => i != itemID + ) + state.secondaryViewerSelectedIDs = newValues + } + }, + viewerSelectionCleared(state, action: PayloadAction) { + const mode = action.payload + + if (mode == "main") { + state.mainViewerSelectedIDs = [] + return + } + // secondary + state.secondaryViewerSelectedIDs = [] } } }) @@ -454,7 +507,10 @@ export const { viewerThumbnailsPanelToggled, zoomFactorIncremented, zoomFactorDecremented, - zoomFactorReseted + zoomFactorReseted, + viewerSelectionPageAdded, + viewerSelectionPageRemoved, + viewerSelectionCleared } = uiSlice.actions export default uiSlice.reducer @@ -527,21 +583,16 @@ export const selectPanelComponent = (state: RootState, mode: PanelMode) => { return state.ui.secondaryPanelComponent } -const selectSelectedNodeIdsRaw = (state: RootState, mode: PanelMode) => { +export const selectSelectedNodeIds = (state: RootState, mode: PanelMode) => { if (mode == "main") { - return state.ui.mainCommanderSelectedIDs + return state.ui.mainCommanderSelectedIDs || [] } - return state.ui.secondaryCommanderSelectedIDs + return state.ui.secondaryCommanderSelectedIDs || [] } -export const selectSelectedNodeIds = createSelector( - selectSelectedNodeIdsRaw, - selectedIds => (selectedIds ? selectedIds : []) -) - export const selectSelectedNodesCount = createSelector( - selectSelectedNodeIdsRaw, + selectSelectedNodeIds, selectedIds => { if (!selectedIds) { return 0 diff --git a/ui2/src/slices/dualPanel/dualPanel.ts b/ui2/src/slices/dualPanel/dualPanel.ts index 27e2a381b..ede04231a 100644 --- a/ui2/src/slices/dualPanel/dualPanel.ts +++ b/ui2/src/slices/dualPanel/dualPanel.ts @@ -15,9 +15,7 @@ import {RootState} from "@/app/types" import { dropThumbnailPageHelper, getLatestVersionPages, - resetPageChangesHelper, - selectionAddPageHelper, - selectionRemovePageHelper + resetPageChangesHelper } from "./helpers" import type { @@ -35,7 +33,7 @@ import type { SearchResultNode, SliceState } from "@/types" -import {DualPanelState, SelectionPagePayload} from "./types" +import {DualPanelState} from "./types" const initialState: DualPanelState = { mainPanel: { @@ -182,19 +180,6 @@ const dualPanelSlice = createSlice({ const mode = action.payload resetPageChangesHelper(state, mode) }, - selectionAddPage: (state, action: PayloadAction) => { - const pageId = action.payload.selectionId - const mode = action.payload.mode - selectionAddPageHelper(state, pageId, mode) - }, - selectionRemovePage: ( - state, - action: PayloadAction - ) => { - const pageId = action.payload.selectionId - const mode = action.payload.mode - selectionRemovePageHelper(state, pageId, mode) - }, dropThumbnailPage(state, action: PayloadAction) { const {mode, sources, target, position} = action.payload @@ -289,8 +274,6 @@ const dualPanelSlice = createSlice({ export const { rotatePages, - selectionAddPage, - selectionRemovePage, updateSearchResultItemTarget, setCurrentPage, dropThumbnailPage, diff --git a/ui2/src/slices/dualPanel/helpers.ts b/ui2/src/slices/dualPanel/helpers.ts index dcc944501..6ecc88114 100644 --- a/ui2/src/slices/dualPanel/helpers.ts +++ b/ui2/src/slices/dualPanel/helpers.ts @@ -1,60 +1,12 @@ import type { - CurrentNodeType, - PanelMode, - PageType, - DroppedThumbnailPosition, DocumentVersion, - PageAndRotOp + DroppedThumbnailPosition, + PageAndRotOp, + PageType, + PanelMode } from "@/types" -import {DualPanelState, Commander} from "./types" -import {INITIAL_PAGE_SIZE} from "@/cconstants" -import {contains_every} from "@/utils" -import {reorder as reorder_pages} from "@/utils" - -export function selectionAddPageHelper( - state: DualPanelState, - pageId: string, - mode: PanelMode -) { - switch (mode) { - case "main": - if (state.mainPanel.viewer) { - state.mainPanel.viewer.selectedIds.push(pageId) - } - break - case "secondary": - if (state.secondaryPanel?.viewer) { - state.secondaryPanel.viewer.selectedIds.push(pageId) - } - break - default: - throw Error("Should never reach this place") - } -} - -export function selectionRemovePageHelper( - state: DualPanelState, - pageId: string, - mode: PanelMode -) { - if (mode == "main") { - if (state.mainPanel.viewer) { - const newSelectedIds = state.mainPanel.viewer.selectedIds.filter( - i => i != pageId - ) - state.mainPanel.viewer.selectedIds = newSelectedIds - } - } - - if (mode == "secondary") { - if (state.secondaryPanel?.viewer) { - const newSelectedIds = state.secondaryPanel.viewer.selectedIds.filter( - i => i != pageId - ) - state.secondaryPanel.viewer.selectedIds = newSelectedIds - } - } -} +import {contains_every, reorder as reorder_pages} from "@/utils" +import {DualPanelState} from "./types" export function dropThumbnailPageHelper({ mode,