diff --git a/README.md b/README.md
index 5f6f161..12929f3 100644
--- a/README.md
+++ b/README.md
@@ -20,5 +20,5 @@ There are some important information regarding Project
- Variable names should be very clear which conveys the proper meaning of its use, to make code reading fast and easy to read by everyone.
- Variable naming should be camelCase e.g. variableName;
- Define variable scope if it only uses in a limited class or function make it private to avoid conflicts.
-- Make a personal git change list if you are working on a file for test purposes. (to avoid that test changes when you git push)
+- Make a personal git change list if you are working on a file for test for your own purposes. (to avoid that test changes when you git push)
- avoid using too many packages if only a few functionalities required (Copy that separate code from the package file and then use this code)
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 7cf5766..6253c65 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -26,7 +26,7 @@ apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
- compileSdkVersion 29
+ compileSdkVersion 31
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@@ -40,7 +40,7 @@ android {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.cloudsolutions.tangheem"
minSdkVersion 19
- targetSdkVersion 29
+ targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
multiDexEnabled true
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index c4fd9d0..ab4ad56 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -11,7 +11,6 @@
addDiscussion(String discussionText, String ayaTangheemTypeId) async {
String url = "${ApiConsts.adminConfiguration}Discussion_Add";
- var postParams = {"discussionText": discussionText, "ayaTangheemTypeId": ayaTangheemTypeId};
+ var postParams = {"discussionText": discussionText, "ayaTangheemTypeId": ayaTangheemTypeId, "statusId": 1};
var _headers = {"Authorization": "Bearer ${AppState().token}"};
return await ApiClient().postJsonForObject((json) => GeneralResponseModel.fromJson(json), url, postParams, headers: _headers);
}
diff --git a/lib/api/api_client.dart b/lib/api/api_client.dart
index 17b1781..89817ad 100644
--- a/lib/api/api_client.dart
+++ b/lib/api/api_client.dart
@@ -103,7 +103,7 @@ class ApiClient {
var queryString = new Uri(queryParameters: queryParameters).query;
url = url + '?' + queryString;
}
- var response = await _post(Uri.parse(url), body: requestBody, headers: _headers).timeout(Duration(seconds: 15));
+ var response = await _post(Uri.parse(url), body: requestBody, headers: _headers).timeout(Duration(minutes: 2));
if (response.statusCode >= 200 && response.statusCode < 300) {
return response;
diff --git a/lib/api/tangheem_user_api_client.dart b/lib/api/tangheem_user_api_client.dart
index 02e2e6c..d369dd6 100644
--- a/lib/api/tangheem_user_api_client.dart
+++ b/lib/api/tangheem_user_api_client.dart
@@ -30,9 +30,9 @@ class TangheemUserApiClient {
return await ApiClient().postJsonForObject((json) => SurahModel.fromJson(json), url, postParams);
}
- Future getTangheemBySurah(int surahId) async {
+ Future getTangheemBySurah(int surahId, int numberInSurahs) async {
String url = "${ApiConsts.tangheemUsers}AyatTangheemTypeMapped_Get";
- var postParams = {"surahNo": surahId};
+ var postParams = {"surahNo": surahId, "numberInSurahs": numberInSurahs.toString()};
return await ApiClient().postJsonForObject((json) => AyatTangheemTypeMapped.fromJson(json), url, postParams);
}
@@ -84,6 +84,21 @@ class TangheemUserApiClient {
return await ApiClient().postJsonForObject((json) => AyatTangheemTypeMapped.fromJson(json), url, postParams);
}
+ Future ayahBaseTextGet(String tangheemTypeName, String ayaText, int itemsPerPage, int currentPageNo) async {
+ String url = "${ApiConsts.tangheemUsers}AyahBaseText_Get";
+ var postParams = {};
+ if (tangheemTypeName != null) {
+ postParams["tangheemTypeName"] = tangheemTypeName;
+ }
+ if (ayaText != null) {
+ postParams["ayahTextBase"] = ayaText;
+ }
+ postParams["itemsPerPage"] = itemsPerPage;
+ postParams["currentPageNo"] = currentPageNo;
+
+ return await ApiClient().postJsonForObject((json) => AyatTangheemTypeMapped.fromJson(json), url, postParams);
+ }
+
Future getAyaTangheemType(int surahNo, String tangheemTypeName) async {
String url = "${ApiConsts.tangheemUsers}AyaTangheemType_Get";
diff --git a/lib/classes/consts.dart b/lib/classes/consts.dart
index 4654e95..a42d180 100644
--- a/lib/classes/consts.dart
+++ b/lib/classes/consts.dart
@@ -1,7 +1,8 @@
class ApiConsts {
//static String baseUrl = "http://10.200.204.20:2801/"; // Local server
// static String baseUrl = "http://20.203.25.82"; // production server
- static String baseUrl = "http://18.221.16.125"; // new production server
+ // static String baseUrl = "http://18.221.16.125"; // new production server
+ static String baseUrl = "https://www.tangheemalquran.com"; // new production server Words
static String baseUrlServices = baseUrl + "/services/"; // production server
// static String baseUrlServices = "https://api.cssynapses.com/tangheem/"; // Live server
static String authentication = baseUrlServices + "api/Authentication/";
@@ -15,7 +16,10 @@ class GlobalConsts {
static String email = "email";
static String password = "password";
static String bookmark = "bookmark";
- static String fontZoomSize = "font_zoom_size";
+ static String fontZoomSize = "fontZoomSize";
+ static String fontZoomSizeQuran = "fontZoomSizeQuran";
+ static String fontZoomSizeTangheem = "fontZoomSizeTangheem";
static String welcomeVideoUrl = "welcomeVideoUrl";
static String doNotShowWelcomeVideo = "doNotShowWelcomeVideo";
+ static String userAuthData = "userAuthData";
}
diff --git a/lib/models/aya_tangheem_type_mapped.dart b/lib/models/aya_tangheem_type_mapped.dart
index 2a78743..609fd9c 100644
--- a/lib/models/aya_tangheem_type_mapped.dart
+++ b/lib/models/aya_tangheem_type_mapped.dart
@@ -165,7 +165,7 @@ class AyatTangheemTypeMappedData {
String _reverseAyatNumber(String ayaText, String ayaLength) {
String _ayaTemp = ayaText.substring(0, ayaText.length - ayaLength.toString().length);
String _ayaNum = ayaText.substring(ayaText.length - ayaLength.toString().length, ayaText.length);
- _ayaNum = _ayaNum.split('').reversed.join('');
+ //_ayaNum = _ayaNum.split('').reversed.join(''); // commenting this line for temperating purpose
return "$_ayaTemp $_ayaNum";
}
}
diff --git a/lib/ui/common_appbar.dart b/lib/ui/common_appbar.dart
index fa25ea0..95d60b8 100644
--- a/lib/ui/common_appbar.dart
+++ b/lib/ui/common_appbar.dart
@@ -1,3 +1,5 @@
+import 'dart:convert';
+
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -7,6 +9,7 @@ import 'package:tangheem/app_state/app_state.dart';
import 'package:tangheem/classes/colors.dart';
import 'package:tangheem/classes/consts.dart';
import 'package:tangheem/classes/utils.dart';
+import 'package:tangheem/models/authentication_user_model.dart';
import 'package:tangheem/models/navigation_model.dart';
import 'package:tangheem/models/quick_links_model.dart';
import 'package:tangheem/ui/dialogs/change_password_dialog.dart';
@@ -90,6 +93,11 @@ class _CommonAppbarState extends State {
void getPrefs() async {
prefs = await SharedPreferences.getInstance();
fontSize = prefs.getInt(GlobalConsts.fontZoomSize) ?? 18;
+ String userAuth = prefs.getString(GlobalConsts.userAuthData);
+ if (userAuth != null) {
+ AuthenticationUserModel authenticationUserModel = AuthenticationUserModel.fromJson(jsonDecode(userAuth));
+ AppState().setAuthenticationModel(authenticationUserModel);
+ }
}
@override
@@ -153,7 +161,7 @@ class _CommonAppbarState extends State {
try {
await UserApiClient().updatePassword(email, oldPassword, password);
} catch (ex) {
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
Utils.hideLoading(context);
return;
} finally {
@@ -288,30 +296,47 @@ class _CommonAppbarState extends State {
Expanded(
child: PopupMenuButton(
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
- onSelected: (int index) {
- Navigator.pop(context);
- Future.delayed(Duration(milliseconds: 200), () {
- showDialog(
- context: context,
- barrierColor: ColorConsts.secondaryWhite.withOpacity(0.8),
- builder: (BuildContext context) => ChangePasswordDialog(
- onPassword: (oldPassword, password) => updatePassword(AppState().userEmail, oldPassword, password),
- ),
- );
- });
+ onSelected: (int index) async {
+ if (index == 0) {
+ Navigator.pop(context);
+ Future.delayed(Duration(milliseconds: 200), () {
+ showDialog(
+ context: context,
+ barrierColor: ColorConsts.secondaryWhite.withOpacity(0.8),
+ builder: (BuildContext context) => ChangePasswordDialog(
+ onPassword: (oldPassword, password) => updatePassword(AppState().userEmail, oldPassword, password),
+ ),
+ );
+ });
+ } else {
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+ await prefs.remove(GlobalConsts.userAuthData);
+ AppState().setAuthenticationModel(null);
+ Utils.showToast("تسجيل خروج المستخدم");
+ Navigator.pop(context);
+ }
},
icon: SvgPicture.asset("assets/icons/fa_key.svg", height: 25, width: 30, color: ColorConsts.textGrey1),
-
- // Icon(Icons.settings, color: ColorConsts.textGrey1),
itemBuilder: (_) => >[
PopupMenuItem(
value: 1,
padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
- height: 16,
+ height: 24,
child: Center(
child: Text(
'تغيير كلمة المرور',
- style: TextStyle(color: ColorConsts.primaryBlack, fontSize: 12),
+ style: TextStyle(color: ColorConsts.primaryBlack, fontSize: 14),
+ ),
+ ),
+ ),
+ PopupMenuItem(
+ value: 1,
+ padding: EdgeInsets.fromLTRB(0, 0, 0, 0),
+ height: 24,
+ child: Center(
+ child: Text(
+ 'تسجيل خروج',
+ style: TextStyle(color: ColorConsts.primaryBlack, fontSize: 14),
),
),
),
diff --git a/lib/ui/screens/contact_us_screen.dart b/lib/ui/screens/contact_us_screen.dart
index f883cc9..955d06b 100644
--- a/lib/ui/screens/contact_us_screen.dart
+++ b/lib/ui/screens/contact_us_screen.dart
@@ -37,7 +37,7 @@ class _ContactUsScreenState extends State {
Utils.hideLoading(context);
Navigator.pop(context);
} catch (ex) {
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
Utils.hideLoading(context);
}
}
diff --git a/lib/ui/screens/content_info_screen.dart b/lib/ui/screens/content_info_screen.dart
index f2b78e2..4837804 100644
--- a/lib/ui/screens/content_info_screen.dart
+++ b/lib/ui/screens/content_info_screen.dart
@@ -33,7 +33,7 @@ class _ContentInfoScreenState extends State {
contentList = membersData?.data ?? [];
} catch (ex) {
contentList = [];
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
} finally {
Utils.hideLoading(context);
}
diff --git a/lib/ui/screens/forgot_password_screen.dart b/lib/ui/screens/forgot_password_screen.dart
index 8ccaf21..16a81a8 100644
--- a/lib/ui/screens/forgot_password_screen.dart
+++ b/lib/ui/screens/forgot_password_screen.dart
@@ -36,7 +36,7 @@ class _ForgotPasswordScreenState extends State {
await UserApiClient().forgotPassword(email);
Utils.showToast("تم إرسال رابط تغيير كلمة المرور إلى بريدك الإلكتروني");
} catch (ex) {
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
Utils.hideLoading(context);
return;
} finally {
@@ -50,7 +50,7 @@ class _ForgotPasswordScreenState extends State {
try {
await UserApiClient().verifyOTP(email, otp);
} catch (ex) {
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
Utils.hideLoading(context);
return;
} finally {
@@ -65,7 +65,7 @@ class _ForgotPasswordScreenState extends State {
try {
//await UserApiClient().updatePassword(email, otp, password);
} catch (ex) {
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
Utils.hideLoading(context);
return;
} finally {
diff --git a/lib/ui/screens/home_screen.dart b/lib/ui/screens/home_screen.dart
index a5f091a..1c2fbe1 100644
--- a/lib/ui/screens/home_screen.dart
+++ b/lib/ui/screens/home_screen.dart
@@ -68,7 +68,7 @@ class _HomeScreenState extends State {
Utils.hideLoading(context);
} catch (ex) {
Utils.hideLoading(context);
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
}
checkScreenMode();
}
@@ -85,7 +85,7 @@ class _HomeScreenState extends State {
if (showLoading) Utils.hideLoading(context);
} catch (ex) {
if (showLoading) Utils.hideLoading(context);
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
}
}
@@ -98,7 +98,7 @@ class _HomeScreenState extends State {
Utils.hideLoading(context);
} catch (ex) {
Utils.hideLoading(context);
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
}
}
@@ -192,7 +192,7 @@ class _HomeScreenState extends State {
SizedBox(height: 8),
Text(
Utils.getNotNullValue(_contentInfoModel?.data ?? [], 0)?.content ?? "",
- style: TextStyle(fontSize: 14, color: ColorConsts.textGrey, height: 1),
+ style: TextStyle(fontSize: 14, color: ColorConsts.textGrey, height: 1.5),
),
SizedBox(height: 32),
Row(
diff --git a/lib/ui/screens/login_screen.dart b/lib/ui/screens/login_screen.dart
index ba90526..f29686c 100644
--- a/lib/ui/screens/login_screen.dart
+++ b/lib/ui/screens/login_screen.dart
@@ -1,3 +1,5 @@
+import 'dart:convert';
+
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:shared_preferences/shared_preferences.dart';
@@ -57,9 +59,9 @@ class _LoginScreenState extends State {
Utils.showLoading(context);
try {
_authenticationUser = await AuthenticationApiClient().authenticateUser(_email, _password);
- Utils.showToast("تسجيل الدخول بنجاح");
- AppState().setAuthenticationModel(_authenticationUser);
SharedPreferences prefs = await SharedPreferences.getInstance();
+ await prefs.setString(GlobalConsts.userAuthData, jsonEncode(_authenticationUser.toJson()));
+ AppState().setAuthenticationModel(_authenticationUser);
if (!_isRemember) {
_email = "";
_password = "";
@@ -67,10 +69,11 @@ class _LoginScreenState extends State {
await prefs.setBool(GlobalConsts.isRememberMe, _isRemember);
await prefs.setString(GlobalConsts.email, _email);
await prefs.setString(GlobalConsts.password, _password);
+ Utils.showToast("تسجيل الدخول بنجاح");
Utils.hideLoading(context);
Navigator.pop(context);
} catch (ex) {
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
Utils.hideLoading(context);
}
}
diff --git a/lib/ui/screens/member_screen.dart b/lib/ui/screens/member_screen.dart
index 192a33b..5156030 100644
--- a/lib/ui/screens/member_screen.dart
+++ b/lib/ui/screens/member_screen.dart
@@ -34,7 +34,7 @@ class _MemberScreenState extends State {
membersList.sort((a, b) => a.orderNo.compareTo(b.orderNo));
} catch (ex) {
membersList = [];
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
} finally {
Utils.hideLoading(context);
}
diff --git a/lib/ui/screens/pdf_viewer_screen.dart b/lib/ui/screens/pdf_viewer_screen.dart
index 4f32035..92acd20 100644
--- a/lib/ui/screens/pdf_viewer_screen.dart
+++ b/lib/ui/screens/pdf_viewer_screen.dart
@@ -33,7 +33,7 @@ class _PdfListScreenState extends State {
contentList = membersData?.data ?? [];
} catch (ex) {
contentList = [];
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
} finally {
Utils.hideLoading(context);
}
diff --git a/lib/ui/screens/quran_screen.dart b/lib/ui/screens/quran_screen.dart
index c4caedd..f00511a 100644
--- a/lib/ui/screens/quran_screen.dart
+++ b/lib/ui/screens/quran_screen.dart
@@ -57,13 +57,13 @@ class _QuranScreenState extends State {
getSurah();
}
- double fontSize = 18;
+ int fontSize = 18;
SharedPreferences prefs;
void getPrefs() async {
prefs = await SharedPreferences.getInstance();
- fontSize = (prefs.getInt(GlobalConsts.fontZoomSize) ?? 18) + 0.0;
+ fontSize = (prefs.getInt(GlobalConsts.fontZoomSize) ?? 18);
setState(() {});
}
@@ -81,7 +81,7 @@ class _QuranScreenState extends State {
Utils.hideLoading(context);
} catch (ex) {
Utils.hideLoading(context);
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
}
setState(() {});
getQuranByPageNo();
@@ -111,38 +111,40 @@ class _QuranScreenState extends State {
setState(() {});
}
- Future getTangheemBySurahId() async {
+ Future> getTangheemBySurahId(int surahId, int numberInSurah) async {
+ Utils.showLoading(context);
try {
- _ayatTangheemTypeMapped = await TangheemUserApiClient().getTangheemBySurah(_selectedSurah + 1);
- _tangheemWords = _ayatTangheemTypeMapped?.data?.map((e) => e.highlightText)?.toList() ?? [];
+ AyatTangheemTypeMapped _ayatTangheemTypeMapped = await TangheemUserApiClient().getTangheemBySurah(surahId, numberInSurah);
+ Utils.hideLoading(context);
+ return _ayatTangheemTypeMapped.data;
} catch (ex) {
- Utils.handleException(ex, null);
- } finally {}
- setState(() {});
+ Utils.hideLoading(context);
+ // if (mounted) Utils.handleException(ex, null);
+ return [];
+ }
}
void getAyaByRange() async {
Utils.showLoading(context);
try {
_ayaModel = await TangheemUserApiClient().getAyaByFilter(_selectedSurah + 1, _fromAyaList[_selectedFromAya], _toAyaList[_selectedToAya]);
- await getTangheemBySurahId();
} catch (ex) {
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
} finally {
Utils.hideLoading(context);
}
- // getTangheemBySurahId();
+ setState(() {});
}
void getQuranByPageNo() async {
Utils.showLoading(context);
try {
_ayaModel = await TangheemUserApiClient().getQuranByPageNo(_currentPage);
- await getTangheemBySurahId();
+ // await getTangheemBySurahId();
Utils.hideLoading(context);
- // setState(() {});
+ setState(() {});
} catch (ex) {
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
Utils.hideLoading(context);
}
}
@@ -256,6 +258,7 @@ class _QuranScreenState extends State {
),
SizedBox(height: 8),
Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
commonIconButton("عرض", "assets/icons/go_forward.svg", () {
if (_selectedSurah < 0) {
@@ -273,6 +276,29 @@ class _QuranScreenState extends State {
}
}
}),
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ zoomButtons("assets/icons/reduce_size.svg", () {
+ if (fontSize <= 12) {
+ Utils.showToast("وصل حجم الخط إلى الحد الأدنى للحجم");
+ return;
+ }
+ fontSize -= 2;
+ prefs.setInt(GlobalConsts.fontZoomSize, fontSize);
+ setState(() {});
+ }),
+ zoomButtons("assets/icons/increase_size.svg", () {
+ if (fontSize >= 36) {
+ Utils.showToast("وصل حجم الخط إلى الحد الأقصى للحجم");
+ return;
+ }
+ fontSize += 2;
+ prefs.setInt(GlobalConsts.fontZoomSize, fontSize);
+ setState(() {});
+ }),
+ ],
+ )
],
),
SizedBox(height: 16),
@@ -486,16 +512,15 @@ class _QuranScreenState extends State {
List textSpanList = [];
String _surahAya = "";
_ayaModel?.data?.forEach((element) {
- var temp = element.numberInSurah == 1
- ? getBismillahWithSurahName(element.surahID, element.surahNameAR, element.surahID != 1, _surahAya.length <= 1) + element.reverseAyatNumber()
- : element.reverseAyatNumber();
+ var temp =
+ element.numberInSurah == 1 ? getBismillahWithSurahName(element.surahID, element.surahNameAR, element.surahID != 1, _surahAya.length <= 1) + element.reverseAyatNumber() : element.ayahText;
textSpanList.add(TextSpan(
text: temp + " ",
style: TextStyle(
backgroundColor: _selectedAyaForBookmark?.ayahID == element.ayahID ? ColorConsts.secondaryOrange.withOpacity(.4) : Colors.transparent,
fontFamily: "UthmanicHafs",
- fontSize: fontSize,
+ fontSize: fontSize.toDouble(),
color: ColorConsts.primaryBlue,
fontWeight: FontWeight.bold,
),
@@ -504,7 +529,7 @@ class _QuranScreenState extends State {
setState(() {
if (_selectedAyaForBookmark == null) {
_selectedAyaForBookmark = BookMarkModel.fromJson(element.toJson());
- showAyaOptions();
+ showAyaOptions(element);
return;
}
_selectedAyaForBookmark = null;
@@ -520,7 +545,7 @@ class _QuranScreenState extends State {
text: "\n" + "$_currentPage",
style: TextStyle(
fontFamily: "BArabics",
- fontSize: fontSize,
+ fontSize: fontSize.toDouble(),
color: ColorConsts.primaryBlue,
fontWeight: FontWeight.bold,
),
@@ -538,7 +563,7 @@ class _QuranScreenState extends State {
);
}
- void showAyaOptions() {
+ void showAyaOptions(AyaModelData ayaModelData) {
showModalBottomSheet(
context: context,
backgroundColor: Colors.transparent,
@@ -562,7 +587,7 @@ class _QuranScreenState extends State {
onTap: () async {
Navigator.pop(context);
List list = [];
- list = _ayatTangheemTypeMapped?.data?.where((element) => int.parse(element.ayahNos.split(",").last) == _selectedAyaForBookmark.ayahID)?.toList() ?? [];
+ list = await getTangheemBySurahId(ayaModelData.surahID, ayaModelData.numberInSurah);
if (list.isEmpty) {
Utils.showToast("لا توجد أساليب تنغيم في هذه الآية");
return;
@@ -577,8 +602,7 @@ class _QuranScreenState extends State {
var name = list.firstWhere((element) => element.tangheemTypeName == tempList.first, orElse: null);
TangheemDetailParams tangheem = TangheemDetailParams(selectedTangheemTypeId: name?.ayaTangheemTypeId ?? "", ayatTangheemTypeMappedDataList: list);
-
- Navigator.pushNamed(context, TangheemDetailScreen.routeName, arguments: tangheem);
+ Navigator.pushNamed(this.context, TangheemDetailScreen.routeName, arguments: tangheem);
},
child: Row(
children: [Text("تفاصيل الأساليب")],
@@ -607,6 +631,14 @@ class _QuranScreenState extends State {
);
});
}
+
+ Widget zoomButtons(String icon, VoidCallback onPressed, {double size, bool isAsset = true}) {
+ return IconButton(
+ padding: EdgeInsets.zero,
+ icon: SvgPicture.asset(icon, height: size ?? 24, width: size ?? 24),
+ onPressed: onPressed,
+ );
+ }
}
class TangheemTemp {
diff --git a/lib/ui/screens/registration_screen.dart b/lib/ui/screens/registration_screen.dart
index 5d0b8a3..05b1d0c 100644
--- a/lib/ui/screens/registration_screen.dart
+++ b/lib/ui/screens/registration_screen.dart
@@ -49,7 +49,7 @@ class _RegistrationScreenState extends State {
}
setState(() {});
} catch (ex) {
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
} finally {
Utils.hideLoading(context);
}
@@ -68,7 +68,7 @@ class _RegistrationScreenState extends State {
Utils.hideLoading(context);
Navigator.pop(context);
} catch (ex) {
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
Utils.hideLoading(context);
}
}
diff --git a/lib/ui/screens/tangheem_detail_screen.dart b/lib/ui/screens/tangheem_detail_screen.dart
index 1fac97c..698cc4c 100644
--- a/lib/ui/screens/tangheem_detail_screen.dart
+++ b/lib/ui/screens/tangheem_detail_screen.dart
@@ -1,7 +1,14 @@
+import 'dart:io';
+import 'dart:typed_data';
+import 'dart:ui' as ui;
+
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
+import 'package:flutter/rendering.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_svg/flutter_svg.dart';
+import 'package:path_provider/path_provider.dart';
+import 'package:share/share.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:tangheem/api/admin_configuration_api_client.dart';
import 'package:tangheem/api/tangheem_user_api_client.dart';
@@ -63,13 +70,13 @@ class _TangheemDetailScreenState extends State {
getTangheemDiscussionAndRelatedData();
}
- double fontSize = 18;
+ int fontSize = 18;
SharedPreferences prefs;
void getPrefs() async {
prefs = await SharedPreferences.getInstance();
- fontSize = (prefs.getInt(GlobalConsts.fontZoomSize) ?? 18) + 0.0;
+ fontSize = (prefs.getInt(GlobalConsts.fontZoomSizeTangheem) ?? 18);
setState(() {});
}
@@ -98,8 +105,7 @@ class _TangheemDetailScreenState extends State {
Utils.hideLoading(context);
setState(() {});
} catch (ex) {
- print(ex);
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
Utils.hideLoading(context);
}
}
@@ -132,14 +138,14 @@ class _TangheemDetailScreenState extends State {
Utils.hideLoading(context);
Navigator.pop(context);
} catch (ex) {
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
Utils.hideLoading(context);
}
}
void filterVoiceListData() {
ayatTangheemTypeMappedDataList.forEach((element) {
- voiceNoteList.addAll(element.voiceNote);
+ voiceNoteList.addAll(element?.voiceNote ?? []);
});
}
@@ -163,14 +169,83 @@ class _TangheemDetailScreenState extends State {
physics: BouncingScrollPhysics(),
padding: EdgeInsets.only(bottom: 16, top: 16),
children: [
- Text(
- _ayatTangheemTypeMappedFirstData.tangheemTypeName ?? "",
- style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: ColorConsts.primaryBlue, height: 1.5),
+ Text.rich(
+ TextSpan(
+ children: [
+ TextSpan(
+ text: _ayatTangheemTypeMappedFirstData.tangheemTypeName ?? "",
+ style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: ColorConsts.primaryBlue, height: 1.5),
+ ),
+ WidgetSpan(
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ zoomButtons("assets/icons/reduce_size.svg", () {
+ if (fontSize <= 12) {
+ Utils.showToast("وصل حجم الخط إلى الحد الأدنى للحجم");
+ return;
+ }
+ fontSize -= 2;
+ prefs.setInt(GlobalConsts.fontZoomSize, fontSize);
+ setState(() {});
+ }),
+ SizedBox(width: 4),
+ zoomButtons("assets/icons/increase_size.svg", () {
+ if (fontSize >= 36) {
+ Utils.showToast("وصل حجم الخط إلى الحد الأقصى للحجم");
+ return;
+ }
+ fontSize += 2;
+ prefs.setInt(GlobalConsts.fontZoomSize, fontSize);
+ setState(() {});
+ }),
+ ],
+ ),
+ ),
+ WidgetSpan(
+ child: PopupMenuButton(
+ child: IconButton(
+ highlightColor: Colors.transparent,
+ splashColor: Colors.transparent,
+ constraints: BoxConstraints(),
+ padding: EdgeInsets.only(right: 2),
+ icon: SvgPicture.asset("assets/icons/share_aya.svg", height: 16, width: 16),
+ onPressed: null),
+ padding: EdgeInsets.fromLTRB(4, 4, 0, 4),
+ itemBuilder: (_) => >[
+ PopupMenuItem(
+ value: 1,
+ child: Text(
+ "مشاركة رابط",
+ style: TextStyle(color: ColorConsts.primaryBlack),
+ ),
+ ),
+ PopupMenuItem(
+ value: 2,
+ child: Text(
+ "مشاركة صورة",
+ style: TextStyle(color: ColorConsts.primaryBlack),
+ ),
+ )
+ ],
+ onSelected: (int value) {
+ if (value == 1) {
+ _shareAyaAsLink();
+ } else {
+ _shareAyaAsImage();
+ }
+ },
+ ),
+ ),
+
+ // TextSpan(text: ' world!'),
+ ],
+ ),
),
SizedBox(height: 8),
Text(
_ayatTangheemTypeMappedFirstData.tangheemTypeDescription ?? "",
- style: TextStyle(fontSize: 14, color: ColorConsts.textGrey, height: 1),
+ style: TextStyle(fontSize: 14, color: ColorConsts.textGrey, height: 1.5),
),
SizedBox(height: 8),
Container(
@@ -191,14 +266,16 @@ class _TangheemDetailScreenState extends State {
shrinkWrap: true,
itemCount: ayatTangheemTypeMappedDataList.length > 5 ? 5 : ayatTangheemTypeMappedDataList.length,
itemBuilder: (context, index) {
- var _ayatTangheemTypeMappedData = ayatTangheemTypeMappedDataList[index];
+ final _ayatTangheemTypeMappedData = ayatTangheemTypeMappedDataList[index];
+
List _tangheemInsideTableList = [];
List _tangheemAboveTableList = [];
List _tangheemBelowTableList = [];
List _tangheemWords = [];
+ List _tempPropertyList = [] + _ayatTangheemTypeMappedData?.property ?? [];
- List _tempPropertyList = List() + _ayatTangheemTypeMappedData?.property ?? [];
int firstIndex = _tempPropertyList.indexWhere((element) => element.isInsideTable);
+
if (firstIndex >= 0) {
var _tempPropertyListTop = _tempPropertyList.take(firstIndex);
_tempPropertyListTop = _tempPropertyListTop.where((element) => (element.propertyValue ?? "").isNotEmpty)?.toList() ?? [];
@@ -254,8 +331,9 @@ class _TangheemDetailScreenState extends State {
startIndex: _ayatTangheemTypeMappedData.startIndex,
endIndex: _ayatTangheemTypeMappedData.endIndex,
textAlign: TextAlign.start,
+ fontSize: fontSize.toDouble(),
highlightAya: _ayatTangheemTypeMappedData.highlightText,
- highlightAyaNos: _ayatTangheemTypeMappedData.highlightAyaNos??"",
+ highlightAyaNos: _ayatTangheemTypeMappedData.highlightAyaNos ?? "",
ayahTextList: _ayatTangheemTypeMappedData.ayahTextList,
),
// TextHighLightWidget(
@@ -395,6 +473,8 @@ class _TangheemDetailScreenState extends State {
var removedData = list[index];
list.remove(removedData);
list.insert(0, removedData);
+ list = list?.where((element) => (element.ayahNos.contains(removedData.ayahNos)) && (element.tangheemTypeId == removedData.tangheemTypeId))?.toList() ?? [];
+
TangheemDetailParams tangheem = TangheemDetailParams(selectedTangheemTypeId: _dataList[index].ayaTangheemTypeId, ayatTangheemTypeMappedDataList: list);
Navigator.pushNamed(context, TangheemDetailScreen.routeName, arguments: tangheem);
},
@@ -416,8 +496,9 @@ class _TangheemDetailScreenState extends State {
if (MediaQuery.of(context).orientation == Orientation.portrait)
AyaPlayerWidget(
surahName: _ayatTangheemTypeMappedFirstData?.surahNameAr ?? "",
- ayaTangheemTypeId: _ayatTangheemTypeMappedFirstData?.ayaTangheemTypeId ?? "",
+ ayaTangheemTypeId: _ayatTangheemTypeMappedFirstData?.tangheemTypeId ?? "",
globalKey: _globalKey,
+ numberInSurah: _ayatTangheemTypeMappedFirstData?.ayatNumberInSurahs,
ayaNo: _ayatTangheemTypeMappedFirstData?.ayahNo,
surahNo: _ayatTangheemTypeMappedFirstData?.surahNo,
voiceNoteList: voiceNoteList),
@@ -451,8 +532,9 @@ class _TangheemDetailScreenState extends State {
if (showAyaPlayer)
AyaPlayerWidget(
surahName: _ayatTangheemTypeMappedFirstData?.surahNameAr ?? "",
- ayaTangheemTypeId: _ayatTangheemTypeMappedFirstData?.ayaTangheemTypeId ?? "",
+ ayaTangheemTypeId: _ayatTangheemTypeMappedFirstData?.tangheemTypeId ?? "",
ayaNo: _ayatTangheemTypeMappedFirstData?.ayahNo,
+ numberInSurah: _ayatTangheemTypeMappedFirstData?.ayatNumberInSurahs,
surahNo: _ayatTangheemTypeMappedFirstData?.surahNo,
globalKey: _globalKey,
voiceNoteList: voiceNoteList),
@@ -567,7 +649,8 @@ class _TangheemDetailScreenState extends State {
return Container(
color: Colors.white,
padding: EdgeInsets.all(2),
- child: Row(crossAxisAlignment: CrossAxisAlignment.start,
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
children: [
for (var property in tangheemPropertyList)
Expanded(
@@ -826,4 +909,42 @@ class _TangheemDetailScreenState extends State {
],
);
}
+
+ void _shareAyaAsLink() async {
+ String _url =
+ "${ApiConsts.baseUrl}/quran/tangheemtype?surahNo=${_ayatTangheemTypeMappedFirstData?.surahNo}&ayahNo=${_ayatTangheemTypeMappedFirstData?.ayahNo}&tanghemType=${_ayatTangheemTypeMappedFirstData?.tangheemTypeId}&numberinsurah=${_ayatTangheemTypeMappedFirstData?.ayatNumberInSurahs}";
+ await Share.share(_url);
+ }
+
+ void _shareAyaAsImage() async {
+ Utils.showLoading(context);
+ try {
+ RenderRepaintBoundary boundary = _globalKey.currentContext.findRenderObject();
+ ui.Image image = await boundary.toImage(pixelRatio: 3.0);
+ ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
+ Uint8List pngBytes = byteData.buffer.asUint8List();
+
+ final tempDir = await getTemporaryDirectory();
+ final file = await File('${tempDir.path}/${DateTime.now().toString()}.png').create();
+ await file.writeAsBytes(pngBytes);
+ await TangheemUserApiClient().addStatistics(3);
+ await Share.shareFiles(['${file.path}']);
+ Utils.hideLoading(context);
+ } catch (ex) {
+ Future.delayed(Duration(seconds: 1), () {
+ Utils.hideLoading(context);
+ });
+ }
+ }
+
+ Widget zoomButtons(String icon, VoidCallback onPressed, {double size, bool isAsset = true}) {
+ return IconButton(
+ highlightColor: Colors.transparent,
+ splashColor: Colors.transparent,
+ constraints: BoxConstraints(),
+ padding: EdgeInsets.only(right: 2),
+ icon: SvgPicture.asset(icon, height: size ?? 20, width: size ?? 20),
+ onPressed: onPressed,
+ );
+ }
}
diff --git a/lib/ui/screens/tangheem_screen.dart b/lib/ui/screens/tangheem_screen.dart
index c223f61..1233f11 100644
--- a/lib/ui/screens/tangheem_screen.dart
+++ b/lib/ui/screens/tangheem_screen.dart
@@ -35,19 +35,42 @@ class _TangheemScreenState extends State {
void initState() {
super.initState();
_controller = new ScrollController()..addListener(_scrollListener);
- getTangheemData();
+ if (widget.tangheemQuery == null) {
+ getTangheemData();
+ } else {
+ getTangheemDataByKeyword();
+ }
}
_scrollListener() {
if (_controller.position.extentAfter.toInt() <= 0 && canCallApi) {
if (_dataList.length < _ayatTangheemTypeMapped.totalItemsCount) {
currentPageNo++;
- getTangheemData();
+ if (widget.tangheemQuery == null) {
+ getTangheemData();
+ } else {
+ getTangheemDataByKeyword();
+ }
}
canCallApi = false;
}
}
+ void getTangheemDataByKeyword() async {
+ Utils.showLoading(context);
+ try {
+ _ayatTangheemTypeMapped = await TangheemUserApiClient().ayahBaseTextGet(widget.tangheemTypeName, widget.tangheemQuery, itemsPerPage, currentPageNo);
+ _dataList = (_dataList ?? []) + (_ayatTangheemTypeMapped?.data ?? []);
+ } catch (ex) {
+ _dataList = _dataList ?? [];
+ if (mounted) Utils.handleException(ex, null);
+ } finally {
+ Utils.hideLoading(context);
+ canCallApi = true;
+ }
+ setState(() {});
+ }
+
void getTangheemData() async {
Utils.showLoading(context);
try {
@@ -55,7 +78,7 @@ class _TangheemScreenState extends State {
_dataList = (_dataList ?? []) + (_ayatTangheemTypeMapped?.data ?? []);
} catch (ex) {
_dataList = _dataList ?? [];
- Utils.handleException(ex, null);
+ if (mounted) Utils.handleException(ex, null);
} finally {
Utils.hideLoading(context);
canCallApi = true;
@@ -116,6 +139,11 @@ class _TangheemScreenState extends State {
" ${_dataList[index].ayatNumberInSurahs}",
style: TextStyle(fontSize: 14, fontFamily: "BArabics", color: ColorConsts.secondaryOrange),
),
+ SizedBox(width: 4),
+ Text(
+ "(${_dataList[index].tangheemTypeName})",
+ style: TextStyle(fontSize: 12, color: ColorConsts.secondaryOrange),
+ ),
],
),
TextHighLightLengthWidget(
@@ -124,7 +152,7 @@ class _TangheemScreenState extends State {
endIndex: _dataList[index].endIndex,
textAlign: TextAlign.start,
highlightAya: _dataList[index].highlightText,
- highlightAyaNos: _dataList[index].highlightAyaNos??"",
+ highlightAyaNos: _dataList[index].highlightAyaNos ?? "",
ayahTextList: _dataList[index].ayahTextList,
),
// TextHighLightWidget(
diff --git a/lib/widgets/aya_player_widget.dart b/lib/widgets/aya_player_widget.dart
index 5b03422..ac1ddb9 100644
--- a/lib/widgets/aya_player_widget.dart
+++ b/lib/widgets/aya_player_widget.dart
@@ -1,5 +1,4 @@
import 'dart:convert';
-import 'dart:io';
import 'dart:math' as math;
import 'dart:typed_data';
import 'dart:ui' as ui;
@@ -10,10 +9,7 @@ import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:just_audio/just_audio.dart';
-import 'package:path_provider/path_provider.dart';
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';
@@ -22,12 +18,13 @@ import 'package:tangheem/models/aya_tangheem_type_mapped.dart';
class AyaPlayerWidget extends StatefulWidget {
final int surahNo;
final int ayaNo;
+ final String numberInSurah;
final String surahName;
final String ayaTangheemTypeId;
final GlobalKey globalKey;
final List voiceNoteList;
- AyaPlayerWidget({Key key, this.surahName, this.ayaTangheemTypeId, this.voiceNoteList, this.ayaNo, this.surahNo, @required this.globalKey}) : super(key: key);
+ AyaPlayerWidget({Key key, this.surahName, this.ayaTangheemTypeId, this.voiceNoteList, this.ayaNo, this.numberInSurah, this.surahNo, @required this.globalKey}) : super(key: key);
@override
_AyaPlayerWidgetState createState() {
@@ -210,33 +207,6 @@ class _AyaPlayerWidgetState extends State {
Utils.showToast("يجب اعطاء الاذن لتنزيل الآية");
}
}),
- PopupMenuButton(
- child: commonIconButton("assets/icons/share_aya.svg", null),
- padding: EdgeInsets.fromLTRB(4, 4, 0, 4),
- itemBuilder: (_) => >[
- PopupMenuItem(
- value: 1,
- child: Text(
- "مشاركة رابط",
- style: TextStyle(color: ColorConsts.primaryBlack),
- ),
- ),
- PopupMenuItem(
- value: 2,
- child: Text(
- "مشاركة صورة",
- style: TextStyle(color: ColorConsts.primaryBlack),
- ),
- )
- ],
- onSelected: (int value) {
- if (value == 1) {
- _shareAyaAsLink();
- } else {
- _shareAyaAsImage();
- }
- },
- )
],
),
SizedBox(height: 8),
@@ -364,30 +334,4 @@ class _AyaPlayerWidgetState extends State {
return false;
}
}
-
- void _shareAyaAsLink() async {
- String _url = "${ApiConsts.baseUrl}/quran/tangheemtype?surahNo=${widget.surahNo}&ayahNo=${widget.ayaNo}&tanghemType=${widget.ayaTangheemTypeId}";
- await Share.share(_url);
- }
-
- void _shareAyaAsImage() async {
- Utils.showLoading(context);
- try {
- RenderRepaintBoundary boundary = widget.globalKey.currentContext.findRenderObject();
- ui.Image image = await boundary.toImage(pixelRatio: 3.0);
- ByteData byteData = await image.toByteData(format: ui.ImageByteFormat.png);
- Uint8List pngBytes = byteData.buffer.asUint8List();
-
- final tempDir = await getTemporaryDirectory();
- final file = await File('${tempDir.path}/${DateTime.now().toString()}.png').create();
- await file.writeAsBytes(pngBytes);
- await TangheemUserApiClient().addStatistics(3);
- await Share.shareFiles(['${file.path}']);
- Utils.hideLoading(context);
- } catch (ex) {
- Future.delayed(Duration(seconds: 1), () {
- Utils.hideLoading(context);
- });
- }
- }
}
diff --git a/lib/widgets/text_highlight_widget.dart b/lib/widgets/text_highlight_widget.dart
index 614be39..04b994d 100644
--- a/lib/widgets/text_highlight_widget.dart
+++ b/lib/widgets/text_highlight_widget.dart
@@ -1,5 +1,3 @@
-import 'dart:math';
-
import 'package:flutter/material.dart';
import 'package:tangheem/classes/colors.dart';
import 'package:tangheem/models/aya_tangheem_type_mapped.dart';
@@ -12,6 +10,7 @@ class TextHighLightLengthWidget extends StatelessWidget {
final String highlightAyaNos;
final String highlightAya;
final List ayahTextList;
+ final double fontSize;
final Color highLightColor;
TextHighLightLengthWidget({
@@ -23,12 +22,13 @@ class TextHighLightLengthWidget extends StatelessWidget {
this.highlightAyaNos = "",
this.highlightAya = "",
this.ayahTextList,
+ this.fontSize = 18,
this.highLightColor = ColorConsts.secondaryOrange,
}) : super(key: key);
TextStyle textStyle = TextStyle(
fontFamily: "UthmanicHafs",
- fontSize: 16,
+ fontSize: 18,
color: ColorConsts.primaryBlue,
fontWeight: FontWeight.bold,
);
@@ -57,6 +57,9 @@ class TextHighLightLengthWidget extends StatelessWidget {
}
}
// print("startIndex:$startIndex");
+ if (startIndex < 0) {
+ startIndex = 0;
+ }
if (actualStartIndex != 0) {
startIndex = actualStartIndex + startIndex;
}
@@ -82,14 +85,14 @@ class TextHighLightLengthWidget extends StatelessWidget {
TextSpan _normalText(String text) {
return TextSpan(
text: text,
- style: textStyle,
+ style: textStyle.copyWith(fontSize: fontSize),
);
}
TextSpan _highlightText(String text) {
return TextSpan(
text: text,
- style: textStyle.copyWith(color: highLightColor),
+ style: textStyle.copyWith(color: highLightColor, fontSize: fontSize),
);
}
diff --git a/pubspec.yaml b/pubspec.yaml
index 743e483..0b21189 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -34,7 +34,7 @@ dependencies:
path_provider: ^2.0.1
permission_handler: ^6.1.1
share: ^2.0.4
- just_audio: ^0.7.2
+ just_audio: ^0.9.24
intl: ^0.17.0
shared_preferences: ^2.0.5
url_launcher: ^6.0.3