diff --git a/assets/images/png/under_maintenance.png b/assets/images/png/under_maintenance.png new file mode 100644 index 0000000..17fbc91 Binary files /dev/null and b/assets/images/png/under_maintenance.png differ diff --git a/assets/images/svg/up_arrow.svg b/assets/images/svg/up_arrow.svg new file mode 100644 index 0000000..1b5a009 --- /dev/null +++ b/assets/images/svg/up_arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/lib/Utils/api_urls.dart b/lib/Utils/api_urls.dart index dcb3b5f..fed98d2 100644 --- a/lib/Utils/api_urls.dart +++ b/lib/Utils/api_urls.dart @@ -9,7 +9,7 @@ class ApiUrls { //send otp static String sendOtp = "${base}sendOTP"; - //verify otp + //verify otp ///9867890261 static String OTPVerify = "${base}OTPVerify"; //secure access @@ -85,4 +85,7 @@ class ApiUrls { //Stock Details static String stockDetailsApi = "${base}get-details-of-stock"; + +//Stock Details + static String subscriptionApi = "${base}my-subscription-page"; } diff --git a/lib/Utils/text.dart b/lib/Utils/text.dart index 8eea1fc..78d672b 100644 --- a/lib/Utils/text.dart +++ b/lib/Utils/text.dart @@ -186,12 +186,12 @@ Widget text15W600_00FF19(String text) { ); } -Widget text12W400(String text) { +Widget text12W400(String text, {Color? clr}) { return Text( text, style: TextStyle( fontSize: 12.sp, - color: Colors.white, + color: clr ?? Colors.white, fontWeight: FontWeight.w400, fontFamily: 'hiragino'), ); @@ -318,12 +318,12 @@ Widget text14W300(String text) { ); } -Widget text14W400(String text) { +Widget text14W400(String text, {Color? clr}) { return Text( text, style: TextStyle( fontSize: 14.sp, - color: Colors.white, + color: clr ?? Colors.white, fontWeight: FontWeight.w400, fontFamily: 'hiragino'), ); diff --git a/lib/Utils/utils.dart b/lib/Utils/utils.dart index 8e4fbdd..d157bd8 100644 --- a/lib/Utils/utils.dart +++ b/lib/Utils/utils.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:device_info_plus/device_info_plus.dart'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; import 'package:flutter/services.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:get/get.dart' as getx; @@ -53,9 +54,25 @@ class Utils { for (final element in data) { priceData.add(element.close!); } + return priceData; } + static List extractTimeFromGraph(List data) { + final List time = []; + for (final element in data) { + DateTime dateTime = DateTime.parse(element.timestamp!); + String formattedDate = DateFormat('MMM d yyyy').format(dateTime); + time.add(formattedDate); + } + return time; + } + + static String dateFormatterForGraph(String dateV) { + DateTime dateTime = DateTime.parse(dateV); + return DateFormat('MMM d yyyy').format(dateTime); + } + static showToast(String? msg) { if (msg != null && msg != "null" && msg.isNotEmpty) { Fluttertoast.showToast( diff --git a/lib/controller/products_controller.dart b/lib/controller/products_controller.dart index c2bd581..848fabf 100644 --- a/lib/controller/products_controller.dart +++ b/lib/controller/products_controller.dart @@ -6,6 +6,7 @@ import 'package:intl/intl.dart'; class ProductsController extends GetxController { RxBool isLoaded = true.obs; + RxBool isUpstoxTokenNotExpired = true.obs; CallRecommendationsModel swingTradeModel = CallRecommendationsModel(); CallRecommendationsModel multibaggerModel = CallRecommendationsModel(); CallRecommendationsModel optionModel = CallRecommendationsModel(); diff --git a/lib/model/HomeModel/home_model.dart b/lib/model/HomeModel/home_model.dart index edb6696..b0ebf7c 100644 --- a/lib/model/HomeModel/home_model.dart +++ b/lib/model/HomeModel/home_model.dart @@ -10,14 +10,14 @@ class HomeModel { status = json['status']; statusCode = json['status_code']; message = json['message']; - data = json['data'] != null ? new Data.fromJson(json['data']) : null; + data = json['data'] != null ? Data.fromJson(json['data']) : null; } Map toJson() { - final Map data = new Map(); - data['status'] = this.status; - data['status_code'] = this.statusCode; - data['message'] = this.message; + final Map data = {}; + data['status'] = status; + data['status_code'] = statusCode; + data['message'] = message; if (this.data != null) { data['data'] = this.data!.toJson(); } @@ -28,65 +28,203 @@ class HomeModel { class Data { List? exploreTheUnseenActiveCalls; List? exploreTheUnseenExitedCalls; + IndexLiveData? indexLiveData; UserData? userData; List? products; ContentByteVideo? contentByteVideo; + bool? isUpstoxTokenRefreshed; Data( {this.exploreTheUnseenActiveCalls, this.exploreTheUnseenExitedCalls, this.userData, this.products, - this.contentByteVideo}); + this.contentByteVideo, + this.isUpstoxTokenRefreshed, + this.indexLiveData}); Data.fromJson(Map json) { if (json['explore_the_unseen_active_calls'] != null) { exploreTheUnseenActiveCalls = []; json['explore_the_unseen_active_calls'].forEach((v) { exploreTheUnseenActiveCalls! - .add(new ExploreTheUnseenActiveCalls.fromJson(v)); + .add(ExploreTheUnseenActiveCalls.fromJson(v)); }); } if (json['explore_the_unseen_exited_calls'] != null) { exploreTheUnseenExitedCalls = []; json['explore_the_unseen_exited_calls'].forEach((v) { exploreTheUnseenExitedCalls! - .add(new ExploreTheUnseenExitedCalls.fromJson(v)); + .add(ExploreTheUnseenExitedCalls.fromJson(v)); }); } - userData = json['user_data'] != null - ? new UserData.fromJson(json['user_data']) + indexLiveData = json['index_live_data'] != null + ? IndexLiveData.fromJson(json['index_live_data']) : null; + userData = + json['user_data'] != null ? UserData.fromJson(json['user_data']) : null; if (json['products'] != null) { products = []; json['products'].forEach((v) { - products!.add(new Products.fromJson(v)); + products!.add(Products.fromJson(v)); }); } contentByteVideo = json['content_byte_video'] != null - ? new ContentByteVideo.fromJson(json['content_byte_video']) + ? ContentByteVideo.fromJson(json['content_byte_video']) + : null; + isUpstoxTokenRefreshed = json['isUpstoxTokenRefreshed']; + } + + Map toJson() { + final Map data = {}; + if (exploreTheUnseenActiveCalls != null) { + data['explore_the_unseen_active_calls'] = + exploreTheUnseenActiveCalls!.map((v) => v.toJson()).toList(); + } + if (exploreTheUnseenExitedCalls != null) { + data['explore_the_unseen_exited_calls'] = + exploreTheUnseenExitedCalls!.map((v) => v.toJson()).toList(); + } + if (indexLiveData != null) { + data['index_live_data'] = indexLiveData!.toJson(); + } + if (userData != null) { + data['user_data'] = userData!.toJson(); + } + if (products != null) { + data['products'] = products!.map((v) => v.toJson()).toList(); + } + if (contentByteVideo != null) { + data['content_byte_video'] = contentByteVideo!.toJson(); + } + data['isUpstoxTokenRefreshed'] = isUpstoxTokenRefreshed; + return data; + } +} + +class IndexLiveData { + String? status; + Data1? data; + + IndexLiveData({this.status, this.data}); + + IndexLiveData.fromJson(Map json) { + status = json['status']; + data = json['data'] != null ? Data1.fromJson(json['data']) : null; + } + + Map toJson() { + final Map data = {}; + data['status'] = status; + if (this.data != null) { + data['data'] = this.data!.toJson(); + } + return data; + } +} + +class Data1 { + NSEINDEXNiftyBank? nSEINDEXNiftyBank; + NSEINDEXNiftyBank? nSEINDEXNifty50; + + Data1({this.nSEINDEXNiftyBank, this.nSEINDEXNifty50}); + + Data1.fromJson(Map json) { + nSEINDEXNiftyBank = json['NSE_INDEX:Nifty Bank'] != null + ? NSEINDEXNiftyBank.fromJson(json['NSE_INDEX:Nifty Bank']) + : null; + nSEINDEXNifty50 = json['NSE_INDEX:Nifty 50'] != null + ? NSEINDEXNiftyBank.fromJson(json['NSE_INDEX:Nifty 50']) : null; } Map toJson() { - final Map data = new Map(); - if (this.exploreTheUnseenActiveCalls != null) { - data['explore_the_unseen_active_calls'] = - this.exploreTheUnseenActiveCalls!.map((v) => v.toJson()).toList(); + final Map data = {}; + if (nSEINDEXNiftyBank != null) { + data['NSE_INDEX:Nifty Bank'] = nSEINDEXNiftyBank!.toJson(); } - if (this.exploreTheUnseenExitedCalls != null) { - data['explore_the_unseen_exited_calls'] = - this.exploreTheUnseenExitedCalls!.map((v) => v.toJson()).toList(); + if (nSEINDEXNifty50 != null) { + data['NSE_INDEX:Nifty 50'] = nSEINDEXNifty50!.toJson(); } - if (this.userData != null) { - data['user_data'] = this.userData!.toJson(); - } - if (this.products != null) { - data['products'] = this.products!.map((v) => v.toJson()).toList(); - } - if (this.contentByteVideo != null) { - data['content_byte_video'] = this.contentByteVideo!.toJson(); + return data; + } +} + +class NSEINDEXNiftyBank { + Ohlc? ohlc; + + String? timestamp; + String? instrumentToken; + String? symbol; + double? lastPrice; + + double? netChange; + + String? lastTradeTime; + + NSEINDEXNiftyBank({ + this.ohlc, + this.timestamp, + this.instrumentToken, + this.symbol, + this.lastPrice, + this.netChange, + this.lastTradeTime, + }); + + NSEINDEXNiftyBank.fromJson(Map json) { + ohlc = json['ohlc'] != null ? Ohlc.fromJson(json['ohlc']) : null; + + timestamp = json['timestamp']; + instrumentToken = json['instrument_token']; + symbol = json['symbol']; + lastPrice = json['last_price']; + + netChange = json['net_change']; + + lastTradeTime = json['last_trade_time']; + } + + Map toJson() { + final Map data = {}; + if (ohlc != null) { + data['ohlc'] = ohlc!.toJson(); } + + data['timestamp'] = timestamp; + data['instrument_token'] = instrumentToken; + data['symbol'] = symbol; + data['last_price'] = lastPrice; + + data['net_change'] = netChange; + + data['last_trade_time'] = lastTradeTime; + + return data; + } +} + +class Ohlc { + double? open; + double? high; + double? low; + double? close; + + Ohlc({this.open, this.high, this.low, this.close}); + + Ohlc.fromJson(Map json) { + open = json['open'].toDouble(); + high = json['high'].toDouble(); + low = json['low'].toDouble(); + close = json['close'].toDouble(); + } + + Map toJson() { + final Map data = {}; + data['open'] = open; + data['high'] = high; + data['low'] = low; + data['close'] = close; return data; } } @@ -146,35 +284,35 @@ class ExploreTheUnseenActiveCalls { scheduleDateTime = json['schedule_date_time']; createdAt = json['created_at']; productData = json['product_data'] != null - ? new ProductData.fromJson(json['product_data']) + ? ProductData.fromJson(json['product_data']) : null; actionData = json['action_data'] != null - ? new ActionData.fromJson(json['action_data']) + ? ActionData.fromJson(json['action_data']) : null; } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['manage_product_xid'] = this.manageProductXid; - data['recommendation_actions_xid'] = this.recommendationActionsXid; - data['stock_name'] = this.stockName; - data['instrument_key'] = this.instrumentKey; - data['stock_image'] = this.stockImage; - data['qty'] = this.qty; - data['duration'] = this.duration; - data['current_price'] = this.currentPrice; - data['buy_price'] = this.buyPrice; - data['target_price'] = this.targetPrice; - data['stop_loss'] = this.stopLoss; - data['is_send_recommendation_now'] = this.isSendRecommendationNow; - data['schedule_date_time'] = this.scheduleDateTime; - data['created_at'] = this.createdAt; - if (this.productData != null) { - data['product_data'] = this.productData!.toJson(); + final Map data = {}; + data['id'] = id; + data['manage_product_xid'] = manageProductXid; + data['recommendation_actions_xid'] = recommendationActionsXid; + data['stock_name'] = stockName; + data['instrument_key'] = instrumentKey; + data['stock_image'] = stockImage; + data['qty'] = qty; + data['duration'] = duration; + data['current_price'] = currentPrice; + data['buy_price'] = buyPrice; + data['target_price'] = targetPrice; + data['stop_loss'] = stopLoss; + data['is_send_recommendation_now'] = isSendRecommendationNow; + data['schedule_date_time'] = scheduleDateTime; + data['created_at'] = createdAt; + if (productData != null) { + data['product_data'] = productData!.toJson(); } - if (this.actionData != null) { - data['action_data'] = this.actionData!.toJson(); + if (actionData != null) { + data['action_data'] = actionData!.toJson(); } return data; } @@ -235,35 +373,35 @@ class ExploreTheUnseenExitedCalls { scheduleDateTime = json['schedule_date_time']; createdAt = json['created_at']; productData = json['product_data'] != null - ? new ProductData.fromJson(json['product_data']) + ? ProductData.fromJson(json['product_data']) : null; actionData = json['action_data'] != null - ? new ActionData.fromJson(json['action_data']) + ? ActionData.fromJson(json['action_data']) : null; } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['manage_product_xid'] = this.manageProductXid; - data['recommendation_actions_xid'] = this.recommendationActionsXid; - data['stock_name'] = this.stockName; - data['instrument_key'] = this.instrumentKey; - data['stock_image'] = this.stockImage; - data['qty'] = this.qty; - data['duration'] = this.duration; - data['current_price'] = this.currentPrice; - data['buy_price'] = this.buyPrice; - data['target_price'] = this.targetPrice; - data['stop_loss'] = this.stopLoss; - data['is_send_recommendation_now'] = this.isSendRecommendationNow; - data['schedule_date_time'] = this.scheduleDateTime; - data['created_at'] = this.createdAt; - if (this.productData != null) { - data['product_data'] = this.productData!.toJson(); + final Map data = {}; + data['id'] = id; + data['manage_product_xid'] = manageProductXid; + data['recommendation_actions_xid'] = recommendationActionsXid; + data['stock_name'] = stockName; + data['instrument_key'] = instrumentKey; + data['stock_image'] = stockImage; + data['qty'] = qty; + data['duration'] = duration; + data['current_price'] = currentPrice; + data['buy_price'] = buyPrice; + data['target_price'] = targetPrice; + data['stop_loss'] = stopLoss; + data['is_send_recommendation_now'] = isSendRecommendationNow; + data['schedule_date_time'] = scheduleDateTime; + data['created_at'] = createdAt; + if (productData != null) { + data['product_data'] = productData!.toJson(); } - if (this.actionData != null) { - data['action_data'] = this.actionData!.toJson(); + if (actionData != null) { + data['action_data'] = actionData!.toJson(); } return data; } @@ -285,11 +423,11 @@ class ProductData { } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['product_name'] = this.productName; - data['is_active'] = this.isActive; - data['created_at'] = this.createdAt; + final Map data = {}; + data['id'] = id; + data['product_name'] = productName; + data['is_active'] = isActive; + data['created_at'] = createdAt; return data; } } @@ -310,11 +448,11 @@ class ActionData { } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['name'] = this.name; - data['is_active'] = this.isActive; - data['created_at'] = this.createdAt; + final Map data = {}; + data['id'] = id; + data['name'] = name; + data['is_active'] = isActive; + data['created_at'] = createdAt; return data; } } @@ -348,14 +486,14 @@ class UserData { } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['first_name'] = this.firstName; - data['last_name'] = this.lastName; - data['user_name'] = this.userName; - data['profile_photo'] = this.profilePhoto; - data['is_active'] = this.isActive; - data['created_at'] = this.createdAt; + final Map data = {}; + data['id'] = id; + data['first_name'] = firstName; + data['last_name'] = lastName; + data['user_name'] = userName; + data['profile_photo'] = profilePhoto; + data['is_active'] = isActive; + data['created_at'] = createdAt; return data; } } @@ -374,10 +512,10 @@ class Products { } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['title'] = this.title; - data['created_at'] = this.createdAt; + final Map data = {}; + data['id'] = id; + data['title'] = title; + data['created_at'] = createdAt; return data; } } @@ -423,18 +561,18 @@ class ContentByteVideo { } Map toJson() { - final Map data = new Map(); - data['id'] = this.id; - data['content_type'] = this.contentType; - data['title'] = this.title; - data['description'] = this.description; - data['tags'] = this.tags; - data['file'] = this.file; - data['category_id'] = this.categoryId; - data['image'] = this.image; - data['is_active'] = this.isActive; - data['created_at'] = this.createdAt; - data['link'] = this.link; + final Map data = {}; + data['id'] = id; + data['content_type'] = contentType; + data['title'] = title; + data['description'] = description; + data['tags'] = tags; + data['file'] = file; + data['category_id'] = categoryId; + data['image'] = image; + data['is_active'] = isActive; + data['created_at'] = createdAt; + data['link'] = link; return data; } } diff --git a/lib/model/StockDetailsModel/stock_details_model.dart b/lib/model/StockDetailsModel/stock_details_model.dart index b5d2368..300fee9 100644 --- a/lib/model/StockDetailsModel/stock_details_model.dart +++ b/lib/model/StockDetailsModel/stock_details_model.dart @@ -149,7 +149,7 @@ class Ohlc { Ohlc.fromJson(Map json) { open = json['open'].toDouble(); high = json['high'].toDouble(); - low = json['low']; + low = json['low'].toDouble(); close = json['close'].toDouble(); } diff --git a/lib/view/MainScreen/HomeScreen.dart b/lib/view/MainScreen/HomeScreen.dart index 0610246..2254d1f 100644 --- a/lib/view/MainScreen/HomeScreen.dart +++ b/lib/view/MainScreen/HomeScreen.dart @@ -4,14 +4,11 @@ import 'dart:developer'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_svg/svg.dart'; import 'package:gap/gap.dart'; import 'package:get/get.dart'; -import 'package:glassmorphism/glassmorphism.dart'; import 'package:traderscircuit/Utils/Common/CommonBottomNavigation.dart'; -import 'package:traderscircuit/Utils/Common/CommonTabBar.dart'; import 'package:traderscircuit/Utils/Common/comonGlassmorphicContainer.dart'; import 'package:traderscircuit/Utils/Common/sized_box.dart'; import 'package:traderscircuit/Utils/text.dart'; @@ -58,11 +55,21 @@ class _HomeScreenState extends State { }); HomeApi().getHomeData().then((value) { homeModel = HomeModel.fromJson(value.data); + productsController.isUpstoxTokenNotExpired.value = + homeModel.data!.isUpstoxTokenRefreshed!; isApiCalling.value = false; }); super.initState(); } + String calculatePercentageChange(double openPrice, double currentPrice) { + final percentageChange = ((currentPrice - openPrice) / openPrice) * 100; + + log(percentageChange.toStringAsFixed(2)); + + return percentageChange.toStringAsFixed(2); + } + @override Widget build(BuildContext context) { return WillPopScope( @@ -145,31 +152,83 @@ class _HomeScreenState extends State { fontFamily: 'hiragino', fontWeight: FontWeight.w500), ), - sizedBoxHeight(25.h), - SingleChildScrollView( - scrollDirection: Axis.horizontal, - child: Row( - children: [ - commoncontainer( - width: 195.w, - text: 'NIFTY', - amount: '22,286.95', - rate: '+304.15 (+1.38%)'), - sizedBoxWidth(10.w), - commoncontainer( - width: 240.w, - text: 'BANKNIFTY', - amount: '22,286.95', - rate: '+896.10 (+1.94%)'), - ], - ), - ), - sizedBoxHeight(30.h), - Container( - width: double.infinity, - height: 1.h, - color: const Color(0xFF3A3A3A), - ), + !homeModel.data!.isUpstoxTokenRefreshed! + ? const SizedBox() + : sizedBoxHeight(25.h), + !homeModel.data!.isUpstoxTokenRefreshed! + ? const SizedBox() + : SingleChildScrollView( + scrollDirection: Axis.horizontal, + child: Row( + children: [ + commoncontainer( + width: 250.w, + text: homeModel + .data! + .indexLiveData! + .data! + .nSEINDEXNifty50! + .instrumentToken! + .split("NSE_INDEX|")[1], + amount: homeModel.data!.indexLiveData! + .data!.nSEINDEXNifty50!.lastPrice! + .toString(), + rate: homeModel.data!.indexLiveData! + .data!.nSEINDEXNifty50!.netChange + .toString(), + percentageChange: + calculatePercentageChange( + homeModel.data!.indexLiveData!.data! + .nSEINDEXNifty50!.ohlc!.open!, + homeModel.data!.indexLiveData!.data! + .nSEINDEXNifty50!.lastPrice!, + ), + ), + sizedBoxWidth(10.w), + commoncontainer( + width: 250.w, + text: homeModel + .data! + .indexLiveData! + .data! + .nSEINDEXNiftyBank! + .instrumentToken! + .split("NSE_INDEX|")[1], + amount: homeModel + .data! + .indexLiveData! + .data! + .nSEINDEXNiftyBank! + .lastPrice! + .toString(), + rate: homeModel + .data! + .indexLiveData! + .data! + .nSEINDEXNiftyBank! + .netChange + .toString(), + percentageChange: + calculatePercentageChange( + homeModel.data!.indexLiveData!.data! + .nSEINDEXNiftyBank!.ohlc!.open!, + homeModel.data!.indexLiveData!.data! + .nSEINDEXNiftyBank!.lastPrice!, + ), + ), + ], + ), + ), + !homeModel.data!.isUpstoxTokenRefreshed! + ? const SizedBox() + : sizedBoxHeight(30.h), + !homeModel.data!.isUpstoxTokenRefreshed! + ? const SizedBox() + : Container( + width: double.infinity, + height: 1.h, + color: const Color(0xFF3A3A3A), + ), sizedBoxHeight(30.h), text22W500('View our products'), sizedBoxHeight(30.h), @@ -332,7 +391,7 @@ class _HomeScreenState extends State { width: 105, height: 35, decoration: ShapeDecoration( - color: Color(0xFF0093FF), + color: const Color(0xFF0093FF), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5)), @@ -625,7 +684,7 @@ Widget cardcallWidget( GestureDetector( onTap: () { log("RUNNING"); - Get.to(ExploreUnseen()); + Get.to(const ExploreUnseen()); }, child: Container( height: 52, @@ -696,11 +755,13 @@ Widget ProductWidget({ ); } -Widget commoncontainer( - {required String text, - required String amount, - required String rate, - required double width}) { +Widget commoncontainer({ + required String text, + required String amount, + required String rate, + required double width, + required String percentageChange, +}) { return Container( height: 83, decoration: ShapeDecoration( @@ -721,15 +782,32 @@ Widget commoncontainer( sizedBoxWidth(8.w), text16W600(amount), sizedBoxWidth(8.w), - SvgPicture.asset( - 'assets/images/svg/Line 587.svg', - height: 15.h, - width: 15.w, - ), + rate.contains("-") + ? SvgPicture.asset( + 'assets/images/svg/Line 587.svg', + height: 15.h, + width: 15.w, + ) + : rate == "0.0" + ? const SizedBox() + : SvgPicture.asset( + 'assets/images/svg/up_arrow.svg', + height: 15.h, + width: 15.w, + ), ], ), sizedBoxHeight(8.w), - text14W400_00FF19(rate) + text14W400( + rate.contains("-") + ? "$rate ($percentageChange%)" + : "+$rate ($percentageChange%)", + clr: rate.contains("-") + ? const Color(0xFFFF0000) + : rate == "0.0" + ? Colors.grey + : const Color(0xFF00FF19), + ), ], ), ), diff --git a/lib/view/MainScreen/stockDetails/stock_details_screen.dart b/lib/view/MainScreen/stockDetails/stock_details_screen.dart index 0cc1034..28ebf27 100644 --- a/lib/view/MainScreen/stockDetails/stock_details_screen.dart +++ b/lib/view/MainScreen/stockDetails/stock_details_screen.dart @@ -8,11 +8,11 @@ import 'package:gap/gap.dart'; import 'package:get/get.dart' hide FormData; import 'package:traderscircuit/Utils/text.dart'; import 'package:traderscircuit/Utils/utils.dart'; +import 'package:traderscircuit/controller/products_controller.dart'; import 'package:traderscircuit/model/StockDetailsModel/stock_details_model.dart'; import 'package:traderscircuit/resources/routes/route_name.dart'; import 'package:traderscircuit/view_model/StockDetailsApi/stock_details_api.dart'; -import 'dart:math'; import '../../../Utils/Common/CommonAppBar.dart'; import '../../onBoarding/splashScreen1.dart'; @@ -26,66 +26,89 @@ class StockDetailsScreen extends StatefulWidget { class _StockDetailsScreenState extends State { RxBool isLoading = true.obs; StockDetailsModel? stockDetailsModel; + String instrumentName = Get.arguments["instrument_name"]; + String percentageDifference = ""; + String netChange = ""; + + ProductsController productsController = Get.put(ProductsController()); + @override void initState() { - String instrumentName = Get.arguments["instrument_name"]; dv.log(instrumentName); - StockDetailsApi() - .getStockDetails( - FormData.fromMap({"upstox_instrument_key": instrumentName})) - .then((value) { - final Map data = value.data; + if (productsController.isUpstoxTokenNotExpired.value) { + StockDetailsApi() + .getStockDetails( + FormData.fromMap({"upstox_instrument_key": instrumentName})) + .then((value) { + final Map data = value.data; - Map data1 = data["data"]['stock_data']['data']; - String dynamicKey = data1.keys.first; - // Access nested data using dynamic key - Map dynamicData = data1[dynamicKey]; + Map data1 = data["data"]['stock_data']['data']; + String dynamicKey = data1.keys.first; + // Access nested data using dynamic key + Map dynamicData = data1[dynamicKey]; - List? candles = []; + List? candles = []; - for (var a in data["data"]['candle_stick']["data"]["candles"]) { - candles.add(Candles( - timestamp: a[0], - open: a[1].toDouble(), - high: a[2].toDouble(), - low: a[3].toDouble(), - close: a[4].toDouble(), - volume: a[5].toInt(), - openInterest: a[6], - )); - } + for (var a in data["data"]['candle_stick']["data"]["candles"]) { + candles.add(Candles( + timestamp: a[0], + open: a[1].toDouble(), + high: a[2].toDouble(), + low: a[3].toDouble(), + close: a[4].toDouble(), + volume: a[5].toInt(), + openInterest: a[6], + )); + } + candles = candles.reversed.toList(); + stockDetailsModel = StockDetailsModel( + status: data["status"], + message: data["message"], + statusCode: data["status_code"], + data: Data( + stockData: StockInfo( + ohlc: Ohlc.fromJson(dynamicData['ohlc']), + averagePrice: dynamicData['average_price'].toDouble(), + instrumentToken: dynamicData['instrument_token'], + lastPrice: dynamicData['last_price'].toDouble(), + lastTradeTime: dynamicData['last_trade_time'], + lowerCircuitLimit: + dynamicData['lower_circuit_limit'].toDouble(), + netChange: dynamicData['net_change'].toDouble(), + oi: dynamicData['oi'], + oiDayHigh: dynamicData['oi_day_high'], + oiDayLow: dynamicData['oi_day_low'], + symbol: dynamicData['symbol'], + timestamp: dynamicData['timestamp'], + totalBuyQuantity: dynamicData['total_buy_quantity'], + totalSellQuantity: dynamicData['total_sell_quantity'], + upperCircuitLimit: dynamicData['upper_circuit_limit'], + volume: dynamicData['volume'], + ), + candleStick: CandleStick(candles: candles), + optionChain: + OptionChain.fromJson(data["data"]['option_chain']))); - stockDetailsModel = StockDetailsModel( - status: data["status"], - message: data["message"], - statusCode: data["status_code"], - data: Data( - stockData: StockInfo( - ohlc: Ohlc.fromJson(dynamicData['ohlc']), - averagePrice: dynamicData['average_price'], - instrumentToken: dynamicData['instrument_token'], - lastPrice: dynamicData['last_price'].toDouble(), - lastTradeTime: dynamicData['last_trade_time'], - lowerCircuitLimit: dynamicData['lower_circuit_limit'], - netChange: dynamicData['net_change'], - oi: dynamicData['oi'], - oiDayHigh: dynamicData['oi_day_high'], - oiDayLow: dynamicData['oi_day_low'], - symbol: dynamicData['symbol'], - timestamp: dynamicData['timestamp'], - totalBuyQuantity: dynamicData['total_buy_quantity'], - totalSellQuantity: dynamicData['total_sell_quantity'], - upperCircuitLimit: dynamicData['upper_circuit_limit'], - volume: dynamicData['volume'], - ), - candleStick: CandleStick(candles: candles), - optionChain: OptionChain.fromJson(data["data"]['option_chain']))); + netChange = dynamicData['net_change'].toString(); + _calculatePercentageChange( + stockDetailsModel!.data!.stockData!.ohlc!.open!, + stockDetailsModel!.data!.stockData!.lastPrice!); + isLoading.value = false; + }); + } else { isLoading.value = false; - }); + } + super.initState(); } + void _calculatePercentageChange(double openPrice, double currentPrice) { + final percentageChange = ((currentPrice - openPrice) / openPrice) * 100; + + percentageDifference = percentageChange.toStringAsFixed(2); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -95,297 +118,468 @@ class _StockDetailsScreenState extends State { appBar: const CommonAppbar( titleTxt: "", ), - body: Obx(() => Stack(children: [ - const CommonBlurLeft(), - const CommonBlurRight(), - isLoading.value - ? const Center( - child: CircularProgressIndicator( - color: Color(0xFF0093FF), - ), - ) - : Padding( - padding: const EdgeInsets.all(15.0), - child: SingleChildScrollView( - child: Column( + body: Obx(() => !productsController.isUpstoxTokenNotExpired.value + ? Stack(children: [ + const CommonBlurLeft(), + const CommonBlurRight(), + Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + children: [ + Image.asset( + "assets/images/png/under_maintenance.png", + width: 200, + height: 220, + ), + Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - text16W700( - stockDetailsModel!.data!.stockData!.symbol!), - const Gap(14), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + text22W600("Oops!"), + const Gap(5), + text16W400("Under Maintenance", clr: Colors.grey) + ], + ) + ], + ), + const Gap(150), + ], + ) + ]) + : RefreshIndicator( + color: const Color(0xFF0093FF), + onRefresh: () async { + Future.delayed(const Duration(seconds: 1), () { + isLoading.value = true; + StockDetailsApi() + .getStockDetails(FormData.fromMap( + {"upstox_instrument_key": instrumentName})) + .then((value) { + final Map data = value.data; + + Map data1 = + data["data"]['stock_data']['data']; + String dynamicKey = data1.keys.first; + // Access nested data using dynamic key + Map dynamicData = data1[dynamicKey]; + + List? candles = []; + + for (var a in data["data"]['candle_stick']["data"] + ["candles"]) { + candles.add(Candles( + timestamp: a[0], + open: a[1].toDouble(), + high: a[2].toDouble(), + low: a[3].toDouble(), + close: a[4].toDouble(), + volume: a[5].toInt(), + openInterest: a[6], + )); + } + + candles = candles.reversed.toList(); + stockDetailsModel = StockDetailsModel( + status: data["status"], + message: data["message"], + statusCode: data["status_code"], + data: Data( + stockData: StockInfo( + ohlc: Ohlc.fromJson(dynamicData['ohlc']), + averagePrice: + dynamicData['average_price'].toDouble(), + instrumentToken: dynamicData['instrument_token'], + lastPrice: dynamicData['last_price'].toDouble(), + lastTradeTime: dynamicData['last_trade_time'], + lowerCircuitLimit: + dynamicData['lower_circuit_limit'].toDouble(), + netChange: dynamicData['net_change'].toDouble(), + oi: dynamicData['oi'], + oiDayHigh: dynamicData['oi_day_high'], + oiDayLow: dynamicData['oi_day_low'], + symbol: dynamicData['symbol'], + timestamp: dynamicData['timestamp'], + totalBuyQuantity: + dynamicData['total_buy_quantity'], + totalSellQuantity: + dynamicData['total_sell_quantity'], + upperCircuitLimit: + dynamicData['upper_circuit_limit'], + volume: dynamicData['volume'], + ), + candleStick: CandleStick(candles: candles), + optionChain: OptionChain.fromJson( + data["data"]['option_chain']))); + + netChange = dynamicData['net_change'].toString(); + _calculatePercentageChange( + stockDetailsModel!.data!.stockData!.ohlc!.open!, + stockDetailsModel!.data!.stockData!.lastPrice!); + isLoading.value = false; + }); + }); + }, + child: Stack(children: [ + const CommonBlurLeft(), + const CommonBlurRight(), + isLoading.value + ? const Center( + child: CircularProgressIndicator( + color: Color(0xFF0093FF), + ), + ) + : Padding( + padding: const EdgeInsets.all(15.0), + child: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - text25W600( - "₹${stockDetailsModel!.data!.stockData!.averagePrice!.toString()}"), - InkWell( - onTap: () { - Get.toNamed(RouteName.optionChain); - }, - child: Container( - width: 145, - height: 40, - decoration: ShapeDecoration( - color: const Color(0xFF0093FF), - shape: RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(5)), - ), - child: Row( - mainAxisAlignment: - MainAxisAlignment.center, - crossAxisAlignment: - CrossAxisAlignment.center, - children: [ - SvgPicture.asset( - "assets/images/svg/option_chain_icon.svg"), - const Gap(5), - text12W600("Option Chain"), - ], - )), + + text16W700( + stockDetailsModel!.data!.stockData!.symbol!), + const Gap(14), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, + children: [ + text25W600( + "₹${stockDetailsModel!.data!.stockData!.lastPrice!.toString()}"), + Container( + width: 145, + height: 40, + decoration: ShapeDecoration( + color: const Color(0xFF0093FF), + shape: RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(5)), + ), + child: Row( + mainAxisAlignment: + MainAxisAlignment.center, + crossAxisAlignment: + CrossAxisAlignment.center, + children: [ + SvgPicture.asset( + "assets/images/svg/option_chain_icon.svg"), + const Gap(5), + text12W600("Option Chain"), + ], + )), + ], ), - ], - ), - const Gap(8), - text12W400( - "${stockDetailsModel!.data!.stockData!.netChange} 1D"), - const Gap(55), - Container( - margin: const EdgeInsets.symmetric(horizontal: 15), - width: Get.width, - height: 220, - color: Colors.transparent, - child: LineChart( - LineChartData( - lineTouchData: LineTouchData( - touchTooltipData: LineTouchTooltipData( - fitInsideHorizontally: true, - fitInsideVertically: true, - tooltipRoundedRadius: 24, - getTooltipItems: ( - List touchedBarSpots, - ) { - return touchedBarSpots.map((barSpot) { - return LineTooltipItem( - "₹ ${Utils.removeDecimal( - Utils.extractPriceFromGraph( - stockDetailsModel! - .data! - .candleStick! - .candles!)[ - barSpot.x.toInt()] - .toStringAsFixed(2), - ).replaceAllMapped( - RegExp( - r'(\d{1,3})(?=(\d{3})+(?!\d))', - ), - (Match m) => '${m[1]},', - )}", - const TextStyle( - fontSize: 16, - fontWeight: FontWeight.w700, - ), - ); - }).toList(); - }, - ), - ), - gridData: FlGridData( - show: true, - drawVerticalLine: false, - drawHorizontalLine: false, - horizontalInterval: 4, - getDrawingHorizontalLine: (value) { - return const FlLine( - color: Color( - 0xff37434d, + const Gap(8), + Row( + children: [ + text12W400( + netChange.contains("-") + ? "${stockDetailsModel!.data!.stockData!.netChange} ($percentageDifference%)" + : "+${stockDetailsModel!.data!.stockData!.netChange} ($percentageDifference%)", + clr: netChange.contains("-") + ? Colors.redAccent + : netChange == "0.0" + ? Colors.grey + : Colors.greenAccent), + text12W400(" Today"), + ], + ), + const Gap(55), + // Container( + // // margin: const EdgeInsets.symmetric(horizontal: 8), + // width: Get.width, + // height: 220, + // color: Colors.transparent, + // child: SfCartesianChart( + // // palette: [ + // // const Color( + // // 0xFF0093FF, + // // ).withOpacity(.01), + // // const Color( + // // 0xFF0093FF, + // // ).withOpacity(.3), + // // ], + + // tooltipBehavior: _tooltipBehavior, + // plotAreaBorderWidth: 0, + // primaryYAxis: NumericAxis(isVisible: false), + // // Initialize category axis + // primaryXAxis: CategoryAxis(isVisible: false), + // series: >[ + // LineSeries( + // // Bind data source + // dataSource: salesDataV, + // color: Color(0xFF0093FF), + // enableTooltip: true, + // xValueMapper: (SalesData sales, _) => + // sales.year, + // yValueMapper: (SalesData sales, _) => + // sales.sales) + // ]), + // ), + + Container( + margin: + const EdgeInsets.symmetric(horizontal: 15), + width: Get.width, + height: 220, + color: Colors.transparent, + child: LineChart( + LineChartData( + lineTouchData: LineTouchData( + touchTooltipData: LineTouchTooltipData( + fitInsideHorizontally: true, + fitInsideVertically: true, + + tooltipRoundedRadius: + 9, // maxContentWidth: 150, + getTooltipItems: ( + List touchedBarSpots, + ) { + return touchedBarSpots.map((barSpot) { + return LineTooltipItem( + "₹ ${Utils.removeDecimal( + Utils.extractPriceFromGraph( + stockDetailsModel! + .data! + .candleStick! + .candles!)[ + barSpot.x.toInt()] + .toStringAsFixed(2), + )}", + const TextStyle( + fontSize: 16, + fontWeight: FontWeight.w700, + ), + // children: [ + // const TextSpan(text: "\n"), + // TextSpan( + // text: Utils + // .extractTimeFromGraph( + // stockDetailsModel! + // .data! + // .candleStick! + ); + }).toList(); + }, ), - strokeWidth: 1, - ); - }, - getDrawingVerticalLine: (value) { - return const FlLine( - color: Color( - 0xff0093FF, - ), - strokeWidth: 1, - ); - }, - ), - titlesData: const FlTitlesData( - show: false, - ), - borderData: FlBorderData( - show: false, - ), - minX: 0, - maxX: (stockDetailsModel! - .data!.candleStick!.candles!.length - .toDouble()) - - 1, - minY: Utils.extractPriceFromGraph( - stockDetailsModel! - .data!.candleStick!.candles!) - .reduce(min) - .toDouble(), - maxY: Utils.extractPriceFromGraph( - stockDetailsModel! - .data!.candleStick!.candles!) - .reduce(max) - .toDouble(), - lineBarsData: [ - LineChartBarData( - color: const Color(0xFF0093FF), - spots: listData( - Utils.extractPriceFromGraph( - stockDetailsModel! - .data!.candleStick!.candles!), ), - barWidth: 3, - isStrokeCapRound: true, - dotData: const FlDotData( + gridData: FlGridData( + show: true, + drawVerticalLine: false, + drawHorizontalLine: false, + horizontalInterval: 4, + getDrawingHorizontalLine: (value) { + return const FlLine( + color: Color( + 0xff37434d, + + ), + strokeWidth: 1, + ); + }, + getDrawingVerticalLine: (value) { + return const FlLine( + color: Color( + 0xff0093FF, + ), + strokeWidth: 1, + ); + }, + ), + titlesData: const FlTitlesData( show: false, ), - belowBarData: BarAreaData( - show: true, - gradient: LinearGradient( - colors: [ - const Color( - 0xFF0093FF, - ).withOpacity(.01), - const Color( - 0xFF0093FF, - ).withOpacity(.3), - ], - )), + borderData: FlBorderData( + show: false, + ), + // minX: 0, + // maxX: (stockDetailsModel! + // .data!.candleStick!.candles!.length + // .toDouble()) - + // 1, + // minY: Utils.extractPriceFromGraph( + // stockDetailsModel! + // .data!.candleStick!.candles!) + // .reduce(min) + // .toDouble(), + // maxY: Utils.extractPriceFromGraph( + // stockDetailsModel! + // .data!.candleStick!.candles!) + // .reduce(max) + // .toDouble(), + lineBarsData: [ + LineChartBarData( + color: const Color(0xFF0093FF), + spots: listData( + Utils.extractPriceFromGraph( + stockDetailsModel! + .data!.candleStick!.candles!), + ), + barWidth: 1.3, + isStrokeCapRound: true, + dotData: const FlDotData( + show: false, + ), + belowBarData: BarAreaData( + show: true, + gradient: LinearGradient( + colors: [ + const Color( + 0xFF0093FF, + ).withOpacity(.01), + const Color( + 0xFF0093FF, + ).withOpacity(.3), + ], + )), + ), + ], ), - ], + curve: Curves.linear, + duration: const Duration(milliseconds: 150), + ), ), - ), - ), - const Gap(20), - text18W400("Overview"), - const Gap(15), - text20W400("Performance"), - const Gap(22), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, + + const Gap(20), + text18W400("Overview"), + const Gap(15), + text20W400("Performance"), + const Gap(22), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, children: [ - text16W400('Today’s Low', - clr: Color(0xFFF979797)), - Gap(5), - text16W500( - stockDetailsModel! - .data!.stockData!.ohlc!.low! - .toString(), + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + text16W400('Today’s Low', + clr: const Color(0xFF979797)), + const Gap(5), + text16W500( + stockDetailsModel! + .data!.stockData!.ohlc!.low! + .toString(), + ) + ], + ), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + text16W400('Today’s High', + clr: const Color(0xFF979797)), + const Gap(5), + text16W500( + stockDetailsModel! + .data!.stockData!.ohlc!.high! + .toString(), + ) + ], ) ], ), - Column( - crossAxisAlignment: CrossAxisAlignment.end, + const Gap(40), + Row( + mainAxisAlignment: + MainAxisAlignment.spaceBetween, children: [ - text16W400('Today’s High', - clr: Color(0xFFF979797)), - Gap(5), - text16W500( - stockDetailsModel! - .data!.stockData!.ohlc!.high! - .toString(), + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + text16W400('Open price', + clr: const Color(0xFF979797)), + const Gap(5), + text16W500( + stockDetailsModel! + .data!.stockData!.ohlc!.open + .toString(), + ) + ], + ), + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + text16W400('Prev. Close', + clr: const Color(0xFF979797)), + const Gap(5), + text16W500( + stockDetailsModel!.data!.candleStick! + .candles!.last.close + .toString(), + ) + ], + ), + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + text16W400('Volume', + clr: const Color(0xFF979797)), + const Gap(5), + text16W500( + stockDetailsModel! + .data!.stockData!.volume + .toString(), + ) + ], ) ], - ) + ), + const Gap(25), + Row( + children: [ + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + text16W400('Lower Circuit', + clr: const Color(0xFF979797)), + const Gap(5), + text16W500( + stockDetailsModel! + .data!.stockData!.lowerCircuitLimit + .toString(), + ) + ], + ), + const Gap(25), + Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + text16W400('Upper Circuit', + clr: const Color(0xFF979797)), + const Gap(5), + text16W500( + stockDetailsModel! + .data!.stockData!.upperCircuitLimit + .toString(), + ) + ], + ) + ], + ), + const Gap(25), ], ), - Gap(40), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - text16W400('Open price', - clr: Color(0xFFF979797)), - Gap(5), - text16W500( - stockDetailsModel! - .data!.stockData!.ohlc!.open - .toString(), - ) - ], - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - text16W400('Prev. Close', - clr: Color(0xFFF979797)), - Gap(5), - text16W500( - stockDetailsModel! - .data!.candleStick!.candles![0].close - .toString(), - ) - ], - ), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - text16W400('Volume', clr: Color(0xFFF979797)), - Gap(5), - text16W500( - stockDetailsModel!.data!.stockData!.volume - .toString(), - ) - ], - ) - ], - ), - Gap(25), - Row( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - text16W400('Lower Circuit', - clr: Color(0xFFF979797)), - Gap(5), - text16W500( - stockDetailsModel! - .data!.stockData!.lowerCircuitLimit - .toString(), - ) - ], - ), - Gap(25), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - text16W400('Upper Circuit', - clr: Color(0xFFF979797)), - Gap(5), - text16W500( - stockDetailsModel! - .data!.stockData!.upperCircuitLimit - .toString(), - ) - ], - ) - ], - ), - Gap(25), - ], + ), ), - ), - ), - ])), + ]), + )), ); } } List listData(List data) { return data.asMap().entries.map((e) { + dv.log("Key ${e.key.toString()} Value ${e.value.toString()}"); return FlSpot(e.key.toDouble(), e.value.toDouble()); }).toList(); } + +class SalesData { + SalesData(this.year, this.sales); + final String year; + final double sales; +} diff --git a/lib/view/Sidemenu/Sidemenu.dart b/lib/view/Sidemenu/Sidemenu.dart index aa7181a..0613d6e 100644 --- a/lib/view/Sidemenu/Sidemenu.dart +++ b/lib/view/Sidemenu/Sidemenu.dart @@ -10,6 +10,8 @@ import 'package:traderscircuit/Utils/text.dart'; import 'package:traderscircuit/resources/routes/route_name.dart'; import 'package:traderscircuit/view_model/ProfileAPI/GetProfileApi.dart'; +import 'webview_subscription.dart'; + class SideMenu extends StatefulWidget { const SideMenu({super.key}); @@ -167,10 +169,12 @@ class _SideMenuState extends State { child: Center(child: text14W500_black('Upgrade')), ), selected: true, - onTap: () { - setState(() { - // Get.toNamed(RouteName.privacypolicy); - }); + onTap: () async { + SharedPreferences prefs = + await SharedPreferences.getInstance(); + + Get.to(WebViewSubscription( + token: prefs.getString('accessToken').toString())); }, ), Container( diff --git a/lib/view/Sidemenu/webview_subscription.dart b/lib/view/Sidemenu/webview_subscription.dart new file mode 100644 index 0000000..9e5b850 --- /dev/null +++ b/lib/view/Sidemenu/webview_subscription.dart @@ -0,0 +1,115 @@ +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:get/get.dart'; +import 'package:traderscircuit/Utils/api_urls.dart'; + +class WebViewSubscription extends StatefulWidget { + WebViewSubscription({ + super.key, + required this.token, + }); + String token; + + @override + State createState() => _WebViewSubscriptionState(); +} + +class _WebViewSubscriptionState extends State { + final GlobalKey webViewKey = GlobalKey(); + + @override + void initState() { + //getData(); + super.initState(); + } + + InAppWebViewController? webViewController; + InAppWebViewController? webViewPopupController; + @override + Widget build(BuildContext context) { + return WillPopScope( + onWillPop: () async { + final controller = webViewController; + if (controller != null) { + if (await controller.canGoBack()) { + Get.back(result: true); + + return false; + } + } + Get.back(result: true); + return false; + }, + child: Scaffold( + body: InAppWebView( + key: webViewKey, + initialSettings: InAppWebViewSettings( + allowsBackForwardNavigationGestures: true, + supportMultipleWindows: true, + javaScriptCanOpenWindowsAutomatically: true, + javaScriptEnabled: true, + // useOnDownloadStart: true, + // useOnLoadResource: true, + // preferredContentMode: UserPreferredContentMode.MOBILE, + // useShouldOverrideUrlLoading: true, + // mediaPlaybackRequiresUserGesture: true, + // allowFileAccessFromFileURLs: true, + // allowUniversalAccessFromFileURLs: true + ), + onLoadStart: (controller, Uri? uri) { + print("Load Started: $uri"); + }, + onCreateWindow: (controller, createWindowRequest) async { + showDialog( + context: context, + builder: (context) { + return AlertDialog( + content: SizedBox( + width: MediaQuery.of(context).size.width, + height: 400, + child: InAppWebView( + windowId: createWindowRequest.windowId, + initialSettings: InAppWebViewSettings( + allowsBackForwardNavigationGestures: true, + supportMultipleWindows: true, + javaScriptCanOpenWindowsAutomatically: true, + javaScriptEnabled: true, + useOnDownloadStart: true, + useOnLoadResource: true, + preferredContentMode: UserPreferredContentMode.MOBILE, + // useShouldOverrideUrlLoading: true, + mediaPlaybackRequiresUserGesture: true, + allowFileAccessFromFileURLs: true, + allowUniversalAccessFromFileURLs: true), + onWebViewCreated: (InAppWebViewController controller) { + webViewPopupController = controller; + }, + onLoadStart: + (InAppWebViewController controller, Uri? url) { + print("onLoadStart popup $url"); + }, + onLoadStop: + (InAppWebViewController controller, Uri? url) { + print("onLoadStop popup $url"); + }, + ), + ), + ); + }, + ); + + return true; + }, + initialUrlRequest: URLRequest( + url: WebUri( + "https://tradercircuit.betadelivery.com/my-subscription-page"), + headers: { + "access-token": widget.token, + }), + ), + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index ca6da19..34b7098 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -422,6 +422,62 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0-beta.2" + flutter_inappwebview: + dependency: "direct main" + description: + name: flutter_inappwebview + sha256: "3e9a443a18ecef966fb930c3a76ca5ab6a7aafc0c7b5e14a4a850cf107b09959" + url: "https://pub.dev" + source: hosted + version: "6.0.0" + flutter_inappwebview_android: + dependency: transitive + description: + name: flutter_inappwebview_android + sha256: d247f6ed417f1f8c364612fa05a2ecba7f775c8d0c044c1d3b9ee33a6515c421 + url: "https://pub.dev" + source: hosted + version: "1.0.13" + flutter_inappwebview_internal_annotations: + dependency: transitive + description: + name: flutter_inappwebview_internal_annotations + sha256: "5f80fd30e208ddded7dbbcd0d569e7995f9f63d45ea3f548d8dd4c0b473fb4c8" + url: "https://pub.dev" + source: hosted + version: "1.1.1" + flutter_inappwebview_ios: + dependency: transitive + description: + name: flutter_inappwebview_ios + sha256: f363577208b97b10b319cd0c428555cd8493e88b468019a8c5635a0e4312bd0f + url: "https://pub.dev" + source: hosted + version: "1.0.13" + flutter_inappwebview_macos: + dependency: transitive + description: + name: flutter_inappwebview_macos + sha256: b55b9e506c549ce88e26580351d2c71d54f4825901666bd6cfa4be9415bb2636 + url: "https://pub.dev" + source: hosted + version: "1.0.11" + flutter_inappwebview_platform_interface: + dependency: transitive + description: + name: flutter_inappwebview_platform_interface + sha256: "545fd4c25a07d2775f7d5af05a979b2cac4fbf79393b0a7f5d33ba39ba4f6187" + url: "https://pub.dev" + source: hosted + version: "1.0.10" + flutter_inappwebview_web: + dependency: transitive + description: + name: flutter_inappwebview_web + sha256: d8c680abfb6fec71609a700199635d38a744df0febd5544c5a020bd73de8ee07 + url: "https://pub.dev" + source: hosted + version: "1.0.8" flutter_isolate: dependency: transitive description: @@ -1109,6 +1165,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.0" + syncfusion_flutter_charts: + dependency: "direct main" + description: + name: syncfusion_flutter_charts + sha256: "5f868f5a82380ef1b3de416b7812e1ac7acce6a629f9281618adee81d90716cc" + url: "https://pub.dev" + source: hosted + version: "21.2.10" syncfusion_flutter_core: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index c3ef4b2..5886ad8 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -54,9 +54,14 @@ dependencies: device_info_plus: ^8.2.2 permission_handler: ^11.3.1 fl_chart: ^0.68.0 + firebase_crashlytics: ^3.4.18 firebase_analytics: ^10.8.9 + syncfusion_flutter_charts: ^21.2.4 + flutter_inappwebview: ^6.0.0 + + dev_dependencies: flutter_test: sdk: flutter