Commit 6f61743479801b967bad9cbdad2f4daaab64484f
1 parent
2a427e12
feat:磨耳朵/视频跟读列表页接口调整
Showing
19 changed files
with
288 additions
and
126 deletions
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<T> = T Function(String value); | @@ -15,6 +16,7 @@ typedef EnumConvertFunction<T> = 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<T>? convertListNotNull<T>(dynamic value, {EnumConvertFunction? enumConvert} | @@ -98,6 +100,9 @@ List<T>? convertListNotNull<T>(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 'listen_state.dart'; | @@ -13,8 +13,8 @@ part 'listen_state.dart'; | ||
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<ListenEvent, ListenState> { | @@ -25,13 +25,7 @@ class ListenBloc extends Bloc<ListenEvent, ListenState> { | ||
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<RepeatAfterEvent, RepeatAfterState> { | @@ -14,10 +22,15 @@ class RepeatAfterBloc extends Bloc<RepeatAfterEvent, RepeatAfterState> { | ||
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, |