option to open tab view in fullscreen
This commit is contained in:
@@ -29,6 +29,7 @@ part of 'routes.dart';
|
|||||||
),
|
),
|
||||||
TypedGoRoute<TorProxyRoute>(name: 'TorProxyRoute', path: 'tor_proxy'),
|
TypedGoRoute<TorProxyRoute>(name: 'TorProxyRoute', path: 'tor_proxy'),
|
||||||
TypedGoRoute<HistoryRoute>(name: 'HistoryRoute', path: 'history'),
|
TypedGoRoute<HistoryRoute>(name: 'HistoryRoute', path: 'history'),
|
||||||
|
TypedGoRoute<TabViewRoute>(name: 'TabViewRoute', path: 'tab_view'),
|
||||||
TypedGoRoute<ContextMenuRoute>(
|
TypedGoRoute<ContextMenuRoute>(
|
||||||
name: 'ContextMenuRoute',
|
name: 'ContextMenuRoute',
|
||||||
path: 'context_menu',
|
path: 'context_menu',
|
||||||
@@ -201,3 +202,10 @@ class HistoryRoute extends GoRouteData with $HistoryRoute {
|
|||||||
return const HistoryScreen();
|
return const HistoryScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TabViewRoute extends GoRouteData with $TabViewRoute {
|
||||||
|
@override
|
||||||
|
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
||||||
|
return DialogPage(builder: (_) => const TabViewScreen());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import 'package:weblibre/features/bangs/presentation/screens/search.dart';
|
|||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/open_shared_content.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/open_shared_content.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/tab_tree.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/tab_tree.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/screens/browser.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/screens/browser.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/browser/presentation/screens/tab_view.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
import 'package:weblibre/features/geckoview/features/contextmenu/extensions/hit_result.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/contextmenu/presentation/context_menu_dialog.dart';
|
import 'package:weblibre/features/geckoview/features/contextmenu/presentation/context_menu_dialog.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/history/presentation/screens/history.dart';
|
import 'package:weblibre/features/geckoview/features/history/presentation/screens/history.dart';
|
||||||
|
|||||||
@@ -395,6 +395,11 @@ RouteBase get $browserRoute => GoRouteData.$route(
|
|||||||
name: 'HistoryRoute',
|
name: 'HistoryRoute',
|
||||||
factory: $HistoryRoute._fromState,
|
factory: $HistoryRoute._fromState,
|
||||||
),
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'tab_view',
|
||||||
|
name: 'TabViewRoute',
|
||||||
|
factory: $TabViewRoute._fromState,
|
||||||
|
),
|
||||||
GoRouteData.$route(
|
GoRouteData.$route(
|
||||||
path: 'context_menu',
|
path: 'context_menu',
|
||||||
name: 'ContextMenuRoute',
|
name: 'ContextMenuRoute',
|
||||||
@@ -545,6 +550,26 @@ mixin $HistoryRoute on GoRouteData {
|
|||||||
void replace(BuildContext context) => context.replace(location);
|
void replace(BuildContext context) => context.replace(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mixin $TabViewRoute on GoRouteData {
|
||||||
|
static TabViewRoute _fromState(GoRouterState state) => TabViewRoute();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get location => GoRouteData.$location('/tab_view');
|
||||||
|
|
||||||
|
@override
|
||||||
|
void go(BuildContext context) => context.go(location);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<T?> push<T>(BuildContext context) => context.push<T>(location);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void pushReplacement(BuildContext context) =>
|
||||||
|
context.pushReplacement(location);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void replace(BuildContext context) => context.replace(location);
|
||||||
|
}
|
||||||
|
|
||||||
mixin $ContextMenuRoute on GoRouteData {
|
mixin $ContextMenuRoute on GoRouteData {
|
||||||
static ContextMenuRoute _fromState(GoRouterState state) =>
|
static ContextMenuRoute _fromState(GoRouterState state) =>
|
||||||
ContextMenuRoute(state.extra as String);
|
ContextMenuRoute(state.extra as String);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ final class GenericWebsiteServiceProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$genericWebsiteServiceHash() =>
|
String _$genericWebsiteServiceHash() =>
|
||||||
r'9bc32261abd76a79efb57f6d27832e949cb495a6';
|
r'44d6e4cc161b1200070d99e29c1db04cd18ca091';
|
||||||
|
|
||||||
abstract class _$GenericWebsiteService extends $Notifier<void> {
|
abstract class _$GenericWebsiteService extends $Notifier<void> {
|
||||||
void build();
|
void build();
|
||||||
|
|||||||
@@ -27,10 +27,12 @@ import 'package:graphview/GraphView.dart';
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:nullability/nullability.dart';
|
import 'package:nullability/nullability.dart';
|
||||||
import 'package:skeletonizer/skeletonizer.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/controllers/bottom_sheet.dart';
|
||||||
import 'package:weblibre/features/geckoview/domain/providers/selected_tab.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/browser/presentation/widgets/tab_preview.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/user/domain/repositories/general_settings.dart';
|
||||||
import 'package:weblibre/utils/ui_helper.dart';
|
import 'package:weblibre/utils/ui_helper.dart';
|
||||||
|
|
||||||
class TabTreeDialog extends HookConsumerWidget {
|
class TabTreeDialog extends HookConsumerWidget {
|
||||||
@@ -131,10 +133,17 @@ class TabTreeDialog extends HookConsumerWidget {
|
|||||||
tabId: id,
|
tabId: id,
|
||||||
activeTabId: selectedTabId,
|
activeTabId: selectedTabId,
|
||||||
onClose: () {
|
onClose: () {
|
||||||
context.pop();
|
final tabViewBottomSheet = ref
|
||||||
ref
|
.read(generalSettingsWithDefaultsProvider)
|
||||||
.read(bottomSheetControllerProvider.notifier)
|
.tabViewBottomSheet;
|
||||||
.requestDismiss();
|
|
||||||
|
if (tabViewBottomSheet) {
|
||||||
|
ref
|
||||||
|
.read(bottomSheetControllerProvider.notifier)
|
||||||
|
.requestDismiss();
|
||||||
|
}
|
||||||
|
|
||||||
|
BrowserRoute().go(context);
|
||||||
},
|
},
|
||||||
sourceSearchQuery: null,
|
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/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/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_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/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/find_in_page/presentation/widgets/find_in_page.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/readerview/presentation/controllers/readerable.dart';
|
import 'package:weblibre/features/geckoview/features/readerview/presentation/controllers/readerable.dart';
|
||||||
@@ -572,7 +572,17 @@ class _ViewUrlSheet extends HookConsumerWidget {
|
|||||||
sheetScrollController: scrollController,
|
sheetScrollController: scrollController,
|
||||||
draggableScrollableController: draggableScrollableController,
|
draggableScrollableController: draggableScrollableController,
|
||||||
onClose: () {
|
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,
|
initialHeight: initialHeight,
|
||||||
),
|
),
|
||||||
@@ -605,16 +615,18 @@ class _ViewTabsSheet extends HookConsumerWidget {
|
|||||||
topRight: Radius.circular(28),
|
topRight: Radius.circular(28),
|
||||||
),
|
),
|
||||||
child: treeModeEnabled
|
child: treeModeEnabled
|
||||||
? ViewTabTreesSheetWidget(
|
? ViewTabTreesWidget(
|
||||||
sheetScrollController: scrollController,
|
scrollController: scrollController,
|
||||||
|
showNewTabFab: true,
|
||||||
onClose: () {
|
onClose: () {
|
||||||
ref
|
ref
|
||||||
.read(bottomSheetControllerProvider.notifier)
|
.read(bottomSheetControllerProvider.notifier)
|
||||||
.requestDismiss();
|
.requestDismiss();
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: ViewTabsSheetWidget(
|
: ViewTabsWidget(
|
||||||
sheetScrollController: scrollController,
|
scrollController: scrollController,
|
||||||
|
showNewTabFab: true,
|
||||||
draggableScrollableController: draggableScrollableController,
|
draggableScrollableController: draggableScrollableController,
|
||||||
onClose: () {
|
onClose: () {
|
||||||
ref
|
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,
|
selectedTabId: selectedTabId,
|
||||||
child: TabsActionButton(
|
child: TabsActionButton(
|
||||||
isActive: displayedSheet is ViewTabsSheet,
|
isActive: displayedSheet is ViewTabsSheet,
|
||||||
onTap: () {
|
onTap: () async {
|
||||||
if (displayedSheet case ViewTabsSheet()) {
|
final tabViewBottomSheet = ref
|
||||||
ref
|
.read(generalSettingsWithDefaultsProvider)
|
||||||
.read(bottomSheetControllerProvider.notifier)
|
.tabViewBottomSheet;
|
||||||
.requestDismiss();
|
|
||||||
|
if (tabViewBottomSheet) {
|
||||||
|
if (displayedSheet case ViewTabsSheet()) {
|
||||||
|
ref
|
||||||
|
.read(bottomSheetControllerProvider.notifier)
|
||||||
|
.requestDismiss();
|
||||||
|
} else {
|
||||||
|
ref
|
||||||
|
.read(bottomSheetControllerProvider.notifier)
|
||||||
|
.show(ViewTabsSheet());
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ref
|
await TabViewRoute().push(context);
|
||||||
.read(bottomSheetControllerProvider.notifier)
|
|
||||||
.show(ViewTabsSheet());
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onLongPress: () {
|
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_material_design_icons/flutter_material_design_icons.dart';
|
||||||
import 'package:flutter_reorderable_grid_view/widgets/widgets.dart';
|
import 'package:flutter_reorderable_grid_view/widgets/widgets.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.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/providers/global_drop.dart';
|
||||||
import 'package:weblibre/core/routing/routes.dart';
|
import 'package:weblibre/core/routing/routes.dart';
|
||||||
import 'package:weblibre/data/models/drag_data.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;
|
static const headerSize = 124.0;
|
||||||
|
|
||||||
final bool treeViewEnabled;
|
final bool treeViewEnabled;
|
||||||
final VoidCallback onClose;
|
final VoidCallback onClose;
|
||||||
|
|
||||||
const _TabSheetHeader({required this.onClose, required this.treeViewEnabled});
|
const _TabViewHeader({required this.onClose, required this.treeViewEnabled});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
@@ -366,15 +367,17 @@ class _TabSheetHeader extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewTabsSheetWidget extends HookConsumerWidget {
|
class ViewTabsWidget extends HookConsumerWidget {
|
||||||
final ScrollController sheetScrollController;
|
final ScrollController scrollController;
|
||||||
final DraggableScrollableController draggableScrollableController;
|
final DraggableScrollableController? draggableScrollableController;
|
||||||
final VoidCallback onClose;
|
final VoidCallback onClose;
|
||||||
|
final bool showNewTabFab;
|
||||||
|
|
||||||
const ViewTabsSheetWidget({
|
const ViewTabsWidget({
|
||||||
required this.onClose,
|
required this.onClose,
|
||||||
required this.sheetScrollController,
|
required this.scrollController,
|
||||||
required this.draggableScrollableController,
|
this.draggableScrollableController,
|
||||||
|
required this.showNewTabFab,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -387,13 +390,18 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
headerSliverBuilder: (context, innerBoxIsScrolled) => [
|
headerSliverBuilder: (context, innerBoxIsScrolled) => [
|
||||||
SliverToBoxAdapter(
|
SliverToBoxAdapter(
|
||||||
child: DraggableScrollableHeader(
|
child:
|
||||||
controller: draggableScrollableController,
|
draggableScrollableController.mapNotNull(
|
||||||
child: _TabSheetHeader(
|
(draggableScrollableController) =>
|
||||||
onClose: onClose,
|
DraggableScrollableHeader(
|
||||||
treeViewEnabled: false,
|
controller: draggableScrollableController,
|
||||||
),
|
child: _TabViewHeader(
|
||||||
),
|
onClose: onClose,
|
||||||
|
treeViewEnabled: false,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
) ??
|
||||||
|
_TabViewHeader(onClose: onClose, treeViewEnabled: false),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
body: HookConsumer(
|
body: HookConsumer(
|
||||||
@@ -455,7 +463,7 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
|
|
||||||
useEffect(() {
|
useEffect(() {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
if (sheetScrollController.hasClients) {
|
if (scrollController.hasClients) {
|
||||||
if (lastScroll.value != activeTab) {
|
if (lastScroll.value != activeTab) {
|
||||||
final index = filteredTabEntities.value.indexWhere(
|
final index = filteredTabEntities.value.indexWhere(
|
||||||
(entity) => entity.tabId == activeTab,
|
(entity) => entity.tabId == activeTab,
|
||||||
@@ -464,11 +472,11 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
final offset = (index ~/ 2) * itemHeight;
|
final offset = (index ~/ 2) * itemHeight;
|
||||||
|
|
||||||
if (offset != sheetScrollController.offset) {
|
if (offset != scrollController.offset) {
|
||||||
lastScroll.value = activeTab;
|
lastScroll.value = activeTab;
|
||||||
|
|
||||||
unawaited(
|
unawaited(
|
||||||
sheetScrollController.animateTo(
|
scrollController.animateTo(
|
||||||
offset,
|
offset,
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(milliseconds: 200),
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
@@ -487,7 +495,7 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
child: FadingScroll(
|
child: FadingScroll(
|
||||||
fadingSize: 5,
|
fadingSize: 5,
|
||||||
controller: sheetScrollController,
|
controller: scrollController,
|
||||||
builder: (context, controller) {
|
builder: (context, controller) {
|
||||||
return ReorderableBuilder.builder(
|
return ReorderableBuilder.builder(
|
||||||
//Rebuild when cross axis count changes
|
//Rebuild when cross axis count changes
|
||||||
@@ -601,38 +609,41 @@ class ViewTabsSheetWidget extends HookConsumerWidget {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Padding(
|
if (showNewTabFab)
|
||||||
padding: const EdgeInsets.only(
|
Padding(
|
||||||
top: _TabSheetHeader.headerSize + 4,
|
padding: const EdgeInsets.only(
|
||||||
right: 4,
|
top: _TabViewHeader.headerSize + 4,
|
||||||
),
|
right: 4,
|
||||||
child: FloatingActionButton.small(
|
),
|
||||||
onPressed: () async {
|
child: FloatingActionButton.small(
|
||||||
final settings = ref.read(generalSettingsWithDefaultsProvider);
|
onPressed: () async {
|
||||||
|
final settings = ref.read(generalSettingsWithDefaultsProvider);
|
||||||
|
|
||||||
await SearchRoute(
|
await SearchRoute(
|
||||||
tabType:
|
tabType:
|
||||||
ref.read(selectedTabTypeProvider) ??
|
ref.read(selectedTabTypeProvider) ??
|
||||||
settings.defaultCreateTabType,
|
settings.defaultCreateTabType,
|
||||||
).push(context);
|
).push(context);
|
||||||
|
|
||||||
onClose();
|
onClose();
|
||||||
},
|
},
|
||||||
child: const Icon(Icons.add),
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ViewTabTreesSheetWidget extends HookConsumerWidget {
|
class ViewTabTreesWidget extends HookConsumerWidget {
|
||||||
final ScrollController sheetScrollController;
|
final ScrollController scrollController;
|
||||||
final VoidCallback onClose;
|
final VoidCallback onClose;
|
||||||
|
final bool showNewTabFab;
|
||||||
|
|
||||||
const ViewTabTreesSheetWidget({
|
const ViewTabTreesWidget({
|
||||||
required this.onClose,
|
required this.onClose,
|
||||||
required this.sheetScrollController,
|
required this.scrollController,
|
||||||
|
required this.showNewTabFab,
|
||||||
super.key,
|
super.key,
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -643,7 +654,7 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
|
|||||||
children: [
|
children: [
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
_TabSheetHeader(onClose: onClose, treeViewEnabled: true),
|
_TabViewHeader(onClose: onClose, treeViewEnabled: true),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: HookConsumer(
|
child: HookConsumer(
|
||||||
builder: (context, ref, child) {
|
builder: (context, ref, child) {
|
||||||
@@ -697,9 +708,9 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
|
|||||||
if (index > -1) {
|
if (index > -1) {
|
||||||
final offset = (index ~/ 2) * itemHeight;
|
final offset = (index ~/ 2) * itemHeight;
|
||||||
|
|
||||||
if (offset != sheetScrollController.offset) {
|
if (offset != scrollController.offset) {
|
||||||
unawaited(
|
unawaited(
|
||||||
sheetScrollController.animateTo(
|
scrollController.animateTo(
|
||||||
offset,
|
offset,
|
||||||
duration: const Duration(milliseconds: 200),
|
duration: const Duration(milliseconds: 200),
|
||||||
curve: Curves.easeInOut,
|
curve: Curves.easeInOut,
|
||||||
@@ -728,7 +739,7 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
|
|||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
controller: sheetScrollController,
|
controller: scrollController,
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
//Sync values for itemHeight calculation _calculateItemHeight
|
//Sync values for itemHeight calculation _calculateItemHeight
|
||||||
childAspectRatio: 0.75,
|
childAspectRatio: 0.75,
|
||||||
@@ -745,26 +756,27 @@ class ViewTabTreesSheetWidget extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
Padding(
|
if (showNewTabFab)
|
||||||
padding: const EdgeInsets.only(
|
Padding(
|
||||||
top: _TabSheetHeader.headerSize + 4,
|
padding: const EdgeInsets.only(
|
||||||
right: 4,
|
top: _TabViewHeader.headerSize + 4,
|
||||||
),
|
right: 4,
|
||||||
child: FloatingActionButton.small(
|
),
|
||||||
onPressed: () async {
|
child: FloatingActionButton.small(
|
||||||
final settings = ref.read(generalSettingsWithDefaultsProvider);
|
onPressed: () async {
|
||||||
|
final settings = ref.read(generalSettingsWithDefaultsProvider);
|
||||||
|
|
||||||
await SearchRoute(
|
await SearchRoute(
|
||||||
tabType:
|
tabType:
|
||||||
ref.read(selectedTabTypeProvider) ??
|
ref.read(selectedTabTypeProvider) ??
|
||||||
settings.defaultCreateTabType,
|
settings.defaultCreateTabType,
|
||||||
).push(context);
|
).push(context);
|
||||||
|
|
||||||
onClose();
|
onClose();
|
||||||
},
|
},
|
||||||
child: const Icon(Icons.add),
|
child: const Icon(Icons.add),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.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:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:weblibre/core/routing/routes.dart';
|
import 'package:weblibre/core/routing/routes.dart';
|
||||||
import 'package:weblibre/features/bangs/data/models/bang_data.dart';
|
import 'package:weblibre/features/bangs/data/models/bang_data.dart';
|
||||||
@@ -120,7 +119,7 @@ class SearchScreen extends HookConsumerWidget {
|
|||||||
if (context.mounted) {
|
if (context.mounted) {
|
||||||
ref.read(bottomSheetControllerProvider.notifier).requestDismiss();
|
ref.read(bottomSheetControllerProvider.notifier).requestDismiss();
|
||||||
|
|
||||||
context.pop();
|
BrowserRoute().go(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -226,7 +225,7 @@ class SearchScreen extends HookConsumerWidget {
|
|||||||
.read(bottomSheetControllerProvider.notifier)
|
.read(bottomSheetControllerProvider.notifier)
|
||||||
.requestDismiss();
|
.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/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_material_design_icons/flutter_material_design_icons.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:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:nullability/nullability.dart';
|
import 'package:nullability/nullability.dart';
|
||||||
import 'package:skeletonizer/skeletonizer.dart';
|
import 'package:skeletonizer/skeletonizer.dart';
|
||||||
import 'package:sliver_tools/sliver_tools.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/controllers/bottom_sheet.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/search/domain/providers/engine_suggestions.dart';
|
import 'package:weblibre/features/geckoview/features/search/domain/providers/engine_suggestions.dart';
|
||||||
@@ -129,7 +129,7 @@ class HistorySuggestions extends HookConsumerWidget {
|
|||||||
)
|
)
|
||||||
.requestDismiss();
|
.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/material.dart';
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:nullability/nullability.dart';
|
import 'package:nullability/nullability.dart';
|
||||||
import 'package:sliver_tools/sliver_tools.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/controllers/bottom_sheet.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/domain/providers.dart';
|
import 'package:weblibre/features/geckoview/features/browser/domain/providers.dart';
|
||||||
@@ -175,7 +175,7 @@ class TabSearch extends HookConsumerWidget {
|
|||||||
.read(bottomSheetControllerProvider.notifier)
|
.read(bottomSheetControllerProvider.notifier)
|
||||||
.requestDismiss();
|
.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/logger.dart';
|
||||||
import 'package:weblibre/core/routing/routes.dart';
|
import 'package:weblibre/core/routing/routes.dart';
|
||||||
import 'package:weblibre/core/uuid.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/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/data/models/container_data.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/container.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/container.dart';
|
||||||
|
|||||||
@@ -392,6 +392,22 @@ class GeneralSettingsScreen extends HookConsumerWidget {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
SwitchListTile.adaptive(
|
||||||
|
title: const Text('Bottom Sheet Tab View'),
|
||||||
|
subtitle: const Text(
|
||||||
|
'Display tabs in a bottom sheet instead of fullscreen',
|
||||||
|
),
|
||||||
|
secondary: const Icon(MdiIcons.dockBottom),
|
||||||
|
value: generalSettings.tabViewBottomSheet,
|
||||||
|
onChanged: (value) async {
|
||||||
|
await ref
|
||||||
|
.read(saveGeneralSettingsControllerProvider.notifier)
|
||||||
|
.save(
|
||||||
|
(currentSettings) =>
|
||||||
|
currentSettings.copyWith.tabViewBottomSheet(value),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.symmetric(
|
padding: const EdgeInsets.symmetric(
|
||||||
horizontal: 16.0,
|
horizontal: 16.0,
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ class GeneralSettings with FastEquatable {
|
|||||||
final bool autoHideTabBar;
|
final bool autoHideTabBar;
|
||||||
final TabBarSwipeAction tabBarSwipeAction;
|
final TabBarSwipeAction tabBarSwipeAction;
|
||||||
final Duration historyAutoCleanInterval;
|
final Duration historyAutoCleanInterval;
|
||||||
|
final bool tabViewBottomSheet;
|
||||||
|
|
||||||
GeneralSettings({
|
GeneralSettings({
|
||||||
required this.themeMode,
|
required this.themeMode,
|
||||||
@@ -86,6 +87,7 @@ class GeneralSettings with FastEquatable {
|
|||||||
required this.autoHideTabBar,
|
required this.autoHideTabBar,
|
||||||
required this.tabBarSwipeAction,
|
required this.tabBarSwipeAction,
|
||||||
required this.historyAutoCleanInterval,
|
required this.historyAutoCleanInterval,
|
||||||
|
required this.tabViewBottomSheet,
|
||||||
});
|
});
|
||||||
|
|
||||||
GeneralSettings.withDefaults({
|
GeneralSettings.withDefaults({
|
||||||
@@ -103,6 +105,7 @@ class GeneralSettings with FastEquatable {
|
|||||||
bool? autoHideTabBar,
|
bool? autoHideTabBar,
|
||||||
TabBarSwipeAction? tabBarSwipeAction,
|
TabBarSwipeAction? tabBarSwipeAction,
|
||||||
Duration? historyAutoCleanInterval,
|
Duration? historyAutoCleanInterval,
|
||||||
|
bool? tabViewBottomSheet,
|
||||||
}) : themeMode = themeMode ?? ThemeMode.dark,
|
}) : themeMode = themeMode ?? ThemeMode.dark,
|
||||||
enableReadability = enableReadability ?? true,
|
enableReadability = enableReadability ?? true,
|
||||||
enforceReadability = enforceReadability ?? false,
|
enforceReadability = enforceReadability ?? false,
|
||||||
@@ -118,7 +121,8 @@ class GeneralSettings with FastEquatable {
|
|||||||
tabBarSwipeAction =
|
tabBarSwipeAction =
|
||||||
tabBarSwipeAction ?? TabBarSwipeAction.switchLastOpened,
|
tabBarSwipeAction ?? TabBarSwipeAction.switchLastOpened,
|
||||||
historyAutoCleanInterval =
|
historyAutoCleanInterval =
|
||||||
historyAutoCleanInterval ?? const Duration(days: 90);
|
historyAutoCleanInterval ?? const Duration(days: 90),
|
||||||
|
tabViewBottomSheet = tabViewBottomSheet ?? false;
|
||||||
|
|
||||||
factory GeneralSettings.fromJson(Map<String, dynamic> json) =>
|
factory GeneralSettings.fromJson(Map<String, dynamic> json) =>
|
||||||
_$GeneralSettingsFromJson(json);
|
_$GeneralSettingsFromJson(json);
|
||||||
@@ -141,5 +145,6 @@ class GeneralSettings with FastEquatable {
|
|||||||
autoHideTabBar,
|
autoHideTabBar,
|
||||||
tabBarSwipeAction,
|
tabBarSwipeAction,
|
||||||
historyAutoCleanInterval,
|
historyAutoCleanInterval,
|
||||||
|
tabViewBottomSheet,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ abstract class _$GeneralSettingsCWProxy {
|
|||||||
|
|
||||||
GeneralSettings historyAutoCleanInterval(Duration historyAutoCleanInterval);
|
GeneralSettings historyAutoCleanInterval(Duration historyAutoCleanInterval);
|
||||||
|
|
||||||
|
GeneralSettings tabViewBottomSheet(bool tabViewBottomSheet);
|
||||||
|
|
||||||
/// Creates a new instance with the provided field values.
|
/// Creates a new instance with the provided field values.
|
||||||
/// Passing `null` to a nullable field nullifies it, while `null` for a non-nullable field is ignored. To update a single field use `GeneralSettings(...).copyWith.fieldName(value)`.
|
/// Passing `null` to a nullable field nullifies it, while `null` for a non-nullable field is ignored. To update a single field use `GeneralSettings(...).copyWith.fieldName(value)`.
|
||||||
///
|
///
|
||||||
@@ -63,6 +65,7 @@ abstract class _$GeneralSettingsCWProxy {
|
|||||||
bool autoHideTabBar,
|
bool autoHideTabBar,
|
||||||
TabBarSwipeAction tabBarSwipeAction,
|
TabBarSwipeAction tabBarSwipeAction,
|
||||||
Duration historyAutoCleanInterval,
|
Duration historyAutoCleanInterval,
|
||||||
|
bool tabViewBottomSheet,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,6 +134,10 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
|
|||||||
GeneralSettings historyAutoCleanInterval(Duration historyAutoCleanInterval) =>
|
GeneralSettings historyAutoCleanInterval(Duration historyAutoCleanInterval) =>
|
||||||
call(historyAutoCleanInterval: historyAutoCleanInterval);
|
call(historyAutoCleanInterval: historyAutoCleanInterval);
|
||||||
|
|
||||||
|
@override
|
||||||
|
GeneralSettings tabViewBottomSheet(bool tabViewBottomSheet) =>
|
||||||
|
call(tabViewBottomSheet: tabViewBottomSheet);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
/// Creates a new instance with the provided field values.
|
/// Creates a new instance with the provided field values.
|
||||||
/// Passing `null` to a nullable field nullifies it, while `null` for a non-nullable field is ignored. To update a single field use `GeneralSettings(...).copyWith.fieldName(value)`.
|
/// Passing `null` to a nullable field nullifies it, while `null` for a non-nullable field is ignored. To update a single field use `GeneralSettings(...).copyWith.fieldName(value)`.
|
||||||
@@ -154,6 +161,7 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
|
|||||||
Object? autoHideTabBar = const $CopyWithPlaceholder(),
|
Object? autoHideTabBar = const $CopyWithPlaceholder(),
|
||||||
Object? tabBarSwipeAction = const $CopyWithPlaceholder(),
|
Object? tabBarSwipeAction = const $CopyWithPlaceholder(),
|
||||||
Object? historyAutoCleanInterval = const $CopyWithPlaceholder(),
|
Object? historyAutoCleanInterval = const $CopyWithPlaceholder(),
|
||||||
|
Object? tabViewBottomSheet = const $CopyWithPlaceholder(),
|
||||||
}) {
|
}) {
|
||||||
return GeneralSettings(
|
return GeneralSettings(
|
||||||
themeMode: themeMode == const $CopyWithPlaceholder() || themeMode == null
|
themeMode: themeMode == const $CopyWithPlaceholder() || themeMode == null
|
||||||
@@ -236,6 +244,12 @@ class _$GeneralSettingsCWProxyImpl implements _$GeneralSettingsCWProxy {
|
|||||||
? _value.historyAutoCleanInterval
|
? _value.historyAutoCleanInterval
|
||||||
// ignore: cast_nullable_to_non_nullable
|
// ignore: cast_nullable_to_non_nullable
|
||||||
: historyAutoCleanInterval as Duration,
|
: historyAutoCleanInterval as Duration,
|
||||||
|
tabViewBottomSheet:
|
||||||
|
tabViewBottomSheet == const $CopyWithPlaceholder() ||
|
||||||
|
tabViewBottomSheet == null
|
||||||
|
? _value.tabViewBottomSheet
|
||||||
|
// ignore: cast_nullable_to_non_nullable
|
||||||
|
: tabViewBottomSheet as bool,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -288,6 +302,7 @@ GeneralSettings _$GeneralSettingsFromJson(Map<String, dynamic> json) =>
|
|||||||
: Duration(
|
: Duration(
|
||||||
microseconds: (json['historyAutoCleanInterval'] as num).toInt(),
|
microseconds: (json['historyAutoCleanInterval'] as num).toInt(),
|
||||||
),
|
),
|
||||||
|
tabViewBottomSheet: json['tabViewBottomSheet'] as bool?,
|
||||||
);
|
);
|
||||||
|
|
||||||
Map<String, dynamic> _$GeneralSettingsToJson(
|
Map<String, dynamic> _$GeneralSettingsToJson(
|
||||||
@@ -314,6 +329,7 @@ Map<String, dynamic> _$GeneralSettingsToJson(
|
|||||||
'autoHideTabBar': instance.autoHideTabBar,
|
'autoHideTabBar': instance.autoHideTabBar,
|
||||||
'tabBarSwipeAction': _$TabBarSwipeActionEnumMap[instance.tabBarSwipeAction]!,
|
'tabBarSwipeAction': _$TabBarSwipeActionEnumMap[instance.tabBarSwipeAction]!,
|
||||||
'historyAutoCleanInterval': instance.historyAutoCleanInterval.inMicroseconds,
|
'historyAutoCleanInterval': instance.historyAutoCleanInterval.inMicroseconds,
|
||||||
|
'tabViewBottomSheet': instance.tabViewBottomSheet,
|
||||||
};
|
};
|
||||||
|
|
||||||
const _$ThemeModeEnumMap = {
|
const _$ThemeModeEnumMap = {
|
||||||
|
|||||||
@@ -100,6 +100,10 @@ class GeneralSettingsRepository extends _$GeneralSettingsRepository {
|
|||||||
DriftSqlType.int,
|
DriftSqlType.int,
|
||||||
db.typeMapping,
|
db.typeMapping,
|
||||||
),
|
),
|
||||||
|
'tabViewBottomSheet': settings['tabViewBottomSheet']?.readAs(
|
||||||
|
DriftSqlType.bool,
|
||||||
|
db.typeMapping,
|
||||||
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ final class GeneralSettingsRepositoryProvider
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _$generalSettingsRepositoryHash() =>
|
String _$generalSettingsRepositoryHash() =>
|
||||||
r'a9b21f9c5ef50bb8a8761995ed2fea723375b80e';
|
r'7ab8eb72c43ed9486bf9fa8b13a6cce83e2b3d66';
|
||||||
|
|
||||||
abstract class _$GeneralSettingsRepository
|
abstract class _$GeneralSettingsRepository
|
||||||
extends $StreamNotifier<GeneralSettings> {
|
extends $StreamNotifier<GeneralSettings> {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ final class CompletePageInfoProvider
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String _$completePageInfoHash() => r'e033a1439ee47af5aef0fd6bf3e8a41d5e88c6fe';
|
String _$completePageInfoHash() => r'edf5538b913d1ebb285c15ec83644818fe90707d';
|
||||||
|
|
||||||
final class CompletePageInfoFamily extends $Family
|
final class CompletePageInfoFamily extends $Family
|
||||||
with
|
with
|
||||||
|
|||||||
Reference in New Issue
Block a user