Skip to content

Commit fc57247

Browse files
committed
fix(ui): pre-load ShopInBit payment info instead of in-page spinner overlay
1 parent 574392a commit fc57247

6 files changed

Lines changed: 143 additions & 162 deletions

File tree

lib/pages/shopinbit/shopinbit_offer_view.dart

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import '../../widgets/desktop/desktop_dialog_close_button.dart';
1313
import '../../widgets/desktop/primary_button.dart';
1414
import '../../widgets/desktop/secondary_button.dart';
1515
import '../../widgets/dialogs/s_dialog.dart';
16-
import '../../widgets/loading_indicator.dart';
1716
import '../../widgets/rounded_white_container.dart';
1817
import 'shopinbit_shipping_view.dart';
1918

@@ -195,13 +194,7 @@ class _ShopInBitOfferViewState extends ConsumerState<ShopInBitOfferView> {
195194
bottom: 32,
196195
top: 16,
197196
),
198-
child: Stack(
199-
children: [
200-
content,
201-
if (_loading)
202-
const LoadingIndicator(width: 24, height: 24),
203-
],
204-
),
197+
child: content,
205198
),
206199
),
207200
],
@@ -222,21 +215,16 @@ class _ShopInBitOfferViewState extends ConsumerState<ShopInBitOfferView> {
222215
body: SafeArea(
223216
child: LayoutBuilder(
224217
builder: (context, constraints) {
225-
return Stack(
226-
children: [
227-
Padding(
228-
padding: const EdgeInsets.all(16),
229-
child: SingleChildScrollView(
230-
child: ConstrainedBox(
231-
constraints: BoxConstraints(
232-
minHeight: constraints.maxHeight - 32,
233-
),
234-
child: IntrinsicHeight(child: content),
235-
),
218+
return Padding(
219+
padding: const EdgeInsets.all(16),
220+
child: SingleChildScrollView(
221+
child: ConstrainedBox(
222+
constraints: BoxConstraints(
223+
minHeight: constraints.maxHeight - 32,
236224
),
225+
child: IntrinsicHeight(child: content),
237226
),
238-
if (_loading) const LoadingIndicator(width: 24, height: 24),
239-
],
227+
),
240228
);
241229
},
242230
),

lib/pages/shopinbit/shopinbit_payment_shared.dart

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
55
import '../../app_config.dart';
66
import '../../models/isar/models/ethereum/eth_contract.dart';
77
import '../../models/shopinbit/shopinbit_order_model.dart';
8+
import '../../providers/global/shopin_bit_service_provider.dart';
89
import '../../providers/providers.dart';
910
import '../../route_generator.dart';
11+
import '../../services/shopinbit/src/models/payment.dart';
1012
import '../../services/wallets.dart';
1113
import '../../themes/stack_colors.dart';
1214
import '../../utilities/address_utils.dart';
@@ -17,7 +19,6 @@ import '../../utilities/util.dart';
1719
import '../../wallets/crypto_currency/crypto_currency.dart';
1820
import '../../widgets/background.dart';
1921
import '../../widgets/custom_buttons/app_bar_icon_button.dart';
20-
import '../../widgets/loading_indicator.dart';
2122
import 'shopinbit_send_from_view.dart';
2223

2324
final String kShopInBitUsdtContractAddress = DefaultTokens.list
@@ -223,20 +224,45 @@ Future<bool> tryNavigateToShopInBitWalletSend({
223224
return false;
224225
}
225226

227+
// Fetches the live payment info for a ticket so the caller can pass it into
228+
// the payment view as an arg (rather than loading it after the view is up).
229+
// GET first to reuse an existing invoice per the spec's "page reload
230+
// recovery" guidance; PUT (which regenerates) only when GET shows none.
231+
// Returns null on any failure so the view can fall back to polling.
232+
Future<PaymentInfo?> fetchShopInBitPaymentInfo(
233+
WidgetRef ref,
234+
int apiTicketId,
235+
) async {
236+
try {
237+
final client = ref.read(pShopinBitService).client;
238+
final getResp = await client.getPayment(apiTicketId);
239+
if (!getResp.hasError &&
240+
getResp.value != null &&
241+
getResp.value!.paymentLinks.isNotEmpty) {
242+
return getResp.value;
243+
}
244+
final putResp = await client.putPayment(apiTicketId);
245+
if (!putResp.hasError && putResp.value != null) {
246+
return putResp.value;
247+
}
248+
} catch (_) {
249+
// Degrade to polling-only.
250+
}
251+
return null;
252+
}
253+
226254
// Shared mobile chrome for the two ShopInBit payment views: Background +
227255
// PopScope (back goes through [onBack]) + AppBar + scrollable, intrinsic
228-
// height body. Set [showLoading] to overlay a spinner.
256+
// height body.
229257
class ShopInBitPaymentMobileScaffold extends StatelessWidget {
230258
const ShopInBitPaymentMobileScaffold({
231259
super.key,
232260
required this.onBack,
233261
required this.child,
234-
this.showLoading = false,
235262
});
236263

237264
final VoidCallback onBack;
238265
final Widget child;
239-
final bool showLoading;
240266

241267
@override
242268
Widget build(BuildContext context) {
@@ -259,22 +285,16 @@ class ShopInBitPaymentMobileScaffold extends StatelessWidget {
259285
body: SafeArea(
260286
child: LayoutBuilder(
261287
builder: (context, constraints) {
262-
return Stack(
263-
children: [
264-
Padding(
265-
padding: const EdgeInsets.all(16),
266-
child: SingleChildScrollView(
267-
child: ConstrainedBox(
268-
constraints: BoxConstraints(
269-
minHeight: constraints.maxHeight - 32,
270-
),
271-
child: IntrinsicHeight(child: child),
272-
),
288+
return Padding(
289+
padding: const EdgeInsets.all(16),
290+
child: SingleChildScrollView(
291+
child: ConstrainedBox(
292+
constraints: BoxConstraints(
293+
minHeight: constraints.maxHeight - 32,
273294
),
295+
child: IntrinsicHeight(child: child),
274296
),
275-
if (showLoading)
276-
const LoadingIndicator(width: 24, height: 24),
277-
],
297+
),
278298
);
279299
},
280300
),

0 commit comments

Comments
 (0)