Bug Fixes
parent
6c71c2095e
commit
dfbf5069f2
@ -0,0 +1,64 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:app_links/app_links.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:mc_common_app/config/routes.dart';
|
||||||
|
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
||||||
|
import 'package:mc_common_app/utils/navigator.dart';
|
||||||
|
import 'package:mc_common_app/utils/utils.dart';
|
||||||
|
import 'package:mc_common_app/view_models/ad_view_model.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
|
/// Handles opening the ad detail screen directly when the app is launched or
|
||||||
|
/// resumed via a shared ad link (e.g. https://ms.hmg.com/ad/1541), for both
|
||||||
|
/// Android App Links and iOS Universal Links.
|
||||||
|
class AdDeepLinkService {
|
||||||
|
static final AppLinks _appLinks = AppLinks();
|
||||||
|
static StreamSubscription<Uri>? _subscription;
|
||||||
|
|
||||||
|
/// Call once, after the app's first frame (so [navigatorKey] is attached to a Navigator).
|
||||||
|
static Future<void> init() async {
|
||||||
|
try {
|
||||||
|
final Uri? initialUri = await _appLinks.getInitialLink();
|
||||||
|
if (initialUri != null) {
|
||||||
|
_handleUri(initialUri);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
log("AdDeepLinkService: failed to read initial link - $e");
|
||||||
|
}
|
||||||
|
|
||||||
|
_subscription?.cancel();
|
||||||
|
_subscription = _appLinks.uriLinkStream.listen(
|
||||||
|
_handleUri,
|
||||||
|
onError: (Object e) => log("AdDeepLinkService: stream error - $e"),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _handleUri(Uri uri) {
|
||||||
|
log("AdDeepLinkService: received $uri");
|
||||||
|
final segments = uri.pathSegments;
|
||||||
|
if (segments.length < 2 || segments[0] != 'ad') return;
|
||||||
|
|
||||||
|
final int? adId = int.tryParse(segments[1]);
|
||||||
|
if (adId == null) return;
|
||||||
|
|
||||||
|
_openAd(adId);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<void> _openAd(int adId) async {
|
||||||
|
final context = navigatorKey.currentContext;
|
||||||
|
if (context == null) return;
|
||||||
|
|
||||||
|
Utils.showLoading(context);
|
||||||
|
final adDetails = await context.read<AdVM>().getAdDetailsById(adId);
|
||||||
|
Utils.hideLoading(context);
|
||||||
|
|
||||||
|
if (adDetails == null) {
|
||||||
|
Utils.showToast(LocaleKeys.somethingWrong.tr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
navigateWithName(context, AppRoutes.adsDetailView, arguments: adDetails);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,46 @@
|
|||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
|
import 'package:easy_localization/easy_localization.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:mc_common_app/extensions/int_extensions.dart';
|
||||||
|
import 'package:mc_common_app/extensions/string_extensions.dart';
|
||||||
|
import 'package:mc_common_app/generated/locale_keys.g.dart';
|
||||||
|
import 'package:mc_common_app/models/advertisment_models/ad_details_model.dart';
|
||||||
|
import 'package:mc_common_app/widgets/extensions/extensions_widget.dart';
|
||||||
|
|
||||||
|
class AdQrCodeSheet extends StatelessWidget {
|
||||||
|
final AdDetailsModel adDetails;
|
||||||
|
|
||||||
|
const AdQrCodeSheet({super.key, required this.adDetails});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
log("dDetails.qrCodePath: ${adDetails.qrCodePath}");
|
||||||
|
return SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
LocaleKeys.qrCode.tr().toText(fontSize: 24, isBold: true),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
20.height,
|
||||||
|
SizedBox(
|
||||||
|
height: 220,
|
||||||
|
width: 220,
|
||||||
|
child: CachedNetworkImage(
|
||||||
|
imageUrl: "${adDetails.qrCodePath}",
|
||||||
|
placeholder: (context, url) => const Center(child: CircularProgressIndicator()),
|
||||||
|
errorWidget: (context, url, error) => const Icon(Icons.error),
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
20.height,
|
||||||
|
],
|
||||||
|
),
|
||||||
|
).horPaddingMain();
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue