💄 Optimized notification page
⬇️ Remove firebase deps
			
			
This commit is contained in:
		
							
								
								
									
										4
									
								
								ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								ios/App/App.xcodeproj/project.xcworkspace/contents.xcworkspacedata
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Workspace | ||||
|    version = "1.0"> | ||||
| </Workspace> | ||||
							
								
								
									
										151
									
								
								ios/Podfile.lock
									
									
									
									
									
								
							
							
						
						
									
										151
									
								
								ios/Podfile.lock
									
									
									
									
									
								
							| @@ -1,187 +1,52 @@ | ||||
| PODS: | ||||
|   - AppAuth (1.6.2): | ||||
|     - AppAuth/Core (= 1.6.2) | ||||
|     - AppAuth/ExternalUserAgent (= 1.6.2) | ||||
|   - AppAuth/Core (1.6.2) | ||||
|   - AppAuth/ExternalUserAgent (1.6.2): | ||||
|     - AppAuth/Core | ||||
|   - Firebase/CoreOnly (10.20.0): | ||||
|     - FirebaseCore (= 10.20.0) | ||||
|   - Firebase/Crashlytics (10.20.0): | ||||
|     - Firebase/CoreOnly | ||||
|     - FirebaseCrashlytics (~> 10.20.0) | ||||
|   - Firebase/Messaging (10.20.0): | ||||
|     - Firebase/CoreOnly | ||||
|     - FirebaseMessaging (~> 10.20.0) | ||||
|   - firebase_core (2.25.4): | ||||
|     - Firebase/CoreOnly (= 10.20.0) | ||||
|     - Flutter | ||||
|   - firebase_crashlytics (3.4.14): | ||||
|     - Firebase/Crashlytics (= 10.20.0) | ||||
|     - firebase_core | ||||
|     - Flutter | ||||
|   - firebase_messaging (14.7.15): | ||||
|     - Firebase/Messaging (= 10.20.0) | ||||
|     - firebase_core | ||||
|     - Flutter | ||||
|   - FirebaseCore (10.20.0): | ||||
|     - FirebaseCoreInternal (~> 10.0) | ||||
|     - GoogleUtilities/Environment (~> 7.12) | ||||
|     - GoogleUtilities/Logger (~> 7.12) | ||||
|   - FirebaseCoreExtension (10.21.0): | ||||
|     - FirebaseCore (~> 10.0) | ||||
|   - FirebaseCoreInternal (10.21.0): | ||||
|     - "GoogleUtilities/NSData+zlib (~> 7.8)" | ||||
|   - FirebaseCrashlytics (10.20.0): | ||||
|     - FirebaseCore (~> 10.5) | ||||
|     - FirebaseInstallations (~> 10.0) | ||||
|     - FirebaseSessions (~> 10.5) | ||||
|     - GoogleDataTransport (~> 9.2) | ||||
|     - GoogleUtilities/Environment (~> 7.8) | ||||
|     - nanopb (< 2.30910.0, >= 2.30908.0) | ||||
|     - PromisesObjC (~> 2.1) | ||||
|   - FirebaseInstallations (10.21.0): | ||||
|     - FirebaseCore (~> 10.0) | ||||
|     - GoogleUtilities/Environment (~> 7.8) | ||||
|     - GoogleUtilities/UserDefaults (~> 7.8) | ||||
|     - PromisesObjC (~> 2.1) | ||||
|   - FirebaseMessaging (10.20.0): | ||||
|     - FirebaseCore (~> 10.0) | ||||
|     - FirebaseInstallations (~> 10.0) | ||||
|     - GoogleDataTransport (~> 9.3) | ||||
|     - GoogleUtilities/AppDelegateSwizzler (~> 7.8) | ||||
|     - GoogleUtilities/Environment (~> 7.8) | ||||
|     - GoogleUtilities/Reachability (~> 7.8) | ||||
|     - GoogleUtilities/UserDefaults (~> 7.8) | ||||
|     - nanopb (< 2.30910.0, >= 2.30908.0) | ||||
|   - FirebaseSessions (10.21.0): | ||||
|     - FirebaseCore (~> 10.5) | ||||
|     - FirebaseCoreExtension (~> 10.0) | ||||
|     - FirebaseInstallations (~> 10.0) | ||||
|     - GoogleDataTransport (~> 9.2) | ||||
|     - GoogleUtilities/Environment (~> 7.10) | ||||
|     - nanopb (< 2.30910.0, >= 2.30908.0) | ||||
|     - PromisesSwift (~> 2.1) | ||||
|   - Flutter (1.0.0) | ||||
|   - flutter_appauth (0.0.1): | ||||
|     - AppAuth (= 1.6.2) | ||||
|     - Flutter | ||||
|   - flutter_secure_storage (6.0.0): | ||||
|     - Flutter | ||||
|   - GoogleDataTransport (9.3.0): | ||||
|     - GoogleUtilities/Environment (~> 7.7) | ||||
|     - nanopb (< 2.30910.0, >= 2.30908.0) | ||||
|     - PromisesObjC (< 3.0, >= 1.2) | ||||
|   - GoogleUtilities/AppDelegateSwizzler (7.12.0): | ||||
|     - GoogleUtilities/Environment | ||||
|     - GoogleUtilities/Logger | ||||
|     - GoogleUtilities/Network | ||||
|   - GoogleUtilities/Environment (7.12.0): | ||||
|     - PromisesObjC (< 3.0, >= 1.2) | ||||
|   - GoogleUtilities/Logger (7.12.0): | ||||
|     - GoogleUtilities/Environment | ||||
|   - GoogleUtilities/Network (7.12.0): | ||||
|     - GoogleUtilities/Logger | ||||
|     - "GoogleUtilities/NSData+zlib" | ||||
|     - GoogleUtilities/Reachability | ||||
|   - "GoogleUtilities/NSData+zlib (7.12.0)" | ||||
|   - GoogleUtilities/Reachability (7.12.0): | ||||
|     - GoogleUtilities/Logger | ||||
|   - GoogleUtilities/UserDefaults (7.12.0): | ||||
|     - GoogleUtilities/Logger | ||||
|   - nanopb (2.30909.1): | ||||
|     - nanopb/decode (= 2.30909.1) | ||||
|     - nanopb/encode (= 2.30909.1) | ||||
|   - nanopb/decode (2.30909.1) | ||||
|   - nanopb/encode (2.30909.1) | ||||
|   - package_info_plus (0.4.5): | ||||
|     - Flutter | ||||
|   - path_provider_foundation (0.0.1): | ||||
|     - Flutter | ||||
|     - FlutterMacOS | ||||
|   - PromisesObjC (2.3.1) | ||||
|   - PromisesSwift (2.3.1): | ||||
|     - PromisesObjC (= 2.3.1) | ||||
|   - shared_preferences_foundation (0.0.1): | ||||
|     - Flutter | ||||
|     - FlutterMacOS | ||||
|   - url_launcher_ios (0.0.1): | ||||
|     - Flutter | ||||
|   - webview_flutter_wkwebview (0.0.1): | ||||
|     - Flutter | ||||
|  | ||||
| DEPENDENCIES: | ||||
|   - firebase_core (from `.symlinks/plugins/firebase_core/ios`) | ||||
|   - firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`) | ||||
|   - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) | ||||
|   - Flutter (from `Flutter`) | ||||
|   - flutter_appauth (from `.symlinks/plugins/flutter_appauth/ios`) | ||||
|   - flutter_secure_storage (from `.symlinks/plugins/flutter_secure_storage/ios`) | ||||
|   - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) | ||||
|   - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) | ||||
|   - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) | ||||
|   - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) | ||||
|   - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`) | ||||
|  | ||||
| SPEC REPOS: | ||||
|   trunk: | ||||
|     - AppAuth | ||||
|     - Firebase | ||||
|     - FirebaseCore | ||||
|     - FirebaseCoreExtension | ||||
|     - FirebaseCoreInternal | ||||
|     - FirebaseCrashlytics | ||||
|     - FirebaseInstallations | ||||
|     - FirebaseMessaging | ||||
|     - FirebaseSessions | ||||
|     - GoogleDataTransport | ||||
|     - GoogleUtilities | ||||
|     - nanopb | ||||
|     - PromisesObjC | ||||
|     - PromisesSwift | ||||
|  | ||||
| EXTERNAL SOURCES: | ||||
|   firebase_core: | ||||
|     :path: ".symlinks/plugins/firebase_core/ios" | ||||
|   firebase_crashlytics: | ||||
|     :path: ".symlinks/plugins/firebase_crashlytics/ios" | ||||
|   firebase_messaging: | ||||
|     :path: ".symlinks/plugins/firebase_messaging/ios" | ||||
|   Flutter: | ||||
|     :path: Flutter | ||||
|   flutter_appauth: | ||||
|     :path: ".symlinks/plugins/flutter_appauth/ios" | ||||
|   flutter_secure_storage: | ||||
|     :path: ".symlinks/plugins/flutter_secure_storage/ios" | ||||
|   package_info_plus: | ||||
|     :path: ".symlinks/plugins/package_info_plus/ios" | ||||
|   path_provider_foundation: | ||||
|     :path: ".symlinks/plugins/path_provider_foundation/darwin" | ||||
|   shared_preferences_foundation: | ||||
|     :path: ".symlinks/plugins/shared_preferences_foundation/darwin" | ||||
|   url_launcher_ios: | ||||
|     :path: ".symlinks/plugins/url_launcher_ios/ios" | ||||
|   webview_flutter_wkwebview: | ||||
|     :path: ".symlinks/plugins/webview_flutter_wkwebview/ios" | ||||
|  | ||||
| SPEC CHECKSUMS: | ||||
|   AppAuth: 3bb1d1cd9340bd09f5ed189fb00b1cc28e1e8570 | ||||
|   Firebase: 10c8cb12fb7ad2ae0c09ffc86cd9c1ab392a0031 | ||||
|   firebase_core: a46c312d8bae4defa3d009b2aa7b5b413aeb394e | ||||
|   firebase_crashlytics: 3d12285fcbd865d576b9965bd4090cd8b68e11fd | ||||
|   firebase_messaging: 40d7dd2f3e88a6367c7326cf601f84633d477582 | ||||
|   FirebaseCore: 28045c1560a2600d284b9c45a904fe322dc890b6 | ||||
|   FirebaseCoreExtension: 1c044fd46e95036cccb29134757c499613f3f564 | ||||
|   FirebaseCoreInternal: 43c1788eaeee9d1b97caaa751af567ce11010d00 | ||||
|   FirebaseCrashlytics: 81530595edb6d99f1918f723a6c33766a24a4c86 | ||||
|   FirebaseInstallations: 390ea1d10a4d02b20c965cbfd527ee9b3b412acb | ||||
|   FirebaseMessaging: 06c414a21b122396a26847c523d5c370f8325df5 | ||||
|   FirebaseSessions: 80c2bbdd28166267b3d132debe5f7531efdb00bc | ||||
|   Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 | ||||
|   flutter_appauth: 0863b1f33110b410213e736aead4a6727303f509 | ||||
|   flutter_secure_storage: 23fc622d89d073675f2eaa109381aefbcf5a49be | ||||
|   GoogleDataTransport: 57c22343ab29bc686febbf7cbb13bad167c2d8fe | ||||
|   GoogleUtilities: 0759d1a57ebb953965c2dfe0ba4c82e95ccc2e34 | ||||
|   nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5 | ||||
|   package_info_plus: 115f4ad11e0698c8c1c5d8a689390df880f47e85 | ||||
|   path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c | ||||
|   PromisesObjC: c50d2056b5253dadbd6c2bea79b0674bd5a52fa4 | ||||
|   PromisesSwift: 28dca69a9c40779916ac2d6985a0192a5cb4a265 | ||||
|   url_launcher_ios: bbd758c6e7f9fd7b5b1d4cde34d2b95fcce5e812 | ||||
|   shared_preferences_foundation: b4c3b4cddf1c21f02770737f147a3f5da9d39695 | ||||
|   url_launcher_ios: 6116280ddcfe98ab8820085d8d76ae7449447586 | ||||
|   webview_flutter_wkwebview: be0f0d33777f1bfd0c9fdcb594786704dbf65f36 | ||||
|  | ||||
| PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 | ||||
|   | ||||
| @@ -506,7 +506,7 @@ | ||||
| 				ENABLE_BITCODE = NO; | ||||
| 				INFOPLIST_FILE = Runner/Info.plist; | ||||
| 				INFOPLIST_KEY_CFBundleDisplayName = SolarAgent; | ||||
| 				INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; | ||||
| 				INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; | ||||
| 				LD_RUNPATH_SEARCH_PATHS = ( | ||||
| 					"$(inherited)", | ||||
| 					"@executable_path/Frameworks", | ||||
| @@ -695,7 +695,7 @@ | ||||
| 				ENABLE_BITCODE = NO; | ||||
| 				INFOPLIST_FILE = Runner/Info.plist; | ||||
| 				INFOPLIST_KEY_CFBundleDisplayName = SolarAgent; | ||||
| 				INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; | ||||
| 				INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; | ||||
| 				LD_RUNPATH_SEARCH_PATHS = ( | ||||
| 					"$(inherited)", | ||||
| 					"@executable_path/Frameworks", | ||||
| @@ -722,7 +722,7 @@ | ||||
| 				ENABLE_BITCODE = NO; | ||||
| 				INFOPLIST_FILE = Runner/Info.plist; | ||||
| 				INFOPLIST_KEY_CFBundleDisplayName = SolarAgent; | ||||
| 				INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; | ||||
| 				INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking"; | ||||
| 				LD_RUNPATH_SEARCH_PATHS = ( | ||||
| 					"$(inherited)", | ||||
| 					"@executable_path/Frameworks", | ||||
|   | ||||
| @@ -3,8 +3,6 @@ import 'dart:io'; | ||||
|  | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter_secure_storage/flutter_secure_storage.dart'; | ||||
| import 'package:solaragent/firebase.dart'; | ||||
| import 'package:solaragent/preferences.dart'; | ||||
| import 'package:solaragent/screens/auth.dart'; | ||||
| import 'package:oauth2/oauth2.dart' as oauth2; | ||||
|  | ||||
| @@ -17,10 +15,8 @@ class AuthGuard { | ||||
|       Uri.parse('https://id.solsynth.dev/api/notifications/subscribe'); | ||||
|   final authorizationEndpoint = | ||||
|       Uri.parse('https://id.solsynth.dev/auth/o/connect'); | ||||
|   final tokenEndpoint = | ||||
|       Uri.parse('https://id.solsynth.dev/api/auth/token'); | ||||
|   final userinfoEndpoint = | ||||
|       Uri.parse('https://id.solsynth.dev/api/users/me'); | ||||
|   final tokenEndpoint = Uri.parse('https://id.solsynth.dev/api/auth/token'); | ||||
|   final userinfoEndpoint = Uri.parse('https://id.solsynth.dev/api/users/me'); | ||||
|   final redirectUrl = Uri.parse('solaragent://auth'); | ||||
|  | ||||
|   static const clientId = "solaragent"; | ||||
| @@ -42,7 +38,7 @@ class AuthGuard { | ||||
|         await pullProfiles(); | ||||
|         return true; | ||||
|       } catch (e) { | ||||
|         logout(); | ||||
|         signoff(); | ||||
|         return false; | ||||
|       } | ||||
|     } else { | ||||
| @@ -89,57 +85,41 @@ class AuthGuard { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Future<void> login(BuildContext context) async { | ||||
|     try { | ||||
|       client = await createClient(context); | ||||
|       storage.write(key: storageKey, value: client!.credentials.toJson()); | ||||
|   Future<void> refreshToken() async { | ||||
|     if (client != null) { | ||||
|       var credentials = await client?.credentials.refresh( | ||||
|           identifier: clientId, secret: clientSecret, basicAuth: false); | ||||
|  | ||||
|       await pullProfiles(); | ||||
|       await subscribeNotify(); | ||||
|     } catch (e) { | ||||
|       print(e); | ||||
|       storage.write(key: storageKey, value: credentials!.toJson()); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Future<void> subscribeNotify() async { | ||||
|     if (client == null) { | ||||
|       return; | ||||
|     } | ||||
|   Future<void> signin(BuildContext context) async { | ||||
|     client = await createClient(context); | ||||
|     storage.write(key: storageKey, value: client!.credentials.toJson()); | ||||
|  | ||||
|     var token = await initializeFirebaseMessaging(); | ||||
|     if (token == null) { | ||||
|       print("failed to initialize firebase messaging..."); | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|     var response = await client!.post( | ||||
|       deviceEndpoint, | ||||
|       headers: {"Content-Type": "application/json"}, | ||||
|       body: jsonEncode({"device_id": token, "provider": "firebase"}), | ||||
|     ); | ||||
|     if (response.statusCode != 200) { | ||||
|       print(response.body); | ||||
|     } | ||||
|     await pullProfiles(); | ||||
|   } | ||||
|  | ||||
|   void logout() { | ||||
|     try { | ||||
|       storage.delete(key: profileKey); | ||||
|       storage.delete(key: storageKey); | ||||
|     } catch (e) { | ||||
|       print(e); | ||||
|     } | ||||
|   void signoff() { | ||||
|     storage.delete(key: profileKey); | ||||
|     storage.delete(key: storageKey); | ||||
|   } | ||||
|  | ||||
|   Future<bool> isAuthorized() async { | ||||
|     const storage = FlutterSecureStorage(); | ||||
|     return await storage.containsKey(key: storageKey); | ||||
|     if (await storage.containsKey(key: storageKey)) { | ||||
|       if (client != null && client!.credentials.isExpired) { | ||||
|         await refreshToken(); | ||||
|       } | ||||
|       return true; | ||||
|     } else { | ||||
|       return false; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Future<dynamic> readProfiles() async { | ||||
|   Future<dynamic> getProfiles() async { | ||||
|     const storage = FlutterSecureStorage(); | ||||
|     return jsonDecode(await storage.read(key: profileKey) ?? "{}"); | ||||
|   } | ||||
|  | ||||
|   AuthGuard._internal(); | ||||
| } | ||||
|   | ||||
| @@ -1,43 +0,0 @@ | ||||
| import 'dart:ui'; | ||||
|  | ||||
| import 'package:firebase_crashlytics/firebase_crashlytics.dart'; | ||||
| import 'package:firebase_messaging/firebase_messaging.dart'; | ||||
| import 'package:firebase_core/firebase_core.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'firebase_options.dart'; | ||||
|  | ||||
| Future<bool> initializeFirebase() async { | ||||
|   await Firebase.initializeApp( | ||||
|     options: DefaultFirebaseOptions.currentPlatform, | ||||
|   ); | ||||
|  | ||||
|   await FirebaseMessaging.instance.requestPermission( | ||||
|     alert: true, | ||||
|     announcement: false, | ||||
|     badge: true, | ||||
|     carPlay: false, | ||||
|     criticalAlert: false, | ||||
|     provisional: false, | ||||
|     sound: true, | ||||
|   ); | ||||
|  | ||||
|   FlutterError.onError = (errorDetails) { | ||||
|     FirebaseCrashlytics.instance.recordFlutterFatalError(errorDetails); | ||||
|   }; | ||||
|   PlatformDispatcher.instance.onError = (error, stack) { | ||||
|     FirebaseCrashlytics.instance.recordError(error, stack, fatal: true); | ||||
|     return true; | ||||
|   }; | ||||
|  | ||||
|   return true; | ||||
| } | ||||
|  | ||||
| Future<String?> initializeFirebaseMessaging() async { | ||||
|   try { | ||||
|     final fcmToken = await FirebaseMessaging.instance.getToken(); | ||||
|     return fcmToken; | ||||
|   } catch (e) { | ||||
|     print("failed to setup firebase messaging: $e"); | ||||
|     return null; | ||||
|   } | ||||
| } | ||||
| @@ -1,81 +0,0 @@ | ||||
| // File generated by FlutterFire CLI. | ||||
| // ignore_for_file: lines_longer_than_80_chars, avoid_classes_with_only_static_members | ||||
| import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; | ||||
| import 'package:flutter/foundation.dart' | ||||
|     show defaultTargetPlatform, kIsWeb, TargetPlatform; | ||||
|  | ||||
| /// Default [FirebaseOptions] for use with your Firebase apps. | ||||
| /// | ||||
| /// Example: | ||||
| /// ```dart | ||||
| /// import 'firebase_options.dart'; | ||||
| /// // ... | ||||
| /// await Firebase.initializeApp( | ||||
| ///   options: DefaultFirebaseOptions.currentPlatform, | ||||
| /// ); | ||||
| /// ``` | ||||
| class DefaultFirebaseOptions { | ||||
|   static FirebaseOptions get currentPlatform { | ||||
|     if (kIsWeb) { | ||||
|       return web; | ||||
|     } | ||||
|     switch (defaultTargetPlatform) { | ||||
|       case TargetPlatform.android: | ||||
|         return android; | ||||
|       case TargetPlatform.iOS: | ||||
|         return ios; | ||||
|       case TargetPlatform.macOS: | ||||
|         return macos; | ||||
|       case TargetPlatform.windows: | ||||
|         throw UnsupportedError( | ||||
|           'DefaultFirebaseOptions have not been configured for windows - ' | ||||
|           'you can reconfigure this by running the FlutterFire CLI again.', | ||||
|         ); | ||||
|       case TargetPlatform.linux: | ||||
|         throw UnsupportedError( | ||||
|           'DefaultFirebaseOptions have not been configured for linux - ' | ||||
|           'you can reconfigure this by running the FlutterFire CLI again.', | ||||
|         ); | ||||
|       default: | ||||
|         throw UnsupportedError( | ||||
|           'DefaultFirebaseOptions are not supported for this platform.', | ||||
|         ); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   static const FirebaseOptions web = FirebaseOptions( | ||||
|     apiKey: 'AIzaSyCjTtCsk3Jo98gDiU2Zh8hX2Y-r2CCsT6g', | ||||
|     appId: '1:659822066072:web:2fbe2e4dc1186e00c013ed', | ||||
|     messagingSenderId: '659822066072', | ||||
|     projectId: 'smartsheep-hydrogen', | ||||
|     authDomain: 'smartsheep-hydrogen.firebaseapp.com', | ||||
|     storageBucket: 'smartsheep-hydrogen.appspot.com', | ||||
|     measurementId: 'G-8HVJ5TVQG8', | ||||
|   ); | ||||
|  | ||||
|   static const FirebaseOptions android = FirebaseOptions( | ||||
|     apiKey: 'AIzaSyBLPaAK4CVW9umXIdUoGOGHO42jKnwZkKo', | ||||
|     appId: '1:659822066072:android:39e699282c97a7cfc013ed', | ||||
|     messagingSenderId: '659822066072', | ||||
|     projectId: 'smartsheep-hydrogen', | ||||
|     storageBucket: 'smartsheep-hydrogen.appspot.com', | ||||
|   ); | ||||
|  | ||||
|   static const FirebaseOptions ios = FirebaseOptions( | ||||
|     apiKey: 'AIzaSyBQB4u2KKe1P5jMG_zWGiUFtpcjQKhG3jY', | ||||
|     appId: '1:659822066072:ios:90dff099ef47fc8fc013ed', | ||||
|     messagingSenderId: '659822066072', | ||||
|     projectId: 'smartsheep-hydrogen', | ||||
|     storageBucket: 'smartsheep-hydrogen.appspot.com', | ||||
|     iosBundleId: 'dev.solsynth.solaragent', | ||||
|   ); | ||||
|  | ||||
|   static const FirebaseOptions macos = FirebaseOptions( | ||||
|     apiKey: 'AIzaSyBQB4u2KKe1P5jMG_zWGiUFtpcjQKhG3jY', | ||||
|     appId: '1:659822066072:ios:17efa96a78467043c013ed', | ||||
|     messagingSenderId: '659822066072', | ||||
|     projectId: 'smartsheep-hydrogen', | ||||
|     storageBucket: 'smartsheep-hydrogen.appspot.com', | ||||
|     iosBundleId: 'dev.solsynth.solaragent.RunnerTests', | ||||
|   ); | ||||
| } | ||||
| @@ -1,18 +1,11 @@ | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:solaragent/auth.dart'; | ||||
| import 'package:solaragent/firebase.dart'; | ||||
| import 'package:solaragent/router.dart'; | ||||
| import 'package:solaragent/widgets/navigation.dart'; | ||||
|  | ||||
| void main() async { | ||||
|   WidgetsFlutterBinding.ensureInitialized(); | ||||
|  | ||||
|   try { | ||||
|     await initializeFirebase(); | ||||
|   } catch (e) { | ||||
|     print(e); | ||||
|   } | ||||
|  | ||||
|   await authClient.pickClient(); | ||||
|  | ||||
|   runApp(const SolarAgent()); | ||||
|   | ||||
| @@ -18,8 +18,8 @@ class AboutScreen extends StatelessWidget { | ||||
|           children: [ | ||||
|             Text('SolarAgent', | ||||
|                 style: Theme.of(context).textTheme.headlineMedium), | ||||
|             Text('Solarworks Official Mobile Helper', | ||||
|                 style: Theme.of(context).textTheme.bodyLarge), | ||||
|             Text('Solar Networks Official Mobile Application', | ||||
|                 style: Theme.of(context).textTheme.bodyMedium), | ||||
|             const SizedBox(height: 20), | ||||
|             FutureBuilder( | ||||
|               future: PackageInfo.fromPlatform(), | ||||
|   | ||||
| @@ -35,7 +35,7 @@ class _AccountScreenState extends State<AccountScreen> { | ||||
|               padding: const EdgeInsets.only(top: 20), | ||||
|               child: NameCard( | ||||
|                 onLogin: () async { | ||||
|                   await authClient.login(context); | ||||
|                   await authClient.signin(context); | ||||
|                   var authorized = await authClient.isAuthorized(); | ||||
|                   setState(() { | ||||
|                     isAuthorized = authorized; | ||||
| @@ -58,7 +58,7 @@ class _AccountScreenState extends State<AccountScreen> { | ||||
|                                   const BorderRadius.all(Radius.circular(40)), | ||||
|                               splashColor: Colors.indigo.withAlpha(30), | ||||
|                               onTap: () async { | ||||
|                                 authClient.logout(); | ||||
|                                 authClient.signoff(); | ||||
|                                 var authorized = | ||||
|                                     await authClient.isAuthorized(); | ||||
|                                 setState(() { | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
| import 'dart:convert'; | ||||
|  | ||||
| import 'package:flutter/cupertino.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:flutter/widgets.dart'; | ||||
| import 'package:solaragent/auth.dart'; | ||||
|  | ||||
| class NotificationScreen extends StatefulWidget { | ||||
| @@ -11,32 +13,32 @@ class NotificationScreen extends StatefulWidget { | ||||
| } | ||||
|  | ||||
| class _NotificationScreenState extends State<NotificationScreen> { | ||||
|   final notificationEndpoint = Uri.parse( | ||||
|       'https://id.solsynth.dev/api/notifications?skip=0&take=25'); | ||||
|   final notificationEndpoint = | ||||
|       Uri.parse('https://id.solsynth.dev/api/notifications?skip=0&take=25'); | ||||
|  | ||||
|   List<dynamic> notifications = List.empty(); | ||||
|  | ||||
|   @override | ||||
|   void initState() { | ||||
|     super.initState(); | ||||
|     _pullNotifications(); | ||||
|     pullNotifications(); | ||||
|   } | ||||
|  | ||||
|   Future<void> _pullNotifications() async { | ||||
|   Future<void> pullNotifications() async { | ||||
|     if (await authClient.isAuthorized()) { | ||||
|       await authClient.pullProfiles(); | ||||
|       var profiles = await authClient.readProfiles(); | ||||
|       setState(() { | ||||
|         notifications = profiles['notifications']; | ||||
|       }); | ||||
|       var res = await authClient.client!.get(notificationEndpoint); | ||||
|       if (res.statusCode == 200) { | ||||
|         setState(() { | ||||
|           notifications = jsonDecode(utf8.decode(res.bodyBytes))["data"]; | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   Future<void> _markAsRead(element) async { | ||||
|   Future<void> markAsRead(element) async { | ||||
|     if (authClient.client != null) { | ||||
|       var id = element['id']; | ||||
|       var uri = | ||||
|           Uri.parse('https://id.solsynth.dev/api/notifications/$id/read'); | ||||
|       var uri = Uri.parse('https://id.solsynth.dev/api/notifications/$id/read'); | ||||
|       await authClient.client!.put(uri); | ||||
|     } | ||||
|   } | ||||
| @@ -45,49 +47,92 @@ class _NotificationScreenState extends State<NotificationScreen> { | ||||
|   Widget build(BuildContext context) { | ||||
|     return Scaffold( | ||||
|       body: SafeArea( | ||||
|         child: Padding( | ||||
|           padding: const EdgeInsets.only(left: 20, right: 20, top: 30), | ||||
|           child: RefreshIndicator( | ||||
|             onRefresh: _pullNotifications, | ||||
|             child: CustomScrollView( | ||||
|               slivers: [ | ||||
|                 notifications.isEmpty | ||||
|                     ? const SliverToBoxAdapter( | ||||
|                         child: Card( | ||||
|                           child: Padding( | ||||
|                             padding: EdgeInsets.all(10), | ||||
|                             child: ListTile( | ||||
|                               leading: Icon(Icons.check), | ||||
|                               title: Text('You\'re done!'), | ||||
|                               subtitle: Text( | ||||
|                                   'There are no notifications unread for you.'), | ||||
|                             ), | ||||
|         child: RefreshIndicator( | ||||
|           onRefresh: pullNotifications, | ||||
|           child: CustomScrollView( | ||||
|             slivers: [ | ||||
|               // Title | ||||
|               SliverToBoxAdapter( | ||||
|                 child: Padding( | ||||
|                   padding: const EdgeInsets.only(left: 10, right: 10, top: 20), | ||||
|                   child: ListTile( | ||||
|                     title: Text( | ||||
|                       'Notifications', | ||||
|                       style: Theme.of(context).textTheme.headlineSmall, | ||||
|                     ), | ||||
|                   ), | ||||
|                 ), | ||||
|               ), | ||||
|               // Content | ||||
|               notifications.isEmpty | ||||
|                   ? SliverToBoxAdapter( | ||||
|                       child: Container( | ||||
|                         padding: const EdgeInsets.symmetric(horizontal: 10), | ||||
|                         color: Colors.grey[300], | ||||
|                         child: const ListTile( | ||||
|                           leading: Icon(Icons.check), | ||||
|                           title: Text('You\'re done!'), | ||||
|                           subtitle: Text( | ||||
|                             'There are no notifications unread for you.', | ||||
|                           ), | ||||
|                         ), | ||||
|                       ) | ||||
|                     : SliverList.builder( | ||||
|                         itemCount: notifications.length, | ||||
|                         itemBuilder: (BuildContext context, int index) { | ||||
|                           var element = notifications[index]; | ||||
|                           return Dismissible( | ||||
|                               key: Key('notification-$index'), | ||||
|                               onDismissed: (direction) { | ||||
|                                 var subject = element["subject"]; | ||||
|                                 _markAsRead(element).then((value) { | ||||
|                                   ScaffoldMessenger.of(context).showSnackBar( | ||||
|                                       SnackBar( | ||||
|                                           content: | ||||
|                                               Text('「$subject」 mark as read'))); | ||||
|                                 }); | ||||
|                               }, | ||||
|                               child: ListTile( | ||||
|                                 title: Text(element["subject"]), | ||||
|                                 subtitle: Text(element["content"]), | ||||
|                               )); | ||||
|                         }, | ||||
|                       ), | ||||
|               ], | ||||
|             ), | ||||
|                     ) | ||||
|                   : SliverList.builder( | ||||
|                       itemCount: notifications.length, | ||||
|                       itemBuilder: (BuildContext context, int index) { | ||||
|                         var element = notifications[index]; | ||||
|                         return Dismissible( | ||||
|                           key: Key('notification-$index'), | ||||
|                           onDismissed: (direction) { | ||||
|                             var subject = element["subject"]; | ||||
|                             markAsRead(element).then((value) { | ||||
|                               ScaffoldMessenger.of(context).showSnackBar( | ||||
|                                 SnackBar( | ||||
|                                   content: RichText( | ||||
|                                     text: TextSpan(children: [ | ||||
|                                       TextSpan( | ||||
|                                         text: subject, | ||||
|                                         style: const TextStyle( | ||||
|                                             fontWeight: FontWeight.bold), | ||||
|                                       ), | ||||
|                                       const TextSpan( | ||||
|                                         text: " is marked as read", | ||||
|                                       ) | ||||
|                                     ]), | ||||
|                                   ), | ||||
|                                 ), | ||||
|                               ); | ||||
|                             }); | ||||
|                             setState(() { | ||||
|                               notifications.removeAt(index); | ||||
|                             }); | ||||
|                           }, | ||||
|                           background: Container( | ||||
|                             color: Colors.green, | ||||
|                           ), | ||||
|                           child: Padding( | ||||
|                             padding: const EdgeInsets.symmetric(horizontal: 10), | ||||
|                             child: ListTile( | ||||
|                               title: Text(element["subject"]), | ||||
|                               subtitle: Text(element["content"]), | ||||
|                             ), | ||||
|                           ), | ||||
|                         ); | ||||
|                       }, | ||||
|                     ), | ||||
|               // Tips | ||||
|               SliverToBoxAdapter( | ||||
|                 child: Padding( | ||||
|                   padding: const EdgeInsets.only(top: 10), | ||||
|                   child: Text( | ||||
|                     "Pull to refresh, swipe to dismiss", | ||||
|                     textAlign: TextAlign.center, | ||||
|                     style: Theme.of(context).textTheme.bodySmall, | ||||
|                   ), | ||||
|                 ), | ||||
|               ), | ||||
|             ], | ||||
|           ), | ||||
|         ), | ||||
|       ), | ||||
|   | ||||
| @@ -13,7 +13,7 @@ class NameCard extends StatelessWidget { | ||||
|  | ||||
|   Future<CircleAvatar> _getAvatar() async { | ||||
|     if (await authClient.isAuthorized()) { | ||||
|       final profiles = await authClient.readProfiles(); | ||||
|       final profiles = await authClient.getProfiles(); | ||||
|       return CircleAvatar(backgroundImage: NetworkImage(profiles["picture"])); | ||||
|     } else { | ||||
|       return const CircleAvatar(child: Icon(Icons.account_circle)); | ||||
| @@ -22,7 +22,7 @@ class NameCard extends StatelessWidget { | ||||
|  | ||||
|   Future<Column> _getDescribe() async { | ||||
|     if (await authClient.isAuthorized()) { | ||||
|       final profiles = await authClient.readProfiles(); | ||||
|       final profiles = await authClient.getProfiles(); | ||||
|       return Column( | ||||
|         crossAxisAlignment: CrossAxisAlignment.start, | ||||
|         children: [ | ||||
|   | ||||
| @@ -5,10 +5,6 @@ | ||||
| import FlutterMacOS | ||||
| import Foundation | ||||
|  | ||||
| import firebase_core | ||||
| import firebase_crashlytics | ||||
| import firebase_messaging | ||||
| import flutter_appauth | ||||
| import flutter_secure_storage_macos | ||||
| import package_info_plus | ||||
| import path_provider_foundation | ||||
| @@ -16,10 +12,6 @@ import shared_preferences_foundation | ||||
| import url_launcher_macos | ||||
|  | ||||
| func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { | ||||
|   FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) | ||||
|   FLTFirebaseCrashlyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCrashlyticsPlugin")) | ||||
|   FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) | ||||
|   FlutterAppauthPlugin.register(with: registry.registrar(forPlugin: "FlutterAppauthPlugin")) | ||||
|   FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) | ||||
|   FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) | ||||
|   PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) | ||||
|   | ||||
							
								
								
									
										100
									
								
								pubspec.lock
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								pubspec.lock
									
									
									
									
									
								
							| @@ -1,14 +1,6 @@ | ||||
| # Generated by pub | ||||
| # See https://dart.dev/tools/pub/glossary#lockfile | ||||
| packages: | ||||
|   _flutterfire_internals: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: _flutterfire_internals | ||||
|       sha256: "4eec93681221723a686ad580c2e7d960e1017cf1a4e0a263c2573c2c6b0bf5cd" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.3.25" | ||||
|   archive: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -129,91 +121,11 @@ packages: | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "7.0.0" | ||||
|   firebase_core: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: firebase_core | ||||
|       sha256: "53316975310c8af75a96e365f9fccb67d1c544ef0acdbf0d88bbe30eedd1c4f9" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.27.0" | ||||
|   firebase_core_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_core_platform_interface | ||||
|       sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "5.0.0" | ||||
|   firebase_core_web: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_core_web | ||||
|       sha256: c8e1d59385eee98de63c92f961d2a7062c5d9a65e7f45bdc7f1b0b205aab2492 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.11.5" | ||||
|   firebase_crashlytics: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: firebase_crashlytics | ||||
|       sha256: c4f1b723d417bc9c4774810e774ff91df8fb0032d33fb2888b2c887e865581b8 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.4.18" | ||||
|   firebase_crashlytics_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_crashlytics_platform_interface | ||||
|       sha256: c5a11fca3df76a98e3fa68fde8b10a08aacb9a7639f619fbfd4dad6c67a08643 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.6.25" | ||||
|   firebase_messaging: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: firebase_messaging | ||||
|       sha256: e41586e0fd04fe9a40424f8b0053d0832e6d04f49e020cdaf9919209a28497e9 | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "14.7.19" | ||||
|   firebase_messaging_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_messaging_platform_interface | ||||
|       sha256: f7a9d74ff7fc588a924f6b2eaeaa148b0db521b13a9db55f6ad45864fa98c06e | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "4.5.27" | ||||
|   firebase_messaging_web: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: firebase_messaging_web | ||||
|       sha256: fc21e771166860c55b103701c5ac7cdb2eec28897b97c42e6e5703cbedf9e02e | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "3.6.8" | ||||
|   flutter: | ||||
|     dependency: "direct main" | ||||
|     description: flutter | ||||
|     source: sdk | ||||
|     version: "0.0.0" | ||||
|   flutter_appauth: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|       name: flutter_appauth | ||||
|       sha256: "6aca161b2a1758478a13f758897fc98688277951dafb4b7e62729c1dfbcefdaa" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "6.0.5" | ||||
|   flutter_appauth_platform_interface: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: flutter_appauth_platform_interface | ||||
|       sha256: "44feaa7058191b5d3cd7c9ff195262725773643121bcada172d49c2ddcff71cb" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "6.0.0" | ||||
|   flutter_launcher_icons: | ||||
|     dependency: "direct dev" | ||||
|     description: | ||||
| @@ -340,10 +252,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: leak_tracker | ||||
|       sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" | ||||
|       sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "10.0.0" | ||||
|     version: "10.0.4" | ||||
|   leak_tracker_flutter_testing: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -356,10 +268,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: leak_tracker_testing | ||||
|       sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 | ||||
|       sha256: d4c8f568c60af6b6daa74c80fc04411765769882600f6bf9cd4b391c96de42ce | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "2.0.1" | ||||
|     version: "2.0.3" | ||||
|   lints: | ||||
|     dependency: transitive | ||||
|     description: | ||||
| @@ -396,10 +308,10 @@ packages: | ||||
|     dependency: transitive | ||||
|     description: | ||||
|       name: meta | ||||
|       sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 | ||||
|       sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" | ||||
|       url: "https://pub.dev" | ||||
|     source: hosted | ||||
|     version: "1.11.0" | ||||
|     version: "1.12.0" | ||||
|   oauth2: | ||||
|     dependency: "direct main" | ||||
|     description: | ||||
|   | ||||
| @@ -35,10 +35,6 @@ dependencies: | ||||
|   # The following adds the Cupertino Icons font to your application. | ||||
|   # Use with the CupertinoIcons class for iOS style icons. | ||||
|   cupertino_icons: ^1.0.2 | ||||
|   firebase_messaging: ^14.7.15 | ||||
|   firebase_core: ^2.25.4 | ||||
|   firebase_crashlytics: ^3.4.14 | ||||
|   flutter_appauth: ^6.0.4 | ||||
|   flutter_secure_storage: ^9.0.0 | ||||
|   oauth2: ^2.0.2 | ||||
|   http: ^1.2.0 | ||||
|   | ||||
| @@ -6,13 +6,10 @@ | ||||
|  | ||||
| #include "generated_plugin_registrant.h" | ||||
|  | ||||
| #include <firebase_core/firebase_core_plugin_c_api.h> | ||||
| #include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h> | ||||
| #include <url_launcher_windows/url_launcher_windows.h> | ||||
|  | ||||
| void RegisterPlugins(flutter::PluginRegistry* registry) { | ||||
|   FirebaseCorePluginCApiRegisterWithRegistrar( | ||||
|       registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); | ||||
|   FlutterSecureStorageWindowsPluginRegisterWithRegistrar( | ||||
|       registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin")); | ||||
|   UrlLauncherWindowsRegisterWithRegistrar( | ||||
|   | ||||
| @@ -3,7 +3,6 @@ | ||||
| # | ||||
|  | ||||
| list(APPEND FLUTTER_PLUGIN_LIST | ||||
|   firebase_core | ||||
|   flutter_secure_storage_windows | ||||
|   url_launcher_windows | ||||
| ) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user