diff --git a/lib/api/tangheem_user_api_client.dart b/lib/api/tangheem_user_api_client.dart index 4187a36..fb119f7 100644 --- a/lib/api/tangheem_user_api_client.dart +++ b/lib/api/tangheem_user_api_client.dart @@ -1,7 +1,11 @@ import 'dart:async'; +import 'package:tangheem/models/aya_tangheem_property.dart'; +import 'package:tangheem/models/aya_tangheem_type.dart'; +import 'package:tangheem/models/aya_tangheem_type_mapped.dart'; import 'package:tangheem/models/country_model.dart'; import 'package:tangheem/models/general_response_model.dart'; +import 'package:tangheem/models/quick_links_model.dart'; import 'package:tangheem/models/tangheem_type_model.dart'; import 'api_client.dart'; import 'package:tangheem/classes/consts.dart'; @@ -21,7 +25,7 @@ class TangheemUserApiClient { Future getAyaByRange(int itemsPerPage, int currentPageNo, int surahID, int ayahFrom, int ayahTo) async { String url = "${ApiConsts.tangheemUsers}AyatByRange_Get"; - var postParams = {"itemsPerPage": itemsPerPage, "currentPageNo": currentPageNo, "sortFieldName": "string", "isSortAsc": true, "surahID": surahID, "ayahFrom": ayahFrom, "ayahTo": ayahTo}; + var postParams = {"itemsPerPage": itemsPerPage, "currentPageNo": currentPageNo, "surahID": surahID, "ayahFrom": ayahFrom, "ayahTo": ayahTo}; return await ApiClient().postJsonForObject((json) => AyaModel.fromJson(json), url, postParams); } @@ -31,6 +35,30 @@ class TangheemUserApiClient { return await ApiClient().postJsonForObject((json) => TangheemType.fromJson(json), url, postParams); } + Future getAyaTangheemTypeMapped(int surahNo, String tangheemTypeName) async { + String url = "${ApiConsts.tangheemUsers}AyatTangheemTypeMapped_Get"; + var postParams = {"surahNo": surahNo, "tangheemTypeName": tangheemTypeName}; + return await ApiClient().postJsonForObject((json) => AyatTangheemTypeMapped.fromJson(json), url, postParams); + } + + Future getAyaTangheemType(int currentPage, int surahNo, String tangheemTypeName) async { + String url = "${ApiConsts.tangheemUsers}AyaTangheemType_Get"; + var postParams = {"itemsPerPage": 5, "currentPageNo": currentPage, "surahNo": surahNo, "tangheemTypeName": tangheemTypeName}; + return await ApiClient().postJsonForObject((json) => AyaTangheemType.fromJson(json), url, postParams); + } + + Future getAyaTangheemProperty(int currentPage, int surahNo, String tangheemTypeName) async { + String url = "${ApiConsts.tangheemUsers}AyaTangheemProperty_Get"; + var postParams = {"itemsPerPage": 5, "currentPageNo": currentPage, "surahNo": surahNo, "tangheemTypeName": tangheemTypeName}; + return await ApiClient().postJsonForObject((json) => AyaTangheemProperty.fromJson(json), url, postParams); + } + + Future quickLinks() async { + String url = "${ApiConsts.tangheemUsers}QuickLinks_Get"; + var postParams = {}; + return await ApiClient().postJsonForObject((json) => QuickLinksModel.fromJson(json), url, postParams); + } + Future contactUs(String firstName, String lastName, String email, String phone, String description) async { String url = "${ApiConsts.tangheemUsers}ContactUs_Add"; var postParams = {"firstName": firstName, "lastName": lastName, "email": email, "phone": phone, "description": description}; diff --git a/lib/main.dart b/lib/main.dart index ac8557a..ec5764c 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -40,7 +40,13 @@ class Application extends StatelessWidget { className = CommonAppbar(showDrawer: true, child: HomeScreen()); break; case TangheemScreen.routeName: - className = CommonAppbar(child: TangheemScreen()); + Map data = settings.arguments; + className = CommonAppbar( + child: TangheemScreen( + surah: data["surahData"], + tangheemTypeName: data["tangheemTypeName"], + ), + ); break; case SurahScreen.routeName: String query = settings.arguments.toString(); diff --git a/lib/models/authentication_user_model.dart b/lib/models/authentication_user_model.dart index 55aac41..962273f 100644 --- a/lib/models/authentication_user_model.dart +++ b/lib/models/authentication_user_model.dart @@ -26,7 +26,7 @@ class Result { int totalItemsCount; int statusCode; String message; - Data data; + ResultData data; Result({this.totalItemsCount, this.statusCode, this.message, this.data}); @@ -34,7 +34,7 @@ class Result { totalItemsCount = json['totalItemsCount']; statusCode = json['statusCode']; message = json['message']; - data = json['data'] != null ? new Data.fromJson(json['data']) : null; + data = json['data'] != null ? new ResultData.fromJson(json['data']) : null; } Map toJson() { @@ -49,16 +49,16 @@ class Result { } } -class Data { +class ResultData { String token; String userId; String email; String mobileNumber; String userName; - Data({this.token, this.userId, this.email, this.mobileNumber, this.userName}); + ResultData({this.token, this.userId, this.email, this.mobileNumber, this.userName}); - Data.fromJson(Map json) { + ResultData.fromJson(Map json) { token = json['token']; userId = json['userId']; email = json['email']; diff --git a/lib/models/aya_model.dart b/lib/models/aya_model.dart index 035b970..a7d2d99 100644 --- a/lib/models/aya_model.dart +++ b/lib/models/aya_model.dart @@ -2,7 +2,7 @@ class AyaModel { int totalItemsCount; int statusCode; String message; - List data; + List data; AyaModel({this.totalItemsCount, this.statusCode, this.message, this.data}); @@ -11,9 +11,9 @@ class AyaModel { statusCode = json['statusCode']; message = json['message']; if (json['data'] != null) { - data = new List(); + data = new List(); json['data'].forEach((v) { - data.add(new Data.fromJson(v)); + data.add(new AyaModelData.fromJson(v)); }); } } @@ -30,7 +30,7 @@ class AyaModel { } } -class Data { +class AyaModelData { int surahID; String surahNameAR; String surahNameEN; @@ -48,7 +48,7 @@ class Data { String ayahText; Null eighthsID; - Data( + AyaModelData( {this.surahID, this.surahNameAR, this.surahNameEN, @@ -66,7 +66,7 @@ class Data { this.ayahText, this.eighthsID}); - Data.fromJson(Map json) { + AyaModelData.fromJson(Map json) { surahID = json['surahID']; surahNameAR = json['surahNameAR']; surahNameEN = json['surahNameEN']; diff --git a/lib/models/aya_tangheem_property.dart b/lib/models/aya_tangheem_property.dart new file mode 100644 index 0000000..b9f8124 --- /dev/null +++ b/lib/models/aya_tangheem_property.dart @@ -0,0 +1,93 @@ +class AyaTangheemProperty { + int totalItemsCount; + int statusCode; + String message; + List data; + + AyaTangheemProperty( + {this.totalItemsCount, this.statusCode, this.message, this.data}); + + AyaTangheemProperty.fromJson(Map json) { + totalItemsCount = json['totalItemsCount']; + statusCode = json['statusCode']; + message = json['message']; + if (json['data'] != null) { + data = new List(); + json['data'].forEach((v) { + data.add(new AyaTangheemPropertyData.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['totalItemsCount'] = this.totalItemsCount; + data['statusCode'] = this.statusCode; + data['message'] = this.message; + if (this.data != null) { + data['data'] = this.data.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class AyaTangheemPropertyData { + String ayaTangheemPropertyId; + String ayaTangheemTypeId; + String tangheemTypePropertyId; + String propertyValue; + int surahNo; + int ayaNo; + String ayaText; + String propertyText; + String tangheemTypeName; + String tangheemTypeId; + bool isInsideTable; + int orderNo; + + AyaTangheemPropertyData( + {this.ayaTangheemPropertyId, + this.ayaTangheemTypeId, + this.tangheemTypePropertyId, + this.propertyValue, + this.surahNo, + this.ayaNo, + this.ayaText, + this.propertyText, + this.tangheemTypeName, + this.tangheemTypeId, + this.isInsideTable, + this.orderNo}); + + AyaTangheemPropertyData.fromJson(Map json) { + ayaTangheemPropertyId = json['ayaTangheemPropertyId']; + ayaTangheemTypeId = json['ayaTangheemTypeId']; + tangheemTypePropertyId = json['tangheemTypePropertyId']; + propertyValue = json['propertyValue']; + surahNo = json['surahNo']; + ayaNo = json['ayaNo']; + ayaText = json['ayaText']; + propertyText = json['propertyText']; + tangheemTypeName = json['tangheemTypeName']; + tangheemTypeId = json['tangheemTypeId']; + isInsideTable = json['isInsideTable']; + orderNo = json['orderNo']; + } + + Map toJson() { + final Map data = new Map(); + data['ayaTangheemPropertyId'] = this.ayaTangheemPropertyId; + data['ayaTangheemTypeId'] = this.ayaTangheemTypeId; + data['tangheemTypePropertyId'] = this.tangheemTypePropertyId; + data['propertyValue'] = this.propertyValue; + data['surahNo'] = this.surahNo; + data['ayaNo'] = this.ayaNo; + data['ayaText'] = this.ayaText; + data['propertyText'] = this.propertyText; + data['tangheemTypeName'] = this.tangheemTypeName; + data['tangheemTypeId'] = this.tangheemTypeId; + data['isInsideTable'] = this.isInsideTable; + data['orderNo'] = this.orderNo; + return data; + } +} diff --git a/lib/models/aya_tangheem_type.dart b/lib/models/aya_tangheem_type.dart new file mode 100644 index 0000000..625521e --- /dev/null +++ b/lib/models/aya_tangheem_type.dart @@ -0,0 +1,68 @@ +class AyaTangheemType { + int totalItemsCount; + int statusCode; + String message; + List data; + + AyaTangheemType({this.totalItemsCount, this.statusCode, this.message, this.data}); + + AyaTangheemType.fromJson(Map json) { + totalItemsCount = json['totalItemsCount']; + statusCode = json['statusCode']; + message = json['message']; + if (json['data'] != null) { + data = new List(); + json['data'].forEach((v) { + data.add(new AyaTangheemTypeData.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['totalItemsCount'] = this.totalItemsCount; + data['statusCode'] = this.statusCode; + data['message'] = this.message; + if (this.data != null) { + data['data'] = this.data.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class AyaTangheemTypeData { + String ayaTangheemTypeId; + int surahNo; + int ayaNo; + String highlightText; + bool isActive; + String tangheemTypeId; + String tangheemTypeName; + int ayatNumberInSurah; + + AyaTangheemTypeData({this.ayaTangheemTypeId, this.surahNo, this.ayaNo, this.highlightText, this.isActive, this.tangheemTypeId, this.tangheemTypeName, this.ayatNumberInSurah}); + + AyaTangheemTypeData.fromJson(Map json) { + ayaTangheemTypeId = json['ayaTangheemTypeId']; + surahNo = json['surahNo']; + ayaNo = json['ayaNo']; + highlightText = json['highlightText']; + isActive = json['isActive']; + tangheemTypeId = json['tangheemTypeId']; + tangheemTypeName = json['tangheemTypeName']; + ayatNumberInSurah = json['ayatNumberInSurah']; + } + + Map toJson() { + final Map data = new Map(); + data['ayaTangheemTypeId'] = this.ayaTangheemTypeId; + data['surahNo'] = this.surahNo; + data['ayaNo'] = this.ayaNo; + data['highlightText'] = this.highlightText; + data['isActive'] = this.isActive; + data['tangheemTypeId'] = this.tangheemTypeId; + data['tangheemTypeName'] = this.tangheemTypeName; + data['ayatNumberInSurah'] = this.ayatNumberInSurah; + return data; + } +} diff --git a/lib/models/aya_tangheem_type_mapped.dart b/lib/models/aya_tangheem_type_mapped.dart new file mode 100644 index 0000000..bf707c0 --- /dev/null +++ b/lib/models/aya_tangheem_type_mapped.dart @@ -0,0 +1,178 @@ +class AyatTangheemTypeMapped { + int totalItemsCount; + int statusCode; + String message; + List data; + + AyatTangheemTypeMapped({this.totalItemsCount, this.statusCode, this.message, this.data}); + + AyatTangheemTypeMapped.fromJson(Map json) { + totalItemsCount = json['totalItemsCount']; + statusCode = json['statusCode']; + message = json['message']; + if (json['data'] != null) { + data = new List(); + json['data'].forEach((v) { + data.add(new AyatTangheemTypeMappedData.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['totalItemsCount'] = this.totalItemsCount; + data['statusCode'] = this.statusCode; + data['message'] = this.message; + if (this.data != null) { + data['data'] = this.data.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class AyatTangheemTypeMappedData { + String tangheemTypeId; + String tangheemTypeName; + String ayaTangheemTypeId; + int surahNo; + String surahNameEn; + String surahNameAr; + int ayahNo; + String ayahText; + int ayatNumberInSurah; + String highlightText; + String userId; + List property; + List voiceNote; + + AyatTangheemTypeMappedData( + {this.tangheemTypeId, + this.tangheemTypeName, + this.ayaTangheemTypeId, + this.surahNo, + this.surahNameEn, + this.surahNameAr, + this.ayahNo, + this.ayahText, + this.ayatNumberInSurah, + this.highlightText, + this.userId, + this.property, + this.voiceNote}); + + AyatTangheemTypeMappedData.fromJson(Map json) { + tangheemTypeId = json['tangheemTypeId']; + tangheemTypeName = json['tangheemTypeName']; + ayaTangheemTypeId = json['ayaTangheemTypeId']; + surahNo = json['surahNo']; + surahNameEn = json['surahNameEn']; + surahNameAr = json['surahNameAr']; + ayahNo = json['ayahNo']; + ayahText = json['ayahText']; + ayatNumberInSurah = json['ayatNumberInSurah']; + highlightText = json['highlightText']; + userId = json['userId']; + if (json['property'] != null) { + property = new List(); + json['property'].forEach((v) { + property.add(new TangheemProperty.fromJson(v)); + }); + } + if (json['voiceNote'] != null) { + voiceNote = new List(); + json['voiceNote'].forEach((v) { + voiceNote.add(new VoiceNote.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['tangheemTypeId'] = this.tangheemTypeId; + data['tangheemTypeName'] = this.tangheemTypeName; + data['ayaTangheemTypeId'] = this.ayaTangheemTypeId; + data['surahNo'] = this.surahNo; + data['surahNameEn'] = this.surahNameEn; + data['surahNameAr'] = this.surahNameAr; + data['ayahNo'] = this.ayahNo; + data['ayahText'] = this.ayahText; + data['ayatNumberInSurah'] = this.ayatNumberInSurah; + data['highlightText'] = this.highlightText; + data['userId'] = this.userId; + if (this.property != null) { + data['property'] = this.property.map((v) => v.toJson()).toList(); + } + if (this.voiceNote != null) { + data['voiceNote'] = this.voiceNote.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class TangheemProperty { + String tangheemTypePropertyId; + String propertyText; + bool isInsideTable; + int orderNo; + String ayaTangheemPropertyId; + String propertyValue; + + TangheemProperty({this.tangheemTypePropertyId, this.propertyText, this.isInsideTable, this.orderNo, this.ayaTangheemPropertyId, this.propertyValue}); + + TangheemProperty.fromJson(Map json) { + tangheemTypePropertyId = json['tangheemTypePropertyId']; + propertyText = json['propertyText']; + isInsideTable = json['isInsideTable']; + orderNo = json['orderNo']; + ayaTangheemPropertyId = json['ayaTangheemPropertyId']; + propertyValue = json['propertyValue']; + } + + Map toJson() { + final Map data = new Map(); + data['tangheemTypePropertyId'] = this.tangheemTypePropertyId; + data['propertyText'] = this.propertyText; + data['isInsideTable'] = this.isInsideTable; + data['orderNo'] = this.orderNo; + data['ayaTangheemPropertyId'] = this.ayaTangheemPropertyId; + data['propertyValue'] = this.propertyValue; + return data; + } +} + +class VoiceNote { + String voiceNoteId; + String voiceNotePath; + String exposeFilePath; + String userId; + String userName; + String fileName; + String fileType; + String ayaTangheemTypeId; + + VoiceNote({this.voiceNoteId, this.voiceNotePath, this.exposeFilePath, this.userId, this.userName, this.fileName, this.fileType, this.ayaTangheemTypeId}); + + VoiceNote.fromJson(Map json) { + voiceNoteId = json['voiceNoteId']; + voiceNotePath = json['voiceNotePath']; + exposeFilePath = json['exposeFilePath']; + userId = json['userId']; + userName = json['userName']; + fileName = json['fileName']; + fileType = json['fileType']; + ayaTangheemTypeId = json['ayaTangheemTypeId']; + } + + Map toJson() { + final Map data = new Map(); + data['voiceNoteId'] = this.voiceNoteId; + data['voiceNotePath'] = this.voiceNotePath; + data['exposeFilePath'] = this.exposeFilePath; + data['userId'] = this.userId; + data['userName'] = this.userName; + data['fileName'] = this.fileName; + data['fileType'] = this.fileType; + data['ayaTangheemTypeId'] = this.ayaTangheemTypeId; + return data; + } +} diff --git a/lib/models/country_model.dart b/lib/models/country_model.dart index 4d97064..f72b70b 100644 --- a/lib/models/country_model.dart +++ b/lib/models/country_model.dart @@ -2,7 +2,7 @@ class CountryModel { int totalItemsCount; int statusCode; String message; - List data; + List data; CountryModel( {this.totalItemsCount, this.statusCode, this.message, this.data}); @@ -12,9 +12,9 @@ class CountryModel { statusCode = json['statusCode']; message = json['message']; if (json['data'] != null) { - data = new List(); + data = new List(); json['data'].forEach((v) { - data.add(new Data.fromJson(v)); + data.add(new CountryModelData.fromJson(v)); }); } } @@ -31,21 +31,21 @@ class CountryModel { } } -class Data { +class CountryModelData { int countryId; String countryCode; String countryNameEn; String countryNameAr; String countryFlag; - Data( + CountryModelData( {this.countryId, this.countryCode, this.countryNameEn, this.countryNameAr, this.countryFlag}); - Data.fromJson(Map json) { + CountryModelData.fromJson(Map json) { countryId = json['countryId']; countryCode = json['countryCode']; countryNameEn = json['countryNameEn']; diff --git a/lib/models/quick_links_model.dart b/lib/models/quick_links_model.dart new file mode 100644 index 0000000..6b0318b --- /dev/null +++ b/lib/models/quick_links_model.dart @@ -0,0 +1,76 @@ +class QuickLinksModel { + int totalItemsCount; + int statusCode; + String message; + List data; + + QuickLinksModel({this.totalItemsCount, this.statusCode, this.message, this.data}); + + QuickLinksModel.fromJson(Map json) { + totalItemsCount = json['totalItemsCount']; + statusCode = json['statusCode']; + message = json['message']; + if (json['data'] != null) { + data = new List(); + json['data'].forEach((v) { + data.add(new QuickLinksData.fromJson(v)); + }); + } + } + + Map toJson() { + final Map data = new Map(); + data['totalItemsCount'] = this.totalItemsCount; + data['statusCode'] = this.statusCode; + data['message'] = this.message; + if (this.data != null) { + data['data'] = this.data.map((v) => v.toJson()).toList(); + } + return data; + } +} + +class QuickLinksData { + int quickLinksId; + String displayText; + String description; + String imageUrl; + String position; + int orderNo; + String fileName; + String exposeFilePath; + + QuickLinksData( + {this.quickLinksId, + this.displayText, + this.description, + this.imageUrl, + this.position, + this.orderNo, + this.fileName, + this.exposeFilePath}); + + QuickLinksData.fromJson(Map json) { + quickLinksId = json['quickLinksId']; + displayText = json['displayText']; + description = json['description']; + imageUrl = json['imageUrl']; + position = json['position']; + orderNo = json['orderNo']; + fileName = json['fileName']; + exposeFilePath = json['exposeFilePath']; + } + + Map toJson() { + final Map data = new Map(); + data['quickLinksId'] = this.quickLinksId; + data['displayText'] = this.displayText; + data['description'] = this.description; + data['imageUrl'] = this.imageUrl; + data['position'] = this.position; + data['orderNo'] = this.orderNo; + data['fileName'] = this.fileName; + data['exposeFilePath'] = this.exposeFilePath; + return data; + } +} diff --git a/lib/models/surah_model.dart b/lib/models/surah_model.dart index 108a2ea..4fb54b6 100644 --- a/lib/models/surah_model.dart +++ b/lib/models/surah_model.dart @@ -2,7 +2,7 @@ class SurahModel { int totalItemsCount; int statusCode; String message; - List data; + List data; SurahModel({this.totalItemsCount, this.statusCode, this.message, this.data}); @@ -11,9 +11,9 @@ class SurahModel { statusCode = json['statusCode']; message = json['message']; if (json['data'] != null) { - data = new List(); + data = new List(); json['data'].forEach((v) { - data.add(new Data.fromJson(v)); + data.add(new SurahModelData.fromJson(v)); }); } } @@ -30,7 +30,7 @@ class SurahModel { } } -class Data { +class SurahModelData { int id; int surahID; String nameAR; @@ -40,7 +40,7 @@ class Data { int revelationID; String revelationType; - Data( + SurahModelData( {this.id, this.surahID, this.nameAR, @@ -50,7 +50,7 @@ class Data { this.revelationID, this.revelationType}); - Data.fromJson(Map json) { + SurahModelData.fromJson(Map json) { id = json['id']; surahID = json['surahID']; nameAR = json['nameAR']; diff --git a/lib/models/tangheem_type_model.dart b/lib/models/tangheem_type_model.dart index ea9d9ce..390c00c 100644 --- a/lib/models/tangheem_type_model.dart +++ b/lib/models/tangheem_type_model.dart @@ -2,7 +2,7 @@ class TangheemType { int totalItemsCount; int statusCode; String message; - List data; + List data; TangheemType( {this.totalItemsCount, this.statusCode, this.message, this.data}); @@ -12,9 +12,9 @@ class TangheemType { statusCode = json['statusCode']; message = json['message']; if (json['data'] != null) { - data = new List(); + data = new List(); json['data'].forEach((v) { - data.add(new Data.fromJson(v)); + data.add(new TangheemTypeData.fromJson(v)); }); } } @@ -31,14 +31,14 @@ class TangheemType { } } -class Data { +class TangheemTypeData { String tangheemTypeId; String tangheemTypeName; bool isActive; - Data({this.tangheemTypeId, this.tangheemTypeName, this.isActive}); + TangheemTypeData({this.tangheemTypeId, this.tangheemTypeName, this.isActive}); - Data.fromJson(Map json) { + TangheemTypeData.fromJson(Map json) { tangheemTypeId = json['tangheemTypeId']; tangheemTypeName = json['tangheemTypeName']; isActive = json['isActive']; diff --git a/lib/ui/bottom_sheets/country_selection_bottom_sheet.dart b/lib/ui/bottom_sheets/country_selection_bottom_sheet.dart index ca8355d..4fbee18 100644 --- a/lib/ui/bottom_sheets/country_selection_bottom_sheet.dart +++ b/lib/ui/bottom_sheets/country_selection_bottom_sheet.dart @@ -4,8 +4,8 @@ import 'package:tangheem/models/country_model.dart'; import 'package:tangheem/widgets/common_textfield_widget.dart'; class CountrySelectionBottomSheet extends StatefulWidget { - final List countryList; - final Function(Data) onSelectCountry; + final List countryList; + final Function(CountryModelData) onSelectCountry; CountrySelectionBottomSheet({Key key, this.countryList, this.onSelectCountry}) : super(key: key); @override @@ -16,7 +16,7 @@ class CountrySelectionBottomSheet extends StatefulWidget { class _CountrySelectionBottomSheetState extends State { TextEditingController _searchCountryController = TextEditingController(); - List _filteredCountryList = []; + List _filteredCountryList = []; @override void initState() { diff --git a/lib/ui/common_appbar.dart b/lib/ui/common_appbar.dart index 79586a5..46b52d5 100644 --- a/lib/ui/common_appbar.dart +++ b/lib/ui/common_appbar.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:tangheem/classes/colors.dart'; import 'package:tangheem/ui/screens/login_screen.dart'; +import 'package:tangheem/ui/screens/surah_screen.dart'; class CommonAppbar extends StatefulWidget { final bool showDrawer; @@ -212,7 +213,9 @@ class _CommonAppbarState extends State { ), ), SizedBox(height: 2), - myListItem("assets/icons/read_quran.svg", "اقرأ القرآن الكريم", false), + myListItem("assets/icons/read_quran.svg", "اقرأ القرآن الكريم", false, onTap: () async { + await Navigator.pushNamed(context, SurahScreen.routeName, arguments: ""); + }), SizedBox(height: 2), myListItem("assets/icons/contact.svg", "الاتصال بنا", false), ], @@ -267,10 +270,13 @@ class _CommonAppbarState extends State { ); } - Widget myListItem(String icon, String title, bool isSelected) { + Widget myListItem(String icon, String title, bool isSelected, {VoidCallback onTap}) { return InkWell( onTap: () { Navigator.pop(context); + if (onTap != null) { + Future.delayed(Duration(milliseconds: 200), () => onTap()); + } }, child: Container( height: 40, diff --git a/lib/ui/screens/home_screen.dart b/lib/ui/screens/home_screen.dart index fcd473c..7e5e32c 100644 --- a/lib/ui/screens/home_screen.dart +++ b/lib/ui/screens/home_screen.dart @@ -3,7 +3,11 @@ import 'package:flutter/material.dart'; import 'package:flutter/painting.dart'; import 'package:flutter/services.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:tangheem/api/tangheem_user_api_client.dart'; import 'package:tangheem/classes/colors.dart'; +import 'package:tangheem/classes/utils.dart'; +import 'package:tangheem/models/surah_model.dart'; +import 'package:tangheem/models/tangheem_type_model.dart'; import 'package:tangheem/ui/screens/surah_screen.dart'; import 'package:tangheem/ui/screens/tangheem_screen.dart'; import 'package:tangheem/widgets/common_dropdown_button.dart'; @@ -23,10 +27,35 @@ class _HomeScreenState extends State { TextEditingController _searchController = TextEditingController(); FocusNode _searchFocusNode = FocusNode(); + List _surahList = []; + List _tangheemList = []; + + int _selectedSurah = 0; + int _selectedTangheemType = 0; + + SurahModel _surahModel; + TangheemType _tangheemType; + @override void initState() { super.initState(); SystemChannels.textInput.invokeMethod('TextInput.hide'); + getSurahAndTangheemTypes(); + } + + void getSurahAndTangheemTypes() async { + Utils.showLoading(context); + try { + _surahModel = await TangheemUserApiClient().getSurahs(); + _tangheemType = await TangheemUserApiClient().getTangheemType(); + _surahList = _surahModel.data.map((element) => element.nameAR).toList(); + _tangheemList = _tangheemType?.data?.where((element) => element.isActive)?.toList()?.map((element) => element.tangheemTypeName)?.toList() ?? []; + setState(() {}); + } catch (ex, tr) { + Utils.handleException(ex, null); + } finally { + Utils.hideLoading(context); + } } @override @@ -60,17 +89,29 @@ class _HomeScreenState extends State { style: TextStyle(fontSize: 14, color: ColorConsts.textGrey, height: 1), ), SizedBox(height: 32), - // Row( - // children: [ - // Expanded( - // child: CommonDropDownButton("الأسلوب اللغوي", onPressed: () {}), - // ), - // SizedBox(width: 8), - // Expanded( - // child: CommonDropDownButton("السورة", onPressed: () {}), - // ) - // ], - // ), + Row( + children: [ + Expanded( + child: CommonDropDownButton(_selectedTangheemType, list: _tangheemList, onSelect: (index) { + if (_selectedTangheemType != index) { + setState(() { + _selectedTangheemType = index; + }); + } + }), + ), + SizedBox(width: 8), + Expanded( + child: CommonDropDownButton(_selectedSurah, list: _surahList, onSelect: (index) { + if (_selectedSurah != index) { + setState(() { + _selectedSurah = index; + }); + } + }), + ) + ], + ), SizedBox(height: 16), InkWell( splashColor: Colors.transparent, @@ -78,16 +119,17 @@ class _HomeScreenState extends State { onTap: () async { _searchFocusNode.unfocus(); _searchFocusNode.canRequestFocus = false; - await Navigator.pushNamed(context, TangheemScreen.routeName); + var data = {"tangheemTypeName": _tangheemList[_selectedTangheemType], "surahData": _surahModel.data[_selectedSurah]}; + await Navigator.pushNamed(context, TangheemScreen.routeName, arguments: data); _searchFocusNode.canRequestFocus = true; }, child: Container( - height: 40, + height: 36, decoration: BoxDecoration( color: ColorConsts.secondaryPink, borderRadius: BorderRadius.circular(6), ), - padding: EdgeInsets.fromLTRB(8, 8, 8, 8), + padding: EdgeInsets.fromLTRB(8, 2, 8, 2), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, @@ -96,10 +138,9 @@ class _HomeScreenState extends State { Text( "ابدأ البحث", maxLines: 1, - // overflow: TextOverflow.ellipsis, style: TextStyle(fontSize: 12, color: Colors.white), ), - SizedBox(width: 8), + SizedBox(width: 12), SvgPicture.asset("assets/icons/go_forward.svg", width: 20, height: 20, color: Colors.white), ], ), @@ -123,10 +164,7 @@ class _HomeScreenState extends State { prefixIconConstraints: BoxConstraints(maxHeight: 16), prefixIcon: Padding( padding: EdgeInsets.only(right: 6), - child: SvgPicture.asset( - "assets/icons/search.svg", - //color: Const.secondaryOrange, - ), + child: SvgPicture.asset("assets/icons/search.svg"), ), suffixIcon: InkWell( onTap: () async { diff --git a/lib/ui/screens/registration_screen.dart b/lib/ui/screens/registration_screen.dart index e6cc260..83e4723 100644 --- a/lib/ui/screens/registration_screen.dart +++ b/lib/ui/screens/registration_screen.dart @@ -30,7 +30,7 @@ class _RegistrationScreenState extends State { bool _isAccept = false; - Data _selectedCountry; + CountryModelData _selectedCountry; CountryModel _countryModel; @override diff --git a/lib/ui/screens/surah_screen.dart b/lib/ui/screens/surah_screen.dart index 109125e..903d37a 100644 --- a/lib/ui/screens/surah_screen.dart +++ b/lib/ui/screens/surah_screen.dart @@ -11,12 +11,14 @@ import 'package:tangheem/widgets/auto_scroll_view/aya_scroll_view.dart'; import 'package:tangheem/widgets/auto_scroll_view/scroll_id.dart'; import 'package:tangheem/widgets/aya_player_widget.dart'; import 'package:tangheem/widgets/common_dropdown_button.dart'; +import 'package:tangheem/widgets/text_highlight_widget.dart'; class SurahScreen extends StatefulWidget { static const String routeName = "/surah"; + final SurahModel surahModel; final String query; - SurahScreen({Key key, @required this.query}) : super(key: key); + SurahScreen({Key key, this.surahModel, @required this.query}) : super(key: key); @override _SurahScreenState createState() { @@ -43,14 +45,18 @@ class _SurahScreenState extends State { void initState() { super.initState(); scrollToId = ScrollToId(scrollController: scrollController); - getSurahAndAya(); + getSurah(); } - void getSurahAndAya() async { + void getSurah() async { Utils.showLoading(context); try { - _surahModel = await TangheemUserApiClient().getSurahs(); - _surahList = _surahModel.data.map((element) => element.nameEN).toList(); + if (widget.surahModel == null) { + _surahModel = await TangheemUserApiClient().getSurahs(); + } else { + _surahModel = widget.surahModel; + } + _surahList = _surahModel.data.map((element) => element.nameAR).toList(); filterData(); } catch (ex, tr) { Utils.handleException(ex, null); @@ -102,7 +108,6 @@ class _SurahScreenState extends State { @override Widget build(BuildContext context) { String _surahAya = _ayaModel?.data?.map((e) => e.ayahText)?.toList()?.fold("", (value, element) => value + element) ?? ""; - return Container( padding: EdgeInsets.fromLTRB(16, 24, 16, 0), width: double.infinity, @@ -267,7 +272,7 @@ class _SurahScreenState extends State { ), ), ), - AyaPlayerWidget(surahName: _surahList.isNotEmpty ? _surahList[_selectedSurah] : null, globalKey: _globalKey) + AyaPlayerWidget(surahName: _surahList.isNotEmpty ? _surahList[_selectedSurah] : "", globalKey: _globalKey) ], ), ); diff --git a/lib/ui/screens/tangheem_screen.dart b/lib/ui/screens/tangheem_screen.dart index e7f0f5c..7232dc4 100644 --- a/lib/ui/screens/tangheem_screen.dart +++ b/lib/ui/screens/tangheem_screen.dart @@ -1,13 +1,22 @@ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; +import 'package:tangheem/api/tangheem_user_api_client.dart'; import 'package:tangheem/classes/colors.dart'; +import 'package:tangheem/classes/utils.dart'; +import 'package:tangheem/models/aya_model.dart'; +import 'package:tangheem/models/aya_tangheem_property.dart'; +import 'package:tangheem/models/aya_tangheem_type.dart'; +import 'package:tangheem/models/aya_tangheem_type_mapped.dart'; +import 'package:tangheem/models/surah_model.dart'; import 'package:tangheem/widgets/aya_player_widget.dart'; +import 'package:tangheem/widgets/text_highlight_widget.dart'; class TangheemScreen extends StatefulWidget { static const String routeName = "/tangheem"; - - TangheemScreen({Key key}) : super(key: key); + final tangheemTypeName; + final SurahModelData surah; + TangheemScreen({Key key, this.surah, this.tangheemTypeName}) : super(key: key); @override _TangheemScreenState createState() { @@ -17,25 +26,45 @@ class TangheemScreen extends StatefulWidget { class _TangheemScreenState extends State { GlobalKey _globalKey = GlobalKey(); - List temp1 = List(); - List temp2 = List(); + List _tangheemInsideTableTrueList = []; + List _tangheemInsideTableValueList = []; + List _tangheemInsideTableEmptyList = []; + List _tangheemWords = []; + + int _currentTangheemPage = -1; + AyatTangheemTypeMapped _ayatTangheemTypeMapped; + AyatTangheemTypeMappedData _ayatTangheemTypeMappedData; @override void initState() { super.initState(); - temp1 = [ - TempModel("نغمة الانتظار الصاعدة على آخر الجزء الأول من الجملة", "( الكتاب، اللاعنون )"), - TempModel("نغمة الانتظار الصاعدة على آخر الجزء الأول من الجملة", "( إلا الذين تابوا وأصلحوا وبينوا ..4)"), - ]; + _tangheemInsideTableValueList = []; + _tangheemInsideTableEmptyList = []; + getTangheemData(); + } - temp2 = [ - TempModel("تلوينات أدائية مناسبة", ""), - TempModel("شرح الاسلوب", ""), - ]; - searchQuery(); + void getTangheemData() async { + Utils.showLoading(context); + try { + _ayatTangheemTypeMapped = await TangheemUserApiClient().getAyaTangheemTypeMapped(0, widget.tangheemTypeName); + if (_ayatTangheemTypeMapped.data.length > 0) _currentTangheemPage = 0; + } catch (ex, tr) { + Utils.handleException(ex, null); + } finally { + Utils.hideLoading(context); + } + filterData(); } - void searchQuery() {} + void filterData() { + _ayatTangheemTypeMappedData = _ayatTangheemTypeMapped.data[_currentTangheemPage]; + _tangheemWords.add(_ayatTangheemTypeMappedData.highlightText ?? ""); + _tangheemInsideTableTrueList = _ayatTangheemTypeMappedData?.property?.where((element) => element.isInsideTable)?.toList() ?? []; + _tangheemInsideTableValueList = _ayatTangheemTypeMappedData?.property?.where((element) => (!element.isInsideTable) && (element.propertyValue ?? "").isNotEmpty)?.toList() ?? []; + _tangheemInsideTableEmptyList = _ayatTangheemTypeMappedData?.property?.where((element) => (!element.isInsideTable) && (element.propertyValue ?? "").isEmpty)?.toList() ?? []; + + setState(() {}); + } @override void dispose() { @@ -47,161 +76,201 @@ class _TangheemScreenState extends State { return Container( padding: EdgeInsets.fromLTRB(16, 24, 16, 0), width: double.infinity, - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "تنغيم أسلوب الإتمام", - style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: ColorConsts.primaryBlue, height: 1.5), - ), - SizedBox(height: 8), - Text( - "هنا نضع\" تعريف بالاستفهام وتداخل الأساليب\"", - style: TextStyle(fontSize: 14, color: ColorConsts.textGrey, height: 1), - ), - SizedBox(height: 8), - Expanded( - child: Container( - margin: EdgeInsets.only(top: 4, bottom: 4), - padding: EdgeInsets.only(top: 8, bottom: 8, right: 4, left: 4), - decoration: BoxDecoration( - color: Colors.white, - borderRadius: BorderRadius.circular(8), - ), - child: Column( - children: [ - Expanded( - child: ListView( - physics: BouncingScrollPhysics(), - padding: EdgeInsets.all(4), + child: _ayatTangheemTypeMappedData == null + ? SizedBox() + : Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + widget.tangheemTypeName ?? "", + style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: ColorConsts.primaryBlue, height: 1.5), + ), + SizedBox(height: 8), + Text( + "هنا نضع\" تعريف بالاستفهام وتداخل الأساليب\"", + style: TextStyle(fontSize: 14, color: ColorConsts.textGrey, height: 1), + ), + SizedBox(height: 8), + Expanded( + child: Container( + margin: EdgeInsets.only(top: 4, bottom: 4), + padding: EdgeInsets.only(top: 8, bottom: 8, right: 4, left: 4), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + child: Column( children: [ - Text( - " إِنَّ الَّذِينَ يَكْتُمُونَ مَا أَنْزَلْنَا مِنَ الْبَيِّنَاتِ وَالْهُدَىٰ مِنْ بَعْدِ مَا بَيَّنَّاهُ لِلنَّاسِ فِي الْكِتَابِ ۙ أُولَٰئِكَ يَلْعَنُهُمُ اللَّهُ وَيَلْعَنُهُمُ اللَّاعِنُونَ ﴿159﴾ إِلَّا الَّذِينَ تَابُوا وَأَصْلَحُوا وَبَيَّنُوا فَأُولَٰئِكَ أَتُوبُ عَلَيْهِمْ ۚ وَأَنَا التَّوَّابُ الرَّحِيمُ ﴿160﴾ْ", - textAlign: TextAlign.center, - style: TextStyle( - fontFamily: "UthmanicHafs", - color: ColorConsts.primaryBlue, - fontSize: 19, - fontWeight: FontWeight.bold, - ), - ), - SizedBox(height: 16), - Row( - children: [ - Expanded( - child: InkWell( - onTap: () {}, - child: Container( - height: 40, - padding: EdgeInsets.only(left: 4, right: 8), - alignment: Alignment.centerRight, - child: Text( - "نوع جملة الاتمام", - style: TextStyle(fontWeight: FontWeight.bold, color: ColorConsts.secondaryOrange), - ), - color: ColorConsts.secondaryWhite, + Expanded( + child: SingleChildScrollView( + physics: BouncingScrollPhysics(), + child: RepaintBoundary( + key: _globalKey, + child: Material( + color: Colors.white, + child: ListView( + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + padding: EdgeInsets.all(4), + children: [ + TextHighLightWidget( + text: _ayatTangheemTypeMappedData.ayahText ?? "", + valueColor: ColorConsts.primaryBlue, + highlights: _tangheemWords, + style: TextStyle( + fontFamily: "UthmanicHafs", + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + SizedBox(height: 16), + ListView.separated( + itemCount: _tangheemInsideTableValueList.length, + physics: NeverScrollableScrollPhysics(), + shrinkWrap: true, + separatorBuilder: (context, index) { + return Divider( + color: Colors.white, + height: 1, + thickness: 0, + ); + }, + itemBuilder: (context, index) { + return Row( + children: [ + Expanded( + child: Container( + height: 40, + padding: EdgeInsets.only(left: 4, right: 8), + alignment: Alignment.centerRight, + child: Text( + _tangheemInsideTableValueList[index].propertyText, + style: TextStyle(fontWeight: FontWeight.bold, color: ColorConsts.secondaryOrange), + ), + color: ColorConsts.secondaryWhite, + ), + ), + SizedBox(width: 8), + Expanded( + child: Container( + height: 40, + padding: EdgeInsets.only(left: 4, right: 8), + alignment: Alignment.centerRight, + child: Text( + _tangheemInsideTableValueList[index].propertyValue, + style: TextStyle(color: ColorConsts.primaryBlack), + ), + color: ColorConsts.secondaryWhite, + ), + ) + ], + ); + }), + if (_tangheemInsideTableTrueList.isNotEmpty) + Container( + color: ColorConsts.primaryBlue, + margin: EdgeInsets.only(top: 8, bottom: 8), + padding: EdgeInsets.all(8), + child: Column( + children: [ + Text( + widget.tangheemTypeName ?? "", + style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white), + ), + SizedBox(height: 8), + tangheemPropertyView(_tangheemInsideTableTrueList) + ], + ), + ), + tangheemPropertyView(_tangheemInsideTableEmptyList) + ], ), ), ), - SizedBox(width: 8), - Expanded( - child: InkWell( - onTap: () {}, - child: Container( - height: 40, - padding: EdgeInsets.only(left: 4, right: 8), - alignment: Alignment.centerRight, - child: Text( - "استثنائية", - style: TextStyle(color: ColorConsts.primaryBlack), - ), - color: ColorConsts.secondaryWhite, - ), - ), - ) - ], + ), ), - Container( - color: ColorConsts.primaryBlue, - margin: EdgeInsets.only(top: 8, bottom: 8), - padding: EdgeInsets.all(8), - child: Column( + SizedBox(height: 4), + Padding( + padding: EdgeInsets.only(left: 4, right: 4), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - "خط التنغيم لأسلوب الإتمام", - style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white), - ), - SizedBox(height: 8), - myListView(temp1) + nextOptionButton( + "assets/icons/prev_single.svg", + "الآيات السابقة", + (_currentTangheemPage == 0 || (_ayatTangheemTypeMapped.data.length < 1)) + ? null + : () { + _currentTangheemPage = _currentTangheemPage - 1; + filterData(); + }), + previousOptionButton( + "assets/icons/next_single.svg", + "الآيات التالية", + (_currentTangheemPage == (_ayatTangheemTypeMapped.data.length - 1) || (_ayatTangheemTypeMapped.data.length < 1)) + ? null + : () { + _currentTangheemPage = _currentTangheemPage + 1; + filterData(); + }), ], ), ), - myListView(temp2) - ], - ), - ), - SizedBox(height: 4), - Padding( - padding: EdgeInsets.only(left: 4, right: 4), - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - nextOptionButton("assets/icons/prev_single.svg", "الآيات السابقة", () {}), - previousOptionButton("assets/icons/next_single.svg", "الآيات التالية", () {}), ], ), ), - ], - ), + ), + AyaPlayerWidget(surahName: _ayatTangheemTypeMappedData.surahNameAr ?? "", globalKey: _globalKey, voiceNoteList: _ayatTangheemTypeMappedData.voiceNote ?? []) + ], ), - ), - AyaPlayerWidget(globalKey: null) - ], - ), ); } Widget nextOptionButton(String icon, String text, VoidCallback onPressed) { return InkWell( onTap: onPressed, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - SvgPicture.asset(icon, height: 12, width: 12), - SizedBox(width: 4), - Text( - text, - style: TextStyle(color: ColorConsts.textGrey), - ), - ], - ), + child: onPressed == null + ? SizedBox() + : Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + SvgPicture.asset(icon, height: 12, width: 12), + SizedBox(width: 4), + Text( + text, + style: TextStyle(color: ColorConsts.textGrey), + ), + ], + ), ); } Widget previousOptionButton(String icon, String text, VoidCallback onPressed) { return InkWell( onTap: onPressed, - child: Row( - crossAxisAlignment: CrossAxisAlignment.center, - mainAxisSize: MainAxisSize.min, - children: [ - Text( - text, - style: TextStyle(color: ColorConsts.textGrey), - ), - SizedBox(width: 4), - SvgPicture.asset(icon, height: 12, width: 12), - ], - ), + child: onPressed == null + ? SizedBox() + : Row( + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + text, + style: TextStyle(color: ColorConsts.textGrey), + ), + SizedBox(width: 4), + SvgPicture.asset(icon, height: 12, width: 12), + ], + ), ); } - Widget myListView(List temp) { + Widget tangheemPropertyView(List tangheemPropertyList) { return Container( color: Colors.white, child: ListView.separated( - itemCount: temp.length, + itemCount: tangheemPropertyList.length, physics: NeverScrollableScrollPhysics(), padding: EdgeInsets.zero, shrinkWrap: true, @@ -222,12 +291,12 @@ class _TangheemScreenState extends State { mainAxisAlignment: MainAxisAlignment.center, children: [ Text( - temp[index].title, + tangheemPropertyList[index].propertyText ?? "", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12, color: ColorConsts.secondaryOrange), ), SizedBox(height: 4), Text( - temp[index].description, + tangheemPropertyList[index].propertyValue ?? "", style: TextStyle(fontSize: 12, color: ColorConsts.secondaryPink), ), ], @@ -238,10 +307,3 @@ class _TangheemScreenState extends State { ); } } - -class TempModel { - String title; - String description; - - TempModel(this.title, this.description); -} diff --git a/lib/widgets/aya_player_widget.dart b/lib/widgets/aya_player_widget.dart index f1207be..11d5d8c 100644 --- a/lib/widgets/aya_player_widget.dart +++ b/lib/widgets/aya_player_widget.dart @@ -13,12 +13,14 @@ import 'package:permission_handler/permission_handler.dart'; import 'package:share/share.dart'; import 'package:tangheem/classes/colors.dart'; import 'package:tangheem/classes/utils.dart'; +import 'package:tangheem/models/aya_tangheem_type_mapped.dart'; import 'package:volume_controller/volume_controller.dart'; class AyaPlayerWidget extends StatefulWidget { final String surahName; final GlobalKey globalKey; - AyaPlayerWidget({Key key, this.surahName, @required this.globalKey}) : super(key: key); + final List voiceNoteList; + AyaPlayerWidget({Key key, this.surahName, this.voiceNoteList, @required this.globalKey}) : super(key: key); @override _AyaPlayerWidgetState createState() { @@ -32,22 +34,39 @@ class _AyaPlayerWidgetState extends State { AudioPlayer _player; bool _isAudioHaveError = false; + int _currentVoiceNote = -1; + @override void initState() { super.initState(); _player = AudioPlayer(); + setAudioSource(); + } + + setAudioSource() { try { - final _playlist = ConcatenatingAudioSource(children: [ - AudioSource.uri( - Uri.parse("https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_1MG.mp3"), - ), - ]); - _player.setAudioSource(_playlist, initialIndex: 0, initialPosition: Duration.zero).then((value) => () {}); + var voiceList = []; + if (widget.voiceNoteList != null && widget.voiceNoteList.length > 0) { + voiceList = widget.voiceNoteList.map((e) => AudioSource.uri(Uri.parse(e.exposeFilePath))).toList(); + _currentVoiceNote = 0; + } + final _playlist = ConcatenatingAudioSource(children: voiceList); + _player.setAudioSource(_playlist, initialIndex: 0, initialPosition: Duration.zero).then((value) => () {}).catchError(() { + _isAudioHaveError = true; + }); } catch (e) { _isAudioHaveError = true; } } + @override + void didUpdateWidget(covariant AyaPlayerWidget oldWidget) { + if (widget.voiceNoteList != oldWidget.voiceNoteList) { + setAudioSource(); + } + super.didUpdateWidget(oldWidget); + } + @override void dispose() { _player.dispose(); @@ -71,7 +90,6 @@ class _AyaPlayerWidgetState extends State { angle: 180 * math.pi / 180, child: SvgPicture.asset( "assets/icons/drop_menu.svg", - // color: Const.secondaryOrange, width: 16, ), ), @@ -95,14 +113,14 @@ class _AyaPlayerWidgetState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - widget.surahName ?? "سورة البقسورة", + widget.surahName, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14, color: ColorConsts.primaryBlack, height: 1), ), SizedBox(height: 4), Text( - "الشيخ عبد الشيخ عبد العزيز الزهراني", + _currentVoiceNote < 1 ? "" : widget.voiceNoteList[_currentVoiceNote], style: TextStyle(fontSize: 10, color: ColorConsts.textGrey1, height: 1), ), ], @@ -133,26 +151,33 @@ class _AyaPlayerWidgetState extends State { Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - commonIconButton("assets/icons/next_aya.svg", () {}), + commonIconButton("assets/icons/next_aya.svg", () { + _player.seekToNext(); + }), SizedBox(width: 4), StreamBuilder( stream: _player.playerStateStream, builder: (context, snapshot) { final state = snapshot.data?.playing ?? false; - if (state) { - if (_player.duration.inSeconds == _player.position.inSeconds) { + if (_player?.duration?.inSeconds == _player?.position?.inSeconds) { _player.pause(); _player.seek(Duration.zero); } } return commonIconButton(state ? "assets/icons/pause.svg" : "assets/icons/play_aya.svg", () { - state ? _player.pause() : _player.play(); + state + ? _player.pause() + : _isAudioHaveError + ? Utils.showToast("Audio file is not loaded") + : _player.play(); }); }, ), SizedBox(width: 4), - commonIconButton("assets/icons/previous_aya.svg", () {}), + commonIconButton("assets/icons/previous_aya.svg", () { + _player.seekToPrevious(); + }), SizedBox(width: 16), Expanded( child: StreamBuilder( @@ -240,7 +265,9 @@ class _AyaPlayerWidgetState extends State { Utils.hideLoading(context); return result["isSuccess"]; } catch (ex) { - Utils.hideLoading(context); + Future.delayed(Duration(seconds: 1), () { + Utils.hideLoading(context); + }); return false; } } @@ -259,7 +286,9 @@ class _AyaPlayerWidgetState extends State { Utils.hideLoading(context); Share.shareFiles(['${file.path}']); } catch (ex) { - Utils.hideLoading(context); + Future.delayed(Duration(seconds: 1), () { + Utils.hideLoading(context); + }); } } } diff --git a/lib/widgets/text_highlight_widget.dart b/lib/widgets/text_highlight_widget.dart new file mode 100644 index 0000000..8a90d1e --- /dev/null +++ b/lib/widgets/text_highlight_widget.dart @@ -0,0 +1,120 @@ +import 'dart:math'; +import 'package:flutter/material.dart'; +import 'package:tangheem/classes/colors.dart'; + +class TextHighLightWidget extends StatelessWidget { + final String text; + final String valueText; + final Color valueColor; + final List highlights; + final TextStyle style; + final Color highLightColor = ColorConsts.secondaryOrange; + + TextHighLightWidget({ + Key key, + this.text, + this.valueText, + this.valueColor, + this.highlights, + this.style = const TextStyle(), + }); + + @override + Widget build(BuildContext context) { + if (text == '') { + return _richText(_normalSpan(text)); + } + if (highlights.isEmpty) { + return _richText(_normalSpan(text)); + } + for (int i = 0; i < highlights.length; i++) { + if (highlights[i] == null) { + assert(highlights[i] != null); + return _richText(_normalSpan(text)); + } + if (highlights[i].isEmpty) { + assert(highlights[i].isNotEmpty); + return _richText(_normalSpan(text)); + } + } + + List _spans = List(); + int _start = 0; + List _lowerCaseHighlights = List(); + + highlights.forEach((element) { + _lowerCaseHighlights.add(element.toLowerCase()); + }); + + while (true) { + Map _highlightsMap = Map(); + + for (int i = 0; i < highlights.length; i++) { + int _index = text.toLowerCase().indexOf(_lowerCaseHighlights[i], _start); + if (_index >= 0) { + _highlightsMap.putIfAbsent(_index, () => highlights[i]); + } + } + + if (_highlightsMap.isNotEmpty) { + List _indexes = List(); + _highlightsMap.forEach((key, value) => _indexes.add(key)); + + int _currentIndex = _indexes.reduce(min); + String _currentHighlight = text.substring(_currentIndex, _currentIndex + _highlightsMap[_currentIndex].length); + + if (_currentIndex == _start) { + _spans.add(_highlightSpan(_currentHighlight)); + _start += _currentHighlight.length; + } else { + _spans.add(_normalSpan(text.substring(_start, _currentIndex))); + _spans.add(_highlightSpan(_currentHighlight)); + _start = _currentIndex + _currentHighlight.length; + } + } else { + _spans.add(_normalSpan(text.substring(_start, text.length))); + break; + } + } + + if (valueText != null) { + _spans.add(TextSpan( + text: ' ' + valueText, + style: TextStyle(color: valueColor ?? Color(0xff170026), fontSize: 12, fontWeight: FontWeight.w800), + )); + } + return _richText(TextSpan(children: _spans)); + } + + TextSpan _highlightSpan(String value) { + if (style.color == null) { + return TextSpan( + text: value, + style: style.copyWith(color: highLightColor, fontSize: 18), + ); + } else { + return TextSpan(text: value, style: style.copyWith(color: valueColor)); + } + } + + TextSpan _normalSpan(String value) { + if (style.color == null) { + return TextSpan( + text: value, + style: style.copyWith(color: valueColor), + ); + } else { + return TextSpan(text: value, style: style, children: [ + if (valueText != null) + TextSpan( + text: ' ' + valueText, + style: style, + ) + ]); + } + } + + RichText _richText(TextSpan text) { + return RichText(key: key, text: text, textAlign: TextAlign.center); + } +}