-
Couldn't load subscription status.
- Fork 1.1k
Multi-selection: Ship review change requests #5841
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
Multi-selection: Ship review change requests #5841
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me! Just a few questions and comments but nothing blocking.
Nice work! 🙌
| if (tabManagerFeatureFlags.multiSelection().isEnabled()) { | ||
| clearAllSiteData(getDeletableTabIds()) | ||
| } | ||
| clearAllSiteData(getDeletableTabIds()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓Why is this unflagged now?
| private fun clearAllSiteData(tabIds: List<String>) { | ||
| tabIds.forEach { tabId -> | ||
| webViewSessionStorage.deleteSession(tabId) | ||
| adClickManager.clearTabId(tabId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓This feels off to me. I don't think it should be the responsibility of the TabRepository to cleanup webViewSessionStorage and adClickManager. I don't think we have the concept of UseCases but this is where I would see one useful, to coordinate all the cleanup needed. But I see we were also doing that for PreviewImages and Favicon here already.
What do you think? And it's beyond the scope of this project.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed that we were already doing the cleanup for other things, like you mentioned. I figured it'd make sense to put it all in a single place where any code deleting a tab would execute this -- hence the tab repository. The reason for this is that we would miss the cleanup for the previews and favicons when the tabs were purged, so it made sense to me to unify it here.
| data object LaunchPlayStore : Command() | ||
| data object LaunchFeedbackView : Command() | ||
| data object LaunchTabSwitcherAfterTabsUndeleted : Command() | ||
| data class ShowAppEnjoymentPrompt(val promptCount: PromptCount) : Command() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡I don't think we need to specify why in this command name, if in the end all we do is launch the TabSwitcher. I would just call it LaunchTabSwitcher
| fun undoDeletableTabs(tabIds: List<String>) { | ||
| viewModelScope.launch(dispatcherProvider.io()) { | ||
| viewModelScope.launch { | ||
| tabRepository.undoDeletable(tabIds) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓Why did you remove the use of the io dispatcher?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They were unnecessary, the operation is scheduled on an IO thread in the repository using databaseExecutor().scheduleDirect().
| private fun configureFlowCollectors() { | ||
| if (swipingTabsFeature.isEnabled) { | ||
| lifecycleScope.launch { | ||
| viewModel.tabsFlow.flowWithLifecycle(lifecycle).collectLatest { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡Use repeatOnLifecycle and launch all flow collections under one lifecycleScope.launch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea!
| } else { | ||
| if (!swipingTabsFeature.isEnabled) { | ||
| // when swiping is enabled, the state is controlled be flows initialized in configureFlowCollectors() | ||
| viewModel.selectedTab.observe(this) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
| }.filterNot { it == -1 } | ||
|
|
||
| val deletableTabsFlow = tabRepository.flowDeletableTabs | ||
| .map { tabs -> tabs.map { tab -> tab.tabId } } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
| .filter { it.isNotEmpty() } | ||
| .distinctUntilChanged() | ||
| .debounce(100.milliseconds) | ||
| .conflate() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓Why do we need the debounce? Is it a similar situation to selectedTabFlow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I've observed this weird edge case when deleting multiple tabs in succession and sometimes the snackbar didn't work correctly. This fixed it.
| tabRepository.deleteTabs(tabIds) | ||
| suspend fun onUndoDeleteSnackbarDismissed(tabIds: List<String>) { | ||
| // delete only recently deleted tabs, because others may need to be preserved for undeleting | ||
| deleteTabs(tabIds) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡"undeleting" -> "restoring"
| webViewSessionStorage.deleteSession(tabId) | ||
| } | ||
| private suspend fun deleteTabs(tabIds: List<String>) { | ||
| tabRepository.deleteTabs(tabIds) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❓Why did we remove the io dispatcher?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the operation is scheduled on an IO thread in the repository using databaseExecutor().scheduleDirect().
d15dea2 to
c727db9
Compare
0e54338 to
0b534bd
Compare
c727db9 to
9f11cf0
Compare
13d87b2 to
725c456
Compare
9f11cf0 to
7f2b510
Compare
725c456 to
12ac334
Compare
7f2b510 to
032bcb3
Compare
bda4f31 to
b744a85
Compare
d480d5e to
40202e1
Compare
8e56d79 to
052eab9
Compare

Task/Issue URL: https://app.asana.com/0/72649045549333/1209846575622288/f
Description
This PR implements the following changes:
Steps to test this PR
Undo snackbar
AI chat
Selection mode menu
Tab switcher screen title