dev #1
@ -14,6 +14,7 @@ analyzer:
|
||||
invalid_annotation_target: ignore
|
||||
use_build_context_synchronously: ignore
|
||||
deprecated_member_use: ignore
|
||||
depend_on_referenced_packages: ignore
|
||||
exclude:
|
||||
- test/generated/**
|
||||
- "**/**.g.dart"
|
||||
|
||||
@ -6,7 +6,7 @@ plugins {
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.apskel.apskel_owner"
|
||||
namespace = "com.apskel.enaklo_owner"
|
||||
compileSdk = flutter.compileSdkVersion
|
||||
ndkVersion = "27.0.12077973"
|
||||
|
||||
@ -21,7 +21,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
|
||||
applicationId = "com.apskel.apskel_owner"
|
||||
applicationId = "com.apskel.enaklo_owner"
|
||||
// You can update the following values to match your application needs.
|
||||
// For more information, see: https://flutter.dev/to/review-gradle-config.
|
||||
minSdk = flutter.minSdkVersion
|
||||
|
||||
48
android/app/google-services.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "765730035527",
|
||||
"project_id": "apskel-pos-v2",
|
||||
"storage_bucket": "apskel-pos-v2.firebasestorage.app"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:765730035527:android:beffb797b781e715241e62",
|
||||
"android_client_info": {
|
||||
"package_name": "com.apskel.enaklo_owner"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyAOZwVSQwUeeM9BjcyTOK9GUh8AmTWucuc"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:765730035527:android:498defd7071336dd241e62",
|
||||
"android_client_info": {
|
||||
"package_name": "com.apskel.pos"
|
||||
}
|
||||
},
|
||||
"oauth_client": [],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyAOZwVSQwUeeM9BjcyTOK9GUh8AmTWucuc"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": []
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
@ -5,9 +5,11 @@
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
|
||||
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
|
||||
<!-- FCM: required for POST_NOTIFICATIONS on Android 13+ -->
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
|
||||
<application
|
||||
android:label="Apskel Owner"
|
||||
android:label="Enaklo Owner"
|
||||
android:name="${applicationName}"
|
||||
android:icon="@mipmap/launcher_icon">
|
||||
<activity
|
||||
@ -37,6 +39,16 @@
|
||||
<meta-data
|
||||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
|
||||
<!-- FCM: default notification channel for Android 8+ -->
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_channel_id"
|
||||
android:value="high_importance_channel" />
|
||||
|
||||
<!-- FCM: default notification icon -->
|
||||
<meta-data
|
||||
android:name="com.google.firebase.messaging.default_notification_icon"
|
||||
android:resource="@mipmap/launcher_icon" />
|
||||
</application>
|
||||
<!-- Required to query activities that can process text, see:
|
||||
https://developer.android.com/training/package-visibility and
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
package com.apskel.apskel_owner
|
||||
package com.apskel.enaklo_owner
|
||||
|
||||
import io.flutter.embedding.android.FlutterActivity
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 37 KiB After Width: | Height: | Size: 108 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 203 KiB |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 7.5 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 4.2 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 654 KiB |
|
Before Width: | Height: | Size: 678 B After Width: | Height: | Size: 775 B |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 14 KiB |
@ -5,7 +5,7 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Apskel Owner</string>
|
||||
<string>Enaklo Owner</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@ -45,5 +45,11 @@
|
||||
<true/>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<!-- FCM: enable background fetch & remote notifications -->
|
||||
<key>UIBackgroundModes</key>
|
||||
<array>
|
||||
<string>fetch</string>
|
||||
<string>remote-notification</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
||||
|
||||
8
lib/common/di/di_firebase.dart
Normal file
@ -0,0 +1,8 @@
|
||||
import 'package:firebase_core/firebase_core.dart';
|
||||
import 'package:injectable/injectable.dart';
|
||||
|
||||
@module
|
||||
abstract class FirebaseDi {
|
||||
@preResolve
|
||||
Future<FirebaseApp> get firebaseApp => Firebase.initializeApp();
|
||||
}
|
||||
150
lib/common/utils/fcm_service.dart
Normal file
@ -0,0 +1,150 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:injectable/injectable.dart';
|
||||
|
||||
/// Background message handler — must be a top-level function.
|
||||
@pragma('vm:entry-point')
|
||||
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
|
||||
debugPrint('[FCM] Background message: ${message.messageId}');
|
||||
}
|
||||
|
||||
@lazySingleton
|
||||
class FcmService {
|
||||
final FirebaseMessaging _messaging = FirebaseMessaging.instance;
|
||||
|
||||
final FlutterLocalNotificationsPlugin _localNotifications =
|
||||
FlutterLocalNotificationsPlugin();
|
||||
|
||||
static const _androidChannel = AndroidNotificationChannel(
|
||||
'high_importance_channel',
|
||||
'High Importance Notifications',
|
||||
description: 'This channel is used for important notifications.',
|
||||
importance: Importance.high,
|
||||
);
|
||||
|
||||
/// Call this once during app startup (after Firebase.initializeApp).
|
||||
Future<void> initialize({
|
||||
void Function(RemoteMessage message)? onMessageTap,
|
||||
}) async {
|
||||
// 1. Request permission (iOS + Android 13+)
|
||||
await _requestPermission();
|
||||
|
||||
// 2. Setup local notifications (needed to show heads-up on Android)
|
||||
await _setupLocalNotifications();
|
||||
|
||||
// 3. Register background handler
|
||||
FirebaseMessaging.onBackgroundMessage(firebaseMessagingBackgroundHandler);
|
||||
|
||||
// 4. Foreground message handler
|
||||
FirebaseMessaging.onMessage.listen((message) {
|
||||
debugPrint('[FCM] Foreground message: ${message.messageId}');
|
||||
_showLocalNotification(message);
|
||||
});
|
||||
|
||||
// 5. App opened from notification (background → foreground)
|
||||
FirebaseMessaging.onMessageOpenedApp.listen((message) {
|
||||
debugPrint('[FCM] Notification tapped (background): ${message.messageId}');
|
||||
onMessageTap?.call(message);
|
||||
});
|
||||
|
||||
// 6. App launched from terminated state via notification
|
||||
final initialMessage = await _messaging.getInitialMessage();
|
||||
if (initialMessage != null) {
|
||||
debugPrint('[FCM] App launched from notification: ${initialMessage.messageId}');
|
||||
onMessageTap?.call(initialMessage);
|
||||
}
|
||||
|
||||
// 7. Print FCM token for debugging
|
||||
final token = await getToken();
|
||||
debugPrint('[FCM] Token: $token');
|
||||
}
|
||||
|
||||
Future<void> _requestPermission() async {
|
||||
final settings = await _messaging.requestPermission(
|
||||
alert: true,
|
||||
badge: true,
|
||||
sound: true,
|
||||
);
|
||||
debugPrint('[FCM] Permission status: ${settings.authorizationStatus}');
|
||||
}
|
||||
|
||||
Future<void> _setupLocalNotifications() async {
|
||||
// Android init
|
||||
const androidInit = AndroidInitializationSettings('@mipmap/launcher_icon');
|
||||
|
||||
// iOS init
|
||||
const iosInit = DarwinInitializationSettings(
|
||||
requestAlertPermission: false,
|
||||
requestBadgePermission: false,
|
||||
requestSoundPermission: false,
|
||||
);
|
||||
|
||||
const initSettings = InitializationSettings(
|
||||
android: androidInit,
|
||||
iOS: iosInit,
|
||||
);
|
||||
|
||||
await _localNotifications.initialize(
|
||||
initSettings,
|
||||
onDidReceiveNotificationResponse: (details) {
|
||||
debugPrint('[FCM] Local notification tapped: ${details.payload}');
|
||||
},
|
||||
);
|
||||
|
||||
// Create Android notification channel
|
||||
if (Platform.isAndroid) {
|
||||
await _localNotifications
|
||||
.resolvePlatformSpecificImplementation<
|
||||
AndroidFlutterLocalNotificationsPlugin>()
|
||||
?.createNotificationChannel(_androidChannel);
|
||||
}
|
||||
|
||||
// iOS: show notification even when app is in foreground
|
||||
await _messaging.setForegroundNotificationPresentationOptions(
|
||||
alert: true,
|
||||
badge: true,
|
||||
sound: true,
|
||||
);
|
||||
}
|
||||
|
||||
void _showLocalNotification(RemoteMessage message) {
|
||||
final notification = message.notification;
|
||||
if (notification == null) return;
|
||||
|
||||
_localNotifications.show(
|
||||
notification.hashCode,
|
||||
notification.title,
|
||||
notification.body,
|
||||
NotificationDetails(
|
||||
android: AndroidNotificationDetails(
|
||||
_androidChannel.id,
|
||||
_androidChannel.name,
|
||||
channelDescription: _androidChannel.description,
|
||||
icon: '@mipmap/launcher_icon',
|
||||
importance: Importance.high,
|
||||
priority: Priority.high,
|
||||
),
|
||||
iOS: const DarwinNotificationDetails(),
|
||||
),
|
||||
payload: jsonEncode(message.data),
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the FCM registration token for this device.
|
||||
Future<String?> getToken() => _messaging.getToken();
|
||||
|
||||
/// Subscribe to a topic (e.g. 'all', 'promo').
|
||||
Future<void> subscribeToTopic(String topic) =>
|
||||
_messaging.subscribeToTopic(topic);
|
||||
|
||||
/// Unsubscribe from a topic.
|
||||
Future<void> unsubscribeFromTopic(String topic) =>
|
||||
_messaging.unsubscribeFromTopic(topic);
|
||||
|
||||
/// Listen for token refresh.
|
||||
Stream<String> get onTokenRefresh => _messaging.onTokenRefresh;
|
||||
}
|
||||
@ -53,11 +53,13 @@ import 'package:apskel_owner_flutter/common/api/api_client.dart' as _i115;
|
||||
import 'package:apskel_owner_flutter/common/di/di_auto_route.dart' as _i311;
|
||||
import 'package:apskel_owner_flutter/common/di/di_connectivity.dart' as _i586;
|
||||
import 'package:apskel_owner_flutter/common/di/di_dio.dart' as _i103;
|
||||
import 'package:apskel_owner_flutter/common/di/di_firebase.dart' as _i73;
|
||||
import 'package:apskel_owner_flutter/common/di/di_package_info.dart' as _i227;
|
||||
import 'package:apskel_owner_flutter/common/di/di_shared_preferences.dart'
|
||||
as _i402;
|
||||
import 'package:apskel_owner_flutter/common/network/network_client.dart'
|
||||
as _i543;
|
||||
import 'package:apskel_owner_flutter/common/utils/fcm_service.dart' as _i179;
|
||||
import 'package:apskel_owner_flutter/domain/analytic/repositories/i_analytic_repository.dart'
|
||||
as _i477;
|
||||
import 'package:apskel_owner_flutter/domain/auth/auth.dart' as _i49;
|
||||
@ -106,6 +108,7 @@ import 'package:apskel_owner_flutter/presentation/router/app_router.dart'
|
||||
as _i258;
|
||||
import 'package:connectivity_plus/connectivity_plus.dart' as _i895;
|
||||
import 'package:dio/dio.dart' as _i361;
|
||||
import 'package:firebase_core/firebase_core.dart' as _i982;
|
||||
import 'package:get_it/get_it.dart' as _i174;
|
||||
import 'package:injectable/injectable.dart' as _i526;
|
||||
import 'package:package_info_plus/package_info_plus.dart' as _i655;
|
||||
@ -121,22 +124,28 @@ extension GetItInjectableX on _i174.GetIt {
|
||||
_i526.EnvironmentFilter? environmentFilter,
|
||||
}) async {
|
||||
final gh = _i526.GetItHelper(this, environment, environmentFilter);
|
||||
final firebaseDi = _$FirebaseDi();
|
||||
final sharedPreferencesDi = _$SharedPreferencesDi();
|
||||
final dioDi = _$DioDi();
|
||||
final autoRouteDi = _$AutoRouteDi();
|
||||
final connectivityDi = _$ConnectivityDi();
|
||||
final dioDi = _$DioDi();
|
||||
final packageInfoDi = _$PackageInfoDi();
|
||||
await gh.factoryAsync<_i982.FirebaseApp>(
|
||||
() => firebaseDi.firebaseApp,
|
||||
preResolve: true,
|
||||
);
|
||||
await gh.factoryAsync<_i460.SharedPreferences>(
|
||||
() => sharedPreferencesDi.prefs,
|
||||
preResolve: true,
|
||||
);
|
||||
gh.lazySingleton<_i361.Dio>(() => dioDi.dio);
|
||||
gh.lazySingleton<_i258.AppRouter>(() => autoRouteDi.appRouter);
|
||||
gh.lazySingleton<_i895.Connectivity>(() => connectivityDi.connectivity);
|
||||
gh.lazySingleton<_i361.Dio>(() => dioDi.dio);
|
||||
await gh.lazySingletonAsync<_i655.PackageInfo>(
|
||||
() => packageInfoDi.packageInfo,
|
||||
preResolve: true,
|
||||
);
|
||||
gh.lazySingleton<_i179.FcmService>(() => _i179.FcmService());
|
||||
gh.lazySingleton<_i543.NetworkClient>(
|
||||
() => _i543.NetworkClient(gh<_i895.Connectivity>()),
|
||||
);
|
||||
@ -151,29 +160,29 @@ extension GetItInjectableX on _i174.GetIt {
|
||||
() => _i115.ApiClient(gh<_i361.Dio>(), gh<_i6.Env>()),
|
||||
);
|
||||
gh.factory<_i6.Env>(() => _i6.ProdEnv(), registerFor: {_prod});
|
||||
gh.factory<_i130.OrderRemoteDataProvider>(
|
||||
() => _i130.OrderRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
);
|
||||
gh.factory<_i333.CategoryRemoteDataProvider>(
|
||||
() => _i333.CategoryRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
gh.factory<_i866.AnalyticRemoteDataProvider>(
|
||||
() => _i866.AnalyticRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
);
|
||||
gh.factory<_i17.AuthRemoteDataProvider>(
|
||||
() => _i17.AuthRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
);
|
||||
gh.factory<_i785.UserRemoteDataProvider>(
|
||||
() => _i785.UserRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
gh.factory<_i333.CategoryRemoteDataProvider>(
|
||||
() => _i333.CategoryRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
);
|
||||
gh.factory<_i823.ProductRemoteDataProvider>(
|
||||
() => _i823.ProductRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
gh.factory<_i1006.CustomerRemoteDataProvider>(
|
||||
() => _i1006.CustomerRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
);
|
||||
gh.factory<_i130.OrderRemoteDataProvider>(
|
||||
() => _i130.OrderRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
);
|
||||
gh.factory<_i27.OutletRemoteDataProvider>(
|
||||
() => _i27.OutletRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
);
|
||||
gh.factory<_i866.AnalyticRemoteDataProvider>(
|
||||
() => _i866.AnalyticRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
gh.factory<_i823.ProductRemoteDataProvider>(
|
||||
() => _i823.ProductRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
);
|
||||
gh.factory<_i1006.CustomerRemoteDataProvider>(
|
||||
() => _i1006.CustomerRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
gh.factory<_i785.UserRemoteDataProvider>(
|
||||
() => _i785.UserRemoteDataProvider(gh<_i115.ApiClient>()),
|
||||
);
|
||||
gh.factory<_i48.ICustomerRepository>(
|
||||
() => _i550.CustomerRepository(gh<_i1006.CustomerRemoteDataProvider>()),
|
||||
@ -220,17 +229,20 @@ extension GetItInjectableX on _i174.GetIt {
|
||||
gh.factory<_i183.CategoryLoaderBloc>(
|
||||
() => _i183.CategoryLoaderBloc(gh<_i1020.ICategoryRepository>()),
|
||||
);
|
||||
gh.factory<_i473.HomeBloc>(
|
||||
() => _i473.HomeBloc(gh<_i477.IAnalyticRepository>()),
|
||||
);
|
||||
gh.factory<_i889.SalesLoaderBloc>(
|
||||
() => _i889.SalesLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
||||
);
|
||||
gh.factory<_i473.HomeBloc>(
|
||||
() => _i473.HomeBloc(gh<_i477.IAnalyticRepository>()),
|
||||
);
|
||||
gh.factory<_i337.CurrentOutletLoaderBloc>(
|
||||
() => _i337.CurrentOutletLoaderBloc(gh<_i197.IOutletRepository>()),
|
||||
);
|
||||
gh.factory<_i221.ProductAnalyticLoaderBloc>(
|
||||
() => _i221.ProductAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
||||
gh.factory<_i1038.CategoryAnalyticLoaderBloc>(
|
||||
() => _i1038.CategoryAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
||||
);
|
||||
gh.factory<_i516.DashboardAnalyticLoaderBloc>(
|
||||
() => _i516.DashboardAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
||||
);
|
||||
gh.factory<_i785.InventoryAnalyticLoaderBloc>(
|
||||
() => _i785.InventoryAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
||||
@ -240,41 +252,38 @@ extension GetItInjectableX on _i174.GetIt {
|
||||
gh<_i477.IAnalyticRepository>(),
|
||||
),
|
||||
);
|
||||
gh.factory<_i1038.CategoryAnalyticLoaderBloc>(
|
||||
() => _i1038.CategoryAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
||||
gh.factory<_i221.ProductAnalyticLoaderBloc>(
|
||||
() => _i221.ProductAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
||||
);
|
||||
gh.factory<_i11.ProfitLossLoaderBloc>(
|
||||
() => _i11.ProfitLossLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
||||
);
|
||||
gh.factory<_i516.DashboardAnalyticLoaderBloc>(
|
||||
() => _i516.DashboardAnalyticLoaderBloc(gh<_i477.IAnalyticRepository>()),
|
||||
gh.factory<_i945.AuthBloc>(
|
||||
() => _i945.AuthBloc(gh<_i49.IAuthRepository>()),
|
||||
);
|
||||
gh.factory<_i775.LoginFormBloc>(
|
||||
() => _i775.LoginFormBloc(gh<_i49.IAuthRepository>()),
|
||||
);
|
||||
gh.factory<_i945.AuthBloc>(
|
||||
() => _i945.AuthBloc(gh<_i49.IAuthRepository>()),
|
||||
);
|
||||
gh.factory<_i574.LogoutFormBloc>(
|
||||
() => _i574.LogoutFormBloc(gh<_i49.IAuthRepository>()),
|
||||
);
|
||||
gh.factory<_i1058.OrderLoaderBloc>(
|
||||
() => _i1058.OrderLoaderBloc(gh<_i219.IOrderRepository>()),
|
||||
);
|
||||
gh.factory<_i147.UserEditFormBloc>(
|
||||
() => _i147.UserEditFormBloc(gh<_i635.IUserRepository>()),
|
||||
);
|
||||
gh.factory<_i1030.ChangePasswordFormBloc>(
|
||||
() => _i1030.ChangePasswordFormBloc(gh<_i635.IUserRepository>()),
|
||||
);
|
||||
gh.factory<_i605.TransactionReportBloc>(
|
||||
() => _i605.TransactionReportBloc(
|
||||
gh.factory<_i147.UserEditFormBloc>(
|
||||
() => _i147.UserEditFormBloc(gh<_i635.IUserRepository>()),
|
||||
);
|
||||
gh.factory<_i346.InventoryReportBloc>(
|
||||
() => _i346.InventoryReportBloc(
|
||||
gh<_i477.IAnalyticRepository>(),
|
||||
gh<_i197.IOutletRepository>(),
|
||||
),
|
||||
);
|
||||
gh.factory<_i346.InventoryReportBloc>(
|
||||
() => _i346.InventoryReportBloc(
|
||||
gh.factory<_i605.TransactionReportBloc>(
|
||||
() => _i605.TransactionReportBloc(
|
||||
gh<_i477.IAnalyticRepository>(),
|
||||
gh<_i197.IOutletRepository>(),
|
||||
),
|
||||
@ -283,12 +292,14 @@ extension GetItInjectableX on _i174.GetIt {
|
||||
}
|
||||
}
|
||||
|
||||
class _$SharedPreferencesDi extends _i402.SharedPreferencesDi {}
|
||||
class _$FirebaseDi extends _i73.FirebaseDi {}
|
||||
|
||||
class _$DioDi extends _i103.DioDi {}
|
||||
class _$SharedPreferencesDi extends _i402.SharedPreferencesDi {}
|
||||
|
||||
class _$AutoRouteDi extends _i311.AutoRouteDi {}
|
||||
|
||||
class _$ConnectivityDi extends _i586.ConnectivityDi {}
|
||||
|
||||
class _$DioDi extends _i103.DioDi {}
|
||||
|
||||
class _$PackageInfoDi extends _i227.PackageInfoDi {}
|
||||
|
||||
@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:injectable/injectable.dart';
|
||||
|
||||
import 'common/utils/fcm_service.dart';
|
||||
import 'injection.dart';
|
||||
import 'presentation/app_widget.dart';
|
||||
|
||||
@ -24,5 +25,13 @@ void main() async {
|
||||
kReleaseMode ? Environment.prod : Environment.dev,
|
||||
);
|
||||
|
||||
// Initialize FCM after dependencies are ready
|
||||
await getIt<FcmService>().initialize(
|
||||
onMessageTap: (message) {
|
||||
// TODO: handle navigation when notification is tapped
|
||||
debugPrint('[FCM] Navigate based on: ${message.data}');
|
||||
},
|
||||
);
|
||||
|
||||
runApp(const AppWidget());
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@ project(runner LANGUAGES CXX)
|
||||
set(BINARY_NAME "apskel_owner_flutter")
|
||||
# The unique GTK application identifier for this application. See:
|
||||
# https://wiki.gnome.org/HowDoI/ChooseApplicationID
|
||||
set(APPLICATION_ID "com.apskel.apskel_owner")
|
||||
set(APPLICATION_ID "com.apskel.enaklo_owner")
|
||||
|
||||
# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
|
||||
# versions of CMake.
|
||||
|
||||
@ -8,6 +8,9 @@ import Foundation
|
||||
import connectivity_plus
|
||||
import device_info_plus
|
||||
import file_selector_macos
|
||||
import firebase_core
|
||||
import firebase_messaging
|
||||
import flutter_local_notifications
|
||||
import open_file_mac
|
||||
import package_info_plus
|
||||
import path_provider_foundation
|
||||
@ -19,6 +22,9 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin"))
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
|
||||
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
|
||||
FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin"))
|
||||
OpenFilePlugin.register(with: registry.registrar(forPlugin: "OpenFilePlugin"))
|
||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
|
||||
126
pubspec.lock
@ -9,6 +9,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "85.0.0"
|
||||
_flutterfire_internals:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: _flutterfire_internals
|
||||
sha256: ff0a84a2734d9e1089f8aedd5c0af0061b82fb94e95260d943404e0ef2134b11
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.3.59"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -205,10 +213,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
version: "1.4.1"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -449,6 +457,54 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+4"
|
||||
firebase_core:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_core
|
||||
sha256: "7be63a3f841fc9663342f7f3a011a42aef6a61066943c90b1c434d79d5c995c5"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.15.2"
|
||||
firebase_core_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_platform_interface
|
||||
sha256: "0ecda14c1bfc9ed8cac303dd0f8d04a320811b479362a9a4efb14fd331a473ce"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "6.0.3"
|
||||
firebase_core_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_core_web
|
||||
sha256: "0ed0dc292e8f9ac50992e2394e9d336a0275b6ae400d64163fdf0a8a8b556c37"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.24.1"
|
||||
firebase_messaging:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: firebase_messaging
|
||||
sha256: "60be38574f8b5658e2f22b7e311ff2064bea835c248424a383783464e8e02fcc"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "15.2.10"
|
||||
firebase_messaging_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_platform_interface
|
||||
sha256: "685e1771b3d1f9c8502771ccc9f91485b376ffe16d553533f335b9183ea99754"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.6.10"
|
||||
firebase_messaging_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: firebase_messaging_web
|
||||
sha256: "0d1be17bc89ed3ff5001789c92df678b2e963a51b6fa2bdb467532cc9dbed390"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.10.10"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -518,6 +574,30 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
flutter_local_notifications:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_local_notifications
|
||||
sha256: ef41ae901e7529e52934feba19ed82827b11baa67336829564aeab3129460610
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "18.0.1"
|
||||
flutter_local_notifications_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_local_notifications_linux
|
||||
sha256: "8f685642876742c941b29c32030f6f4f6dacd0e4eaecb3efbb187d6a3812ca01"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
flutter_local_notifications_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_local_notifications_platform_interface
|
||||
sha256: "6c5b83c86bf819cdb177a9247a3722067dd8cc6313827ce7c77a4b238a26fd52"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "8.0.0"
|
||||
flutter_localizations:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@ -777,26 +857,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
|
||||
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.0.9"
|
||||
version: "11.0.2"
|
||||
leak_tracker_flutter_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
|
||||
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.9"
|
||||
version: "3.0.10"
|
||||
leak_tracker_testing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
|
||||
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "3.0.2"
|
||||
line_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -833,26 +913,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.17"
|
||||
version: "0.12.19"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
version: "0.13.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
|
||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.16.0"
|
||||
version: "1.17.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1422,10 +1502,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
|
||||
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.4"
|
||||
version: "0.7.10"
|
||||
time:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1434,6 +1514,14 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
timezone:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timezone
|
||||
sha256: dd14a3b83cfd7cb19e7888f1cbc20f258b8d71b54c06f79ac585f14093a287d1
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.10.1"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1550,10 +1638,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
|
||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.2.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1635,5 +1723,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.8.1 <4.0.0"
|
||||
dart: ">=3.9.0-0 <4.0.0"
|
||||
flutter: ">=3.29.0"
|
||||
|
||||
@ -48,6 +48,9 @@ dependencies:
|
||||
pdf: ^3.11.3
|
||||
open_file: ^3.5.10
|
||||
permission_handler: ^12.0.1
|
||||
firebase_core: ^3.13.1
|
||||
firebase_messaging: ^15.2.5
|
||||
flutter_local_notifications: ^18.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
BIN
web/favicon.png
|
Before Width: | Height: | Size: 519 B After Width: | Height: | Size: 835 B |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 291 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 291 KiB |
@ -8,6 +8,7 @@
|
||||
|
||||
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
|
||||
#include <file_selector_windows/file_selector_windows.h>
|
||||
#include <firebase_core/firebase_core_plugin_c_api.h>
|
||||
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
||||
@ -16,6 +17,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
|
||||
FileSelectorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||
FirebaseCorePluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
|
||||
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
connectivity_plus
|
||||
file_selector_windows
|
||||
firebase_core
|
||||
permission_handler_windows
|
||||
url_launcher_windows
|
||||
)
|
||||
|
||||
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 4.2 KiB |