quick tab switcher depth
This commit is contained in:
+80
-37
@@ -46,12 +46,15 @@ import 'package:weblibre/features/geckoview/features/browser/presentation/widget
|
|||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_icon.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_icon.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_menu.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_menu.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/tab_context_menu_draggable.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/tab_context_menu_draggable.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/tab_depth_indicator.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/tab_view_item.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/tab_view_item.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/toolbar_button.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/toolbar_button.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/readerview/presentation/controllers/readerable.dart';
|
import 'package:weblibre/features/geckoview/features/readerview/presentation/controllers/readerable.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/readerview/presentation/widgets/reader_button.dart';
|
import 'package:weblibre/features/geckoview/features/readerview/presentation/widgets/reader_button.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_entity.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/tabs/domain/providers/selected_container.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/tabs/utils/container_colors.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/utils/container_colors.dart';
|
||||||
import 'package:weblibre/features/user/data/models/general_settings.dart';
|
import 'package:weblibre/features/user/data/models/general_settings.dart';
|
||||||
@@ -460,6 +463,7 @@ class QuickTabSwitcherItem with FastEquatable {
|
|||||||
final bool isHistory;
|
final bool isHistory;
|
||||||
final bool isPinned;
|
final bool isPinned;
|
||||||
final bool isSandbox;
|
final bool isSandbox;
|
||||||
|
final int depth;
|
||||||
final String title;
|
final String title;
|
||||||
final Uri url;
|
final Uri url;
|
||||||
final Widget avatar;
|
final Widget avatar;
|
||||||
@@ -475,6 +479,7 @@ class QuickTabSwitcherItem with FastEquatable {
|
|||||||
required this.url,
|
required this.url,
|
||||||
required this.avatar,
|
required this.avatar,
|
||||||
this.isSandbox = false,
|
this.isSandbox = false,
|
||||||
|
this.depth = 0,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -486,6 +491,7 @@ class QuickTabSwitcherItem with FastEquatable {
|
|||||||
isHistory,
|
isHistory,
|
||||||
isPinned,
|
isPinned,
|
||||||
isSandbox,
|
isSandbox,
|
||||||
|
depth,
|
||||||
title,
|
title,
|
||||||
url,
|
url,
|
||||||
avatar,
|
avatar,
|
||||||
@@ -531,14 +537,36 @@ class QuickTabSwitcher extends HookConsumerWidget {
|
|||||||
final sortPinnedFirst = ref.watch(
|
final sortPinnedFirst = ref.watch(
|
||||||
tabViewFilterControllerProvider.select((v) => v.sortPinnedFirst),
|
tabViewFilterControllerProvider.select((v) => v.sortPinnedFirst),
|
||||||
);
|
);
|
||||||
|
final showHierarchicalTabs = ref.watch(
|
||||||
|
tabViewFilterControllerProvider.select((v) => v.showHierarchicalTabs),
|
||||||
|
);
|
||||||
|
final selectedContainerId = ref.watch(selectedContainerProvider);
|
||||||
|
final hierarchyContainerId =
|
||||||
|
effectiveMode == QuickTabSwitcherMode.containerTabs
|
||||||
|
? selectedContainerId
|
||||||
|
: null;
|
||||||
|
|
||||||
|
final tabDepthById = ref
|
||||||
|
.watch(
|
||||||
|
groupedTabListItemsProvider(containerId: hierarchyContainerId).select(
|
||||||
|
(value) {
|
||||||
|
return EquatableValue(<String, int>{
|
||||||
|
if (showHierarchicalTabs)
|
||||||
|
for (final item in value.value)
|
||||||
|
if (item is TabListChildItem) item.tabId: item.depth,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
.value;
|
||||||
|
|
||||||
final pinnedTabIds = ref.watch(
|
final pinnedTabIds = ref.watch(
|
||||||
watchPinnedTabIdsProvider.select(
|
watchPinnedTabIdsProvider.select(
|
||||||
(value) => value.value ?? const <String>{},
|
(value) => value.value ?? const <String>{},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
final reorderEnabled =
|
final reorderEnabled =
|
||||||
effectiveMode == QuickTabSwitcherMode.containerTabs &&
|
effectiveMode == QuickTabSwitcherMode.containerTabs && canManualReorder;
|
||||||
canManualReorder;
|
|
||||||
final tabItems = tabStates.value.map<QuickTabSwitcherItem>((state) {
|
final tabItems = tabStates.value.map<QuickTabSwitcherItem>((state) {
|
||||||
final sandboxSourceUri = parseSandboxSource(
|
final sandboxSourceUri = parseSandboxSource(
|
||||||
sandboxCaptureMap[state.$1.id],
|
sandboxCaptureMap[state.$1.id],
|
||||||
@@ -556,26 +584,27 @@ class QuickTabSwitcher extends HookConsumerWidget {
|
|||||||
isHistory: false,
|
isHistory: false,
|
||||||
isPinned: pinnedTabIds.contains(state.$1.id),
|
isPinned: pinnedTabIds.contains(state.$1.id),
|
||||||
isSandbox: sandboxSourceUri != null,
|
isSandbox: sandboxSourceUri != null,
|
||||||
|
depth: tabDepthById[state.$1.id] ?? 0,
|
||||||
url: displayUrl,
|
url: displayUrl,
|
||||||
avatar: TabIcon(tabState: state.$1, iconSize: 20),
|
avatar: TabIcon(tabState: state.$1, iconSize: 20),
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
final historyItems = (historySuggestions ?? [])
|
final historyItems = (historySuggestions ?? []).map<QuickTabSwitcherItem>((
|
||||||
.map<QuickTabSwitcherItem>((state) {
|
state,
|
||||||
final url = Uri.parse(state.url);
|
) {
|
||||||
return QuickTabSwitcherItem(
|
final url = Uri.parse(state.url);
|
||||||
color: null,
|
return QuickTabSwitcherItem(
|
||||||
id: state.url,
|
color: null,
|
||||||
isActive: false,
|
id: state.url,
|
||||||
title: state.title ?? url.authority,
|
isActive: false,
|
||||||
tabMode: TabMode.regular,
|
title: state.title ?? url.authority,
|
||||||
isHistory: true,
|
tabMode: TabMode.regular,
|
||||||
isPinned: false,
|
isHistory: true,
|
||||||
url: url,
|
isPinned: false,
|
||||||
avatar: UrlIcon([url], iconSize: 20),
|
url: url,
|
||||||
);
|
avatar: UrlIcon([url], iconSize: 20),
|
||||||
})
|
);
|
||||||
.toList();
|
}).toList();
|
||||||
final availableItems = [...tabItems, ...historyItems];
|
final availableItems = [...tabItems, ...historyItems];
|
||||||
|
|
||||||
final activeItem = availableItems.isEmpty
|
final activeItem = availableItems.isEmpty
|
||||||
@@ -666,8 +695,7 @@ class QuickTabSwitcher extends HookConsumerWidget {
|
|||||||
activeItemKey: activeItemKey.value,
|
activeItemKey: activeItemKey.value,
|
||||||
showTitles: showTitles,
|
showTitles: showTitles,
|
||||||
showIsolatedTabUi: showIsolatedTabUi,
|
showIsolatedTabUi: showIsolatedTabUi,
|
||||||
enablePinTabInMenu:
|
enablePinTabInMenu: effectiveMode == QuickTabSwitcherMode.containerTabs,
|
||||||
effectiveMode == QuickTabSwitcherMode.containerTabs,
|
|
||||||
onSelected: (item) async {
|
onSelected: (item) async {
|
||||||
if (!item.isHistory && item.isActive) {
|
if (!item.isHistory && item.isActive) {
|
||||||
return;
|
return;
|
||||||
@@ -687,8 +715,7 @@ class QuickTabSwitcher extends HookConsumerWidget {
|
|||||||
onReorderItem: !reorderEnabled
|
onReorderItem: !reorderEnabled
|
||||||
? null
|
? null
|
||||||
: (oldIndex, newIndex) async {
|
: (oldIndex, newIndex) async {
|
||||||
if (oldIndex >= tabItems.length ||
|
if (oldIndex >= tabItems.length || newIndex > tabItems.length) {
|
||||||
newIndex > tabItems.length) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final visibleItems = [
|
final visibleItems = [
|
||||||
@@ -762,8 +789,7 @@ class QuickTabSwitcherView extends StatelessWidget {
|
|||||||
/// or after are appended as a static trailing row (e.g. history hints).
|
/// or after are appended as a static trailing row (e.g. history hints).
|
||||||
final int reorderableItemCount;
|
final int reorderableItemCount;
|
||||||
|
|
||||||
bool get _reorderEnabled =>
|
bool get _reorderEnabled => onReorderItem != null && reorderableItemCount > 0;
|
||||||
onReorderItem != null && reorderableItemCount > 0;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -795,13 +821,10 @@ class QuickTabSwitcherView extends StatelessWidget {
|
|||||||
selectedItem: activeItem,
|
selectedItem: activeItem,
|
||||||
selectedBorderColor: Theme.of(context).colorScheme.primary,
|
selectedBorderColor: Theme.of(context).colorScheme.primary,
|
||||||
decoration: _chipDecoration(context),
|
decoration: _chipDecoration(context),
|
||||||
itemLabel: (item) =>
|
itemLabel: (item) => _chipLabel(context, item, activeItem?.id == item.id),
|
||||||
_chipLabel(context, item, activeItem?.id == item.id),
|
|
||||||
itemAvatar: (item) => item.avatar,
|
|
||||||
onSelected: onSelected,
|
onSelected: onSelected,
|
||||||
itemWrap: (child, item) => item.isHistory
|
itemWrap: (child, item) =>
|
||||||
? child
|
item.isHistory ? child : _wrapWithMenu(itemId: item.id, child: child),
|
||||||
: _wrapWithMenu(itemId: item.id, child: child),
|
|
||||||
availableItems: availableItems,
|
availableItems: availableItems,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -884,14 +907,18 @@ class QuickTabSwitcherView extends StatelessWidget {
|
|||||||
) {
|
) {
|
||||||
return SelectableChipDecoration(
|
return SelectableChipDecoration(
|
||||||
color: (item, isSelected) => switch (item.color) {
|
color: (item, isSelected) => switch (item.color) {
|
||||||
final color? when isSelected =>
|
final color? when isSelected => ContainerColors.palette(
|
||||||
ContainerColors.palette(context, color).selectedBackgroundColor,
|
context,
|
||||||
|
color,
|
||||||
|
).selectedBackgroundColor,
|
||||||
final color? => ContainerColors.palette(context, color).backgroundColor,
|
final color? => ContainerColors.palette(context, color).backgroundColor,
|
||||||
null => null,
|
null => null,
|
||||||
},
|
},
|
||||||
side: (item, isSelected) => switch (item.color) {
|
side: (item, isSelected) => switch (item.color) {
|
||||||
final color? when isSelected =>
|
final color? when isSelected => ContainerColors.palette(
|
||||||
ContainerColors.palette(context, color).selectedBorderSide,
|
context,
|
||||||
|
color,
|
||||||
|
).selectedBorderSide,
|
||||||
final color? => ContainerColors.palette(context, color).borderSide,
|
final color? => ContainerColors.palette(context, color).borderSide,
|
||||||
null => null,
|
null => null,
|
||||||
},
|
},
|
||||||
@@ -900,6 +927,7 @@ class QuickTabSwitcherView extends StatelessWidget {
|
|||||||
!item.isHistory &&
|
!item.isHistory &&
|
||||||
!item.isPinned &&
|
!item.isPinned &&
|
||||||
!item.isSandbox &&
|
!item.isSandbox &&
|
||||||
|
item.depth == 0 &&
|
||||||
item.tabMode is! PrivateTabMode &&
|
item.tabMode is! PrivateTabMode &&
|
||||||
item.tabMode is! IsolatedTabMode)
|
item.tabMode is! IsolatedTabMode)
|
||||||
? EdgeInsets.zero
|
? EdgeInsets.zero
|
||||||
@@ -913,10 +941,25 @@ class QuickTabSwitcherView extends StatelessWidget {
|
|||||||
bool isSelected,
|
bool isSelected,
|
||||||
) {
|
) {
|
||||||
final appColors = AppColors.of(context);
|
final appColors = AppColors.of(context);
|
||||||
|
final hasTitle = item.isHistory || showTitles;
|
||||||
final row = Row(
|
final row = Row(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (item.isHistory || showTitles)
|
if (item.depth > 0)
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.only(right: 6.0),
|
||||||
|
child: TabDepthIndicator(
|
||||||
|
depth: item.depth,
|
||||||
|
height: 24.0,
|
||||||
|
iconSize: 14.0,
|
||||||
|
horizontalPadding: 4.0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(right: hasTitle ? 6.0 : 0.0),
|
||||||
|
child: item.avatar,
|
||||||
|
),
|
||||||
|
if (hasTitle)
|
||||||
ConstrainedBox(
|
ConstrainedBox(
|
||||||
constraints: const BoxConstraints(maxWidth: 64),
|
constraints: const BoxConstraints(maxWidth: 64),
|
||||||
child: Text(item.title),
|
child: Text(item.title),
|
||||||
@@ -1010,7 +1053,8 @@ class _ReorderableSwitcherChip extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final itemColor = decoration.color?.call(item, isSelected);
|
final itemColor = decoration.color?.call(item, isSelected);
|
||||||
final side = decoration.side?.call(item, isSelected) ??
|
final side =
|
||||||
|
decoration.side?.call(item, isSelected) ??
|
||||||
(isSelected
|
(isSelected
|
||||||
? BorderSide(color: selectedBorderColor, width: 2.0)
|
? BorderSide(color: selectedBorderColor, width: 2.0)
|
||||||
: null);
|
: null);
|
||||||
@@ -1027,7 +1071,6 @@ class _ReorderableSwitcherChip extends StatelessWidget {
|
|||||||
unawaited(onTap());
|
unawaited(onTap());
|
||||||
},
|
},
|
||||||
label: label,
|
label: label,
|
||||||
avatar: item.avatar,
|
|
||||||
side: side,
|
side: side,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024-2026 Fabian Freund.
|
||||||
|
*
|
||||||
|
* This file is part of WebLibre
|
||||||
|
* (see https://weblibre.eu).
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import 'dart:math' as math;
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||||
|
|
||||||
|
// Cap glyph count so the badge stays readable on deep trees.
|
||||||
|
const int _maxDepthGlyphs = 4;
|
||||||
|
|
||||||
|
class TabDepthIndicator extends StatelessWidget {
|
||||||
|
final int depth;
|
||||||
|
final double height;
|
||||||
|
final double iconSize;
|
||||||
|
final double horizontalPadding;
|
||||||
|
|
||||||
|
const TabDepthIndicator({
|
||||||
|
required this.depth,
|
||||||
|
this.height = 28.0,
|
||||||
|
this.iconSize = 16.0,
|
||||||
|
this.horizontalPadding = 6.0,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final scheme = Theme.of(context).colorScheme;
|
||||||
|
final glyphCount = math.min(depth, _maxDepthGlyphs);
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
height: height,
|
||||||
|
child: Material(
|
||||||
|
color: scheme.surfaceContainerHighest.withAlpha(200),
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(8.0)),
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: horizontalPadding),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
for (var i = 0; i < glyphCount; i++)
|
||||||
|
Icon(
|
||||||
|
MdiIcons.subdirectoryArrowRight,
|
||||||
|
size: iconSize,
|
||||||
|
color: scheme.onSurfaceVariant,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-40
@@ -30,6 +30,7 @@ import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
|||||||
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/utils/tab_close_confirmation.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/utils/tab_close_confirmation.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_icon.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_icon.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_view/tab_depth_indicator.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/find_in_page/domain/entities/find_in_page_state.dart';
|
import 'package:weblibre/features/geckoview/features/find_in_page/domain/entities/find_in_page_state.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart';
|
import 'package:weblibre/features/geckoview/features/find_in_page/presentation/controllers/find_in_page.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/data/entities/tab_mode.dart';
|
||||||
@@ -308,7 +309,7 @@ class GridTabPreview extends HookConsumerWidget {
|
|||||||
Positioned(
|
Positioned(
|
||||||
bottom: 6.0,
|
bottom: 6.0,
|
||||||
left: 6.0,
|
left: 6.0,
|
||||||
child: _GridDepthIndicator(depth: depth),
|
child: TabDepthIndicator(depth: depth),
|
||||||
),
|
),
|
||||||
if (trailingChild != null || isPinned || groupToggle != null)
|
if (trailingChild != null || isPinned || groupToggle != null)
|
||||||
Positioned(
|
Positioned(
|
||||||
@@ -700,45 +701,6 @@ class ListTabPreview extends HookConsumerWidget {
|
|||||||
const double _listIndentStep = 16.0;
|
const double _listIndentStep = 16.0;
|
||||||
const int _listMaxIndentLevels = 3;
|
const int _listMaxIndentLevels = 3;
|
||||||
|
|
||||||
// Cap glyph count so the badge stays readable on deep trees.
|
|
||||||
const int _gridMaxDepthGlyphs = 4;
|
|
||||||
|
|
||||||
class _GridDepthIndicator extends StatelessWidget {
|
|
||||||
final int depth;
|
|
||||||
const _GridDepthIndicator({required this.depth});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
final scheme = Theme.of(context).colorScheme;
|
|
||||||
final glyphCount = math.min(depth, _gridMaxDepthGlyphs);
|
|
||||||
|
|
||||||
// Same shell as the top-left toggle / top-right close button:
|
|
||||||
// 28px tall, surfaceContainerHighest with 200 alpha, 8px radius,
|
|
||||||
// onSurfaceVariant icons at 16px.
|
|
||||||
return SizedBox(
|
|
||||||
height: 28,
|
|
||||||
child: Material(
|
|
||||||
color: scheme.surfaceContainerHighest.withAlpha(200),
|
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(8.0)),
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 6),
|
|
||||||
child: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
for (var i = 0; i < glyphCount; i++)
|
|
||||||
Icon(
|
|
||||||
MdiIcons.subdirectoryArrowRight,
|
|
||||||
size: 16,
|
|
||||||
color: scheme.onSurfaceVariant,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class _IndentGuidePainter extends CustomPainter {
|
class _IndentGuidePainter extends CustomPainter {
|
||||||
final Color color;
|
final Color color;
|
||||||
final double stubInsetFromRight;
|
final double stubInsetFromRight;
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ class TabBarPreviewCard extends HookWidget {
|
|||||||
tabMode: TabMode.private,
|
tabMode: TabMode.private,
|
||||||
isHistory: false,
|
isHistory: false,
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
|
depth: 1,
|
||||||
url: Uri.parse('https://example.com/private'),
|
url: Uri.parse('https://example.com/private'),
|
||||||
color: null,
|
color: null,
|
||||||
avatar: const Icon(MdiIcons.web, size: 20),
|
avatar: const Icon(MdiIcons.web, size: 20),
|
||||||
@@ -159,6 +160,7 @@ class TabBarPreviewCard extends HookWidget {
|
|||||||
tabMode: TabMode.isolated('preview-isolated-context'),
|
tabMode: TabMode.isolated('preview-isolated-context'),
|
||||||
isHistory: false,
|
isHistory: false,
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
|
depth: 2,
|
||||||
url: Uri.parse('https://example.com/bank'),
|
url: Uri.parse('https://example.com/bank'),
|
||||||
color: null,
|
color: null,
|
||||||
avatar: const Icon(MdiIcons.web, size: 20),
|
avatar: const Icon(MdiIcons.web, size: 20),
|
||||||
|
|||||||
Reference in New Issue
Block a user