Код: Выделить всё
void showSnackBar({required String title, required String message, required Color color, duration}) {
Get.snackbar(
title,
message,
backgroundColor: color,
colorText: cWhiteColor,
maxWidth: 400,
duration: Duration(milliseconds: duration ?? 1500),
);
}
например, посмотрите функцию входа в этот файл контроллера:
Код: Выделить всё
Future userLogin() async {
try {
isLoginLoading.value = true;
final authController = Get.find();
Map body = {
'email': emailTextEditingController.text.trim().toString(),
"password": passwordTextEditingController.text.toString(),
};
print("body : $body");
var response = await apiServices.commonApiCall(
url: kuLogin,
body: body,
requestMethod: kPost,
) as CommonDM;
print("Can Login: ${authController.canLogin.value}");
if (response.success == true) {
LoginModel loginData = LoginModel.fromJson(response.data);
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setInt('user_role', loginData.roleId ?? -1);
await prefs.setInt('isPrimary', loginData.isPrimary ?? 0);
await prefs.setInt('client_id', loginData.clientId ?? -1);
String? fcmToken = await FirebaseMessaging.instance.getToken();
if (fcmToken != null) {
authController.fcmToken.value = fcmToken;
await prefs.setString('fcm_token', fcmToken);
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
String deviceType;
String deviceModel;
String osVersion;
if (Platform.isAndroid) {
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
deviceType = 'android';
deviceModel = androidInfo.model;
osVersion = androidInfo.version.release;
} else if (Platform.isIOS) {
IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
deviceType = 'ios';
deviceModel = iosInfo.model;
osVersion = iosInfo.systemVersion;
} else {
deviceType = 'unknown';
deviceModel = 'unknown';
osVersion = 'unknown';
}
authController.clientId.value = loginData.clientId;
authController.userId.value = loginData.id;
authController.deviceType.value = deviceType;
authController.deviceModel.value = deviceModel;
authController.osVersion.value = osVersion;
authController.userName.value = loginData.name;
authController.isPrimary.value = loginData.isPrimary;
Map headers = {
'Content-Type': 'application/json',
};
Map deviceData = {
'client_id': loginData.clientId,
'user_id': loginData.id,
'device_type': deviceType,
'device_model': deviceModel,
'os_version': osVersion,
'fcm_token': fcmToken,
'apns_token': 'dummy_apns_token_for_android',
};
final String url = Environment.apiUrl + kuRegister;
try {
final response = await http.post(
Uri.parse(url),
headers: headers,
body: json.encode(deviceData),
);
print('Response Body: ${response.body}');
if (response.statusCode == 201) {
var responseBody = json.decode(response.body);
if (responseBody['message'] == 'Device registered successfully') {
print("Device data sent successfully!");
print("Device data: ${responseBody['data']}");
} else {
print("Error: ${responseBody['message']}");
}
} else {
print("Failed to add user data. Response: ${response.body}");
}
} catch (e) {
print("Error occurred: $e");
}
} else {
print("❌ Login Failed: ${response.message}");
}
await spController.saveBearerToken(loginData.token);
await spController.saveUserId(loginData.id);
await spController.saveClientId(loginData.clientId);
await spController.saveRememberMe(isStayLoggedInChecked.value);
await spController.saveUserName(loginData.name.toString());
await spController.saveLocation(loginData.location.toString());
await spController.saveUserImage(loginData.profileImage.toString());
await spController.saveUserEmail(loginData.email.toString());
await spController.saveUserPassword(passwordTextEditingController.text.toString());
await spController.saveUserPhone(loginData.phone.toString());
// Save user API key
if (loginData.apiKey != null) {
await spController.saveUserApiKey(loginData.apiKey!);
} else {
print("⚠️ API Key is null in login response");
}
bool? isRememberMe = await spController.getRememberMe();
print("The remember me value for auth is $isRememberMe");
TextInput.finishAutofillContext();
// ⬇️ Added this line to ensure everything is saved/flushed
await Future.delayed(Duration(milliseconds: 50));
// ⬆️
Get.offAllNamed(krHomeScreen);
final RxInt clientId = RxInt(-1);
clientId.value = await spController.getClientId() ?? -1;
if (clientId.value != -1) {
void onEvent(PusherEvent event) async {
print("In onevent");
print("event came: ${event.data.toString()}");
print("The event name is ${event.eventName}");
try {
if (event.eventName == r"App\Events\ReceiveUpcomingMessage") {
if (Get.find().currentRoute.value == "/chat-screen") {
Get.find().getAllMessage();
} else {
print("in else auth");
if (Get.find().isConversationClicked.value) {
await Get.find().chatRoom();
} else {
await Get.find().contactsByClient();
}
}
print("here");
}
} catch (e) {
print(e.toString());
}
}
print("The client id is ${clientId.value}");
final pusherConfig = PusherConfig();
pusherConfig.initPusher(
onEvent,
roomId: clientId.value.toString(),
);
}
isLoginLoading.value = false;
// await Get.find().chatRoom();
// await Get.find().getTeam();
// await Get.find().getTag();
} else {
isLoginLoading.value = false;
showSnackBar(title: ksError.tr, message: "Login Error!", color: cRedColor);
}
} catch (e) {
isLoginLoading.value = false;
print('userLogin error: $e');
}
}
мой main.dart:
Код: Выделить всё
import 'package:salebot_chat/controllers/common/binder_controller.dart';
import 'package:salebot_chat/language/languages.dart';
import 'package:salebot_chat/screens/chat/chat_screen.dart';
import 'package:salebot_chat/utils/constants/imports.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:flutter/foundation.dart';
import 'package:app_links/app_links.dart';
import 'controllers/auth/authentication_controller.dart';
import 'controllers/chat/chat_controller.dart';
import 'controllers/home/home_controller.dart';
import 'services/notification_services.dart';
bool hasHandledInitialNavigation = false;
late final AppLinks _appLinks;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterDownloader.initialize(debug: kDebugMode);
await dotenv.load(fileName: Environment.fileName);
SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
));
try {
await Firebase.initializeApp();
} catch (error) {
print("❌ Firebase initialization failed: $error");
}
FirebaseMessaging.instance.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
NotificationService.initialize();
await NotificationService.createNotificationChannel();
NotificationService.listenToForegroundNotifications();
final initialMessage = await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
print("📩 Initial FCM message found");
NotificationService.handleNotificationTap(initialMessage.data);
}
FirebaseMessaging.onMessageOpenedApp.listen((message) {
print("📲 FCM tapped (onMessageOpenedApp)");
NotificationService.handleNotificationTap(message.data);
});
await _loadRole();
await _loadIsPrimary();
await getClientId();
// ✅ Deep linking setup for wam://chat?phone=...
// print("🔗 Initializing AppLinks...");
_appLinks = AppLinks();
Get.put(ChatController());
Get.put(AuthenticationController());
Get.put(HomeController());
final Uri? initialUri = await _appLinks.getInitialLink();
print("🔗 Initial URI = $initialUri");
// _handleUri(initialUri);
if (initialUri != null) {
hasHandledInitialNavigation = true; // 🔴 Set before splash runs
await _handleUri(initialUri);
}
_appLinks.uriLinkStream.listen((uri) {
_handleUri(uri);
}, onError: (err) => print("❌ Deep link stream error: $err"));
// _appLinks.uriLinkStream.listen(
// (uri) {
// print("📡 URI stream received: $uri");
// _handleUri(uri);
// },
// onError: (err) => print("❌ Deep link stream error: $err"),
// );
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp])
.then((_) => runApp(const MyApp()));
}
Future _loadRole() async {
final prefs = await SharedPreferences.getInstance();
final savedRoleId = prefs.getInt('user_role');
print(savedRoleId != null && savedRoleId != -1
? "👤 User Role ID: $savedRoleId"
: "⚠️ No role found, user may not be logged in.");
}
Future _loadIsPrimary() async {
final prefs = await SharedPreferences.getInstance();
final savedPrimaryid = prefs.getInt('isPrimary');
print(savedPrimaryid != null
? "🔑 isPrimary: $savedPrimaryid"
: "⚠️ isPrimary not set properly");
}
Future getClientId() async {
final prefs = await SharedPreferences.getInstance();
final savedClientId = prefs.getInt('client_id');
print(savedClientId != null
? "🏢 Stored clientId: $savedClientId"
: "⚠️ clientId not found in SharedPreferences");
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
print("🎯 MyApp.build() called");
return GestureDetector(
onTap: () {
final currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus &&
currentFocus.focusedChild != null) {
FocusManager.instance.primaryFocus!.unfocus();
}
},
child: ScreenUtilInit(
designSize: const Size(360, 690),
builder: (context, child) {
print("🎨 GetMaterialApp built");
return GetMaterialApp(
translations: Languages(),
locale: const Locale('en', 'US'),
fallbackLocale: const Locale('en', 'US'),
localizationsDelegates: const [
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
],
debugShowCheckedModeBanner: false,
initialRoute: krSplashScreen,
getPages: routes,
unknownRoute: unknownRoute,
initialBinding: BinderController(),
theme: ThemeData(useMaterial3: false),
);
},
),
);
}
}
// ✅ Deep link handler
// Future _handleUri(Uri? uri) async {
// print('📥 Deep link received: $uri');
//
// if (uri == null) {
// print('⚠️ URI is null, returning');
// return;
// }
//
// try {
// if (uri.scheme == 'wam' && uri.host == 'chat') {
// final phone = uri.queryParameters['phone'];
// print('📲 Extracted phone: $phone');
//
// if (phone != null && phone.isNotEmpty) {
// final chatController = Get.find();
// print('✅ ChatController found, calling openChatFromPhone');
//
// await chatController.openChatFromPhone(phone);
//
// print('📟 openChatFromPhone complete — navigating to chat screen');
// hasHandledInitialNavigation = true;
//
// // 🧠 FIX: delay navigation until after build is stable
// WidgetsBinding.instance.addPostFrameCallback((_) async {
// Get.offAllNamed(krHomeScreen); // optional, if you want a clean stack
// await Future.delayed(Duration(milliseconds: 100));
// Get.toNamed(krChatScreen);
//
// });
// } else {
// print('⚠️ Phone number missing in deep link');
// }
// } else {
// print('⚠️ Deep link scheme or host did not match');
// }
// } catch (e, stack) {
// print('🔥 Exception in _handleUri: $e');
// print(stack);
// }
// }
Future _handleUri(Uri? uri) async {
print('📥 Deep link received: $uri');
if (uri == null) {
print('⚠️ URI is null, returning');
return;
}
try {
if (uri.scheme == 'wam' && uri.host == 'chat') {
final phone = uri.queryParameters['phone'];
print('📲 Extracted phone: $phone');
if (phone != null && phone.isNotEmpty) {
final chatController = Get.find();
print('✅ ChatController found, calling openChatFromPhone');
await chatController.openChatFromPhone(phone);
print('📟 openChatFromPhone complete — navigating to chat screen');
hasHandledInitialNavigation = true;
// ✅ Delay + PostFrame to ensure UI is ready
WidgetsBinding.instance.addPostFrameCallback((_) async {
Get.offAllNamed(krHomeScreen); // optional clean stack
await Future.delayed(const Duration(milliseconds: 100));
Get.toNamed(krChatScreen);
// ✅ Show popup after chat screen is fully built
Future.delayed(const Duration(milliseconds: 200), () {
if (Get.context != null) {
print("🪟 Opening templateListPopup...");
templateListPopup(Get.context!);
} else {
print("⚠️ Get.context was null — popup not shown.");
}
});
});
} else {
print('⚠️ Phone number missing in deep link');
}
} else {
print('⚠️ Deep link scheme or host did not match');
}
} catch (e, stack) {
print('🔥 Exception in _handleUri: $e');
print(stack);
}
}
Подробнее здесь: https://stackoverflow.com/questions/798 ... g-anywhere