api methods added,

development
Sikander Saleem 5 years ago
parent 43a44cba93
commit aac94f590f

@ -0,0 +1,150 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:http/http.dart';
import 'package:http/io_client.dart';
import 'package:tangheem/exceptions/api_exception.dart';
typedef FactoryConstructor<U> = U Function(dynamic);
class APIError {
int errorCode;
String errorMessage;
APIError(this.errorCode, this.errorMessage);
Map<String, dynamic> toJson() => {'errorCode': errorCode, 'errorMessage': errorMessage};
@override
String toString() {
return jsonEncode(this);
}
}
APIException _throwAPIException(Response response) {
switch (response.statusCode) {
case 400:
APIError apiError;
if (response.body != null && response.body.isNotEmpty) {
var jsonError = jsonDecode(response.body);
apiError = APIError(jsonError['errorCode'], jsonError['errorMessage']);
}
return APIException(APIException.BAD_REQUEST, error: apiError);
case 401:
return APIException(APIException.UNAUTHORIZED);
case 403:
return APIException(APIException.FORBIDDEN);
case 404:
return APIException(APIException.NOT_FOUND);
case 500:
return APIException(APIException.INTERNAL_SERVER_ERROR);
case 444:
var downloadUrl = response.headers["location"];
return APIException(APIException.UPGRADE_REQUIRED, arguments: downloadUrl);
default:
return APIException(APIException.OTHER);
}
}
class ApiClient {
static final ApiClient _instance = ApiClient._internal();
ApiClient._internal();
factory ApiClient() => _instance;
Future<U> postJsonForObject<T, U>(FactoryConstructor<U> factoryConstructor, String url, T jsonObject,
{String token, Map<String, dynamic> queryParameters, Map<String, String> headers, int retryTimes = 0}) async {
var _headers = {'Accept': 'application/json'};
if (headers != null && headers.isNotEmpty) {
_headers.addAll(headers);
}
print("Url:$url");
var response = await postJsonForResponse(url, jsonObject, token: token, queryParameters: queryParameters, headers: _headers, retryTimes: retryTimes);
try {
var jsonData = jsonDecode(response.body);
return factoryConstructor(jsonData);
} catch (ex, tr) {
print('${ex.runtimeType}\n$ex\n$tr');
throw APIException(APIException.BAD_RESPONSE_FORMAT, arguments: ex);
}
}
Future<Response> postJsonForResponse<T>(String url, T jsonObject, {String token, Map<String, dynamic> queryParameters, Map<String, String> headers, int retryTimes = 0}) async {
String requestBody;
if (jsonObject != null) {
requestBody = jsonEncode(jsonObject);
if (headers == null) {
headers = {'Content-Type': 'application/json'};
} else {
headers['Content-Type'] = 'application/json';
}
}
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes);
}
Future<Response> _postForResponse(String url, requestBody, {String token, Map<String, dynamic> queryParameters, Map<String, String> headers, int retryTimes = 0}) async {
try {
var _headers = <String, String>{};
if (token != null) {
_headers['Authorization'] = 'Bearer $token';
}
if (headers != null && headers.isNotEmpty) {
_headers.addAll(headers);
}
if (queryParameters != null) {
var queryString = new Uri(queryParameters: queryParameters).query;
url = url + '?' + queryString;
}
var response = await _post(Uri.parse(url), body: requestBody, headers: _headers).timeout(Duration(seconds: 12));
if (response.statusCode >= 200 && response.statusCode < 300) {
return response;
} else {
throw _throwAPIException(response);
}
} on SocketException catch (e) {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
} on HttpException catch (e) {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
} on TimeoutException catch (e) {
throw APIException(APIException.TIMEOUT, arguments: e);
} on ClientException catch (e) {
if (retryTimes > 0) {
print('will retry after 3 seconds...');
await Future.delayed(Duration(seconds: 3));
return await _postForResponse(url, requestBody, token: token, queryParameters: queryParameters, headers: headers, retryTimes: retryTimes - 1);
} else {
throw APIException(APIException.OTHER, arguments: e);
}
}
}
bool _certificateCheck(X509Certificate cert, String host, int port) => true;
Future<T> _withClient<T>(Future<T> Function(Client) fn) async {
var httpClient = HttpClient()..badCertificateCallback = _certificateCheck;
var client = IOClient(httpClient);
try {
return await fn(client);
} finally {
client.close();
}
}
Future<Response> _post(url, {Map<String, String> headers, body, Encoding encoding}) => _withClient((client) => client.post(url, headers: headers, body: body, encoding: encoding));
}

@ -0,0 +1,3 @@
class AuthenticationApiClient{
}

@ -0,0 +1,24 @@
import 'dart:async';
import 'package:tangheem/api/api_client.dart';
import 'package:tangheem/classes/consts.dart';
import 'package:tangheem/models/aya_model.dart';
import 'package:tangheem/models/surah_model.dart';
class TangheemUserApiClient {
static final TangheemUserApiClient _instance = TangheemUserApiClient._internal();
TangheemUserApiClient._internal();
factory TangheemUserApiClient() => _instance;
Future<SurahModel> getSurahs() async {
String url = "${ApiConsts.tangheemUsers}AlSuar_Get";
var postParams = {};
return await ApiClient().postJsonForObject((json) => SurahModel.fromJson(json), url, postParams);
}
Future<AyaModel> 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};
return await ApiClient().postJsonForObject((json) => AyaModel.fromJson(json), url, postParams);
}
}

@ -0,0 +1 @@
class UserApiClient {}

@ -1,6 +1,6 @@
import 'package:flutter/cupertino.dart';
class Const {
class ColorConsts {
static Color primaryBlack = Color(0xff1C2238);
static Color primaryBlue = Color(0xff374061);

@ -0,0 +1,6 @@
class ApiConsts {
static String baseUrl = "http://10.200.204.20:2801/"; // Local server
static String authentication = baseUrl + "api/Authentication/";
static String tangheemUsers = baseUrl + "api/TangheemUsers/";
static String user = baseUrl + "api/User/";
}

@ -1,9 +1,56 @@
import 'package:flutter/material.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:tangheem/exceptions/api_exception.dart';
import 'package:tangheem/ui/dialogs/loading_dialog.dart';
import 'colors.dart';
class Utils {
static bool _isLoadingVisible = false;
static void showToast(String message) {
Fluttertoast.showToast(
msg: message, toastLength: Toast.LENGTH_SHORT, gravity: ToastGravity.BOTTOM, timeInSecForIosWeb: 1, backgroundColor: Colors.black54, textColor: Colors.white, fontSize: 16.0);
}
static void showLoading(BuildContext context) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_isLoadingVisible = true;
showDialog(
context: context,
barrierColor: ColorConsts.primaryBlack.withOpacity(0.5),
builder: (BuildContext context) => LoadingDialog(),
).then((value) {
_isLoadingVisible = false;
});
});
}
static void hideLoading(BuildContext context) {
if (_isLoadingVisible) {
_isLoadingVisible = false;
Navigator.of(context).pop();
}
_isLoadingVisible = false;
}
static void handleException(dynamic exception, Function(String) onErrorMessage) {
String errorMessage;
if (exception is APIException) {
if (exception.message == APIException.UNAUTHORIZED) {
return;
} else {
var message = exception.error?.errorMessage;
if (message == null) {
message = exception.message;
}
errorMessage = message;
}
} else {
errorMessage = APIException.UNKNOWN;
}
if (onErrorMessage != null) {
onErrorMessage(errorMessage);
} else {
showToast(errorMessage);
}
}
}

