strip auth
This commit is contained in:
@@ -23,7 +23,6 @@ import 'package:weblibre/features/settings/presentation/screens/web_engine_harde
|
|||||||
import 'package:weblibre/features/settings/presentation/screens/web_engine_hardening_group.dart';
|
import 'package:weblibre/features/settings/presentation/screens/web_engine_hardening_group.dart';
|
||||||
import 'package:weblibre/features/settings/presentation/screens/web_engine_settings.dart';
|
import 'package:weblibre/features/settings/presentation/screens/web_engine_settings.dart';
|
||||||
import 'package:weblibre/features/tor/presentation/screens/tor_proxy.dart';
|
import 'package:weblibre/features/tor/presentation/screens/tor_proxy.dart';
|
||||||
import 'package:weblibre/features/user/presentation/screens/auth.dart';
|
|
||||||
import 'package:weblibre/features/web_feed/presentation/add_feed_dialog.dart';
|
import 'package:weblibre/features/web_feed/presentation/add_feed_dialog.dart';
|
||||||
import 'package:weblibre/features/web_feed/presentation/screens/feed_article.dart';
|
import 'package:weblibre/features/web_feed/presentation/screens/feed_article.dart';
|
||||||
import 'package:weblibre/features/web_feed/presentation/screens/feed_article_list.dart';
|
import 'package:weblibre/features/web_feed/presentation/screens/feed_article_list.dart';
|
||||||
@@ -44,11 +43,3 @@ class AboutRoute extends GoRouteData {
|
|||||||
return DialogPage(builder: (_) => const AboutDialogScreen());
|
return DialogPage(builder: (_) => const AboutDialogScreen());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@TypedGoRoute<UserAuthRoute>(name: 'UserAuthRoute', path: '/userAuth')
|
|
||||||
class UserAuthRoute extends GoRouteData {
|
|
||||||
@override
|
|
||||||
Page<void> buildPage(BuildContext context, GoRouterState state) {
|
|
||||||
return DialogPage(builder: (_) => const UserAuthScreen());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ part of 'routes.dart';
|
|||||||
|
|
||||||
List<RouteBase> get $appRoutes => [
|
List<RouteBase> get $appRoutes => [
|
||||||
$aboutRoute,
|
$aboutRoute,
|
||||||
$userAuthRoute,
|
|
||||||
$settingsRoute,
|
$settingsRoute,
|
||||||
$browserRoute,
|
$browserRoute,
|
||||||
$bangCategoriesRoute,
|
$bangCategoriesRoute,
|
||||||
@@ -37,28 +36,6 @@ extension $AboutRouteExtension on AboutRoute {
|
|||||||
void replace(BuildContext context) => context.replace(location);
|
void replace(BuildContext context) => context.replace(location);
|
||||||
}
|
}
|
||||||
|
|
||||||
RouteBase get $userAuthRoute => GoRouteData.$route(
|
|
||||||
path: '/userAuth',
|
|
||||||
name: 'UserAuthRoute',
|
|
||||||
|
|
||||||
factory: $UserAuthRouteExtension._fromState,
|
|
||||||
);
|
|
||||||
|
|
||||||
extension $UserAuthRouteExtension on UserAuthRoute {
|
|
||||||
static UserAuthRoute _fromState(GoRouterState state) => UserAuthRoute();
|
|
||||||
|
|
||||||
String get location => GoRouteData.$location('/userAuth');
|
|
||||||
|
|
||||||
void go(BuildContext context) => context.go(location);
|
|
||||||
|
|
||||||
Future<T?> push<T>(BuildContext context) => context.push<T>(location);
|
|
||||||
|
|
||||||
void pushReplacement(BuildContext context) =>
|
|
||||||
context.pushReplacement(location);
|
|
||||||
|
|
||||||
void replace(BuildContext context) => context.replace(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
RouteBase get $settingsRoute => GoRouteData.$route(
|
RouteBase get $settingsRoute => GoRouteData.$route(
|
||||||
path: '/settings',
|
path: '/settings',
|
||||||
name: 'SettingsRoute',
|
name: 'SettingsRoute',
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:pocketbase/pocketbase.dart';
|
|
||||||
import 'package:riverpod/riverpod.dart';
|
import 'package:riverpod/riverpod.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:weblibre/features/user/data/providers.dart';
|
import 'package:weblibre/features/user/data/providers.dart';
|
||||||
@@ -21,35 +20,6 @@ Stream<double> iconCacheSizeMegabytes(Ref ref) {
|
|||||||
return repository.cacheDao.getIconCacheSize().watchSingle();
|
return repository.cacheDao.getIconCacheSize().watchSingle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Riverpod(keepAlive: true)
|
|
||||||
AsyncAuthStore authStore(Ref ref) {
|
|
||||||
const secureStorage = FlutterSecureStorage();
|
|
||||||
|
|
||||||
final intial = ref.watch(
|
|
||||||
_storedAuthDataProvider.select((value) => value.valueOrNull),
|
|
||||||
);
|
|
||||||
|
|
||||||
return AsyncAuthStore(
|
|
||||||
initial: intial,
|
|
||||||
save: (data) async {
|
|
||||||
await secureStorage.write(key: _authKey, value: data);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Riverpod()
|
|
||||||
Stream<AuthStoreEvent> authState(Ref ref) {
|
|
||||||
final authStore = ref.watch(authStoreProvider);
|
|
||||||
return authStore.onChange;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Riverpod(keepAlive: true)
|
|
||||||
PocketBase pocketBase(Ref ref) {
|
|
||||||
final authStore = ref.watch(authStoreProvider);
|
|
||||||
|
|
||||||
return PocketBase('http://192.168.2.104:8090', authStore: authStore);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Riverpod()
|
@Riverpod()
|
||||||
bool incognitoModeEnabled(Ref ref) {
|
bool incognitoModeEnabled(Ref ref) {
|
||||||
return ref.watch(
|
return ref.watch(
|
||||||
|
|||||||
@@ -44,54 +44,6 @@ final iconCacheSizeMegabytesProvider =
|
|||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
||||||
// ignore: unused_element
|
// ignore: unused_element
|
||||||
typedef IconCacheSizeMegabytesRef = AutoDisposeStreamProviderRef<double>;
|
typedef IconCacheSizeMegabytesRef = AutoDisposeStreamProviderRef<double>;
|
||||||
String _$authStoreHash() => r'766c001bbb8d7dc4e148eff3816c414d78e77f26';
|
|
||||||
|
|
||||||
/// See also [authStore].
|
|
||||||
@ProviderFor(authStore)
|
|
||||||
final authStoreProvider = Provider<AsyncAuthStore>.internal(
|
|
||||||
authStore,
|
|
||||||
name: r'authStoreProvider',
|
|
||||||
debugGetCreateSourceHash:
|
|
||||||
const bool.fromEnvironment('dart.vm.product') ? null : _$authStoreHash,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
);
|
|
||||||
|
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
|
||||||
// ignore: unused_element
|
|
||||||
typedef AuthStoreRef = ProviderRef<AsyncAuthStore>;
|
|
||||||
String _$authStateHash() => r'ffa411ae0abc5c7bb3e8a93e783bd8398ce7f666';
|
|
||||||
|
|
||||||
/// See also [authState].
|
|
||||||
@ProviderFor(authState)
|
|
||||||
final authStateProvider = AutoDisposeStreamProvider<AuthStoreEvent>.internal(
|
|
||||||
authState,
|
|
||||||
name: r'authStateProvider',
|
|
||||||
debugGetCreateSourceHash:
|
|
||||||
const bool.fromEnvironment('dart.vm.product') ? null : _$authStateHash,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
);
|
|
||||||
|
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
|
||||||
// ignore: unused_element
|
|
||||||
typedef AuthStateRef = AutoDisposeStreamProviderRef<AuthStoreEvent>;
|
|
||||||
String _$pocketBaseHash() => r'9e1dc8057e300bc7ca697da9f68ec61e70fdbaab';
|
|
||||||
|
|
||||||
/// See also [pocketBase].
|
|
||||||
@ProviderFor(pocketBase)
|
|
||||||
final pocketBaseProvider = Provider<PocketBase>.internal(
|
|
||||||
pocketBase,
|
|
||||||
name: r'pocketBaseProvider',
|
|
||||||
debugGetCreateSourceHash:
|
|
||||||
const bool.fromEnvironment('dart.vm.product') ? null : _$pocketBaseHash,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
);
|
|
||||||
|
|
||||||
@Deprecated('Will be removed in 3.0. Use Ref instead')
|
|
||||||
// ignore: unused_element
|
|
||||||
typedef PocketBaseRef = ProviderRef<PocketBase>;
|
|
||||||
String _$incognitoModeEnabledHash() =>
|
String _$incognitoModeEnabledHash() =>
|
||||||
r'3968c2d4945be09a0bc08ce0d70b0390187c44e8';
|
r'3968c2d4945be09a0bc08ce0d70b0390187c44e8';
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
import 'package:pocketbase/pocketbase.dart';
|
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
||||||
import 'package:weblibre/features/user/domain/entities/auth_exception.dart';
|
|
||||||
import 'package:weblibre/features/user/domain/providers.dart';
|
|
||||||
import 'package:weblibre/features/user/extensions/client_exception.dart';
|
|
||||||
|
|
||||||
part 'auth.g.dart';
|
|
||||||
|
|
||||||
@Riverpod()
|
|
||||||
class AuthRepository extends _$AuthRepository {
|
|
||||||
late PocketBase _pb;
|
|
||||||
|
|
||||||
Future<RecordAuth> authWithPassword(String user, String password) async {
|
|
||||||
try {
|
|
||||||
return await _pb.collection('users').authWithPassword(user, password);
|
|
||||||
} on ClientException catch (e) {
|
|
||||||
throw AuthException(e.errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<RecordModel> createUserWithPassword(
|
|
||||||
String email,
|
|
||||||
String password,
|
|
||||||
) async {
|
|
||||||
try {
|
|
||||||
return await _pb
|
|
||||||
.collection('users')
|
|
||||||
.create(
|
|
||||||
body: {
|
|
||||||
"email": email,
|
|
||||||
"password": password,
|
|
||||||
"passwordConfirm": password,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
} on ClientException catch (e) {
|
|
||||||
throw AuthException(e.errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void build() {
|
|
||||||
_pb = ref.watch(pocketBaseProvider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'auth.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// RiverpodGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
String _$authRepositoryHash() => r'90ea6f082ef968831763c7f7ee31863f1fe329fe';
|
|
||||||
|
|
||||||
/// See also [AuthRepository].
|
|
||||||
@ProviderFor(AuthRepository)
|
|
||||||
final authRepositoryProvider =
|
|
||||||
AutoDisposeNotifierProvider<AuthRepository, void>.internal(
|
|
||||||
AuthRepository.new,
|
|
||||||
name: r'authRepositoryProvider',
|
|
||||||
debugGetCreateSourceHash:
|
|
||||||
const bool.fromEnvironment('dart.vm.product')
|
|
||||||
? null
|
|
||||||
: _$authRepositoryHash,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef _$AuthRepository = AutoDisposeNotifier<void>;
|
|
||||||
// ignore_for_file: type=lint
|
|
||||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
import 'package:pocketbase/pocketbase.dart';
|
|
||||||
import 'package:weblibre/extensions/string.dart';
|
|
||||||
|
|
||||||
extension ClientExceptionExtension on ClientException {
|
|
||||||
String get errorMessage {
|
|
||||||
var message = "${response["message"] as String? ?? ""}\n\n";
|
|
||||||
final data = response["data"] as Map<String, dynamic>;
|
|
||||||
try {
|
|
||||||
data.forEach((key, value) {
|
|
||||||
final detailedMessage = (value as Map<String, dynamic>)["message"];
|
|
||||||
if (detailedMessage != null) {
|
|
||||||
message += '${key.toCapitalized()}: $detailedMessage\n';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (_) {}
|
|
||||||
try {
|
|
||||||
if (originalError != null) {
|
|
||||||
message += ' $originalError';
|
|
||||||
}
|
|
||||||
} catch (_) {}
|
|
||||||
|
|
||||||
return message.trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
|
||||||
import 'package:weblibre/features/user/domain/repositories/auth.dart';
|
|
||||||
|
|
||||||
part 'controllers.g.dart';
|
|
||||||
|
|
||||||
@Riverpod()
|
|
||||||
class AuthController extends _$AuthController {
|
|
||||||
@override
|
|
||||||
Future<void> build() {
|
|
||||||
return Future.value();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> authWithPassword(String user, String password) async {
|
|
||||||
state = const AsyncLoading();
|
|
||||||
state = await AsyncValue.guard(
|
|
||||||
() => ref
|
|
||||||
.read(authRepositoryProvider.notifier)
|
|
||||||
.authWithPassword(user, password),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> registerWithPassword(String user, String password) async {
|
|
||||||
state = const AsyncLoading();
|
|
||||||
state = await AsyncValue.guard(() {
|
|
||||||
final repo = ref.read(authRepositoryProvider.notifier);
|
|
||||||
return repo
|
|
||||||
.createUserWithPassword(user, password)
|
|
||||||
.then((_) => repo.authWithPassword(user, password));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearState() {
|
|
||||||
state = const AsyncValue.data(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
||||||
|
|
||||||
part of 'controllers.dart';
|
|
||||||
|
|
||||||
// **************************************************************************
|
|
||||||
// RiverpodGenerator
|
|
||||||
// **************************************************************************
|
|
||||||
|
|
||||||
String _$authControllerHash() => r'0085e324fbe093c1984eaa56dbfac33472138f9f';
|
|
||||||
|
|
||||||
/// See also [AuthController].
|
|
||||||
@ProviderFor(AuthController)
|
|
||||||
final authControllerProvider =
|
|
||||||
AutoDisposeAsyncNotifierProvider<AuthController, void>.internal(
|
|
||||||
AuthController.new,
|
|
||||||
name: r'authControllerProvider',
|
|
||||||
debugGetCreateSourceHash:
|
|
||||||
const bool.fromEnvironment('dart.vm.product')
|
|
||||||
? null
|
|
||||||
: _$authControllerHash,
|
|
||||||
dependencies: null,
|
|
||||||
allTransitiveDependencies: null,
|
|
||||||
);
|
|
||||||
|
|
||||||
typedef _$AuthController = AutoDisposeAsyncNotifier<void>;
|
|
||||||
// ignore_for_file: type=lint
|
|
||||||
// ignore_for_file: subtype_of_sealed_class, invalid_use_of_internal_member, invalid_use_of_visible_for_testing_member, deprecated_member_use_from_same_package
|
|
||||||
@@ -1,201 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
|
||||||
import 'package:go_router/go_router.dart';
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:nullability/nullability.dart';
|
|
||||||
import 'package:weblibre/features/user/domain/providers.dart';
|
|
||||||
import 'package:weblibre/features/user/presentation/controllers/controllers.dart';
|
|
||||||
|
|
||||||
enum _AuthType { login, signup }
|
|
||||||
|
|
||||||
class UserAuthScreen extends HookConsumerWidget {
|
|
||||||
const UserAuthScreen();
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
|
||||||
final formKey = useMemoized(() => GlobalKey<FormState>());
|
|
||||||
|
|
||||||
final authType = useState(_AuthType.login);
|
|
||||||
|
|
||||||
final userTextController = useTextEditingController();
|
|
||||||
final passwordTextController = useTextEditingController();
|
|
||||||
final confirmPasswordTextController = useTextEditingController();
|
|
||||||
|
|
||||||
final authState = ref.watch(authControllerProvider);
|
|
||||||
|
|
||||||
ref.listen(authStateProvider.select((value) => value.valueOrNull), (
|
|
||||||
previous,
|
|
||||||
next,
|
|
||||||
) {
|
|
||||||
if (next?.token.isNotEmpty ?? false) {
|
|
||||||
context.pop(true);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return Dialog(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(16.0),
|
|
||||||
child: Form(
|
|
||||||
key: formKey,
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
TextFormField(
|
|
||||||
controller: userTextController,
|
|
||||||
decoration: const InputDecoration(
|
|
||||||
label: Text('Email'),
|
|
||||||
icon: Icon(Icons.account_circle),
|
|
||||||
),
|
|
||||||
validator: (value) {
|
|
||||||
if (value.isEmpty) {
|
|
||||||
return 'Email must be provided';
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
keyboardType: TextInputType.emailAddress,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 8.0),
|
|
||||||
HookBuilder(
|
|
||||||
builder: (context) {
|
|
||||||
final obscure = useState(true);
|
|
||||||
|
|
||||||
return Column(
|
|
||||||
children: [
|
|
||||||
TextFormField(
|
|
||||||
controller: passwordTextController,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
label: const Text('Password'),
|
|
||||||
icon: const Icon(Icons.lock),
|
|
||||||
suffixIcon: IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
obscure.value = !obscure.value;
|
|
||||||
},
|
|
||||||
icon: Icon(
|
|
||||||
obscure.value
|
|
||||||
? Icons.visibility
|
|
||||||
: Icons.visibility_off,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
obscureText: obscure.value,
|
|
||||||
validator: (value) {
|
|
||||||
if (value.isEmpty) {
|
|
||||||
return 'Password must be provided';
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
if (authType.value == _AuthType.signup)
|
|
||||||
TextFormField(
|
|
||||||
controller: confirmPasswordTextController,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
label: const Text('Confirm Password'),
|
|
||||||
icon: const Icon(Icons.lock),
|
|
||||||
suffixIcon: IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
obscure.value = !obscure.value;
|
|
||||||
},
|
|
||||||
icon: Icon(
|
|
||||||
obscure.value
|
|
||||||
? Icons.visibility
|
|
||||||
: Icons.visibility_off,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
obscureText: obscure.value,
|
|
||||||
validator: (value) {
|
|
||||||
if (value.isEmpty) {
|
|
||||||
return 'Password must be provided';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (value != passwordTextController.text) {
|
|
||||||
return 'Password not matching';
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
const SizedBox(height: 16),
|
|
||||||
if (authState.hasError && !authState.isLoading)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(bottom: 16.0),
|
|
||||||
child: Text(
|
|
||||||
authState.error.toString(),
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context).colorScheme.error,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
if (!authState.isLoading)
|
|
||||||
switch (authType.value) {
|
|
||||||
_AuthType.login => FilledButton(
|
|
||||||
onPressed: () async {
|
|
||||||
if (formKey.currentState?.validate() ?? false) {
|
|
||||||
final controller = ref.read(
|
|
||||||
authControllerProvider.notifier,
|
|
||||||
);
|
|
||||||
|
|
||||||
await controller.authWithPassword(
|
|
||||||
userTextController.text,
|
|
||||||
passwordTextController.text,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: const Text('Login'),
|
|
||||||
),
|
|
||||||
_AuthType.signup => FilledButton(
|
|
||||||
onPressed: () async {
|
|
||||||
if (formKey.currentState?.validate() ?? false) {
|
|
||||||
final controller = ref.read(
|
|
||||||
authControllerProvider.notifier,
|
|
||||||
);
|
|
||||||
|
|
||||||
await controller.registerWithPassword(
|
|
||||||
userTextController.text,
|
|
||||||
passwordTextController.text,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
child: const Text('Signup'),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
else
|
|
||||||
const CircularProgressIndicator(),
|
|
||||||
if (!authState.isLoading)
|
|
||||||
switch (authType.value) {
|
|
||||||
_AuthType.login => TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
final controller = ref.read(
|
|
||||||
authControllerProvider.notifier,
|
|
||||||
);
|
|
||||||
|
|
||||||
controller.clearState();
|
|
||||||
authType.value = _AuthType.signup;
|
|
||||||
},
|
|
||||||
child: const Text('Signup'),
|
|
||||||
),
|
|
||||||
_AuthType.signup => TextButton(
|
|
||||||
onPressed: () {
|
|
||||||
final controller = ref.read(
|
|
||||||
authControllerProvider.notifier,
|
|
||||||
);
|
|
||||||
|
|
||||||
controller.clearState();
|
|
||||||
authType.value = _AuthType.login;
|
|
||||||
},
|
|
||||||
child: const Text('Login'),
|
|
||||||
),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -48,7 +48,6 @@ dependencies:
|
|||||||
package_info_plus: ^8.3.0
|
package_info_plus: ^8.3.0
|
||||||
path: ^1.9.1
|
path: ^1.9.1
|
||||||
path_provider: ^2.1.5
|
path_provider: ^2.1.5
|
||||||
pocketbase: ^0.22.0
|
|
||||||
riverpod: ^2.6.1
|
riverpod: ^2.6.1
|
||||||
riverpod_annotation: ^2.6.1
|
riverpod_annotation: ^2.6.1
|
||||||
rss_dart: ^1.0.12
|
rss_dart: ^1.0.12
|
||||||
|
|||||||
Reference in New Issue
Block a user