Commit 6f61743479801b967bad9cbdad2f4daaab64484f

Authored by liangchengyou
1 parent 2a427e12

feat:磨耳朵/视频跟读列表页接口调整

lib/common/request/dao/home_dao.dart
@@ -22,9 +22,6 @@ class HomeDao { @@ -22,9 +22,6 @@ class HomeDao {
22 Apis.courseLesson, 22 Apis.courseLesson,
23 queryParameters: mapData 23 queryParameters: mapData
24 ); 24 );
25 - if (kDebugMode) {  
26 - print('>>>>>>>>>${data.runtimeType}');  
27 - }  
28 return data; 25 return data;
29 } 26 }
30 } 27 }
lib/common/request/dao/listen_dao.dart
1 import 'package:wow_english/common/request/apis.dart'; 1 import 'package:wow_english/common/request/apis.dart';
2 import 'package:wow_english/common/request/request_client.dart'; 2 import 'package:wow_english/common/request/request_client.dart';
  3 +import 'package:wow_english/models/follow_read_entity.dart';
  4 +import 'package:wow_english/models/listen_entity.dart';
3 5
4 class ListenDao { 6 class ListenDao {
5 /// 磨耳朵 7 /// 磨耳朵
6 - static Future listen() async {  
7 - var data = await requestClient.get(Apis.ears); 8 + static Future<List<ListenEntity?>?> listen() async {
  9 + var data = await requestClient.get<List<ListenEntity?>>(Apis.ears);
  10 + return data;
  11 + }
  12 +
  13 + ///视频跟读
  14 + static Future<List<FollowReadEntity?>?> followRead() async {
  15 + var data = await requestClient.get<List<FollowReadEntity?>>(Apis.followRead);
8 return data; 16 return data;
9 } 17 }
10 } 18 }
11 \ No newline at end of file 19 \ No newline at end of file
lib/common/widgets/ow_image_widget.dart 0 → 100644
  1 +import 'package:cached_network_image/cached_network_image.dart';
  2 +import 'package:flutter/material.dart';
  3 +
  4 +class OwImageWidget extends StatelessWidget {
  5 + const OwImageWidget({super.key, this.width, this.height, required this.name, this.fit});
  6 + final double? width;
  7 + final double? height;
  8 + final BoxFit? fit;
  9 + final String name;
  10 +
  11 + @override
  12 + Widget build(BuildContext context) {
  13 + if (name.isEmpty) {
  14 + return SizedBox(
  15 + height: height,
  16 + width: width,
  17 + );
  18 + }
  19 + return name.contains('http')?
  20 + CachedNetworkImage(
  21 + imageUrl: name,
  22 + height: height,
  23 + width: width,
  24 + fit: fit,
  25 + ):Image.asset(
  26 + name,
  27 + height: height,
  28 + width: width,
  29 + fit: fit,
  30 + );
  31 + }
  32 +}
0 \ No newline at end of file 33 \ No newline at end of file
lib/generated/json/base/json_convert_content.dart
@@ -4,6 +4,7 @@ @@ -4,6 +4,7 @@
4 4
5 // This file is automatically generated. DO NOT EDIT, all your changes would be lost. 5 // This file is automatically generated. DO NOT EDIT, all your changes would be lost.
6 import 'package:flutter/material.dart' show debugPrint; 6 import 'package:flutter/material.dart' show debugPrint;
  7 +import 'package:wow_english/models/follow_read_entity.dart';
