Skip to content

feat(highlight): Improve selection logic#559

Merged
mergify[bot] merged 3 commits intobox:masterfrom
mingzexiao6:selection-change
Aug 25, 2020
Merged

feat(highlight): Improve selection logic#559
mergify[bot] merged 3 commits intobox:masterfrom
mingzexiao6:selection-change

Conversation

@mingzexiao6
Copy link
Contributor

@mingzexiao6 mingzexiao6 commented Aug 24, 2020

This PR addresses following feedbacks from product:

  1. The promotion popup shouldn't show up during mouse dragging.
  2. Debounce keyboard selection 500ms.
  3. When there're multiple ranges in one selection, only care about the last one.

Todo:

  • Fix unit tests

Copy link
Contributor

@ConradJChan ConradJChan left a comment

Choose a reason for hiding this comment

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

I wonder if it would be better to encapsulate the highlight logic in a separate class that so that this logic could be easily turned on or off. Thoughts?

// Clear previous selection
this.store.dispatch(setSelectionAction(null));

if (!this.mouseEventHandlerAdded && this.annotatedEl) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would an overridden init method in DocumentAnnotator be a better place to add this?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think we should try to avoid overriding init. It calls render, so it doesn't seem to change much in this circumstance.

export default class DocumentAnnotator extends BaseAnnotator {
annotatedEl?: HTMLElement;

isMouseSelecting = false;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ideally, all state should live in the redux store. What is the reasoning for keeping this as an instance value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The store instance and annotator instance create and destroy together, so I think an instance variable in annotator is equivalent to a state in store and the variable is only used in this class.

this.store.dispatch(setSelectionAction(null));

if (!this.mouseEventHandlerAdded && this.annotatedEl) {
this.annotatedEl.addEventListener('mousedown', this.handleMouseDown);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do these handlers work as expected for touch-enabled devices?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tested on Chrome developer tool and iPad simulator on Mac and they both work fine. I think most of the browsers today fire both touch events and mouse events.


if (!this.mouseEventHandlerAdded && this.annotatedEl) {
this.annotatedEl.addEventListener('mousedown', this.handleMouseDown);
this.annotatedEl.addEventListener('mouseup', this.handleMouseUp);
Copy link
Collaborator

Choose a reason for hiding this comment

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

What happens if the mouse button is released outside of the annotated element or vice versa? Do things work as desired?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If the mouse is released outside of the annotated element or vice versa, the popup will not show, which is the desired behavior confirmed with designer.

@mingzexiao6 mingzexiao6 force-pushed the selection-change branch 3 times, most recently from 0c55bb8 to d7cb9c7 Compare August 24, 2020 23:01

store: AppStore;

constructor({ getSelection, selectionChangeDelay = 0, store }: Options) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to default selectionChangeDelay to the 300ms magic number?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think 300ms magic number is only related to pdfjs, which is only related to DocumentAnnotator. For the other annotators which don't use pdfjs, it should be 0.

@mingzexiao6 mingzexiao6 marked this pull request as ready for review August 25, 2020 04:23
@mingzexiao6 mingzexiao6 requested a review from a team as a code owner August 25, 2020 04:23
ConradJChan
ConradJChan previously approved these changes Aug 25, 2020
import { MOUSE_PRIMARY } from '../constants';

export type Options = {
getSelection: () => SelectionArg | null;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: feels a bit funny that the return type has name Arg in it, could Selection type be used here?

Copy link
Contributor Author

@mingzexiao6 mingzexiao6 Aug 25, 2020

Choose a reason for hiding this comment

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

The Selection type is defined in docUtil, which I want to separate from highlight. I can rename SelectionArg to Selection in the import.

@mergify mergify bot merged commit 7bb178e into box:master Aug 25, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants