respect pinned tabs and direction when sorting

This commit is contained in:
Fabian Freund
2026-05-04 18:15:31 +02:00
parent d503f032ab
commit 8220fad626
12 changed files with 206 additions and 80 deletions
@@ -401,7 +401,7 @@ class TabRepository extends _$TabRepository {
// anchored to the bar's mental model. // anchored to the bar's mental model.
final newestFirst = final newestFirst =
ref.read(generalSettingsWithDefaultsProvider).tabBarDirection == ref.read(generalSettingsWithDefaultsProvider).tabBarDirection ==
TabBarDirection.newestFirst; TabDirection.newestFirst;
final TabDatabase tabDatabase = ref.read(tabDatabaseProvider); final TabDatabase tabDatabase = ref.read(tabDatabaseProvider);
final definitions = tabDatabase.definitionsDrift; final definitions = tabDatabase.definitionsDrift;
@@ -41,7 +41,7 @@ final class TabRepositoryProvider
} }
} }
String _$tabRepositoryHash() => r'84ecfed72f17c367fc7bf0100f6367d4e7609596'; String _$tabRepositoryHash() => r'a68941d373f348201e3d8b1cab26343acca3852f';
abstract class _$TabRepository extends $Notifier<void> { abstract class _$TabRepository extends $Notifier<void> {
void build(); void build();
@@ -227,11 +227,74 @@ selectedContainerTabStatesWithContainer(Ref ref) {
.watch(groupedTabListItemsProvider(containerId: filter.containerId)) .watch(groupedTabListItemsProvider(containerId: filter.containerId))
.value; .value;
final tabListDirection = ref.watch(
generalSettingsWithDefaultsProvider.select((s) => s.tabListDirection),
);
final tabBarDirection = ref.watch(
generalSettingsWithDefaultsProvider.select((s) => s.tabBarDirection),
);
final pinnedTabIds = ref.watch(
watchPinnedTabIdsProvider.select(
(value) => value.value ?? const <String>{},
),
);
final sortPinnedFirst = ref.watch(
tabViewFilterControllerProvider.select((v) => v.sortPinnedFirst),
);
// Build an order map from groupedItems. When the tab bar direction differs
// from the tab list direction, reverse root group order within each
// pinned/unpinned partition so the bar respects the user's direction
// preference while keeping parentchild groups intact.
List<TabListItemEntity> orderedItems = groupedItems;
if (tabBarDirection != tabListDirection) {
// Split groupedItems into root groups (each: root + its children).
final rootGroups = <(bool isPinned, List<TabListItemEntity>)>[];
var currentGroup = <TabListItemEntity>[];
for (final item in groupedItems) {
final isRoot =
item is TabListStandaloneItem || item is TabListParentGroup;
if (isRoot && currentGroup.isNotEmpty) {
final isPinned =
sortPinnedFirst && pinnedTabIds.contains(currentGroup.first.tabId);
rootGroups.add((isPinned, currentGroup));
currentGroup = [];
}
currentGroup.add(item);
}
if (currentGroup.isNotEmpty) {
final isPinned =
sortPinnedFirst && pinnedTabIds.contains(currentGroup.first.tabId);
rootGroups.add((isPinned, currentGroup));
}
// Reverse root groups within each partition (pinned / unpinned).
final result = <TabListItemEntity>[];
if (sortPinnedFirst) {
final pinned = rootGroups
.where((g) => g.$1)
.toList()
.reversed
.expand((g) => g.$2);
final unpinned = rootGroups
.where((g) => !g.$1)
.toList()
.reversed
.expand((g) => g.$2);
result
..addAll(pinned)
..addAll(unpinned);
} else {
result.addAll(rootGroups.reversed.expand((g) => g.$2));
}
orderedItems = result;
}
final groupedOrder = { final groupedOrder = {
for (var i = 0; i < groupedItems.length; i++) groupedItems[i].tabId: i, for (var i = 0; i < orderedItems.length; i++) orderedItems[i].tabId: i,
}; };
final items = [ var items = [
for (final tabEntity in sortedTabs) for (final tabEntity in sortedTabs)
if (tabStates.containsKey(tabEntity.tabId)) if (tabStates.containsKey(tabEntity.tabId))
( (
@@ -243,11 +306,21 @@ selectedContainerTabStatesWithContainer(Ref ref) {
]; ];
items.sort((a, b) { items.sort((a, b) {
final aIndex = groupedOrder[a.$1.id] ?? groupedItems.length; final aIndex = groupedOrder[a.$1.id] ?? orderedItems.length;
final bIndex = groupedOrder[b.$1.id] ?? groupedItems.length; final bIndex = groupedOrder[b.$1.id] ?? orderedItems.length;
return aIndex.compareTo(bIndex); return aIndex.compareTo(bIndex);
}); });
// Flat pinned-first: move all pinned tabs before unpinned regardless of
// hierarchy, preserving relative order within each partition.
if (sortPinnedFirst && pinnedTabIds.isNotEmpty) {
final pinned = items.where((i) => pinnedTabIds.contains(i.$1.id)).toList();
final unpinned = items
.where((i) => !pinnedTabIds.contains(i.$1.id))
.toList();
items = [...pinned, ...unpinned];
}
return EquatableValue(items); return EquatableValue(items);
} }
@@ -277,12 +350,35 @@ EquatableValue<List<TabStateWithContainer>> quickTabSwitcherTabStates(
generalSettingsWithDefaultsProvider.select((s) => s.tabBarDirection), generalSettingsWithDefaultsProvider.select((s) => s.tabBarDirection),
); );
final pinnedTabIds = ref.watch(
watchPinnedTabIdsProvider.select(
(value) => value.value ?? const <String>{},
),
);
final sortPinnedFirst = ref.watch(
tabViewFilterControllerProvider.select((v) => v.sortPinnedFirst),
);
return EquatableValue(switch (effectiveMode) { return EquatableValue(switch (effectiveMode) {
QuickTabSwitcherMode.lastUsedTabs => () { QuickTabSwitcherMode.lastUsedTabs => () {
final filtered = tabStates final filtered = tabStates
.where((state) => state.$1.id != selectedTabId) .where((state) => state.$1.id != selectedTabId)
.toList(); .toList();
return tabBarDirection == TabBarDirection.oldestFirst if (sortPinnedFirst && pinnedTabIds.isNotEmpty) {
final pinned = filtered
.where((s) => pinnedTabIds.contains(s.$1.id))
.toList();
final unpinned = filtered
.where((s) => !pinnedTabIds.contains(s.$1.id))
.toList();
// Each partition is MRU-first from fifoTabStates. For oldestFirst,
// reverse each partition independently so pinned stays on top.
if (tabBarDirection == TabDirection.oldestFirst) {
return [...pinned.reversed, ...unpinned.reversed];
}
return [...pinned, ...unpinned];
}
return tabBarDirection == TabDirection.oldestFirst
? filtered.reversed.toList() ? filtered.reversed.toList()
: filtered; : filtered;
}(), }(),
@@ -605,7 +701,7 @@ EquatableValue<List<TabEntity>> seamlessFilteredTabEntities(
// database order (ascending order_key) is oldest-first. Flip to // database order (ascending order_key) is oldest-first. Flip to
// newest-first when the user selects that direction. // newest-first when the user selects that direction.
List<TabEntity> applyDirection(List<TabEntity> entities) { List<TabEntity> applyDirection(List<TabEntity> entities) {
return tabListDirection == TabListDirection.newestFirst return tabListDirection == TabDirection.newestFirst
? entities.reversed.toList() ? entities.reversed.toList()
: entities; : entities;
} }
@@ -697,7 +793,7 @@ EquatableValue<List<TabPreview>> filteredTabPreviews(
/// Grouped flat-list rendering for the list and grid views. /// Grouped flat-list rendering for the list and grid views.
/// ///
/// Parent rows always render before their descendants. [TabListDirection] /// Parent rows always render before their descendants. [TabDirection]
/// applies both to root group ordering and to sibling ordering below each /// applies both to root group ordering and to sibling ordering below each
/// parent, so parent-child pairs stay together while child order still follows /// parent, so parent-child pairs stay together while child order still follows
/// the configured direction. /// the configured direction.
@@ -867,7 +963,7 @@ EquatableValue<List<TabListItemEntity>> groupedTabListItems(
// order_key ASC; newest-first reverses the group list. Pinned and // order_key ASC; newest-first reverses the group list. Pinned and
// unpinned partitions are reversed independently so pinned-first stays // unpinned partitions are reversed independently so pinned-first stays
// intact while still flipping the relative order within each partition. // intact while still flipping the relative order within each partition.
if (sortField == null && tabListDirection == TabListDirection.newestFirst) { if (sortField == null && tabListDirection == TabDirection.newestFirst) {
if (filterOptions.sortPinnedFirst) { if (filterOptions.sortPinnedFirst) {
final pinned = groupRecords.where((g) => g.isPinned).toList() final pinned = groupRecords.where((g) => g.isPinned).toList()
..sort((a, b) => b.rootOrderKey.compareTo(a.rootOrderKey)); ..sort((a, b) => b.rootOrderKey.compareTo(a.rootOrderKey));
@@ -931,17 +1027,36 @@ EquatableValue<List<TabListItemEntity>> groupedTabListItems(
.add(member); .add(member);
} }
// Children are always sorted by storage `order_key` (optionally reversed // Children are sorted by storage `order_key` (optionally reversed for
// for newest-first) — even when an explicit `sortField` (title/url/date) // newest-first) — even when an explicit `sortField` is active. The
// is active. The explicit sort applies only to root groups; descendants // explicit sort applies only to root groups; descendants remain in
// remain in insertion order so a parent's children stay grouped in the // insertion order. When `sortPinnedFirst` is true, pinned children are
// order they were opened rather than alphabetically interleaving across // sorted before unpinned siblings within each parent group.
// siblings.
for (final children in childrenByVisibleParent.values) { for (final children in childrenByVisibleParent.values) {
children.sort((a, b) { if (filterOptions.sortPinnedFirst) {
final cmp = a.row.orderKey.compareTo(b.row.orderKey); final pinned = children
return tabListDirection == TabListDirection.newestFirst ? -cmp : cmp; .where((c) => pinnedTabIds.contains(c.row.id))
}); .toList();
final unpinned = children
.where((c) => !pinnedTabIds.contains(c.row.id))
.toList();
final cmp = (_GroupedRow a, _GroupedRow b) =>
a.row.orderKey.compareTo(b.row.orderKey);
final directionCmp = tabListDirection == TabDirection.newestFirst
? (_GroupedRow a, _GroupedRow b) => -cmp(a, b)
: cmp;
pinned.sort(directionCmp);
unpinned.sort(directionCmp);
children
..clear()
..addAll(pinned)
..addAll(unpinned);
} else {
children.sort((a, b) {
final cmp = a.row.orderKey.compareTo(b.row.orderKey);
return tabListDirection == TabDirection.newestFirst ? -cmp : cmp;
});
}
} }
void addChildren(String parentId) { void addChildren(String parentId) {
@@ -49,7 +49,7 @@ final class CanManualTabReorderProvider
} }
String _$canManualTabReorderHash() => String _$canManualTabReorderHash() =>
r'598bc67a750f45893ba555b9b7866499b1808896'; r'ba5d961933464b6e005d7945802908a9a4ae034b';
@ProviderFor(SelectedBangTrigger) @ProviderFor(SelectedBangTrigger)
final selectedBangTriggerProvider = SelectedBangTriggerFamily._(); final selectedBangTriggerProvider = SelectedBangTriggerFamily._();
@@ -529,7 +529,7 @@ final class SelectedContainerTabStatesWithContainerProvider
} }
String _$selectedContainerTabStatesWithContainerHash() => String _$selectedContainerTabStatesWithContainerHash() =>
r'6b630cdfc589af6961d4c96c90d09bd107560f15'; r'e6fd0e1e0ca4cfb0a0a46e8ff4e63d41032bfad9';
@ProviderFor(quickTabSwitcherTabStates) @ProviderFor(quickTabSwitcherTabStates)
final quickTabSwitcherTabStatesProvider = QuickTabSwitcherTabStatesFamily._(); final quickTabSwitcherTabStatesProvider = QuickTabSwitcherTabStatesFamily._();
@@ -601,7 +601,7 @@ final class QuickTabSwitcherTabStatesProvider
} }
String _$quickTabSwitcherTabStatesHash() => String _$quickTabSwitcherTabStatesHash() =>
r'32e928b4596ef2388f8c0e4cfdcf8f3563a1e24a'; r'3a1a195f6b2fc4cc54e689fab7bacaf4e6422196';
final class QuickTabSwitcherTabStatesFamily extends $Family final class QuickTabSwitcherTabStatesFamily extends $Family
with with
@@ -962,7 +962,7 @@ final class SeamlessFilteredTabEntitiesProvider
} }
String _$seamlessFilteredTabEntitiesHash() => String _$seamlessFilteredTabEntitiesHash() =>
r'79abca3ad2753af4482c0e3bcfa317a6f336ca17'; r'83113c04be7932c60c7c97b70595fde0145f8040';
final class SeamlessFilteredTabEntitiesFamily extends $Family final class SeamlessFilteredTabEntitiesFamily extends $Family
with with
@@ -1097,7 +1097,7 @@ final class FilteredTabPreviewsFamily extends $Family
/// Grouped flat-list rendering for the list and grid views. /// Grouped flat-list rendering for the list and grid views.
/// ///
/// Parent rows always render before their descendants. [TabListDirection] /// Parent rows always render before their descendants. [TabDirection]
/// applies both to root group ordering and to sibling ordering below each /// applies both to root group ordering and to sibling ordering below each
/// parent, so parent-child pairs stay together while child order still follows /// parent, so parent-child pairs stay together while child order still follows
/// the configured direction. /// the configured direction.
@@ -1109,7 +1109,7 @@ final groupedTabListItemsProvider = GroupedTabListItemsFamily._();
/// Grouped flat-list rendering for the list and grid views. /// Grouped flat-list rendering for the list and grid views.
/// ///
/// Parent rows always render before their descendants. [TabListDirection] /// Parent rows always render before their descendants. [TabDirection]
/// applies both to root group ordering and to sibling ordering below each /// applies both to root group ordering and to sibling ordering below each
/// parent, so parent-child pairs stay together while child order still follows /// parent, so parent-child pairs stay together while child order still follows
/// the configured direction. /// the configured direction.
@@ -1126,7 +1126,7 @@ final class GroupedTabListItemsProvider
with $Provider<EquatableValue<List<TabListItemEntity>>> { with $Provider<EquatableValue<List<TabListItemEntity>>> {
/// Grouped flat-list rendering for the list and grid views. /// Grouped flat-list rendering for the list and grid views.
/// ///
/// Parent rows always render before their descendants. [TabListDirection] /// Parent rows always render before their descendants. [TabDirection]
/// applies both to root group ordering and to sibling ordering below each /// applies both to root group ordering and to sibling ordering below each
/// parent, so parent-child pairs stay together while child order still follows /// parent, so parent-child pairs stay together while child order still follows
/// the configured direction. /// the configured direction.
@@ -1186,11 +1186,11 @@ final class GroupedTabListItemsProvider
} }
String _$groupedTabListItemsHash() => String _$groupedTabListItemsHash() =>
r'48c7c971d95934afb48aa19b7400e208ee2f10e4'; r'15106bfa42146270245c7178928a834237042c1c';
/// Grouped flat-list rendering for the list and grid views. /// Grouped flat-list rendering for the list and grid views.
/// ///
/// Parent rows always render before their descendants. [TabListDirection] /// Parent rows always render before their descendants. [TabDirection]
/// applies both to root group ordering and to sibling ordering below each /// applies both to root group ordering and to sibling ordering below each
/// parent, so parent-child pairs stay together while child order still follows /// parent, so parent-child pairs stay together while child order still follows
/// the configured direction. /// the configured direction.
@@ -1214,7 +1214,7 @@ final class GroupedTabListItemsFamily extends $Family
/// Grouped flat-list rendering for the list and grid views. /// Grouped flat-list rendering for the list and grid views.
/// ///
/// Parent rows always render before their descendants. [TabListDirection] /// Parent rows always render before their descendants. [TabDirection]
/// applies both to root group ordering and to sibling ordering below each /// applies both to root group ordering and to sibling ordering below each
/// parent, so parent-child pairs stay together while child order still follows /// parent, so parent-child pairs stay together while child order still follows
/// the configured direction. /// the configured direction.
@@ -41,7 +41,7 @@ TabViewReorderResult? buildTabViewReorderResult({
required Set<String> pinnedTabIds, required Set<String> pinnedTabIds,
required int oldIndex, required int oldIndex,
required int newIndex, required int newIndex,
required TabListDirection tabListDirection, required TabDirection tabListDirection,
required bool hierarchical, required bool hierarchical,
required bool sortPinnedFirst, required bool sortPinnedFirst,
}) { }) {
@@ -178,7 +178,7 @@ TabViewReorderResult? buildTabViewReorderResult({
// order before picking anchors so genBetween receives prev.orderKey < // order before picking anchors so genBetween receives prev.orderKey <
// next.orderKey. Block contents (e.g. the moving subtree from _subtreeIds) // next.orderKey. Block contents (e.g. the moving subtree from _subtreeIds)
// are already storage-ordered internally, so we reverse blocks as units. // are already storage-ordered internally, so we reverse blocks as units.
if (tabListDirection == TabListDirection.newestFirst) { if (tabListDirection == TabDirection.newestFirst) {
for (final blocks in blocksByRoot.values) { for (final blocks in blocksByRoot.values) {
if (blocks.length > 1) { if (blocks.length > 1) {
final reversedTail = blocks.sublist(1).reversed.toList(); final reversedTail = blocks.sublist(1).reversed.toList();
@@ -189,7 +189,7 @@ TabViewReorderResult? buildTabViewReorderResult({
} }
} }
final orderedRootIds = tabListDirection == TabListDirection.newestFirst final orderedRootIds = tabListDirection == TabDirection.newestFirst
? rootOrder.reversed ? rootOrder.reversed
: rootOrder; : rootOrder;
@@ -213,13 +213,13 @@ TabViewReorderResult? buildTabViewReorderResult({
List<String> _orderedIdsForStorageAnchors( List<String> _orderedIdsForStorageAnchors(
List<String> orderedTabIds, { List<String> orderedTabIds, {
required TabListDirection tabListDirection, required TabDirection tabListDirection,
required Set<String> pinnedTabIds, required Set<String> pinnedTabIds,
required Map<String, String?> parentById, required Map<String, String?> parentById,
required String movingPartitionRootId, required String movingPartitionRootId,
required bool sortPinnedFirst, required bool sortPinnedFirst,
}) { }) {
var storageOrderedIds = tabListDirection == TabListDirection.newestFirst var storageOrderedIds = tabListDirection == TabDirection.newestFirst
// Rendering flips root group order for newest-first; convert the // Rendering flips root group order for newest-first; convert the
// display order back to storage order before choosing anchors. // display order back to storage order before choosing anchors.
? orderedTabIds.reversed.toList() ? orderedTabIds.reversed.toList()
@@ -200,7 +200,7 @@ class _TabGridView extends HookConsumerWidget {
).select((value) => (value.value?.query ?? '').isNotEmpty), ).select((value) => (value.value?.query ?? '').isNotEmpty),
); );
final List<TabViewItem> primaryRows; List<TabViewItem> primaryRows;
if (hasActiveSearch) { if (hasActiveSearch) {
final flat = ref.watch( final flat = ref.watch(
seamlessFilteredTabEntitiesProvider( seamlessFilteredTabEntitiesProvider(
@@ -242,6 +242,15 @@ class _TabGridView extends HookConsumerWidget {
: TabViewItem.standalone(tabId: c.tabId), : TabViewItem.standalone(tabId: c.tabId),
}, },
]; ];
if (!showHierarchicalTabs && filterOptions.sortPinnedFirst) {
final pinned = primaryRows
.where((r) => pinnedTabIds.contains(r.tabId))
.toList();
final unpinned = primaryRows
.where((r) => !pinnedTabIds.contains(r.tabId))
.toList();
primaryRows = [...pinned, ...unpinned];
}
} }
final tabSuggestionsEnabled = ref.watch( final tabSuggestionsEnabled = ref.watch(
@@ -261,7 +261,7 @@ class _TabListView extends HookConsumerWidget {
).select((value) => (value.value?.query ?? '').isNotEmpty), ).select((value) => (value.value?.query ?? '').isNotEmpty),
); );
final List<TabViewItem> primaryRows; List<TabViewItem> primaryRows;
if (hasActiveSearch) { if (hasActiveSearch) {
final flat = ref.watch( final flat = ref.watch(
seamlessFilteredTabEntitiesProvider( seamlessFilteredTabEntitiesProvider(
@@ -303,6 +303,15 @@ class _TabListView extends HookConsumerWidget {
: TabViewItem.standalone(tabId: c.tabId), : TabViewItem.standalone(tabId: c.tabId),
}, },
]; ];
if (!showHierarchicalTabs && filterOptions.sortPinnedFirst) {
final pinned = primaryRows
.where((r) => pinnedTabIds.contains(r.tabId))
.toList();
final unpinned = primaryRows
.where((r) => !pinnedTabIds.contains(r.tabId))
.toList();
primaryRows = [...pinned, ...unpinned];
}
} }
final tabSuggestionsEnabled = ref.watch( final tabSuggestionsEnabled = ref.watch(
@@ -33,7 +33,7 @@ final class IntentGatekeeperProvider
IntentGatekeeper create() => IntentGatekeeper(); IntentGatekeeper create() => IntentGatekeeper();
} }
String _$intentGatekeeperHash() => r'0ab4a96dde7a21df5dd32d034f841bf4d40dbb10'; String _$intentGatekeeperHash() => r'466bef55521edc3574edaaea6e8cb2805bd87296';
abstract class _$IntentGatekeeper abstract class _$IntentGatekeeper
extends $StreamNotifier<PendingIntentDecision> { extends $StreamNotifier<PendingIntentDecision> {
@@ -13,8 +13,8 @@ part of 'native_gatekeeper_replicator.dart';
/// Only blocked packages are replicated — allow/unknown still fall through to /// Only blocked packages are replicated — allow/unknown still fall through to
/// the Flutter gatekeeper dialog. /// the Flutter gatekeeper dialog.
/// ///
/// On startup, also consumes any "always allow" decisions made via notification /// Also consumes any "always allow" decisions made via notification actions
/// actions while Flutter was not running, and merges them into Flutter's policy. /// and merges them into Flutter's policy before the next gatekeeper check.
@ProviderFor(NativeIntentGatekeeperReplicator) @ProviderFor(NativeIntentGatekeeperReplicator)
final nativeIntentGatekeeperReplicatorProvider = final nativeIntentGatekeeperReplicatorProvider =
@@ -25,8 +25,8 @@ final nativeIntentGatekeeperReplicatorProvider =
/// Only blocked packages are replicated — allow/unknown still fall through to /// Only blocked packages are replicated — allow/unknown still fall through to
/// the Flutter gatekeeper dialog. /// the Flutter gatekeeper dialog.
/// ///
/// On startup, also consumes any "always allow" decisions made via notification /// Also consumes any "always allow" decisions made via notification actions
/// actions while Flutter was not running, and merges them into Flutter's policy. /// and merges them into Flutter's policy before the next gatekeeper check.
final class NativeIntentGatekeeperReplicatorProvider final class NativeIntentGatekeeperReplicatorProvider
extends $NotifierProvider<NativeIntentGatekeeperReplicator, void> { extends $NotifierProvider<NativeIntentGatekeeperReplicator, void> {
/// Mirrors the Flutter-side block list to the native side so the /// Mirrors the Flutter-side block list to the native side so the
@@ -34,8 +34,8 @@ final class NativeIntentGatekeeperReplicatorProvider
/// Only blocked packages are replicated — allow/unknown still fall through to /// Only blocked packages are replicated — allow/unknown still fall through to
/// the Flutter gatekeeper dialog. /// the Flutter gatekeeper dialog.
/// ///
/// On startup, also consumes any "always allow" decisions made via notification /// Also consumes any "always allow" decisions made via notification actions
/// actions while Flutter was not running, and merges them into Flutter's policy. /// and merges them into Flutter's policy before the next gatekeeper check.
NativeIntentGatekeeperReplicatorProvider._() NativeIntentGatekeeperReplicatorProvider._()
: super( : super(
from: null, from: null,
@@ -65,15 +65,15 @@ final class NativeIntentGatekeeperReplicatorProvider
} }
String _$nativeIntentGatekeeperReplicatorHash() => String _$nativeIntentGatekeeperReplicatorHash() =>
r'ed1ba2a318467317d6fb412495171acb8819e483'; r'bb2e2a252143879e558d513f9c48f3e66513baa9';
/// Mirrors the Flutter-side block list to the native side so the /// Mirrors the Flutter-side block list to the native side so the
/// `IntentReceiverActivity` can reject intents without launching Flutter. /// `IntentReceiverActivity` can reject intents without launching Flutter.
/// Only blocked packages are replicated — allow/unknown still fall through to /// Only blocked packages are replicated — allow/unknown still fall through to
/// the Flutter gatekeeper dialog. /// the Flutter gatekeeper dialog.
/// ///
/// On startup, also consumes any "always allow" decisions made via notification /// Also consumes any "always allow" decisions made via notification actions
/// actions while Flutter was not running, and merges them into Flutter's policy. /// and merges them into Flutter's policy before the next gatekeeper check.
abstract class _$NativeIntentGatekeeperReplicator extends $Notifier<void> { abstract class _$NativeIntentGatekeeperReplicator extends $Notifier<void> {
void build(); void build();
@@ -383,12 +383,12 @@ class _TabListDirectionSection extends HookConsumerWidget {
showSelectedIcon: false, showSelectedIcon: false,
segments: const [ segments: const [
ButtonSegment( ButtonSegment(
value: TabListDirection.newestFirst, value: TabDirection.newestFirst,
label: Text('Newest first'), label: Text('Newest first'),
icon: Icon(MdiIcons.arrowCollapseUp), icon: Icon(MdiIcons.arrowCollapseUp),
), ),
ButtonSegment( ButtonSegment(
value: TabListDirection.oldestFirst, value: TabDirection.oldestFirst,
label: Text('Oldest first'), label: Text('Oldest first'),
icon: Icon(MdiIcons.arrowCollapseDown), icon: Icon(MdiIcons.arrowCollapseDown),
), ),
@@ -438,12 +438,12 @@ class _TabBarDirectionSection extends HookConsumerWidget {
showSelectedIcon: false, showSelectedIcon: false,
segments: const [ segments: const [
ButtonSegment( ButtonSegment(
value: TabBarDirection.newestFirst, value: TabDirection.newestFirst,
label: Text('Newest first'), label: Text('Newest first'),
icon: Icon(MdiIcons.arrowCollapseLeft), icon: Icon(MdiIcons.arrowCollapseLeft),
), ),
ButtonSegment( ButtonSegment(
value: TabBarDirection.oldestFirst, value: TabDirection.oldestFirst,
label: Text('Oldest first'), label: Text('Oldest first'),
icon: Icon(MdiIcons.arrowCollapseRight), icon: Icon(MdiIcons.arrowCollapseRight),
), ),
@@ -46,9 +46,7 @@ enum QuickTabSwitcherMode { lastUsedTabs, containerTabs }
enum TabIntentOpenSetting { regular, private, isolated, ask } enum TabIntentOpenSetting { regular, private, isolated, ask }
enum TabListDirection { newestFirst, oldestFirst } enum TabDirection { newestFirst, oldestFirst }
enum TabBarDirection { newestFirst, oldestFirst }
enum TabBarPosition { top, bottom } enum TabBarPosition { top, bottom }
@@ -88,8 +86,8 @@ class GeneralSettings with FastEquatable {
final bool showIsolatedTabUi; final bool showIsolatedTabUi;
@JsonKey(name: 'defaultCreateTabType') @JsonKey(name: 'defaultCreateTabType')
final TabType storedDefaultCreateTabType; final TabType storedDefaultCreateTabType;
final TabListDirection tabListDirection; final TabDirection tabListDirection;
final TabBarDirection tabBarDirection; final TabDirection tabBarDirection;
final TabIntentOpenSetting tabIntentOpenSetting; final TabIntentOpenSetting tabIntentOpenSetting;
final bool autoHideTabBar; final bool autoHideTabBar;
final TabBarSwipeAction tabBarSwipeAction; final TabBarSwipeAction tabBarSwipeAction;
@@ -199,8 +197,8 @@ class GeneralSettings with FastEquatable {
bool? showContainerUi, bool? showContainerUi,
bool? showIsolatedTabUi, bool? showIsolatedTabUi,
TabType? storedDefaultCreateTabType, TabType? storedDefaultCreateTabType,
TabListDirection? tabListDirection, TabDirection? tabListDirection,
TabBarDirection? tabBarDirection, TabDirection? tabBarDirection,
TabIntentOpenSetting? tabIntentOpenSetting, TabIntentOpenSetting? tabIntentOpenSetting,
bool? autoHideTabBar, bool? autoHideTabBar,
TabBarSwipeAction? tabBarSwipeAction, TabBarSwipeAction? tabBarSwipeAction,
@@ -253,8 +251,8 @@ class GeneralSettings with FastEquatable {
showIsolatedTabUi = showIsolatedTabUi ?? true, showIsolatedTabUi = showIsolatedTabUi ?? true,
storedDefaultCreateTabType = storedDefaultCreateTabType =
storedDefaultCreateTabType ?? TabType.regular, storedDefaultCreateTabType ?? TabType.regular,
tabListDirection = tabListDirection ?? TabListDirection.newestFirst, tabListDirection = tabListDirection ?? TabDirection.newestFirst,
tabBarDirection = tabBarDirection ?? TabBarDirection.newestFirst, tabBarDirection = tabBarDirection ?? TabDirection.newestFirst,
tabIntentOpenSetting = tabIntentOpenSetting ?? TabIntentOpenSetting.ask, tabIntentOpenSetting = tabIntentOpenSetting ?? TabIntentOpenSetting.ask,
autoHideTabBar = autoHideTabBar ?? true, autoHideTabBar = autoHideTabBar ?? true,
tabBarSwipeAction = tabBarSwipeAction =
@@ -43,9 +43,9 @@ abstract class _$GeneralSettingsCWProxy {
TabType storedDefaultCreateTabType, TabType storedDefaultCreateTabType,
); );
GeneralSettings tabListDirection(TabListDirection tabListDirection); GeneralSettings tabListDirection(TabDirection tabListDirection);
GeneralSettings tabBarDirection(TabBarDirection tabBarDirection); GeneralSettings tabBarDirection(TabDirection tabBarDirection);
GeneralSettings tabIntentOpenSetting( GeneralSettings tabIntentOpenSetting(
TabIntentOpenSetting tabIntentOpenSetting, TabIntentOpenSetting tabIntentOpenSetting,
@@ -156,8 +156,8 @@ abstract class _$GeneralSettingsCWProxy {
bool showContainerUi, bool showContainerUi,
bool showIsolatedTabUi, bool showIsolatedTabUi,
TabType storedDefaultCreateTabType, TabType storedDefaultCreateTabType,
TabListDirection tabListDirection, TabDirection tabListDirection,
TabBarDirection tabBarDirection, TabDirection tabBarDirection,
TabIntentOpenSetting tabIntentOpenSetting, TabIntentOpenSetting tabIntentOpenSetting,
bool autoHideTabBar, bool autoHideTabBar,
TabBarSwipeAction tabBarSwipeAction, TabBarSwipeAction tabBarSwipeAction,
@@ -268,11 +268,11 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
) => call(storedDefaultCreateTabType: storedDefaultCreateTabType); ) => call(storedDefaultCreateTabType: storedDefaultCreateTabType);
@override @override
GeneralSettings tabListDirection(TabListDirection tabListDirection) => GeneralSettings tabListDirection(TabDirection tabListDirection) =>
call(tabListDirection: tabListDirection); call(tabListDirection: tabListDirection);
@override @override
GeneralSettings tabBarDirection(TabBarDirection tabBarDirection) => GeneralSettings tabBarDirection(TabDirection tabBarDirection) =>
call(tabBarDirection: tabBarDirection); call(tabBarDirection: tabBarDirection);
@override @override
@@ -585,13 +585,13 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
tabListDirection == null tabListDirection == null
? _value.tabListDirection ? _value.tabListDirection
// ignore: cast_nullable_to_non_nullable // ignore: cast_nullable_to_non_nullable
: tabListDirection as TabListDirection, : tabListDirection as TabDirection,
tabBarDirection: tabBarDirection:
tabBarDirection == const $CopyWithPlaceholder() || tabBarDirection == const $CopyWithPlaceholder() ||
tabBarDirection == null tabBarDirection == null
? _value.tabBarDirection ? _value.tabBarDirection
// ignore: cast_nullable_to_non_nullable // ignore: cast_nullable_to_non_nullable
: tabBarDirection as TabBarDirection, : tabBarDirection as TabDirection,
tabIntentOpenSetting: tabIntentOpenSetting:
tabIntentOpenSetting == const $CopyWithPlaceholder() || tabIntentOpenSetting == const $CopyWithPlaceholder() ||
tabIntentOpenSetting == null tabIntentOpenSetting == null
@@ -851,11 +851,11 @@ GeneralSettings _$GeneralSettingsFromJson(
json['defaultCreateTabType'], json['defaultCreateTabType'],
), ),
tabListDirection: $enumDecodeNullable( tabListDirection: $enumDecodeNullable(
_$TabListDirectionEnumMap, _$TabDirectionEnumMap,
json['tabListDirection'], json['tabListDirection'],
), ),
tabBarDirection: $enumDecodeNullable( tabBarDirection: $enumDecodeNullable(
_$TabBarDirectionEnumMap, _$TabDirectionEnumMap,
json['tabBarDirection'], json['tabBarDirection'],
), ),
tabIntentOpenSetting: $enumDecodeNullable( tabIntentOpenSetting: $enumDecodeNullable(
@@ -955,8 +955,8 @@ Map<String, dynamic> _$GeneralSettingsToJson(
'showIsolatedTabUi': instance.showIsolatedTabUi, 'showIsolatedTabUi': instance.showIsolatedTabUi,
'defaultCreateTabType': 'defaultCreateTabType':
_$TabTypeEnumMap[instance.storedDefaultCreateTabType]!, _$TabTypeEnumMap[instance.storedDefaultCreateTabType]!,
'tabListDirection': _$TabListDirectionEnumMap[instance.tabListDirection]!, 'tabListDirection': _$TabDirectionEnumMap[instance.tabListDirection]!,
'tabBarDirection': _$TabBarDirectionEnumMap[instance.tabBarDirection]!, 'tabBarDirection': _$TabDirectionEnumMap[instance.tabBarDirection]!,
'tabIntentOpenSetting': 'tabIntentOpenSetting':
_$TabIntentOpenSettingEnumMap[instance.tabIntentOpenSetting]!, _$TabIntentOpenSettingEnumMap[instance.tabIntentOpenSetting]!,
'autoHideTabBar': instance.autoHideTabBar, 'autoHideTabBar': instance.autoHideTabBar,
@@ -1031,14 +1031,9 @@ const _$TabTypeEnumMap = {
TabType.isolated: 'isolated', TabType.isolated: 'isolated',
}; };
const _$TabListDirectionEnumMap = { const _$TabDirectionEnumMap = {
TabListDirection.newestFirst: 'newestFirst', TabDirection.newestFirst: 'newestFirst',
TabListDirection.oldestFirst: 'oldestFirst', TabDirection.oldestFirst: 'oldestFirst',
};
const _$TabBarDirectionEnumMap = {
TabBarDirection.newestFirst: 'newestFirst',
TabBarDirection.oldestFirst: 'oldestFirst',
}; };
const _$TabIntentOpenSettingEnumMap = { const _$TabIntentOpenSettingEnumMap = {