diff --git a/ios/Podfile b/ios/Podfile index b2aa6c1..2d17462 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -40,6 +40,9 @@ end post_install do |installer| installer.pods_project.targets.each do |target| flutter_additional_ios_build_settings(target) + target.build_configurations.each do |config| + config.build_settings['BUILD_LIBRARY_FOR_DISTRIBUTION'] = 'NO' + end end # ################ Awesome Notifications pod modification ################### diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f237dd0..4903c89 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -15,18 +15,33 @@ PODS: - HLSCachingReverseProxyServer - PINCache - Cache (6.0.0) + - Firebase/Auth (10.25.0): + - Firebase/CoreOnly + - FirebaseAuth (~> 10.25.0) - Firebase/CoreOnly (10.25.0): - FirebaseCore (= 10.25.0) - Firebase/Messaging (10.25.0): - Firebase/CoreOnly - FirebaseMessaging (~> 10.25.0) - - firebase_core (2.31.0): + - firebase_auth (4.19.6): + - Firebase/Auth (= 10.25.0) + - firebase_core + - Flutter + - firebase_core (2.31.1): - Firebase/CoreOnly (= 10.25.0) - Flutter - firebase_messaging (14.9.2): - Firebase/Messaging (= 10.25.0) - firebase_core - Flutter + - FirebaseAppCheckInterop (10.25.0) + - FirebaseAuth (10.25.0): + - FirebaseAppCheckInterop (~> 10.17) + - FirebaseCore (~> 10.0) + - GoogleUtilities/AppDelegateSwizzler (~> 7.8) + - GoogleUtilities/Environment (~> 7.8) + - GTMSessionFetcher/Core (< 4.0, >= 2.1) + - RecaptchaInterop (~> 100.0) - FirebaseCore (10.25.0): - FirebaseCoreInternal (~> 10.0) - GoogleUtilities/Environment (~> 7.12) @@ -86,6 +101,7 @@ PODS: - GoogleUtilities/UserDefaults (7.13.3): - GoogleUtilities/Logger - GoogleUtilities/Privacy + - GTMSessionFetcher/Core (3.4.1) - HLSCachingReverseProxyServer (0.1.0): - GCDWebServer (~> 3.5) - PINCache (>= 3.0.1-beta.3) @@ -116,6 +132,7 @@ PODS: - PINOperation (~> 1.2.3) - PINOperation (1.2.3) - PromisesObjC (2.4.0) + - RecaptchaInterop (100.0.0) - record (0.0.1): - Flutter - rive_common (0.0.1): @@ -137,6 +154,7 @@ DEPENDENCIES: - awesome_notifications (from `.symlinks/plugins/awesome_notifications/ios`) - awesome_notifications_core (from `.symlinks/plugins/awesome_notifications_core/ios`) - better_player (from `.symlinks/plugins/better_player/ios`) + - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`) - firebase_core (from `.symlinks/plugins/firebase_core/ios`) - firebase_messaging (from `.symlinks/plugins/firebase_messaging/ios`) - Flutter (from `Flutter`) @@ -159,6 +177,8 @@ SPEC REPOS: trunk: - Cache - Firebase + - FirebaseAppCheckInterop + - FirebaseAuth - FirebaseCore - FirebaseCoreInternal - FirebaseInstallations @@ -166,12 +186,14 @@ SPEC REPOS: - GCDWebServer - GoogleDataTransport - GoogleUtilities + - GTMSessionFetcher - HLSCachingReverseProxyServer - IosAwnCore - nanopb - PINCache - PINOperation - PromisesObjC + - RecaptchaInterop - TOCropViewController EXTERNAL SOURCES: @@ -185,6 +207,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/awesome_notifications_core/ios" better_player: :path: ".symlinks/plugins/better_player/ios" + firebase_auth: + :path: ".symlinks/plugins/firebase_auth/ios" firebase_core: :path: ".symlinks/plugins/firebase_core/ios" firebase_messaging: @@ -228,8 +252,11 @@ SPEC CHECKSUMS: better_player: 2406bfe8175203c7a46fa15f9d778d73b12e1646 Cache: 4ca7e00363fca5455f26534e5607634c820ffc2d Firebase: 0312a2352584f782ea56f66d91606891d4607f06 - firebase_core: 0b39f4f424e02eecabb2356ddf331fa07b772af8 + firebase_auth: 193301a23be35329120526c6a83672ea40676472 + firebase_core: 22e117a2e0dec3cb318c8f53f2dd01c140375617 firebase_messaging: 8999827b6efc9c3ab4b1f9dc246deaa7f13dbf88 + FirebaseAppCheckInterop: 5da5ce93e8797a215e3f677fb0654b74e736c8b8 + FirebaseAuth: c0f93dcc570c9da2bffb576969d793e95c344fbb FirebaseCore: 7ec4d0484817f12c3373955bc87762d96842d483 FirebaseCoreInternal: 910a81992c33715fec9263ca7381d59ab3a750b7 FirebaseInstallations: 91950fe859846fff0fbd296180909dd273103b09 @@ -241,6 +268,7 @@ SPEC CHECKSUMS: GCDWebServer: 2c156a56c8226e2d5c0c3f208a3621ccffbe3ce4 GoogleDataTransport: 6c09b596d841063d76d4288cc2d2f42cc36e1e2a GoogleUtilities: ea963c370a38a8069cc5f7ba4ca849a60b6d7d15 + GTMSessionFetcher: 8000756fc1c19d2e5697b90311f7832d2e33f6cd HLSCachingReverseProxyServer: 59935e1e0244ad7f3375d75b5ef46e8eb26ab181 home_widget: 0434835a4c9a75704264feff6be17ea40e0f0d57 image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98 @@ -252,6 +280,7 @@ SPEC CHECKSUMS: PINCache: d9a87a0ff397acffe9e2f0db972ac14680441158 PINOperation: fb563bcc9c32c26d6c78aaff967d405aa2ee74a7 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 + RecaptchaInterop: 7d1a4a01a6b2cb1610a47ef3f85f0c411434cb21 record: cae05d8dd3cdb1dea3511b20e5a5811a1ae00d0d rive_common: c537b4eed761e903a9403d93c347b69bd7a4762f sqflite: 673a0e54cc04b7d6dba8d24fb8095b31c3a99eec @@ -260,6 +289,6 @@ SPEC CHECKSUMS: wakelock: d0fc7c864128eac40eba1617cb5264d9c940b46f webview_flutter_wkwebview: be0f0d33777f1bfd0c9fdcb594786704dbf65f36 -PODFILE CHECKSUM: 43b7f04e2401bb5f4734fd7bf7644eef34165887 +PODFILE CHECKSUM: d9825a12b7b9489d4776b9c9434f6b977b656841 COCOAPODS: 1.15.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 0f96cdd..c9f31e5 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -61,6 +61,7 @@ 98ACB01D5FA5A78DB2686183 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; B2EEE8F55C4C405BB5B4B0F1 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; C97DED20C4A171F16FB949CD /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + D143FC822BFF1A95002238F7 /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = ""; }; D167C7BB2BFE275B0039A883 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; D167C7BD2BFE275B0039A883 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; D194CE3D27D4A4740049AFC7 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; @@ -146,6 +147,7 @@ 97C146F01CF9000F007C117D /* Runner */ = { isa = PBXGroup; children = ( + D143FC822BFF1A95002238F7 /* Runner.entitlements */, D194CE3D27D4A4740049AFC7 /* GoogleService-Info.plist */, 97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FD1CF9000F007C117D /* Assets.xcassets */, @@ -241,6 +243,8 @@ Base, ); mainGroup = 97C146E51CF9000F007C117D; + packageReferences = ( + ); productRefGroup = 97C146EF1CF9000F007C117D /* Products */; projectDirPath = ""; projectRoot = ""; @@ -488,15 +492,18 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 9YUQA68P22; + DEVELOPMENT_TEAM = MB63F4VV5H; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Didvan; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.news"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -623,15 +630,18 @@ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 9YUQA68P22; + DEVELOPMENT_TEAM = MB63F4VV5H; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Didvan; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.news"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -652,15 +662,18 @@ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; - DEVELOPMENT_TEAM = 9YUQA68P22; + DEVELOPMENT_TEAM = MB63F4VV5H; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; INFOPLIST_KEY_CFBundleDisplayName = Didvan; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.news"; + IPHONEOS_DEPLOYMENT_TARGET = 12.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -680,6 +693,7 @@ baseConfigurationReference = D5C8C888FE458FD90D3E41DB /* Pods-RunnerTests.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; @@ -714,6 +728,7 @@ baseConfigurationReference = B2EEE8F55C4C405BB5B4B0F1 /* Pods-RunnerTests.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; @@ -746,6 +761,7 @@ baseConfigurationReference = F9A8A938029FFAC4FD6CE33B /* Pods-RunnerTests.profile.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + BUILD_LIBRARY_FOR_DISTRIBUTION = NO; BUNDLE_LOADER = "$(TEST_HOST)"; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 0000000..ec60633 --- /dev/null +++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,123 @@ +{ + "originHash" : "c63c63846d9c539229e96de38d6af51417e28c0ee9a0bc48bd0f0f19d923c329", + "pins" : [ + { + "identity" : "abseil-cpp-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/abseil-cpp-binary.git", + "state" : { + "revision" : "748c7837511d0e6a507737353af268484e1745e2", + "version" : "1.2024011601.1" + } + }, + { + "identity" : "app-check", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/app-check.git", + "state" : { + "revision" : "076b241a625e25eac22f8849be256dfb960fcdfe", + "version" : "10.19.1" + } + }, + { + "identity" : "firebase-ios-sdk", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/firebase-ios-sdk", + "state" : { + "revision" : "9d17b500cd98d9a7009751ad62f802e152e97021", + "version" : "10.26.0" + } + }, + { + "identity" : "googleappmeasurement", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleAppMeasurement.git", + "state" : { + "revision" : "16244d177c4e989f87b25e9db1012b382cfedc55", + "version" : "10.25.0" + } + }, + { + "identity" : "googledatatransport", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleDataTransport.git", + "state" : { + "revision" : "a637d318ae7ae246b02d7305121275bc75ed5565", + "version" : "9.4.0" + } + }, + { + "identity" : "googleutilities", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/GoogleUtilities.git", + "state" : { + "revision" : "57a1d307f42df690fdef2637f3e5b776da02aad6", + "version" : "7.13.3" + } + }, + { + "identity" : "grpc-binary", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/grpc-binary.git", + "state" : { + "revision" : "e9fad491d0673bdda7063a0341fb6b47a30c5359", + "version" : "1.62.2" + } + }, + { + "identity" : "gtm-session-fetcher", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/gtm-session-fetcher.git", + "state" : { + "revision" : "0382ca27f22fb3494cf657d8dc356dc282cd1193", + "version" : "3.4.1" + } + }, + { + "identity" : "interop-ios-for-google-sdks", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/interop-ios-for-google-sdks.git", + "state" : { + "revision" : "2d12673670417654f08f5f90fdd62926dc3a2648", + "version" : "100.0.0" + } + }, + { + "identity" : "leveldb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/leveldb.git", + "state" : { + "revision" : "a0bc79961d7be727d258d33d5a6b2f1023270ba1", + "version" : "1.22.5" + } + }, + { + "identity" : "nanopb", + "kind" : "remoteSourceControl", + "location" : "https://github.com/firebase/nanopb.git", + "state" : { + "revision" : "b7e1104502eca3a213b46303391ca4d3bc8ddec1", + "version" : "2.30910.0" + } + }, + { + "identity" : "promises", + "kind" : "remoteSourceControl", + "location" : "https://github.com/google/promises.git", + "state" : { + "revision" : "540318ecedd63d883069ae7f1ed811a2df00b6ac", + "version" : "2.4.0" + } + }, + { + "identity" : "swift-protobuf", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-protobuf.git", + "state" : { + "revision" : "9f0c76544701845ad98716f3f6a774a892152bcb", + "version" : "1.26.0" + } + } + ], + "version" : 3 +} diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 3e69320..749f9b4 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -70,6 +70,16 @@ ReferencedContainer = "container:Runner.xcodeproj"> + + + + + + - - CADisableMinimumFrameDurationOnPhone - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - didvan - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - FirebaseAppDelegateProxyEnabled - - LSRequiresIPhoneOS - - NSCameraUsageDescription - We need to access to the user gallery to add user profile photo - NSMicrophoneUsageDescription - We need to access to the microphone to record audio file - NSPhotoLibraryUsageDescription - We need to access to the user gallery to add user profile photo - UIApplicationSupportsIndirectInputEvents - - UIBackgroundModes - - audio - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - UIInterfaceOrientationPortrait - - UIViewControllerBasedStatusBarAppearance - - UNNotificationServiceExtension - - $(PRODUCT_BUNDLE_IDENTIFIER).MyNotificationServiceExtension - - + + CADisableMinimumFrameDurationOnPhone + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + didvan + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + FirebaseAppDelegateProxyEnabled + + LSRequiresIPhoneOS + + NSCameraUsageDescription + We need to access to the user gallery to add user profile photo + NSMicrophoneUsageDescription + We need to access to the microphone to record audio file + NSPhotoLibraryUsageDescription + We need to access to the user gallery to add user profile photo + UIApplicationSupportsIndirectInputEvents + + UIBackgroundModes + + audio + fetch + remote-notification + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortrait + + UIViewControllerBasedStatusBarAppearance + + UNNotificationServiceExtension + + $(PRODUCT_BUNDLE_IDENTIFIER).MyNotificationServiceExtension + + diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements new file mode 100644 index 0000000..903def2 --- /dev/null +++ b/ios/Runner/Runner.entitlements @@ -0,0 +1,8 @@ + + + + + aps-environment + development + + diff --git a/lib/main.dart b/lib/main.dart index af419b0..8492d52 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,12 +1,18 @@ +import 'dart:io'; + import 'package:android_intent_plus/android_intent.dart'; +import 'package:awesome_notifications/awesome_notifications.dart'; import 'package:bot_toast/bot_toast.dart'; import 'package:didvan/config/theme_data.dart'; +import 'package:didvan/models/notification_message.dart'; import 'package:didvan/providers/media.dart'; import 'package:didvan/providers/theme.dart'; import 'package:didvan/providers/user.dart'; import 'package:didvan/routes/route_generator.dart'; import 'package:didvan/routes/routes.dart'; import 'package:didvan/services/app_home_widget/home_widget_repository.dart'; +import 'package:didvan/services/app_initalizer.dart'; +import 'package:didvan/services/notification/awsome/awsome_notification_controller.dart'; import 'package:didvan/services/notification/awsome/awsome_notification_handler.dart'; import 'package:didvan/services/notification/fcm/firebase_notification_handler.dart'; import 'package:didvan/views/podcasts/podcasts_state.dart'; @@ -24,24 +30,10 @@ final GlobalKey navigatorKey = GlobalKey(); @pragma('vm:entry-point') Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp( - options: kIsWeb - ? const FirebaseOptions( - apiKey: "AIzaSyA0HZjKpRuPOi1SC3f_EZTvlS3mcj9UVo0", - authDomain: "didvan-9b7da.firebaseapp.com", - projectId: "didvan-9b7da", - storageBucket: "didvan-9b7da.appspot.com", - messagingSenderId: "935017686266", - appId: "1:935017686266:web:a93f7a19bed23c51d2d543", - measurementId: "G-80B4H9E8Y0") - : const FirebaseOptions( - apiKey: 'AIzaSyBp-UHjWeM0H0UHtX5yguFKG-riMzvvCzw', - appId: '1:935017686266:android:f9cbc9aba8e3d65ed2d543', - messagingSenderId: '935017686266', - projectId: 'didvan-9b7da', - ), - ); - AwsomeNotificationHandler().show(message); + await AppInitializer.initializeFirebase(); + await AwsomeNotificationHandler.startListeningNotificationEvents(); + await AwsomeNotificationHandler().show(message); + return; } @@ -66,8 +58,8 @@ void main() async { //ignore: deprecated_member_use HomeWidget.registerBackgroundCallback(_backgroundCallbackHomeWidget); HomeWidget.registerInteractivityCallback(_backgroundCallbackHomeWidget); - AwsomeNotificationHandler().alarm(); - FirebaseNotificationHandler().initial(); + await AwsomeNotificationHandler().alarm(); + await AppInitializer.initializeFirebase(); } catch (e) { debugPrintStack(); } @@ -90,6 +82,8 @@ class _DidvanState extends State with WidgetsBindingObserver { @override void initState() { + AwsomeNotificationHandler.startListeningNotificationEvents(); + super.initState(); WidgetsBinding.instance.addObserver(this); } @@ -108,6 +102,12 @@ class _DidvanState extends State with WidgetsBindingObserver { var r = await HomeWidget.getWidgetData("cRoute", defaultValue: ''); if (r!.toString() != Routes.splash) { await HomeWidgetRepository.decideWhereToGo(); + + NotificationMessage? data = HomeWidgetRepository.data; + print("hhhhshahahjsfghasgfhjgfsahjghgfhgsahfghsag $data"); + if (data != null) { + await HomeWidgetRepository.decideWhereToGoNotif(); + } } } } diff --git a/lib/models/message_data/message_data.dart b/lib/models/message_data/message_data.dart index cc9f81f..893c4d8 100644 --- a/lib/models/message_data/message_data.dart +++ b/lib/models/message_data/message_data.dart @@ -5,7 +5,7 @@ import 'news_attachment.dart'; import 'radar_attachment.dart'; class MessageData { - final int id; + int id; final String? text; final String? audio; final bool writedByAdmin; @@ -16,7 +16,7 @@ class MessageData { final File? audioFile; final int? audioDuration; - const MessageData({ + MessageData({ required this.id, required this.writedByAdmin, required this.readed, diff --git a/lib/providers/user.dart b/lib/providers/user.dart index cf3d984..69720ad 100644 --- a/lib/providers/user.dart +++ b/lib/providers/user.dart @@ -32,12 +32,16 @@ class UserProvider extends CoreProvier { static final List _itemMarkQueue = []; Future setAndGetToken({String? newToken}) async { - if (newToken == null) { - final token = await StorageService.getValue(key: 'token'); - return token; + try { + if (newToken == null) { + final token = await StorageService.getValue(key: 'token'); + return token; + } + await StorageService.setValue(key: 'token', value: newToken); + return null; + } catch (e) { + return null; } - await StorageService.setValue(key: 'token', value: newToken); - return null; } Future getUserInfo() async { @@ -49,18 +53,27 @@ class UserProvider extends CoreProvier { return false; } if (service.isSuccess) { - user = User.fromJson(service.result['user']); - await StorageService.setValue( - key: 'notificationTimeRangeStart', - value: service.result['user']['start'], - ); - await StorageService.setValue( - key: 'notificationTimeRangeEnd', - value: service.result['user']['end'], - ); - AppInitializer.initializeFirebase().then((_) => _registerFirebaseToken()); - return true; + try { + user = User.fromJson(service.result['user']); + await StorageService.setValue( + key: 'notificationTimeRangeStart', + value: service.result['user']['start'], + ); + await StorageService.setValue( + key: 'notificationTimeRangeEnd', + value: service.result['user']['end'], + ); + + AppInitializer.initializeFirebase().then((_) { + _registerFirebaseToken(); + }).catchError((err) {}); + + return true; + } catch (e) { + return false; + } } + throw 'Getting user from API failed!'; } diff --git a/lib/routes/route_generator.dart b/lib/routes/route_generator.dart index 148de1e..ad24918 100644 --- a/lib/routes/route_generator.dart +++ b/lib/routes/route_generator.dart @@ -137,11 +137,16 @@ class RouteGenerator { ); case Routes.podcasts: return _createRoute( - const Podcasts(viewPodcasts: true), + Podcasts( + viewPodcasts: true, + pageData: settings.arguments as Map?, + ), ); case Routes.videocasts: return _createRoute( - const Podcasts(), + Podcasts( + pageData: settings.arguments as Map?, + ), ); case Routes.radars: return _createRoute( @@ -160,7 +165,9 @@ class RouteGenerator { case Routes.infography: return _createRoute(ChangeNotifierProvider( create: (context) => InfographyScreenState(), - child: const InfographyScreen(), + child: InfographyScreen( + pageData: settings.arguments as Map?, + ), )); case Routes.radarDetails: diff --git a/lib/services/app_home_widget/home_widget_repository.dart b/lib/services/app_home_widget/home_widget_repository.dart index c965ba2..862afed 100644 --- a/lib/services/app_home_widget/home_widget_repository.dart +++ b/lib/services/app_home_widget/home_widget_repository.dart @@ -1,3 +1,4 @@ +import 'package:didvan/models/notification_message.dart'; import 'package:flutter/cupertino.dart'; import 'package:home_widget/home_widget.dart'; import 'package:persian_number_utility/persian_number_utility.dart'; @@ -90,54 +91,53 @@ class HomeWidgetRepository { '${data.link}', mode: LaunchMode.inAppWebView, ); - return; - } - - switch (data.type!) { - case "infography": - route = Routes.infography; - args = { - // 'onMarkChanged': (id, value) => - // markChangeHandler(data.type, id, value), - 'id': data.id, - 'args': const InfographyRequestArgs(page: 0), - 'hasUnmarkConfirmation': false, - }; - break; - case "news": - route = Routes.newsDetails; - args = { - // 'onMarkChanged': (id, value) => - // markChangeHandler(data.type, id, value), - 'id': data.id, - 'args': const NewsRequestArgs(page: 0), - 'hasUnmarkConfirmation': false, - }; - break; - case "radar": - route = Routes.radarDetails; - args = { - // 'onMarkChanged': (id, value) => - // markChangeHandler(data.type, id, value), - 'id': data.id, - 'args': const RadarRequestArgs(page: 0), - 'hasUnmarkConfirmation': false, - }; - break; - case "video": - route = Routes.studioDetails; - args = { - 'type': 'podcast', - 'id': data.id, - }; - break; - case "podcast": - route = Routes.podcasts; - args = { - 'type': 'podcast', - 'id': data.id, - }; - break; + } else { + switch (data.type!) { + case "infography": + route = Routes.infography; + args = { + // 'onMarkChanged': (id, value) => + // markChangeHandler(data.type, id, value), + 'id': data.id, + 'args': const InfographyRequestArgs(page: 0), + 'hasUnmarkConfirmation': false, + }; + break; + case "news": + route = Routes.newsDetails; + args = { + // 'onMarkChanged': (id, value) => + // markChangeHandler(data.type, id, value), + 'id': data.id, + 'args': const NewsRequestArgs(page: 0), + 'hasUnmarkConfirmation': false, + }; + break; + case "radar": + route = Routes.radarDetails; + args = { + // 'onMarkChanged': (id, value) => + // markChangeHandler(data.type, id, value), + 'id': data.id, + 'args': const RadarRequestArgs(page: 0), + 'hasUnmarkConfirmation': false, + }; + break; + case "video": + route = Routes.studioDetails; + args = { + 'type': 'podcast', + 'id': data.id, + }; + break; + case "podcast": + route = Routes.podcasts; + args = { + 'type': 'podcast', + 'id': data.id, + }; + break; + } } } @@ -151,4 +151,78 @@ class HomeWidgetRepository { await HomeWidget.saveWidgetData("uri", ""); return; } + + static NotificationMessage? data; + static Future decideWhereToGoNotif() async { + NotificationMessage? data = HomeWidgetRepository.data; + // Navigate into pages, avoiding to open the notification details page over another details page already opened + String route = ""; + dynamic args; + bool openComments = data!.notificationType.toString() == "2"; + + if (data.link.toString().isEmpty) { + switch (data.type!) { + case "infography": + route = Routes.infography; + args = { + // 'onMarkChanged': (id, value) => + // markChangeHandler(data.type, id, value), + 'id': int.parse(data.id.toString()), + 'args': const InfographyRequestArgs(page: 0), + 'hasUnmarkConfirmation': false, + 'goToComment': openComments + }; + break; + case "news": + route = Routes.newsDetails; + args = { + // 'onMarkChanged': (id, value) => + // markChangeHandler(data.type, id, value), + 'id': int.parse(data.id.toString()), + 'args': const NewsRequestArgs(page: 0), + 'hasUnmarkConfirmation': false, + 'goToComment': openComments + }; + break; + case "radar": + route = Routes.radarDetails; + args = { + // 'onMarkChanged': (id, value) => + // markChangeHandler(data.type, id, value), + 'id': int.parse(data.id.toString()), + 'args': const RadarRequestArgs(page: 0), + 'hasUnmarkConfirmation': false, + 'goToComment': openComments + }; + break; + case "video": + route = Routes.studioDetails; + args = { + 'type': 'podcast', + 'id': int.parse(data.id.toString()), + 'goToComment': openComments + }; + break; + case "podcast": + route = Routes.podcasts; + args = { + 'type': 'podcast', + 'id': int.parse(data.id.toString()), + 'goToComment': openComments + }; + break; + } + } else { + if (data.link!.startsWith('http')) { + launchUrlString( + '${data.link}', + mode: LaunchMode.inAppWebView, + ); + } + } + if (route.isNotEmpty) { + navigatorKey.currentState!.pushNamed(route, arguments: args); + } + return; + } } diff --git a/lib/services/app_initalizer.dart b/lib/services/app_initalizer.dart index 757f5c2..d632562 100644 --- a/lib/services/app_initalizer.dart +++ b/lib/services/app_initalizer.dart @@ -43,19 +43,49 @@ class AppInitializer { } static Future initilizeSettings() async { - final brightness = await StorageService.getValue(key: 'brightness'); - if (brightness != null) { - final themeMode = brightness == 'dark' ? ThemeMode.dark : ThemeMode.light; - final fontFamily = await StorageService.getValue(key: 'fontFamily'); - final fontScale = double.parse( - await StorageService.getValue(key: 'fontSizeScale'), - ); - return SettingsData( - fontFamily: fontFamily, - fontScale: fontScale, - themeMode: themeMode, - ); - } else { + try { + final brightness = await StorageService.getValue(key: 'brightness'); + + if (brightness != null) { + final themeMode = + brightness == 'dark' ? ThemeMode.dark : ThemeMode.light; + final fontFamily = await StorageService.getValue(key: 'fontFamily'); + final fontScale = double.parse( + await StorageService.getValue(key: 'fontSizeScale'), + ); + return SettingsData( + fontFamily: fontFamily, + fontScale: fontScale, + themeMode: themeMode, + ); + } else { + await StorageService.setValue( + key: 'notificationTimeRangeStart', + value: '0', + ); + await StorageService.setValue( + key: 'notificationTimeRangeEnd', + value: '24', + ); + await StorageService.setValue( + key: 'fontFamily', + value: 'Dana-FA', + ); + await StorageService.setValue( + key: 'fontSizeScale', + value: '1', + ); + await StorageService.setValue( + key: 'brightness', + value: 'light', + ); + return SettingsData( + fontFamily: 'Dana-FA', + fontScale: 1, + themeMode: ThemeMode.light, + ); + } + } catch (e) { await StorageService.setValue( key: 'notificationTimeRangeStart', value: '0', @@ -141,18 +171,26 @@ class AppInitializer { appId: '1:935017686266:ios:de47638bd662463fd2d543', messagingSenderId: '935017686266', projectId: 'didvan-9b7da', + // iosBundleId: "com.didvan.didvanapp", + // storageBucket: "didvan-9b7da.appspot.com", + // iosClientId: + // "935017686266-54hu01v9cc5pqpgofo1gk2n3hegj4r2m.apps.googleusercontent.com" ), ); } catch (e) { Firebase.app(); } + final initMsg = await FirebaseMessaging.instance.getInitialMessage(); + if (initMsg != null) { + print("aaaaaaaaaa: ${initMsg.data}"); clickAction = initMsg.data['click_action'].replaceAll( 'navigate-', '', ); } + final FirebaseMessaging fcm = FirebaseMessaging.instance; fcmToken = await fcm.getToken( vapidKey: kIsWeb diff --git a/lib/services/notification/awsome/awsome_notification_controller.dart b/lib/services/notification/awsome/awsome_notification_controller.dart index 74bbb40..a417a57 100644 --- a/lib/services/notification/awsome/awsome_notification_controller.dart +++ b/lib/services/notification/awsome/awsome_notification_controller.dart @@ -1,12 +1,6 @@ import 'package:awesome_notifications/awesome_notifications.dart'; -import 'package:didvan/main.dart'; -import 'package:url_launcher/url_launcher_string.dart'; - +import 'package:didvan/services/app_home_widget/home_widget_repository.dart'; import '../../../models/notification_message.dart'; -import '../../../models/requests/infography.dart'; -import '../../../models/requests/news.dart'; -import '../../../models/requests/radar.dart'; -import '../../../routes/routes.dart'; class NotificationController { /// Use this method to detect when a new notification or a schedule is created @@ -14,7 +8,8 @@ class NotificationController { static Future onNotificationCreatedMethod( ReceivedNotification receivedNotification) async { // Your code goes here - // print("onNotificationCreatedMethod--------------------------------------------------------------"); + print( + "onNotificationCreatedMethod--------------------------------------------------------------"); } /// Use this method to detect every time that a new notification is displayed @@ -22,7 +17,8 @@ class NotificationController { static Future onNotificationDisplayedMethod( ReceivedNotification receivedNotification) async { // Your code goes here - // print("onNotificationDisplayedMethod--------------------------------------------------------------"); + print( + "onNotificationDisplayedMethod--------------------------------------------------------------"); } /// Use this method to detect if the user dismissed a notification @@ -30,88 +26,25 @@ class NotificationController { static Future onDismissActionReceivedMethod( ReceivedAction receivedAction) async { // Your code goes here - // print("onDismissActionReceivedMethod--------------------------------------------------------------"); + print( + "onDismissActionReceivedMethod--------------------------------------------------------------"); } /// Use this method to detect when the user taps on a notification or action button @pragma("vm:entry-point") static Future onActionReceivedMethod( ReceivedAction receivedAction) async { + print("obiiiiiiiiiiiiiiii $receivedAction"); NotificationMessage data = NotificationMessage.fromJson(receivedAction.payload!); // Your code goes here - // Navigate into pages, avoiding to open the notification details page over another details page already opened - String route = ""; - dynamic args; - bool openComments = data.notificationType.toString() == "2"; - - if (data.link.toString().isEmpty) { - switch (data.type!) { - case "infography": - route = Routes.infography; - args = { - // 'onMarkChanged': (id, value) => - // markChangeHandler(data.type, id, value), - 'id': int.parse(data.id.toString()), - 'args': const InfographyRequestArgs(page: 0), - 'hasUnmarkConfirmation': false, - 'goToComment': openComments - }; - break; - case "news": - route = Routes.newsDetails; - args = { - // 'onMarkChanged': (id, value) => - // markChangeHandler(data.type, id, value), - 'id': int.parse(data.id.toString()), - 'args': const NewsRequestArgs(page: 0), - 'hasUnmarkConfirmation': false, - 'goToComment': openComments - }; - break; - case "radar": - route = Routes.radarDetails; - args = { - // 'onMarkChanged': (id, value) => - // markChangeHandler(data.type, id, value), - 'id': int.parse(data.id.toString()), - 'args': const RadarRequestArgs(page: 0), - 'hasUnmarkConfirmation': false, - 'goToComment': openComments - }; - break; - case "video": - route = Routes.studioDetails; - args = { - 'type': 'podcast', - 'id': int.parse(data.id.toString()), - 'goToComment': openComments - }; - break; - case "podcast": - route = Routes.podcasts; - args = { - 'type': 'podcast', - 'id': data.id, - }; - break; - } - } else { - if (data.link!.startsWith('http')) { - launchUrlString( - '${data.link}', - mode: LaunchMode.inAppWebView, - ); - } - } - if (route.isNotEmpty) { - navigatorKey.currentState!.pushNamed(route, arguments: args); - } - + HomeWidgetRepository.data = data; + return; // MyApp.navigatorKey.currentState?.pushNamedAndRemoveUntil('/notification-page', // (route) => (route.settings.name != '/notification-page') || route.isFirst, // arguments: receivedAction); - // print("onActionReceivedMethod--------------------------------------------------------------"); + print( + "onActionReceivedMethod--------------------------------------------------------------"); } } diff --git a/lib/services/notification/awsome/awsome_notification_handler.dart b/lib/services/notification/awsome/awsome_notification_handler.dart index 67c53a4..4da5f81 100644 --- a/lib/services/notification/awsome/awsome_notification_handler.dart +++ b/lib/services/notification/awsome/awsome_notification_handler.dart @@ -1,7 +1,9 @@ +import 'dart:io'; + import 'package:awesome_notifications/awesome_notifications.dart'; +import 'package:didvan/services/storage/storage.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; -import 'package:home_widget/home_widget.dart'; import 'package:intl/intl.dart'; import '../../../models/notification_message.dart'; @@ -11,24 +13,26 @@ import '../../network/request_helper.dart'; import 'awsome_notification_controller.dart'; class AwsomeNotificationHandler { - alarm() async { + static ReceivedAction? initialAction; + alarm() async { AwesomeNotifications().initialize( // set the icon to null if you want to use the default app icon null, [ NotificationChannel( - channelKey: 'alerts', - channelName: 'Alerts', - channelDescription: 'Notification tests as alerts', - playSound: true, - onlyAlertOnce: true, - groupAlertBehavior: GroupAlertBehavior.Children, - importance: NotificationImportance.High, - defaultPrivacy: NotificationPrivacy.Public, - defaultColor: const Color(0xFF007EA7), - criticalAlerts: true, - ledColor: Colors.white) + channelKey: 'alerts', + channelName: 'Alerts', + channelDescription: 'Notification tests as alerts', + playSound: true, + onlyAlertOnce: true, + groupAlertBehavior: GroupAlertBehavior.Children, + importance: NotificationImportance.High, + defaultPrivacy: NotificationPrivacy.Public, + defaultColor: const Color(0xFF007EA7), + criticalAlerts: true, + ledColor: Colors.white, + ) ], // Channel groups are only visual and are not required @@ -39,15 +43,10 @@ class AwsomeNotificationHandler { // ], debug: true); - - AwesomeNotifications().setListeners( - onActionReceivedMethod: NotificationController.onActionReceivedMethod, - onNotificationCreatedMethod: - NotificationController.onNotificationCreatedMethod, - onNotificationDisplayedMethod: - NotificationController.onNotificationDisplayedMethod, - onDismissActionReceivedMethod: - NotificationController.onDismissActionReceivedMethod); + startListeningNotificationEvents(); + // Get initial notification action is optional + initialAction = await AwesomeNotifications() + .getInitialNotificationAction(removeFromActionEvents: false); AwesomeNotifications().isNotificationAllowed().then((isAllowed) { //It would be more appropriate if you can show your own dialog @@ -67,6 +66,19 @@ class AwsomeNotificationHandler { }); } + @pragma("vm:entry-point") + static Future startListeningNotificationEvents() async { + await AwesomeNotifications().setListeners( + onActionReceivedMethod: NotificationController.onActionReceivedMethod, + onNotificationCreatedMethod: + NotificationController.onNotificationCreatedMethod, + onNotificationDisplayedMethod: + NotificationController.onNotificationDisplayedMethod, + onDismissActionReceivedMethod: + NotificationController.onDismissActionReceivedMethod); + return; + } + show(RemoteMessage message) async { NotificationMessage notificationMessage = NotificationMessage.fromJson(message.data); @@ -103,8 +115,11 @@ class AwsomeNotificationHandler { actionType: ActionType.Default, title: "\u200f ${message.title} \u200f", // body: message.body.toString(), - notificationLayout: NotificationLayout.Default, + notificationLayout: Platform.isAndroid + ? NotificationLayout.Default + : NotificationLayout.BigPicture, largeIcon: message.image.toString(), + bigPicture: Platform.isAndroid ? null : message.image.toString(), payload: message.toPayload(), color: const Color(0xFF007EA7)), ); @@ -116,8 +131,11 @@ class AwsomeNotificationHandler { actionType: ActionType.Default, title: "\u200f ${message.title} \u200f", // body: message.body.toString(), - notificationLayout: NotificationLayout.Default, + notificationLayout: Platform.isAndroid + ? NotificationLayout.Default + : NotificationLayout.BigPicture, largeIcon: message.image.toString(), + bigPicture: Platform.isAndroid ? null : message.image.toString(), payload: message.toPayload(), color: const Color(0xFF007EA7)), schedule: NotificationCalendar( @@ -153,16 +171,18 @@ class AwsomeNotificationHandler { actionType: ActionType.Default, body: "${message.title.toString()} ${message.body.toString()}", - largeIcon: message.photo.toString(), + largeIcon: Platform.isAndroid + ? message.photo.toString() + : message.image.toString(), roundedLargeIcon: true, bigPicture: message.image.toString(), payload: message.toPayload(), notificationLayout: NotificationLayout.BigPicture, color: const Color(0xFF007EA7)), schedule: NotificationCalendar( - hour: time.hour, - minute: time.minute, - )); + hour: time.hour, + minute: time.minute, + )); } // actionButtons: [ @@ -190,7 +210,7 @@ class AwsomeNotificationHandler { 'Simple body with a bunch of Emojis! ${Emojis.transport_police_car} ${Emojis.animals_dog} ${Emojis.flag_UnitedStates} ${Emojis.person_baby}', largeIcon: 'https://cdn.britannica.com/72/232772-050-4E3D86CC/mind-blown-emoji-head-exploding-emoticon.jpg', - notificationLayout: NotificationLayout.BigPicture, + notificationLayout: NotificationLayout.Default, payload: { 'title': 'Notification Title', 'body': 'Notification Body', @@ -200,28 +220,26 @@ class AwsomeNotificationHandler { } Future _getTime() async { - await HomeWidget.getWidgetData('token', defaultValue: "") - .then((value) async { - final service = RequestService(RequestHelper.notificationTime(), - useAutherization: false, - requestHeaders: { - "accept": "*/*", - "Content-Type": "application/json; charset=UTF-8", - 'Authorization': 'Bearer $value' - }); - await service.httpGet(); - if (service.isSuccess) { - final time = service.data('time'); - DateTime result = DateTime.now(); - if (time.toString().isNotEmpty) { - DateFormat format = DateFormat("HH:mm"); - DateTime dateTime = format.parse(time); - result = DateTime.now().copyWith(hour: dateTime.hour, minute: dateTime.minute); - } - + final token = await StorageService.getValue(key: 'token'); + final service = RequestService(RequestHelper.notificationTime(), + useAutherization: false, + requestHeaders: { + "accept": "*/*", + "Content-Type": "application/json; charset=UTF-8", + 'Authorization': 'Bearer $token' + }); + await service.httpGet(); + if (service.isSuccess) { + final time = service.data('time'); + DateTime result = DateTime.now(); + if (time.toString().isNotEmpty) { + DateFormat format = DateFormat("HH:mm"); + DateTime dateTime = format.parse(time); + result = DateTime.now() + .copyWith(hour: dateTime.hour, minute: dateTime.minute); return result; } - }); + } return null; } diff --git a/lib/services/notification/fcm/firebase_notification_handler.dart b/lib/services/notification/fcm/firebase_notification_handler.dart index 69bb1a0..fe4da68 100644 --- a/lib/services/notification/fcm/firebase_notification_handler.dart +++ b/lib/services/notification/fcm/firebase_notification_handler.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; @@ -20,12 +22,23 @@ class FirebaseNotificationHandler { messagingSenderId: "935017686266", appId: "1:935017686266:web:a93f7a19bed23c51d2d543", measurementId: "G-80B4H9E8Y0") - : const FirebaseOptions( - apiKey: 'AIzaSyBp-UHjWeM0H0UHtX5yguFKG-riMzvvCzw', - appId: '1:935017686266:android:f9cbc9aba8e3d65ed2d543', - messagingSenderId: '935017686266', - projectId: 'didvan-9b7da', - ), + : Platform.isAndroid + ? const FirebaseOptions( + apiKey: 'AIzaSyBp-UHjWeM0H0UHtX5yguFKG-riMzvvCzw', + appId: '1:935017686266:android:f9cbc9aba8e3d65ed2d543', + messagingSenderId: '935017686266', + projectId: 'didvan-9b7da', + ) + : const FirebaseOptions( + apiKey: 'AIzaSyCMa-zg_uVhOfTnea5Klz6aPZlgHwVGj7U', + appId: '1:935017686266:ios:de47638bd662463fd2d543', + messagingSenderId: '935017686266', + projectId: 'didvan-9b7da', + // iosBundleId: "com.didvan.didvanapp", + // storageBucket: "didvan-9b7da.appspot.com", + // iosClientId: + // "935017686266-54hu01v9cc5pqpgofo1gk2n3hegj4r2m.apps.googleusercontent.com" + ), ); final initMsg = await FirebaseMessaging.instance.getInitialMessage(); if (initMsg != null) { @@ -56,5 +69,4 @@ class FirebaseNotificationHandler { } } } - } diff --git a/lib/views/authentication/authentication.dart b/lib/views/authentication/authentication.dart index 9119411..456269d 100644 --- a/lib/views/authentication/authentication.dart +++ b/lib/views/authentication/authentication.dart @@ -40,6 +40,7 @@ class _AuthenticationState extends State { @override Widget build(BuildContext context) { return Scaffold( + resizeToAvoidBottomInset: false, body: Consumer( builder: (context, state, child) => WillPopScope( onWillPop: () async { diff --git a/lib/views/authentication/authentication_state.dart b/lib/views/authentication/authentication_state.dart index 4d85735..796682a 100644 --- a/lib/views/authentication/authentication_state.dart +++ b/lib/views/authentication/authentication_state.dart @@ -48,11 +48,11 @@ class AuthenticationState extends CoreProvier { await service.post(); if (service.isSuccess && service.result['loggedIn']) { final token = service.result['token']; - appState = AppState.idle; await userProvider.setAndGetToken(newToken: token); RequestService.token = token; HomeWidget.saveWidgetData("token", token.toString()); await userProvider.getUserInfo(); + appState = AppState.idle; return token; } else { appState = AppState.failed; diff --git a/lib/views/authentication/screens/password.dart b/lib/views/authentication/screens/password.dart index e813f5b..4a465aa 100644 --- a/lib/views/authentication/screens/password.dart +++ b/lib/views/authentication/screens/password.dart @@ -76,12 +76,12 @@ class _PasswordInputState extends State { final userProvider = context.read(); final token = await state.login(userProvider); if (token != null) { - ActionSheetUtils.showLogoLoadingIndicator(); await ServerDataProvider.getData(); - ActionSheetUtils.pop(); + if (mounted) { Navigator.of(context).pushReplacementNamed(Routes.home); } + _showResetPasswordDialog(); } } diff --git a/lib/views/direct/direct_state.dart b/lib/views/direct/direct_state.dart index 6f5725b..1b97b8e 100644 --- a/lib/views/direct/direct_state.dart +++ b/lib/views/direct/direct_state.dart @@ -130,6 +130,7 @@ class DirectState extends CoreProvier { replyRadar = null; replyNews = null; notifyListeners(); + final service = RequestService(RequestHelper.sendDirectMessage(typeId), body: body); @@ -147,7 +148,30 @@ class DirectState extends CoreProvier { } } } else { - service.multipart( + messages.insert( + 0, + MessageData( + id: 0, + writedByAdmin: false, + readed: false, + createdAt: + DateTime.now().subtract(const Duration(minutes: 210)).toString(), + text: text, + audio: null, + audioFile: uploadFile, + radar: replyRadar, + news: replyNews, + audioDuration: audioDuration, + ), + ); + + dailyMessages.clear(); + + for (var i = 0; i < messages.length; i++) { + _addToDailyGrouped(messages[i]); + } + + await service.multipart( file: Platform.isIOS ? File(uploadFile.path.replaceAll('file://', '')) : uploadFile, @@ -157,6 +181,11 @@ class DirectState extends CoreProvier { mediaExtension: 'm4a', mediaFormat: 'audio', ); + + if (service.isSuccess) { + final message = service.result['message']; + messages[0].id = MessageData.fromJson(message).id; + } } } } diff --git a/lib/views/direct/widgets/audio_widget.dart b/lib/views/direct/widgets/audio_widget.dart index f734114..89db854 100644 --- a/lib/views/direct/widgets/audio_widget.dart +++ b/lib/views/direct/widgets/audio_widget.dart @@ -98,7 +98,9 @@ class _AudioControllerButton extends StatelessWidget { ); } } - if (snapshot.data == null && _nowPlaying) { + if (snapshot.data == null && + _nowPlaying && + MediaService.audioPlayer.isPlaying.value) { return; } if (audioMetaData != null) { diff --git a/lib/views/home/home.dart b/lib/views/home/home.dart index 1316c34..649c762 100644 --- a/lib/views/home/home.dart +++ b/lib/views/home/home.dart @@ -1,6 +1,10 @@ +import 'package:awesome_notifications/awesome_notifications.dart'; import 'package:didvan/config/design_config.dart'; +import 'package:didvan/models/notification_message.dart'; import 'package:didvan/providers/theme.dart'; import 'package:didvan/services/app_initalizer.dart'; +import 'package:didvan/services/notification/awsome/awsome_notification_controller.dart'; +import 'package:didvan/services/notification/awsome/awsome_notification_handler.dart'; import 'package:didvan/views/home/bookmarks/bookmarks.dart'; import 'package:didvan/views/home/categories/categories_page.dart'; import 'package:didvan/views/home/main/main_page.dart'; @@ -26,6 +30,8 @@ class _HomeState extends State @override void initState() { + AwsomeNotificationHandler.startListeningNotificationEvents(); + final state = context.read(); DesignConfig.updateSystemUiOverlayStyle(); _tabController = TabController(length: 4, vsync: this, initialIndex: 0); @@ -33,9 +39,14 @@ class _HomeState extends State _tabController.addListener(() { state.currentPageIndex = _tabController.index; }); + Future.delayed(Duration.zero, () { HomeWidgetRepository.fetchWidget(); HomeWidgetRepository.decideWhereToGo(); + NotificationMessage? data = HomeWidgetRepository.data; + if (data != null) { + HomeWidgetRepository.decideWhereToGoNotif(); + } AppInitializer.handleCLick(state, _tabController); }); state.refresh(); diff --git a/lib/views/home/home_state.dart b/lib/views/home/home_state.dart index d23dac2..7bb6c0c 100644 --- a/lib/views/home/home_state.dart +++ b/lib/views/home/home_state.dart @@ -142,6 +142,11 @@ class HomeState extends CoreProvier { void refresh() async { menuItems = [ + MenuItemType( + label: 'آمار و داده', + asset: Assets.stats, + link: 'tab-0', + ), MenuItemType( label: 'دنیای فولاد', asset: Assets.fooladWorld, @@ -153,19 +158,19 @@ class HomeState extends CoreProvier { link: Routes.radars, ), MenuItemType( - label: 'آمار و داده', - asset: Assets.stats, - link: 'tab-0', + label: 'ویدیوکست', + asset: Assets.videocast, + link: Routes.videocasts, ), MenuItemType( - label: 'سها', - asset: Assets.saha, - link: 'https://saha.didvan.app', + label: 'پادکست', + asset: Assets.podcast, + link: Routes.podcasts, ), MenuItemType( - label: 'رادار استارت‌آپ', - asset: Assets.startup, - link: 'https://startup.didvan.app/', + label: 'اینفوگرافی', + asset: Assets.infography, + link: Routes.infography, ), MenuItemType( label: 'رادار روند', @@ -183,19 +188,14 @@ class HomeState extends CoreProvier { link: 'https://risk.didvan.app/', ), MenuItemType( - label: 'اینفوگرافی', - asset: Assets.infography, - link: Routes.infography, + label: 'رادار استارت‌آپ', + asset: Assets.startup, + link: 'https://startup.didvan.app/', ), MenuItemType( - label: 'ویدیوکست', - asset: Assets.videocast, - link: Routes.videocasts, - ), - MenuItemType( - label: 'پادکست', - asset: Assets.podcast, - link: Routes.podcasts, + label: 'سها', + asset: Assets.saha, + link: 'https://saha.didvan.app', ), ]; diff --git a/lib/views/home/infography/infography_screen.dart b/lib/views/home/infography/infography_screen.dart index e1c345e..9af0972 100644 --- a/lib/views/home/infography/infography_screen.dart +++ b/lib/views/home/infography/infography_screen.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:didvan/constants/app_icons.dart'; import 'package:didvan/models/infography/info_tag.dart'; import 'package:didvan/models/view/action_sheet_data.dart'; +import 'package:didvan/routes/routes.dart'; import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/views/home/infography/infography_screen_state.dart'; import 'package:didvan/views/home/main/widgets/infography_item.dart'; @@ -20,7 +21,8 @@ import 'package:provider/provider.dart'; import 'package:animated_custom_dropdown/custom_dropdown.dart'; class InfographyScreen extends StatefulWidget { - const InfographyScreen({super.key}); + final Map? pageData; + const InfographyScreen({super.key, this.pageData}); @override State createState() => _InfographyScreenState(); @@ -36,6 +38,25 @@ class _InfographyScreenState extends State { void initState() { context.read().init(); _scrollController.addListener(_onScroll); + + if (widget.pageData?['goToComment'] != null) { + var openComments = widget.pageData?['goToComment']; + + if (openComments) { + Future.delayed( + const Duration(seconds: 1), + () => Navigator.of(context).pushNamed( + Routes.mentions, + arguments: { + 'id': widget.pageData?['id'], + 'type': 'banner', + 'title': '', + }, + ), + ); + } + } + super.initState(); } diff --git a/lib/views/mentions/mentions.dart b/lib/views/mentions/mentions.dart index e08e526..c312db5 100644 --- a/lib/views/mentions/mentions.dart +++ b/lib/views/mentions/mentions.dart @@ -34,6 +34,7 @@ class Mentions extends StatefulWidget { class _MentionsState extends State { final _focusNode = FocusNode(); + final _focusNodeMention = FocusNode(); double _bottomPadding = 0; @override @@ -142,7 +143,7 @@ class _MentionsState extends State { enableEmptyState: state.users.isEmpty, emptyState: EmptyState( asset: Assets.emptyBookmark, - title: 'لیست خالی است', + title: 'لیست افراد خالی است', ), builder: (context, state, index) { return UserMention( @@ -158,6 +159,7 @@ class _MentionsState extends State { children: [ Expanded( child: TextField( + focusNode: _focusNodeMention, keyboardType: TextInputType.multiline, textInputAction: TextInputAction.send, style: Theme.of(context).textTheme.bodyMedium, @@ -166,7 +168,7 @@ class _MentionsState extends State { decoration: InputDecoration( icon: const Icon(DidvanIcons.search_regular), border: InputBorder.none, - hintText: 'جستجو کنید...', + hintText: 'نام فرد مورد نظر را بنویسید...', hintStyle: Theme.of(context) .textTheme .bodySmall! @@ -204,7 +206,10 @@ class _MentionsState extends State { left: 0, right: 0, bottom: MediaQuery.of(context).viewInsets.bottom, - child: _MessageBox(focusNode: _focusNode), + child: _MessageBox( + focusNode: _focusNode, + focusNodeMention: _focusNodeMention, + ), ), ], ), @@ -214,8 +219,11 @@ class _MentionsState extends State { class _MessageBox extends StatefulWidget { final FocusNode focusNode; + final FocusNode focusNodeMention; - const _MessageBox({Key? key, required this.focusNode}) : super(key: key); + const _MessageBox( + {Key? key, required this.focusNode, required this.focusNodeMention}) + : super(key: key); @override State<_MessageBox> createState() => _MessageBoxState(); @@ -379,12 +387,23 @@ class _MessageBoxState extends State<_MessageBox> { ), child: Row( children: [ - DidvanIconButton( - onPressed: () => _onSend(state), - icon: DidvanIcons.send_solid, - size: 24, - color: Theme.of(context).colorScheme.focusedBorder, - ), + state.mentionedUsers.isEmpty + ? DidvanIconButton( + onPressed: () { + state.showUsersForMentionsLayout = true; + widget.focusNodeMention.requestFocus(); + state.update(); + }, + icon: DidvanIcons.mention_icon, + size: 24, + color: Theme.of(context).colorScheme.focusedBorder, + ) + : DidvanIconButton( + onPressed: () => _onSend(state), + icon: DidvanIcons.send_solid, + size: 24, + color: Theme.of(context).colorScheme.focusedBorder, + ), Expanded( child: TextField( focusNode: widget.focusNode, @@ -392,21 +411,32 @@ class _MessageBoxState extends State<_MessageBox> { keyboardType: TextInputType.multiline, textInputAction: TextInputAction.send, style: Theme.of(context).textTheme.bodyMedium, + onTap: () { + if (state.mentionedUsers.isEmpty) { + state.showUsersForMentionsLayout = true; + widget.focusNodeMention.requestFocus(); + state.update(); + } + }, onEditingComplete: () {}, onSubmitted: (value) => _onSend(state), decoration: InputDecoration( border: InputBorder.none, - hintText: 'پیام خود را ارسال کنید', + hintMaxLines: 2, + hintText: state.mentionedUsers.isEmpty + ? 'همکاران خود را فراخوانی کنید' + : 'پیام خود را ارسال کنید', hintStyle: Theme.of(context).textTheme.bodySmall!.copyWith( color: Theme.of(context).colorScheme.disabledText), ), ), ), - const Spacer(), - if (!state.showUsersForMentionsLayout) + if (!state.showUsersForMentionsLayout && + state.mentionedUsers.isNotEmpty) DidvanIconButton( onPressed: () { state.showUsersForMentionsLayout = true; + widget.focusNodeMention.requestFocus(); state.update(); }, icon: DidvanIcons.mention_icon, diff --git a/lib/views/mentions/widgets/mention.dart b/lib/views/mentions/widgets/mention.dart index 4f8bd2f..377dfce 100644 --- a/lib/views/mentions/widgets/mention.dart +++ b/lib/views/mentions/widgets/mention.dart @@ -85,12 +85,14 @@ class MentionState extends State { color: Theme.of(context).colorScheme.caption, ), const SizedBox(width: 4), - DidvanIconButton( - size: 18, - gestureSize: 24, - icon: DidvanIcons.menu_light, - onPressed: () => _showCommentActions(comment), - ), + if (comment.user.id == + context.read().user.id) + DidvanIconButton( + size: 18, + gestureSize: 24, + icon: DidvanIcons.menu_light, + onPressed: () => _showCommentActions(comment), + ), ], ), DidvanText( diff --git a/lib/views/podcasts/podcasts.dart b/lib/views/podcasts/podcasts.dart index 665d897..d08fdb2 100644 --- a/lib/views/podcasts/podcasts.dart +++ b/lib/views/podcasts/podcasts.dart @@ -6,6 +6,7 @@ import 'package:didvan/models/enums.dart'; import 'package:didvan/models/requests/studio.dart'; import 'package:didvan/models/view/action_sheet_data.dart'; import 'package:didvan/models/view/app_bar_data.dart'; +import 'package:didvan/routes/routes.dart'; import 'package:didvan/utils/action_sheet.dart'; import 'package:didvan/views/podcasts/podcasts_state.dart'; import 'package:didvan/views/podcasts/widgets/slider.dart'; @@ -26,8 +27,11 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class Podcasts extends StatefulWidget { + final Map? pageData; final bool? viewPodcasts; - const Podcasts({Key? key, this.viewPodcasts}) : super(key: key); + + const Podcasts({Key? key, this.viewPodcasts, this.pageData}) + : super(key: key); @override State createState() => _PodcastsState(); @@ -40,6 +44,25 @@ class _PodcastsState extends State { @override void initState() { context.read().init(widget.viewPodcasts); + + if (widget.pageData?['goToComment'] != null) { + var openComments = widget.pageData?['goToComment']; + + if (openComments) { + Future.delayed( + const Duration(seconds: 1), + () => Navigator.of(context).pushNamed( + Routes.mentions, + arguments: { + 'id': widget.pageData?['id'], + 'type': 'studio', + 'title': '', + }, + ), + ); + } + } + super.initState(); } diff --git a/lib/views/podcasts/studio_details/studio_details.mobile.dart b/lib/views/podcasts/studio_details/studio_details.mobile.dart index d6db5e4..e6e8050 100644 --- a/lib/views/podcasts/studio_details/studio_details.mobile.dart +++ b/lib/views/podcasts/studio_details/studio_details.mobile.dart @@ -10,6 +10,7 @@ import 'package:didvan/views/widgets/didvan/app_bar.dart'; import 'package:didvan/views/widgets/state_handlers/state_handler.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; +import 'package:didvan/routes/routes.dart'; class StudioDetails extends StatefulWidget { final Map pageData; @@ -36,14 +37,27 @@ class _StudioDetailsState extends State { ); final state = context.read(); state.args = widget.pageData['args']; + Future.delayed( Duration.zero, () => state.getStudioDetails(widget.pageData['id']), ); + if (widget.pageData['goToComment'] != null) { var openComments = widget.pageData['goToComment']; + if (openComments) { - state.selectedDetailsIndex = 1; + Future.delayed( + const Duration(seconds: 1), + () => Navigator.of(context).pushNamed( + Routes.mentions, + arguments: { + 'id': state.studio.id, + 'type': 'studio', + 'title': state.studio.title, + }, + ), + ); } } super.initState(); diff --git a/lib/views/profile/edit_profile/edit_profile.dart b/lib/views/profile/edit_profile/edit_profile.dart index 6117aac..8ac0596 100644 --- a/lib/views/profile/edit_profile/edit_profile.dart +++ b/lib/views/profile/edit_profile/edit_profile.dart @@ -48,100 +48,102 @@ class _EditProfileState extends State { builder: (context, state, child) => Material( child: Stack( children: [ - Form( - key: _formKey, - child: DidvanScaffold( - padding: const EdgeInsets.only( - top: 16, - left: 16, - right: 16, - bottom: 92, - ), - appBarData: AppBarData(title: 'ویرایش پروفایل'), - children: [ - const ProfilePhoto(), - const SizedBox(height: 16), - DidvanCard( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - DidvanTextField( - title: 'نام و نام‌ خانوادگی', - hintText: 'نام و نام خانوادگی', - initialValue: state.user.fullName, - onChanged: (value) { - _setButtonState(); - fullName = value; - }, - ), - const SizedBox(height: 16), - DidvanTextField( - title: 'موبایل', - enabled: false, - hintText: state.user.phoneNumber, - ), - const SizedBox(height: 16), - DidvanTextField( - title: 'نام کاربری', - hintText: 'انتخاب نام کاربری (اختیاری)', - onChanged: _onUsernameChanged, - initialValue: state.user.username, - acceptSpace: false, - ), - Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: DidvanText( - 'نام کاربری می‌تواند شامل کاراکترهای کوچک و بزرگ انگلیسی و اعداد باشد.', - style: Theme.of(context).textTheme.labelSmall, - ), - ), - AnimatedVisibility( - duration: DesignConfig.lowAnimationDuration, - isVisible: !_usernameIsAvailible, - child: DidvanText( - 'نام کاربری در دسترس نمی‌باشد', - style: Theme.of(context).textTheme.bodySmall, - color: Theme.of(context).colorScheme.error, - ), - ), - const SizedBox(height: 16), - DidvanTextField( - title: 'ایمیل', - hintText: 'مثال: example@email.com', - onChanged: (value) { - _setButtonState(); - email = value; - }, - initialValue: state.user.email, - validator: (value) { - if (value.isEmpty) return null; - bool emailValid = RegExp( - r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") - .hasMatch(value); - if (!emailValid) { - return 'ایمیل وارد شده معتبر نمی‌باشد'; - } - return null; - }, - ), - // const SizedBox(height: 16), - // DidvanSwitch( - // value: true, - // title: 'ورود با اثر انگشت', - // onChanged: (value) => {}, - // ), - const DidvanDivider(), - MenuOption( - title: 'تغییر رمز عبور', - onTap: () => Navigator.of(context).pushNamed( - Routes.authenticaion, - arguments: true, - ), - ), - ], - ), + Container( + padding: const EdgeInsets.only(bottom: 80), + child: Form( + key: _formKey, + child: DidvanScaffold( + padding: const EdgeInsets.only( + top: 16, + left: 16, + right: 16, ), - ], + appBarData: AppBarData(title: 'ویرایش پروفایل'), + children: [ + const ProfilePhoto(), + const SizedBox(height: 16), + DidvanCard( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + DidvanTextField( + title: 'نام و نام‌ خانوادگی', + hintText: 'نام و نام خانوادگی', + initialValue: state.user.fullName, + onChanged: (value) { + _setButtonState(); + fullName = value; + }, + ), + const SizedBox(height: 16), + DidvanTextField( + title: 'موبایل', + enabled: false, + hintText: state.user.phoneNumber, + ), + const SizedBox(height: 16), + DidvanTextField( + title: 'نام کاربری', + hintText: 'انتخاب نام کاربری (اختیاری)', + onChanged: _onUsernameChanged, + initialValue: state.user.username, + acceptSpace: false, + ), + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: DidvanText( + 'نام کاربری می‌تواند شامل کاراکترهای کوچک و بزرگ انگلیسی و اعداد باشد.', + style: Theme.of(context).textTheme.labelSmall, + ), + ), + AnimatedVisibility( + duration: DesignConfig.lowAnimationDuration, + isVisible: !_usernameIsAvailible, + child: DidvanText( + 'نام کاربری در دسترس نمی‌باشد', + style: Theme.of(context).textTheme.bodySmall, + color: Theme.of(context).colorScheme.error, + ), + ), + const SizedBox(height: 16), + DidvanTextField( + title: 'ایمیل', + hintText: 'مثال: example@email.com', + onChanged: (value) { + _setButtonState(); + email = value; + }, + initialValue: state.user.email, + validator: (value) { + if (value.isEmpty) return null; + bool emailValid = RegExp( + r"^[a-zA-Z0-9.a-zA-Z0-9.!#$%&'*+-/=?^_`{|}~]+@[a-zA-Z0-9]+\.[a-zA-Z]+") + .hasMatch(value); + if (!emailValid) { + return 'ایمیل وارد شده معتبر نمی‌باشد'; + } + return null; + }, + ), + // const SizedBox(height: 16), + // DidvanSwitch( + // value: true, + // title: 'ورود با اثر انگشت', + // onChanged: (value) => {}, + // ), + const DidvanDivider(), + MenuOption( + title: 'تغییر رمز عبور', + onTap: () => Navigator.of(context).pushNamed( + Routes.authenticaion, + arguments: true, + ), + ), + ], + ), + ), + ], + ), ), ), Positioned( diff --git a/lib/views/splash/splash.dart b/lib/views/splash/splash.dart index 972b0bf..6aa692e 100644 --- a/lib/views/splash/splash.dart +++ b/lib/views/splash/splash.dart @@ -1,4 +1,3 @@ - import 'package:didvan/config/design_config.dart'; import 'package:didvan/constants/assets.dart'; import 'package:didvan/main.dart'; @@ -19,7 +18,6 @@ import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; import 'package:universal_html/html.dart' as html; - class Splash extends StatefulWidget { const Splash({Key? key}) : super(key: key); @@ -28,24 +26,24 @@ class Splash extends StatefulWidget { } class _SplashState extends State { - bool _isGettingThemeData = true; bool _errorOccured = false; + late ThemeProvider themeProvider; + late UserProvider userProvider; + late MediaProvider mediaProvider; @override void initState() { - _initialize(); super.initState(); + + themeProvider = context.read(); + userProvider = context.read(); + mediaProvider = context.read(); + + _initialize(themeProvider, userProvider, mediaProvider); } @override Widget build(BuildContext context) { - if (_isGettingThemeData) { - return Container( - color: Colors.transparent, - height: double.infinity, - width: double.infinity, - ); - } return AnnotatedRegion( value: DesignConfig.systemUiOverlayStyle.copyWith( systemNavigationBarColor: Theme.of(context).colorScheme.background, @@ -77,7 +75,7 @@ class _SplashState extends State { setState(() { _errorOccured = false; }); - _initialize(); + _initialize(themeProvider, userProvider, mediaProvider); }, ), ], @@ -87,73 +85,70 @@ class _SplashState extends State { ); } - Future _initialize() async { + Future _initialize(ThemeProvider themeProvider, + UserProvider userProvider, MediaProvider mediaProvider) async { try { - var v = navigatorKey.currentContext; ActionSheetUtils.context = navigatorKey.currentContext!; + if (kIsWeb) { html.window.onBeforeUnload.listen((event) { StorageService.webStorage .removeWhere((key, value) => key == 'image-cache'); }); } + final settingsData = await AppInitializer.initilizeSettings(); - if (!mounted) { - return; - } - final themeProvider = context.read(); + themeProvider.themeMode = settingsData.themeMode; themeProvider.fontFamily = settingsData.fontFamily; themeProvider.fontScale = settingsData.fontScale; - await Future.delayed( - const Duration(milliseconds: 200), - () => setState(() { - _isGettingThemeData = false; - }), - ); - if (!mounted) { - return; - } - await AppInitializer.setupServices(context); - if (!mounted) { - return; - } - final userProvider = context.read(); + + await AppInitializer.setupServices(navigatorKey.currentContext!); + final String? token = await userProvider.setAndGetToken(); + if (token != null) { - if (!kIsWeb && mounted) { - context.read().getDownloadsList(); + if (!kIsWeb) { + await mediaProvider.getDownloadsList(); } + RequestService.token = token; + final result = await userProvider.getUserInfo(); - if (!result && mounted) { - StorageService.delete(key: 'token'); - Navigator.of(context).pushNamedAndRemoveUntil( + + if (!result) { + try { + StorageService.delete(key: 'token'); + } catch (e) { + // catch + } + + navigatorKey.currentState!.pushNamedAndRemoveUntil( Routes.splash, (_) => false, ); + return; } + await ServerDataProvider.getData(); } - if (mounted) { - Navigator.of(context).pushReplacementNamed( - token == null ? Routes.authenticaion : Routes.home, - arguments: token == null ? false : null, - ); + navigatorKey.currentState!.pushReplacementNamed( + token == null ? Routes.authenticaion : Routes.home, + arguments: token == null ? false : null, + ); + return; - return; - // await HomeWidget.getWidgetData("cRouteGoTo", defaultValue: '') - // .then((cRouteGoTo) async { - // if (cRouteGoTo!.isNotEmpty) { - // navigatorKey.currentState! - // .pushNamed(cRouteGoTo.toString(), arguments:cRouteArgs ); - // HomeWidget.saveWidgetData("cRouteGoTo", ''); - // } - // }); - } + // await HomeWidget.getWidgetData("cRouteGoTo", defaultValue: '') + // .then((cRouteGoTo) async { + // if (cRouteGoTo!.isNotEmpty) { + // navigatorKey.currentState! + // .pushNamed(cRouteGoTo.toString(), arguments:cRouteArgs ); + // HomeWidget.saveWidgetData("cRouteGoTo", ''); + // } + // }); } catch (e) { setState(() { _errorOccured = true; diff --git a/lib/views/widgets/floating_navigation_bar.dart b/lib/views/widgets/floating_navigation_bar.dart index 4b41e6c..d9b8180 100644 --- a/lib/views/widgets/floating_navigation_bar.dart +++ b/lib/views/widgets/floating_navigation_bar.dart @@ -51,12 +51,11 @@ class _FloatingNavigationBarState extends State { Future.delayed( const Duration(seconds: 1), () => Navigator.of(context).pushNamed( - Routes.comments, + Routes.mentions, arguments: { 'id': widget.item.id, 'type': widget.isRadar ? 'radar' : 'news', 'title': widget.item.title, - 'onCommentsChanged': widget.onCommentsChanged, }, ), ); @@ -77,12 +76,11 @@ class _FloatingNavigationBarState extends State { Future.delayed( const Duration(seconds: 1), () => Navigator.of(context).pushNamed( - Routes.comments, + Routes.mentions, arguments: { 'id': widget.item.id, 'type': widget.isRadar ? 'radar' : 'news', 'title': widget.item.title, - 'onCommentsChanged': widget.onCommentsChanged, }, ), ); diff --git a/lib/views/widgets/logo_app_bar.dart b/lib/views/widgets/logo_app_bar.dart index 3304a46..2b65a9d 100644 --- a/lib/views/widgets/logo_app_bar.dart +++ b/lib/views/widgets/logo_app_bar.dart @@ -106,7 +106,7 @@ class LogoAppBar extends StatelessWidget implements PreferredSizeWidget { builder: (context, state, child) => SearchField( key: state.search.isEmpty ? ValueKey(state.search) : null, value: state.search, - title: state.currentPageIndex == 3 ? 'رصدهای من' : 'دیدوان', + title: 'دیدوان', onChanged: (value) => _onChanged(value, context), focusNode: state.searchFieldFocusNode, onFilterButtonPressed: () => _showFilterBottomSheet(context), diff --git a/pubspec.lock b/pubspec.lock index d2f20dc..5fbc021 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "2350805d7afefb0efe7acd325cb19d3ae8ba4039b906eade3807ffb69938a01f" + sha256: e4be6711f96d3d4eebe79728897d645b7a5585bbfdd6d534878d202c171266d7 url: "https://pub.dev" source: hosted - version: "1.3.33" + version: "1.3.34" android_intent_plus: dependency: "direct main" description: name: android_intent_plus - sha256: "2bfdbee8d65e7c26f88b66f0a91f2863da4d3596d8a658b4162c8de5cf04b074" + sha256: bfb29839be3886fa48faa631aa0123cd8531205df1abb80ee804935c75dd3cdb url: "https://pub.dev" source: hosted - version: "5.0.2" + version: "5.0.0" animated_custom_dropdown: dependency: "direct main" description: @@ -298,14 +298,38 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.3+1" + firebase_auth: + dependency: "direct main" + description: + name: firebase_auth + sha256: ea95cd29e27e8ec1971af263d74b208ce85dbc7df9197d8b5eab2aa7de7cfea8 + url: "https://pub.dev" + source: hosted + version: "4.19.6" + firebase_auth_platform_interface: + dependency: transitive + description: + name: firebase_auth_platform_interface + sha256: c252d2c97a02cf03fbf3595c5f7edf2a731062356b09d2c338f0b3d63567239f + url: "https://pub.dev" + source: hosted + version: "7.2.7" + firebase_auth_web: + dependency: transitive + description: + name: firebase_auth_web + sha256: "5db2319d59b4bb08cf0cc26e0f110f9ae1cf9cf775ce516e5cc38cd6704253de" + url: "https://pub.dev" + source: hosted + version: "5.11.6" firebase_core: dependency: "direct main" description: name: firebase_core - sha256: "372d94ced114b9c40cb85e18c50ac94a7e998c8eec630c50d7aec047847d27bf" + sha256: "4b5100e2dbc3fe72c2d4241a046d3f01457fe11293283a324f5c52575e3406f8" url: "https://pub.dev" source: hosted - version: "2.31.0" + version: "2.31.1" firebase_core_platform_interface: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 5e3ed2e..bf204f8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -82,8 +82,9 @@ dependencies: awesome_notifications_core: ^0.9.0 awesome_notifications: any home_widget: ^0.5.0 - android_intent_plus: ^5.0.2 + android_intent_plus: ^5.0.0 get: ^4.6.6 + firebase_auth: ^4.19.6 dev_dependencies: flutter_test: