option to open tab view in fullscreen
This commit is contained in:
@@ -27,10 +27,12 @@ import 'package:graphview/GraphView.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:nullability/nullability.dart';
|
||||
import 'package:skeletonizer/skeletonizer.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_preview.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart';
|
||||
import 'package:weblibre/features/user/domain/repositories/general_settings.dart';
|
||||
import 'package:weblibre/utils/ui_helper.dart';
|
||||
|
||||
class TabTreeDialog extends HookConsumerWidget {
|
||||
@@ -131,10 +133,17 @@ class TabTreeDialog extends HookConsumerWidget {
|
||||
tabId: id,
|
||||
activeTabId: selectedTabId,
|
||||
onClose: () {
|
||||
context.pop();
|
||||
ref
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.requestDismiss();
|
||||
final tabViewBottomSheet = ref
|
||||
.read(generalSettingsWithDefaultsProvider)
|
||||
.tabViewBottomSheet;
|
||||
|
||||
if (tabViewBottomSheet) {
|
||||
ref
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.requestDismiss();
|
||||
}
|
||||
|
||||
BrowserRoute().go(context);
|
||||
},
|
||||
sourceSearchQuery: null,
|
||||
),
|
||||
|
||||
@@ -43,7 +43,7 @@ import 'package:weblibre/features/geckoview/features/browser/presentation/contro
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/bottom_app_bar.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/browser_view.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/sheets/view_tab.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/sheets/view_tabs.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/view_tabs.dart';
|
||||
import 'package:weblibre/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||
import 'package:weblibre/features/geckoview/features/find_in_page/presentation/widgets/find_in_page.dart';
|
||||
import 'package:weblibre/features/geckoview/features/readerview/presentation/controllers/readerable.dart';
|
||||
@@ -572,7 +572,17 @@ class _ViewUrlSheet extends HookConsumerWidget {
|
||||
sheetScrollController: scrollController,
|
||||
draggableScrollableController: draggableScrollableController,
|
||||
onClose: () {
|
||||
ref.read(bottomSheetControllerProvider.notifier).requestDismiss();
|
||||
final tabViewBottomSheet = ref
|
||||
.read(generalSettingsWithDefaultsProvider)
|
||||
.tabViewBottomSheet;
|
||||
|
||||
if (tabViewBottomSheet) {
|
||||
ref
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.requestDismiss();
|
||||
} else {
|
||||
BrowserRoute().go(context);
|
||||
}
|
||||
},
|
||||
initialHeight: initialHeight,
|
||||
),
|
||||
@@ -605,16 +615,18 @@ class _ViewTabsSheet extends HookConsumerWidget {
|
||||
topRight: Radius.circular(28),
|
||||
),
|
||||
child: treeModeEnabled
|
||||
? ViewTabTreesSheetWidget(
|
||||
sheetScrollController: scrollController,
|
||||
? ViewTabTreesWidget(
|
||||
scrollController: scrollController,
|
||||
showNewTabFab: true,
|
||||
onClose: () {
|
||||
ref
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.requestDismiss();
|
||||
},
|
||||
)
|
||||
: ViewTabsSheetWidget(
|
||||
sheetScrollController: scrollController,
|
||||
: ViewTabsWidget(
|
||||
scrollController: scrollController,
|
||||
showNewTabFab: true,
|
||||
draggableScrollableController: draggableScrollableController,
|
||||
onClose: () {
|
||||
ref
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/providers/tab_state.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/controllers/tree_view.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/view_tabs.dart';
|
||||
import 'package:weblibre/features/user/domain/repositories/general_settings.dart';
|
||||
|
||||
class TabViewScreen extends HookConsumerWidget {
|
||||
const TabViewScreen();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final treeModeEnabled = ref.watch(treeViewControllerProvider);
|
||||
|
||||
final scrollController = useScrollController();
|
||||
|
||||
return Dialog.fullscreen(
|
||||
child: Scaffold(
|
||||
body: SafeArea(
|
||||
child: treeModeEnabled
|
||||
? ViewTabTreesWidget(
|
||||
scrollController: scrollController,
|
||||
showNewTabFab: false,
|
||||
onClose: () {
|
||||
BrowserRoute().go(context);
|
||||
},
|
||||
)
|
||||
: ViewTabsWidget(
|
||||
scrollController: scrollController,
|
||||
showNewTabFab: false,
|
||||
onClose: () {
|
||||
BrowserRoute().go(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () async {
|
||||
final settings = ref.read(generalSettingsWithDefaultsProvider);
|
||||
|
||||
await SearchRoute(
|
||||
tabType:
|
||||
ref.read(selectedTabTypeProvider) ??
|
||||
settings.defaultCreateTabType,
|
||||
).push(context);
|
||||
|
||||
if (context.mounted) {
|
||||
BrowserRoute().go(context);
|
||||
}
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
+16
-8
@@ -158,15 +158,23 @@ class BrowserBottomAppBar extends HookConsumerWidget {
|
||||
selectedTabId: selectedTabId,
|
||||
child: TabsActionButton(
|
||||
isActive: displayedSheet is ViewTabsSheet,
|
||||
onTap: () {
|
||||
if (displayedSheet case ViewTabsSheet()) {
|
||||
ref
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.requestDismiss();
|
||||
onTap: () async {
|
||||
final tabViewBottomSheet = ref
|
||||
.read(generalSettingsWithDefaultsProvider)
|
||||
.tabViewBottomSheet;
|
||||
|
||||
if (tabViewBottomSheet) {
|
||||
if (displayedSheet case ViewTabsSheet()) {
|
||||
ref
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.requestDismiss();
|
||||
} else {
|
||||
ref
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.show(ViewTabsSheet());
|
||||
}
|
||||
} else {
|
||||
ref
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.show(ViewTabsSheet());
|
||||
await TabViewRoute().push(context);
|
||||
}
|
||||
},
|
||||
onLongPress: () {
|
||||
|
||||
+73
-61
@@ -27,6 +27,7 @@ import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||
import 'package:flutter_reorderable_grid_view/widgets/widgets.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:nullability/nullability.dart';
|
||||
import 'package:weblibre/core/providers/global_drop.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
import 'package:weblibre/data/models/drag_data.dart';
|
||||
@@ -160,13 +161,13 @@ class _TabDraggable extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _TabSheetHeader extends HookConsumerWidget {
|
||||
class _TabViewHeader extends HookConsumerWidget {
|
||||
static const headerSize = 124.0;
|
||||
|
||||
final bool treeViewEnabled;
|
||||
final VoidCallback onClose;
|
||||
|
||||
const _TabSheetHeader({required this.onClose, required this.treeViewEnabled});
|
||||
const _TabViewHeader({required this.onClose, required this.treeViewEnabled});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
@@ -366,15 +367,17 @@ class _TabSheetHeader extends HookConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class ViewTabsSheetWidget extends HookConsumerWidget {
|
||||
final ScrollController sheetScrollController;
|
||||
final DraggableScrollableController draggableScrollableController;
|
||||
class ViewTabsWidget extends HookConsumerWidget {
|
||||
final ScrollController scrollController;
|
||||
final DraggableScrollableController? draggableScrollableController;
|
||||
final VoidCallback onClose;
|
||||
final bool showNewTabFab;
|
||||
|
||||
const ViewTabsSheetWidget({
|
||||
const ViewTabsWidget({
|
||||
required this.onClose,
|
||||
required this.sheetScrollController,
|
||||
required this.draggableScrollableController,
|
||||
required this.scrollController,
|
||||
this.draggableScrollableController,
|
||||
required this.showNewTabFab,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -387,13 +390,18 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
headerSliverBuilder: (context, innerBoxIsScrolled) => [
|
||||
SliverToBoxAdapter(
|
||||
child: DraggableScrollableHeader(
|
||||
controller: draggableScrollableController,
|
||||
child: _TabSheetHeader(
|
||||
onClose: onClose,
|
||||
treeViewEnabled: false,
|
||||
),
|
||||
),
|
||||
child:
|
||||
draggableScrollableController.mapNotNull(
|
||||
(draggableScrollableController) =>
|
||||
DraggableScrollableHeader(
|
||||
controller: draggableScrollableController,
|
||||
child: _TabViewHeader(
|
||||
onClose: onClose,
|
||||
treeViewEnabled: false,
|
||||
),
|
||||
),
|
||||
) ??
|
||||
_TabViewHeader(onClose: onClose, treeViewEnabled: false),
|
||||
),
|
||||
],
|
||||
body: HookConsumer(
|
||||
@@ -455,7 +463,7 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
||||
|
||||
useEffect(() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
if (sheetScrollController.hasClients) {
|
||||
if (scrollController.hasClients) {
|
||||
if (lastScroll.value != activeTab) {
|
||||
final index = filteredTabEntities.value.indexWhere(
|
||||
(entity) => entity.tabId == activeTab,
|
||||
@@ -464,11 +472,11 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
||||
if (index > -1) {
|
||||
final offset = (index ~/ 2) * itemHeight;
|
||||
|
||||
if (offset != sheetScrollController.offset) {
|
||||
if (offset != scrollController.offset) {
|
||||
lastScroll.value = activeTab;
|
||||
|
||||
unawaited(
|
||||
sheetScrollController.animateTo(
|
||||
scrollController.animateTo(
|
||||
offset,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeInOut,
|
||||
@@ -487,7 +495,7 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
child: FadingScroll(
|
||||
fadingSize: 5,
|
||||
controller: sheetScrollController,
|
||||
controller: scrollController,
|
||||
builder: (context, controller) {
|
||||
return ReorderableBuilder.builder(
|
||||
//Rebuild when cross axis count changes
|
||||
@@ -601,38 +609,41 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
||||
},
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: _TabSheetHeader.headerSize + 4,
|
||||
right: 4,
|
||||
),
|
||||
child: FloatingActionButton.small(
|
||||
onPressed: () async {
|
||||
final settings = ref.read(generalSettingsWithDefaultsProvider);
|
||||
if (showNewTabFab)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: _TabViewHeader.headerSize + 4,
|
||||
right: 4,
|
||||
),
|
||||
child: FloatingActionButton.small(
|
||||
onPressed: () async {
|
||||
final settings = ref.read(generalSettingsWithDefaultsProvider);
|
||||
|
||||
await SearchRoute(
|
||||
tabType:
|
||||
ref.read(selectedTabTypeProvider) ??
|
||||
settings.defaultCreateTabType,
|
||||
).push(context);
|
||||
await SearchRoute(
|
||||
tabType:
|
||||
ref.read(selectedTabTypeProvider) ??
|
||||
settings.defaultCreateTabType,
|
||||
).push(context);
|
||||
|
||||
onClose();
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
onClose();
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ViewTabTreesSheetWidget extends HookConsumerWidget {
|
||||
final ScrollController sheetScrollController;
|
||||
class ViewTabTreesWidget extends HookConsumerWidget {
|
||||
final ScrollController scrollController;
|
||||
final VoidCallback onClose;
|
||||
final bool showNewTabFab;
|
||||
|
||||
const ViewTabTreesSheetWidget({
|
||||
const ViewTabTreesWidget({
|
||||
required this.onClose,
|
||||
required this.sheetScrollController,
|
||||
required this.scrollController,
|
||||
required this.showNewTabFab,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@@ -643,7 +654,7 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
_TabSheetHeader(onClose: onClose, treeViewEnabled: true),
|
||||
_TabViewHeader(onClose: onClose, treeViewEnabled: true),
|
||||
Expanded(
|
||||
child: HookConsumer(
|
||||
builder: (context, ref, child) {
|
||||
@@ -697,9 +708,9 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
|
||||
if (index > -1) {
|
||||
final offset = (index ~/ 2) * itemHeight;
|
||||
|
||||
if (offset != sheetScrollController.offset) {
|
||||
if (offset != scrollController.offset) {
|
||||
unawaited(
|
||||
sheetScrollController.animateTo(
|
||||
scrollController.animateTo(
|
||||
offset,
|
||||
duration: const Duration(milliseconds: 200),
|
||||
curve: Curves.easeInOut,
|
||||
@@ -728,7 +739,7 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
child: GridView.builder(
|
||||
controller: sheetScrollController,
|
||||
controller: scrollController,
|
||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||
//Sync values for itemHeight calculation _calculateItemHeight
|
||||
childAspectRatio: 0.75,
|
||||
@@ -745,26 +756,27 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: _TabSheetHeader.headerSize + 4,
|
||||
right: 4,
|
||||
),
|
||||
child: FloatingActionButton.small(
|
||||
onPressed: () async {
|
||||
final settings = ref.read(generalSettingsWithDefaultsProvider);
|
||||
if (showNewTabFab)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(
|
||||
top: _TabViewHeader.headerSize + 4,
|
||||
right: 4,
|
||||
),
|
||||
child: FloatingActionButton.small(
|
||||
onPressed: () async {
|
||||
final settings = ref.read(generalSettingsWithDefaultsProvider);
|
||||
|
||||
await SearchRoute(
|
||||
tabType:
|
||||
ref.read(selectedTabTypeProvider) ??
|
||||
settings.defaultCreateTabType,
|
||||
).push(context);
|
||||
await SearchRoute(
|
||||
tabType:
|
||||
ref.read(selectedTabTypeProvider) ??
|
||||
settings.defaultCreateTabType,
|
||||
).push(context);
|
||||
|
||||
onClose();
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
onClose();
|
||||
},
|
||||
child: const Icon(Icons.add),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -20,7 +20,6 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
import 'package:weblibre/features/bangs/data/models/bang_data.dart';
|
||||
@@ -120,7 +119,7 @@ class SearchScreen extends HookConsumerWidget {
|
||||
if (context.mounted) {
|
||||
ref.read(bottomSheetControllerProvider.notifier).requestDismiss();
|
||||
|
||||
context.pop();
|
||||
BrowserRoute().go(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -226,7 +225,7 @@ class SearchScreen extends HookConsumerWidget {
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.requestDismiss();
|
||||
|
||||
context.pop();
|
||||
BrowserRoute().go(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -21,11 +21,11 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:nullability/nullability.dart';
|
||||
import 'package:skeletonizer/skeletonizer.dart';
|
||||
import 'package:sliver_tools/sliver_tools.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||
import 'package:weblibre/features/geckoview/features/search/domain/providers/engine_suggestions.dart';
|
||||
@@ -129,7 +129,7 @@ class HistorySuggestions extends HookConsumerWidget {
|
||||
)
|
||||
.requestDismiss();
|
||||
|
||||
context.pop();
|
||||
BrowserRoute().go(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -21,10 +21,10 @@ import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:nullability/nullability.dart';
|
||||
import 'package:sliver_tools/sliver_tools.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/controllers/bottom_sheet.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/domain/providers.dart';
|
||||
@@ -175,7 +175,7 @@ class TabSearch extends HookConsumerWidget {
|
||||
.read(bottomSheetControllerProvider.notifier)
|
||||
.requestDismiss();
|
||||
|
||||
context.pop();
|
||||
BrowserRoute().go(context);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ import 'package:skeletonizer/skeletonizer.dart';
|
||||
import 'package:weblibre/core/logger.dart';
|
||||
import 'package:weblibre/core/routing/routes.dart';
|
||||
import 'package:weblibre/core/uuid.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/sheets/view_tabs.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/view_tabs.dart';
|
||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/tab_preview.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/data/models/container_data.dart';
|
||||
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/container.dart';
|
||||
|
||||
Reference in New Issue
Block a user