bug-66 #67

Closed
tech wants to merge 4 commits from bug-66 into main
7 changed files with 47 additions and 19 deletions

1
.gitignore vendored
View File

@@ -9,3 +9,4 @@ untranslated.txt
generate_protos.sh generate_protos.sh
update_dep.sh update_dep.sh
.vscode/ .vscode/
GeneratedPluginRegistrant.swift

View File

@@ -8,6 +8,7 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/tech/sendico/fx/storage/model" "github.com/tech/sendico/fx/storage/model"
"github.com/tech/sendico/pkg/merrors" "github.com/tech/sendico/pkg/merrors"
smodel "github.com/tech/sendico/pkg/model"
fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1" fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1"
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1" moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
tracev1 "github.com/tech/sendico/pkg/proto/common/trace/v1" tracev1 "github.com/tech/sendico/pkg/proto/common/trace/v1"
@@ -138,11 +139,11 @@ func (qc *quoteComputation) buildModelQuote(firm bool, expiryMillis int64, req *
Pair: qc.pair.Pair, Pair: qc.pair.Pair,
Side: qc.sideModel, Side: qc.sideModel,
Price: formatRat(qc.priceRounded, qc.priceScale), Price: formatRat(qc.priceRounded, qc.priceScale),
BaseAmount: model.Money{ BaseAmount: smodel.Money{
Currency: qc.pair.Pair.Base, Currency: qc.pair.Pair.Base,
Amount: formatRat(qc.baseRounded, qc.baseScale), Amount: formatRat(qc.baseRounded, qc.baseScale),
}, },
QuoteAmount: model.Money{ QuoteAmount: smodel.Money{
Currency: qc.pair.Pair.Quote, Currency: qc.pair.Pair.Quote,
Amount: formatRat(qc.quoteRounded, qc.quoteScale), Amount: formatRat(qc.quoteRounded, qc.quoteScale),
}, },

View File

@@ -3,7 +3,6 @@ package oracle
import ( import (
"math/big" "math/big"
"strings" "strings"
"time"
"github.com/tech/sendico/fx/storage/model" "github.com/tech/sendico/fx/storage/model"
"github.com/tech/sendico/pkg/decimal" "github.com/tech/sendico/pkg/decimal"
@@ -61,7 +60,3 @@ func priceFromRate(rate *model.RateSnapshot, side fxv1.Side) (*big.Rat, error) {
return ratFromString(priceStr) return ratFromString(priceStr)
} }
func timeFromUnixMilli(ms int64) time.Time {
return time.Unix(0, ms*int64(time.Millisecond))
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/tech/sendico/fx/storage" "github.com/tech/sendico/fx/storage"
"github.com/tech/sendico/fx/storage/model" "github.com/tech/sendico/fx/storage/model"
"github.com/tech/sendico/pkg/merrors" "github.com/tech/sendico/pkg/merrors"
smodel "github.com/tech/sendico/pkg/model"
fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1" fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1"
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1" moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
tracev1 "github.com/tech/sendico/pkg/proto/common/trace/v1" tracev1 "github.com/tech/sendico/pkg/proto/common/trace/v1"
@@ -381,8 +382,8 @@ func TestServiceValidateQuote(t *testing.T) {
Pair: model.CurrencyPair{Base: "USD", Quote: "EUR"}, Pair: model.CurrencyPair{Base: "USD", Quote: "EUR"},
Side: model.QuoteSideBuyBaseSellQuote, Side: model.QuoteSideBuyBaseSellQuote,
Price: "1.10", Price: "1.10",
BaseAmount: model.Money{Currency: "USD", Amount: "100"}, BaseAmount: smodel.Money{Currency: "USD", Amount: "100"},
QuoteAmount: model.Money{Currency: "EUR", Amount: "110"}, QuoteAmount: smodel.Money{Currency: "EUR", Amount: "110"},
ExpiresAtUnixMs: now.UnixMilli(), ExpiresAtUnixMs: now.UnixMilli(),
Status: model.QuoteStatusIssued, Status: model.QuoteStatusIssued,
}, nil }, nil

View File

@@ -4,6 +4,7 @@ import (
"strings" "strings"
"github.com/tech/sendico/fx/storage/model" "github.com/tech/sendico/fx/storage/model"
smodel "github.com/tech/sendico/pkg/model"
fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1" fxv1 "github.com/tech/sendico/pkg/proto/common/fx/v1"
moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1" moneyv1 "github.com/tech/sendico/pkg/proto/common/money/v1"
tracev1 "github.com/tech/sendico/pkg/proto/common/trace/v1" tracev1 "github.com/tech/sendico/pkg/proto/common/trace/v1"
@@ -49,7 +50,7 @@ func quoteModelToProto(q *model.Quote) *oraclev1.Quote {
} }
} }
func moneyModelToProto(m *model.Money) *moneyv1.Money { func moneyModelToProto(m *smodel.Money) *moneyv1.Money {
if m == nil { if m == nil {
return nil return nil
} }

View File

@@ -27,6 +27,7 @@ class AccountProvider extends ChangeNotifier {
Resource<Account?> get resource => _resource; Resource<Account?> get resource => _resource;
late LocaleProvider _localeProvider; late LocaleProvider _localeProvider;
PendingLogin? _pendingLogin; PendingLogin? _pendingLogin;
Future<void>? _restoreFuture;
Account? get account => _resource.data; Account? get account => _resource.data;
PendingLogin? get pendingLogin => _pendingLogin; PendingLogin? get pendingLogin => _pendingLogin;
@@ -34,6 +35,7 @@ class AccountProvider extends ChangeNotifier {
bool get isLoading => _resource.isLoading; bool get isLoading => _resource.isLoading;
Object? get error => _resource.error; Object? get error => _resource.error;
bool get isReady => (!isLoading) && (account != null); bool get isReady => (!isLoading) && (account != null);
Future<void>? get restoreFuture => _restoreFuture;
Account? currentUser() { Account? currentUser() {
final acc = account; final acc = account;
@@ -220,4 +222,12 @@ class AccountProvider extends ChangeNotifier {
rethrow; rethrow;
} }
} }
Future<void> restoreIfPossible() {
return _restoreFuture ??= () async {
final hasAuth = await AuthorizationService.isAuthorizationStored();
if (!hasAuth) return;
await restore();
}();
}
} }

View File

@@ -17,15 +17,34 @@ class AccountLoader extends StatelessWidget {
@override @override
Widget build(BuildContext context) => Consumer<AccountProvider>(builder: (context, provider, _) { Widget build(BuildContext context) => Consumer<AccountProvider>(builder: (context, provider, _) {
if (provider.isLoading) return const Center(child: CircularProgressIndicator()); if (provider.account != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
});
return child;
}
if (provider.error != null) { if (provider.error != null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
postNotifyUserOfErrorX( postNotifyUserOfErrorX(
context: context, context: context,
errorSituation: AppLocalizations.of(context)!.errorLogin, errorSituation: AppLocalizations.of(context)!.errorLogin,
exception: provider.error!, exception: provider.error!,
); );
navigateAndReplace(context, Pages.login); navigateAndReplace(context, Pages.login);
});
return const Center(child: CircularProgressIndicator());
} }
if (provider.restoreFuture == null) {
WidgetsBinding.instance.addPostFrameCallback((_) {
provider.restoreIfPossible().catchError((error, stack) {
debugPrint('Account restore failed: $error');
});
});
return const Center(child: CircularProgressIndicator());
}
if (provider.isLoading) return const Center(child: CircularProgressIndicator());
if (provider.account == null) { if (provider.account == null) {
WidgetsBinding.instance.addPostFrameCallback((_) => navigateAndReplace(context, Pages.login)); WidgetsBinding.instance.addPostFrameCallback((_) => navigateAndReplace(context, Pages.login));
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());