second commit

This commit is contained in:
Anbarasu
2026-05-27 10:35:09 +05:30
parent c53794c04c
commit 1435ac47b0
501 changed files with 52818 additions and 0 deletions

426
lib/mainlive.dart Normal file
View File

@@ -0,0 +1,426 @@
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:new_version_plus/new_version_plus.dart';
import 'package:http/http.dart' as http;
import 'Controller/Internetcheck/check_internet.dart';
import 'Globalwidgets/Localnotificationservice.dart';
import 'Globalwidgets/binding.dart';
import 'Helper/Constants/Apiconstants.dart';
import 'Helper/Constants/Colorconstants.dart';
import 'Helper/Constants/api_config.dart';
import 'Helper/Logger.dart';
import 'Helper/Locationservice/app_config_service.dart';
import 'View/Home/Homeview.dart';
import 'View/Introscreen/Introscreenview.dart';
import 'View/Update/Updateview.dart';
/// ---------------------------------------------------------------------------
/// 1. GLOBAL NOTIFICATION OBJECTS
/// ---------------------------------------------------------------------------
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
final AndroidNotificationChannel channel = AndroidNotificationChannel(
'Nearlexpress Business', // id
'Nearlexpress Business Notifications', // name
description: 'Nearlexpress Business',
importance: Importance.high,
sound: const RawResourceAndroidNotificationSound('ring'), // raw/ring.mp3
enableLights: true,
enableVibration: true,
playSound: true,
showBadge: true,
vibrationPattern: Int64List.fromList(const [500, 1000, 500]),
);
/// ---------------------------------------------------------------------------
/// 2. BACKGROUND MESSAGE HANDLER (must be top-level)
/// ---------------------------------------------------------------------------
@pragma('vm:entry-point')
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
// Initialize local notifications in background isolate
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('@mipmap/ic_launcher');
const DarwinInitializationSettings initializationSettingsIOS =
DarwinInitializationSettings();
const InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
);
await flutterLocalNotificationsPlugin.initialize(initializationSettings);
// Create notification channel
final AndroidNotificationChannel channel = AndroidNotificationChannel(
'Nearlexpress Business',
'Nearlexpress Business Notifications',
description: 'Nearlexpress Business',
importance: Importance.high,
sound: const RawResourceAndroidNotificationSound('ring'),
playSound: true,
enableVibration: true,
vibrationPattern: Int64List.fromList(const [500, 1000, 500]),
);
final androidPlugin = flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<AndroidFlutterLocalNotificationsPlugin>();
await androidPlugin?.createNotificationChannel(channel);
// === LOAD LOGO FROM ASSETS IN BACKGROUND ===
final ByteData logoData = await rootBundle.load('assets/images/nearlebusiness.png');
final Uint8List logoBytes = logoData.buffer.asUint8List();
// Show notification if it has title/body
if (message.notification != null) {
await flutterLocalNotificationsPlugin.show(
message.hashCode,
message.notification!.title,
message.notification!.body,
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
importance: Importance.high,
priority: Priority.high,
icon: '@mipmap/ic_launcher',
sound: const RawResourceAndroidNotificationSound('ring'),
enableVibration: true,
vibrationPattern: Int64List.fromList([500, 1000, 500]),
playSound: true,
color: const Color(0xFF662582),
largeIcon: ByteArrayAndroidBitmap(logoBytes), // LOGO ON RIGHT
styleInformation: BigPictureStyleInformation(
ByteArrayAndroidBitmap(logoBytes),
largeIcon: ByteArrayAndroidBitmap(logoBytes),
contentTitle: message.notification!.title,
htmlFormatContentTitle: true,
),
),
iOS: const DarwinNotificationDetails(
sound: 'ring.wav',
),
),
payload: jsonEncode(message.data.isNotEmpty ? message.data : {
"type": message.notification?.android?.tag ?? ""
}),
);
}
}
/// ---------------------------------------------------------------------------
/// 3. LOCAL NOTIFICATION HELPER (foreground + background)
/// ---------------------------------------------------------------------------
Future<void> _showLocalNotification(RemoteMessage message) async {
final notification = message.notification;
if (notification == null) return;
// === LOAD LOGO FROM ASSETS ===
final ByteData logoData = await rootBundle.load('assets/images/nearle_logo.jpeg');
final Uint8List logoBytes = logoData.buffer.asUint8List();
final AndroidNotificationDetails androidDetails = AndroidNotificationDetails(
channel.id,
channel.name,
channelDescription: channel.description,
importance: channel.importance,
priority: Priority.high,
sound: channel.sound,
enableVibration: channel.enableVibration,
vibrationPattern: channel.vibrationPattern,
playSound: channel.playSound,
enableLights: channel.enableLights,
icon: '@mipmap/ic_launcher',
color: const Color(0xFF662582),
largeIcon: ByteArrayAndroidBitmap(logoBytes), // LOGO ON RIGHT
styleInformation: BigPictureStyleInformation(
ByteArrayAndroidBitmap(logoBytes),
largeIcon: ByteArrayAndroidBitmap(logoBytes),
contentTitle: notification.title,
summaryText: notification.body,
htmlFormatContentTitle: true,
htmlFormatSummaryText: true,
),
);
const DarwinNotificationDetails iOSDetails = DarwinNotificationDetails(
sound: 'ring.mp3',
presentAlert: true,
presentBadge: true,
presentSound: true,
);
final NotificationDetails platformDetails =
NotificationDetails(android: androidDetails, iOS: iOSDetails);
await flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
platformDetails,
payload: jsonEncode(message.data.isNotEmpty ? message.data : {
"type": message.notification?.android?.tag ?? ""
}),
);
}
/// ---------------------------------------------------------------------------
/// 4. NOTIFICATION TAP HANDLER
/// ---------------------------------------------------------------------------
void _handleNotificationTap(Map<String, dynamic> data) {
final type = data['type']?.toString();
print('Notification tapped type: $type');
if (type == 'tojoin') {
Get.toNamed('/join');
}
}
/// ---------------------------------------------------------------------------
/// 5. HTTP OVERRIDE (dev only remove in production)
/// ---------------------------------------------------------------------------
class MyHttpOverrides extends HttpOverrides {
@override
HttpClient createHttpClient(SecurityContext? context) {
return super.createHttpClient(context)
..badCertificateCallback = (cert, host, port) => true;
}
}
/// ---------------------------------------------------------------------------
/// 6. MAIN
/// ---------------------------------------------------------------------------
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent, // or your color
statusBarIconBrightness: Brightness.dark, // Android icons
statusBarBrightness: Brightness.light, // iOS icons
),
);
// Allow self-signed certs (dev only)
HttpOverrides.global = MyHttpOverrides();
await Firebase.initializeApp();
// ---------- LOCAL NOTIFICATIONS INITIALISATION ----------
const AndroidInitializationSettings androidInit =
AndroidInitializationSettings('@mipmap/ic_launcher');
const DarwinInitializationSettings iOSInit = DarwinInitializationSettings(
requestAlertPermission: true,
requestBadgePermission: true,
requestSoundPermission: true,
);
const InitializationSettings initSettings =
InitializationSettings(android: androidInit, iOS: iOSInit);
await flutterLocalNotificationsPlugin.initialize(
initSettings,
);
// Create Android channel (mandatory for Android 8+)
final androidPlugin = flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>();
await androidPlugin?.createNotificationChannel(channel);
// ---------- FCM ----------
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
DeviceOrientation.portraitDown,
]);
ApiConfig.setLive(); // 👈 clean call
// Dependency injection
Get.put(ConnectivityController());
runApp(const MyApp());
}
/// ---------------------------------------------------------------------------
/// 7. APP WIDGET
/// ---------------------------------------------------------------------------
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Nearlexpress Business',
debugShowCheckedModeBanner: false,
initialBinding: GlobalBinding(),
navigatorKey: MyHomePageOne.mNavigationState,
theme: ThemeData(
primaryColor: ColorConstants.primaryColor,
useMaterial3: false,
scaffoldBackgroundColor: Colors.grey.shade200,
appBarTheme: AppBarTheme(
iconTheme:
IconThemeData(color: ColorConstants.secondaryColor),
color: ColorConstants.secondaryColor,
elevation: 0,
titleTextStyle: TextStyle(
color: ColorConstants.secondaryColor,
fontSize: 18,
),
),
fontFamily: 'Lato',
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const SafeArea(top: false, child: MyHomePageOne()),
);
}
}
/// ---------------------------------------------------------------------------
/// 8. HOME PAGE (FCM + UI logic)
/// ---------------------------------------------------------------------------
class MyHomePageOne extends StatefulWidget {
static final GlobalKey<NavigatorState> mNavigationState =
GlobalKey<NavigatorState>();
const MyHomePageOne({Key? key}) : super(key: key);
@override
State<MyHomePageOne> createState() => _MyHomePageOneState();
}
class _MyHomePageOneState extends State<MyHomePageOne> {
final AppConfigurationService _appConfig = AppConfigurationService();
String? _tenantFcmToken;
String? _tenantContact;
int? _moduleId;
int? _tenantId;
@override
void initState() {
super.initState();
_initApp();
}
Future<void> _initApp() async {
await _loadPrefs();
await _setupFCM();
await _getAppVersion();
_checkForUpdate(context);
_fetchLocation();
_appConfig.getAppConfig("${ApiConstants.configUrl}?configid=1");
LocalNotificationService.initialize(context);
}
Future<void> _loadPrefs() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_tenantFcmToken = prefs.getString('tenantFcmToken');
_tenantContact = prefs.getString('tenantContactNo');
_moduleId = prefs.getInt('moduleId');
_tenantId = prefs.getInt('tenantId');
});
}
Future<void> _setupFCM() async {
final settings = await FirebaseMessaging.instance.requestPermission(
alert: true,
badge: true,
sound: true,
);
print('FCM permission: ${settings.authorizationStatus}');
final token = await FirebaseMessaging.instance.getToken();
print('=== FCM TOKEN ===\n$token\n=================');
final prefs = await SharedPreferences.getInstance();
await prefs.setString('fcmToken', token!);
FirebaseMessaging.onMessage.listen((RemoteMessage msg) async {
print('FOREGROUND: ${msg.notification?.title}');
await _showLocalNotification(msg);
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage msg) {
print('OPENED FROM NOTIFICATION');
_handleNotificationTap(msg.data);
});
}
String currentVersion = '';
Future<void> _getAppVersion() async {
final packageInfo = await PackageInfo.fromPlatform();
currentVersion = packageInfo.version;
final prefs = await SharedPreferences.getInstance();
await prefs.setString('CurrentVersion', currentVersion);
logger.i('Current version: $currentVersion');
}
Future<void> _checkForUpdate(BuildContext context) async {
final newVersion = NewVersionPlus(
iOSId: '284882215',
androidId: "com.nearle.bond",
);
final status = await newVersion.getVersionStatus();
if (status != null && status.canUpdate) {
Get.to(() => UpdateAppPage(
mCurrentVersion: status.localVersion,
mUpdateVersion: status.storeVersion,
));
}
}
Future<void> _fetchLocation() async {
final url = Uri.http('ip-api.com', '/json');
try {
final response = await http.get(url);
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
final country = data['countryCode'].toString();
final city = data['city'].toString();
final prefs = await SharedPreferences.getInstance();
await prefs.setString('location_Country', country);
await prefs.setString('MainCity', city);
await prefs.setString('location_CountryCode', country);
}
} catch (e) {
print('Location error: $e');
}
}
@override
Widget build(BuildContext context) {
return (_tenantFcmToken == null && _tenantContact == null)
? IntroScreenView()
: HomeView(selectedIndex: 0);
}
}