()
-const List = (): JSX.Element => {
- const { state } = useMain()
- const { rowSelection, setRowSelection } = useTableContext()
-
- const { status, fetchData } = useFetchDirectories()
-
- useEffect(() => {
- fetchData()
- }, [])
-
- const directories = state.directorySrcs
-
- const columns = useMemo(
- () => [
- columnHelper.display({
- id: 'select',
- size: 16,
- header: ({ table }) => (
-
- ),
- cell: ({ row }) => (
-
-
-
- )
- }),
- columnHelper.accessor('id', {
- id: 'id'
- }),
- columnHelper.accessor('path', {
- id: 'path',
- cell: (info) => info.getValue(),
- header: () => Path
- })
- ],
- []
- )
-
- const table = useReactTable({
- data: directories ?? [],
- columns,
- getCoreRowModel: getCoreRowModel(),
- state: {
- columnVisibility: {
- id: false
- },
- rowSelection
- },
- filterFns: {
- fuzzy: fuzzyFilter
- },
- enableRowSelection: true,
- onRowSelectionChange: setRowSelection
- })
-
- const renderList = (): JSX.Element => {
- if (status === 'pending') {
- return (
-
-
-
- )
- }
-
- return (
-
- headerGroups={table.getHeaderGroups()} />
-
- table={table}
- noResultsMessage="No directories selected. Use the buttons below to add/remove directories to scan."
- />
-
- )
- }
-
- return {renderList()}
-}
-
-export default memo(function Directories(): JSX.Element {
+function Directories(): JSX.Element {
return (
@@ -119,4 +17,6 @@ export default memo(function Directories(): JSX.Element {
)
-})
+}
+
+export default Directories
diff --git a/src/renderer/src/Sections/Results/ActionsRow.tsx b/src/renderer/src/Sections/Results/ActionsRow.tsx
index f878eb9..6218683 100644
--- a/src/renderer/src/Sections/Results/ActionsRow.tsx
+++ b/src/renderer/src/Sections/Results/ActionsRow.tsx
@@ -1,6 +1,6 @@
import ErrorMessage from '@renderer/components/ErrorMessage'
-import { useMain } from '@renderer/context/MainContext'
-import { useTableContext } from '@renderer/context/TableContext'
+import useMain from '@renderer/context/hooks/useMain'
+import useTableContext from '@renderer/context/hooks/useTableContext'
import { useMemo } from 'react'
const classNames = {
diff --git a/src/renderer/src/Sections/Results/ConfigurationPanel.tsx b/src/renderer/src/Sections/Results/ConfigurationPanel.tsx
index e1eac0a..d8fc3ab 100644
--- a/src/renderer/src/Sections/Results/ConfigurationPanel.tsx
+++ b/src/renderer/src/Sections/Results/ConfigurationPanel.tsx
@@ -1,7 +1,7 @@
import DebouncedInput from '@renderer/components/DebouncedInput'
import ColumnSelection from '@renderer/components/Table/ColumnSelection'
-import { useMain } from '@renderer/context/MainContext'
-import { useTableContext } from '@renderer/context/TableContext'
+import useMain from '@renderer/context/hooks/useMain'
+import useTableContext from '@renderer/context/hooks/useTableContext'
import { values } from 'ramda'
import { useMemo } from 'react'
import ErrorIcon from '../../assets/error.svg?react'
@@ -59,52 +59,7 @@ export default function ConfigurationPanel({ id }: { id: string }): JSX.Element
)}
- {
- return includeCrates || column.key !== 'crates'
- })}
- />
+
}
-export default memo(function deleteWarningModal({
+const DeleteModal = memo(function DeleteWarningModal({
data,
id,
selected,
@@ -79,3 +79,5 @@ export default memo(function deleteWarningModal({
)
})
+
+export default DeleteModal
diff --git a/src/renderer/src/Sections/Results/columns.tsx b/src/renderer/src/Sections/Results/columns.tsx
index 9825e83..6d59161 100644
--- a/src/renderer/src/Sections/Results/columns.tsx
+++ b/src/renderer/src/Sections/Results/columns.tsx
@@ -6,6 +6,7 @@ import { getCommonValue } from './utils'
export const duplicatesColumns: ColumnDef[] = [
{
+ id: 'id',
accessorKey: 'id',
enableGrouping: true,
size: 16,
@@ -49,6 +50,7 @@ export const duplicatesColumns: ColumnDef[] = [
},
{
accessorKey: 'name',
+ header: 'Name',
cell: (info) => info.getValue(),
enableGrouping: false,
enableSorting: true
@@ -162,7 +164,7 @@ export const duplicatesColumns: ColumnDef[] = [
header: 'Crates',
accessorFn: (row): number => {
if ((row as DuplicateData)?.files?.length === 0) {
- // @ts-ignore
+ // @ts-ignore row type is incorrect
return (row.crates || []).length
}
@@ -173,7 +175,7 @@ export const duplicatesColumns: ColumnDef[] = [
cell: (info): JSX.Element | number | string => {
if (info.row.depth === 0) {
const count = info.row.subRows.reduce((acc, row) => {
- // @ts-ignore
+ // @ts-ignore row type is incorrect
return acc + row.original?.crates?.length ?? 0
}, 0)
@@ -253,7 +255,9 @@ export const duplicateImageColumns: ColumnDef[] = [
)
},
{
+ id: 'name',
accessorKey: 'name',
+ header: 'Name',
cell: (info) => info.getValue(),
enableGrouping: false,
enableSorting: true
@@ -344,7 +348,38 @@ export const duplicateImageColumns: ColumnDef[] = [
enableGrouping: false,
size: 32
},
- // TODO add camera & lens
+ {
+ id: 'cameraModel',
+ accessorKey: 'cameraModel',
+ header: 'Camera Model',
+ enableSorting: false,
+ cell: (info): CommonValue => {
+ if (info.row.depth === 0) {
+ return null
+ }
+
+ const row = info.row.original as unknown as DuplicateFile
+ if (row.fileType === 'audio') return
+
+ return row?.metadata?.cameraModel ?? ''
+ }
+ },
+ {
+ id: 'lensModel',
+ accessorKey: 'lensModel',
+ header: 'Lens Model',
+ enableSorting: false,
+ cell: (info): CommonValue => {
+ if (info.row.depth === 0) {
+ return null
+ }
+
+ const row = info.row.original as unknown as DuplicateFile
+ if (row.fileType === 'audio') return
+
+ return row?.metadata?.lensModel ?? ''
+ }
+ },
{
id: 'duplicateCount',
size: 24,
@@ -359,6 +394,7 @@ export const duplicateImageColumns: ColumnDef[] = [
export const unCratedColumns: ColumnDef[] = [
{
+ id: 'id',
accessorKey: 'id',
enableGrouping: true,
size: 16,
@@ -380,7 +416,9 @@ export const unCratedColumns: ColumnDef[] = [
)
},
{
+ id: 'name',
accessorKey: 'name',
+ header: 'Name',
cell: (info) => info.getValue(),
enableGrouping: false,
enableSorting: true
diff --git a/src/renderer/src/Sections/Results/index.tsx b/src/renderer/src/Sections/Results/index.tsx
index ba80284..57d0487 100644
--- a/src/renderer/src/Sections/Results/index.tsx
+++ b/src/renderer/src/Sections/Results/index.tsx
@@ -1,7 +1,8 @@
import Loader from '@renderer/components/Loader'
import Body from '@renderer/components/Table/Body'
-import { useMain } from '@renderer/context/MainContext'
-import { TableProvider, useTableContext } from '@renderer/context/TableContext'
+import { TableProvider } from '@renderer/context/TableContext'
+import useMain from '@renderer/context/hooks/useMain'
+import useTableContext from '@renderer/context/hooks/useTableContext'
import { ResultsData, ScanResults } from '@src/types'
import { RankingInfo } from '@tanstack/match-sorter-utils'
import {
@@ -50,13 +51,12 @@ const Table = ({ id }: { id: string }): JSX.Element => {
setRowSelection
} = useTableContext()
const scan = state.scans[id]
- const results: ScanResults = scan.results ?? { files: {} }
+ const results: ScanResults = useMemo(() => scan.results ?? { files: {} }, [scan])
const [sorted, setSorting] = useState([])
const data: ResultsData[] = useMemo(() => {
return transformScanResultsToRows(results, scan)
}, [results, scan])
const [columnFilters, setColumnFilters] = useState([])
-
const columns = useMemo[]>(() => {
if (scan.configuration.type === 'image') {
return duplicateImageColumns
@@ -71,7 +71,7 @@ const Table = ({ id }: { id: string }): JSX.Element => {
}
return []
- }, [])
+ }, [scan])
const table = useReactTable({
columnResizeMode: 'onChange',
diff --git a/src/renderer/src/components/DebouncedInput.tsx b/src/renderer/src/components/DebouncedInput.tsx
index 094b413..219eb31 100644
--- a/src/renderer/src/components/DebouncedInput.tsx
+++ b/src/renderer/src/components/DebouncedInput.tsx
@@ -1,6 +1,6 @@
import { InputHTMLAttributes, memo, useEffect, useState } from 'react'
-export default memo(function DebouncedInput({
+const Input = memo(function DebouncedInput({
value: initialValue,
onChange,
debounce = 500,
@@ -24,7 +24,7 @@ export default memo(function DebouncedInput({
}, debounce)
return (): void => clearTimeout(timeout)
- }, [value])
+ }, [debounce, onChange, value])
return (
)
})
+
+export default Input
diff --git a/src/renderer/src/components/PreviousResults.tsx b/src/renderer/src/components/PreviousResults.tsx
index d52b400..b3d64f0 100644
--- a/src/renderer/src/components/PreviousResults.tsx
+++ b/src/renderer/src/components/PreviousResults.tsx
@@ -1,4 +1,4 @@
-import { useMain } from '@renderer/context/MainContext'
+import useMain from '@renderer/context/hooks/useMain'
import useScansList from '@renderer/hooks/useScansList'
import { UPDATE_ACTIVE_TAB } from '@src/constants'
import { format } from 'date-fns'
diff --git a/src/renderer/src/components/SectionTabs.tsx b/src/renderer/src/components/SectionTabs.tsx
index b714ae4..76cb598 100644
--- a/src/renderer/src/components/SectionTabs.tsx
+++ b/src/renderer/src/components/SectionTabs.tsx
@@ -1,5 +1,5 @@
import Directories from '@renderer/Sections/Directories'
-import { useMain } from '@renderer/context/MainContext'
+import useMain from '@renderer/context/hooks/useMain'
import { REMOVE_SCAN, UPDATE_ACTIVE_TAB } from '@src/constants'
import { keys } from 'ramda'
import { Suspense, lazy, memo, useMemo } from 'react'
@@ -15,7 +15,7 @@ const classNames = {
contentContainer: 'bg-base-300 h-full w-full rounded-t-none rounded-b overflow-hidden p-4'
}
-function SectionTabs(): JSX.Element {
+const Tabs = memo(function SectionTabs(): JSX.Element {
const { state, dispatch } = useMain()
const handleTabClick = (tabId: string): void => {
@@ -101,6 +101,6 @@ function SectionTabs(): JSX.Element {
)
-}
+})
-export default memo(SectionTabs)
+export default Tabs
diff --git a/src/renderer/src/components/Table/ColumnSelection.tsx b/src/renderer/src/components/Table/ColumnSelection.tsx
index 92744d9..772aa05 100644
--- a/src/renderer/src/components/Table/ColumnSelection.tsx
+++ b/src/renderer/src/components/Table/ColumnSelection.tsx
@@ -1,16 +1,55 @@
-import { useTableContext } from '@renderer/context/TableContext'
-import { useEffect } from 'react'
-
-const ColumnSelection = ({
- columns
-}: {
- columns: {
- key: string
- name: string
- }[]
-}): JSX.Element => {
+import {
+ duplicateImageColumns,
+ duplicatesColumns,
+ unCratedColumns
+} from '@renderer/Sections/Results/columns'
+import useMain from '@renderer/context/hooks/useMain'
+import useTableContext from '@renderer/context/hooks/useTableContext'
+import { useEffect, useMemo } from 'react'
+
+const columMap = {
+ duplicateAudio: duplicatesColumns,
+ duplicateImage: duplicateImageColumns,
+ uncrated: unCratedColumns
+}
+
+const ColumnSelection = ({ id }: { id: string }): JSX.Element => {
+ const { state } = useMain()
+ const scan = state.scans[id]
+ const { type, scanType, includeCrates } = scan.configuration
const { columnVisibility, setColumnVisibility } = useTableContext()
+ const columns: { key: string; name: string }[] = useMemo(() => {
+ if (type === 'image') {
+ return columMap['duplicateImage']
+ .map((col) => ({
+ key: col.id as string,
+ name: col.header as string
+ }))
+ .filter((col) => col.key && col.key !== 'id')
+ }
+
+ if (scanType === 'duplicate') {
+ return columMap['duplicateAudio']
+ .map((col) => ({
+ key: col.id as string,
+ name: col.header as string
+ }))
+ .filter((col) => col.key && (includeCrates || col.key !== 'crates') && col.key !== 'id')
+ }
+
+ if (scanType === 'not_crated') {
+ return columMap['uncrated']
+ .map((col) => ({
+ key: col.id as string,
+ name: col.header as string
+ }))
+ .filter((col) => col.key && col.key !== 'id')
+ }
+
+ return []
+ }, [type, scanType, includeCrates])
+
useEffect(() => {
// on mount set all to true except crates
setColumnVisibility((cur) => {
@@ -19,6 +58,7 @@ const ColumnSelection = ({
{}
)
})
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
const handleCheckboxChange = (columnName: string): void => {
@@ -39,14 +79,14 @@ const ColumnSelection = ({
>
{columns.map((col) => (
-
+
+
))}
diff --git a/src/renderer/src/components/Table/InderminateCheckbox.tsx b/src/renderer/src/components/Table/InderminateCheckbox.tsx
index c99453f..1450c44 100644
--- a/src/renderer/src/components/Table/InderminateCheckbox.tsx
+++ b/src/renderer/src/components/Table/InderminateCheckbox.tsx
@@ -11,7 +11,7 @@ export default function IndeterminateCheckbox({
if (typeof indeterminate === 'boolean') {
ref.current.indeterminate = !rest.checked && indeterminate
}
- }, [ref, indeterminate])
+ }, [ref, indeterminate, rest.checked])
return (
diff --git a/src/renderer/src/context/MainContext.tsx b/src/renderer/src/context/MainContext.tsx
index 76245fa..e2b1bd1 100644
--- a/src/renderer/src/context/MainContext.tsx
+++ b/src/renderer/src/context/MainContext.tsx
@@ -5,10 +5,10 @@ import { useIpcListener } from '@renderer/hooks/useIPCListener'
import useScanTracking from '@renderer/hooks/useScanTracking'
import { NEW_FILES_DIRECTORY } from '@src/constants'
import { DatabaseOperationResult } from '@src/types'
-import React, { ReactNode, createContext, useContext, useReducer } from 'react'
+import React, { ReactNode, createContext, useReducer } from 'react'
import { directoryReducer, initialState } from '../actions/reducer'
-const MainContext = createContext
(null)
+export const MainContext = createContext(null)
interface MainProviderProps {
children: ReactNode
@@ -40,12 +40,3 @@ export const MainProvider: React.FC = ({ children }) => {
return {children}
}
-
-// Custom hook to use the directory state and dispatch
-export const useMain = (): MainContextProps => {
- const context = useContext(MainContext)
- if (!context) {
- throw new Error('useDirectory must be used within a DirectoryProvider')
- }
- return context
-}
diff --git a/src/renderer/src/context/TableContext.tsx b/src/renderer/src/context/TableContext.tsx
index 409bf37..c1e55d1 100644
--- a/src/renderer/src/context/TableContext.tsx
+++ b/src/renderer/src/context/TableContext.tsx
@@ -1,8 +1,8 @@
import { TableContextProps } from '@src/types'
import { ExpandedState, VisibilityState } from '@tanstack/react-table'
-import React, { ReactNode, createContext, useContext, useState } from 'react'
+import React, { ReactNode, createContext, useState } from 'react'
-const TableContext = createContext(undefined)
+export const TableContext = createContext(undefined)
interface TableProviderProps {
children: ReactNode
@@ -31,11 +31,3 @@ export const TableProvider: React.FC = ({ children }) => {
)
}
-
-export const useTableContext = (): TableContextProps => {
- const context = useContext(TableContext)
- if (!context) {
- throw new Error('useTableContext must be used within a TableProvider')
- }
- return context
-}
diff --git a/src/renderer/src/context/hooks/useMain.ts b/src/renderer/src/context/hooks/useMain.ts
new file mode 100644
index 0000000..f06b9f6
--- /dev/null
+++ b/src/renderer/src/context/hooks/useMain.ts
@@ -0,0 +1,14 @@
+import { MainContextProps } from '@renderer/actions/types'
+import { useContext } from 'react'
+import { MainContext } from '../MainContext'
+
+// Custom hook to use the directory state and dispatch
+const useMain = (): MainContextProps => {
+ const context = useContext(MainContext)
+ if (!context) {
+ throw new Error('useDirectory must be used within a DirectoryProvider')
+ }
+ return context
+}
+
+export default useMain
diff --git a/src/renderer/src/context/hooks/useTableContext.ts b/src/renderer/src/context/hooks/useTableContext.ts
new file mode 100644
index 0000000..13d22c7
--- /dev/null
+++ b/src/renderer/src/context/hooks/useTableContext.ts
@@ -0,0 +1,13 @@
+import { TableContextProps } from '@src/types'
+import { useContext } from 'react'
+import { TableContext } from '../TableContext'
+
+const useTableContext = (): TableContextProps => {
+ const context = useContext(TableContext)
+ if (!context) {
+ throw new Error('useTableContext must be used within a TableProvider')
+ }
+ return context
+}
+
+export default useTableContext
diff --git a/src/renderer/src/hooks/useDeletedFilesTracking.ts b/src/renderer/src/hooks/useDeletedFilesTracking.ts
index 2be4020..98f1c14 100644
--- a/src/renderer/src/hooks/useDeletedFilesTracking.ts
+++ b/src/renderer/src/hooks/useDeletedFilesTracking.ts
@@ -1,10 +1,9 @@
import { DeletedFiles } from '@prisma/client'
import { getDeletedFilesById } from '@renderer/actions/ipc'
-import { useMain } from '@renderer/context/MainContext'
+import useMain from '@renderer/context/hooks/useMain'
import { transformDeletedFiles } from '@renderer/utils/transformDeletedFiles'
import { ADD_DELETED_FILES_RESULT } from '@src/constants'
-import { DatabaseOperationResult } from '@src/types'
-import { useQueries, useQueryClient } from '@tanstack/react-query'
+import { ExtendedScan } from '@src/types'
import { useEffect } from 'react'
/**
@@ -22,49 +21,52 @@ const useDeletedFilesTracking = ({
state: ReturnType['state']
dispatch: ReturnType['dispatch']
}): void => {
- const queryClient = useQueryClient()
- const scans = Object.values(state.scans)
+ useEffect(() => {
+ const intervalIds: NodeJS.Timeout[] = []
+ const pollingDuration = 3 * 60 * 1000 // timeout at 3 min
- const queries = useQueries({
- queries: scans.map((scan) => ({
- queryKey: ['deletedFiles', scan.trackingDeleteId],
- queryFn: () => (scan.trackingDeleteId ? getDeletedFilesById(scan.trackingDeleteId) : null),
- refetchInterval: 2000, // Refetch every 2 seconds
- onSuccess: (deleteRes: DatabaseOperationResult): void => {
- if (deleteRes.success && deleteRes.data) {
- dispatch({
- type: ADD_DELETED_FILES_RESULT,
- payload: {
- scanId: scan.id,
- deletedFiles: transformDeletedFiles(deleteRes.data)
- }
- })
- }
- }
- }))
- })
+ Object.keys(state.scans).forEach((id) => {
+ const scan = state.scans[id]
+ const { trackingDeleteId } = scan
+ const deletedFiles =
+ (scan as ExtendedScan & { deletedFiles: DeletedFiles[] })?.deletedFiles ?? []
+ const deletedFilesIds = deletedFiles.map((file) => file.id)
- useEffect(() => {
- const timeoutId = setTimeout(
- () => {
- scans.forEach((scan) => {
- queryClient.removeQueries({
- queryKey: ['deletedFiles', scan.trackingDeleteId]
- })
+ if (trackingDeleteId && !deletedFilesIds.includes(trackingDeleteId)) {
+ const intervalId = setInterval(async () => {
+ const deleteRes = await getDeletedFilesById(trackingDeleteId)
+
+ if (deleteRes.success === false) {
+ clearInterval(intervalId)
+ }
+
+ if (deleteRes.success && deleteRes.data) {
+ clearInterval(intervalId)
+
+ dispatch({
+ type: ADD_DELETED_FILES_RESULT,
+ payload: {
+ scanId: id,
+ deletedFiles: transformDeletedFiles(deleteRes.data)
+ }
+ })
+ }
})
- },
- 3 * 60 * 1000
- ) // Stop refetching after 3 minutes
+
+ intervalIds.push(intervalId)
+ }
+ })
+
+ const timeoutId = setTimeout(() => {
+ intervalIds.forEach((id) => clearInterval(id))
+ }, pollingDuration)
return () => {
clearTimeout(timeoutId)
- scans.forEach((scan) => {
- queryClient.removeQueries({
- queryKey: ['deletedFiles', scan.trackingDeleteId]
- })
- })
+
+ intervalIds.forEach((id) => clearInterval(id))
}
- }, [queries])
+ }, [state.scans, dispatch])
}
export default useDeletedFilesTracking
diff --git a/src/renderer/src/hooks/useDirectoriesList.ts b/src/renderer/src/hooks/useDirectoriesList.ts
index ac64f4d..42d5b77 100644
--- a/src/renderer/src/hooks/useDirectoriesList.ts
+++ b/src/renderer/src/hooks/useDirectoriesList.ts
@@ -1,6 +1,6 @@
import { FilesDirectory } from '@prisma/client'
import { getFilesDirectories } from '@renderer/actions/ipc'
-import { useMain } from '@renderer/context/MainContext'
+import useMain from '@renderer/context/hooks/useMain'
import { GET_FILES_DIRECTORIES } from '@src/constants'
import { DatabaseOperationResult } from '@src/types'
import { useQuery } from '@tanstack/react-query'
diff --git a/src/renderer/src/hooks/useIPCListener.ts b/src/renderer/src/hooks/useIPCListener.ts
index c8be3c7..f2d5130 100644
--- a/src/renderer/src/hooks/useIPCListener.ts
+++ b/src/renderer/src/hooks/useIPCListener.ts
@@ -7,5 +7,5 @@ export const useIpcListener = (channel: string, callback: IPCListenerCallBack
return () => {
removeListener()
}
- }, [channel])
+ }, [callback, channel])
}
diff --git a/src/renderer/src/hooks/usePolling.ts b/src/renderer/src/hooks/usePolling.ts
index a865e82..5cd6bbc 100644
--- a/src/renderer/src/hooks/usePolling.ts
+++ b/src/renderer/src/hooks/usePolling.ts
@@ -38,5 +38,5 @@ export const usePolling = (
clearInterval(intervalId.current)
}
}
- }, [callback, interval])
+ }, [callback, dispatch, interval])
}
diff --git a/src/renderer/src/hooks/useScanTracking.ts b/src/renderer/src/hooks/useScanTracking.ts
index ffbeb48..dbc2ea8 100644
--- a/src/renderer/src/hooks/useScanTracking.ts
+++ b/src/renderer/src/hooks/useScanTracking.ts
@@ -1,5 +1,5 @@
import { fetchScanStatusById } from '@renderer/actions/ipc'
-import { useMain } from '@renderer/context/MainContext'
+import useMain from '@renderer/context/hooks/useMain'
import { transformScan } from '@renderer/utils/transformScan'
import { UPDATE_SCAN_STATUS } from '@src/constants'
import { useEffect } from 'react'
@@ -112,7 +112,7 @@ const useScanTracking = ({
clearTimeout(timeoutId)
intervalIds.forEach((id) => clearInterval(id))
}
- }, [state.scans])
+ }, [dispatch, state.scans])
}
export default useScanTracking
diff --git a/src/renderer/src/hooks/useScansList.ts b/src/renderer/src/hooks/useScansList.ts
index ea38b2a..54b2c26 100644
--- a/src/renderer/src/hooks/useScansList.ts
+++ b/src/renderer/src/hooks/useScansList.ts
@@ -1,6 +1,6 @@
import { Scan } from '@prisma/client'
import { getScansList } from '@renderer/actions/ipc'
-import { useMain } from '@renderer/context/MainContext'
+import useMain from '@renderer/context/hooks/useMain'
import { DatabaseOperationResult } from '@src/types'
import { useQuery } from '@tanstack/react-query'
import { useEffect } from 'react'
@@ -31,5 +31,5 @@ export default function useScansList(): void {
}
})
}
- }, [data])
+ }, [data, dispatch])
}
diff --git a/yarn.lock b/yarn.lock
index 3ec54ee..27fcf81 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2738,6 +2738,11 @@ eslint-plugin-prettier@^5.0.0:
prettier-linter-helpers "^1.0.0"
synckit "^0.8.5"
+eslint-plugin-react-hooks@^4.6.0:
+ version "4.6.0"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3"
+ integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==
+
eslint-plugin-react-refresh@^0.4.3:
version "0.4.3"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.3.tgz#59dae8c00a119f06ea16b1d3e6891df3775947c7"