changed color theme to be black and added the ability to enter the amount in the recipient’s currency

This commit is contained in:
Arseni
2026-03-02 17:41:41 +03:00
parent 17e08ff26f
commit 6bb3ab5063
41 changed files with 618 additions and 239 deletions

View File

@@ -1,3 +1,5 @@
import 'dart:developer' as developer;
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@@ -12,7 +14,6 @@ import 'package:pweb/models/account/account_loader.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class AccountLoader extends StatefulWidget {
final Widget child;
const AccountLoader({super.key, required this.child});
@@ -27,7 +28,8 @@ class _AccountLoaderState extends State<AccountLoader> {
@override
void initState() {
super.initState();
_controller = AccountLoaderController()..addListener(_handleControllerAction);
_controller = AccountLoaderController()
..addListener(_handleControllerAction);
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return;
Provider.of<AccountProvider>(context, listen: false).restoreIfPossible();
@@ -45,6 +47,17 @@ class _AccountLoaderState extends State<AccountLoader> {
switch (action) {
case AccountLoaderAction.showErrorAndGoToLogin:
final error = _controller.error ?? Exception('Authorization failed');
assert(() {
developer.log(
'AccountLoader action=showErrorAndGoToLogin',
name: 'pweb.auth.redirect',
error: error,
);
developer.debugger(
message: 'AccountLoader: redirecting to login due to auth error',
);
return true;
}());
WidgetsBinding.instance.addPostFrameCallback((_) {
if (!mounted) return;
postNotifyUserOfErrorX(
@@ -56,6 +69,17 @@ class _AccountLoaderState extends State<AccountLoader> {
});
break;
case AccountLoaderAction.goToLogin:
assert(() {
developer.log(
'AccountLoader action=goToLogin',
name: 'pweb.auth.redirect',
);
developer.debugger(
message:
'AccountLoader: redirecting to login due to empty auth state',
);
return true;
}());
WidgetsBinding.instance.addPostFrameCallback((_) => goToLogin());
break;
}
@@ -70,12 +94,14 @@ class _AccountLoaderState extends State<AccountLoader> {
@override
Widget build(BuildContext context) {
return Consumer<AccountProvider>(builder: (context, provider, _) {
_controller.update(provider);
if (provider.authState == AuthState.ready && provider.account != null) {
return widget.child;
}
return const Center(child: CircularProgressIndicator());
});
return Consumer<AccountProvider>(
builder: (context, provider, _) {
_controller.update(provider);
if (provider.authState == AuthState.ready && provider.account != null) {
return widget.child;
}
return const Center(child: CircularProgressIndicator());
},
);
}
}

View File

@@ -1,3 +1,5 @@
import 'dart:developer' as developer;
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@@ -6,34 +8,45 @@ import 'package:pshared/provider/organizations.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class OrganizationLoader extends StatelessWidget {
final Widget child;
const OrganizationLoader({super.key, required this.child});
@override
Widget build(BuildContext context) => Consumer<OrganizationsProvider>(builder: (context, provider, _) {
if (provider.isLoading) return const Center(child: CircularProgressIndicator());
if (provider.error != null) {
final loc = AppLocalizations.of(context)!;
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(loc.errorLogin),
const SizedBox(height: 12),
ElevatedButton(
onPressed: provider.load,
child: Text(loc.retry),
),
],
),
);
}
if ((provider.error == null) && (!provider.isOrganizationSet)) {
return const Center(child: CircularProgressIndicator());
}
return child;
});
Widget build(BuildContext context) => Consumer<OrganizationsProvider>(
builder: (context, provider, _) {
if (provider.isLoading) {
return const Center(child: CircularProgressIndicator());
}
if (provider.error != null) {
assert(() {
developer.log(
'OrganizationLoader: provider.error != null',
name: 'pweb.auth.redirect',
error: provider.error,
);
developer.debugger(
message: 'OrganizationLoader blocked app with error',
);
return true;
}());
final loc = AppLocalizations.of(context)!;
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Text(loc.errorLogin),
const SizedBox(height: 12),
ElevatedButton(onPressed: provider.load, child: Text(loc.retry)),
],
),
);
}
if ((provider.error == null) && (!provider.isOrganizationSet)) {
return const Center(child: CircularProgressIndicator());
}
return child;
},
);
}

View File

@@ -1,3 +1,5 @@
import 'dart:developer' as developer;
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
@@ -7,7 +9,6 @@ import 'package:pshared/provider/permissions.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
class PermissionsLoader extends StatelessWidget {
final Widget child;
const PermissionsLoader({super.key, required this.child});
@@ -17,6 +18,17 @@ class PermissionsLoader extends StatelessWidget {
return Consumer2<PermissionsProvider, AccountProvider>(
builder: (context, provider, _, _) {
if (provider.error != null) {
assert(() {
developer.log(
'PermissionsLoader: provider.error != null',
name: 'pweb.auth.redirect',
error: provider.error,
);
developer.debugger(
message: 'PermissionsLoader blocked app with error',
);
return true;
}());
final loc = AppLocalizations.of(context)!;
return Center(
child: Column(