Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Move deselect and isListening logic #662

Merged
merged 3 commits into from
Jan 4, 2021

Conversation

ConradJChan
Copy link
Contributor

@ConradJChan ConradJChan commented Dec 22, 2020

This PR changes the logic for how deselecting the activeId is handled as well as how each *List component determines whether the existing rendered annotations are listening for interaction events.

Deselect activeId

Deselecting the activeId is now moved to the BaseAnnotator which listens for the mousedown event on the document. One benefit of this is that it is done once for all annotators vs once per page per type of annotation, i.e. 1 vs 1 * 3 * 3 = 9 (assuming a 3 page document supporting region, highlight, drawing). One drawback is that it no longer benefits from the useOutsideClick logic that was in place to ignore mousedown events that originated from the *List component's root element but that should be minimal since multi page documents continued to trigger the same logic anyway when mousedown events occurred on other pages.

isListening

isListening is now determined based on two pieces of store state: (1) CreatorStatus from the creator store and (2) isSelecting from the highlight store. If CreatorStatus is init and isSelecting is false then the existing rendered annotations should be listening for interaction events. The benefit of this change is that the individual *List components do not need to maintain their own state for this.

TODO:

  • unit tests

@ConradJChan ConradJChan marked this pull request as ready for review December 22, 2020 20:35
@ConradJChan ConradJChan requested a review from a team as a code owner December 22, 2020 20:35
Copy link
Collaborator

@jstoffan jstoffan left a comment

Choose a reason for hiding this comment

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

The previous logic was always a little questionable, so this seems like a good change overall. I'm wary of global event handling sprawl, especially in the base annotator, since that was a contributor to some of the issues in prior versions of the library. It should be fine here, but should be cautious about adding more of these.

One other question is whether this works correctly with multiple preview instances within the same document. Does that cause any weird behavior?

@@ -141,6 +143,8 @@ export default class BaseAnnotator extends EventEmitter {
this.annotatedEl.classList.add(CSS_LOADED_CLASS);
this.containerEl.classList.add(CSS_CONTAINER_CLASS);

document.addEventListener('mousedown', this.handleDeselect);
Copy link
Collaborator

Choose a reason for hiding this comment

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

The init method can be called many times. Should we have a guard against this being added more than once?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch, I could add a guard clause here or would adding it in the constructor make more sense?


annotator.destroy();

expect(removeEventListenerSpy).toHaveBeenCalledWith('mousedown', expect.any(Function));
Copy link
Collaborator

Choose a reason for hiding this comment

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

We should be able to pass annotator.handleDeselect as the second parameter here. Same for the other new test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since its visibility is protected typescript complains about attempting to reference it. It appears the other event callbacks follow this expect.any(Function) approach as well. I tried looking for a disable rule for the tslint but haven't been able to find one

src/common/useIsListening.ts Outdated Show resolved Hide resolved
src/common/useIsListening.ts Outdated Show resolved Hide resolved
src/common/BaseAnnotator.ts Outdated Show resolved Hide resolved
src/highlight/HighlightList.tsx Outdated Show resolved Hide resolved
@ConradJChan
Copy link
Contributor Author

I think having multiple preview instances on the same document should be ok because this document mousedown listener's purpose is to set the active annotation to null when the document receives the mousedown -- meaning that it should work correctly regardless of which annotator instance is creating an annotation, each annotator instance would first set any active annotation to null on mousedown which would be my expectation. The document listener for handling text selection, on the other hand, might have some issues.

@ConradJChan ConradJChan merged commit 2f4a9e1 into box:master Jan 4, 2021
@ConradJChan ConradJChan deleted the deselect-is-listening branch January 4, 2021 21:31
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