TLA Line data Source code
1 : // Copyright (c) 2026 Flipdare Pty Ltd. All rights reserved.
2 : //
3 : // This file is part of Flipdare's proprietary software and contains
4 : // confidential and copyrighted material. Unauthorised copying,
5 : // modification, distribution, or use of this file is strictly
6 : // prohibited without prior written permission from Flipdare Pty Ltd.
7 : //
8 : // This software includes third-party components licensed under MIT,
9 : // BSD, and Apache 2.0 licences. See THIRD_PARTY_NOTICES for details.
10 : //
11 :
12 : import 'package:core/admin/user_info_service_interface.dart';
13 : import 'package:flutter_neumorphic_plus/flutter_neumorphic.dart';
14 : import 'package:services/_prelude.dart';
15 : import 'package:services/cache/app_http_cache_manager.dart';
16 : import 'package:services/services.dart';
17 :
18 : import 'startup/alert_manager_register.dart';
19 : import 'startup/analytics_register.dart';
20 : import 'startup/theme_register.dart';
21 : import 'startup/user_info_service_register.dart';
22 :
23 : /// NOTE: This unfortunately needs to be in the `services` package.
24 : /// NOTE: and not in `manager`.
25 MIS 0 : /// NOTE: This is because including in `manager` generates circular dependencies..
26 : class AppCoreService {
27 0 : AuthClientFactory _authFactory;
28 : LocationServiceInterface _locationService;
29 : AppHttpCacheManager _httpCacheManager;
30 :
31 : AnalyticsRegister _analyticsRegister;
32 : UserInfoServiceRegister _userInfoRegister;
33 0 : AlertManagerRegister _alertRegister;
34 0 : ThemeRegister _themeRegister;
35 0 :
36 0 : AppCoreService() : this._();
37 0 :
38 0 : AppCoreService._({
39 0 : GetIt? getIt,
40 : AnalyticsInterface? analytics,
41 : AlertManagerInterface? alertManager,
42 0 : UserInfoService? userInfoService,
43 : AppTheme? appTheme,
44 : }) : _authFactory = AuthClientFactory(),
45 HIT 1 : _locationService = RadarLocationService(),
46 : _httpCacheManager = AppHttpCacheManager(),
47 : _analyticsRegister = AnalyticsRegister(instance: analytics),
48 : _themeRegister = ThemeRegister(instance: appTheme),
49 : _alertRegister = AlertManagerRegister(instance: alertManager),
50 : _userInfoRegister = UserInfoServiceRegister(
51 : instance: userInfoService,
52 : ) {
53 1 : _initialize();
54 1 : }
55 1 :
56 1 : @visibleForTesting
57 1 : AppCoreService.override(
58 : this._authFactory,
59 : this._locationService,
60 1 : this._httpCacheManager,
61 2 : AnalyticsInterface? analytics,
62 : UserInfoService? infoService,
63 : AppTheme? appTheme,
64 : ) : _analyticsRegister = AnalyticsRegister(instance: analytics),
65 : _themeRegister = ThemeRegister(instance: appTheme),
66 2 : _alertRegister = AlertManagerRegister(instance: null), // NOTE: this needs to be set later.
67 2 : _userInfoRegister = UserInfoServiceRegister(instance: infoService) {
68 : _initialize();
69 : }
70 2 :
71 MIS 0 : void _initialize() {
72 0 : LOG.i('Initializing Core AppServices...');
73 0 : // NOTE: these are non-gui related services, so we can initialize them now.
74 : // gui related services (AppTheme, AlertManager) need to wait till we have a BuildContext
75 0 : // e.g. in the presentation package.
76 : // see setAppTheme() and setAlertManager() below.
77 0 : _userInfoRegister.setUpAndRegister(force: true);
78 0 : _analyticsRegister.setUpAndRegister(force: true);
79 0 : }
80 :
81 : AuthClientFactory get authFactory => _authFactory;
82 0 : AnalyticsInterface get analytics => _analyticsRegister.instance!;
83 0 : LocationServiceInterface get locationService => _locationService;
84 0 : AppHttpCacheManager get httpCacheManager => _httpCacheManager;
85 :
86 : bool get isSetupComplete => _themeRegister.isRegistered && _alertRegister.isRegistered;
87 :
88 : AlertManagerInterface get alertManager {
89 : if (!_alertRegister.isRegistered) _throwInitError('AlertManager');
90 : return _alertRegister.instance!;
91 : }
92 :
93 : AppTheme get appTheme {
94 : if (!_themeRegister.isRegistered) _throwInitError('AppTheme');
95 : return _themeRegister.instance!;
96 : }
97 :
98 : /// !! ---------------------------------------------------------------------------
99 0 : /// !! IMPORTANT !!
100 : /// We have to wait till we have access to a [BuildContext] to complete the setup...
101 : /// !! ---------------------------------------------------------------------------
102 : ///
103 0 : /// e.g. In the [presentation] or [core-widget] packages in the `build` function call
104 0 : ///
105 0 : /// ```dart
106 0 : /// kAppStateInstance<AppCoreService>().setAppTheme(context);
107 : /// ```
108 : ///
109 0 : ///
110 0 : void setupPost({
111 0 : required AlertManagerInterface alertManager,
112 0 : required BuildContext context,
113 0 : }) {
114 : LOG.d('Setting up AlertManager with provided instance...');
115 : _alertRegister.setUpAndRegister(alertBuilder: () => alertManager);
116 : LOG.d('Setting up AppTheme with BuildContext...');
117 0 : _themeRegister.setUpAndRegister(context: context);
118 0 : }
119 :
120 0 : void dispose() {
121 : LOG.c('Disposing Core AppServices...');
122 : _httpCacheManager.dispose();
123 : _userInfoRegister.instance?.setAnonymous();
124 : _authFactory.client?.signOut();
125 : // NOTE: gui stuff doesn't need to be cleaned up ..
126 : }
127 HIT 1 :
128 : Never _throwInitError(String name) {
129 : throw AppCoreException.fromCode(
130 : AppCoreExceptionCode.initializationError,
131 : debugMsg: '$name is not initialized',
132 : );
133 : }
134 : }
135 :
136 1 : @visibleForTesting
137 : class MockAppCoreService extends AppCoreService {
138 : @override
139 : MockAppCoreService({
140 : required AuthClientFactory authFactory,
141 : required AnalyticsInterface analytics,
142 : required LocationServiceInterface locationService,
143 : required UserInfoService userInfoService,
144 : required AppHttpCacheManager httpCacheManager,
145 MIS 0 : AlertManagerInterface? alertManager,
146 : AppTheme? appTheme,
147 : }) : super.override(
148 : authFactory,
149 : locationService,
150 : httpCacheManager,
151 : analytics,
152 0 : userInfoService,
153 : appTheme,
154 0 : );
155 0 :
156 : void update({
157 0 : AuthClientFactory? authFactory,
158 : AnalyticsInterface? analytics,
159 0 : LocationServiceInterface? locationService,
160 0 : UserInfoServiceInterface? userInfoService,
161 : AppHttpCacheManager? httpCacheManager,
162 0 : }) {
163 : if (authFactory != null) _authFactory = authFactory;
164 : if (analytics != null) {
165 : _analyticsRegister.instance = analytics;
166 : _analyticsRegister.registerInstance(force: true);
167 : }
168 : if (locationService != null) _locationService = locationService;
169 : if (userInfoService != null) {
170 : _userInfoRegister.instance = userInfoService as UserInfoService;
171 : _userInfoRegister.registerInstance(force: true);
172 : }
173 : if (httpCacheManager != null) _httpCacheManager = httpCacheManager;
174 : }
175 : }
|