TKK_E32230499/lib/main.dart

264 lines
8.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:firebase_database/firebase_database.dart';
import 'package:in_app_notification/in_app_notification.dart';
import 'firebase_options.dart';
import 'service/notification_service.dart';
// IMPORT PAGE
import 'screen/welcome.dart';
import 'screen/login.dart';
import 'screen/register.dart';
import 'screen/dashboard.dart';
import 'screen/pesan.dart';
import 'screen/history.dart';
import 'screen/akun.dart';
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
/// 🔔 HANDLER NOTIFIKASI BACKGROUND
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// Inisialisasi Firebase di background
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
if (message.notification != null) {
String body = message.notification!.body ?? "";
body = body
.replaceAll(RegExp(r'Proses Optimal', caseSensitive: false), 'Belum Matang')
.replaceAll(RegExp(r'Proses Awal', caseSensitive: false), 'Belum Matang')
.replaceAll(RegExp(r'Menjelang Matang', caseSensitive: false), 'Belum Matang');
await NotificationService.showNotification(
message.notification!.title ?? "Notifikasi",
body,
);
}
}
Future<void> main() async {
// 1. Pastikan binding sudah siap
WidgetsFlutterBinding.ensureInitialized();
// 2. Inisialisasi Firebase (Gunakan Try-Catch agar aman)
try {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
} catch (e) {
debugPrint("Firebase init error: $e");
}
// 3. Register Background Handler
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
// 4. Init Local Notification
await NotificationService.init();
// 5. Jalankan Aplikasi Dulu (SANGAT PENTING agar tidak layar hitam)
runApp(const GoTapeApp());
// 6. Jalankan konfigurasi tambahan setelah runApp agar tidak menghambat startup
_initNotification();
}
/// Fungsi tambahan untuk setup notifikasi tanpa menghambat UI
void _initNotification() async {
try {
FirebaseMessaging messaging = FirebaseMessaging.instance;
// Minta Izin
await messaging.requestPermission();
// Ambil & Simpan Token
String? token = await messaging.getToken();
if (token != null) {
// Simpan ke database tanpa await agar tidak nunggu lama
FirebaseDatabase.instance.ref("fcm_token").set(token);
debugPrint("🔥 FCM TOKEN: $token");
}
// Listener Foreground
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
if (message.notification != null) {
String title = message.notification!.title ?? "Notifikasi";
String body = message.notification!.body ?? "";
body = body
.replaceAll(RegExp(r'Proses Optimal', caseSensitive: false), 'Belum Matang')
.replaceAll(RegExp(r'Proses Awal', caseSensitive: false), 'Belum Matang')
.replaceAll(RegExp(r'Menjelang Matang', caseSensitive: false), 'Belum Matang');
NotificationService.showNotification(title, body);
// Tampilkan In-App Notification (Seperti WhatsApp)
final context = navigatorKey.currentContext;
if (context != null) {
InAppNotification.show(
child: _buildWhatsAppStyleNotification(title, body),
context: context,
duration: const Duration(seconds: 4),
curve: Curves.easeOutCubic,
);
}
}
});
// Listener saat notif diklik
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
debugPrint("🔔 User membuka notifikasi");
});
} catch (e) {
debugPrint("Notification Setup Error: $e");
}
}
Widget _buildWhatsAppStyleNotification(String title, String body) {
bool isAlert = title.toLowerCase().contains('berbahaya') || title.toLowerCase().contains('matang');
return SafeArea(
child: Container(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.15),
blurRadius: 15,
offset: const Offset(0, 5),
),
],
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: isAlert ? Colors.redAccent : const Color(0xFF5B35D5),
shape: BoxShape.circle,
),
child: Icon(
isAlert ? Icons.warning_rounded : Icons.notifications_active,
color: Colors.white,
size: 24,
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
title,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 16,
color: isAlert ? Colors.redAccent : Colors.black87,
),
),
const SizedBox(height: 4),
Text(
body,
style: const TextStyle(
color: Colors.black54,
fontSize: 14,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
],
),
),
);
}
class GoTapeApp extends StatelessWidget {
const GoTapeApp({super.key});
@override
Widget build(BuildContext context) {
return InAppNotification(
child: MaterialApp(
navigatorKey: navigatorKey,
debugShowCheckedModeBanner: false,
title: 'GoTape',
theme: ThemeData(
useMaterial3: true,
colorSchemeSeed: const Color(0xFF4DB6AC),
scaffoldBackgroundColor: const Color(0xFFF2F6F6),
appBarTheme: const AppBarTheme(
centerTitle: true,
elevation: 0,
backgroundColor: Colors.transparent,
),
),
// Halaman Utama menggunakan AuthGate
home: const AuthGate(),
// Daftar Route
routes: {
'/welcome': (_) => const WelcomeScreen(),
'/login': (_) => const LoginPage(),
'/register': (_) => const RegisterScreen(),
'/dashboard': (_) => const DashboardPage(),
'/pesan': (_) => const NotificationPage(),
'/riwayat': (_) => const HistoryPage(),
'/akun': (_) => const AkunScreen(),
},
),
);
}
}
class AuthGate extends StatelessWidget {
const AuthGate({super.key});
@override
Widget build(BuildContext context) {
return StreamBuilder<User?>(
stream: FirebaseAuth.instance.authStateChanges(),
builder: (context, snapshot) {
// Jika sedang mengecek status login
if (snapshot.connectionState == ConnectionState.waiting) {
return const Scaffold(
body: Center(
child: CircularProgressIndicator(color: Color(0xFF4DB6AC)),
),
);
}
// Jika terjadi error pada Firebase Auth
if (snapshot.hasError) {
return const Scaffold(
body: Center(
child: Text(
'Terjadi kesalahan autentikasi',
style: TextStyle(color: Colors.red),
),
),
);
}
// Jika user sudah login, lempar ke Dashboard
if (snapshot.hasData && snapshot.data != null) {
return const DashboardPage();
}
// Jika belum login, tampilkan Welcome Screen
return const WelcomeScreen();
},
);
}
}