7 import 'package:wow_english/models/course_entity.dart'; 8 import 'package:wow_english/models/course_entity.dart';
8 import 'package:wow_english/models/course_module_entity.dart'; 9 import 'package:wow_english/models/course_module_entity.dart';
9 import 'package:wow_english/models/listen_entity.dart'; 10 import 'package:wow_english/models/listen_entity.dart';
@@ -15,6 +16,7 @@ typedef EnumConvertFunction&lt;T&gt; = T Function(String value); @@ -15,6 +16,7 @@ typedef EnumConvertFunction&lt;T&gt; = T Function(String value);
15 16
16 class JsonConvert { 17 class JsonConvert {
17 static final Map<String, JsonConvertFunction> convertFuncMap = { 18 static final Map<String, JsonConvertFunction> convertFuncMap = {
  19 + (FollowReadEntity).toString(): FollowReadEntity.fromJson,
18 (CourseEntity).toString(): CourseEntity.fromJson, 20 (CourseEntity).toString(): CourseEntity.fromJson,
19 (CourseCourseLessons).toString(): CourseCourseLessons.fromJson, 21 (CourseCourseLessons).toString(): CourseCourseLessons.fromJson,
20 (CourseModuleEntity).toString(): CourseModuleEntity.fromJson, 22 (CourseModuleEntity).toString(): CourseModuleEntity.fromJson,
@@ -98,6 +100,9 @@ List&lt;T&gt;? convertListNotNull&lt;T&gt;(dynamic value, {EnumConvertFunction? enumConvert} @@ -98,6 +100,9 @@ List&lt;T&gt;? convertListNotNull&lt;T&gt;(dynamic value, {EnumConvertFunction? enumConvert}
98 100
99 //list is returned by type 101 //list is returned by type
100 static M? _getListChildType<M>(List<Map<String, dynamic>> data) { 102 static M? _getListChildType<M>(List<Map<String, dynamic>> data) {
  103 + if(<FollowReadEntity>[] is M){
  104 + return data.map<FollowReadEntity>((Map<String, dynamic> e) => FollowReadEntity.fromJson(e)).toList() as M;
  105 + }
101 if(<CourseEntity>[] is M){ 106 if(<CourseEntity>[] is M){
102 return data.map<CourseEntity>((Map<String, dynamic> e) => CourseEntity.fromJson(e)).toList() as M; 107 return data.map<CourseEntity>((Map<String, dynamic> e) => CourseEntity.fromJson(e)).toList() as M;
103 } 108 }
lib/generated/json/follow_read_entity.g.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_convert_content.dart';
  2 +import 'package:wow_english/models/follow_read_entity.dart';
  3 +
  4 +FollowReadEntity $FollowReadEntityFromJson(Map<String, dynamic> json) {
  5 + final FollowReadEntity followReadEntity = FollowReadEntity();
  6 + final String? coverUrl = jsonConvert.convert<String>(json['coverUrl']);
  7 + if (coverUrl != null) {
  8 + followReadEntity.coverUrl = coverUrl;
  9 + }
  10 + final String? createTime = jsonConvert.convert<String>(json['createTime']);
  11 + if (createTime != null) {
  12 + followReadEntity.createTime = createTime;
  13 + }
  14 + final String? deleted = jsonConvert.convert<String>(json['deleted']);
  15 + if (deleted != null) {
  16 + followReadEntity.deleted = deleted;
  17 + }
  18 + final String? id = jsonConvert.convert<String>(json['id']);
  19 + if (id != null) {
  20 + followReadEntity.id = id;
  21 + }
  22 + final bool? lock = jsonConvert.convert<bool>(json['lock']);
  23 + if (lock != null) {
  24 + followReadEntity.lock = lock;
  25 + }
  26 + final String? modifyTime = jsonConvert.convert<String>(json['modifyTime']);
  27 + if (modifyTime != null) {
  28 + followReadEntity.modifyTime = modifyTime;
  29 + }
  30 + final int? sortOrder = jsonConvert.convert<int>(json['sortOrder']);
  31 + if (sortOrder != null) {
  32 + followReadEntity.sortOrder = sortOrder;
  33 + }
  34 + final int? star = jsonConvert.convert<int>(json['star']);
  35 + if (star != null) {
  36 + followReadEntity.star = star;
  37 + }
  38 + final int? status = jsonConvert.convert<int>(json['status']);
  39 + if (status != null) {
  40 + followReadEntity.status = status;
  41 + }
  42 + final String? title = jsonConvert.convert<String>(json['title']);
  43 + if (title != null) {
  44 + followReadEntity.title = title;
  45 + }
  46 + final int? videoTotal = jsonConvert.convert<int>(json['videoTotal']);
  47 + if (videoTotal != null) {
  48 + followReadEntity.videoTotal = videoTotal;
  49 + }
  50 + return followReadEntity;
  51 +}
  52 +
  53 +Map<String, dynamic> $FollowReadEntityToJson(FollowReadEntity entity) {
  54 + final Map<String, dynamic> data = <String, dynamic>{};
  55 + data['coverUrl'] = entity.coverUrl;
  56 + data['createTime'] = entity.createTime;
  57 + data['deleted'] = entity.deleted;
  58 + data['id'] = entity.id;
  59 + data['lock'] = entity.lock;
  60 + data['modifyTime'] = entity.modifyTime;
  61 + data['sortOrder'] = entity.sortOrder;
  62 + data['star'] = entity.star;
  63 + data['status'] = entity.status;
  64 + data['title'] = entity.title;
  65 + data['videoTotal'] = entity.videoTotal;
  66 + return data;
  67 +}
0 \ No newline at end of file 68 \ No newline at end of file
lib/models/follow_read_entity.dart 0 → 100644
  1 +import 'package:wow_english/generated/json/base/json_field.dart';
  2 +import 'package:wow_english/generated/json/follow_read_entity.g.dart';
  3 +import 'dart:convert';
  4 +
  5 +@JsonSerializable()
  6 +class FollowReadEntity {
  7 + String? coverUrl;
  8 + String? createTime;
  9 + String? deleted;
  10 + String? id;
  11 + bool? lock;
  12 + String? modifyTime;
  13 + int? sortOrder;
  14 + int? star;
  15 + int? status;
  16 + String? title;
  17 + int? videoTotal;
  18 +
  19 + FollowReadEntity();
  20 +
  21 + factory FollowReadEntity.fromJson(Map<String, dynamic> json) => $FollowReadEntityFromJson(json);
  22 +
  23 + Map<String, dynamic> toJson() => $FollowReadEntityToJson(this);
  24 +
  25 + @override
  26 + String toString() {
  27 + return jsonEncode(this);
  28 + }
  29 +}
0 \ No newline at end of file 30 \ No newline at end of file
lib/pages/home/home_page.dart
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 2 import 'package:flutter_bloc/flutter_bloc.dart';
  3 +import 'package:flutter_easyloading/flutter_easyloading.dart';
3 import 'package:flutter_screenutil/flutter_screenutil.dart'; 4 import 'package:flutter_screenutil/flutter_screenutil.dart';
4 import 'package:wow_english/common/extension/string_extension.dart'; 5 import 'package:wow_english/common/extension/string_extension.dart';
5 import 'package:wow_english/models/course_entity.dart'; 6 import 'package:wow_english/models/course_entity.dart';
@@ -75,15 +76,30 @@ class _HomePageView extends StatelessWidget { @@ -75,15 +76,30 @@ class _HomePageView extends StatelessWidget {
75 itemCount: bloc.modelData?.totalCourseLesson, 76 itemCount: bloc.modelData?.totalCourseLesson,
76 scrollDirection: Axis.horizontal, 77 scrollDirection: Axis.horizontal,
77 itemBuilder: (BuildContext context, int index){ 78 itemBuilder: (BuildContext context, int index){
78 - String? title = bloc.modelData?.courseLessons?[index]?.name;  
79 CourseCourseLessons? data = bloc.modelData?.courseLessons?[index]; 79 CourseCourseLessons? data = bloc.modelData?.courseLessons?[index];
80 if (data?.courseType == 5) {//彩蛋 80 if (data?.courseType == 5) {//彩蛋
81 - return HomeBoundsItem(  
82 - imageUrl: data?.coverUrl, 81 + return GestureDetector(
  82 + onTap: (){
  83 + if (data!.lock!) {
  84 + return;
  85 + }
  86 + EasyLoading.showToast('点击事件');
  87 + },
  88 + child: HomeBoundsItem(
  89 + imageUrl: data?.coverUrl,
  90 + ),
83 ); 91 );
84 } else { 92 } else {
85 - return HomeVideoItem(  
86 - lessons: data, 93 + return GestureDetector(
  94 + onTap: () {
  95 + if (data!.lock!) {
  96 + return;
  97 + }
  98 + EasyLoading.showToast('点击事件');
  99 + },
  100 + child: HomeVideoItem(
  101 + lessons: data,
  102 + ),
87 ); 103 );
88 } 104 }
89 }) 105 })
lib/pages/home/widgets/home_bouns_item.dart
1 import 'package:flutter/cupertino.dart'; 1 import 'package:flutter/cupertino.dart';
2 import 'package:flutter_screenutil/flutter_screenutil.dart'; 2 import 'package:flutter_screenutil/flutter_screenutil.dart';
  3 +import 'package:wow_english/common/widgets/ow_image_widget.dart';
3 4
4 class HomeBoundsItem extends StatelessWidget { 5 class HomeBoundsItem extends StatelessWidget {
5 const HomeBoundsItem({super.key, this.imageUrl}); 6 const HomeBoundsItem({super.key, this.imageUrl});
@@ -11,7 +12,7 @@ class HomeBoundsItem extends StatelessWidget { @@ -11,7 +12,7 @@ class HomeBoundsItem extends StatelessWidget {
11 return SizedBox( 12 return SizedBox(
12 height: 207.h, 13 height: 207.h,
13 width: 169.w, 14 width: 169.w,
14 - child: Image.network(imageUrl??''), 15 + child: OwImageWidget(name:imageUrl??''),
15 ); 16 );
16 } 17 }
17 } 18 }
18 \ No newline at end of file 19 \ No newline at end of file
lib/pages/home/widgets/home_lesson_item_widget.dart deleted
1 -import 'package:flutter/material.dart';  
2 -import 'package:flutter_screenutil/flutter_screenutil.dart';  
3 -  
4 -class HomeLessonItem extends StatelessWidget {  
5 - const HomeLessonItem({super.key});  
6 -  
7 - @override  
8 - Widget build(BuildContext context) {  
9 - return SizedBox(  
10 - width: 200,  
11 - child: ListView.builder(  
12 - itemCount: 5,  
13 - scrollDirection: Axis.horizontal,  
14 - physics: const NeverScrollableScrollPhysics(),  
15 - itemBuilder: (BuildContext context,int index){  
16 - return Padding(  
17 - padding: EdgeInsets.symmetric(horizontal: 4.w),  
18 - child: Image.network(  
19 - 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Faa1c2213-820a-4223-8757-5f8cee318a28%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1688713226&t=192b18a613683bcdc5bd76f65c9ff032',  
20 - width: 40,  
21 - fit: BoxFit.fitHeight,  
22 - ),  
23 - );  
24 - }),  
25 - );  
26 - }  
27 -}  
28 \ No newline at end of file 0 \ No newline at end of file
lib/pages/home/widgets/home_tab_header_widget.dart
@@ -117,14 +117,14 @@ class HomeTabHeaderWidget extends StatelessWidget { @@ -117,14 +117,14 @@ class HomeTabHeaderWidget extends StatelessWidget {
117 }, 117 },
118 icon: Image.asset('listen'.assetPng) 118 icon: Image.asset('listen'.assetPng)
119 ), 119 ),
120 - IconButton(  
121 - onPressed: (){  
122 - if(actionTap != null) {  
123 - actionTap!(HeaderActionType.shop);  
124 - }  
125 - },  
126 - icon: Image.asset('shop'.assetPng)  
127 - ), 120 + // IconButton(
  121 + // onPressed: (){
  122 + // if(actionTap != null) {
  123 + // actionTap!(HeaderActionType.shop);
  124 + // }
  125 + // },
  126 + // icon: Image.asset('shop'.assetPng)
  127 + // ),
128 ScreenUtil().bottomBarHeight.horizontalSpace, 128 ScreenUtil().bottomBarHeight.horizontalSpace,
129 ], 129 ],
130 ), 130 ),
lib/pages/home/widgets/home_vidoe_item.dart
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 import 'package:flutter_screenutil/flutter_screenutil.dart'; 2 import 'package:flutter_screenutil/flutter_screenutil.dart';
3 import 'package:wow_english/common/extension/string_extension.dart'; 3 import 'package:wow_english/common/extension/string_extension.dart';
  4 +import 'package:wow_english/common/widgets/ow_image_widget.dart';
4 import 'package:wow_english/models/course_entity.dart'; 5 import 'package:wow_english/models/course_entity.dart';
5 6
6 class HomeVideoItem extends StatelessWidget { 7 class HomeVideoItem extends StatelessWidget {
@@ -16,9 +17,9 @@ class HomeVideoItem extends StatelessWidget { @@ -16,9 +17,9 @@ class HomeVideoItem extends StatelessWidget {
16 width: 165.w, 17 width: 165.w,
17 padding: EdgeInsets.symmetric(horizontal: 16.w,vertical: 24.h), 18 padding: EdgeInsets.symmetric(horizontal: 16.w,vertical: 24.h),
18 decoration: BoxDecoration( 19 decoration: BoxDecoration(
19 - image: DecorationImage(  
20 - image: AssetImage('gendubeij'.assetPng),  
21 - ), 20 + image: DecorationImage(
  21 + image: AssetImage('gendubeij'.assetPng),
  22 + ),
22 ), 23 ),
23 child: Column( 24 child: Column(
24 mainAxisAlignment: MainAxisAlignment.spaceAround, 25 mainAxisAlignment: MainAxisAlignment.spaceAround,
@@ -26,17 +27,17 @@ class HomeVideoItem extends StatelessWidget { @@ -26,17 +27,17 @@ class HomeVideoItem extends StatelessWidget {
26 Expanded( 27 Expanded(
27 child: Container( 28 child: Container(
28 decoration: BoxDecoration( 29 decoration: BoxDecoration(
29 - border: Border.all(  
30 - width: 2,  
31 - color: const Color(0xFF140C10), 30 + border: Border.all(
  31 + width: 2,
  32 + color: const Color(0xFF140C10),
  33 + ),
  34 + borderRadius: BorderRadius.circular(6)
32 ), 35 ),
33 - borderRadius: BorderRadius.circular(6)  
34 - ),  
35 - child: Image.network(  
36 - lessons?.coverUrl??'', 36 + child: OwImageWidget(
  37 + name: lessons?.coverUrl??'',
37 fit: BoxFit.fill, 38 fit: BoxFit.fill,
38 ), 39 ),
39 - )), 40 + )),
40 24.verticalSpace, 41 24.verticalSpace,
41 Container( 42 Container(
42 decoration: BoxDecoration( 43 decoration: BoxDecoration(
lib/pages/lessons/lesson_page.dart
@@ -52,15 +52,15 @@ class _LessonPageView extends StatelessWidget { @@ -52,15 +52,15 @@ class _LessonPageView extends StatelessWidget {
52 width: 43, 52 width: 43,
53 ) 53 )
54 ), 54 ),
55 - actions: <Widget>[  
56 - IconButton(  
57 - icon: Image.asset('shop'.assetPng),  
58 - color: Colors.white,  
59 - onPressed: () {  
60 - EasyLoading.showToast('购买');  
61 - },  
62 - )  
63 - ], 55 + // actions: <Widget>[
  56 + // IconButton(
  57 + // icon: Image.asset('shop'.assetPng),
  58 + // color: Colors.white,
  59 + // onPressed: () {
  60 + // EasyLoading.showToast('购买');
  61 + // },
  62 + // )
  63 + // ],
64 ), 64 ),
65 body: _lessViewWidget(), 65 body: _lessViewWidget(),
66 ), 66 ),
@@ -88,7 +88,7 @@ class _LessonPageView extends StatelessWidget { @@ -88,7 +88,7 @@ class _LessonPageView extends StatelessWidget {
88 32.verticalSpace, 88 32.verticalSpace,
89 SizedBox( 89 SizedBox(
90 height: 32.h, 90 height: 32.h,
91 - width: double.infinity, 91 + width: 66.w * bloc.listData.length,
92 child: ListView.builder( 92 child: ListView.builder(
93 itemCount: bloc.listData.length, 93 itemCount: bloc.listData.length,
94 scrollDirection: Axis.horizontal, 94 scrollDirection: Axis.horizontal,
@@ -109,6 +109,7 @@ class _LessonPageView extends StatelessWidget { @@ -109,6 +109,7 @@ class _LessonPageView extends StatelessWidget {
109 height: bloc.currentPageIndex == index ? 32:20, 109 height: bloc.currentPageIndex == index ? 32:20,
110 decoration: BoxDecoration( 110 decoration: BoxDecoration(
111 color: bloc.currentPageIndex == index ? Colors.red:Colors.white, 111 color: bloc.currentPageIndex == index ? Colors.red:Colors.white,
  112 + borderRadius: BorderRadius.circular(5.r),
112 border: Border.all( 113 border: Border.all(
113 width: 0.5, 114 width: 0.5,
114 color: Colors.black, 115 color: Colors.black,
lib/pages/lessons/widgets/lesson_item_widget.dart
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 import 'package:flutter_screenutil/flutter_screenutil.dart'; 2 import 'package:flutter_screenutil/flutter_screenutil.dart';
3 import 'package:wow_english/common/extension/string_extension.dart'; 3 import 'package:wow_english/common/extension/string_extension.dart';
  4 +import 'package:wow_english/common/widgets/ow_image_widget.dart';
4 import 'package:wow_english/models/course_module_entity.dart'; 5 import 'package:wow_english/models/course_module_entity.dart';
5 6
6 class LessonItemWidget extends StatelessWidget { 7 class LessonItemWidget extends StatelessWidget {
@@ -30,8 +31,8 @@ class LessonItemWidget extends StatelessWidget { @@ -30,8 +31,8 @@ class LessonItemWidget extends StatelessWidget {
30 image: AssetImage('gendubeij'.assetPng) 31 image: AssetImage('gendubeij'.assetPng)
31 ) 32 )
32 ), 33 ),
33 - child: Image.network(  
34 - model?.picUrl??'', 34 + child: OwImageWidget(
  35 + name: model?.picUrl??'',
35 ), 36 ),
36 ); 37 );
37 } 38 }
@@ -40,29 +41,48 @@ class LessonItemWidget extends StatelessWidget { @@ -40,29 +41,48 @@ class LessonItemWidget extends StatelessWidget {
40 return Container( 41 return Container(
41 padding: const EdgeInsets.all(10), 42 padding: const EdgeInsets.all(10),
42 decoration: BoxDecoration( 43 decoration: BoxDecoration(
43 - image: DecorationImage(  
44 - image: AssetImage('gendubeij'.assetPng)  
45 - ) 44 + image: DecorationImage(
  45 + image: AssetImage(
  46 + 'gendubeij'.assetPng,
  47 + ),
  48 + fit: BoxFit.fill
  49 + ),
46 ), 50 ),
47 child: Column( 51 child: Column(
48 mainAxisAlignment: MainAxisAlignment.spaceBetween, 52 mainAxisAlignment: MainAxisAlignment.spaceBetween,
49 children: [ 53 children: [
50 Expanded( 54 Expanded(
51 - child: Image.network(  
52 - model?.picUrl??'',  
53 - fit: BoxFit.contain 55 + child: OwImageWidget(
  56 + name: model?.picUrl??'',
54 ), 57 ),
55 ), 58 ),
56 10.verticalSpace, 59 10.verticalSpace,
57 Container( 60 Container(
58 - color: Colors.red, 61 + decoration: BoxDecoration(
  62 + color: Colors.red,
  63 + borderRadius: BorderRadius.circular(6.r),
  64 + border: Border.all(
  65 + color: const Color(0xFF333333),
  66 + width: 1.0
  67 + )
  68 + ),
59 padding: EdgeInsets.symmetric(horizontal: 10.w), 69 padding: EdgeInsets.symmetric(horizontal: 10.w),
60 child: Column( 70 child: Column(
61 children: [ 71 children: [
62 - Text(model?.name??''), 72 + Text(
  73 + model?.name??'',
  74 + style: TextStyle(
  75 + color: Colors.white,
  76 + fontSize: 12.sp
  77 + ),
  78 + ),
63 Text( 79 Text(
64 model?.des??'', 80 model?.des??'',
65 maxLines: 1, 81 maxLines: 1,
  82 + style: TextStyle(
  83 + color: Colors.white,
  84 + fontSize: 12.sp
  85 + ),
66 ) 86 )
67 ], 87 ],
68 ), 88 ),
lib/pages/listen/bloc/listen_bloc.dart
@@ -13,8 +13,8 @@ part &#39;listen_state.dart&#39;; @@ -13,8 +13,8 @@ part &#39;listen_state.dart&#39;;
13 13
14 class ListenBloc extends Bloc<ListenEvent, ListenState> { 14 class ListenBloc extends Bloc<ListenEvent, ListenState> {
15 15
16 - final List<ListenEntity?> _listData = [];  
17 - List<ListenEntity?> get listData => _listData; 16 + List<ListenEntity?>? _listData;
  17 + List<ListenEntity?>? get listData => _listData;
18 18
19 ListenBloc() : super(ListenInitial()) { 19 ListenBloc() : super(ListenInitial()) {
20 on<ListenEvent>((event, emit) { 20 on<ListenEvent>((event, emit) {
@@ -25,13 +25,7 @@ class ListenBloc extends Bloc&lt;ListenEvent, ListenState&gt; { @@ -25,13 +25,7 @@ class ListenBloc extends Bloc&lt;ListenEvent, ListenState&gt; {
25 Future<void> requestData() async { 25 Future<void> requestData() async {
26 try { 26 try {
27 await loading(() async { 27 await loading(() async {
28 - List<String> list = await ListenDao.listen()??[];  
29 - if (list.isNotEmpty) {  
30 - for (String jsonStr in list) {  
31 - ListenEntity? data = ListenEntity.fromJson(jsonDecode(jsonStr));  
32 - _listData.add(data);  
33 - }  
34 - } 28 + _listData = await ListenDao.listen()??[];
35 emit(RequestListenDataState()); 29 emit(RequestListenDataState());
36 }); 30 });
37 } catch (e) { 31 } catch (e) {
lib/pages/listen/listen_page.dart
@@ -40,12 +40,12 @@ class _ListenPageView extends StatelessWidget { @@ -40,12 +40,12 @@ class _ListenPageView extends StatelessWidget {
40 builder: (context, state) { 40 builder: (context, state) {
41 final bloc = BlocProvider.of<ListenBloc>(context); 41 final bloc = BlocProvider.of<ListenBloc>(context);
42 return ListView.builder( 42 return ListView.builder(
43 - itemCount: bloc.listData.length, 43 + itemCount: bloc.listData?.length,
44 scrollDirection: Axis.horizontal, 44 scrollDirection: Axis.horizontal,
45 padding: EdgeInsets.symmetric(horizontal: 30.w,vertical: 36.h), 45 padding: EdgeInsets.symmetric(horizontal: 30.w,vertical: 36.h),
46 itemBuilder: (BuildContext context,int index){ 46 itemBuilder: (BuildContext context,int index){
47 return ListenItemWidget( 47 return ListenItemWidget(
48 - isLock: (index > 5), 48 + entity: bloc.listData?[index],
49 clickEvent: (){ 49 clickEvent: (){
50 Navigator.of(context).pushNamed(AppRouteName.lookVideo,arguments: {'videoUrl':'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7194236f31b2e1e3da0fe06cfed4ba2b.mp4'}); 50 Navigator.of(context).pushNamed(AppRouteName.lookVideo,arguments: {'videoUrl':'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/7194236f31b2e1e3da0fe06cfed4ba2b.mp4'});
51 }); 51 });
lib/pages/listen/widgets/listen_item_widget.dart
  1 +import 'package:cached_network_image/cached_network_image.dart';
1 import 'package:flutter/material.dart'; 2 import 'package:flutter/material.dart';
2 import 'package:flutter_screenutil/flutter_screenutil.dart'; 3 import 'package:flutter_screenutil/flutter_screenutil.dart';
3 import 'package:wow_english/common/extension/string_extension.dart'; 4 import 'package:wow_english/common/extension/string_extension.dart';
  5 +import 'package:wow_english/common/widgets/ow_image_widget.dart';
  6 +import 'package:wow_english/models/listen_entity.dart';
4 7
5 class ListenItemWidget extends StatelessWidget { 8 class ListenItemWidget extends StatelessWidget {
6 - const ListenItemWidget({super.key, this.isLock = false, required this.clickEvent}); 9 + const ListenItemWidget({super.key, required this.clickEvent, this.entity});
7 10
8 final Function() clickEvent; 11 final Function() clickEvent;
9 12
10 - final bool isLock; 13 + final ListenEntity? entity;
11 14
12 @override 15 @override
13 Widget build(BuildContext context) { 16 Widget build(BuildContext context) {
@@ -17,23 +20,24 @@ class ListenItemWidget extends StatelessWidget { @@ -17,23 +20,24 @@ class ListenItemWidget extends StatelessWidget {
17 children: [ 20 children: [
18 GestureDetector( 21 GestureDetector(
19 onTap: () { 22 onTap: () {
20 - if (!isLock) {  
21 - clickEvent(); 23 + if (entity?.lock??false) {
  24 + return;
22 } 25 }
  26 + clickEvent?.call();
23 }, 27 },
24 child: ClipRRect( 28 child: ClipRRect(
25 borderRadius:BorderRadius.circular(90.r), 29 borderRadius:BorderRadius.circular(90.r),
26 child: Stack( 30 child: Stack(
27 alignment:Alignment.center, 31 alignment:Alignment.center,
28 children: [ 32 children: [
29 - Image.network(  
30 - 'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fsafe-img.xhscdn.com%2Fbw1%2Faa1c2213-820a-4223-8757-5f8cee318a28%3FimageView2%2F2%2Fw%2F1080%2Fformat%2Fjpg&refer=http%3A%2F%2Fsafe-img.xhscdn.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1688713226&t=192b18a613683bcdc5bd76f65c9ff032',  
31 - height: 180.h, 33 + OwImageWidget(
32 width: 180.h, 34 width: 180.h,
  35 + height: 180.h,
33 fit: BoxFit.fill, 36 fit: BoxFit.fill,
  37 + name:entity?.coverUrl??'',
34 ), 38 ),
35 Visibility( 39 Visibility(
36 - visible: isLock, 40 + visible: entity?.lock??false,
37 child: Container( 41 child: Container(
38 height: 180.h, 42 height: 180.h,
39 width: 180.h, 43 width: 180.h,
@@ -41,7 +45,7 @@ class ListenItemWidget extends StatelessWidget { @@ -41,7 +45,7 @@ class ListenItemWidget extends StatelessWidget {
41 ), 45 ),
42 ), 46 ),
43 Visibility( 47 Visibility(
44 - visible: isLock, 48 + visible: entity?.lock??false,
45 child: Image.asset( 49 child: Image.asset(
46 'listen_lock'.assetPng, 50 'listen_lock'.assetPng,
47 height: 36.h, 51 height: 36.h,
@@ -66,7 +70,7 @@ class ListenItemWidget extends StatelessWidget { @@ -66,7 +70,7 @@ class ListenItemWidget extends StatelessWidget {
66 ), 70 ),
67 alignment: Alignment.center, 71 alignment: Alignment.center,
68 child: Text( 72 child: Text(
69 - 'listen title', 73 + entity?.title??'',
70 style: TextStyle( 74 style: TextStyle(
71 fontSize: 20.sp, 75 fontSize: 20.sp,
72 color: const Color(0xFF333333) 76 color: const Color(0xFF333333)
lib/pages/repeatafter/bloc/repeat_after_bloc.dart
1 import 'package:flutter/cupertino.dart'; 1 import 'package:flutter/cupertino.dart';
2 import 'package:flutter_bloc/flutter_bloc.dart'; 2 import 'package:flutter_bloc/flutter_bloc.dart';
3 import 'package:flutter_easyloading/flutter_easyloading.dart'; 3 import 'package:flutter_easyloading/flutter_easyloading.dart';
  4 +import 'package:wow_english/common/request/dao/listen_dao.dart';
  5 +import 'package:wow_english/common/request/exception.dart';
  6 +import 'package:wow_english/models/follow_read_entity.dart';
  7 +import 'package:wow_english/utils/loading.dart';
4 8
5 part 'repeat_after_event.dart'; 9 part 'repeat_after_event.dart';
6 part 'repeat_after_state.dart'; 10 part 'repeat_after_state.dart';
7 11
8 class RepeatAfterBloc extends Bloc<RepeatAfterEvent, RepeatAfterState> { 12 class RepeatAfterBloc extends Bloc<RepeatAfterEvent, RepeatAfterState> {
  13 +
  14 + List<FollowReadEntity?> _listData = [];
  15 + List<FollowReadEntity?> get listData => _listData;
  16 +
9 RepeatAfterBloc() : super(RepeatAfterInitial()) { 17 RepeatAfterBloc() : super(RepeatAfterInitial()) {
10 on<RepeatAfterEvent>((event, emit) { 18 on<RepeatAfterEvent>((event, emit) {
11 // TODO: implement event handler 19 // TODO: implement event handler
@@ -14,10 +22,15 @@ class RepeatAfterBloc extends Bloc&lt;RepeatAfterEvent, RepeatAfterState&gt; { @@ -14,10 +22,15 @@ class RepeatAfterBloc extends Bloc&lt;RepeatAfterEvent, RepeatAfterState&gt; {
14 22
15 23
16 Future<void> requestData() async { 24 Future<void> requestData() async {
17 - EasyLoading.show();  
18 - Future.delayed(const Duration(milliseconds: 2000),(){  
19 - EasyLoading.dismiss();  
20 - emit(RequestDataState());  
21 - }); 25 + try {
  26 + await loading(() async {
  27 + _listData = await ListenDao.followRead()??[];
  28 + emit(RequestDataState());
  29 + });
  30 + } catch (e) {
  31 + if (e is ApiException) {
  32 + EasyLoading.showToast(e.message??'请求失败,请检查网络连接');
  33 + }
  34 + }
22 } 35 }
23 } 36 }
lib/pages/repeatafter/repeat_after_page.dart
1 -import 'dart:math';  
2 -  
3 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
4 import 'package:flutter_bloc/flutter_bloc.dart'; 2 import 'package:flutter_bloc/flutter_bloc.dart';
5 import 'package:flutter_easyloading/flutter_easyloading.dart'; 3 import 'package:flutter_easyloading/flutter_easyloading.dart';
6 import 'package:wow_english/common/widgets/we_app_bar.dart'; 4 import 'package:wow_english/common/widgets/we_app_bar.dart';
  5 +import 'package:wow_english/models/follow_read_entity.dart';
7 import 'package:wow_english/pages/repeatafter/widgets/repeat_after_item.dart'; 6 import 'package:wow_english/pages/repeatafter/widgets/repeat_after_item.dart';
8 7
9 import 'bloc/repeat_after_bloc.dart'; 8 import 'bloc/repeat_after_bloc.dart';
@@ -35,6 +34,7 @@ class _RepeatAfterPageView extends StatelessWidget { @@ -35,6 +34,7 @@ class _RepeatAfterPageView extends StatelessWidget {
35 34
36 Widget _repeatAfterView() => BlocBuilder<RepeatAfterBloc, RepeatAfterState>( 35 Widget _repeatAfterView() => BlocBuilder<RepeatAfterBloc, RepeatAfterState>(
37 builder: (context, state) { 36 builder: (context, state) {
  37 + final bloc = BlocProvider.of<RepeatAfterBloc>(context);
38 return Scaffold( 38 return Scaffold(
39 appBar: const WEAppBar( 39 appBar: const WEAppBar(
40 titleText: '视频跟读', 40 titleText: '视频跟读',
@@ -44,16 +44,15 @@ class _RepeatAfterPageView extends StatelessWidget { @@ -44,16 +44,15 @@ class _RepeatAfterPageView extends StatelessWidget {
44 child: Container( 44 child: Container(
45 alignment: Alignment.center, 45 alignment: Alignment.center,
46 child: ListView.builder( 46 child: ListView.builder(
47 - itemCount: 10, 47 + itemCount: bloc.listData.length,
48 scrollDirection: Axis.horizontal, 48 scrollDirection: Axis.horizontal,
49 itemBuilder: (BuildContext context,int index){ 49 itemBuilder: (BuildContext context,int index){
50 - bool unLock = index%3==0; 50 + FollowReadEntity? entity = bloc.listData[index];
51 return RepeatAfterItem( 51 return RepeatAfterItem(
52 - unLock: unLock,  
53 tapEvent: () { 52 tapEvent: () {
54 53
55 }, 54 },
56 - starNumber: !unLock?0:Random().nextInt(5) 55 + entity: entity,
57 ); 56 );
58 }), 57 }),
59 ), 58 ),
lib/pages/repeatafter/widgets/repeat_after_item.dart
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
2 import 'package:flutter_screenutil/flutter_screenutil.dart'; 2 import 'package:flutter_screenutil/flutter_screenutil.dart';
3 import 'package:wow_english/common/extension/string_extension.dart'; 3 import 'package:wow_english/common/extension/string_extension.dart';
  4 +import 'package:wow_english/common/widgets/ow_image_widget.dart';
  5 +import 'package:wow_english/models/follow_read_entity.dart';
4 6
5 class RepeatAfterItem extends StatelessWidget { 7 class RepeatAfterItem extends StatelessWidget {
6 - const RepeatAfterItem({super.key, required this.starNumber, required this.unLock, required this.tapEvent});  
7 - //分数  
8 - final int starNumber;  
9 - //是否解锁  
10 - final bool unLock; 8 + const RepeatAfterItem({super.key, required this.tapEvent, this.entity});
  9 +
  10 + final FollowReadEntity? entity;
11 11
12 final Function() tapEvent; 12 final Function() tapEvent;
13 13
@@ -19,8 +19,10 @@ class RepeatAfterItem extends StatelessWidget { @@ -19,8 +19,10 @@ class RepeatAfterItem extends StatelessWidget {
19 ), 19 ),
20 child: GestureDetector( 20 child: GestureDetector(
21 onTap: (){ 21 onTap: (){
22 - if(unLock) {  
23 - tapEvent(); 22 + if (entity != null) {
  23 + if (entity?.lock??false) {
  24 + tapEvent();
  25 + }
24 } 26 }
25 }, 27 },
26 child: Stack( 28 child: Stack(
@@ -50,8 +52,8 @@ class RepeatAfterItem extends StatelessWidget { @@ -50,8 +52,8 @@ class RepeatAfterItem extends StatelessWidget {
50 child: Column( 52 child: Column(
51 mainAxisAlignment: MainAxisAlignment.spaceBetween, 53 mainAxisAlignment: MainAxisAlignment.spaceBetween,
52 children: [ 54 children: [
53 - Image.network(  
54 - 'https://img.liblibai.com/web/648331d033b41.png?image_process=format,webp&x-oss-process=image/resize,w_2980,m_lfit/format,webp', 55 + OwImageWidget(
  56 + name:entity?.coverUrl??'',
55 height: 100.h, 57 height: 100.h,
56 width: 140.w, 58 width: 140.w,
57 fit: BoxFit.fitWidth, 59 fit: BoxFit.fitWidth,
@@ -60,27 +62,27 @@ class RepeatAfterItem extends StatelessWidget { @@ -60,27 +62,27 @@ class RepeatAfterItem extends StatelessWidget {
60 mainAxisAlignment: MainAxisAlignment.spaceBetween, 62 mainAxisAlignment: MainAxisAlignment.spaceBetween,
61 children: [ 63 children: [
62 Image.asset( 64 Image.asset(
63 - starNumber >= 1 ? 'star_light'.assetPng:'star_dark'.assetPng, 65 + (entity?.star??0) >= 1 ? 'star_light'.assetPng:'star_dark'.assetPng,
64 width: 23.w, 66 width: 23.w,
65 height: 21.h, 67 height: 21.h,
66 ), 68 ),
67 Image.asset( 69 Image.asset(
68 - starNumber >= 2 ? 'star_light'.assetPng:'star_dark'.assetPng, 70 + (entity?.star??0) >= 2 ? 'star_light'.assetPng:'star_dark'.assetPng,
69 width: 23.w, 71 width: 23.w,
70 height: 21.h, 72 height: 21.h,
71 ), 73 ),
72 Image.asset( 74 Image.asset(
73 - starNumber >= 3 ? 'star_light'.assetPng:'star_dark'.assetPng, 75 + (entity?.star??0) >= 3 ? 'star_light'.assetPng:'star_dark'.assetPng,
74 width: 23.w, 76 width: 23.w,
75 height: 21.h, 77 height: 21.h,
76 ), 78 ),
77 Image.asset( 79 Image.asset(
78 - starNumber >= 4 ? 'star_light'.assetPng:'star_dark'.assetPng, 80 + (entity?.star??0) >= 4 ? 'star_light'.assetPng:'star_dark'.assetPng,
79 width: 23.w, 81 width: 23.w,
80 height: 21.h, 82 height: 21.h,
81 ), 83 ),
82 Image.asset( 84 Image.asset(
83 - starNumber >= 5 ? 'star_light'.assetPng:'star_dark'.assetPng, 85 + (entity?.star??0) >= 5 ? 'star_light'.assetPng:'star_dark'.assetPng,
84 width: 23.w, 86 width: 23.w,
85 height: 21.h, 87 height: 21.h,
86 ), 88 ),
@@ -99,7 +101,7 @@ class RepeatAfterItem extends StatelessWidget { @@ -99,7 +101,7 @@ class RepeatAfterItem extends StatelessWidget {
99 ), 101 ),
100 alignment: Alignment.center, 102 alignment: Alignment.center,
101 child: Text( 103 child: Text(
102 - 'video title', 104 + entity?.title??'',
103 style: TextStyle( 105 style: TextStyle(
104 fontSize: 16.sp, 106 fontSize: 16.sp,
105 color: const Color(0xFF333333) 107 color: const Color(0xFF333333)
@@ -112,8 +114,8 @@ class RepeatAfterItem extends StatelessWidget { @@ -112,8 +114,8 @@ class RepeatAfterItem extends StatelessWidget {
112 } 114 }
113 115
114 Widget _lockWidget() { 116 Widget _lockWidget() {
115 - return Offstage(  
116 - offstage: unLock, 117 + return Visibility(
  118 + visible: entity?.lock??false,
117 child: Container( 119 child: Container(
118 width: 162.w, 120 width: 162.w,
119 height: 235.h, 121 height: 235.h,