- 同步商城 H5 登录态与原生 token - 完善商城/原生 tab 切换、动画及返回交互 - 修复七鱼客服键盘避让和状态栏恢复 - 调整开屏跳过按钮与登录入口交互
103 lines
2.7 KiB
Dart
103 lines
2.7 KiB
Dart
import 'dart:async';
|
|
import 'package:flutter/material.dart';
|
|
|
|
import '../application/splash_ad_controller.dart';
|
|
import 'ad_media.dart';
|
|
|
|
enum SplashAdResult { clicked, skipped, completed }
|
|
|
|
class SplashAdDialog extends StatefulWidget {
|
|
const SplashAdDialog({
|
|
super.key,
|
|
required this.entry,
|
|
required this.onClick,
|
|
required this.onShown,
|
|
});
|
|
final SplashAdEntry entry;
|
|
final Future<void> Function() onClick;
|
|
final VoidCallback onShown;
|
|
@override
|
|
State<SplashAdDialog> createState() => _SplashAdDialogState();
|
|
}
|
|
|
|
class _SplashAdDialogState extends State<SplashAdDialog> {
|
|
Timer? timer;
|
|
late int remain;
|
|
bool opening = false;
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
remain = widget.entry.ad.countdownSeconds.clamp(1, 5);
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
widget.onShown();
|
|
});
|
|
timer = Timer.periodic(const Duration(seconds: 1), (_) {
|
|
if (remain <= 1) {
|
|
Navigator.of(context).pop(SplashAdResult.completed);
|
|
} else if (mounted) {
|
|
setState(() => remain--);
|
|
}
|
|
});
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
timer?.cancel();
|
|
super.dispose();
|
|
}
|
|
|
|
Future<void> open() async {
|
|
if (opening) return;
|
|
opening = true;
|
|
timer?.cancel();
|
|
await widget.onClick();
|
|
if (mounted) Navigator.of(context).pop(SplashAdResult.clicked);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) => Material(
|
|
color: Colors.black,
|
|
child: Stack(
|
|
children: [
|
|
Positioned.fill(
|
|
child: GestureDetector(
|
|
onTap: open,
|
|
child: AdMedia(
|
|
ad: widget.entry.ad,
|
|
assetPath: widget.entry.assetPath,
|
|
),
|
|
),
|
|
),
|
|
Positioned(
|
|
top: MediaQuery.paddingOf(context).top + 16,
|
|
right: 18,
|
|
child: GestureDetector(
|
|
key: const ValueKey('splash-skip'),
|
|
onTap: () => Navigator.of(context).pop(SplashAdResult.skipped),
|
|
child: DecoratedBox(
|
|
decoration: BoxDecoration(
|
|
color: Colors.black.withValues(alpha: 0.62),
|
|
borderRadius: BorderRadius.circular(18),
|
|
),
|
|
child: Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: 14,
|
|
vertical: 7,
|
|
),
|
|
child: Text(
|
|
'跳过 ${remain > 0 ? remain : 0}s',
|
|
style: const TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 13,
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|