add container selection to new tab screen

This commit is contained in:
Fabian Freund
2026-02-03 04:21:58 +01:00
parent ba9865a22e
commit 6b361aaada
@@ -19,6 +19,7 @@
*/ */
import 'dart:async'; import 'dart:async';
import 'package:drift/drift.dart' hide Column;
import 'package:fading_scroll/fading_scroll.dart'; import 'package:fading_scroll/fading_scroll.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart'; import 'package:flutter_hooks/flutter_hooks.dart';
@@ -40,6 +41,9 @@ import 'package:weblibre/features/geckoview/features/search/presentation/widgets
import 'package:weblibre/features/geckoview/features/search/presentation/widgets/search_modules/full_search_suggestions.dart'; import 'package:weblibre/features/geckoview/features/search/presentation/widgets/search_modules/full_search_suggestions.dart';
import 'package:weblibre/features/geckoview/features/search/presentation/widgets/search_modules/history_suggestions.dart'; import 'package:weblibre/features/geckoview/features/search/presentation/widgets/search_modules/history_suggestions.dart';
import 'package:weblibre/features/geckoview/features/search/presentation/widgets/search_modules/tab_search.dart'; import 'package:weblibre/features/geckoview/features/search/presentation/widgets/search_modules/tab_search.dart';
import 'package:weblibre/features/geckoview/features/tabs/data/models/container_data.dart';
import 'package:weblibre/features/geckoview/features/tabs/domain/providers/selected_container.dart';
import 'package:weblibre/features/geckoview/features/tabs/presentation/widgets/container_chips.dart';
import 'package:weblibre/features/user/domain/repositories/general_settings.dart'; import 'package:weblibre/features/user/domain/repositories/general_settings.dart';
import 'package:weblibre/presentation/hooks/on_listenable_change_selector.dart'; import 'package:weblibre/presentation/hooks/on_listenable_change_selector.dart';
import 'package:weblibre/presentation/hooks/sampled_value_notifier.dart'; import 'package:weblibre/presentation/hooks/sampled_value_notifier.dart';
@@ -77,6 +81,13 @@ class SearchScreen extends HookConsumerWidget {
final selectedTabType = useState(tabType); final selectedTabType = useState(tabType);
final currentTabTabType = ref.watch(selectedTabTypeProvider); final currentTabTabType = ref.watch(selectedTabTypeProvider);
final selectedContainer = useState<ContainerData?>(null);
ref.listen(selectedContainerDataProvider, (previous, next) {
next.whenData((container) {
selectedContainer.value = container;
});
});
// When editing an existing tab, get its state // When editing an existing tab, get its state
// If tab no longer exists (null), fall back to new tab mode // If tab no longer exists (null), fall back to new tab mode
final existingTabState = tabId != null final existingTabState = tabId != null
@@ -240,6 +251,7 @@ class SearchScreen extends HookConsumerWidget {
: null, : null,
launchedFromIntent: launchedFromIntent, launchedFromIntent: launchedFromIntent,
selectTab: true, selectTab: true,
container: Value(selectedContainer.value),
); );
} }
@@ -264,58 +276,84 @@ class SearchScreen extends HookConsumerWidget {
floating: true, floating: true,
pinned: true, pinned: true,
automaticallyImplyLeading: false, automaticallyImplyLeading: false,
toolbarHeight: isEditMode ? 0 : kToolbarHeight, toolbarHeight: isEditMode ? 0 : kToolbarHeight + 56,
title: isEditMode title: isEditMode
? null ? null
: Align( : Column(
child: Focus( mainAxisSize: MainAxisSize.min,
canRequestFocus: false, children: [
child: SegmentedButton( Focus(
showSelectedIcon: false, canRequestFocus: false,
segments: [ child: SegmentedButton(
const ButtonSegment( showSelectedIcon: false,
value: TabType.regular, segments: [
label: Text('Regular'),
icon: Icon(MdiIcons.tab),
),
const ButtonSegment(
value: TabType.private,
label: Text('Private'),
icon: Icon(WebLibreIcons.privateTab),
),
if (createChildTabsOption)
const ButtonSegment( const ButtonSegment(
value: TabType.child, value: TabType.regular,
label: Text('Child'), label: Text('Regular'),
icon: Icon(MdiIcons.fileTree), icon: Icon(MdiIcons.tab),
), ),
], const ButtonSegment(
selected: {selectedTabType.value}, value: TabType.private,
onSelectionChanged: (value) { label: Text('Private'),
selectedTabType.value = value.first; icon: Icon(WebLibreIcons.privateTab),
// Restore focus to search field after segment change ),
WidgetsBinding.instance.addPostFrameCallback(( if (createChildTabsOption)
_, const ButtonSegment(
) { value: TabType.child,
searchFocusNode.requestFocus(); label: Text('Child'),
}); icon: Icon(MdiIcons.fileTree),
}, ),
style: switch (selectedTabType.value) { ],
TabType.regular => null, selected: {selectedTabType.value},
TabType.private => SegmentedButton.styleFrom( onSelectionChanged: (value) {
selectedBackgroundColor: selectedTabType.value = value.first;
appColors.privateSelectionOverlay, // Restore focus to search field after segment change
), WidgetsBinding.instance
TabType.child => .addPostFrameCallback((_) {
(currentTabTabType == TabType.private) searchFocusNode.requestFocus();
? SegmentedButton.styleFrom( });
selectedBackgroundColor: appColors },
.privateSelectionOverlay, style: switch (selectedTabType.value) {
) TabType.regular => null,
: null, TabType.private =>
}, SegmentedButton.styleFrom(
selectedBackgroundColor:
appColors.privateSelectionOverlay,
),
TabType.child =>
(currentTabTabType == TabType.private)
? SegmentedButton.styleFrom(
selectedBackgroundColor: appColors
.privateSelectionOverlay,
)
: null,
},
),
), ),
), const SizedBox(height: 8),
SizedBox(
height: 48,
child: ContainerChips(
selectedContainer: selectedContainer.value,
onSelected: (container) async {
if (container != null) {
if (await ref
.read(
selectedContainerProvider.notifier,
)
.authenticateContainer(container)) {
selectedContainer.value = container;
}
} else {
selectedContainer.value = container;
}
},
onDeleted: (container) {
selectedContainer.value = null;
},
),
),
],
), ),
bottom: PreferredSize( bottom: PreferredSize(
preferredSize: Size.fromHeight(preferredHeight.value), preferredSize: Size.fromHeight(preferredHeight.value),
@@ -393,6 +431,9 @@ class SearchScreen extends HookConsumerWidget {
: null, : null,
launchedFromIntent: launchedFromIntent, launchedFromIntent: launchedFromIntent,
selectTab: true, selectTab: true,
container: Value(
selectedContainer.value,
),
); );
} }
@@ -446,6 +487,7 @@ class SearchScreen extends HookConsumerWidget {
: null, : null,
launchedFromIntent: launchedFromIntent, launchedFromIntent: launchedFromIntent,
selectTab: true, selectTab: true,
container: Value(selectedContainer.value),
); );
} }