Skip to content

Conversation

@0nko
Copy link
Member

@0nko 0nko commented Mar 31, 2025

Task/Issue URL: https://app.asana.com/0/72649045549333/1209846575622288/f

Description

This PR implements the following changes:

  • Implement undo snackbar after tab deletion in the browser screen
  • Add the AI chat back to the normal mode menu
  • Reverse the order of share/bookmark tabs in selection mode
  • Revert the tab switcher title back to "Tabs"

Steps to test this PR

Undo snackbar

  • Go to the tab switcher
  • Make sure you have multiple tabs
  • Tap on the more menu -> Close all tabs
  • Verify a snackbar with the Undo button appears in the browser
  • Tap on the Undo button
  • Verify the closed tabs are all restored
  • Verify the NTP is at the last position

AI chat

  • Go to the tab switcher
  • Verify the AI chat menu item is visible and works

Selection mode menu

  • Go to the tab switcher
  • Tap on the more menu
  • Tap on the Select tabs
  • Select some tabs
  • Tap on the more menu
  • Verify the Bookmark menu item is above Share menu item

Tab switcher screen title

  • Go to the tab switcher
  • Verify the title says "Tabs"

This was referenced Mar 31, 2025
Copy link
Member Author

0nko commented Mar 31, 2025

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.
Learn more

This stack of pull requests is managed by Graphite. Learn more about stacking.

This was referenced Mar 31, 2025
@0nko 0nko changed the title Perform all tab-related data clearing in the repository Multi-selection: Ship review Mar 31, 2025
@0nko 0nko changed the title Multi-selection: Ship review Multi-selection: Ship review change requests Mar 31, 2025
@0nko 0nko marked this pull request as ready for review March 31, 2025 17:38
@0nko 0nko requested a review from mikescamell March 31, 2025 17:57
@mikescamell mikescamell self-assigned this Apr 1, 2025
Copy link
Contributor

@mikescamell mikescamell left a 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())
Copy link
Contributor

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)
Copy link
Contributor

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.

Copy link
Member Author

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()
Copy link
Contributor

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)
Copy link
Contributor

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?

Copy link
Member Author

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 {
Copy link
Contributor

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

Copy link
Member Author

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) {
Copy link
Contributor

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 } }
Copy link
Contributor

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()
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 we need the debounce? Is it a similar situation to selectedTabFlow?

Copy link
Member Author

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)
Copy link
Contributor

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)
Copy link
Contributor

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?

Copy link
Member Author

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().

@0nko 0nko force-pushed the feature/ondrej/tab-multi-selection-ship-review-changes branch from d15dea2 to c727db9 Compare April 1, 2025 17:27
@0nko 0nko force-pushed the feature/ondrej/tab-multi-selection-translation branch from 0e54338 to 0b534bd Compare April 1, 2025 17:27
@0nko 0nko force-pushed the feature/ondrej/tab-multi-selection-ship-review-changes branch from c727db9 to 9f11cf0 Compare April 2, 2025 10:09
@0nko 0nko force-pushed the feature/ondrej/tab-multi-selection-translation branch from 13d87b2 to 725c456 Compare April 2, 2025 10:09
@0nko 0nko force-pushed the feature/ondrej/tab-multi-selection-ship-review-changes branch from 9f11cf0 to 7f2b510 Compare April 2, 2025 11:05
@0nko 0nko force-pushed the feature/ondrej/tab-multi-selection-translation branch from 725c456 to 12ac334 Compare April 2, 2025 11:05
@0nko 0nko force-pushed the feature/ondrej/tab-multi-selection-ship-review-changes branch from 7f2b510 to 032bcb3 Compare April 2, 2025 16:19
@0nko 0nko force-pushed the feature/ondrej/tab-multi-selection-translation branch from bda4f31 to b744a85 Compare April 2, 2025 16:19
@0nko 0nko force-pushed the feature/ondrej/tab-multi-selection-ship-review-changes branch from d480d5e to 40202e1 Compare April 3, 2025 09:50
Base automatically changed from feature/ondrej/tab-multi-selection-translation to feature/ondrej/tab-multi-selection April 3, 2025 09:59
@0nko 0nko force-pushed the feature/ondrej/tab-multi-selection branch from 8e56d79 to 052eab9 Compare April 3, 2025 10:00
@0nko 0nko merged commit ec8e0fb into feature/ondrej/tab-multi-selection Apr 3, 2025
3 of 5 checks passed
@0nko 0nko deleted the feature/ondrej/tab-multi-selection-ship-review-changes branch April 3, 2025 10:10
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