assign container via menu
This commit is contained in:
@@ -28,6 +28,10 @@ part of 'routes.dart';
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
TypedGoRoute<ContainerSelectionRoute>(
|
||||||
|
name: 'ContainerSelectionRoute',
|
||||||
|
path: 'select_container',
|
||||||
|
),
|
||||||
TypedGoRoute<TabTreeRoute>(
|
TypedGoRoute<TabTreeRoute>(
|
||||||
name: 'TabTreeRoute',
|
name: 'TabTreeRoute',
|
||||||
path: 'tab_tree/:rootTabId',
|
path: 'tab_tree/:rootTabId',
|
||||||
@@ -97,6 +101,14 @@ class ContainerListRoute extends GoRouteData with _$ContainerListRoute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ContainerSelectionRoute extends GoRouteData
|
||||||
|
with _$ContainerSelectionRoute {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, GoRouterState state) {
|
||||||
|
return const ContainerSelectionScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ContainerEditRoute extends GoRouteData with _$ContainerEditRoute {
|
class ContainerEditRoute extends GoRouteData with _$ContainerEditRoute {
|
||||||
final ContainerData $extra;
|
final ContainerData $extra;
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import 'package:weblibre/features/geckoview/features/search/presentation/screens
|
|||||||
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/presentation/screens/container_edit.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/presentation/screens/container_edit.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/tabs/presentation/screens/container_list.dart';
|
import 'package:weblibre/features/geckoview/features/tabs/presentation/screens/container_list.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/tabs/presentation/screens/container_selection.dart';
|
||||||
import 'package:weblibre/features/onboarding/presentation/onboarding.dart';
|
import 'package:weblibre/features/onboarding/presentation/onboarding.dart';
|
||||||
import 'package:weblibre/features/settings/presentation/screens/bang_settings.dart';
|
import 'package:weblibre/features/settings/presentation/screens/bang_settings.dart';
|
||||||
import 'package:weblibre/features/settings/presentation/screens/developer_settings.dart';
|
import 'package:weblibre/features/settings/presentation/screens/developer_settings.dart';
|
||||||
|
|||||||
@@ -327,6 +327,12 @@ RouteBase get $browserRoute => GoRouteData.$route(
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
GoRouteData.$route(
|
||||||
|
path: 'select_container',
|
||||||
|
name: 'ContainerSelectionRoute',
|
||||||
|
|
||||||
|
factory: _$ContainerSelectionRoute._fromState,
|
||||||
|
),
|
||||||
GoRouteData.$route(
|
GoRouteData.$route(
|
||||||
path: 'tab_tree/:rootTabId',
|
path: 'tab_tree/:rootTabId',
|
||||||
name: 'TabTreeRoute',
|
name: 'TabTreeRoute',
|
||||||
@@ -534,6 +540,27 @@ mixin _$ContainerEditRoute on GoRouteData {
|
|||||||
context.replace(location, extra: _self.$extra);
|
context.replace(location, extra: _self.$extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mixin _$ContainerSelectionRoute on GoRouteData {
|
||||||
|
static ContainerSelectionRoute _fromState(GoRouterState state) =>
|
||||||
|
ContainerSelectionRoute();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String get location => GoRouteData.$location('/select_container');
|
||||||
|
|
||||||
|
@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 _$TabTreeRoute on GoRouteData {
|
mixin _$TabTreeRoute on GoRouteData {
|
||||||
static TabTreeRoute _fromState(GoRouterState state) =>
|
static TabTreeRoute _fromState(GoRouterState state) =>
|
||||||
TabTreeRoute(state.pathParameters['rootTabId']!);
|
TabTreeRoute(state.pathParameters['rootTabId']!);
|
||||||
|
|||||||
+33
-1
@@ -7,13 +7,17 @@ import 'package:flutter_material_design_icons/flutter_material_design_icons.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:share_plus/share_plus.dart';
|
import 'package:share_plus/share_plus.dart';
|
||||||
|
import 'package:weblibre/core/routing/routes.dart';
|
||||||
import 'package:weblibre/data/models/web_page_info.dart';
|
import 'package:weblibre/data/models/web_page_info.dart';
|
||||||
import 'package:weblibre/features/bangs/domain/providers/bangs.dart';
|
import 'package:weblibre/features/bangs/domain/providers/bangs.dart';
|
||||||
import 'package:weblibre/features/bangs/presentation/widgets/site_search.dart';
|
import 'package:weblibre/features/bangs/presentation/widgets/site_search.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/domain/providers/selected_tab.dart';
|
||||||
import 'package:weblibre/features/geckoview/domain/providers/tab_session.dart';
|
import 'package:weblibre/features/geckoview/domain/providers/tab_session.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/dialogs/qr_code.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/dialogs/qr_code.dart';
|
||||||
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/address_with_suggestions_field.dart';
|
import 'package:weblibre/features/geckoview/features/browser/presentation/widgets/browser_modules/address_with_suggestions_field.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/container.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/tab.dart';
|
||||||
import 'package:weblibre/features/user/domain/providers.dart';
|
import 'package:weblibre/features/user/domain/providers.dart';
|
||||||
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
import 'package:weblibre/presentation/widgets/failure_widget.dart';
|
||||||
import 'package:weblibre/presentation/widgets/share_tile.dart';
|
import 'package:weblibre/presentation/widgets/share_tile.dart';
|
||||||
@@ -110,7 +114,6 @@ class WebPageDialog extends HookConsumerWidget {
|
|||||||
availableBangCount == null ||
|
availableBangCount == null ||
|
||||||
availableBangCount > 0)
|
availableBangCount > 0)
|
||||||
const Divider(),
|
const Divider(),
|
||||||
WebsiteFeedTile(url, precachedInfo: precachedInfo),
|
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: const Icon(MdiIcons.contentCopy),
|
leading: const Icon(MdiIcons.contentCopy),
|
||||||
title: const Text('Copy address'),
|
title: const Text('Copy address'),
|
||||||
@@ -180,6 +183,34 @@ class WebPageDialog extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
ListTile(
|
||||||
|
leading: const Icon(MdiIcons.folderArrowUpDown),
|
||||||
|
title: const Text('Assign container'),
|
||||||
|
onTap: () async {
|
||||||
|
final selectedTabId = ref.read(selectedTabProvider);
|
||||||
|
if (selectedTabId != null) {
|
||||||
|
final targetContainerId =
|
||||||
|
await ContainerSelectionRoute().push<String?>(
|
||||||
|
context,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (targetContainerId != null) {
|
||||||
|
final containerData = await ref
|
||||||
|
.read(containerRepositoryProvider.notifier)
|
||||||
|
.getContainerData(targetContainerId);
|
||||||
|
|
||||||
|
if (containerData != null) {
|
||||||
|
await ref
|
||||||
|
.read(tabDataRepositoryProvider.notifier)
|
||||||
|
.assignContainer(
|
||||||
|
selectedTabId,
|
||||||
|
containerData,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
ShareTile(
|
ShareTile(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await SharePlus.instance.share(
|
await SharePlus.instance.share(
|
||||||
@@ -231,6 +262,7 @@ class WebPageDialog extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
WebsiteFeedTile(url, precachedInfo: precachedInfo),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
+83
@@ -0,0 +1,83 @@
|
|||||||
|
import 'package:fading_scroll/fading_scroll.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:go_router/go_router.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:skeletonizer/skeletonizer.dart';
|
||||||
|
import 'package:weblibre/core/routing/routes.dart';
|
||||||
|
import 'package:weblibre/core/uuid.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/tabs/data/models/container_data.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/tabs/domain/providers.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/tabs/domain/repositories/container.dart';
|
||||||
|
import 'package:weblibre/features/geckoview/features/tabs/presentation/widgets/container_list_tile.dart';
|
||||||
|
|
||||||
|
class ContainerSelectionScreen extends HookConsumerWidget {
|
||||||
|
const ContainerSelectionScreen();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: const Text('Select Container')),
|
||||||
|
body: HookConsumer(
|
||||||
|
builder: (context, ref, child) {
|
||||||
|
final containersAsync = ref.watch(containersWithCountProvider);
|
||||||
|
|
||||||
|
return Skeletonizer(
|
||||||
|
enabled: containersAsync.isLoading,
|
||||||
|
child: containersAsync.when(
|
||||||
|
skipLoadingOnReload: true,
|
||||||
|
data: (containers) => FadingScroll(
|
||||||
|
fadingSize: 25,
|
||||||
|
builder: (context, controller) {
|
||||||
|
return ListView.builder(
|
||||||
|
controller: controller,
|
||||||
|
itemCount: containers.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final container = containers[index];
|
||||||
|
return ContainerListTile(
|
||||||
|
container,
|
||||||
|
isSelected: false,
|
||||||
|
onTap: () {
|
||||||
|
context.pop<String?>(container.id);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
error: (error, stackTrace) => SizedBox.shrink(),
|
||||||
|
loading: () => ListView.builder(
|
||||||
|
itemCount: 3,
|
||||||
|
itemBuilder: (context, index) => ContainerListTile(
|
||||||
|
ContainerData(id: 'null', color: Colors.transparent),
|
||||||
|
isSelected: false,
|
||||||
|
onTap: null,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton.extended(
|
||||||
|
onPressed: () async {
|
||||||
|
final initialColor = await ref
|
||||||
|
.read(containerRepositoryProvider.notifier)
|
||||||
|
.unusedRandomContainerColor();
|
||||||
|
|
||||||
|
if (context.mounted) {
|
||||||
|
final result = await ContainerCreateRoute(
|
||||||
|
ContainerData(id: uuid.v7(), color: initialColor),
|
||||||
|
).push<ContainerData?>(context);
|
||||||
|
|
||||||
|
if (result != null) {
|
||||||
|
await ref
|
||||||
|
.read(containerRepositoryProvider.notifier)
|
||||||
|
.addContainer(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
label: const Text('Container'),
|
||||||
|
icon: const Icon(Icons.add),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user