add more tab type options for long press
This commit is contained in:
+90
-33
@@ -22,6 +22,8 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.dart
|
|||||||
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
import 'package:flutter_mozilla_components/flutter_mozilla_components.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:weblibre/core/design/app_colors.dart';
|
||||||
|
import 'package:weblibre/core/routing/routes.dart';
|
||||||
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
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/contextmenu/extensions/hit_result.dart';
|
import 'package:weblibre/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
@@ -38,44 +40,99 @@ class OpenInNewTab extends HookConsumerWidget {
|
|||||||
return hitResult.isHttpLink();
|
return hitResult.isHttpLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> _openInNewTab(
|
||||||
|
BuildContext context,
|
||||||
|
WidgetRef ref,
|
||||||
|
TabMode tabMode,
|
||||||
|
) async {
|
||||||
|
final currentTab = ref.read(selectedTabStateProvider);
|
||||||
|
|
||||||
|
final tabId = await ref
|
||||||
|
.read(tabRepositoryProvider.notifier)
|
||||||
|
.addTab(
|
||||||
|
url: hitResult.tryGetLink(),
|
||||||
|
parentId: currentTab?.id,
|
||||||
|
selectTab: false,
|
||||||
|
tabMode: tabMode,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (context.mounted) {
|
||||||
|
//save reference before pop `ref` gets disposed
|
||||||
|
final repo = ref.read(tabRepositoryProvider.notifier);
|
||||||
|
|
||||||
|
showTabSwitchMessage(
|
||||||
|
context,
|
||||||
|
onSwitch: () async {
|
||||||
|
await repo.selectTab(tabId);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
context.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final settings = ref.watch(generalSettingsWithDefaultsProvider);
|
||||||
|
final currentTab = ref.watch(selectedTabStateProvider);
|
||||||
|
|
||||||
|
final currentTabMode =
|
||||||
|
currentTab?.tabMode ??
|
||||||
|
TabMode.fromTabType(settings.effectiveDefaultCreateTabType);
|
||||||
|
|
||||||
|
// Alternative tab types the user can explicitly choose, excluding the type
|
||||||
|
// that the main tile action already opens (the current tab's type).
|
||||||
|
final alternativeTypes =
|
||||||
|
<TabType>[
|
||||||
|
TabType.regular,
|
||||||
|
TabType.private,
|
||||||
|
if (settings.showIsolatedTabUi) TabType.isolated,
|
||||||
|
]..remove(currentTabMode.toTabType());
|
||||||
|
|
||||||
return ListTile(
|
return ListTile(
|
||||||
leading: const Icon(MdiIcons.tabPlus),
|
leading: const Icon(MdiIcons.tabPlus),
|
||||||
title: const Text('Open in new tab'),
|
title: const Text('Open in new tab'),
|
||||||
onTap: () async {
|
trailing: alternativeTypes.isEmpty
|
||||||
final currentTab = ref.read(selectedTabStateProvider);
|
? null
|
||||||
final tabMode =
|
: MenuAnchor(
|
||||||
currentTab?.tabMode ??
|
menuChildren: [
|
||||||
TabMode.fromTabType(
|
for (final type in alternativeTypes)
|
||||||
ref
|
MenuItemButton(
|
||||||
.read(generalSettingsWithDefaultsProvider)
|
onPressed: () =>
|
||||||
.effectiveDefaultCreateTabType,
|
_openInNewTab(context, ref, TabMode.fromTabType(type)),
|
||||||
);
|
leadingIcon: Icon(
|
||||||
|
_iconFor(type),
|
||||||
final tabId = await ref
|
color: _colorFor(context, type),
|
||||||
.read(tabRepositoryProvider.notifier)
|
),
|
||||||
.addTab(
|
child: Text(_labelFor(type)),
|
||||||
url: hitResult.tryGetLink(),
|
),
|
||||||
parentId: currentTab?.id,
|
],
|
||||||
selectTab: false,
|
builder: (context, controller, child) => IconButton(
|
||||||
tabMode: tabMode,
|
icon: const Icon(Icons.expand_more),
|
||||||
);
|
tooltip: 'Open in a different tab type',
|
||||||
|
onPressed: () =>
|
||||||
if (context.mounted) {
|
controller.isOpen ? controller.close() : controller.open(),
|
||||||
//save reference before pop `ref` gets disposed
|
),
|
||||||
final repo = ref.read(tabRepositoryProvider.notifier);
|
),
|
||||||
|
onTap: () => _openInNewTab(context, ref, currentTabMode),
|
||||||
showTabSwitchMessage(
|
|
||||||
context,
|
|
||||||
onSwitch: () async {
|
|
||||||
await repo.selectTab(tabId);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
context.pop();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IconData _iconFor(TabType type) => switch (type) {
|
||||||
|
TabType.private => MdiIcons.dominoMask,
|
||||||
|
TabType.isolated => MdiIcons.snowflake,
|
||||||
|
_ => MdiIcons.tab,
|
||||||
|
};
|
||||||
|
|
||||||
|
Color? _colorFor(BuildContext context, TabType type) => switch (type) {
|
||||||
|
TabType.private => AppColors.of(context).privateTabPurple,
|
||||||
|
TabType.isolated => AppColors.of(context).isolatedTabTeal,
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
|
|
||||||
|
String _labelFor(TabType type) => switch (type) {
|
||||||
|
TabType.private => 'New private tab',
|
||||||
|
TabType.isolated => 'New isolated tab',
|
||||||
|
_ => 'New regular tab',
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user