Skip to content

Conversation

lethemanh
Copy link
Contributor

Change:

  • Moved all logics that're related to shift selection out of SelectionProvider.
  • Implemented new hook and helper functions for shift selection.
  • Implemented unit test for shift selection.
  • Modified useLongPress to be available with shift selection.
  • Modified folder view component to trigger shift selection.

Copy link

bundlemon bot commented Oct 13, 2025

BundleMon

Files updated (2)
Status Path Size Limits
static/js/main.(hash).js
145.67KB (+110B +0.07%) -
public/static/js/public.(hash).js
109.36KB (+47B +0.04%) -
Unchanged files (19)
Status Path Size Limits
static/js/(chunkId).(hash).js
958.28KB -
static/js/cozy.(hash).js
870.82KB -
public/static/js/(chunkId).(hash).js
870.09KB -
public/static/js/cozy.(hash).js
727.75KB -
(hash).js
336.11KB -
public/(hash).js
336.11KB -
services/qualificationMigration.js
282.45KB -
services/dacc.js
262.26KB -
public/static/js/lib-react.(hash).js
39.24KB -
static/js/lib-react.(hash).js
39.24KB -
public/static/css/cozy.(hash).css
33.38KB -
static/css/cozy.(hash).css
33.38KB -
public/static/js/lib-router.(hash).js
21.86KB -
static/js/lib-router.(hash).js
21.86KB -
static/css/main.(hash).css
16.77KB -
public/static/css/public.(hash).css
6.46KB -
manifest.webapp
2.96KB -
index.html
690B -
assets/manifest.json
185B -

Total files change +162B 0%

Groups updated (1)
Status Path Size Limits
**/*.js
6.74MB (+161B 0%) -
Unchanged groups (2)
Status Path Size Limits
**/*.{png,svg,ico}
2.17MB -
**/*.css
129.68KB -

Final result: ✅

View report in BundleMon website ➡️


Current branch size history | Target branch size history

@lethemanh lethemanh force-pushed the refactor-shift-selection branch 3 times, most recently from 6e220e3 to c640640 Compare October 13, 2025 07:01
newSelected[targetItem._id] = targetItem
} else {
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
delete newSelected[targetItem._id]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please don't use delete, look here

@lethemanh lethemanh force-pushed the refactor-shift-selection branch 2 times, most recently from 7502202 to 2c4808e Compare October 13, 2025 08:23
@lethemanh lethemanh requested a review from rezk2ll October 13, 2025 08:26
@lethemanh lethemanh force-pushed the refactor-shift-selection branch from 2c4808e to 1aa9225 Compare October 13, 2025 09:09
* Clamps an index value to be within valid array bounds.
*
* @param maxLength - The maximum length of the array
* @param index - The index to clamp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer a human generated JSDoc .

param {type} name description

@lethemanh lethemanh force-pushed the refactor-shift-selection branch from 1aa9225 to b2a9217 Compare October 14, 2025 04:51
@lethemanh lethemanh force-pushed the refactor-shift-selection branch from b2a9217 to a5960c1 Compare October 14, 2025 07:55
@lethemanh lethemanh requested a review from rezk2ll October 14, 2025 08:01
Copy link
Contributor

@rezk2ll rezk2ll left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Testing locally, the shift select is working fine with double click, kudos for that 🎉

Thanks for the type definitions and the JSDoc attempt

But I have some remarks to point out:

  • Making more functions does not mean that it will be easier to understand; having more than enough functions will split the mind of the person reading the code.
  • Let's not abuse useMemo for things that are not necessary
  • Try to avoid useEffect as much as possible; we already have enough.
  • In the code, we are mixing responsibilities in functions. You have functions that are one-line return something, and functions that do more than they should do like toggleSelection
  • keyboard listener is bloated
  • The state is overcomplicated
  • isSelectAll state can be computed instead of computing it in an useEffect
  • not all functions have JSDoc ( or a proper one with types )
  • The useshiftselect hook should be tested

}, [lastInteractedItem, items])

const selectItemByIds: SelectedItems = useMemo(() => {
return selectedItems.reduce<SelectedItems>(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure selectedItems is an array?

it is an object in the selection provider

 const [selectedItems, setSelectedItems] = useState({})

isSelectionBarVisible: boolean

/** List of selected items as an array */
selectedItems: IOCozyFile[]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not an array it's an object

Comment on lines +86 to +90
const viewTypeRef = useRef<ViewType>()
viewTypeRef.current = useMemo(() => viewType, [viewType])

const itemsRef = useRef<IOCozyFile[]>()
itemsRef.current = useMemo(() => items, [items])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is unnecessary and double-storing the value

Comment on lines +92 to +94
useEffect(() => {
setIsSelectAll(selectedItems.length === itemsRef.current?.length)
}, [setIsSelectAll, selectedItems])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please avoid useEffect

>
<GridFile
const onToggleSelect = (fileId, event) => {
event.stopPropagation()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do you need to do it here outside the onSelect?

...row,
index
}))
return rows
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this change have other impacts on virtualized table? @JF-Cozy


useShiftArrowsSelection({ items: sortedRow, viewType: 'list' }, tableRef)
const handleRowSelect = (row, event) => {
event.stopPropagation()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same comment


const onToggleSelect = (fileId, e) => {
setLastInteractedItem(fileId)
if (e.shiftKey) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we shouldn't check the keyboard event key in each place we use the onShiftClick

const viewTypeRef = useRef<ViewType>()
viewTypeRef.current = useMemo(() => viewType, [viewType])

const itemsRef = useRef<IOCozyFile[]>()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const itemsRef = useRef<IOCozyFile[]>()
const itemsRef = useRef<IOCozyFile[]>([])


/**
* Returns a new SelectedItems object with the specified key removed.
* This is a safe way to remove items from selection without using delete operator.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AI comment slipped in.

onShiftClick: (clickedItemId: string) => void
}

const useShiftSelection = (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JSDoc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants