169 lines
5.1 KiB
Dart
169 lines
5.1 KiB
Dart
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<GlobalOverlayService>();
|
||
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: KrLocalImage(
|
||
imageName: 'money-icon',
|
||
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();
|
||
}
|
||
}
|