small fixes
This commit is contained in:
@@ -15,19 +15,9 @@ class EmailVerificationProvider extends ChangeNotifier {
|
||||
Exception? get error => _resource.error;
|
||||
ErrorResponse? get errorResponse =>
|
||||
_resource.error is ErrorResponse ? _resource.error as ErrorResponse : null;
|
||||
bool get canResendVerification {
|
||||
final err = errorResponse;
|
||||
if (err == null) return false;
|
||||
switch (err.error) {
|
||||
case 'not_found':
|
||||
case 'token_expired':
|
||||
case 'data_conflict':
|
||||
case 'internal_error':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
int? get errorCode => errorResponse?.code;
|
||||
bool get canResendVerification =>
|
||||
errorCode == 400 || errorCode == 410 || errorCode == 500;
|
||||
|
||||
Future<void> verify(String token) async {
|
||||
final trimmed = token.trim();
|
||||
|
||||
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
import 'package:pshared/config/constants.dart';
|
||||
import 'package:pshared/models/organization/organization.dart';
|
||||
import 'package:pshared/provider/resource.dart';
|
||||
@@ -88,4 +90,55 @@ class OrganizationsProvider extends ChangeNotifier {
|
||||
// Best-effort cleanup of stored selection to avoid using stale org on next login.
|
||||
await SecureStorageService.delete(Constants.currentOrgKey);
|
||||
}
|
||||
|
||||
Future<Organization> uploadLogo(XFile logoFile) async {
|
||||
if (!isOrganizationSet) {
|
||||
throw StateError('Organization is not set');
|
||||
}
|
||||
|
||||
_setResource(_resource.copyWith(isLoading: true, error: null));
|
||||
try {
|
||||
final updated = await OrganizationService.uploadLogoAndUpdate(current, logoFile);
|
||||
final updatedList = organizations
|
||||
.map((org) => org.id == updated.id ? updated : org)
|
||||
.toList(growable: false);
|
||||
_setResource(Resource(data: updatedList, isLoading: false));
|
||||
_currentOrg = updated.id;
|
||||
return updated;
|
||||
} catch (e) {
|
||||
_setResource(_resource.copyWith(isLoading: false, error: toException(e)));
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<Organization> updateCurrent({
|
||||
String? name,
|
||||
String? description,
|
||||
String? timeZone,
|
||||
String? logoUrl,
|
||||
}) async {
|
||||
if (!isOrganizationSet) {
|
||||
throw StateError('Organization is not set');
|
||||
}
|
||||
|
||||
_setResource(_resource.copyWith(isLoading: true, error: null));
|
||||
try {
|
||||
final updated = await OrganizationService.updateSettings(
|
||||
current,
|
||||
name: name,
|
||||
description: description,
|
||||
timeZone: timeZone,
|
||||
logoUrl: logoUrl,
|
||||
);
|
||||
final updatedList = organizations
|
||||
.map((org) => org.id == updated.id ? updated : org)
|
||||
.toList(growable: false);
|
||||
_setResource(Resource(data: updatedList, isLoading: false));
|
||||
_currentOrg = updated.id;
|
||||
return updated;
|
||||
} catch (e) {
|
||||
_setResource(_resource.copyWith(isLoading: false, error: toException(e)));
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
import 'package:uuid/uuid.dart';
|
||||
@@ -23,9 +21,6 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
List<PaymentIntent>? _lastIntents;
|
||||
bool _lastPreviewOnly = false;
|
||||
Map<String, String>? _lastMetadata;
|
||||
Timer? _autoRefreshTimer;
|
||||
|
||||
static const Duration _autoRefreshLead = Duration(seconds: 5);
|
||||
|
||||
Resource<PaymentQuotes> get resource => _quotation;
|
||||
PaymentQuotes? get quotation => _quotation.data;
|
||||
@@ -86,7 +81,6 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
? null
|
||||
: Map<String, String>.from(metadata);
|
||||
|
||||
_cancelAutoRefresh();
|
||||
_setResource(_quotation.copyWith(isLoading: true, error: null));
|
||||
try {
|
||||
final response = await MultiplePaymentsService.getQuotation(
|
||||
@@ -102,7 +96,6 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
_setResource(
|
||||
_quotation.copyWith(data: response, isLoading: false, error: null),
|
||||
);
|
||||
_scheduleAutoRefresh();
|
||||
} catch (e) {
|
||||
_setResource(
|
||||
_quotation.copyWith(
|
||||
@@ -131,7 +124,6 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
_lastIntents = null;
|
||||
_lastPreviewOnly = false;
|
||||
_lastMetadata = null;
|
||||
_cancelAutoRefresh();
|
||||
_quotation = Resource(data: null);
|
||||
notifyListeners();
|
||||
}
|
||||
@@ -141,36 +133,8 @@ class MultiQuotationProvider extends ChangeNotifier {
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
void _scheduleAutoRefresh() {
|
||||
_autoRefreshTimer?.cancel();
|
||||
final expiresAt = quoteExpiresAt;
|
||||
if (expiresAt == null) return;
|
||||
|
||||
final now = DateTime.now().toUtc();
|
||||
var delay = expiresAt.difference(now) - _autoRefreshLead;
|
||||
if (delay.isNegative) delay = Duration.zero;
|
||||
_autoRefreshTimer = Timer(delay, _triggerAutoRefresh);
|
||||
}
|
||||
|
||||
Future<void> _triggerAutoRefresh() async {
|
||||
if (_quotation.isLoading) return;
|
||||
final intents = _lastIntents;
|
||||
if (intents == null || intents.isEmpty) return;
|
||||
await quotePayments(
|
||||
intents,
|
||||
previewOnly: _lastPreviewOnly,
|
||||
metadata: _lastMetadata,
|
||||
);
|
||||
}
|
||||
|
||||
void _cancelAutoRefresh() {
|
||||
_autoRefreshTimer?.cancel();
|
||||
_autoRefreshTimer = null;
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_cancelAutoRefresh();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user