FunyMeeAI/lib/app.dart
2026-04-14 15:25:53 +08:00

165 lines
4.8 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:async';
import 'package:client_proxy_framework/client_proxy_framework.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import 'core/auth/auth_service.dart';
import 'core/theme/app_colors.dart';
import 'core/theme/app_theme.dart';
import 'features/shell/main_screen.dart';
class App extends StatefulWidget {
const App({super.key, required this.title});
final String title;
@override
State<App> createState() => _AppState();
}
class _AppState extends State<App> with WidgetsBindingObserver {
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
WidgetsBinding.instance.addPostFrameCallback((_) {
_reportFacebookActivateApp('first_frame');
});
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
/// 与 app_client 一致:关闭 FB 自动 App Events 时手动 [FacebookService.activateApp]。
void _reportFacebookActivateApp(String reason) {
FacebookService.activateApp();
if (kDebugMode) {
debugPrint('[App] Facebook activateApp ($reason)');
}
}
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
_reportFacebookActivateApp('lifecycle_resumed');
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
title: widget.title,
debugShowCheckedModeBanner: false,
theme: buildFunyMeeTheme(),
home: const MainScreen(),
builder: (context, child) {
return Stack(
fit: StackFit.expand,
children: [
SafeArea(
top: false,
left: false,
right: false,
bottom: false,
child: child ?? const SizedBox.shrink(),
),
ValueListenableBuilder<bool>(
valueListenable: AuthService.isLoginComplete,
builder: (context, done, _) {
if (done) return const SizedBox.shrink();
return const _StartupLoginOverlay();
},
),
],
);
},
);
}
}
/// 对齐 app_client首帧即进入壳层登录完成前遮罩 + 久等网络提示。
class _StartupLoginOverlay extends StatefulWidget {
const _StartupLoginOverlay();
@override
State<_StartupLoginOverlay> createState() => _StartupLoginOverlayState();
}
class _StartupLoginOverlayState extends State<_StartupLoginOverlay> {
static const _longWaitAfter = Duration(seconds: 22);
Timer? _longWaitTimer;
bool _showNetworkHint = false;
@override
void initState() {
super.initState();
_longWaitTimer = Timer(_longWaitAfter, () {
if (mounted) setState(() => _showNetworkHint = true);
});
}
@override
void dispose() {
_longWaitTimer?.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Positioned.fill(
child: AbsorbPointer(
child: Container(
color: Colors.black.withValues(alpha: 0.22),
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 28),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const CircularProgressIndicator(color: AppColors.primary),
const SizedBox(height: 16),
Text(
'Signing in…',
style: GoogleFonts.inter(
color: Colors.white.withValues(alpha: 0.92),
fontSize: 15,
fontWeight: FontWeight.w600,
),
),
if (_showNetworkHint) ...[
const SizedBox(height: 22),
Text(
'Network is slow or unavailable',
textAlign: TextAlign.center,
style: GoogleFonts.inter(
color: Colors.white.withValues(alpha: 0.96),
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
const SizedBox(height: 10),
Text(
'Check WiFi or mobile data. If the connection is fine, the server may be busy—try again shortly.',
textAlign: TextAlign.center,
style: GoogleFonts.inter(
color: Colors.white.withValues(alpha: 0.78),
fontSize: 14,
height: 1.4,
),
),
],
],
),
),
),
),
),
);
}
}