Showing
8 changed files
with
115 additions
and
25 deletions
| ... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
| 3 | // ignore_for_file: prefer_single_quotes | 3 | // ignore_for_file: prefer_single_quotes |
| 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'; | 6 | +import 'package:flutter/material.dart' show debugPrint; |
| 7 | import 'package:Parlando/account/models/my_videos_entity.dart'; | 7 | import 'package:Parlando/account/models/my_videos_entity.dart'; |
| 8 | import 'package:Parlando/account/models/upload_avatar_entity.dart'; | 8 | import 'package:Parlando/account/models/upload_avatar_entity.dart'; |
| 9 | import 'package:Parlando/account/models/user_entity.dart'; | 9 | import 'package:Parlando/account/models/user_entity.dart'; |
| ... | @@ -22,7 +22,6 @@ import 'package:Parlando/poem/models/search_entity.dart'; | ... | @@ -22,7 +22,6 @@ import 'package:Parlando/poem/models/search_entity.dart'; |
| 22 | import 'package:Parlando/timeline/models/friend_entity.dart'; | 22 | import 'package:Parlando/timeline/models/friend_entity.dart'; |
| 23 | 23 | ||
| 24 | JsonConvert jsonConvert = JsonConvert(); | 24 | JsonConvert jsonConvert = JsonConvert(); |
| 25 | - | ||
| 26 | typedef JsonConvertFunction<T> = T Function(Map<String, dynamic> json); | 25 | typedef JsonConvertFunction<T> = T Function(Map<String, dynamic> json); |
| 27 | 26 | ||
| 28 | class JsonConvert { | 27 | class JsonConvert { | ... | ... |
| ... | @@ -75,22 +75,30 @@ HomeData $HomeDataFromJson(Map<String, dynamic> json) { | ... | @@ -75,22 +75,30 @@ HomeData $HomeDataFromJson(Map<String, dynamic> json) { |
| 75 | if (bgm != null) { | 75 | if (bgm != null) { |
| 76 | homeData.bgm = bgm; | 76 | homeData.bgm = bgm; |
| 77 | } | 77 | } |
| 78 | - final String? praise = jsonConvert.convert<String>(json['praise']); | 78 | + final int? praise = jsonConvert.convert<int>(json['praise']); |
| 79 | if (praise != null) { | 79 | if (praise != null) { |
| 80 | homeData.praise = praise; | 80 | homeData.praise = praise; |
| 81 | } | 81 | } |
| 82 | - final String? view = jsonConvert.convert<String>(json['view']); | 82 | + final int? view = jsonConvert.convert<int>(json['view']); |
| 83 | if (view != null) { | 83 | if (view != null) { |
| 84 | homeData.view = view; | 84 | homeData.view = view; |
| 85 | } | 85 | } |
| 86 | - final String? collect = jsonConvert.convert<String>(json['collect']); | 86 | + final int? collect = jsonConvert.convert<int>(json['collect']); |
| 87 | if (collect != null) { | 87 | if (collect != null) { |
| 88 | homeData.collect = collect; | 88 | homeData.collect = collect; |
| 89 | } | 89 | } |
| 90 | - final String? share = jsonConvert.convert<String>(json['share']); | 90 | + final int? share = jsonConvert.convert<int>(json['share']); |
| 91 | if (share != null) { | 91 | if (share != null) { |
| 92 | homeData.share = share; | 92 | homeData.share = share; |
| 93 | } | 93 | } |
| 94 | + final bool? isPraise = jsonConvert.convert<bool>(json['is_praise']); | ||
| 95 | + if (isPraise != null) { | ||
| 96 | + homeData.isPraise = isPraise; | ||
| 97 | + } | ||
| 98 | + final bool? isCollect = jsonConvert.convert<bool>(json['is_collect']); | ||
| 99 | + if (isCollect != null) { | ||
| 100 | + homeData.isCollect = isCollect; | ||
| 101 | + } | ||
| 94 | return homeData; | 102 | return homeData; |
| 95 | } | 103 | } |
| 96 | 104 | ||
| ... | @@ -109,6 +117,8 @@ Map<String, dynamic> $HomeDataToJson(HomeData entity) { | ... | @@ -109,6 +117,8 @@ Map<String, dynamic> $HomeDataToJson(HomeData entity) { |
| 109 | data['view'] = entity.view; | 117 | data['view'] = entity.view; |
| 110 | data['collect'] = entity.collect; | 118 | data['collect'] = entity.collect; |
| 111 | data['share'] = entity.share; | 119 | data['share'] = entity.share; |
| 120 | + data['is_praise'] = entity.isPraise; | ||
| 121 | + data['is_collect'] = entity.isCollect; | ||
| 112 | return data; | 122 | return data; |
| 113 | } | 123 | } |
| 114 | 124 | ... | ... |
| ... | @@ -64,7 +64,6 @@ class HomeState extends State<Home> with WidgetsBindingObserver { | ... | @@ -64,7 +64,6 @@ class HomeState extends State<Home> with WidgetsBindingObserver { |
| 64 | //设置pageView 滑动监听 | 64 | //设置pageView 滑动监听 |
| 65 | _controller.addListener(() { | 65 | _controller.addListener(() { |
| 66 | if (_controller.position.pixels == _controller.position.maxScrollExtent) { | 66 | if (_controller.position.pixels == _controller.position.maxScrollExtent) { |
| 67 | - print('滑动到了最底部'); | ||
| 68 | _getMore(); | 67 | _getMore(); |
| 69 | } | 68 | } |
| 70 | }); | 69 | }); |
| ... | @@ -111,9 +110,12 @@ class HomeState extends State<Home> with WidgetsBindingObserver { | ... | @@ -111,9 +110,12 @@ class HomeState extends State<Home> with WidgetsBindingObserver { |
| 111 | videos.clear(); | 110 | videos.clear(); |
| 112 | for (HomeData data in data!.data!) { | 111 | for (HomeData data in data!.data!) { |
| 113 | videos.add(VideoSlides( | 112 | videos.add(VideoSlides( |
| 113 | + videoId: data.id!, | ||
| 114 | poemId: data.poemId!, | 114 | poemId: data.poemId!, |
| 115 | poemType: data.type!, | 115 | poemType: data.type!, |
| 116 | url: data.url!, | 116 | url: data.url!, |
| 117 | + isCollect: data.isCollect!, | ||
| 118 | + isPraise: data.isPraise!, | ||
| 117 | )); | 119 | )); |
| 118 | } | 120 | } |
| 119 | setState(() {}); | 121 | setState(() {}); |
| ... | @@ -140,9 +142,12 @@ class HomeState extends State<Home> with WidgetsBindingObserver { | ... | @@ -140,9 +142,12 @@ class HomeState extends State<Home> with WidgetsBindingObserver { |
| 140 | 142 | ||
| 141 | for (HomeData data in data!.data!) { | 143 | for (HomeData data in data!.data!) { |
| 142 | videos.add(VideoSlides( | 144 | videos.add(VideoSlides( |
| 145 | + videoId: data.id!, | ||
| 143 | poemId: data.poemId!, | 146 | poemId: data.poemId!, |
| 144 | poemType: data.type!, | 147 | poemType: data.type!, |
| 145 | url: data.url!, | 148 | url: data.url!, |
| 149 | + isCollect: data.isCollect!, | ||
| 150 | + isPraise: data.isPraise!, | ||
| 146 | )); | 151 | )); |
| 147 | } | 152 | } |
| 148 | setState(() {}); | 153 | setState(() {}); | ... | ... |
| 1 | -import 'dart:convert'; | ||
| 2 | import 'package:Parlando/generated/json/base/json_field.dart'; | 1 | import 'package:Parlando/generated/json/base/json_field.dart'; |
| 3 | import 'package:Parlando/generated/json/home_entity.g.dart'; | 2 | import 'package:Parlando/generated/json/home_entity.g.dart'; |
| 3 | +import 'dart:convert'; | ||
| 4 | 4 | ||
| 5 | @JsonSerializable() | 5 | @JsonSerializable() |
| 6 | class HomeEntity { | 6 | class HomeEntity { |
| ... | @@ -37,10 +37,14 @@ class HomeData { | ... | @@ -37,10 +37,14 @@ class HomeData { |
| 37 | @JSONField(name: "temp_id") | 37 | @JSONField(name: "temp_id") |
| 38 | int? tempId; | 38 | int? tempId; |
| 39 | String? bgm; | 39 | String? bgm; |
| 40 | - String? praise; | 40 | + int? praise; |
| 41 | - String? view; | 41 | + int? view; |
| 42 | - String? collect; | 42 | + int? collect; |
| 43 | - String? share; | 43 | + int? share; |
| 44 | + @JSONField(name: "is_praise") | ||
| 45 | + bool? isPraise; | ||
| 46 | + @JSONField(name: "is_collect") | ||
| 47 | + bool? isCollect; | ||
| 44 | 48 | ||
| 45 | HomeData(); | 49 | HomeData(); |
| 46 | 50 | ... | ... |
| 1 | +import 'package:dio/dio.dart'; | ||
| 1 | import 'package:flutter/material.dart'; | 2 | import 'package:flutter/material.dart'; |
| 2 | import 'package:getwidget/getwidget.dart'; | 3 | import 'package:getwidget/getwidget.dart'; |
| 4 | +import 'package:path_provider/path_provider.dart'; | ||
| 3 | import 'package:share_plus/share_plus.dart'; | 5 | import 'package:share_plus/share_plus.dart'; |
| 6 | +import '../../net/dio_utils.dart'; | ||
| 7 | +import '../../net/http_api.dart'; | ||
| 4 | import '../theme/tik_video_player.dart'; | 8 | import '../theme/tik_video_player.dart'; |
| 5 | 9 | ||
| 6 | class VideoSlides extends StatefulWidget { | 10 | class VideoSlides extends StatefulWidget { |
| ... | @@ -11,7 +15,9 @@ class VideoSlides extends StatefulWidget { | ... | @@ -11,7 +15,9 @@ class VideoSlides extends StatefulWidget { |
| 11 | required this.url, | 15 | required this.url, |
| 12 | this.isPraise = false, | 16 | this.isPraise = false, |
| 13 | this.isCollect = false, | 17 | this.isCollect = false, |
| 18 | + required this.videoId, | ||
| 14 | }) : super(key: key); | 19 | }) : super(key: key); |
| 20 | + final int videoId; | ||
| 15 | final int poemId; | 21 | final int poemId; |
| 16 | final int poemType; | 22 | final int poemType; |
| 17 | final String url; | 23 | final String url; |
| ... | @@ -24,6 +30,15 @@ class VideoSlides extends StatefulWidget { | ... | @@ -24,6 +30,15 @@ class VideoSlides extends StatefulWidget { |
| 24 | 30 | ||
| 25 | class VideoSlidesState extends State<VideoSlides> { | 31 | class VideoSlidesState extends State<VideoSlides> { |
| 26 | bool isSharing = false; | 32 | bool isSharing = false; |
| 33 | + bool isPraise = false; | ||
| 34 | + bool isCollect = false; | ||
| 35 | + | ||
| 36 | + @override | ||
| 37 | + void initState() { | ||
| 38 | + super.initState(); | ||
| 39 | + isPraise = widget.isPraise; | ||
| 40 | + isCollect = widget.isCollect; | ||
| 41 | + } | ||
| 27 | 42 | ||
| 28 | @override | 43 | @override |
| 29 | Widget build(BuildContext context) { | 44 | Widget build(BuildContext context) { |
| ... | @@ -90,6 +105,21 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -90,6 +105,21 @@ class VideoSlidesState extends State<VideoSlides> { |
| 90 | Padding( | 105 | Padding( |
| 91 | padding: const EdgeInsetsDirectional.fromSTEB( | 106 | padding: const EdgeInsetsDirectional.fromSTEB( |
| 92 | 0, 20, 0, 0), | 107 | 0, 20, 0, 0), |
| 108 | + child: InkWell( | ||
| 109 | + onTap: () { | ||
| 110 | + isPraise = | ||
| 111 | + isPraise == false ? true : false; | ||
| 112 | + setState(() {}); | ||
| 113 | + String url = | ||
| 114 | + '${HttpApi.praise}/${widget.videoId}'; | ||
| 115 | + DioUtils.instance.asyncRequestNetwork( | ||
| 116 | + Method.post, | ||
| 117 | + url, | ||
| 118 | + params: [], | ||
| 119 | + onSuccess: (data) {}, | ||
| 120 | + onError: (code, msg) {}, | ||
| 121 | + ); | ||
| 122 | + }, | ||
| 93 | child: Container( | 123 | child: Container( |
| 94 | width: 40, | 124 | width: 40, |
| 95 | height: 40, | 125 | height: 40, |
| ... | @@ -97,13 +127,16 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -97,13 +127,16 @@ class VideoSlidesState extends State<VideoSlides> { |
| 97 | color: Color(0x69EEEEEE), | 127 | color: Color(0x69EEEEEE), |
| 98 | shape: BoxShape.circle, | 128 | shape: BoxShape.circle, |
| 99 | ), | 129 | ), |
| 100 | - child: const Icon( | 130 | + child: Icon( |
| 101 | Icons.favorite_rounded, | 131 | Icons.favorite_rounded, |
| 102 | - color: Colors.white, | 132 | + color: isPraise |
| 133 | + ? Colors.red | ||
| 134 | + : Colors.white, | ||
| 103 | size: 20, | 135 | size: 20, |
| 104 | ), | 136 | ), |
| 105 | ), | 137 | ), |
| 106 | ), | 138 | ), |
| 139 | + ), | ||
| 107 | ], | 140 | ], |
| 108 | ), | 141 | ), |
| 109 | ], | 142 | ], |
| ... | @@ -124,7 +157,20 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -124,7 +157,20 @@ class VideoSlidesState extends State<VideoSlides> { |
| 124 | padding: const EdgeInsetsDirectional.fromSTEB( | 157 | padding: const EdgeInsetsDirectional.fromSTEB( |
| 125 | 0, 20, 0, 0), | 158 | 0, 20, 0, 0), |
| 126 | child: InkWell( | 159 | child: InkWell( |
| 127 | - onTap: () async {}, | 160 | + onTap: () async { |
| 161 | + isCollect = | ||
| 162 | + isCollect == false ? true : false; | ||
| 163 | + setState(() {}); | ||
| 164 | + String url = | ||
| 165 | + '${HttpApi.collect}/${widget.videoId}'; | ||
| 166 | + DioUtils.instance.asyncRequestNetwork( | ||
| 167 | + Method.post, | ||
| 168 | + url, | ||
| 169 | + params: [], | ||
| 170 | + onSuccess: (data) {}, | ||
| 171 | + onError: (code, msg) {}, | ||
| 172 | + ); | ||
| 173 | + }, | ||
| 128 | child: Container( | 174 | child: Container( |
| 129 | width: 40, | 175 | width: 40, |
| 130 | height: 40, | 176 | height: 40, |
| ... | @@ -132,9 +178,11 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -132,9 +178,11 @@ class VideoSlidesState extends State<VideoSlides> { |
| 132 | color: Color(0x69EEEEEE), | 178 | color: Color(0x69EEEEEE), |
| 133 | shape: BoxShape.circle, | 179 | shape: BoxShape.circle, |
| 134 | ), | 180 | ), |
| 135 | - child: const Icon( | 181 | + child: Icon( |
| 136 | Icons.star, | 182 | Icons.star, |
| 137 | - color: Colors.white, | 183 | + color: isCollect |
| 184 | + ? Colors.red | ||
| 185 | + : Colors.white, | ||
| 138 | size: 20, | 186 | size: 20, |
| 139 | ), | 187 | ), |
| 140 | ), | 188 | ), |
| ... | @@ -163,11 +211,10 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -163,11 +211,10 @@ class VideoSlidesState extends State<VideoSlides> { |
| 163 | onTap: () async { | 211 | onTap: () async { |
| 164 | isSharing = true; | 212 | isSharing = true; |
| 165 | setState(() {}); | 213 | setState(() {}); |
| 166 | - Future.delayed(const Duration(seconds: 3), | 214 | + await downVideo(widget.url); |
| 167 | - () async { | 215 | + isSharing = false; |
| 168 | - setState(() => isSharing = false); | 216 | + await Share.shareFiles([tempVideoPath], |
| 169 | - await Share.share('一言以世界 临境不蹉跎'); | 217 | + text: '一言以世界 临境不蹉跎'); |
| 170 | - }); | ||
| 171 | }, | 218 | }, |
| 172 | child: Container( | 219 | child: Container( |
| 173 | width: 40, | 220 | width: 40, |
| ... | @@ -177,9 +224,10 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -177,9 +224,10 @@ class VideoSlidesState extends State<VideoSlides> { |
| 177 | shape: BoxShape.circle, | 224 | shape: BoxShape.circle, |
| 178 | ), | 225 | ), |
| 179 | child: isSharing | 226 | child: isSharing |
| 180 | - ? const GFLoader( | 227 | + ? GFProgressBar( |
| 181 | - type: GFLoaderType.ios, | 228 | + percentage: currentProgress, |
| 182 | - ) | 229 | + backgroundColor: Colors.black26, |
| 230 | + progressBarColor: GFColors.DANGER) | ||
| 183 | : const Icon( | 231 | : const Icon( |
| 184 | Icons.share_rounded, | 232 | Icons.share_rounded, |
| 185 | color: Colors.white, | 233 | color: Colors.white, |
| ... | @@ -203,4 +251,28 @@ class VideoSlidesState extends State<VideoSlides> { | ... | @@ -203,4 +251,28 @@ class VideoSlidesState extends State<VideoSlides> { |
| 203 | ], | 251 | ], |
| 204 | ); | 252 | ); |
| 205 | } | 253 | } |
| 254 | + | ||
| 255 | + Future<String> getPhoneLocalPath() async { | ||
| 256 | + final directory = Theme.of(context).platform == TargetPlatform.android | ||
| 257 | + ? await getExternalStorageDirectory() | ||
| 258 | + : await getApplicationDocumentsDirectory(); | ||
| 259 | + return directory!.path; | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + double currentProgress = 0.0; | ||
| 263 | + String tempVideoPath = ""; | ||
| 264 | + | ||
| 265 | + Future<void> downVideo(String url) async { | ||
| 266 | + String savePath = await getPhoneLocalPath(); | ||
| 267 | + String appName = "my_parlando.mp4"; | ||
| 268 | + Dio dio = Dio(); | ||
| 269 | + tempVideoPath = "$savePath$appName"; | ||
| 270 | + Response response = await dio.download(url, tempVideoPath, | ||
| 271 | + onReceiveProgress: (received, total) { | ||
| 272 | + if (total != -1) { | ||
| 273 | + currentProgress = received / total; | ||
| 274 | + setState(() {}); | ||
| 275 | + } | ||
| 276 | + }); | ||
| 277 | + } | ||
| 206 | } | 278 | } | ... | ... |
-
Please register or login to post a comment