diff --git a/assets/images/svg/filled_thumb_down.svg b/assets/images/svg/filled_thumb_down.svg
new file mode 100644
index 0000000..4e7fd4e
--- /dev/null
+++ b/assets/images/svg/filled_thumb_down.svg
@@ -0,0 +1,3 @@
+
diff --git a/assets/images/svg/filled_thumb_up.svg b/assets/images/svg/filled_thumb_up.svg
new file mode 100644
index 0000000..440e863
--- /dev/null
+++ b/assets/images/svg/filled_thumb_up.svg
@@ -0,0 +1,3 @@
+
diff --git a/lib/Utils/api_urls.dart b/lib/Utils/api_urls.dart
index c6db056..cd3c1c6 100644
--- a/lib/Utils/api_urls.dart
+++ b/lib/Utils/api_urls.dart
@@ -38,6 +38,7 @@ class ApiUrls {
//FAQ API
static String faqApi = "${base}getFaq";
+ static String faqLikeDislikeApi = "${base}userFaqLikeDislike";
//RISK PROFILE API
static String getRiskProfileQuestionAnswerApi = "${base}riskProfileQueAns";
diff --git a/lib/controller/content_bytes_controller.dart b/lib/controller/content_bytes_controller.dart
index 7fa544c..39ff627 100644
--- a/lib/controller/content_bytes_controller.dart
+++ b/lib/controller/content_bytes_controller.dart
@@ -1,11 +1,176 @@
+import 'package:flutter/material.dart';
import 'package:get/get.dart';
+import 'package:just_audio/just_audio.dart';
import 'package:traderscircuit/model/ContentBytesModel/content_bytes_categories_model.dart';
import 'package:traderscircuit/model/ContentBytesModel/content_bytes_model.dart';
+import '../view/Sidemenu/ContentByte/ContentBytes.dart';
+
class ContentBytesController extends GetxController {
ContentBytesCategoriesModel contentBytesCategoriesModel =
ContentBytesCategoriesModel();
ContentBytesModel contentBytesModel = ContentBytesModel();
int filterId = 0;
RxBool isApiCalling = true.obs;
+ RxBool isAudioSeekBarVisible = false.obs;
+ RxInt indexForAudios = 0.obs;
+ RxBool titlePlaying = false.obs;
+ RxList? titlePlayingList = [].obs;
+
+ final progressNotifier = ValueNotifier(
+ ProgressBarState(
+ current: Duration.zero,
+ buffered: Duration.zero,
+ total: Duration.zero,
+ ),
+ );
+ final buttonNotifier = ValueNotifier(ButtonState.paused);
+
+ late AudioPlayer _audioPlayer;
+
+ void getAudio() => _audioPlayer;
+
+ void init(index) async {
+ _audioPlayer = AudioPlayer();
+ try {
+ await _audioPlayer.setUrl(
+ //contentBytesModel.data!.audio![index].file ??
+ 'https://ghantalele.com/uploads/files/data-78/38825/Besharam%20Rang_192(Ghantalele.com).mp3');
+ // await _audioPlayer.setAsset(url);
+ } on PlayerException catch (e) {
+ print("Error code: ${e.code}");
+ // iOS/macOS: maps to NSError.localizedDescription
+ // Android: maps to ExoPlaybackException.getMessage()
+ // Web/Linux: a generic message
+ // Windows: MediaPlayerError.message
+ print("Error message: ${e.message}");
+ }
+//Catching errors during playback (e.g. lost network connection)
+ _audioPlayer.playbackEventStream.listen((event) {},
+ onError: (Object e, StackTrace st) {
+ if (e is PlayerException) {
+ print('Error code: ${e.code}');
+ print('Error message: ${e.message}');
+ } else {
+ print('An error occurred: $e');
+ }
+ });
+
+ _audioPlayer.playerStateStream.listen((playerState) {
+ final isPlaying = playerState.playing;
+ final processingState = playerState.processingState;
+ if (!isPlaying) {
+ buttonNotifier.value = ButtonState.paused;
+ } else if (processingState != ProcessingState.completed) {
+ buttonNotifier.value = ButtonState.playing;
+ } else {
+ _playNextTrack();
+
+ // _audioPlayer.seek(Duration.zero);
+ // _audioPlayer.pause();
+ }
+ });
+
+ _audioPlayer.positionStream.listen((position) {
+ final oldState = progressNotifier.value;
+ progressNotifier.value = ProgressBarState(
+ current: position,
+ buffered: oldState.buffered,
+ total: oldState.total,
+ );
+ });
+
+ _audioPlayer.bufferedPositionStream.listen((bufferedPosition) {
+ final oldState = progressNotifier.value;
+ progressNotifier.value = ProgressBarState(
+ current: oldState.current,
+ buffered: bufferedPosition,
+ total: oldState.total,
+ );
+ });
+
+ _audioPlayer.durationStream.listen((totalDuration) {
+ final oldState = progressNotifier.value;
+ progressNotifier.value = ProgressBarState(
+ current: oldState.current,
+ buffered: oldState.buffered,
+ total: totalDuration ?? Duration.zero,
+ );
+ });
+ }
+
+ void _playNextTrack() {
+ // Determine the index of the next track (you need to implement this logic)
+ int nextIndex = getNextTrackIndex();
+
+ if (nextIndex != -1) {
+ // Play the next track
+ updateTitlePlaying(nextIndex);
+ if (isPlaying()) {
+ stop();
+ }
+ init(nextIndex);
+ play(nextIndex);
+ } else {
+ _audioPlayer.seek(Duration.zero);
+ _audioPlayer.pause();
+ }
+ }
+
+ int getNextTrackIndex() {
+ if (indexForAudios.value == contentBytesModel.data!.audio!.length - 1) {
+ return -1;
+ } else {
+ return indexForAudios.value + 1;
+ }
+
+ // You need to implement this logic based on your playlist structure
+ // For example, if you have a list of tracks, return the index of the next track
+ // If there is no next track, return -1
+ // This logic depends on how you manage your playlist
+ // Example: return currentTrackIndex + 1;
+ }
+
+ void play(index) {
+ _audioPlayer.play();
+ isAudioSeekBarVisible.value = false;
+ isAudioSeekBarVisible.value = true;
+ indexForAudios.value = index;
+ }
+
+ void pause() {
+ _audioPlayer.pause();
+ }
+
+ void seek(Duration position) {
+ _audioPlayer.seek(position);
+ }
+
+ void stop() {
+ _audioPlayer.stop();
+ }
+
+ bool isPlaying() {
+ return _audioPlayer.playing;
+ }
+
+ addTitles() {
+ titlePlayingList = List.generate(
+ contentBytesModel.data!.audio!.length,
+ (index) => false,
+ ).obs;
+ }
+
+ void updateTitlePlaying(int index) {
+ // Check if the index is within valid range
+ if (index >= 0 && index < titlePlayingList!.length) {
+ // Set all values to false
+ titlePlayingList!.assignAll(List.generate(
+ titlePlayingList!.length,
+ (index) => false,
+ ));
+ // Set the specified index to true
+ titlePlayingList![index] = true;
+ }
+ }
}
diff --git a/lib/data/network/network_api_services.dart b/lib/data/network/network_api_services.dart
index 513c5d0..38ffc6c 100644
--- a/lib/data/network/network_api_services.dart
+++ b/lib/data/network/network_api_services.dart
@@ -64,7 +64,10 @@ class NetworkApiServices extends BaseApiServices {
}
@override
- Future postApi(data, String url, {bool isAuth = false}) async {
+ Future postApi(
+ data,
+ String url,
+ ) async {
if (kDebugMode) {
print("data >>> $data");
print("api url is >>> $url");
diff --git a/lib/model/FAQModel/faq_model.dart b/lib/model/FAQModel/faq_model.dart
index 6e7b938..4822d9b 100644
--- a/lib/model/FAQModel/faq_model.dart
+++ b/lib/model/FAQModel/faq_model.dart
@@ -1,3 +1,5 @@
+import 'package:get/get.dart';
+
class FAQModel {
String? status;
int? statusCode;
@@ -97,6 +99,7 @@ class FaqQueAns {
String? deletedAt;
String? createdAt;
String? updatedAt;
+ List? userLikes;
FaqQueAns(
{this.id,
@@ -108,7 +111,8 @@ class FaqQueAns {
this.modifiedBy,
this.deletedAt,
this.createdAt,
- this.updatedAt});
+ this.updatedAt,
+ this.userLikes});
FaqQueAns.fromJson(Map json) {
id = json['id'];
@@ -121,6 +125,12 @@ class FaqQueAns {
deletedAt = json['deleted_at'] ?? "";
createdAt = json['created_at'];
updatedAt = json['updated_at'];
+ if (json['user_likes'] != null) {
+ userLikes = [];
+ json['user_likes'].forEach((v) {
+ userLikes!.add(UserLikes.fromJson(v));
+ });
+ }
}
Map toJson() {
@@ -133,6 +143,53 @@ class FaqQueAns {
data['created_by'] = createdBy;
data['modified_by'] = modifiedBy;
data['deleted_at'] = deletedAt;
+ data['created_at'] = createdAt;
+ data['updated_at'] = updatedAt;
+ if (userLikes != null) {
+ data['user_likes'] = userLikes!.map((v) => v.toJson()).toList();
+ }
+ return data;
+ }
+}
+
+class UserLikes {
+ int? id;
+ int? userId;
+ int? faqId;
+ int? status; //RxInt? status;
+ String? isActive;
+
+ String? createdAt;
+ String? updatedAt;
+
+ UserLikes(
+ {this.id,
+ this.userId,
+ this.faqId,
+ this.status,
+ this.isActive,
+ this.createdAt,
+ this.updatedAt});
+
+ UserLikes.fromJson(Map json) {
+ id = json['id'];
+ userId = json['user_id'];
+ faqId = json['faq_id'];
+ status = (json['status']); // RxInt(json['status']);
+ isActive = json['is_active'];
+
+ createdAt = json['created_at'];
+ updatedAt = json['updated_at'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['id'] = id;
+ data['user_id'] = userId;
+ data['faq_id'] = faqId;
+ data['status'] = status;
+ data['is_active'] = isActive;
+
data['created_at'] = createdAt;
data['updated_at'] = updatedAt;
return data;
diff --git a/lib/view/MainScreen/HomeScreen.dart b/lib/view/MainScreen/HomeScreen.dart
index e63c15c..aa3effe 100644
--- a/lib/view/MainScreen/HomeScreen.dart
+++ b/lib/view/MainScreen/HomeScreen.dart
@@ -244,9 +244,9 @@ Widget ActiveCallsTab() {
children: [
InkWell(
onTap: () {
- Get.to(
- () => PlayerWidget(),
- );
+ Get.to(() => PlayerWidget(), arguments: {
+ "video_url": "",
+ });
},
child: Container(
height: 200.h,
diff --git a/lib/view/MainScreen/ShortTrade.dart b/lib/view/MainScreen/ShortTrade.dart
index f5c93c4..d9adedd 100644
--- a/lib/view/MainScreen/ShortTrade.dart
+++ b/lib/view/MainScreen/ShortTrade.dart
@@ -194,9 +194,9 @@ class _ShortTradeState extends State {
children: [
InkWell(
onTap: () {
- Get.to(
- () => PlayerWidget(),
- );
+ Get.to(() => PlayerWidget(), arguments: {
+ "video_url": "",
+ });
},
child: Container(
height: 200.h,
diff --git a/lib/view/Sidemenu/ContentByte/ContentBytes.dart b/lib/view/Sidemenu/ContentByte/ContentBytes.dart
index 32bcf70..845b2fc 100644
--- a/lib/view/Sidemenu/ContentByte/ContentBytes.dart
+++ b/lib/view/Sidemenu/ContentByte/ContentBytes.dart
@@ -1,13 +1,12 @@
import 'dart:developer';
-import 'package:cached_network_image/cached_network_image.dart';
+import 'package:audio_video_progress_bar/audio_video_progress_bar.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:gap/gap.dart';
import 'package:get/get.dart';
import 'package:traderscircuit/Utils/Common/CommonAppbar.dart';
-import 'package:traderscircuit/Utils/Common/CustomTextFormField.dart';
import 'package:traderscircuit/Utils/Common/comonGlassmorphicContainer.dart';
import 'package:traderscircuit/Utils/Common/sized_box.dart';
import 'package:traderscircuit/Utils/text.dart';
@@ -15,10 +14,23 @@ import 'package:traderscircuit/controller/content_bytes_controller.dart';
import 'package:traderscircuit/model/ContentBytesModel/content_bytes_categories_model.dart';
import 'package:traderscircuit/model/ContentBytesModel/content_bytes_model.dart';
import 'package:traderscircuit/view/Sidemenu/ContentByte/PlayerWidget.dart';
-import 'package:traderscircuit/view/Sidemenu/ContentByte/Reels.dart';
+import 'package:traderscircuit/view/Sidemenu/ContentByte/read_pdf.dart';
import 'package:traderscircuit/view/onBoarding/splashScreen1.dart';
import 'package:traderscircuit/view_model/ContentBytesApi/content_bytes_api.dart';
+class ProgressBarState {
+ ProgressBarState({
+ required this.current,
+ required this.buffered,
+ required this.total,
+ });
+ final Duration current;
+ final Duration buffered;
+ final Duration total;
+}
+
+enum ButtonState { paused, playing }
+
class ContentBytes extends StatefulWidget {
const ContentBytes({super.key});
@@ -27,7 +39,7 @@ class ContentBytes extends StatefulWidget {
}
class _ContentBytesState extends State {
- GlobalKey _scaffoldKey1 = GlobalKey();
+ final GlobalKey _scaffoldKey1 = GlobalKey();
final selectedIndex = 0.obs;
List reels = [
@@ -37,42 +49,12 @@ class _ContentBytesState extends State {
"assets/images/png/sidemenu/reels4.png",
];
- List audionewimage = [
- "assets/images/png/sidemenu/audionew1.png",
- "assets/images/png/sidemenu/audionew2.png",
- "assets/images/png/sidemenu/audionew1.png",
- ];
-
List mostread = [
"assets/images/png/sidemenu/Read1.png",
"assets/images/png/sidemenu/Read2.png",
"assets/images/png/sidemenu/Read1.png",
];
- List audio = [
- "assets/images/png/sidemenu/audio1.png",
- "assets/images/png/sidemenu/audio2.png",
- "assets/images/png/sidemenu/audio3.png",
- "assets/images/png/sidemenu/audio4.png",
- "assets/images/png/sidemenu/audio1.png",
- "assets/images/png/sidemenu/audio2.png",
- ];
-
- List audioname = [
- "Week of 21st March 2024",
- "Week of 21st March 2024",
- "Week of 21st March 2024",
- "Week of 21st March 2024",
- "Week of 21st March 2024",
- "Week of 21st March 2024",
- ];
-
- List audionamenewrelease = [
- "Week of 21st March 2024",
- "Week of 21st March 2024",
- "Week of 21st March 2024",
- ];
-
ContentBytesController contentBytesController =
Get.put(ContentBytesController());
@override
@@ -91,64 +73,187 @@ class _ContentBytesState extends State {
@override
Widget build(BuildContext context) {
- return Scaffold(
- key: _scaffoldKey1,
- backgroundColor: Colors.black,
- extendBody: true,
- appBar: const CommonAppbar(titleTxt: "Content Bytes"),
- body: Stack(
- children: [
- const CommonBlurLeft(),
- const CommonBlurRight(),
- Stack(
- children: [
- Padding(
- padding:
- const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
- child: ListView(
+ return WillPopScope(
+ onWillPop: () async {
+ return true;
+ },
+ child: Scaffold(
+ key: _scaffoldKey1,
+ floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
+ floatingActionButton: Obx(() => contentBytesController
+ .isAudioSeekBarVisible.value
+ ? commonGlassContainer(
+ borderradius: 8,
+ width: Get.size.width,
+ height: 100,
+ customWidget: Row(
children: [
- const SizedBox(
- height: 10,
- ),
- DefaultTabController(
- length: 3,
- // initialIndex: selectedIndex.value,
- child: Column(
- children: [
- ContentTabBar(),
- SizedBox(
- height: 30.h,
+ Expanded(
+ flex: 1,
+ child: Align(
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(100),
+ child: Image.network(
+ contentBytesController
+ .contentBytesModel
+ .data!
+ .audio![
+ contentBytesController.indexForAudios.value]
+ .image!,
+ width: 57,
+ height: 57,
+ fit: BoxFit.cover,
),
- SizedBox(
- height: 600.h,
- child: TabBarView(
- children: [
- Videos(images: reels),
- Audios(
- audio: audio,
- audioname: audioname,
- audionewimage: audionewimage,
- audionamenewrelease: audionamenewrelease),
- Reads(mostread: mostread),
- ],
+ ),
+ ),
+ ),
+ Expanded(
+ flex: 3,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Text(
+ contentBytesController
+ .contentBytesModel
+ .data!
+ .audio![
+ contentBytesController.indexForAudios.value]
+ .title!,
+ style: const TextStyle(
+ fontSize: 14,
+ color: Colors.white,
+ fontFamily: 'hiragino',
+ fontWeight: FontWeight.w600,
+ height: 1.5,
),
),
+ // SizedBox(height: 5),
+ Text(
+ contentBytesController
+ .contentBytesModel
+ .data!
+ .audio![
+ contentBytesController.indexForAudios.value]
+ .description!,
+ style: const TextStyle(
+ fontSize: 14,
+ color: Colors.white,
+ fontFamily: 'hiragino',
+ fontWeight: FontWeight.w600,
+ height: 1.5,
+ ),
+ ),
+ ValueListenableBuilder(
+ valueListenable:
+ contentBytesController.progressNotifier,
+ builder: (context, value, _) {
+ return ProgressBar(
+ progress: value.current,
+ buffered: value.buffered,
+ total: value.total,
+ onSeek: contentBytesController.seek,
+ barHeight: 4,
+ thumbRadius: 6,
+ thumbGlowRadius: 15,
+ timeLabelTextStyle: TextStyle(
+ color: Colors.white,
+ ),
+ thumbColor: Colors.white,
+ baseBarColor: Colors.white.withOpacity(0.3),
+ progressBarColor: Colors.white,
+ bufferedBarColor: Colors.white.withOpacity(0.3),
+ );
+ },
+ ),
],
),
),
- sizedBoxHeight(40.h),
+ Expanded(
+ flex: 1,
+ child: ValueListenableBuilder(
+ valueListenable: contentBytesController.buttonNotifier,
+ builder: (context, value, _) {
+ switch (value) {
+ case ButtonState.paused:
+ return IconButton(
+ icon: const Icon(
+ Icons.play_arrow_rounded,
+ color: Colors.white,
+ ),
+ iconSize: 50.0,
+ onPressed: () => contentBytesController.play(
+ contentBytesController
+ .indexForAudios.value),
+ );
+ case ButtonState.playing:
+ return IconButton(
+ icon: const Icon(Icons.pause,
+ color: Colors.white),
+ iconSize: 50.0,
+ onPressed: contentBytesController.pause,
+ );
+ }
+ },
+ ),
+ ),
],
),
- ),
- ],
- ),
- ],
+ )
+ : Container()),
+ backgroundColor: Colors.black,
+ extendBody: true,
+ appBar: const CommonAppbar(titleTxt: "Content Bytes"),
+ body: Stack(
+ children: [
+ const CommonBlurLeft(),
+ const CommonBlurRight(),
+ Stack(
+ children: [
+ Padding(
+ padding:
+ const EdgeInsets.symmetric(horizontal: 16, vertical: 16),
+ child: ListView(
+ children: [
+ const SizedBox(
+ height: 10,
+ ),
+ DefaultTabController(
+ length: 3,
+ // initialIndex: selectedIndex.value,
+ child: Column(
+ children: [
+ ContentTabBar(),
+ SizedBox(
+ height: 30.h,
+ ),
+ SizedBox(
+ height: 600.h,
+ child: TabBarView(
+ children: [
+ Videos(images: reels),
+ Audios(),
+ Reads(mostread: mostread),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ sizedBoxHeight(40.h),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
),
);
}
}
-class Reads extends StatelessWidget {
+class Reads extends StatefulWidget {
const Reads({
super.key,
required this.mostread,
@@ -156,254 +261,235 @@ class Reads extends StatelessWidget {
final List mostread;
+ @override
+ State createState() => _ReadsState();
+}
+
+class _ReadsState extends State {
+ ContentBytesController contentBytesController =
+ Get.put(ContentBytesController());
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Row(
- children: [
- const SizedBox(
- width: 300,
- child: CustomTextFormField(
- leadingIcon: Icon(Icons.search),
- ),
- ),
- SizedBox(
- width: 15.w,
- ),
- Image.asset(
- "assets/images/png/filter.png",
- height: 30.h,
- width: 30.w,
- ),
- ],
- ),
- SizedBox(
- height: 10.h,
- ),
+ // Row(
+ // children: [
+ // const SizedBox(
+ // width: 300,
+ // child: CustomTextFormField(
+ // leadingIcon: Icon(Icons.search),
+ // ),
+ // ),
+ // SizedBox(
+ // width: 15.w,
+ // ),
+ // Image.asset(
+ // "assets/images/png/filter.png",
+ // height: 30.h,
+ // width: 30.w,
+ // ),
+ // ],
+ // ),
+ // SizedBox(
+ // height: 10.h,
+ // ),
text22W600('Harnessing the Power of Ebooks"'),
sizedBoxHeight(20.h),
- commonGlassContainer(
- borderradius: 8,
- width: double.infinity,
- height: 150.h,
- customWidget: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- const SizedBox(
- width: 10,
- ),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- const Spacer(),
- SizedBox(
- width: 235.w,
- child: text20W400('"Stock Market Essentials"'),
- ),
- sizedBoxHeight(10.h),
- SizedBox(
- width: 230.w,
- child: text16W400(
- 'A Comprehensive Guide to Understanding the Market'),
- ),
- const Spacer()
- ],
- ),
- const SizedBox(
- width: 20,
- ),
- Column(
- mainAxisAlignment: MainAxisAlignment.end,
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- Image.asset(
- "assets/images/png/sidemenu/book1.png",
- height: 110,
- ),
- ],
- )
- ],
- ),
- ),
- sizedBoxHeight(20.h),
- commonGlassContainer(
- borderradius: 8,
- width: double.infinity,
- height: 150.h,
- customWidget: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- const SizedBox(
- width: 10,
- ),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- const Spacer(),
- SizedBox(
- width: 235.w,
- child: text20W400('"Stock Market Essentials"'),
- ),
- sizedBoxHeight(10.h),
- SizedBox(
- width: 230.w,
- child: text16W400(
- 'A Comprehensive Guide to Understanding the Market'),
- ),
- const Spacer()
- ],
- ),
- const SizedBox(
- width: 20,
- ),
- Column(
- mainAxisAlignment: MainAxisAlignment.end,
- crossAxisAlignment: CrossAxisAlignment.end,
- children: [
- Image.asset(
- "assets/images/png/sidemenu/book1.png",
- height: 110,
- ),
- ],
- )
- ],
- ),
- ),
- sizedBoxHeight(30.h),
- text22W500("Most Read"),
- sizedBoxHeight(25.h),
- Container(
- height: 220.h,
- child: ListView.separated(
- separatorBuilder: (context, index) {
- return SizedBox(
- width: 10.w,
- );
- },
- scrollDirection: Axis.horizontal,
- itemCount: 3,
- itemBuilder: (context, index) {
+ ListView.builder(
+ itemCount:
+ contentBytesController.contentBytesModel.data!.read!.length,
+ shrinkWrap: true,
+ physics: NeverScrollableScrollPhysics(),
+ itemBuilder: (ctx, index) {
return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Container(
- height: 216.h,
- width: 150.w,
- decoration: BoxDecoration(
- gradient: LinearGradient(
- begin: Alignment.topLeft,
- end: Alignment.bottomRight,
- colors: [
- Colors.white.withOpacity(0.1),
- const Color(0xFFFFFFFF).withOpacity(0.05),
- ],
- stops: [
- 0.1,
- 1,
+ InkWell(
+ onTap: () {
+ Get.to(ReadPDF(
+ title: contentBytesController
+ .contentBytesModel.data!.read![index].title,
+ pdfUrfl: contentBytesController
+ .contentBytesModel.data!.read![index].file,
+ ));
+ },
+ child: commonGlassContainer(
+ borderradius: 8,
+ width: double.infinity,
+ height: 150.h,
+ customWidget: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ const SizedBox(
+ width: 10,
+ ),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const Spacer(),
+ SizedBox(
+ width: 235.w,
+ child: text20W400(
+ '"${contentBytesController.contentBytesModel.data!.read![index].title}"'),
+ ),
+ sizedBoxHeight(10.h),
+ SizedBox(
+ width: 230.w,
+ child: text16W400(
+ '"${contentBytesController.contentBytesModel.data!.read![index].description}"'),
+ ),
+ const Spacer()
+ ],
+ ),
+ Column(
+ mainAxisAlignment: MainAxisAlignment.end,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ Image.network(
+ "${contentBytesController.contentBytesModel.data!.read![index].image}",
+ height: 110,
+ ),
+ ],
+ )
],
),
- borderRadius: BorderRadius.circular(8),
- ),
- child: Image.asset(mostread[index]),
- ),
- ],
- );
- },
- ),
- ),
- sizedBoxHeight(30.h),
- text22W500("Previous Read"),
- sizedBoxHeight(20.h),
- Container(
- height: 90.h,
- child: ListView.separated(
- separatorBuilder: (context, index) {
- return SizedBox(
- width: 10.w,
- );
- },
- scrollDirection: Axis.horizontal,
- itemCount: 2,
- itemBuilder: (context, index) {
- return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Container(
- height: 85.h,
- width: 230.w,
- decoration: BoxDecoration(
- gradient: LinearGradient(
- begin: Alignment.topLeft,
- end: Alignment.bottomRight,
- colors: [
- Colors.white.withOpacity(0.1),
- const Color(0xFFFFFFFF).withOpacity(0.05),
- ],
- stops: [
- 0.1,
- 1,
- ],
- ),
- borderRadius: BorderRadius.circular(8),
- ),
- child: Row(
- // mainAxisAlignment:
- // MainAxisAlignment.start,
- children: [
- const SizedBox(
- width: 10,
- ),
- Image.asset(mostread[index]),
- SizedBox(
- width: 15.w,
- ),
- Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- SizedBox(
- width: 135.w,
- child: text12W500("Stock Market Essentials"),
- ),
- SizedBox(
- width: 130.w,
- child: text10W300(
- "A Comprehensive Guide to Understanding the Market"),
- )
- ],
- )
- ],
),
),
+ sizedBoxHeight(20.h),
],
);
- },
- ),
- ),
+ }),
+ // sizedBoxHeight(30.h),
+ // text22W500("Most Read"),
+ // sizedBoxHeight(25.h),
+ // Container(
+ // height: 220.h,
+ // child: ListView.separated(
+ // separatorBuilder: (context, index) {
+ // return SizedBox(
+ // width: 10.w,
+ // );
+ // },
+ // scrollDirection: Axis.horizontal,
+ // itemCount: 3,
+ // itemBuilder: (context, index) {
+ // return Column(
+ // crossAxisAlignment: CrossAxisAlignment.start,
+ // children: [
+ // Container(
+ // height: 216.h,
+ // width: 150.w,
+ // decoration: BoxDecoration(
+ // gradient: LinearGradient(
+ // begin: Alignment.topLeft,
+ // end: Alignment.bottomRight,
+ // colors: [
+ // Colors.white.withOpacity(0.1),
+ // const Color(0xFFFFFFFF).withOpacity(0.05),
+ // ],
+ // stops: [
+ // 0.1,
+ // 1,
+ // ],
+ // ),
+ // borderRadius: BorderRadius.circular(8),
+ // ),
+ // child: Image.asset(mostread[index]),
+ // ),
+ // ],
+ // );
+ // },
+ // ),
+ // ),
+ // sizedBoxHeight(30.h),
+ // text22W500("Previous Read"),
+ // sizedBoxHeight(20.h),
+ // Container(
+ // height: 90.h,
+ // child: ListView.separated(
+ // separatorBuilder: (context, index) {
+ // return SizedBox(
+ // width: 10.w,
+ // );
+ // },
+ // scrollDirection: Axis.horizontal,
+ // itemCount: 2,
+ // itemBuilder: (context, index) {
+ // return Column(
+ // crossAxisAlignment: CrossAxisAlignment.start,
+ // children: [
+ // Container(
+ // height: 85.h,
+ // width: 230.w,
+ // decoration: BoxDecoration(
+ // gradient: LinearGradient(
+ // begin: Alignment.topLeft,
+ // end: Alignment.bottomRight,
+ // colors: [
+ // Colors.white.withOpacity(0.1),
+ // const Color(0xFFFFFFFF).withOpacity(0.05),
+ // ],
+ // stops: [
+ // 0.1,
+ // 1,
+ // ],
+ // ),
+ // borderRadius: BorderRadius.circular(8),
+ // ),
+ // child: Row(
+ // // mainAxisAlignment:
+ // // MainAxisAlignment.start,
+ // children: [
+ // const SizedBox(
+ // width: 10,
+ // ),
+ // Image.asset(mostread[index]),
+ // SizedBox(
+ // width: 15.w,
+ // ),
+ // Column(
+ // crossAxisAlignment: CrossAxisAlignment.start,
+ // mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+ // children: [
+ // SizedBox(
+ // width: 135.w,
+ // child: text12W500("Stock Market Essentials"),
+ // ),
+ // SizedBox(
+ // width: 130.w,
+ // child: text10W300(
+ // "A Comprehensive Guide to Understanding the Market"),
+ // )
+ // ],
+ // )
+ // ],
+ // ),
+ // ),
+ // ],
+ // );
+ // },
+ // ),
+ // ),
],
),
);
}
}
-class Audios extends StatelessWidget {
+class Audios extends StatefulWidget {
const Audios({
super.key,
- required this.audio,
- required this.audioname,
- required this.audionewimage,
- required this.audionamenewrelease,
});
- final List audio;
- final List audioname;
- final List audionewimage;
- final List audionamenewrelease;
+ @override
+ State createState() => _AudiosState();
+}
+
+class _AudiosState extends State {
+ ContentBytesController contentBytesController =
+ Get.put(ContentBytesController());
@override
Widget build(BuildContext context) {
@@ -411,45 +497,51 @@ class Audios extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Row(
- children: [
- const SizedBox(
- width: 300,
- child: CustomTextFormField(
- leadingIcon: Icon(Icons.search),
- ),
- ),
- SizedBox(
- width: 15.w,
- ),
- Image.asset(
- "assets/images/png/filter.png",
- height: 30.h,
- width: 30.w,
- ),
- ],
- ),
- SizedBox(
- height: 10.h,
- ),
+ // Row(
+ // children: [
+ // const SizedBox(
+ // width: 300,
+ // child: CustomTextFormField(
+ // leadingIcon: Icon(Icons.search),
+ // ),
+ // ),
+ // SizedBox(
+ // width: 15.w,
+ // ),
+ // Image.asset(
+ // "assets/images/png/filter.png",
+ // height: 30.h,
+ // width: 30.w,
+ // ),
+ // ],
+ // ),
+ // SizedBox(
+ // height: 10.h,
+ // ),
text22W600('Content Bytes'),
sizedBoxHeight(8.w),
- text16W400_DADADA('The Beauty and Power of Video'),
+ text16W400_DADADA('The Beauty and Power of Audios'),
sizedBoxHeight(20.h),
- Container(
- height: 550,
- child: GridView.builder(
- physics: const NeverScrollableScrollPhysics(),
- gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
- mainAxisExtent: 172,
- crossAxisCount: 2, // number of items in each row
- mainAxisSpacing: 8.0, // spacing between rows
- crossAxisSpacing: 8.0, // spacing between columns
- ),
+ GridView.builder(
+ shrinkWrap: true,
+ physics: const NeverScrollableScrollPhysics(),
+ gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
+ mainAxisExtent: 172,
+ crossAxisCount: 2, // number of items in each row
+ mainAxisSpacing: 8.0, // spacing between rows
+ crossAxisSpacing: 8.0, // spacing between columns
+ ),
- itemCount: 6, // total number of items
- itemBuilder: (context, index) {
- return Container(
+ itemCount: contentBytesController
+ .contentBytesModel.data!.audio!.length, // total number of items
+ itemBuilder: (context, index) {
+ return InkWell(
+ onTap: () {
+ contentBytesController.init(0);
+ contentBytesController.isAudioSeekBarVisible.value = true;
+ //https://actions.google.com/sounds/v1/horror/aggressive_zombie_snarls.ogg
+ },
+ child: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
@@ -467,8 +559,9 @@ class Audios extends StatelessWidget {
),
child: Stack(
children: [
- Image.asset(
- audio[index],
+ Image.network(
+ contentBytesController
+ .contentBytesModel.data!.audio![index].image!,
),
Positioned(
bottom: 5,
@@ -484,90 +577,101 @@ class Audios extends StatelessWidget {
),
SizedBox(
width: 125.w,
- child: text14W500(audioname[index]),
+ child: text14W500(contentBytesController
+ .contentBytesModel
+ .data!
+ .audio![index]
+ .title!),
),
],
),
),
],
),
- );
- },
- ),
+ ),
+ );
+ },
),
- SizedBox(
- height: 20.h,
- ),
- text22W600("New Release"),
- SizedBox(
- height: 25.h,
- ),
- Container(
- height: 250.h,
- child: ListView.separated(
- separatorBuilder: (context, index) {
- return const SizedBox(
- width: 10,
- );
- },
- scrollDirection: Axis.horizontal,
- itemCount: 3,
- itemBuilder: (context, index) {
- return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Container(
- height: 183.h,
- width: 148.w,
- decoration: BoxDecoration(
- gradient: LinearGradient(
- begin: Alignment.topLeft,
- end: Alignment.bottomRight,
- colors: [
- Colors.white.withOpacity(0.1),
- const Color(0xFFFFFFFF).withOpacity(0.05),
- ],
- stops: [
- 0.1,
- 1,
- ],
- ),
- borderRadius: BorderRadius.circular(8),
- ),
- child: Stack(
- children: [
- Image.asset(audionewimage[index]),
- const Positioned(
- right: 5,
- top: 5,
- child: CircleAvatar(
- radius: 15,
- child: Icon(
- Icons.headphones,
- size: 20,
- ),
- ),
- ),
- ],
- ),
- ),
- const SizedBox(
- height: 10,
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.start,
- children: [
- SizedBox(
- width: 148.w,
- child: text14W500Overflow(audionamenewrelease[index]),
- ),
- ],
- )
- ],
- );
- },
- ),
- )
+ // SizedBox(
+ // height: 20.h,
+ // ),
+ // text22W600("New Release"),
+ // SizedBox(
+ // height: 25.h,
+ // ),
+ // Container(
+ // height: 250.h,
+ // child: ListView.separated(
+ // separatorBuilder: (context, index) {
+ // return const SizedBox(
+ // width: 10,
+ // );
+ // },
+ // scrollDirection: Axis.horizontal,
+ // itemCount:
+ // contentBytesController.contentBytesModel.data!.audio!.length,
+ // itemBuilder: (context, index) {
+ // return Column(
+ // crossAxisAlignment: CrossAxisAlignment.start,
+ // children: [
+ // Container(
+ // height: 183.h,
+ // width: 148.w,
+ // decoration: BoxDecoration(
+ // gradient: LinearGradient(
+ // begin: Alignment.topLeft,
+ // end: Alignment.bottomRight,
+ // colors: [
+ // Colors.white.withOpacity(0.1),
+ // const Color(0xFFFFFFFF).withOpacity(0.05),
+ // ],
+ // stops: [
+ // 0.1,
+ // 1,
+ // ],
+ // ),
+ // borderRadius: BorderRadius.circular(8),
+ // ),
+ // child: Stack(
+ // children: [
+ // Image.network(
+ // contentBytesController
+ // .contentBytesModel.data!.audio![index].image!,
+ // ),
+ // const Positioned(
+ // right: 5,
+ // top: 5,
+ // child: CircleAvatar(
+ // radius: 15,
+ // child: Icon(
+ // Icons.headphones,
+ // size: 20,
+ // ),
+ // ),
+ // ),
+ // ],
+ // ),
+ // ),
+ // const SizedBox(
+ // height: 10,
+ // ),
+ // Row(
+ // mainAxisAlignment: MainAxisAlignment.start,
+ // children: [
+ // SizedBox(
+ // width: 148.w,
+ // child: text14W500Overflow(
+ // contentBytesController
+ // .contentBytesModel.data!.audio![index].title!,
+ // ),
+ // ),
+ // ],
+ // )
+ // ],
+ // );
+ // },
+ // ),
+ // )
],
),
);
@@ -695,14 +799,14 @@ class _VideosState extends State {
Widget videoCard(Video video) {
return InkWell(
onTap: () {
- Get.to(() => PlayerWidget(), arguments: {
+ Get.to(() => const PlayerWidget(), arguments: {
"video_url": video.file,
});
},
child: commonGlassContainer(
borderradius: 8,
width: double.infinity,
- height: 300.h,
+ height: 320.h,
customWidget: Padding(
padding: EdgeInsets.symmetric(vertical: 10.h, horizontal: 10.w),
child: Column(
@@ -727,18 +831,20 @@ class _VideosState extends State {
sizedBoxHeight(20.h),
Row(
children: [
- CircleAvatar(
- radius: 23.r,
- backgroundImage: const AssetImage(
- 'assets/images/png/Ellipse 1494.png'),
- ),
+ // CircleAvatar(
+ // radius: 23.r,
+ // backgroundImage: const AssetImage(
+ // 'assets/images/png/Ellipse 1494.png'),
+ // ),
sizedBoxWidth(10.w),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
text18W500(video.title!),
+ text16W400(video.description!),
// sizedBoxHeight(10.h),
- text12W400_979797('20k views . 2 days ago'),
+ //text12W400_979797('20k views . 2 days ago'),
+ text12W400_979797('2 days ago'),
],
)
],
@@ -756,23 +862,23 @@ class _VideosState extends State {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
- Row(
- children: [
- const SizedBox(
- width: 295,
- child: CustomTextFormField(
- leadingIcon: Icon(Icons.search),
- ),
- ),
- SizedBox(
- width: 15.w,
- ),
- filter(),
- ],
- ),
- SizedBox(
- height: 10.h,
- ),
+ // Row(
+ // children: [
+ // const SizedBox(
+ // width: 295,
+ // child: CustomTextFormField(
+ // leadingIcon: Icon(Icons.search),
+ // ),
+ // ),
+ // SizedBox(
+ // width: 15.w,
+ // ),
+ // filter(),
+ // ],
+ // ),
+ // SizedBox(
+ // height: 10.h,
+ // ),
text22W600('Content Bytes'),
sizedBoxHeight(8.w),
text16W400_DADADA('The Beauty and Power of Video'),
@@ -808,64 +914,66 @@ class _VideosState extends State {
: videoCard(contentBytesController
.contentBytesModel.data!.video![1]),
sizedBoxHeight(15.h),
- text22W600("Reels"),
- sizedBoxHeight(25.h),
- Container(
- height: 500,
- child: GridView.builder(
- physics: const NeverScrollableScrollPhysics(),
- gridDelegate:
- const SliverGridDelegateWithFixedCrossAxisCount(
- mainAxisExtent: 215,
- crossAxisCount: 2, // number of items in each row
- mainAxisSpacing: 8.0, // spacing between rows
- crossAxisSpacing: 8.0, // spacing between columns
- ),
+ // text22W600("Reels"),
+ // sizedBoxHeight(25.h),
+ // Container(
+ // height: 500,
+ // child: GridView.builder(
+ // physics: const NeverScrollableScrollPhysics(),
+ // gridDelegate:
+ // const SliverGridDelegateWithFixedCrossAxisCount(
+ // mainAxisExtent: 215,
+ // crossAxisCount: 2, // number of items in each row
+ // mainAxisSpacing: 8.0, // spacing between rows
+ // crossAxisSpacing: 8.0, // spacing between columns
+ // ),
+
+ // itemCount: 4, // total number of items
+ // itemBuilder: (context, index) {
+ // return InkWell(
+ // onTap: () {
+ // Get.to(
+ // () => const Reels(),
+ // );
+ // },
+ // child: Container(
+ // decoration: BoxDecoration(
+ // gradient: LinearGradient(
+ // begin: Alignment.topLeft,
+ // end: Alignment.bottomRight,
+ // colors: [
+ // Colors.white.withOpacity(0.1),
+ // const Color(0xFFFFFFFF).withOpacity(0.05),
+ // ],
+ // stops: [
+ // 0.1,
+ // 1,
+ // ],
+ // ),
+ // borderRadius: BorderRadius.circular(8),
+ // ),
+ // child: Image.asset(widget.images[index]),
+ // ),
+ // );
+ // },
+ // ),
+ // ),
- itemCount: 4, // total number of items
- itemBuilder: (context, index) {
- return InkWell(
- onTap: () {
- Get.to(
- () => const Reels(),
- );
- },
- child: Container(
- decoration: BoxDecoration(
- gradient: LinearGradient(
- begin: Alignment.topLeft,
- end: Alignment.bottomRight,
- colors: [
- Colors.white.withOpacity(0.1),
- const Color(0xFFFFFFFF).withOpacity(0.05),
- ],
- stops: [
- 0.1,
- 1,
- ],
- ),
- borderRadius: BorderRadius.circular(8),
- ),
- child: Image.asset(widget.images[index]),
- ),
- );
- },
- ),
- ),
// sizedBoxHeight(10.h),
+
contentBytesController
.contentBytesModel.data!.video!.length <
3
? const SizedBox()
: ListView.builder(
- physics: NeverScrollableScrollPhysics(),
+ physics: const NeverScrollableScrollPhysics(),
itemCount: contentBytesController
.contentBytesModel.data!.video!.length -
2,
shrinkWrap: true,
itemBuilder: (ctx, index) {
return Container(
- margin: EdgeInsets.only(
+ margin: const EdgeInsets.only(
bottom: 20,
),
child: videoCard(contentBytesController
diff --git a/lib/view/Sidemenu/ContentByte/PlayerWidget.dart b/lib/view/Sidemenu/ContentByte/PlayerWidget.dart
index 6ff9eda..0d4bb05 100644
--- a/lib/view/Sidemenu/ContentByte/PlayerWidget.dart
+++ b/lib/view/Sidemenu/ContentByte/PlayerWidget.dart
@@ -13,7 +13,9 @@ class PlayerWidget extends StatefulWidget {
class _PlayerWidgetState extends State {
late VideoPlayerController videoPlayerController;
late ChewieController chewieController;
- var videoUrl = Get.arguments["video_url"];
+ var videoUrl = Get.arguments["video_url"] == ""
+ ? "https://player.vimeo.com/progressive_redirect/playback/930595309/rendition/360p/file.mp4?loc=external&signature=55ffa7ff72b807e1b3830cd6d308b092d4b1f82baadf6c20e7c235cd9a33bcdf"
+ : Get.arguments["video_url"];
@override
void initState() {
_initializePlayer();
@@ -41,6 +43,13 @@ class _PlayerWidgetState extends State {
looping: false);
}
+ @override
+ void dispose() {
+ videoPlayerController.dispose();
+ chewieController.dispose();
+ super.dispose();
+ }
+
@override
Widget build(BuildContext context) {
return videoPlayerController != null &&
diff --git a/lib/view/Sidemenu/ContentByte/read_pdf.dart b/lib/view/Sidemenu/ContentByte/read_pdf.dart
new file mode 100644
index 0000000..88c327c
--- /dev/null
+++ b/lib/view/Sidemenu/ContentByte/read_pdf.dart
@@ -0,0 +1,24 @@
+import 'package:flutter/material.dart';
+import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
+
+class ReadPDF extends StatelessWidget {
+ ReadPDF({
+ super.key,
+ required this.title,
+ required this.pdfUrfl,
+ });
+ String? title;
+ String? pdfUrfl;
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text(title!),
+ ),
+ body: SfPdfViewer.network(
+ 'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf',
+ ),
+ );
+ }
+}
diff --git a/lib/view/Sidemenu/FaqScreen.dart b/lib/view/Sidemenu/FaqScreen.dart
index 0532b1c..e7bbae1 100644
--- a/lib/view/Sidemenu/FaqScreen.dart
+++ b/lib/view/Sidemenu/FaqScreen.dart
@@ -1,7 +1,10 @@
+import 'dart:developer';
+
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart';
+import 'package:shared_preferences/shared_preferences.dart';
import 'package:traderscircuit/Utils/Common/CommonAppBar.dart';
import 'package:traderscircuit/Utils/Common/CustomTextFormField.dart';
import 'package:traderscircuit/Utils/Common/comonGlassmorphicContainer.dart';
@@ -11,6 +14,8 @@ import 'package:traderscircuit/model/FAQModel/faq_model.dart';
import 'package:traderscircuit/view/onBoarding/splashScreen1.dart';
import 'package:traderscircuit/view_model/FaqApi/faq_api.dart';
+Rx faqModel = FAQModel().obs;
+
class FaqScreen extends StatefulWidget {
const FaqScreen({super.key});
@@ -22,23 +27,29 @@ class _FaqScreenState extends State {
List categoryList = [];
RxBool isLoading = true.obs;
- FAQModel faqModel = FAQModel();
@override
void initState() {
+ getData();
FAQApi().getFAQData().then((value) {
- faqModel = FAQModel.fromJson(value.data);
- for (var a in faqModel.data!) {
+ faqModel.value = FAQModel.fromJson(value.data);
+ for (var a in faqModel.value.data!) {
categoryList.add(a.categoryName!);
}
isExpandedList = RxList.generate(
- faqModel.data![selectedIndex.value].faqQueAns!.length,
+ faqModel.value.data![selectedIndex.value].faqQueAns!.length,
(index) => index == 0);
isLoading.value = false;
});
super.initState();
}
+ String? token;
+ getData() async {
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+ token = prefs.getString('accessToken');
+ }
+
final selectedIndex = 0.obs;
late RxList isExpandedList;
@@ -95,6 +106,7 @@ class _FaqScreenState extends State {
selectedIndex.value = index;
isExpandedList = RxList.generate(
faqModel
+ .value
.data![selectedIndex.value]
.faqQueAns!
.length,
@@ -114,16 +126,33 @@ class _FaqScreenState extends State {
Obx(() {
return Column(
children: List.generate(
- faqModel.data![selectedIndex.value]
- .faqQueAns!.length, (index) {
+ faqModel
+ .value
+ .data![selectedIndex.value]
+ .faqQueAns!
+ .length, (index) {
return customExpandableItem(
+ index: index,
+ selectedIndex: selectedIndex.value,
+ faqModel1: faqModel.value,
isExpanded: isExpandedList[index],
- title: faqModel.data![selectedIndex.value]
- .faqQueAns![index].faqQuestion!,
- content: faqModel.data![selectedIndex.value]
- .faqQueAns![index].faqAnswer!,
+ title: faqModel
+ .value
+ .data![selectedIndex.value]
+ .faqQueAns![index]
+ .faqQuestion!,
+ content: faqModel
+ .value
+ .data![selectedIndex.value]
+ .faqQueAns![index]
+ .faqAnswer!,
toggleExpansion: () =>
toggleExpansion(index),
+ faqId: faqModel
+ .value
+ .data![selectedIndex.value]
+ .faqQueAns![index]
+ .id!,
);
}));
}),
@@ -144,13 +173,21 @@ class _FaqScreenState extends State {
borderRadius: BorderRadius.circular(5),
color: const Color(0XFF3F0502),
border: Border.all(color: const Color(0xFF9A0000), width: 1)),
- child: Center(child: text16W500(text)),
+ child: Center(
+ child: Padding(
+ padding: const EdgeInsets.symmetric(vertical: 8),
+ child: FittedBox(child: text16W500(text)),
+ )),
)
: commonGlassContainer(
width: 136.w,
height: 38.h,
borderradius: 5,
- customWidget: Center(child: text16W400(text)),
+ customWidget: Center(
+ child: Padding(
+ padding: const EdgeInsets.symmetric(vertical: 9),
+ child: FittedBox(child: text16W400(text)),
+ )),
);
});
}
@@ -171,6 +208,10 @@ class _FaqScreenState extends State {
required String title,
required String content,
required VoidCallback toggleExpansion,
+ required int faqId,
+ required FAQModel faqModel1,
+ required int selectedIndex,
+ required int index,
}) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
@@ -230,58 +271,125 @@ class _FaqScreenState extends State {
child: Text(
content,
style: TextStyle(
-
- color: Color(0xFFFFFFFF),
+ color: const Color(0xFFFFFFFF),
fontFamily: 'hiragino',
-
-
fontSize: 14.sp,
fontWeight: FontWeight.w400,
),
),
),
),
- sizedBoxHeight(12.h),
- commonGlassContainer(
- width: double.infinity,
- height: 65.h,
- borderradius: 8,
- customWidget: Padding(
- padding: EdgeInsets.only(right: 8.w, left: 13.w),
- child: Center(
- child: Row(children: [
- Text(
- 'Was this answer helpful?',
- style: TextStyle(
- fontFamily: 'hiragino',
- fontSize: 16.sp,
- fontWeight: FontWeight.w500,
- color: Colors.white,
- ),
- ),
- const Spacer(),
- Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- text16W500('Yes'),
- sizedBoxWidth(2.w),
- SvgPicture.asset(
- 'assets/images/svg/thumbs-up.svg'),
- sizedBoxWidth(8.w),
- text16W500('No'),
- sizedBoxWidth(2.w),
- Column(
- mainAxisAlignment: MainAxisAlignment.center,
+ token == null || token!.isEmpty
+ ? const SizedBox()
+ : sizedBoxHeight(12.h),
+ token == null || token!.isEmpty
+ ? const SizedBox()
+ : commonGlassContainer(
+ width: double.infinity,
+ height: 65.h,
+ borderradius: 8,
+ customWidget: Padding(
+ padding: EdgeInsets.only(right: 8.w, left: 13.w),
+ child: Center(
+ child: Row(children: [
+ Text(
+ 'Was this answer helpful?',
+ style: TextStyle(
+ fontFamily: 'hiragino',
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w500,
+ color: Colors.white,
+ ),
+ ),
+ const Spacer(),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
children: [
- sizedBoxHeight(5.h),
- SvgPicture.asset(
- 'assets/images/svg/thumbs-down.svg'),
+ InkWell(
+ onTap: () {
+ FAQApi()
+ .updaeFAQLikeDisklikeData(faqId, 1)
+ .then((value) {
+ FAQApi().getFAQData().then((value) {
+ faqModel.value =
+ FAQModel.fromJson(value.data);
+
+ setState(() {});
+ });
+ });
+ },
+ child: Row(
+ children: [
+ text16W500('Yes'),
+ sizedBoxWidth(2.w),
+ (faqModel
+ .value
+ .data![selectedIndex]
+ .faqQueAns![index]
+ .userLikes!
+ .isNotEmpty &&
+ faqModel
+ .value
+ .data![selectedIndex]
+ .faqQueAns![index]
+ .userLikes![0]
+ .status! ==
+ 1)
+ ? SvgPicture.asset(
+ 'assets/images/svg/filled_thumb_up.svg')
+ : SvgPicture.asset(
+ 'assets/images/svg/thumbs-up.svg'),
+ ],
+ ),
+ ),
+ sizedBoxWidth(8.w),
+ InkWell(
+ onTap: () {
+ FAQApi()
+ .updaeFAQLikeDisklikeData(faqId, 0)
+ .then((value) {
+ FAQApi().getFAQData().then((value) {
+ faqModel.value =
+ FAQModel.fromJson(value.data);
+ });
+ });
+ },
+ child: Row(
+ children: [
+ text16W500('No'),
+ sizedBoxWidth(2.w),
+ Column(
+ mainAxisAlignment:
+ MainAxisAlignment.center,
+ children: [
+ sizedBoxHeight(5.h),
+ (faqModel
+ .value
+ .data![selectedIndex]
+ .faqQueAns![index]
+ .userLikes!
+ .isNotEmpty &&
+ faqModel
+ .value
+ .data![
+ selectedIndex]
+ .faqQueAns![index]
+ .userLikes![0]
+ .status! ==
+ 0)
+ ? SvgPicture.asset(
+ 'assets/images/svg/filled_thumb_down.svg')
+ : SvgPicture.asset(
+ 'assets/images/svg/thumbs-down.svg'),
+ ],
+ )
+ ],
+ ),
+ )
],
- )
- ],
- )
- ]),
- )))
+ ),
+ ]),
+ )))
],
),
),
diff --git a/lib/view/onBoarding/splashScreen.dart b/lib/view/onBoarding/splashScreen.dart
index a5ffe5f..049f6ca 100644
--- a/lib/view/onBoarding/splashScreen.dart
+++ b/lib/view/onBoarding/splashScreen.dart
@@ -9,6 +9,8 @@ import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:traderscircuit/resources/routes/route_name.dart';
+import '../../Utils/Common/noInternet.dart';
+
class SplashScreen extends StatefulWidget {
const SplashScreen({super.key});
@@ -44,52 +46,55 @@ class _SplashScreenState extends State
void initState() {
super.initState();
checkInternet();
- log(_connectionStatus.toString());
- Future.delayed(Duration(seconds: 2), () async {
- Get.toNamed(RouteName.sliderscreen1);
- // if (_connectionStatus == ConnectivityResult.none) {
- // var result = await Get.to(NoInternet());
- // if (result != null && result) {
- // Timer(const Duration(seconds: 1), () async {
- // SharedPreferences prefs = await SharedPreferences.getInstance();
- // token = prefs.getString('token');
- // myusername = prefs.getString('name');
- // phonenumber = prefs.getString('contact_number');
- // OnBoard = prefs.getBool('OnBoard') ?? false;
- // if (OnBoard == false) {
- // Get.toNamed(RouteName.sliderscreen1);
- // } else {
- // if (token == null || token!.isEmpty) {
- // Get.offAndToNamed(RouteName.loginScreen);
- // } else {
- // GetProfile().GetProfileAPI().then((value) {
- // Get.toNamed(RouteName.mainScreen, arguments: 0);
- // });
- // }
- // }
- // });
- // }
- // } else {
- // Timer(const Duration(seconds: 2), () async {
- // SharedPreferences prefs = await SharedPreferences.getInstance();
- // token = prefs.getString('token');
- // myusername = prefs.getString('name');
- // phonenumber = prefs.getString('contact_number');
- // OnBoard = prefs.getBool('OnBoard') ?? false;
- // if (OnBoard == false) {
- // Get.toNamed(RouteName.sliderscreen1);
- // } else {
- // if (token == null || token!.isEmpty) {
- // Get.offAndToNamed(RouteName.loginScreen);
- // } else {
- // GetProfile().GetProfileAPI().then((value) {
- // Get.toNamed(RouteName.mainScreen, arguments: 0);
- // });
- // }
- // }
- // });
- // }
+ Future.delayed(Duration(seconds: 2), () async {
+ if (_connectionStatus == ConnectivityResult.none) {
+ var result = await Get.to(NoInternet());
+ if (result != null && result) {
+ Timer(const Duration(seconds: 1), () async {
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+ var token = prefs.getString('accessToken');
+ // myusername = prefs.getString('name');
+ // phonenumber = prefs.getString('contact_number');
+ // OnBoard = prefs.getBool('OnBoard') ?? false;
+ // if (OnBoard == false) {
+ // Get.toNamed(RouteName.sliderscreen1);
+ // }
+ // else {
+ if (token == null || token!.isEmpty) {
+ Get.offAndToNamed(RouteName.loginscreen);
+ } else {
+ // GetProfile().GetProfileAPI().then((value) {
+ // Get.toNamed(RouteName.mainScreen, arguments: 0);
+ // });
+ Get.toNamed(RouteName.mainscreen);
+ }
+ // }
+ });
+ }
+ } else {
+ Timer(const Duration(seconds: 2), () async {
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+
+ var token = prefs.getString('accessToken');
+ // myusername = prefs.getString('name');
+ // phonenumber = prefs.getString('contact_number');
+ // OnBoard = prefs.getBool('OnBoard') ?? false;
+ // if (OnBoard == false) {
+ // Get.toNamed(RouteName.sliderscreen1);
+ // }
+ // else {
+ if (token == null || token!.isEmpty) {
+ Get.offAndToNamed(RouteName.loginscreen);
+ } else {
+ // GetProfile().GetProfileAPI().then((value) {
+ // Get.toNamed(RouteName.mainScreen, arguments: 0);
+ // });
+ Get.toNamed(RouteName.mainscreen);
+ }
+ // }
+ });
+ }
});
// for scaleTansition
_scaleController = AnimationController(
@@ -131,7 +136,8 @@ class _SplashScreenState extends State
scale: _scaleAnimation,
child: Text(
"Traders Circuit",
- style: TextStyle(fontFamily: 'hiragino',
+ style: TextStyle(
+ fontFamily: 'hiragino',
fontSize: 50,
fontWeight: FontWeight.w600,
color: Colors.white),
diff --git a/lib/view_model/FaqApi/faq_api.dart b/lib/view_model/FaqApi/faq_api.dart
index 4fc4a4e..9a8ab86 100644
--- a/lib/view_model/FaqApi/faq_api.dart
+++ b/lib/view_model/FaqApi/faq_api.dart
@@ -3,10 +3,15 @@ import 'dart:developer';
import '../../Utils/api_urls.dart';
import '../../Utils/base_manager.dart';
import '../../data/network/network_api_services.dart';
+import 'package:shared_preferences/shared_preferences.dart';
class FAQApi {
Future> getFAQData() async {
- final response = await NetworkApiServices().getApi(
+ SharedPreferences prefs = await SharedPreferences.getInstance();
+ String? token = prefs.getString('accessToken');
+
+ final response = await NetworkApiServices().postApi(
+ token == null || token.isEmpty ? {} : {"token": token},
ApiUrls.faqApi,
);
log(response.data.toString());
@@ -22,4 +27,27 @@ class FAQApi {
}
return response;
}
+
+ Future> updaeFAQLikeDisklikeData(
+ int faqId, int status) async {
+ final response = await NetworkApiServices().postApi(
+ {
+ "faq_id": faqId,
+ "status": status,
+ },
+ ApiUrls.faqLikeDislikeApi,
+ );
+ log(response.data.toString());
+ if (response.status == ResponseStatus.SUCCESS) {
+ Map responseData =
+ Map.from(response.data);
+ if (responseData['status'] == "success") {
+ return response;
+ } else {
+ return ResponseData(
+ responseData['message'], ResponseStatus.FAILED);
+ }
+ }
+ return response;
+ }
}
diff --git a/pubspec.lock b/pubspec.lock
index 0cdab15..2f2e831 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -33,6 +33,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.11.0"
+ audio_session:
+ dependency: transitive
+ description:
+ name: audio_session
+ sha256: a49af9981eec5d7cd73b37bacb6ee73f8143a6a9f9bd5b6021e6c346b9b6cf4e
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.1.19"
+ audio_video_progress_bar:
+ dependency: "direct main"
+ description:
+ name: audio_video_progress_bar
+ sha256: ccc7d7b83d2a16c52d4a7fb332faabd1baa053fb0e4c16815aefd3945ab33b81
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.2"
boolean_selector:
dependency: transitive
description:
@@ -161,6 +177,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.10"
+ device_info_plus:
+ dependency: transitive
+ description:
+ name: device_info_plus
+ sha256: f52ab3b76b36ede4d135aab80194df8925b553686f0fa12226b4e2d658e45903
+ url: "https://pub.dev"
+ source: hosted
+ version: "8.2.2"
+ device_info_plus_platform_interface:
+ dependency: transitive
+ description:
+ name: device_info_plus_platform_interface
+ sha256: d3b01d5868b50ae571cd1dc6e502fc94d956b665756180f7b16ead09e836fd64
+ url: "https://pub.dev"
+ source: hosted
+ version: "7.0.0"
dio:
dependency: "direct main"
description:
@@ -404,10 +436,10 @@ packages:
dependency: transitive
description:
name: http
- sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
+ sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2"
url: "https://pub.dev"
source: hosted
- version: "1.1.0"
+ version: "0.13.6"
http_parser:
dependency: transitive
description:
@@ -420,26 +452,26 @@ packages:
dependency: "direct main"
description:
name: image_cropper
- sha256: f4bad5ed2dfff5a7ce0dfbad545b46a945c702bb6182a921488ef01ba7693111
+ sha256: "542c3453109d16bcc388e43ae2276044d2cd6a6d20c68bdcff2c94ab9363ea15"
url: "https://pub.dev"
source: hosted
- version: "5.0.1"
+ version: "4.0.1"
image_cropper_for_web:
dependency: transitive
description:
name: image_cropper_for_web
- sha256: "865d798b5c9d826f1185b32e5d0018c4183ddb77b7b82a931e1a06aa3b74974e"
+ sha256: "89c936aa772a35b69ca67b78049ae9fa163a4fb8da2f6dee3893db8883fb49d2"
url: "https://pub.dev"
source: hosted
- version: "3.0.0"
+ version: "2.0.0"
image_cropper_platform_interface:
dependency: transitive
description:
name: image_cropper_platform_interface
- sha256: ee160d686422272aa306125f3b6fb1c1894d9b87a5e20ed33fa008e7285da11e
+ sha256: b232175c132b2f7ede3e1f101652bcd635cb4079a77c6dded8e6d32e6578d685
url: "https://pub.dev"
source: hosted
- version: "5.0.0"
+ version: "4.0.0"
image_picker:
dependency: "direct main"
description:
@@ -516,10 +548,10 @@ packages:
dependency: transitive
description:
name: intl
- sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
+ sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
- version: "0.19.0"
+ version: "0.18.1"
js:
dependency: transitive
description:
@@ -528,6 +560,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.6.7"
+ just_audio:
+ dependency: "direct main"
+ description:
+ name: just_audio
+ sha256: b7cb6bbf3750caa924d03f432ba401ec300fd90936b3f73a9b33d58b1e96286b
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.9.37"
+ just_audio_platform_interface:
+ dependency: transitive
+ description:
+ name: just_audio_platform_interface
+ sha256: c3dee0014248c97c91fe6299edb73dc4d6c6930a2f4f713579cd692d9e47f4a1
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.2.2"
+ just_audio_web:
+ dependency: transitive
+ description:
+ name: just_audio_web
+ sha256: "134356b0fe3d898293102b33b5fd618831ffdc72bb7a1b726140abdf22772b70"
+ url: "https://pub.dev"
+ source: hosted
+ version: "0.4.9"
lints:
dependency: transitive
description:
@@ -540,10 +596,10 @@ packages:
dependency: "direct main"
description:
name: local_auth
- sha256: "280421b416b32de31405b0a25c3bd42dfcef2538dfbb20c03019e02a5ed55ed0"
+ sha256: "27679ed8e0d7daab2357db6bb7076359e083a56b295c0c59723845301da6aed9"
url: "https://pub.dev"
source: hosted
- version: "2.2.0"
+ version: "2.1.8"
local_auth_android:
dependency: transitive
description:
@@ -552,14 +608,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.37"
- local_auth_darwin:
+ local_auth_ios:
dependency: transitive
description:
- name: local_auth_darwin
- sha256: "33381a15b0de2279523eca694089393bb146baebdce72a404555d03174ebc1e9"
+ name: local_auth_ios
+ sha256: eb283b530029b334698918f1e282d4483737cbca972ff21b9193be3d6de8e2b8
url: "https://pub.dev"
source: hosted
- version: "1.2.2"
+ version: "1.1.6"
local_auth_platform_interface:
dependency: transitive
description:
@@ -869,14 +925,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.10.0"
- sprintf:
- dependency: transitive
- description:
- name: sprintf
- sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
- url: "https://pub.dev"
- source: hosted
- version: "7.0.0"
sqflite:
dependency: transitive
description:
@@ -917,6 +965,62 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
+ syncfusion_flutter_core:
+ dependency: transitive
+ description:
+ name: syncfusion_flutter_core
+ sha256: "8db8f55c77f56968681447d3837c10f27a9e861e238a898fda116c7531def979"
+ url: "https://pub.dev"
+ source: hosted
+ version: "21.2.10"
+ syncfusion_flutter_pdf:
+ dependency: transitive
+ description:
+ name: syncfusion_flutter_pdf
+ sha256: e97daea47f9ac4cf25cc8fc11a0475580ad9c592056d9c2bdc809c73e276decf
+ url: "https://pub.dev"
+ source: hosted
+ version: "21.2.10"
+ syncfusion_flutter_pdfviewer:
+ dependency: "direct main"
+ description:
+ name: syncfusion_flutter_pdfviewer
+ sha256: fdd2ff565cd42247b8e86e26304329bae924fdfe8ddc1f4a3a264916f6c1ff1f
+ url: "https://pub.dev"
+ source: hosted
+ version: "21.2.10"
+ syncfusion_pdfviewer_macos:
+ dependency: transitive
+ description:
+ name: syncfusion_pdfviewer_macos
+ sha256: "8cc925cae532c0fa17e849165796d962107f45b86e66ee334dcaabf6b7305c82"
+ url: "https://pub.dev"
+ source: hosted
+ version: "21.2.10"
+ syncfusion_pdfviewer_platform_interface:
+ dependency: transitive
+ description:
+ name: syncfusion_pdfviewer_platform_interface
+ sha256: "08039ecdb8f79454fb367c6bf5a833846a666039415d2b5d76a7e59a5b3ff710"
+ url: "https://pub.dev"
+ source: hosted
+ version: "21.2.10"
+ syncfusion_pdfviewer_web:
+ dependency: transitive
+ description:
+ name: syncfusion_pdfviewer_web
+ sha256: "8e5ed0d313a1aa3869e4f2e8d079bc9bfa37ce79d91be7bb328e456f37b7995f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "21.2.10"
+ syncfusion_pdfviewer_windows:
+ dependency: transitive
+ description:
+ name: syncfusion_pdfviewer_windows
+ sha256: "3e93f281135fb0562f7e6c343d2db741cf3cbd78c5b04884eef9af414408bc77"
+ url: "https://pub.dev"
+ source: hosted
+ version: "21.2.10"
synchronized:
dependency: transitive
description:
@@ -949,6 +1053,30 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.2"
+ url_launcher:
+ dependency: transitive
+ description:
+ name: url_launcher
+ sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.2.4"
+ url_launcher_android:
+ dependency: transitive
+ description:
+ name: url_launcher_android
+ sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.3.0"
+ url_launcher_ios:
+ dependency: transitive
+ description:
+ name: url_launcher_ios
+ sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.2.4"
url_launcher_linux:
dependency: transitive
description:
@@ -957,6 +1085,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.1.1"
+ url_launcher_macos:
+ dependency: transitive
+ description:
+ name: url_launcher_macos
+ sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.0"
url_launcher_platform_interface:
dependency: transitive
description:
@@ -985,10 +1121,10 @@ packages:
dependency: transitive
description:
name: uuid
- sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f"
+ sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313"
url: "https://pub.dev"
source: hosted
- version: "4.2.2"
+ version: "3.0.7"
vector_graphics:
dependency: transitive
description:
@@ -1143,5 +1279,7 @@ packages:
source: hosted
version: "6.3.0"
sdks:
+
dart: ">=3.2.3 <4.0.0"
flutter: ">=3.16.6"
+
diff --git a/pubspec.yaml b/pubspec.yaml
index 6edff00..d128e7b 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -28,7 +28,7 @@ dependencies:
gap: ^3.0.1
image_picker: ^1.0.7
dotted_border: ^2.1.0
- image_cropper: ^5.0.1
+ image_cropper:
file_picker: any
lottie: ^2.7.0
chewie: ^1.5.0
@@ -40,11 +40,13 @@ dependencies:
dio: ^5.1.2
expansion_tile_group: ^1.2.4
- local_auth: ^2.2.0
+ local_auth:
scgateway_flutter_plugin: ^2.3.1
async: ^2.4.1
-
+ just_audio: ^0.9.37
+ audio_video_progress_bar: ^2.0.2
+ syncfusion_flutter_pdfviewer:
dev_dependencies:
flutter_test: