diff --git a/android/app/build.gradle b/android/app/build.gradle index a4703e1..669d9d6 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -57,7 +57,9 @@ android { flutter { source '../..' } - +apply plugin: 'com.android.application' +apply plugin: 'com.google.gms.google-services' dependencies { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'com.google.firebase:firebase-analytics:17.4.1' } diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..b351e9d --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,46 @@ +{ + "project_info": { + "project_number": "991502296436", + "project_id": "tangheemcom", + "storage_bucket": "tangheemcom.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:991502296436:android:c51807fe0a1b9be358b821", + "android_client_info": { + "package_name": "com.cloudsolutions.tangheem" + } + }, + "oauth_client": [ + { + "client_id": "991502296436-e75nl9l5ph9l8ccgs13p912dfq08nvgc.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyA_qjuXPTR3KR2KoXWLwijkA9lhkwhWaVs" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "991502296436-e75nl9l5ph9l8ccgs13p912dfq08nvgc.apps.googleusercontent.com", + "client_type": 3 + }, + { + "client_id": "991502296436-alfpp5j6d8m38aaue7o12fnls9gk44hh.apps.googleusercontent.com", + "client_type": 2, + "ios_info": { + "bundle_id": "com.cloudsolutions.tangheem" + } + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/build.gradle b/android/build.gradle index 3100ad2..b5e8417 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -7,6 +7,7 @@ buildscript { dependencies { classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.google.gms:google-services:4.3.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } diff --git a/lib/app_state/app_state.dart b/lib/app_state/app_state.dart index 1b40ebf..9f637bf 100644 --- a/lib/app_state/app_state.dart +++ b/lib/app_state/app_state.dart @@ -1,3 +1,4 @@ +import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:tangheem/models/authentication_user_model.dart'; import 'package:tangheem/models/content_info_model.dart'; import 'package:tangheem/models/navigation_model.dart'; @@ -43,4 +44,12 @@ class AppState { void setNavigationModel(NavigationModel _navigationModel) { this._navigationModel = _navigationModel; } + + FirebaseAnalytics _analytics; + + FirebaseAnalytics get getAnalytics => _analytics; + + void setAnalytics(FirebaseAnalytics _analytics) { + this._analytics = _analytics; + } } diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart index e80ce36..e1f1e94 100644 --- a/lib/classes/consts.dart +++ b/lib/classes/consts.dart @@ -1,10 +1,11 @@ class ApiConsts { //static String baseUrl = "http://10.200.204.20:2801/"; // Local server - static String baseUrl = "https://api.cssynapses.com/tangheem/"; // Live server - static String authentication = baseUrl + "api/Authentication/"; - static String tangheemUsers = baseUrl + "api/TangheemUsers/"; - static String adminConfiguration = baseUrl + "api/AdminConfiguration/"; - static String user = baseUrl + "api/User/"; + static String baseUrl = "http://20.203.25.82"; // Live server + static String baseUrlServices = baseUrl + "/services/"; // Live server + static String authentication = baseUrlServices + "api/Authentication/"; + static String tangheemUsers = baseUrlServices + "api/TangheemUsers/"; + static String adminConfiguration = baseUrlServices + "api/AdminConfiguration/"; + static String user = baseUrlServices + "api/User/"; } class GlobalConsts { diff --git a/lib/main.dart b/lib/main.dart index 0381438..a515c78 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,5 +1,8 @@ import 'dart:io'; +import 'package:firebase_analytics/firebase_analytics.dart'; +import 'package:firebase_analytics/observer.dart'; +import 'package:firebase_core/firebase_core.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:tangheem/ui/screens/bookmark_screen.dart'; @@ -18,17 +21,23 @@ import 'ui/screens/registration_screen.dart'; import 'ui/screens/tangheem_detail_screen.dart'; import 'ui/screens/tangheem_screen.dart'; -void main() { +Future main() async { + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp(); runApp(Application()); } class Application extends StatelessWidget { + static FirebaseAnalytics analytics = FirebaseAnalytics(); + static FirebaseAnalyticsObserver observer = FirebaseAnalyticsObserver(analytics: analytics); + @override Widget build(BuildContext context) { return MaterialApp( title: 'Tangheem', theme: lightTheme(), debugShowCheckedModeBanner: false, + // navigatorObservers: [observer], initialRoute: HomeScreen.routeName, onGenerateRoute: (settings) { var className; @@ -43,7 +52,7 @@ class Application extends StatelessWidget { className = CommonAppbar(child: ForgotPasswordScreen()); break; case HomeScreen.routeName: - className = CommonAppbar(showDrawer: true, child: HomeScreen()); + className = CommonAppbar(showDrawer: true, child: HomeScreen(analytics)); break; case ContactUsScreen.routeName: className = CommonAppbar(child: ContactUsScreen()); @@ -84,6 +93,18 @@ class Application extends StatelessWidget { if (className == null) { return null; } + var eventName = settings.name; + eventName = eventName.replaceAll("/", ""); + if (eventName.isEmpty) eventName = "home"; + try { + analytics.setCurrentScreen( + screenName: eventName, + screenClassOverride: eventName, + ).then((value) => print("EventSent:$eventName")); + + } catch (ex) { + print("Analytics:$ex"); + } return goToNavigation(className); }, ); diff --git a/lib/ui/screens/home_screen.dart b/lib/ui/screens/home_screen.dart index 6620866..4aa74bc 100644 --- a/lib/ui/screens/home_screen.dart +++ b/lib/ui/screens/home_screen.dart @@ -1,3 +1,4 @@ +import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/painting.dart'; @@ -15,8 +16,8 @@ import 'package:tangheem/widgets/common_dropdown_button.dart'; class HomeScreen extends StatefulWidget { static const String routeName = "/"; - - HomeScreen({Key key}) : super(key: key); + final FirebaseAnalytics analytics; + HomeScreen(this.analytics, {Key key}) : super(key: key); @override _HomeScreenState createState() { @@ -54,6 +55,9 @@ class _HomeScreenState extends State { _surahList = _surahModel.data.map((element) => element.nameAR).toList(); await getTangheemTypes(); TangheemUserApiClient().addStatistics(1); + AppState().setAnalytics(widget.analytics); + await widget.analytics.setAnalyticsCollectionEnabled(true); + await widget.analytics.setCurrentScreen(screenName: "home"); setState(() {}); Utils.hideLoading(context); } catch (ex) { @@ -144,6 +148,17 @@ class _HomeScreenState extends State { _searchFocusNode.unfocus(); _searchFocusNode.canRequestFocus = false; var data = {"tangheemTypeName": _tangheemListNotifier.value[_selectedTangheemType], "surahData": _surahModel.data[_selectedSurah]}; + try { + await widget.analytics.logEvent( + name: 'tangheem_by_selection', + parameters: { + "tangheemTypeName": _tangheemListNotifier.value[_selectedTangheemType], + "surahName": _surahModel.data[_selectedSurah].nameAR, + }, + ); + } catch (ex) { + print("tangheemTypeName:$ex"); + } await Navigator.pushNamed(context, TangheemScreen.routeName, arguments: data); _searchFocusNode.canRequestFocus = true; getTangheemTypes(); @@ -200,6 +215,11 @@ class _HomeScreenState extends State { } _searchFocusNode.canRequestFocus = false; var data = {"tangheemQuery": _searchController.text}; + await widget.analytics.setAnalyticsCollectionEnabled(true); + await widget.analytics.logEvent( + name: 'tangheem_by_search', + parameters: {"tangheemQuery": _searchController.text}, + ); await Navigator.pushNamed(context, TangheemScreen.routeName, arguments: data); _searchFocusNode.canRequestFocus = true; getTangheemTypes(); diff --git a/lib/widgets/aya_player_widget.dart b/lib/widgets/aya_player_widget.dart index 5d55d46..ad8667c 100644 --- a/lib/widgets/aya_player_widget.dart +++ b/lib/widgets/aya_player_widget.dart @@ -15,6 +15,7 @@ import 'package:permission_handler/permission_handler.dart'; import 'package:share/share.dart'; import 'package:tangheem/api/tangheem_user_api_client.dart'; import 'package:tangheem/classes/colors.dart'; +import 'package:tangheem/classes/consts.dart'; import 'package:tangheem/classes/utils.dart'; import 'package:tangheem/models/aya_tangheem_type_mapped.dart'; @@ -49,7 +50,7 @@ class _AyaPlayerWidgetState extends State { List voiceList = []; if ((widget.voiceNoteList?.length ?? 0) > 0) { - voiceList = widget.voiceNoteList.map((e) => AudioSource.uri(Uri.parse(e.exposeFilePath))).toList(); + voiceList = widget.voiceNoteList.map((e) => AudioSource.uri(Uri.parse(ApiConsts.baseUrl + e.exposeFilePath))).toList(); } final _playlist = ConcatenatingAudioSource(children: voiceList); @@ -107,34 +108,34 @@ class _AyaPlayerWidgetState extends State { children: [ Row( children: [ - if(widget.voiceNoteList.length>1) - PopupMenuButton( - padding: EdgeInsets.fromLTRB(4, 4, 0, 4), - onSelected: (int index) { - _player.seek(Duration.zero, index: index); - }, - child: Transform.rotate( - angle: 180 * math.pi / 180, - child: SvgPicture.asset( - "assets/icons/drop_menu.svg", - width: 16, + if (widget.voiceNoteList.length > 1) + PopupMenuButton( + padding: EdgeInsets.fromLTRB(4, 4, 0, 4), + onSelected: (int index) { + _player.seek(Duration.zero, index: index); + }, + child: Transform.rotate( + angle: 180 * math.pi / 180, + child: SvgPicture.asset( + "assets/icons/drop_menu.svg", + width: 16, + ), ), - ), - itemBuilder: (context) { - var _voiceList = widget.voiceNoteList; - var length = _voiceList.length < 2 ? 0 : _voiceList.length; + itemBuilder: (context) { + var _voiceList = widget.voiceNoteList; + var length = _voiceList.length < 2 ? 0 : _voiceList.length; - return List.generate(length, (index) { - return PopupMenuItem( - value: index, - child: Text( - '${_voiceList[index].userName}', - style: TextStyle(color: ColorConsts.primaryBlack), - ), - ); - }); - }, - ), + return List.generate(length, (index) { + return PopupMenuItem( + value: index, + child: Text( + '${_voiceList[index].userName}', + style: TextStyle(color: ColorConsts.primaryBlack), + ), + ); + }); + }, + ), StreamBuilder( stream: _player.currentIndexStream, builder: (context, snapshot) { diff --git a/lib/widgets/aya_record_widget.dart b/lib/widgets/aya_record_widget.dart index 16a2c9d..3dd7ab7 100644 --- a/lib/widgets/aya_record_widget.dart +++ b/lib/widgets/aya_record_widget.dart @@ -280,7 +280,6 @@ class _AyaRecordWidgetState extends State { Map statuses = await [ Permission.storage, ].request(); - return statuses[Permission.storage].isGranted; } diff --git a/pubspec.yaml b/pubspec.yaml index bc44c41..3e6c39b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -41,6 +41,8 @@ dependencies: flutter_slidable: ^0.6.0 record_mp3: ^2.1.0 syncfusion_flutter_pdfviewer: ^19.1.59-beta + firebase_core: ^1.3.0 + firebase_analytics: ^8.1.2 dev_dependencies: flutter_test: