import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../modules/kr_home/views/hi_subscription_corner_button.dart'; import 'package:kaer_with_panels/main.dart'; import 'package:kaer_with_panels/app/widgets/kr_local_image.dart'; class GlobalOverlayService extends GetxService { Color? _currentColor; static GlobalOverlayService get instance => Get.find(); VoidCallback? _subscriptionAnimationTrigger; void registerAnimationTrigger(VoidCallback trigger) { _subscriptionAnimationTrigger = trigger; } /// 触发按钮动画跳转购买页 void triggerSubscriptionAnimation() { if (_subscriptionAnimationTrigger != null) { _subscriptionAnimationTrigger!.call(); } else { print('🔥 Subscription animation trigger not registered yet'); } } OverlayEntry? _overlayEntry; final RxBool _isVisible = false.obs; bool get isVisible => _isVisible.value; @override void onInit() { super.onInit(); print('🔥 GlobalOverlayService: Service initialized'); } void showSubscriptionButton([OverlayState? overlay]) { if (_isVisible.value) return; WidgetsBinding.instance.addPostFrameCallback((_) { _doShowSubscriptionButton(overlay); }); } void _doShowSubscriptionButton([OverlayState? overlay, Color? color]) { print('🔥 _doShowSubscriptionButton called, overlay=$overlay'); if (_isVisible.value) return; try { overlay ??= navigatorKey.currentState?.overlay; if (overlay == null) { print('🔥 GlobalOverlayService: No overlay found, cannot show subscription button'); return; } _overlayEntry = OverlayEntry( builder: (context) { final statusBarHeight = MediaQuery.of(context).padding.top < 62 ? 62 : MediaQuery.of(context).padding.top; final double radius = 40.0 + statusBarHeight; final double diameter = radius * 2; return Stack( children: [ // 1️⃣ 圆背景,保持原来位置 Positioned( top: -(diameter - (radius + statusBarHeight)), right: -(radius - (statusBarHeight / 2)), width: diameter, height: diameter, child: HISubscriptionCornerButton( size: diameter, color: _currentColor ?? Theme.of(context).primaryColor, topOffset: -radius, rightOffset: -radius, ), ), // 2️⃣ money-icon,独立定位,固定在屏幕右上角 Positioned( top: MediaQuery.of(context).padding.top + 8, right: (radius - (statusBarHeight / 2)) / 2, child: GestureDetector( behavior: HitTestBehavior.translucent, // 让区域可响应点击 onTap: () { // ✅ 这里“代理”点击事件,转发到底层按钮动画逻辑 print('🔥 money-icon tapped → trigger HISubscriptionCornerButton animation'); GlobalOverlayService.instance.triggerSubscriptionAnimation(); }, child: IgnorePointer( ignoring: false, // 不阻断事件 child: SizedBox( width: 44, height: 44, child: KrLocalImage( imageName: 'money-icon', width: 44, height: 44, imageType: ImageType.svg, ), ), ), ), ), ], ); }, ); overlay.insert(_overlayEntry!); _isVisible.value = true; print('🔥 GlobalOverlayService: Subscription button shown successfully'); } catch (e) { print('🔥 GlobalOverlayService: Error showing subscription button: $e'); } } void hideSubscriptionButton() { if (!_isVisible.value) return; _overlayEntry?.remove(); _overlayEntry = null; _isVisible.value = false; } void toggleSubscriptionButton() { if (_isVisible.value) { hideSubscriptionButton(); } else { showSubscriptionButton(); } } void safeShowSubscriptionButton() { void _attemptShow() { final overlay = navigatorKey.currentState?.overlay; if (overlay == null) { print('🔥 Overlay not ready, retrying...'); Future.delayed(const Duration(milliseconds: 200), _attemptShow); return; } WidgetsBinding.instance.addPostFrameCallback((_) { print('🔥 Overlay ready, inserting subscription button'); showSubscriptionButton(overlay); }); } _attemptShow(); } void updateSubscriptionButtonColor(Color? color) { if (_overlayEntry == null) { print('🔥 updateSubscriptionButtonColor: OverlayEntry is null'); return; } _currentColor = color; _overlayEntry!.markNeedsBuild(); // 🔥 强制刷新 UI } void forceShowSubscriptionButton() { print('🔥 GlobalOverlayService: Force showing subscription button'); hideSubscriptionButton(); Future.delayed(const Duration(milliseconds: 100), () { safeShowSubscriptionButton(); }); } @override void onClose() { hideSubscriptionButton(); super.onClose(); } }