58 lines
2.1 KiB
Dart
58 lines
2.1 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
import '../../../common/router/app_router.dart';
|
|
import '../data/ads_api_client.dart';
|
|
import '../presentation/splash_ad_dialog.dart';
|
|
import 'splash_ad_controller.dart';
|
|
|
|
final startupAdResolvedProvider = StateProvider<bool>((_) => false);
|
|
|
|
abstract final class StartupAdService {
|
|
static Future<void>? _running;
|
|
static Future<void> showIfAvailable(BuildContext context, WidgetRef ref) =>
|
|
_running ??= _show(context, ref);
|
|
static Future<void> _show(BuildContext context, WidgetRef ref) async {
|
|
final controller = ref.read(splashAdControllerProvider);
|
|
try {
|
|
final entry = await controller.coldLaunchDecision();
|
|
if (entry != null && context.mounted) {
|
|
final result = await showGeneralDialog<SplashAdResult>(
|
|
context: context,
|
|
useRootNavigator: true,
|
|
barrierDismissible: false,
|
|
barrierColor: Colors.black,
|
|
pageBuilder: (ctx, _, _) => SplashAdDialog(
|
|
entry: entry,
|
|
onShown: () => unawaited(controller.markShown(entry)),
|
|
onClick: () async {
|
|
final id = ref.read(adsApiClientProvider).newClickId();
|
|
final uri = entry.ad.clickUri(id);
|
|
if (uri != null) {
|
|
unawaited(
|
|
ref
|
|
.read(adsApiClientProvider)
|
|
.report(entry.ad, 'ad_click', clickId: id),
|
|
);
|
|
if (entry.ad.openMode == AdOpenMode.inApp) {
|
|
context.push(
|
|
'${AppRoutes.web}?url=${Uri.encodeComponent(uri.toString())}',
|
|
);
|
|
} else {
|
|
await launchUrl(uri, mode: LaunchMode.externalApplication);
|
|
}
|
|
}
|
|
},
|
|
),
|
|
);
|
|
if (result == SplashAdResult.skipped) unawaited(controller.skip(entry));
|
|
}
|
|
} finally {
|
|
ref.read(startupAdResolvedProvider.notifier).state = true;
|
|
unawaited(controller.refresh());
|
|
}
|
|
}
|
|
}
|