@ -0,0 +1,28 @@
import 'dart:convert';
import 'package:tangheem/api/api_client.dart';
class APIException implements Exception {
static const String BAD_REQUEST = 'api_common_bad_request';
static const String UNAUTHORIZED = 'api_common_unauthorized';
static const String FORBIDDEN = 'api_common_forbidden';
static const String NOT_FOUND = 'api_common_not_found';
static const String INTERNAL_SERVER_ERROR = 'api_common_internal_server_error';
static const String UPGRADE_REQUIRED = 'api_common_upgrade_required';
static const String BAD_RESPONSE_FORMAT = 'api_common_bad_response_format';
static const String OTHER = 'api_common_http_error';
static const String TIMEOUT = 'api_common_http_timeout';
static const String UNKNOWN = 'unexpected_error';
final String message;
final APIError error;
final arguments;
const APIException(this.message, {this.arguments, this.error});
Map<String, dynamic> toJson() => {'message': message, 'error': error, 'arguments': '$arguments'};
@override
String toString() {
return jsonEncode(this);
}
}

@ -10,7 +10,7 @@ import 'package:tangheem/ui/screens/registration_screen.dart';
import 'package:tangheem/ui/screens/surah_screen.dart';
import 'package:tangheem/ui/screens/tangheem_screen.dart';
import 'classes/const.dart';
import 'classes/colors.dart';
void main() {
runApp(Application());
@ -63,7 +63,7 @@ class Application extends StatelessWidget {
return ThemeData(
fontFamily: 'DroidKufi',
brightness: Brightness.light,
backgroundColor: Const.secondaryWhite,
backgroundColor: ColorConsts.secondaryWhite,
primarySwatch: Colors.blue,
primaryColor: Colors.white,
primaryColorBrightness: Brightness.light,

@ -0,0 +1,55 @@
class AuthenticationUserModel {
int totalItemsCount;
int statusCode;
String message;
Data data;
AuthenticationUserModel(
{this.totalItemsCount, this.statusCode, this.message, this.data});
AuthenticationUserModel.fromJson(Map<String, dynamic> json) {
totalItemsCount = json['totalItemsCount'];
statusCode = json['statusCode'];
message = json['message'];
data = json['data'] != null ? new Data.fromJson(json['data']) : null;
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['totalItemsCount'] = this.totalItemsCount;
data['statusCode'] = this.statusCode;
data['message'] = this.message;
if (this.data != null) {
data['data'] = this.data.toJson();
}
return data;
}
}
class Data {
String token;
String userId;
String email;
String mobileNumber;
String userName;
Data({this.token, this.userId, this.email, this.mobileNumber, this.userName});
Data.fromJson(Map<String, dynamic> json) {
token = json['token'];
userId = json['userId'];
email = json['email'];
mobileNumber = json['mobileNumber'];
userName = json['userName'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['token'] = this.token;
data['userId'] = this.userId;
data['email'] = this.email;
data['mobileNumber'] = this.mobileNumber;
data['userName'] = this.userName;
return data;
}
}

@ -0,0 +1,108 @@
class AyaModel {
int totalItemsCount;
int statusCode;
String message;
List<Data> data;
AyaModel({this.totalItemsCount, this.statusCode, this.message, this.data});
AyaModel.fromJson(Map<String, dynamic> json) {
totalItemsCount = json['totalItemsCount'];
statusCode = json['statusCode'];
message = json['message'];
if (json['data'] != null) {
data = new List<Data>();
json['data'].forEach((v) {
data.add(new Data.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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 Data {
int surahID;
String surahNameAR;
String surahNameEN;
int numberOfAyahs;
String englishNameTranslation;
int revelationID;
String revelationType;
int ayahID;
int numberInSurah;
int page;
int quarterID;
int juzID;
int manzil;
bool sajda;
String ayahText;
Null eighthsID;
Data(
{this.surahID,
this.surahNameAR,
this.surahNameEN,
this.numberOfAyahs,
this.englishNameTranslation,
this.revelationID,
this.revelationType,
this.ayahID,
this.numberInSurah,
this.page,
this.quarterID,
this.juzID,
this.manzil,
this.sajda,
this.ayahText,
this.eighthsID});
Data.fromJson(Map<String, dynamic> json) {
surahID = json['surahID'];
surahNameAR = json['surahNameAR'];
surahNameEN = json['surahNameEN'];
numberOfAyahs = json['numberOfAyahs'];
englishNameTranslation = json['englishNameTranslation'];
revelationID = json['revelation_ID'];
revelationType = json['revelationType'];
ayahID = json['ayahID'];
numberInSurah = json['numberInSurah'];
page = json['page'];
quarterID = json['quarter_ID'];
juzID = json['juz_ID'];
manzil = json['manzil'];
sajda = json['sajda'];
ayahText = json['ayah_Text'];
eighthsID = json['eighths_ID'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['surahID'] = this.surahID;
data['surahNameAR'] = this.surahNameAR;
data['surahNameEN'] = this.surahNameEN;
data['numberOfAyahs'] = this.numberOfAyahs;
data['englishNameTranslation'] = this.englishNameTranslation;
data['revelation_ID'] = this.revelationID;
data['revelationType'] = this.revelationType;
data['ayahID'] = this.ayahID;
data['numberInSurah'] = this.numberInSurah;
data['page'] = this.page;
data['quarter_ID'] = this.quarterID;
data['juz_ID'] = this.juzID;
data['manzil'] = this.manzil;
data['sajda'] = this.sajda;
data['ayah_Text'] = this.ayahText;
data['eighths_ID'] = this.eighthsID;
return data;
}
}

@ -0,0 +1,76 @@
class SurahModel {
int totalItemsCount;
int statusCode;
String message;
List<Data> data;
SurahModel({this.totalItemsCount, this.statusCode, this.message, this.data});
SurahModel.fromJson(Map<String, dynamic> json) {
totalItemsCount = json['totalItemsCount'];
statusCode = json['statusCode'];
message = json['message'];
if (json['data'] != null) {
data = new List<Data>();
json['data'].forEach((v) {
data.add(new Data.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
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 Data {
int id;
int surahID;
String nameAR;
String nameEN;
int numberOfAyahs;
String englishNameTranslation;
int revelationID;
String revelationType;
Data(
{this.id,
this.surahID,
this.nameAR,
this.nameEN,
this.numberOfAyahs,
this.englishNameTranslation,
this.revelationID,
this.revelationType});
Data.fromJson(Map<String, dynamic> json) {
id = json['id'];
surahID = json['surahID'];
nameAR = json['nameAR'];
nameEN = json['nameEN'];
numberOfAyahs = json['numberOfAyahs'];
englishNameTranslation = json['englishNameTranslation'];
revelationID = json['revelation_ID'];
revelationType = json['revelationType'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['id'] = this.id;
data['surahID'] = this.surahID;
data['nameAR'] = this.nameAR;
data['nameEN'] = this.nameEN;
data['numberOfAyahs'] = this.numberOfAyahs;
data['englishNameTranslation'] = this.englishNameTranslation;
data['revelation_ID'] = this.revelationID;
data['revelationType'] = this.revelationType;
return data;
}
}

@ -0,0 +1,46 @@
class UserRegistrationModel {
String userName;
String password;
String email;
String countryCode;
String mobileNumber;
bool isUserLock;
int gender;
int passWrongAttempt;
int statusId;
bool isEmailVerified;
bool isMobileVerified;
UserRegistrationModel(
{this.userName, this.password, this.email, this.countryCode, this.mobileNumber, this.isUserLock, this.gender, this.passWrongAttempt, this.statusId, this.isEmailVerified, this.isMobileVerified});
UserRegistrationModel.fromJson(Map<String, dynamic> json) {
userName = json['userName'];
password = json['password'];
email = json['email'];
countryCode = json['countryCode'];
mobileNumber = json['mobileNumber'];
isUserLock = json['isUserLock'];
gender = json['gender'];
passWrongAttempt = json['passWrongAttempt'];
statusId = json['statusId'];
isEmailVerified = json['isEmailVerified'];
isMobileVerified = json['isMobileVerified'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['userName'] = this.userName;
data['password'] = this.password;
data['email'] = this.email;
data['countryCode'] = this.countryCode;
data['mobileNumber'] = this.mobileNumber;
data['isUserLock'] = this.isUserLock;
data['gender'] = this.gender;
data['passWrongAttempt'] = this.passWrongAttempt;
data['statusId'] = this.statusId;
data['isEmailVerified'] = this.isEmailVerified;
data['isMobileVerified'] = this.isMobileVerified;
return data;
}
}

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tangheem/classes/const.dart';
import 'package:tangheem/classes/colors.dart';
import 'package:tangheem/ui/screens/login_screen.dart';
class CommonAppbar extends StatefulWidget {
@ -48,7 +48,7 @@ class _CommonAppbarState extends State<CommonAppbar> {
children: [
if (!widget.isFirst)
IconButton(
icon: Icon(widget.showDrawer ? Icons.menu : Icons.arrow_back_ios, color: Const.textGrey),
icon: Icon(widget.showDrawer ? Icons.menu : Icons.arrow_back_ios, color: ColorConsts.textGrey),
padding: EdgeInsets.only(left: 16),
onPressed: () {
if (widget.showDrawer) {
@ -93,7 +93,7 @@ class _CommonAppbarState extends State<CommonAppbar> {
padding: EdgeInsets.only(left: 0, top: height),
alignment: Alignment.centerLeft,
child: IconButton(
icon: Icon(Icons.clear, color: Const.textGrey),
icon: Icon(Icons.clear, color: ColorConsts.textGrey),
onPressed: () {
if (_scaffoldKey.currentState.isDrawerOpen) {
Navigator.pop(context);
@ -138,7 +138,7 @@ class _CommonAppbarState extends State<CommonAppbar> {
height: 40,
margin: EdgeInsets.only(right: 17, left: 10),
// color: Const.primaryBlack,
child: VerticalDivider(color: Const.primaryBlack, thickness: .7, width: 1),
child: VerticalDivider(color: ColorConsts.primaryBlack, thickness: .7, width: 1),
),
],
),
@ -155,7 +155,7 @@ class _CommonAppbarState extends State<CommonAppbar> {
height: 40,
margin: EdgeInsets.only(right: 17, left: 10),
// color: Const.primaryBlack,
child: VerticalDivider(color: Const.primaryBlack, thickness: .7, width: 1),
child: VerticalDivider(color: ColorConsts.primaryBlack, thickness: .7, width: 1),
),
],
),
@ -172,7 +172,7 @@ class _CommonAppbarState extends State<CommonAppbar> {
height: 40,
margin: EdgeInsets.only(right: 17, left: 10),
// color: Const.primaryBlack,
child: VerticalDivider(color: Const.primaryBlack, thickness: .7, width: 1),
child: VerticalDivider(color: ColorConsts.primaryBlack, thickness: .7, width: 1),
),
],
),
@ -189,7 +189,7 @@ class _CommonAppbarState extends State<CommonAppbar> {
height: 40,
margin: EdgeInsets.only(right: 17, left: 10),
// color: Const.primaryBlack,
child: VerticalDivider(color: Const.primaryBlack, thickness: .7, width: 1),
child: VerticalDivider(color: ColorConsts.primaryBlack, thickness: .7, width: 1),
),
],
),
@ -206,7 +206,7 @@ class _CommonAppbarState extends State<CommonAppbar> {
height: 40,
margin: EdgeInsets.only(right: 17, left: 10),
// color: Const.primaryBlack,
child: VerticalDivider(color: Const.primaryBlack, thickness: .7, width: 1),
child: VerticalDivider(color: ColorConsts.primaryBlack, thickness: .7, width: 1),
),
],
),
@ -283,7 +283,7 @@ class _CommonAppbarState extends State<CommonAppbar> {
stops: [0.0, 0.5],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Const.gradientPink, Const.gradientOrange],
colors: [ColorConsts.gradientPink, ColorConsts.gradientOrange],
)
: null,
),
@ -292,10 +292,10 @@ class _CommonAppbarState extends State<CommonAppbar> {
children: [
Text(
title,
style: TextStyle(fontSize: 14, color: isSelected ? Colors.white : Const.textGrey),
style: TextStyle(fontSize: 14, color: isSelected ? Colors.white : ColorConsts.textGrey),
),
SizedBox(width: 8),
SvgPicture.asset(icon, height: 20, width: 20, color: isSelected ? Colors.white : Const.textGrey),
SvgPicture.asset(icon, height: 20, width: 20, color: isSelected ? Colors.white : ColorConsts.textGrey),
],
),
),

@ -0,0 +1,59 @@
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:tangheem/classes/colors.dart';
class LoadingDialog extends StatefulWidget {
LoadingDialog({Key key}) : super(key: key);
@override
_LoadingDialogState createState() {
return _LoadingDialogState();
}
}
class _LoadingDialogState extends State<LoadingDialog> {
@override
void initState() {
super.initState();
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Dialog(
insetPadding: EdgeInsets.symmetric(horizontal: 60.0, vertical: 24.0),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
elevation: 0,
backgroundColor: Colors.transparent,
child: Directionality(
textDirection: TextDirection.rtl,
child: Center(
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(16),
),
padding: EdgeInsets.symmetric(vertical: 12, horizontal: 12),
child: SizedBox(
height: 32,
width: 32,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor: AlwaysStoppedAnimation<Color>(ColorConsts.textGrey),
),
),
),
),
),
);
}
}

@ -1,7 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:tangheem/classes/const.dart';
import 'package:tangheem/classes/colors.dart';
import 'package:tangheem/widgets/otp_widget.dart';
class OTPDialog extends StatefulWidget {
@ -42,7 +42,7 @@ class _OTPDialogState extends State<OTPDialog> {
child: Container(
width: double.infinity,
decoration: BoxDecoration(
color: Const.primaryBlue,
color: ColorConsts.primaryBlue,
borderRadius: BorderRadius.circular(16),
),
padding: EdgeInsets.symmetric(vertical: 32, horizontal: 16),
@ -63,7 +63,7 @@ class _OTPDialogState extends State<OTPDialog> {
border: Border.all(width: 1, color: Colors.white),
),
child: OTPWidget(
autofocus: true,
autoFocus: true,
controller: _pinPutController,
defaultBorderColor: Colors.transparent,
maxLength: 4,
@ -73,12 +73,12 @@ class _OTPDialogState extends State<OTPDialog> {
hasError = false;
});
},
pinBoxColor: Const.secondaryWhite.withOpacity(0.2),
pinBoxColor: ColorConsts.secondaryWhite.withOpacity(0.2),
onDone: (text) {},
textBorderColor: Colors.transparent,
pinBoxWidth: 40,
pinBoxHeight: 40,
pinTextStyle: TextStyle(fontSize: 20.0, color: Colors.white),
pinTextStyle: TextStyle(fontSize: 20.0, color: Colors.white,height: .2),
pinTextAnimatedSwitcherTransition: ProvidedPinBoxTextAnimation.scalingTransition,
pinTextAnimatedSwitcherDuration: Duration(milliseconds: 300),
keyboardType: TextInputType.number,
@ -94,7 +94,7 @@ class _OTPDialogState extends State<OTPDialog> {
style: TextButton.styleFrom(
primary: Colors.white,
padding: EdgeInsets.all(2),
backgroundColor: Const.secondaryPink,
backgroundColor: ColorConsts.secondaryPink,
textStyle: TextStyle(fontSize: 14, fontFamily: "DroidKufi"),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6.0),
@ -111,7 +111,7 @@ class _OTPDialogState extends State<OTPDialog> {
BoxDecoration get _pinPutDecoration {
return BoxDecoration(
color: Const.secondaryWhite.withOpacity(0.2),
color: ColorConsts.secondaryWhite.withOpacity(0.2),
//border: Border.all(color: Colors.deepPurpleAccent),
//borderRadius: BorderRadius.circular(0.0),
);

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:tangheem/classes/const.dart';
import 'package:tangheem/classes/colors.dart';
import 'package:tangheem/classes/utils.dart';
import 'package:tangheem/ui/dialogs/opt_dialog.dart';
import 'package:tangheem/widgets/common_textfield_widget.dart';
@ -33,7 +33,7 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Const.secondaryWhite,
backgroundColor: ColorConsts.secondaryWhite,
body: SingleChildScrollView(
padding: EdgeInsets.all(32.0),
physics: BouncingScrollPhysics(),
@ -50,14 +50,14 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
),
Text(
"نسيت كلمة المرور؟",
style: TextStyle(fontSize: 22, color: Const.primaryBlue),
style: TextStyle(fontSize: 22, color: ColorConsts.primaryBlue),
),
Container(
margin: EdgeInsets.only(top: 16),
width: double.infinity,
padding: EdgeInsets.all(32.0),
decoration: BoxDecoration(
color: Const.primaryBlue,
color: ColorConsts.primaryBlue,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(8),
bottomRight: Radius.circular(8),
@ -92,7 +92,7 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
},
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: Const.secondaryPink,
backgroundColor: ColorConsts.secondaryPink,
textStyle: TextStyle(fontSize: 16, fontFamily: "DroidKufi"),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6.0),
@ -114,7 +114,7 @@ class _ForgotPasswordScreenState extends State<ForgotPasswordScreen> {
getOTP() {
showDialog(
context: context,
barrierColor: Const.secondaryWhite.withOpacity(0.8),
barrierColor: ColorConsts.secondaryWhite.withOpacity(0.8),
builder: (BuildContext context) => OTPDialog(),
);
}

@ -3,7 +3,7 @@ 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/classes/const.dart';
import 'package:tangheem/classes/colors.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';
@ -47,44 +47,63 @@ class _HomeScreenState extends State<HomeScreen> {
children: [
Text(
"موسوعةالأداء القرآني",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Const.primaryBlue, height: 1),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: ColorConsts.primaryBlue, height: 1),
),
SizedBox(height: 4),
Text(
"للأساليب اللغوية",
style: TextStyle(fontSize: 20, color: Const.primaryBlue, height: 1),
style: TextStyle(fontSize: 20, color: ColorConsts.primaryBlue, height: 1),
),
SizedBox(height: 8),
Text(
"تساعدك موسوعة \"تنغيم\" على أداء الأساليب اللغوية القرآنية (كالاستفهام والأمر والنهي والإتمام) بما يخدم معنى الآية. وقد أشرف عليها متخصصون في اللغة العربية والدراسات القرآنية.",
style: TextStyle(fontSize: 14, color: Const.textGrey, height: 1),
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("الأسلوب اللغوي", onPressed: () {}),
// ),
// SizedBox(width: 8),
// Expanded(
// child: CommonDropDownButton("السورة", onPressed: () {}),
// )
// ],
// ),
SizedBox(height: 16),
CommonDropDownButton(
"ابدأ البحث",
color: Const.secondaryPink,
icon: "assets/icons/go_forward.svg",
widthHeight: 20,
isExpanded: false,
iconColor: Colors.white,
onPressed: () async {
InkWell(
splashColor: Colors.transparent,
highlightColor: Colors.transparent,
onTap: () async {
_searchFocusNode.unfocus();
_searchFocusNode.canRequestFocus = false;
await Navigator.pushNamed(context, TangheemScreen.routeName);
_searchFocusNode.canRequestFocus = true;
},
child: Container(
height: 40,
decoration: BoxDecoration(
color: ColorConsts.secondaryPink,
borderRadius: BorderRadius.circular(6),
),
padding: EdgeInsets.fromLTRB(8, 8, 8, 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text(
"ابدأ البحث",
maxLines: 1,
// overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 12, color: Colors.white),
),
SizedBox(width: 8),
SvgPicture.asset("assets/icons/go_forward.svg", width: 20, height: 20, color: Colors.white),
],
),
),
),
SizedBox(height: 16),
Container(
@ -93,13 +112,13 @@ class _HomeScreenState extends State<HomeScreen> {
child: TextField(
controller: _searchController,
focusNode: _searchFocusNode,
style: TextStyle(color: Const.primaryBlack, fontSize: 14),
style: TextStyle(color: ColorConsts.primaryBlack, fontSize: 14),
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(4, 4, 4, 4),
alignLabelWithHint: true,
fillColor: Colors.white,
filled: true,
hintStyle: TextStyle(color: Const.textHintGrey, fontSize: 12),
hintStyle: TextStyle(color: ColorConsts.textHintGrey, fontSize: 12),
hintText: "البحث عن سورة أو آية",
prefixIconConstraints: BoxConstraints(maxHeight: 16),
prefixIcon: Padding(
@ -126,7 +145,7 @@ class _HomeScreenState extends State<HomeScreen> {
style: TextStyle(fontSize: 14, color: Colors.white),
),
decoration: BoxDecoration(
color: Const.secondaryPink,
color: ColorConsts.secondaryPink,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(6),
topLeft: Radius.circular(6),

@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tangheem/classes/const.dart';
import 'package:tangheem/classes/colors.dart';
import 'package:tangheem/classes/utils.dart';
import 'package:tangheem/ui/screens/forgot_password_screen.dart';
import 'package:tangheem/ui/screens/registration_screen.dart';
@ -35,7 +35,7 @@ class _LoginScreenState extends State<LoginScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Const.secondaryWhite,
backgroundColor: ColorConsts.secondaryWhite,
body: SafeArea(
child: Directionality(
textDirection: TextDirection.rtl,
@ -55,13 +55,13 @@ class _LoginScreenState extends State<LoginScreen> {
),
Text(
"تسجيل الدخول",
style: TextStyle(fontSize: 22, color: Const.primaryBlue),
style: TextStyle(fontSize: 22, color: ColorConsts.primaryBlue),
),
Container(
margin: EdgeInsets.only(top: 16),
width: double.infinity,
padding: EdgeInsets.all(32.0),
color: Const.primaryBlue,
color: ColorConsts.primaryBlue,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
@ -86,7 +86,7 @@ class _LoginScreenState extends State<LoginScreen> {
},
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: Const.secondaryPink,
backgroundColor: ColorConsts.secondaryPink,
textStyle: TextStyle(fontSize: 16, fontFamily: "DroidKufi"),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6.0),
@ -139,7 +139,7 @@ class _LoginScreenState extends State<LoginScreen> {
height: 50,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Const.tertiaryPurple,
color: ColorConsts.tertiaryPurple,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(8),
bottomRight: Radius.circular(8),

@ -1,7 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:tangheem/classes/const.dart';
import 'package:tangheem/classes/colors.dart';
import 'package:tangheem/classes/utils.dart';
import 'package:tangheem/widgets/common_textfield_widget.dart';
import 'package:tangheem/extensions/email_validator.dart';
@ -39,7 +39,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Const.secondaryWhite,
backgroundColor: ColorConsts.secondaryWhite,
body: SingleChildScrollView(
padding: EdgeInsets.all(32.0),
physics: BouncingScrollPhysics(),
@ -56,14 +56,14 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
),
Text(
"انشاء حساب جديد",
style: TextStyle(fontSize: 22, color: Const.primaryBlue),
style: TextStyle(fontSize: 22, color: ColorConsts.primaryBlue),
),
Padding(
padding: EdgeInsets.all(8),
child: Text(
"قم بتعبئة بيانات طلب انشاء الحساب و ستصلك رسالة تأكيد, ومن ثم يمكنك الدخول لحسابك الجديد",
textAlign: TextAlign.center,
style: TextStyle(fontSize: 14, color: Const.primaryBlue, height: 1),
style: TextStyle(fontSize: 14, color: ColorConsts.primaryBlue, height: 1),
),
),
Container(
@ -71,7 +71,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
width: double.infinity,
padding: EdgeInsets.all(32.0),
decoration: BoxDecoration(
color: Const.primaryBlue,
color: ColorConsts.primaryBlue,
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(8),
bottomRight: Radius.circular(8),
@ -171,7 +171,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
},
style: TextButton.styleFrom(
primary: Colors.white,
backgroundColor: Const.secondaryPink,
backgroundColor: ColorConsts.secondaryPink,
textStyle: TextStyle(fontSize: 16, fontFamily: "DroidKufi"),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(6.0),
@ -216,7 +216,7 @@ class _RegistrationScreenState extends State<RegistrationScreen> {
Container(
padding: EdgeInsets.all(16),
decoration: BoxDecoration(
color: Const.primaryBlue,
color: ColorConsts.primaryBlue,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16),
topRight: Radius.circular(16),

@ -1,7 +1,11 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tangheem/classes/const.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/surah_model.dart';
import 'package:tangheem/widgets/aya_player_widget.dart';
import 'package:tangheem/widgets/common_dropdown_button.dart';
@ -18,13 +22,65 @@ class SurahScreen extends StatefulWidget {
}
class _SurahScreenState extends State<SurahScreen> {
int _selectedSurah = 0;
int _selectedFromAya = 0;
int _selectedToAya = 0;
int _currentPage = 0;
int _ayaInPage = 0;
List<String> _surahList = [];
List<int> _fromAyaList = [];
List<int> _toAyaList = [];
SurahModel _surahModel;
AyaModel _ayaModel;
@override
void initState() {
super.initState();
searchQuery();
getSurahAndAya();
}
void getSurahAndAya() async {
Utils.showLoading(context);
try {
_surahModel = await TangheemUserApiClient().getSurahs();
_surahList = _surahModel.data.map((element) => element.nameEN).toList();
filterData();
} catch (ex, tr) {
Utils.handleException(ex, null);
} finally {
Utils.hideLoading(context);
}
}
void searchQuery() {}
int numberOfAyah = 0;
void filterData() {
numberOfAyah = _surahModel?.data[_selectedSurah]?.numberOfAyahs ?? 0;
var filteredAyahList = List.generate(getNextMultiple(numberOfAyah), (index) => index + 1).toList().where((element) => element == 1 || (element % 5) == 0).toList() ?? [];
_fromAyaList = filteredAyahList.getRange(0, filteredAyahList.length - 1)?.toList() ?? [];
_toAyaList = filteredAyahList.getRange(1, filteredAyahList.length)?.toList() ?? [];
getAyaByRange();
}
void getAyaByRange() async {
Utils.showLoading(context);
try {
_ayaModel = await TangheemUserApiClient().getAyaByRange(5, 1, _selectedSurah + 1, _fromAyaList[_selectedFromAya], _toAyaList[_selectedToAya]);
setState(() {});
} catch (ex, tr) {
Utils.handleException(ex, null);
} finally {
Utils.hideLoading(context);
}
}
int getNextMultiple(int num) {
int multipleOf = 5;
int nextDiff = multipleOf - (num % multipleOf);
int total = num + nextDiff;
return total;
}
@override
void dispose() {
@ -41,21 +97,39 @@ class _SurahScreenState extends State<SurahScreen> {
children: [
Text(
"اقرأ القرآن الكريم",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Const.primaryBlue, height: 1),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: ColorConsts.primaryBlue, height: 1),
),
SizedBox(height: 16),
Row(
children: [
Expanded(
child: CommonDropDownButton("سورة البقرة", onPressed: () {}),
child: CommonDropDownButton(_selectedSurah, list: _surahList, onSelect: (index) {
if (_selectedSurah != index) {
_selectedSurah = index;
_selectedToAya = 0;
_selectedFromAya = 0;
filterData();
}
}),
),
SizedBox(width: 4),
Expanded(
child: CommonDropDownButton("من الاية" + " 158", onPressed: () {}),
child: CommonDropDownButton(_selectedFromAya, list: _fromAyaList.map((e) => "من الاية" + " $e").toList(), onSelect: (index) {
if (_selectedFromAya != index) {
_selectedFromAya = index;
_selectedToAya = index;
filterData();
}
}),
),
SizedBox(width: 4),
Expanded(
child: CommonDropDownButton("الى الاية" + " 123", onPressed: () {}),
child: CommonDropDownButton(_selectedToAya, list: _toAyaList.map((e) => "الى الاية" + " $e").toList(), onSelect: (index) {
if (_selectedToAya != index) {
_selectedToAya = index;
filterData();
}
}),
),
],
),
@ -85,17 +159,17 @@ class _SurahScreenState extends State<SurahScreen> {
Text(
"بسم الله الرحمن الرحيم",
textAlign: TextAlign.center,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Const.primaryBlue, height: 1),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: ColorConsts.primaryBlue, height: 1),
),
SizedBox(height: 8),
Container(
padding: EdgeInsets.only(left: 4, right: 4),
child: Text(
"إِنَّ الصَّفَا وَالْمَرْوَةَ مِنْ شَعَائِرِ اللَّهِ ۖ فَمَنْ حَجَّ الْبَيْتَ أَوِ اعْتَمَرَ فَلَا جُنَاحَ عَلَيْهِ أَنْ يَطَّوَّفَ بِهِمَا ۚ وَمَنْ تَطَوَّعَ خَيْرًا فَإِنَّ اللَّهَ شَاكِرٌ عَلِيمٌ ﴿158 إِنَّ الَّذِينَ يَكْتُمُونَ مَا أَنْزَلْنَا مِنَ الْبَيِّنَاتِ وَالْهُدَىٰ مِنْ بَعْدِ مَا بَيَّنَّاهُ لِلنَّاسِ فِي الْكِتَابِ ۙ أُولَٰئِكَ يَلْعَنُهُمُ اللَّهُ وَيَلْعَنُهُمُ اللَّاعِنُونَ ﴿159 إِلَّا الَّذِينَ تَابُوا وَأَصْلَحُوا وَبَيَّنُوا فَأُولَٰئِكَ أَتُوبُ عَلَيْهِمْ ۚ وَأَنَا التَّوَّابُ الرَّحِيمُ ﴿160 إِنَّ الَّذِينَ كَفَرُوا وَمَاتُوا وَهُمْ كُفَّارٌ أُولَٰئِكَ عَلَيْهِمْ لَعْنَةُ اللَّهِ وَالْمَلَائِكَةِ وَالنَّاسِ أَجْمَعِينَ ﴿161 خَالِدِينَ فِيهَا ۖ لَا يُخَفَّفُ عَنْهُمُ الْعَذَابُ وَلَا هُمْ يُنْظَرُونَ ﴿162 وَإِلَٰهُكُمْ إِلَٰهٌ وَاحِدٌ ۖ لَا إِلَٰهَ إِلَّا هُوَ الرَّحْمَٰنُ الرَّحِيمُ ﴿163إِنَّ فِي خَلْقِ السَّمَاوَاتِ وَالْأَرْضِ وَاخْتِلَافِ اللَّيْلِ وَالنَّهَارِ وَالْفُلْكِ الَّتِي تَجْرِي فِي الْبَحْرِ بِمَا يَنْفَعُ النَّاسَ وَمَا أَنْزَلَ اللَّهُ مِنَ السَّمَاءِ مِنْ مَاءٍ فَأَحْيَا بِهِ الْأَرْضَ بَعْدَ مَوْتِهَا وَبَثَّ فِيهَا مِنْ كُلِّ دَابَّةٍ وَتَصْرِيفِ الرِّيَاحِ وَالسَّحَابِ الْمُسَخَّرِ بَيْنَ السَّمَاءِ وَالْأَرْضِ لَآيَاتٍ لِقَوْمٍ يَعْقِلُونَ ﴿164 وَمِنَ النَّاسِ مَنْ يَتَّخِذُ مِنْ دُونِ اللَّهِ أَنْدَادًا يُحِبُّونَهُمْ كَحُبِّ اللَّهِ ۖ وَالَّذِينَ آمَنُوا أَشَدُّ حُبًّا لِلَّهِ ۗ وَلَوْ يَرَى الَّذِينَ ظَلَمُوا إِذْ يَرَوْنَ الْعَذَابَ أَنَّ الْقُوَّةَ لِلَّهِ جَمِيعًا وَأَنَّ اللَّهَ شَدِيدُ الْعَذَابِ ﴿165 إِذْ تَبَرَّأَ الَّذِينَ اتُّبِعُوا مِنَ الَّذِينَ اتَّبَعُوا وَرَأَوُا الْعَذَابَ وَتَقَطَّعَتْ بِهِمُ الْأَسْبَابُ ﴿166 وَقَالَ الَّذِينَ اتَّبَعُوا لَوْ أَنَّ لَنَا كَرَّةً فَنَتَبَرَّأَ مِنْهُمْ كَمَا تَبَرَّءُوا مِنَّا ۗ كَذَٰلِكَ يُرِيهِمُ اللَّهُ أَعْمَالَهُمْ حَسَرَاتٍ عَلَيْهِمْ ۖ وَمَا هُمْ بِخَارِجِينَ مِنَ النَّارِ ﴿1674",
_ayaModel?.data?.map((e) => e.ayahText)?.toList()?.reduce((value, element) => value + element) ?? "",
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: "UthmanicHafs",
color: Const.primaryBlue,
color: ColorConsts.primaryBlue,
fontSize: 18,
fontWeight: FontWeight.bold,
),
@ -107,7 +181,7 @@ class _SurahScreenState extends State<SurahScreen> {
SizedBox(height: 8),
Text(
"1 2 3 4 5 6 7 8 9",
style: TextStyle(fontSize: 16, color: Const.textHintGrey),
style: TextStyle(fontSize: 16, color: ColorConsts.textHintGrey),
),
SizedBox(height: 4),
Row(
@ -138,7 +212,7 @@ class _SurahScreenState extends State<SurahScreen> {
SizedBox(width: 4),
Text(
text,
style: TextStyle(color: Const.textGrey),
style: TextStyle(color: ColorConsts.textGrey),
),
],
),
@ -154,7 +228,7 @@ class _SurahScreenState extends State<SurahScreen> {
children: [
Text(
text,
style: TextStyle(color: Const.textGrey),
style: TextStyle(color: ColorConsts.textGrey),
),
SizedBox(width: 4),
SvgPicture.asset(icon, height: 12, width: 12),

@ -1,7 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tangheem/classes/const.dart';
import 'package:tangheem/classes/colors.dart';
import 'package:tangheem/widgets/aya_player_widget.dart';
class TangheemScreen extends StatefulWidget {
@ -51,12 +51,12 @@ class _TangheemScreenState extends State<TangheemScreen> {
children: [
Text(
"تنغيم أسلوب الإتمام",
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Const.primaryBlue, height: 1.5),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: ColorConsts.primaryBlue, height: 1.5),
),
SizedBox(height: 8),
Text(
"هنا نضع\" تعريف بالاستفهام وتداخل الأساليب\"",
style: TextStyle(fontSize: 14, color: Const.textGrey, height: 1),
style: TextStyle(fontSize: 14, color: ColorConsts.textGrey, height: 1),
),
SizedBox(height: 8),
Expanded(
@ -79,7 +79,7 @@ class _TangheemScreenState extends State<TangheemScreen> {
textAlign: TextAlign.center,
style: TextStyle(
fontFamily: "UthmanicHafs",
color: Const.primaryBlue,
color: ColorConsts.primaryBlue,
fontSize: 19,
fontWeight: FontWeight.bold,
),
@ -96,9 +96,9 @@ class _TangheemScreenState extends State<TangheemScreen> {
alignment: Alignment.centerRight,
child: Text(
"نوع جملة الاتمام",
style: TextStyle(fontWeight: FontWeight.bold, color: Const.secondaryOrange),
style: TextStyle(fontWeight: FontWeight.bold, color: ColorConsts.secondaryOrange),
),
color: Const.secondaryWhite,
color: ColorConsts.secondaryWhite,
),
),
),
@ -112,16 +112,16 @@ class _TangheemScreenState extends State<TangheemScreen> {
alignment: Alignment.centerRight,
child: Text(
"استثنائية",
style: TextStyle(color: Const.primaryBlack),
style: TextStyle(color: ColorConsts.primaryBlack),
),
color: Const.secondaryWhite,
color: ColorConsts.secondaryWhite,
),
),
)
],
),
Container(
color: Const.primaryBlue,
color: ColorConsts.primaryBlue,
margin: EdgeInsets.only(top: 8, bottom: 8),
padding: EdgeInsets.all(8),
child: Column(
@ -171,7 +171,7 @@ class _TangheemScreenState extends State<TangheemScreen> {
SizedBox(width: 4),
Text(
text,
style: TextStyle(color: Const.textGrey),
style: TextStyle(color: ColorConsts.textGrey),
),
],
),
@ -187,7 +187,7 @@ class _TangheemScreenState extends State<TangheemScreen> {
children: [
Text(
text,
style: TextStyle(color: Const.textGrey),
style: TextStyle(color: ColorConsts.textGrey),
),
SizedBox(width: 4),
SvgPicture.asset(icon, height: 12, width: 12),
@ -213,7 +213,7 @@ class _TangheemScreenState extends State<TangheemScreen> {
},
itemBuilder: (context, index) {
return Container(
color: Const.secondaryWhite,
color: ColorConsts.secondaryWhite,
padding: EdgeInsets.all(8),
child: Column(
mainAxisSize: MainAxisSize.min,
@ -222,12 +222,12 @@ class _TangheemScreenState extends State<TangheemScreen> {
children: [
Text(
temp[index].title,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12, color: Const.secondaryOrange),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 12, color: ColorConsts.secondaryOrange),
),
SizedBox(height: 4),
Text(
temp[index].description,
style: TextStyle(fontSize: 12, color: Const.secondaryPink),
style: TextStyle(fontSize: 12, color: ColorConsts.secondaryPink),
),
],
),

@ -2,7 +2,7 @@ import 'dart:math' as math;
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tangheem/classes/const.dart';
import 'package:tangheem/classes/colors.dart';
class AyaPlayerWidget extends StatefulWidget {
AyaPlayerWidget({Key key}) : super(key: key);
@ -71,12 +71,12 @@ class _AyaPlayerWidgetState extends State<AyaPlayerWidget> {
"سورة البقسورة",
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14, color: Const.primaryBlack, height: 1),
style: TextStyle(fontWeight: FontWeight.bold, fontSize: 14, color: ColorConsts.primaryBlack, height: 1),
),
SizedBox(height: 4),
Text(
"الشيخ عبد الشيخ عبد العزيز الزهراني",
style: TextStyle(fontSize: 10, color: Const.textGrey1, height: 1),
style: TextStyle(fontSize: 10, color: ColorConsts.textGrey1, height: 1),
),
],
),
@ -104,11 +104,11 @@ class _AyaPlayerWidgetState extends State<AyaPlayerWidget> {
Expanded(
child: SliderTheme(
data: SliderTheme.of(context).copyWith(
activeTrackColor: Const.sliderBackground,
inactiveTrackColor: Const.secondaryOrange,
activeTrackColor: ColorConsts.sliderBackground,
inactiveTrackColor: ColorConsts.secondaryOrange,
// trackShape: RoundedRectRangeSliderTrackShape(),
trackHeight: 8.0,
thumbColor: Const.primaryBlack,
thumbColor: ColorConsts.primaryBlack,
thumbShape: RoundSliderThumbShape(enabledThumbRadius: 10.0),
overlayColor: Colors.red.withAlpha(32),
overlayShape: RoundSliderOverlayShape(overlayRadius: 12.0),
@ -125,7 +125,7 @@ class _AyaPlayerWidgetState extends State<AyaPlayerWidget> {
),
Text(
"06:00",
style: TextStyle(color: Const.textGrey1, height: 1.1, fontFamily: "Roboto"),
style: TextStyle(color: ColorConsts.textGrey1, height: 1.1, fontFamily: "Roboto"),
),
],
)

@ -1,17 +1,21 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:tangheem/classes/const.dart';
import 'package:tangheem/classes/colors.dart';
class CommonDropDownButton extends StatelessWidget {
final int index;
final String text;
final String icon;
final Color iconColor;
final Color color;
final bool isExpanded;
final bool isDropDown;
final VoidCallback onPressed;
final Function(int) onSelect;
final double widthHeight;
final List<String> list;
CommonDropDownButton(this.text, {Key key, this.onPressed, this.isExpanded = true, this.color, this.icon, this.widthHeight, this.iconColor}) : super(key: key);
CommonDropDownButton(this.index, {Key key, this.onPressed, this.isDropDown = true, this.text = "", this.color, this.icon, this.widthHeight, this.iconColor, this.onSelect, this.list})
: super(key: key);
@override
Widget build(BuildContext context) {
@ -22,38 +26,48 @@ class CommonDropDownButton extends StatelessWidget {
child: Container(
height: 40,
decoration: BoxDecoration(
color: color ?? Const.primaryBlue,
color: color ?? ColorConsts.primaryBlue,
borderRadius: BorderRadius.circular(6),
),
padding: EdgeInsets.fromLTRB(8, 8, 8, 8),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
isExpanded
? Expanded(
child: Text(
text,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 12, color: Colors.white),
),
)
: Text(
text,
maxLines: 1,
// overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 12, color: Colors.white),
),
SizedBox(width: 4),
SvgPicture.asset(
child: DropdownButtonHideUnderline(
child: DropdownButton<int>(
isExpanded: isDropDown,
dropdownColor: ColorConsts.secondaryWhite,
icon: SvgPicture.asset(
icon ?? "assets/icons/drop_menu.svg",
width: widthHeight ?? 10,
height: widthHeight ?? 5,
color: iconColor ?? Const.secondaryOrange,
color: iconColor ?? ColorConsts.secondaryOrange,
),
],
hint: Text(
list.isNotEmpty ? list[index] : text,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 12, color: Colors.white),
),
focusColor: Colors.white,
style: TextStyle(color: Colors.white),
items: !isDropDown
? []
: [
for (int i = 0; i < list.length; i++)
DropdownMenuItem<int>(
value: i,
child: SizedBox(
width: double.infinity,
child: Text(
list[i],
maxLines: 1,
textDirection: TextDirection.rtl,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 14, color: ColorConsts.primaryBlack),
),
),
)
],
onChanged: onSelect,
),
),
),
);

@ -1,6 +1,7 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:tangheem/classes/const.dart';
import 'package:tangheem/classes/colors.dart';
class CommonTextFieldWidget extends StatelessWidget {
final String hint;
@ -21,21 +22,22 @@ class CommonTextFieldWidget extends StatelessWidget {
controller: controller,
obscureText: isPassword,
textInputAction: TextInputAction.next,
style: TextStyle(color: Const.primaryBlack, fontSize: 14),
cursorColor: Const.primaryBlue,
style: TextStyle(color: ColorConsts.primaryBlack, fontSize: 14),
cursorColor: ColorConsts.primaryBlue,
readOnly: onTap != null,
onTap: onTap,
decoration: InputDecoration(
contentPadding: EdgeInsets.fromLTRB(4, 4, 8, 4),
alignLabelWithHint: true,
fillColor: Colors.white,
filled: true,
hintStyle: TextStyle(color: Const.textGrey2, fontSize: 14),
hintStyle: TextStyle(color: ColorConsts.textGrey2, fontSize: 14),
hintText: hint,
suffixIcon: !showSuffix
? null
: Padding(
padding: EdgeInsets.only(left: 8, right: 0),
child: Icon(Icons.keyboard_arrow_down, size: 18, color: Const.secondaryOrange),
child: Icon(Icons.keyboard_arrow_down, size: 18, color: ColorConsts.secondaryOrange),
),
suffixIconConstraints: !showSuffix ? null : BoxConstraints(maxHeight: 30),
prefixIconConstraints: prefixIcon == null ? prefixIcon : BoxConstraints(maxHeight: 18),
@ -43,7 +45,7 @@ class CommonTextFieldWidget extends StatelessWidget {
? prefixIcon
: Padding(
padding: EdgeInsets.only(left: 4, right: 0),
child: SvgPicture.asset(prefixIcon, color: Const.textGrey2),
child: SvgPicture.asset(prefixIcon, color: ColorConsts.textGrey2),
),
border: OutlineInputBorder(borderRadius: BorderRadius.circular(6), borderSide: BorderSide.none),
),

@ -22,7 +22,6 @@ class ProvidedPinBoxTextAnimation {
}
class OTPWidget extends StatefulWidget {
final bool isCupertino;
final int maxLength;
final TextEditingController controller;
@ -40,7 +39,7 @@ class OTPWidget extends StatefulWidget {
final Color errorBorderColor;
final Color textBorderColor;
final Function(String) onTextChanged;
final bool autofocus;
final bool autoFocus;
final FocusNode focusNode;
final AnimatedSwitcherTransitionBuilder pinTextAnimatedSwitcherTransition;
final Duration pinTextAnimatedSwitcherDuration;
@ -50,7 +49,6 @@ class OTPWidget extends StatefulWidget {
const OTPWidget({
Key key,
this.isCupertino: false,
this.maxLength: 4,
this.controller,
this.pinBoxWidth: 70.0,
@ -64,7 +62,7 @@ class OTPWidget extends StatefulWidget {
this.hasError: false,
this.errorBorderColor: Colors.red,
this.onTextChanged,
this.autofocus: false,
this.autoFocus: false,
this.focusNode,
this.textDirection: TextDirection.ltr,
this.keyboardType: TextInputType.number,
@ -235,15 +233,15 @@ class OTPWidgetState extends State<OTPWidget> with SingleTickerProviderStateMixi
width: _width,
height: widget.pinBoxHeight,
child: TextField(
autofocus: !kIsWeb ? widget.autofocus : false,
autofocus: !kIsWeb ? widget.autoFocus : false,
enableInteractiveSelection: false,
focusNode: focusNode,
controller: widget.controller,
keyboardType: widget.keyboardType,
inputFormatters: widget.keyboardType == TextInputType.number ? <TextInputFormatter>[FilteringTextInputFormatter.digitsOnly] : null,
style: TextStyle(
height: 0.1, color: Colors.transparent,
// color: Colors.transparent,
height: 0.1,
color: Colors.transparent,
),
decoration: InputDecoration(
contentPadding: EdgeInsets.all(0),

@ -29,6 +29,7 @@ dependencies:
cupertino_icons: ^1.0.2
flutter_svg: ^0.19.3
fluttertoast: ^7.1.8
http: ^0.13.0
dev_dependencies:
flutter_test:

Loading…
Cancel
Save