Set the preview selection to null when there is no selection#5568
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5568 +/- ##
==========================================
- Coverage 85.84% 85.83% -0.02%
==========================================
Files 309 309
Lines 30338 30349 +11
Branches 8346 8348 +2
==========================================
+ Hits 26045 26050 +5
- Misses 3873 3879 +6
Partials 420 420 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
canova
left a comment
There was a problem hiding this comment.
It looks much better indeed! Thanks!
Nit: I think this previewSelection can be just PreviewSelection now:
profiler/src/components/timeline/Selection.tsx
Lines 343 to 349 in fb9a4bc
src/actions/profile-view.ts
Outdated
| if (oldPreviewSelection === newPreviewSelection) { | ||
| return true; | ||
| } |
There was a problem hiding this comment.
I hope no one will pass the same object with the mutated value here. We know we should always pass a new object inside updatePreviewSelection and never mutate, but should we make this assumption clearer with a function comment, so other people in the future don't use it incorrectly?
There was a problem hiding this comment.
Ah true, I'm not sure why I thought that check was worth adding. I've just inlined-away this function again and removed that strict equality check.
This replaces uses where we're assuming that we can access an isModifying property both when we have a preview selection and when we don't have a preview selection. In a future commit I want to make us use null instead of hasSelection==false, and this makes that easier.
Instead of a PreviewSelection with hasSelection: false, just use null. This makes the PreviewSelection type usable in places where we want to only get objects with an actual selection, and is simpler overall.
Selection is the only user of Draggable. In this use, TypeScript will now infer the type PreviewSelection for the type argument.
I was having a hard time reading this code. This moves most of the function contents into a separate method.
ee22ac9 to
118c6a4
Compare
Oops, of course! I think that was my initial motivation for making this change, and then I just forgot about it! Thanks for catching it. |
| if ( | ||
| !currentPreviewSelection || | ||
| !previewSelection || | ||
| !objectShallowEquals(currentPreviewSelection, previewSelection) | ||
| ) { |
There was a problem hiding this comment.
Hm, I think this new if check is not 100% correct.
We have:
!currentPreviewSelection ||
!previewSelection)This means that when either currentPreviewSelection or previewSelection is null, it will always dispatch UPDATE_PREVIEW_SELECTION, including the cases where they are both null.
This strict equality check was still needed for the case where they are both null. Probably that's why you initially wanted to have a different function so it's easier to do early return.
Maybe something like:
if (
(currentPreviewSelection === null) !== (previewSelection === null) ||
(currentPreviewSelection &&
previewSelection &&
!objectShallowEquals(currentPreviewSelection, previewSelection))
) There was a problem hiding this comment.
Yes, what I landed is not equivalent to the check we had before this PR, but that just means that we may dispatch the action unnecessarily - this may be slower but it's not a "bug". My thinking was that we probably don't call it in a loop when the selection is null. But I haven't verified this.
Looks like the check was initially added in #1481 for the case where you're "zooming out" on a viewport when you're already fully zoomed out.
Ok, checking now, we will indeed repeatedly dispatch UPDATE_PREVIEW_SELECTION with null in that case.
Oh, but this doesn't actually change the identity of the redux state object! The previewSelection reducer returns null for its new state when processing this action, which is the same as its previous state, so the viewOptions reducer (from combineReducers) doesn't recreate the outer object.
Ok so I think we can keep it as-is.
Changes: [Nazım Can Altınova] Display the marker description at the top inside the marker tooltips (#5534) [Florian Quèze] Change the 'JavaScript' radio button label to 'Script' (#5530) [Markus Stange] Implement profile logic and some selectors for the function list (#5525) [Markus Stange] Some small type fixes (#5538) [Markus Stange] Simplify return type of the callback we pass to setState. (#5540) [Markus Stange] Pass the correct value to the reducer's action argument (#5543) [Markus Stange] Change withSize to accept PropsWithoutSize as its type parameter (#5541) [Nazım Can Altınova] Make sure that the test-debug command runs the tests properly (#5545) [Markus Stange] Improve type coverage involving network phases (#5539) [Markus Stange] Change implementation of withChartViewport (#5542) [Florian Quèze] A new permalink should be generated and shown after using the re-upload feature. (#5547) [Florian Quèze] Show the vertical ruler in the timeline when hovering the network chart (#5548) [Markus Stange] Convert the entire codebase to TypeScript (#5549) [Nazım Can Altınova] Update the yarn.lock file after recent changes (#5557) [Markus Stange] Add proper TypeScript coverage for window-navigation.ts (#5559) [Markus Stange] Remove leftover $FlowExpectError comments (#5560) [Markus Stange] Fix Iterator / Iterable confusion (#5561) [Nazım Can Altınova] Remove the unneeded test-all:ci script (#5566) [Nazım Can Altınova] Fix a type case inconsistency (#5569) [Florian Quèze] Make 'yarn lint --fix' work as an alias to 'yarn lint-fix'. (#5563) [Ryan Hunt] Don't stringify JSON again in fetchUrlResponse (#5570) [Nazım Can Altınova] Upgrade ESLint to version 9 (#5567) [Markus Stange] Simplify Worker setup, and support .json.gz inputs in symbolicator-cli (#5556) [Nazım Can Altınova] Add TypeScript coverage to the intersection observer mock (#5574) [Markus Stange] Set the preview selection to null when there is no selection (#5568) [Markus Stange] Add tests for query-api.ts (#5571) [Markus Stange] Enable noUnusedParameters and @typescript-eslint/no-unused-vars and clean up a few more things (#5576) [Ryan Hunt] Embed iongraph-web and use for iongraph.json source files (#5577) [Markus Stange] Remove recursion in filterThreadToSearchString (#5572) And thanks to our localizers: be: Mikalai Udodau de: Michael Köhler el: Jim Spentzos en-CA: chutten en-GB: Paul es-CL: ravmn fr: Théo Chevalier fur: Fabio Tomat fy-NL: Fjoerfoks ia: Melo46 it: Francesco Lodolo [:flod] nl: Mark Heijl pt-BR: Marcelo Ghelman ru: Valery Ledovskoy sv-SE: Luna Jernberg tr: Rua tr: Selim Şumlu uk: Іhor Hordiichuk zh-CN: Olvcpr423 zh-TW: Pin-guang Chen
We are currently using a "no preview selection" object of the shape
{ hasSelection: false, isModifying: false }when there is no preview selection. We can instead just use null, it's more idiomatic.I recommend reviewing commits individually.