update onboarding, perimissions, layout
This commit is contained in:
@@ -7,6 +7,7 @@ import 'package:weblibre/core/providers/router.dart';
|
||||
import 'package:weblibre/features/geckoview/domain/repositories/tab.dart';
|
||||
import 'package:weblibre/features/onboarding/presentation/pages/abstract/i_form_page.dart';
|
||||
import 'package:weblibre/features/onboarding/presentation/pages/default_search.dart';
|
||||
import 'package:weblibre/features/onboarding/presentation/pages/permissions.dart';
|
||||
import 'package:weblibre/features/onboarding/presentation/pages/ublock_opt_in.dart';
|
||||
import 'package:weblibre/features/onboarding/presentation/pages/welcome.dart';
|
||||
import 'package:weblibre/features/user/domain/repositories/onboarding.dart';
|
||||
@@ -32,6 +33,7 @@ class OnboardingScreen extends HookConsumerWidget {
|
||||
const WelcomePage(),
|
||||
const DefaultSearchPage(),
|
||||
UBlockOptInPage(formKey: GlobalKey<FormState>()),
|
||||
PermissionsPage(formKey: GlobalKey<FormState>()),
|
||||
];
|
||||
}, [currentRevision, targetRevision]);
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ class DefaultSearchPage extends HookConsumerWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
final bangs = ref.watch(bangListProvider(triggers: defaultBangs));
|
||||
|
||||
final activeBang = ref.watch(defaultSearchBangDataProvider).valueOrNull;
|
||||
@@ -26,67 +28,77 @@ class DefaultSearchPage extends HookConsumerWidget {
|
||||
);
|
||||
}
|
||||
|
||||
return bangs.when(
|
||||
skipLoadingOnReload: true,
|
||||
data: (availableBangs) {
|
||||
return ListView(
|
||||
children: [
|
||||
SizedBox(
|
||||
height: 48,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text('Default Search:'),
|
||||
if (activeBang != null)
|
||||
FilterChip(
|
||||
showCheckmark: false,
|
||||
label: Text(activeBang.websiteName),
|
||||
avatar: UrlIcon([
|
||||
activeBang.getTemplateUrl(''),
|
||||
], iconSize: 20),
|
||||
selected: true,
|
||||
onSelected: (value) {},
|
||||
),
|
||||
],
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: bangs.when(
|
||||
skipLoadingOnReload: true,
|
||||
data: (availableBangs) {
|
||||
return ListView(
|
||||
children: [
|
||||
const SizedBox(height: 24),
|
||||
Center(
|
||||
child: Text(
|
||||
'Default Search Provider',
|
||||
style: theme.textTheme.headlineMedium,
|
||||
),
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
Wrap(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
...availableBangs.map(
|
||||
(bang) => FilterChip(
|
||||
showCheckmark: false,
|
||||
label: Text(bang.websiteName),
|
||||
avatar: UrlIcon([bang.getTemplateUrl('')], iconSize: 20),
|
||||
selected: activeBang?.trigger == bang.trigger,
|
||||
onSelected: (selected) async {
|
||||
if (selected) {
|
||||
await updateSearchProvider(bang.trigger);
|
||||
const SizedBox(height: 24),
|
||||
SizedBox(
|
||||
height: 48,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
const Text('Selected Provider'),
|
||||
if (activeBang != null)
|
||||
FilterChip(
|
||||
showCheckmark: false,
|
||||
label: Text(activeBang.websiteName),
|
||||
avatar: UrlIcon([
|
||||
activeBang.getTemplateUrl(''),
|
||||
], iconSize: 20),
|
||||
selected: true,
|
||||
onSelected: (value) {},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const Divider(),
|
||||
Wrap(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
...availableBangs.map(
|
||||
(bang) => FilterChip(
|
||||
showCheckmark: false,
|
||||
label: Text(bang.websiteName),
|
||||
avatar: UrlIcon([bang.getTemplateUrl('')], iconSize: 20),
|
||||
selected: activeBang?.trigger == bang.trigger,
|
||||
onSelected: (selected) async {
|
||||
if (selected) {
|
||||
await updateSearchProvider(bang.trigger);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
ActionChip(
|
||||
label: const Text('Search more'),
|
||||
avatar: const Icon(Icons.search),
|
||||
onPressed: () async {
|
||||
final trigger = await const BangSearchRoute()
|
||||
.push<String?>(context);
|
||||
|
||||
if (trigger != null) {
|
||||
await updateSearchProvider(trigger);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
ActionChip(
|
||||
label: const Text('Search more'),
|
||||
avatar: const Icon(Icons.search),
|
||||
onPressed: () async {
|
||||
final trigger = await const BangSearchRoute().push<String?>(
|
||||
context,
|
||||
);
|
||||
|
||||
if (trigger != null) {
|
||||
await updateSearchProvider(trigger);
|
||||
}
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
error: (error, stackTrace) => const SizedBox.shrink(),
|
||||
loading: () => const SizedBox(height: 48, width: double.infinity),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
error: (error, stackTrace) => const SizedBox.shrink(),
|
||||
loading: () => const SizedBox(height: 48, width: double.infinity),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
import 'package:skeletonizer/skeletonizer.dart';
|
||||
import 'package:weblibre/features/onboarding/presentation/pages/abstract/i_form_page.dart';
|
||||
import 'package:weblibre/presentation/hooks/cached_future.dart';
|
||||
|
||||
class PermissionsPage extends HookConsumerWidget implements IFormPage {
|
||||
@override
|
||||
final GlobalKey<FormState> formKey;
|
||||
|
||||
const PermissionsPage({super.key, required this.formKey});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
final notificationPermissionEnabled = useCachedFuture(
|
||||
() => Permission.notification.isGranted,
|
||||
);
|
||||
|
||||
return Form(
|
||||
key: formKey,
|
||||
child: ListView(
|
||||
children: [
|
||||
const SizedBox(height: 24),
|
||||
Center(
|
||||
child: Text('Permissions', style: theme.textTheme.headlineMedium),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
// Padding(
|
||||
// padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
// child: const Text('WebLibre requires following permissions'),
|
||||
// ),
|
||||
// const SizedBox(height: 24),
|
||||
Skeletonizer(
|
||||
enabled: !notificationPermissionEnabled.hasData,
|
||||
child: FormField(
|
||||
initialValue: true,
|
||||
onSaved: (newValue) async {
|
||||
if (newValue == true) {
|
||||
await Permission.notification.request();
|
||||
}
|
||||
},
|
||||
builder: (field) => SwitchListTile(
|
||||
value: field.value ?? true,
|
||||
title: const Text('Notifications'),
|
||||
subtitle: const Text(
|
||||
'Required to inform about download status',
|
||||
),
|
||||
onChanged: (notificationPermissionEnabled.data == true)
|
||||
? null
|
||||
: (value) {
|
||||
field.didChange(value);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -21,10 +21,11 @@ class UBlockOptInPage extends HookConsumerWidget implements IFormPage {
|
||||
key: formKey,
|
||||
child: ListView(
|
||||
children: [
|
||||
const SizedBox(height: 24),
|
||||
SvgPicture.asset('assets/images/ublock.svg'),
|
||||
const SizedBox(height: 8),
|
||||
Center(
|
||||
child: Text('uBlock Origin', style: theme.textTheme.headlineLarge),
|
||||
child: Text('uBlock Origin', style: theme.textTheme.headlineMedium),
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
const Padding(
|
||||
|
||||
@@ -48,6 +48,7 @@ dependencies:
|
||||
package_info_plus: ^8.3.0
|
||||
path: ^1.9.1
|
||||
path_provider: ^2.1.5
|
||||
permission_handler: ^12.0.0+1
|
||||
pretty_qr_code: ^3.4.0
|
||||
riverpod: ^2.6.1
|
||||
riverpod_annotation: ^2.6.1
|
||||
|
||||
Reference in New Issue
Block a user