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