Showing
15 changed files
with
581 additions
and
339 deletions
... | @@ -4,13 +4,16 @@ import 'package:Parlando/generated/json/user_entity.g.dart'; | ... | @@ -4,13 +4,16 @@ import 'package:Parlando/generated/json/user_entity.g.dart'; |
4 | 4 | ||
5 | @JsonSerializable() | 5 | @JsonSerializable() |
6 | class UserEntity { | 6 | class UserEntity { |
7 | - late int id; | 7 | + String? status; |
8 | - late String name; | 8 | + int? code; |
9 | - late String avatar; | 9 | + String? message; |
10 | + UserData? data; | ||
11 | + UserError? error; | ||
10 | 12 | ||
11 | UserEntity(); | 13 | UserEntity(); |
12 | 14 | ||
13 | - factory UserEntity.fromJson(Map<String, dynamic> json) => $UserEntityFromJson(json); | 15 | + factory UserEntity.fromJson(Map<String, dynamic> json) => |
16 | + $UserEntityFromJson(json); | ||
14 | 17 | ||
15 | Map<String, dynamic> toJson() => $UserEntityToJson(this); | 18 | Map<String, dynamic> toJson() => $UserEntityToJson(this); |
16 | 19 | ||
... | @@ -18,4 +21,49 @@ class UserEntity { | ... | @@ -18,4 +21,49 @@ class UserEntity { |
18 | String toString() { | 21 | String toString() { |
19 | return jsonEncode(this); | 22 | return jsonEncode(this); |
20 | } | 23 | } |
24 | +} | ||
25 | + | ||
26 | +@JsonSerializable() | ||
27 | +class UserData { | ||
28 | + int? id; | ||
29 | + dynamic nickname; | ||
30 | + dynamic mobile; | ||
31 | + String? email; | ||
32 | + String? avatar; | ||
33 | + String? gender; | ||
34 | + dynamic provider; | ||
35 | + @JSONField(name: "provider_id") | ||
36 | + dynamic providerId; | ||
37 | + String? state; | ||
38 | + @JSONField(name: "created_at") | ||
39 | + String? createdAt; | ||
40 | + @JSONField(name: "updated_at") | ||
41 | + String? updatedAt; | ||
42 | + | ||
43 | + UserData(); | ||
44 | + | ||
45 | + factory UserData.fromJson(Map<String, dynamic> json) => | ||
46 | + $UserDataFromJson(json); | ||
47 | + | ||
48 | + Map<String, dynamic> toJson() => $UserDataToJson(this); | ||
49 | + | ||
50 | + @override | ||
51 | + String toString() { | ||
52 | + return jsonEncode(this); | ||
53 | + } | ||
54 | +} | ||
55 | + | ||
56 | +@JsonSerializable() | ||
57 | +class UserError { | ||
58 | + UserError(); | ||
59 | + | ||
60 | + factory UserError.fromJson(Map<String, dynamic> json) => | ||
61 | + $UserErrorFromJson(json); | ||
62 | + | ||
63 | + Map<String, dynamic> toJson() => $UserErrorToJson(this); | ||
64 | + | ||
65 | + @override | ||
66 | + String toString() { | ||
67 | + return jsonEncode(this); | ||
68 | + } | ||
21 | } | 69 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | -import 'package:Parlando/net/dio_utils.dart'; | 1 | +import 'package:Parlando/account/models/user_entity.dart'; |
2 | -import 'package:Parlando/net/http_api.dart'; | 2 | +import 'package:Parlando/account/view_models/account_view_model.dart'; |
3 | +import 'package:Parlando/apis/api_response.dart'; | ||
4 | +import 'package:Parlando/login/login_router.dart'; | ||
3 | import 'package:Parlando/res/constant.dart'; | 5 | import 'package:Parlando/res/constant.dart'; |
4 | -import 'package:Parlando/util/toast_utils.dart'; | 6 | +import 'package:flustars/flustars.dart'; |
5 | import 'package:flutter/material.dart'; | 7 | import 'package:flutter/material.dart'; |
6 | import 'package:Parlando/membership/membership_router.dart'; | 8 | import 'package:Parlando/membership/membership_router.dart'; |
7 | import 'package:Parlando/poem/poem_router.dart'; | 9 | import 'package:Parlando/poem/poem_router.dart'; |
8 | import 'package:Parlando/routers/fluro_navigator.dart'; | 10 | import 'package:Parlando/routers/fluro_navigator.dart'; |
9 | import 'package:Parlando/setting/setting_router.dart'; | 11 | import 'package:Parlando/setting/setting_router.dart'; |
10 | import 'package:Parlando/tiktok/style/style.dart'; | 12 | import 'package:Parlando/tiktok/style/style.dart'; |
13 | +import 'package:provider/provider.dart'; | ||
11 | import 'package:tapped/tapped.dart'; | 14 | import 'package:tapped/tapped.dart'; |
12 | import 'package:flutter_gen/gen_l10n/Parlando_localizations.dart'; | 15 | import 'package:flutter_gen/gen_l10n/Parlando_localizations.dart'; |
13 | 16 | ||
... | @@ -38,207 +41,221 @@ class _AccountPageState extends State<AccountPage> { | ... | @@ -38,207 +41,221 @@ class _AccountPageState extends State<AccountPage> { |
38 | void initState() { | 41 | void initState() { |
39 | super.initState(); | 42 | super.initState(); |
40 | 43 | ||
41 | - //todo MVVM? | 44 | + if (SpUtil.containsKey(Constant.userToken)!) { |
42 | - Map<String, String> params = <String, String>{ | 45 | + Provider.of<AccountViewProvider>(context, listen: false) |
43 | - "profile": "1", | 46 | + .setSelectedAccount(null); |
44 | - }; | 47 | + Provider.of<AccountViewProvider>(context, listen: false) |
45 | - DioUtils.instance.asyncRequestNetwork( | 48 | + .fetchAccountData('0'); |
46 | - Method.post, | 49 | + } else { |
47 | - HttpApi.login, | 50 | + NavigatorUtils.push(context, LoginRouter.loginPage, replace: true); |
48 | - queryParameters: params, | 51 | + } |
49 | - onSuccess: (data) {}, | ||
50 | - onError: (code, msg) { | ||
51 | - Toast.show(msg.toString()); | ||
52 | - }, | ||
53 | - ); | ||
54 | } | 52 | } |
55 | 53 | ||
56 | @override | 54 | @override |
57 | Widget build(BuildContext context) { | 55 | Widget build(BuildContext context) { |
58 | - Widget likeButton = Container( | 56 | + ApiResponse apiResponse = |
59 | - color: ColorPlate.white, | 57 | + Provider.of<AccountViewProvider>(context).response; |
60 | - child: Row( | 58 | + switch (apiResponse.status) { |
61 | - crossAxisAlignment: CrossAxisAlignment.start, | 59 | + case Status.LOADING: |
62 | - mainAxisAlignment: MainAxisAlignment.end, | 60 | + return const Center(child: CircularProgressIndicator()); |
63 | - children: <Widget>[ | 61 | + case Status.COMPLETED: |
64 | - Tapped( | 62 | + UserData _user = apiResponse.data as UserData; |
65 | - onTap: () { | 63 | + Widget likeButton = Container( |
66 | - NavigatorUtils.push(context, MembershipRouter.membershipPage); | 64 | + color: ColorPlate.white, |
67 | - }, | 65 | + child: Row( |
68 | - child: const _MembershipButton( | 66 | + crossAxisAlignment: CrossAxisAlignment.start, |
69 | - title: '会员中心', | 67 | + mainAxisAlignment: MainAxisAlignment.end, |
70 | - ), | 68 | + children: <Widget>[ |
69 | + Tapped( | ||
70 | + onTap: () { | ||
71 | + NavigatorUtils.push(context, MembershipRouter.membershipPage); | ||
72 | + }, | ||
73 | + child: const _MembershipButton( | ||
74 | + title: '会员中心', | ||
75 | + ), | ||
76 | + ), | ||
77 | + ], | ||
71 | ), | 78 | ), |
72 | - ], | 79 | + ); |
73 | - ), | 80 | + Widget avatar = Container( |
74 | - ); | 81 | + height: 120.px + MediaQuery.of(context).padding.top, |
75 | - Widget avatar = Container( | 82 | + padding: EdgeInsets.only(left: 18.px), |
76 | - height: 120.px + MediaQuery.of(context).padding.top, | 83 | + alignment: Alignment.bottomLeft, |
77 | - padding: EdgeInsets.only(left: 18.px), | 84 | + child: OverflowBox( |
78 | - alignment: Alignment.bottomLeft, | 85 | + alignment: Alignment.bottomLeft, |
79 | - child: OverflowBox( | 86 | + minHeight: 20.px, |
80 | - alignment: Alignment.bottomLeft, | 87 | + maxHeight: 300.px, |
81 | - minHeight: 20.px, | 88 | + child: Container( |
82 | - maxHeight: 300.px, | 89 | + height: 74.px, |
83 | - child: Container( | 90 | + width: 74.px, |
84 | - height: 74.px, | 91 | + margin: EdgeInsets.only(bottom: 12.px), |
85 | - width: 74.px, | 92 | + decoration: BoxDecoration( |
86 | - margin: EdgeInsets.only(bottom: 12.px), | 93 | + borderRadius: BorderRadius.circular(44.px), |
87 | - decoration: BoxDecoration( | 94 | + color: Colors.orange, |
88 | - borderRadius: BorderRadius.circular(44.px), | 95 | + border: Border.all( |
89 | - color: Colors.orange, | 96 | + color: Colors.white, |
90 | - border: Border.all( | 97 | + width: 1.px, |
91 | - color: Colors.white, | 98 | + ), |
92 | - width: 1.px, | 99 | + ), |
100 | + child: ClipOval( | ||
101 | + child: Image.network( | ||
102 | + "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif", | ||
103 | + fit: BoxFit.cover, | ||
104 | + ), | ||
105 | + ), | ||
93 | ), | 106 | ), |
94 | ), | 107 | ), |
95 | - child: ClipOval( | 108 | + ); |
96 | - child: Image.network( | 109 | + Widget body = ListView( |
97 | - "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif", | 110 | + physics: const BouncingScrollPhysics( |
98 | - fit: BoxFit.cover, | 111 | + parent: AlwaysScrollableScrollPhysics(), |
99 | - ), | ||
100 | ), | 112 | ), |
101 | - ), | ||
102 | - ), | ||
103 | - ); | ||
104 | - Widget body = ListView( | ||
105 | - physics: const BouncingScrollPhysics( | ||
106 | - parent: AlwaysScrollableScrollPhysics(), | ||
107 | - ), | ||
108 | - children: <Widget>[ | ||
109 | - Stack( | ||
110 | - alignment: Alignment.bottomLeft, | ||
111 | children: <Widget>[ | 113 | children: <Widget>[ |
112 | - likeButton, | 114 | + Stack( |
113 | - avatar, | 115 | + alignment: Alignment.bottomLeft, |
114 | - Positioned( | 116 | + children: <Widget>[ |
115 | - child: GestureDetector( | 117 | + likeButton, |
116 | - child: CircleAvatar( | 118 | + avatar, |
117 | - backgroundColor: Colors.red.withOpacity(0.4), | 119 | + Positioned( |
118 | - radius: 14.px, | 120 | + child: GestureDetector( |
119 | - child: Icon( | 121 | + child: CircleAvatar( |
120 | - Icons.edit, | 122 | + backgroundColor: Colors.red.withOpacity(0.4), |
121 | - color: Colors.white, | 123 | + radius: 14.px, |
122 | - size: 16.px, | 124 | + child: Icon( |
125 | + Icons.edit, | ||
126 | + color: Colors.white, | ||
127 | + size: 16.px, | ||
128 | + ), | ||
129 | + ), | ||
130 | + onTap: () { | ||
131 | + NavigatorUtils.push( | ||
132 | + context, AccountRouter.accountEditPage); | ||
133 | + }, | ||
123 | ), | 134 | ), |
135 | + left: 64.px, | ||
136 | + bottom: 10.px, | ||
124 | ), | 137 | ), |
125 | - onTap: () { | 138 | + ], |
126 | - NavigatorUtils.push(context, AccountRouter.accountEditPage); | ||
127 | - }, | ||
128 | - ), | ||
129 | - left: 64.px, | ||
130 | - bottom: 10.px, | ||
131 | ), | 139 | ), |
132 | - ], | 140 | + Container( |
133 | - ), | 141 | + color: ColorPlate.white, |
134 | - Container( | 142 | + child: Column( |
135 | - color: ColorPlate.white, | 143 | + children: <Widget>[ |
136 | - child: Column( | 144 | + Container( |
137 | - children: <Widget>[ | 145 | + padding: EdgeInsets.only(left: 18.px), |
138 | - Container( | 146 | + color: ColorPlate.white, |
139 | - padding: EdgeInsets.only(left: 18.px), | 147 | + child: Column( |
140 | - color: ColorPlate.white, | 148 | + crossAxisAlignment: CrossAxisAlignment.start, |
141 | - child: Column( | 149 | + children: <Widget>[ |
142 | - crossAxisAlignment: CrossAxisAlignment.start, | 150 | + Text( |
143 | - children: <Widget>[ | 151 | + _user.email ?? '@唐宋八大家TOP8', |
144 | - const Text( | 152 | + style: StandardTextStyle.big, |
145 | - '@唐宋八大家TOP8', | 153 | + ), |
146 | - style: StandardTextStyle.big, | 154 | + Container(height: 8.px), |
155 | + Text( | ||
156 | + '朴实无华,且枯燥', | ||
157 | + style: StandardTextStyle.small.apply( | ||
158 | + color: Colors.black45, | ||
159 | + ), | ||
160 | + ), | ||
161 | + Container(height: 10.px), | ||
162 | + Row( | ||
163 | + children: const <Widget>[ | ||
164 | + _UserTag(tag: '幽默'), | ||
165 | + _UserTag(tag: '机智'), | ||
166 | + _UserTag(tag: '枯燥'), | ||
167 | + _UserTag(tag: '狮子座'), | ||
168 | + ], | ||
169 | + ), | ||
170 | + Container(height: 10.px), | ||
171 | + ], | ||
147 | ), | 172 | ), |
148 | - Container(height: 8.px), | 173 | + ), |
149 | - Text( | 174 | + Container( |
150 | - '朴实无华,且枯燥', | 175 | + color: ColorPlate.white, |
151 | - style: StandardTextStyle.small.apply( | 176 | + padding: EdgeInsets.symmetric( |
152 | - color: Colors.black45, | 177 | + horizontal: 8.px, |
153 | - ), | 178 | + vertical: 2.px, |
154 | ), | 179 | ), |
155 | - Container(height: 10.px), | 180 | + child: Row( |
156 | - Row( | 181 | + mainAxisAlignment: MainAxisAlignment.start, |
182 | + crossAxisAlignment: CrossAxisAlignment.center, | ||
157 | children: const <Widget>[ | 183 | children: const <Widget>[ |
158 | - _UserTag(tag: '幽默'), | 184 | + TextGroup('356', '关注'), |
159 | - _UserTag(tag: '机智'), | 185 | + TextGroup('145万', '粉丝'), |
160 | - _UserTag(tag: '枯燥'), | 186 | + TextGroup('1423万', '获赞'), |
161 | - _UserTag(tag: '狮子座'), | ||
162 | ], | 187 | ], |
163 | ), | 188 | ), |
164 | - Container(height: 10.px), | ||
165 | - ], | ||
166 | - ), | ||
167 | - ), | ||
168 | - Container( | ||
169 | - color: ColorPlate.white, | ||
170 | - padding: EdgeInsets.symmetric( | ||
171 | - horizontal: 8.px, | ||
172 | - vertical: 2.px, | ||
173 | - ), | ||
174 | - child: Row( | ||
175 | - mainAxisAlignment: MainAxisAlignment.start, | ||
176 | - crossAxisAlignment: CrossAxisAlignment.center, | ||
177 | - children: const <Widget>[ | ||
178 | - TextGroup('356', '关注'), | ||
179 | - TextGroup('145万', '粉丝'), | ||
180 | - TextGroup('1423万', '获赞'), | ||
181 | - ], | ||
182 | - ), | ||
183 | - ), | ||
184 | - Container( | ||
185 | - height: 10.px, | ||
186 | - margin: const EdgeInsets.symmetric(horizontal: 12), | ||
187 | - decoration: BoxDecoration( | ||
188 | - border: Border( | ||
189 | - bottom: BorderSide( | ||
190 | - color: Colors.white.withOpacity(0.1), | ||
191 | - ), | ||
192 | ), | 189 | ), |
193 | - ), | 190 | + Container( |
194 | - ), | 191 | + height: 10.px, |
195 | - const _UserVideoTable(), | 192 | + margin: const EdgeInsets.symmetric(horizontal: 12), |
196 | - ], | 193 | + decoration: BoxDecoration( |
197 | - ), | 194 | + border: Border( |
198 | - ), | 195 | + bottom: BorderSide( |
199 | - ], | 196 | + color: Colors.white.withOpacity(0.1), |
200 | - ); | 197 | + ), |
201 | - return Scaffold( | 198 | + ), |
202 | - body: Container( | ||
203 | - decoration: const BoxDecoration( | ||
204 | - image: DecorationImage( | ||
205 | - image: AssetImage("assets/images/poem/poem_background.png"), | ||
206 | - fit: BoxFit.fill, | ||
207 | - ), | ||
208 | - ), | ||
209 | - child: Stack( | ||
210 | - alignment: Alignment.topCenter, | ||
211 | - children: <Widget>[ | ||
212 | - Container( | ||
213 | - margin: const EdgeInsets.only(top: 500), | ||
214 | - height: double.infinity, | ||
215 | - width: double.infinity, | ||
216 | - color: ColorPlate.white, | ||
217 | - ), | ||
218 | - body, | ||
219 | - Container( | ||
220 | - alignment: Alignment.centerRight, | ||
221 | - height: 64.px, | ||
222 | - width: double.infinity, | ||
223 | - child: Row( | ||
224 | - mainAxisAlignment: MainAxisAlignment.end, | ||
225 | - children: [ | ||
226 | - IconButton( | ||
227 | - icon: const Icon( | ||
228 | - Icons.settings_outlined, | ||
229 | - color: Colors.black54, | ||
230 | ), | 199 | ), |
231 | - onPressed: () { | ||
232 | - NavigatorUtils.push(context, SettingRouter.settingPage); | ||
233 | - }, | ||
234 | ), | 200 | ), |
201 | + const _UserVideoTable(), | ||
235 | ], | 202 | ], |
236 | ), | 203 | ), |
237 | ), | 204 | ), |
238 | ], | 205 | ], |
239 | - ), | 206 | + ); |
240 | - ), | 207 | + return Scaffold( |
241 | - ); | 208 | + body: Container( |
209 | + decoration: const BoxDecoration( | ||
210 | + image: DecorationImage( | ||
211 | + image: AssetImage("assets/images/poem/poem_background.png"), | ||
212 | + fit: BoxFit.fill, | ||
213 | + ), | ||
214 | + ), | ||
215 | + child: Stack( | ||
216 | + alignment: Alignment.topCenter, | ||
217 | + children: <Widget>[ | ||
218 | + Container( | ||
219 | + margin: const EdgeInsets.only(top: 500), | ||
220 | + height: double.infinity, | ||
221 | + width: double.infinity, | ||
222 | + color: ColorPlate.white, | ||
223 | + ), | ||
224 | + body, | ||
225 | + Container( | ||
226 | + alignment: Alignment.centerRight, | ||
227 | + height: 64.px, | ||
228 | + width: double.infinity, | ||
229 | + child: Row( | ||
230 | + mainAxisAlignment: MainAxisAlignment.end, | ||
231 | + children: [ | ||
232 | + IconButton( | ||
233 | + icon: const Icon( | ||
234 | + Icons.settings_outlined, | ||
235 | + color: Colors.black54, | ||
236 | + ), | ||
237 | + onPressed: () { | ||
238 | + NavigatorUtils.push( | ||
239 | + context, SettingRouter.settingPage); | ||
240 | + }, | ||
241 | + ), | ||
242 | + ], | ||
243 | + ), | ||
244 | + ), | ||
245 | + ], | ||
246 | + ), | ||
247 | + ), | ||
248 | + ); | ||
249 | + case Status.ERROR: | ||
250 | + return Center( | ||
251 | + child: Text('暂时无法获取数据,请稍候再试!' + apiResponse.message.toString()), | ||
252 | + ); | ||
253 | + case Status.INITIAL: | ||
254 | + default: | ||
255 | + return const Center( | ||
256 | + child: Text('正在获取数据....'), | ||
257 | + ); | ||
258 | + } | ||
242 | } | 259 | } |
243 | } | 260 | } |
244 | 261 | ||
... | @@ -399,11 +416,12 @@ class _PointSelectTextButton extends StatelessWidget { | ... | @@ -399,11 +416,12 @@ class _PointSelectTextButton extends StatelessWidget { |
399 | final String title; | 416 | final String title; |
400 | final Function? onTap; | 417 | final Function? onTap; |
401 | 418 | ||
402 | - const _PointSelectTextButton(this.isSelect, | 419 | + const _PointSelectTextButton( |
403 | - this.title, { | 420 | + this.isSelect, |
404 | - Key? key, | 421 | + this.title, { |
405 | - this.onTap, | 422 | + Key? key, |
406 | - }) : super(key: key); | 423 | + this.onTap, |
424 | + }) : super(key: key); | ||
407 | 425 | ||
408 | @override | 426 | @override |
409 | Widget build(BuildContext context) { | 427 | Widget build(BuildContext context) { |
... | @@ -413,13 +431,13 @@ class _PointSelectTextButton extends StatelessWidget { | ... | @@ -413,13 +431,13 @@ class _PointSelectTextButton extends StatelessWidget { |
413 | children: <Widget>[ | 431 | children: <Widget>[ |
414 | isSelect | 432 | isSelect |
415 | ? Container( | 433 | ? Container( |
416 | - width: 6.px, | 434 | + width: 6.px, |
417 | - height: 6.px, | 435 | + height: 6.px, |
418 | - decoration: BoxDecoration( | 436 | + decoration: BoxDecoration( |
419 | - color: ColorPlate.orange, | 437 | + color: ColorPlate.orange, |
420 | - borderRadius: BorderRadius.circular(3), | 438 | + borderRadius: BorderRadius.circular(3), |
421 | - ), | 439 | + ), |
422 | - ) | 440 | + ) |
423 | : Container(), | 441 | : Container(), |
424 | Container( | 442 | Container( |
425 | padding: const EdgeInsets.only(left: 2), | 443 | padding: const EdgeInsets.only(left: 2), |
... | @@ -438,11 +456,12 @@ class TextGroup extends StatelessWidget { | ... | @@ -438,11 +456,12 @@ class TextGroup extends StatelessWidget { |
438 | final String title, tag; | 456 | final String title, tag; |
439 | final Color? color; | 457 | final Color? color; |
440 | 458 | ||
441 | - const TextGroup(this.title, | 459 | + const TextGroup( |
442 | - this.tag, { | 460 | + this.title, |
443 | - Key? key, | 461 | + this.tag, { |
444 | - this.color, | 462 | + Key? key, |
445 | - }) : super(key: key); | 463 | + this.color, |
464 | + }) : super(key: key); | ||
446 | 465 | ||
447 | @override | 466 | @override |
448 | Widget build(BuildContext context) { | 467 | Widget build(BuildContext context) { | ... | ... |
1 | +import 'package:Parlando/account/models/user_entity.dart'; | ||
2 | +import 'package:Parlando/apis/api_response.dart'; | ||
3 | +import 'package:Parlando/net/dio_utils.dart'; | ||
4 | +import 'package:Parlando/net/http_api.dart'; | ||
5 | +import 'package:flutter/material.dart'; | ||
6 | + | ||
7 | +class AccountViewProvider with ChangeNotifier { | ||
8 | + ApiResponse _apiResponse = ApiResponse.initial('Empty data'); | ||
9 | + UserData? _user; | ||
10 | + | ||
11 | + ApiResponse get response { | ||
12 | + return _apiResponse; | ||
13 | + } | ||
14 | + | ||
15 | + UserData? get media { | ||
16 | + return _user; | ||
17 | + } | ||
18 | + | ||
19 | + Future<void> fetchAccountData(String value) async { | ||
20 | + _apiResponse = ApiResponse.loading('Fetching artist data'); | ||
21 | + // TODO 不知道为啥会提前触发,先注释掉吧 | ||
22 | + | ||
23 | + DioUtils.instance.asyncRequestNetwork<UserEntity>( | ||
24 | + Method.get, | ||
25 | + HttpApi.user, | ||
26 | + onSuccess: (data) { | ||
27 | + _apiResponse = ApiResponse.completed(data!.data); | ||
28 | + notifyListeners(); | ||
29 | + }, | ||
30 | + onError: (code, msg) { | ||
31 | + _apiResponse = ApiResponse.error(msg); | ||
32 | + notifyListeners(); | ||
33 | + }, | ||
34 | + ); | ||
35 | + } | ||
36 | + | ||
37 | + void setSelectedAccount(UserData? user) { | ||
38 | + _user = user; | ||
39 | + // notifyListeners(); | ||
40 | + } | ||
41 | +} |
lib/apis/api_response.dart
0 → 100644
1 | +class ApiResponse<T> { | ||
2 | + Status status; | ||
3 | + T? data; | ||
4 | + String? message; | ||
5 | + | ||
6 | + ApiResponse.initial(this.message) : status = Status.INITIAL; | ||
7 | + | ||
8 | + ApiResponse.loading(this.message) : status = Status.LOADING; | ||
9 | + | ||
10 | + ApiResponse.completed(this.data) : status = Status.COMPLETED; | ||
11 | + | ||
12 | + ApiResponse.error(this.message) : status = Status.ERROR; | ||
13 | + | ||
14 | + @override | ||
15 | + String toString() { | ||
16 | + return "Status : $status \n Message : $message \n Data : $data"; | ||
17 | + } | ||
18 | +} | ||
19 | + | ||
20 | +enum Status { INITIAL, LOADING, COMPLETED, ERROR } |
lib/apis/app_exception.dart
0 → 100644
1 | +class AppException implements Exception { | ||
2 | + late final String? _message; | ||
3 | + late final String? _prefix; | ||
4 | + | ||
5 | + AppException([this._message, this._prefix]); | ||
6 | + | ||
7 | + @override | ||
8 | + String toString() { | ||
9 | + return "$_prefix$_message"; | ||
10 | + } | ||
11 | +} | ||
12 | + | ||
13 | +class FetchDataException extends AppException { | ||
14 | + FetchDataException([String? message]) | ||
15 | + : super(message, "Error During Communication: "); | ||
16 | +} | ||
17 | + | ||
18 | +class BadRequestException extends AppException { | ||
19 | + BadRequestException([message]) : super(message, "Invalid Request: "); | ||
20 | +} | ||
21 | + | ||
22 | +class UnauthorisedException extends AppException { | ||
23 | + UnauthorisedException([message]) : super(message, "Unauthorised Request: "); | ||
24 | +} | ||
25 | + | ||
26 | +class InvalidInputException extends AppException { | ||
27 | + InvalidInputException([String? message]) : super(message, "Invalid Input: "); | ||
28 | +} |
1 | import 'package:Parlando/generated/json/base/json_convert_content.dart'; | 1 | import 'package:Parlando/generated/json/base/json_convert_content.dart'; |
2 | import 'package:Parlando/login/models/auth_entity.dart'; | 2 | import 'package:Parlando/login/models/auth_entity.dart'; |
3 | 3 | ||
4 | -AuthEntity $LoginEntityFromJson(Map<String, dynamic> json) { | 4 | +AuthEntity $AuthEntityFromJson(Map<String, dynamic> json) { |
5 | - final AuthEntity loginEntity = AuthEntity(); | 5 | + final AuthEntity authEntity = AuthEntity(); |
6 | final String? status = jsonConvert.convert<String>(json['status']); | 6 | final String? status = jsonConvert.convert<String>(json['status']); |
7 | if (status != null) { | 7 | if (status != null) { |
8 | - loginEntity.status = status; | 8 | + authEntity.status = status; |
9 | } | 9 | } |
10 | final int? code = jsonConvert.convert<int>(json['code']); | 10 | final int? code = jsonConvert.convert<int>(json['code']); |
11 | if (code != null) { | 11 | if (code != null) { |
12 | - loginEntity.code = code; | 12 | + authEntity.code = code; |
13 | } | 13 | } |
14 | final String? message = jsonConvert.convert<String>(json['message']); | 14 | final String? message = jsonConvert.convert<String>(json['message']); |
15 | if (message != null) { | 15 | if (message != null) { |
16 | - loginEntity.message = message; | 16 | + authEntity.message = message; |
17 | } | 17 | } |
18 | final AuthData? data = jsonConvert.convert<AuthData>(json['data']); | 18 | final AuthData? data = jsonConvert.convert<AuthData>(json['data']); |
19 | if (data != null) { | 19 | if (data != null) { |
20 | - loginEntity.data = data; | 20 | + authEntity.data = data; |
21 | } | 21 | } |
22 | final AuthError? error = jsonConvert.convert<AuthError>(json['error']); | 22 | final AuthError? error = jsonConvert.convert<AuthError>(json['error']); |
23 | if (error != null) { | 23 | if (error != null) { |
24 | - loginEntity.error = error; | 24 | + authEntity.error = error; |
25 | } | 25 | } |
26 | - return loginEntity; | 26 | + return authEntity; |
27 | } | 27 | } |
28 | 28 | ||
29 | -Map<String, dynamic> $LoginEntityToJson(AuthEntity entity) { | 29 | +Map<String, dynamic> $AuthEntityToJson(AuthEntity entity) { |
30 | final Map<String, dynamic> data = <String, dynamic>{}; | 30 | final Map<String, dynamic> data = <String, dynamic>{}; |
31 | data['status'] = entity.status; | 31 | data['status'] = entity.status; |
32 | data['code'] = entity.code; | 32 | data['code'] = entity.code; |
... | @@ -36,27 +36,27 @@ Map<String, dynamic> $LoginEntityToJson(AuthEntity entity) { | ... | @@ -36,27 +36,27 @@ Map<String, dynamic> $LoginEntityToJson(AuthEntity entity) { |
36 | return data; | 36 | return data; |
37 | } | 37 | } |
38 | 38 | ||
39 | -AuthData $LoginDataFromJson(Map<String, dynamic> json) { | 39 | +AuthData $AuthDataFromJson(Map<String, dynamic> json) { |
40 | - final AuthData loginData = AuthData(); | 40 | + final AuthData authData = AuthData(); |
41 | final String? token = jsonConvert.convert<String>(json['token']); | 41 | final String? token = jsonConvert.convert<String>(json['token']); |
42 | if (token != null) { | 42 | if (token != null) { |
43 | - loginData.token = token; | 43 | + authData.token = token; |
44 | } | 44 | } |
45 | - return loginData; | 45 | + return authData; |
46 | } | 46 | } |
47 | 47 | ||
48 | -Map<String, dynamic> $LoginDataToJson(AuthData entity) { | 48 | +Map<String, dynamic> $AuthDataToJson(AuthData entity) { |
49 | final Map<String, dynamic> data = <String, dynamic>{}; | 49 | final Map<String, dynamic> data = <String, dynamic>{}; |
50 | data['token'] = entity.token; | 50 | data['token'] = entity.token; |
51 | return data; | 51 | return data; |
52 | } | 52 | } |
53 | 53 | ||
54 | -AuthError $LoginErrorFromJson(Map<String, dynamic> json) { | 54 | +AuthError $AuthErrorFromJson(Map<String, dynamic> json) { |
55 | - final AuthError loginError = AuthError(); | 55 | + final AuthError authError = AuthError(); |
56 | - return loginError; | 56 | + return authError; |
57 | } | 57 | } |
58 | 58 | ||
59 | -Map<String, dynamic> $LoginErrorToJson(AuthError entity) { | 59 | +Map<String, dynamic> $AuthErrorToJson(AuthError entity) { |
60 | final Map<String, dynamic> data = <String, dynamic>{}; | 60 | final Map<String, dynamic> data = <String, dynamic>{}; |
61 | return data; | 61 | return data; |
62 | } | 62 | } | ... | ... |
... | @@ -3,24 +3,41 @@ | ... | @@ -3,24 +3,41 @@ |
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:Parlando/account/models/user_entity.dart'; | 7 | import 'package:Parlando/account/models/user_entity.dart'; |
7 | -import 'package:Parlando/generated/json/user_entity.g.dart'; | ||
8 | import 'package:Parlando/category/models/category_item_entity.dart'; | 8 | import 'package:Parlando/category/models/category_item_entity.dart'; |
9 | -import 'package:Parlando/generated/json/category_item_entity.g.dart'; | ||
10 | import 'package:Parlando/home/models/setting_entity.dart'; | 9 | import 'package:Parlando/home/models/setting_entity.dart'; |
11 | -import 'package:Parlando/generated/json/setting_entity.g.dart'; | ||
12 | import 'package:Parlando/login/models/auth_entity.dart'; | 10 | import 'package:Parlando/login/models/auth_entity.dart'; |
13 | -import 'package:Parlando/generated/json/login_entity.g.dart'; | ||
14 | import 'package:Parlando/poem/models/lang_sort_entity.dart'; | 11 | import 'package:Parlando/poem/models/lang_sort_entity.dart'; |
15 | -import 'package:Parlando/generated/json/lang_sort_entity.g.dart'; | ||
16 | import 'package:Parlando/poem/models/search_entity.dart'; | 12 | import 'package:Parlando/poem/models/search_entity.dart'; |
17 | -import 'package:Parlando/generated/json/search_entity.g.dart'; | ||
18 | import 'package:Parlando/timeline/models/friend_entity.dart'; | 13 | import 'package:Parlando/timeline/models/friend_entity.dart'; |
19 | -import 'package:Parlando/generated/json/friend_entity.g.dart'; | ||
20 | 14 | ||
21 | JsonConvert jsonConvert = JsonConvert(); | 15 | JsonConvert jsonConvert = JsonConvert(); |
22 | 16 | ||
17 | +typedef JsonConvertFunction<T> = T Function(Map<String, dynamic> json); | ||
18 | + | ||
23 | class JsonConvert { | 19 | class JsonConvert { |
20 | + static final Map<String, JsonConvertFunction> _convertFuncMap = { | ||
21 | + (UserEntity).toString(): UserEntity.fromJson, | ||
22 | + (UserData).toString(): UserData.fromJson, | ||
23 | + (UserError).toString(): UserError.fromJson, | ||
24 | + (CategoryItemEntity).toString(): CategoryItemEntity.fromJson, | ||
25 | + (SettingEntity).toString(): SettingEntity.fromJson, | ||
26 | + (SettingData).toString(): SettingData.fromJson, | ||
27 | + (SettingDataLoginSetting).toString(): SettingDataLoginSetting.fromJson, | ||
28 | + (SettingError).toString(): SettingError.fromJson, | ||
29 | + (AuthEntity).toString(): AuthEntity.fromJson, | ||
30 | + (AuthData).toString(): AuthData.fromJson, | ||
31 | + (AuthError).toString(): AuthError.fromJson, | ||
32 | + (LangSortEntity).toString(): LangSortEntity.fromJson, | ||
33 | + (SearchEntity).toString(): SearchEntity.fromJson, | ||
34 | + (SearchItems).toString(): SearchItems.fromJson, | ||
35 | + (SearchItemsOwner).toString(): SearchItemsOwner.fromJson, | ||
36 | + (SearchItemsLicense).toString(): SearchItemsLicense.fromJson, | ||
37 | + (FriendEntity).toString(): FriendEntity.fromJson, | ||
38 | + (FriendData).toString(): FriendData.fromJson, | ||
39 | + }; | ||
40 | + | ||
24 | T? convert<T>(dynamic value) { | 41 | T? convert<T>(dynamic value) { |
25 | if (value == null) { | 42 | if (value == null) { |
26 | return null; | 43 | return null; |
... | @@ -35,7 +52,7 @@ class JsonConvert { | ... | @@ -35,7 +52,7 @@ class JsonConvert { |
35 | try { | 52 | try { |
36 | return value.map((dynamic e) => asT<T>(e)).toList(); | 53 | return value.map((dynamic e) => asT<T>(e)).toList(); |
37 | } catch (e, stackTrace) { | 54 | } catch (e, stackTrace) { |
38 | - print('asT<$T> $e $stackTrace'); | 55 | + debugPrint('asT<$T> $e $stackTrace'); |
39 | return <T>[]; | 56 | return <T>[]; |
40 | } | 57 | } |
41 | } | 58 | } |
... | @@ -47,15 +64,16 @@ class JsonConvert { | ... | @@ -47,15 +64,16 @@ class JsonConvert { |
47 | try { | 64 | try { |
48 | return (value as List<dynamic>).map((dynamic e) => asT<T>(e)!).toList(); | 65 | return (value as List<dynamic>).map((dynamic e) => asT<T>(e)!).toList(); |
49 | } catch (e, stackTrace) { | 66 | } catch (e, stackTrace) { |
50 | - print('asT<$T> $e $stackTrace'); | 67 | + debugPrint('asT<$T> $e $stackTrace'); |
51 | return <T>[]; | 68 | return <T>[]; |
52 | } | 69 | } |
53 | } | 70 | } |
71 | + | ||
54 | T? asT<T extends Object?>(dynamic value) { | 72 | T? asT<T extends Object?>(dynamic value) { |
55 | if (value is T) { | 73 | if (value is T) { |
56 | return value; | 74 | return value; |
57 | } | 75 | } |
58 | - final String type = T.toString(); | 76 | + final String type = T.toString(); |
59 | try { | 77 | try { |
60 | final String valueS = value.toString(); | 78 | final String valueS = value.toString(); |
61 | if (type == "String") { | 79 | if (type == "String") { |
... | @@ -66,87 +84,48 @@ class JsonConvert { | ... | @@ -66,87 +84,48 @@ class JsonConvert { |
66 | return double.tryParse(valueS)?.toInt() as T?; | 84 | return double.tryParse(valueS)?.toInt() as T?; |
67 | } else { | 85 | } else { |
68 | return intValue as T; | 86 | return intValue as T; |
69 | - } } else if (type == "double") { | 87 | + } |
88 | + } else if (type == "double") { | ||
70 | return double.parse(valueS) as T; | 89 | return double.parse(valueS) as T; |
71 | - } else if (type == "DateTime") { | 90 | + } else if (type == "DateTime") { |
72 | return DateTime.parse(valueS) as T; | 91 | return DateTime.parse(valueS) as T; |
73 | - } else if (type == "bool") { | 92 | + } else if (type == "bool") { |
74 | if (valueS == '0' || valueS == '1') { | 93 | if (valueS == '0' || valueS == '1') { |
75 | return (valueS == '1') as T; | 94 | return (valueS == '1') as T; |
76 | } | 95 | } |
77 | return (valueS == 'true') as T; | 96 | return (valueS == 'true') as T; |
97 | + } else if (type == "Map" || type.startsWith("Map<")) { | ||
98 | + return value as T; | ||
78 | } else { | 99 | } else { |
79 | - return JsonConvert.fromJsonAsT<T>(value); | 100 | + if (_convertFuncMap.containsKey(type)) { |
101 | + return _convertFuncMap[type]!(value) as T; | ||
102 | + } else { | ||
103 | + throw UnimplementedError('$type unimplemented'); | ||
104 | + } | ||
80 | } | 105 | } |
81 | } catch (e, stackTrace) { | 106 | } catch (e, stackTrace) { |
82 | - print('asT<$T> $e $stackTrace'); | 107 | + debugPrint('asT<$T> $e $stackTrace'); |
83 | return null; | 108 | return null; |
84 | } | 109 | } |
85 | - } | 110 | + } |
86 | - //Go back to a single instance by type | ||
87 | - static M? _fromJsonSingle<M>(Map<String, dynamic> json) { | ||
88 | - final String type = M.toString(); | ||
89 | - if (type == (UserEntity).toString()) { | ||
90 | - return UserEntity.fromJson(json) as M; | ||
91 | - } | ||
92 | - if (type == (CategoryItemEntity).toString()) { | ||
93 | - return CategoryItemEntity.fromJson(json) as M; | ||
94 | - } | ||
95 | - if (type == (SettingEntity).toString()) { | ||
96 | - return SettingEntity.fromJson(json) as M; | ||
97 | - } | ||
98 | - if (type == (SettingData).toString()) { | ||
99 | - return SettingData.fromJson(json) as M; | ||
100 | - } | ||
101 | - if (type == (SettingDataLoginSetting).toString()) { | ||
102 | - return SettingDataLoginSetting.fromJson(json) as M; | ||
103 | - } | ||
104 | - if (type == (SettingError).toString()) { | ||
105 | - return SettingError.fromJson(json) as M; | ||
106 | - } | ||
107 | - if (type == (AuthEntity).toString()) { | ||
108 | - return AuthEntity.fromJson(json) as M; | ||
109 | - } | ||
110 | - if (type == (AuthData).toString()) { | ||
111 | - return AuthData.fromJson(json) as M; | ||
112 | - } | ||
113 | - if (type == (AuthError).toString()) { | ||
114 | - return AuthError.fromJson(json) as M; | ||
115 | - } | ||
116 | - if (type == (LangSortEntity).toString()) { | ||
117 | - return LangSortEntity.fromJson(json) as M; | ||
118 | - } | ||
119 | - if (type == (SearchEntity).toString()) { | ||
120 | - return SearchEntity.fromJson(json) as M; | ||
121 | - } | ||
122 | - if (type == (SearchItems).toString()) { | ||
123 | - return SearchItems.fromJson(json) as M; | ||
124 | - } | ||
125 | - if (type == (SearchItemsOwner).toString()) { | ||
126 | - return SearchItemsOwner.fromJson(json) as M; | ||
127 | - } | ||
128 | - if (type == (SearchItemsLicense).toString()) { | ||
129 | - return SearchItemsLicense.fromJson(json) as M; | ||
130 | - } | ||
131 | - if (type == (FriendEntity).toString()) { | ||
132 | - return FriendEntity.fromJson(json) as M; | ||
133 | - } | ||
134 | - if (type == (FriendData).toString()) { | ||
135 | - return FriendData.fromJson(json) as M; | ||
136 | - } | ||
137 | - | ||
138 | - print("$type not found"); | ||
139 | - | ||
140 | - return null; | ||
141 | -} | ||
142 | 111 | ||
143 | //list is returned by type | 112 | //list is returned by type |
144 | - static M? _getListChildType<M>(List<Map<String, dynamic>> data) { | 113 | + static M? _getListChildType<M>(List<Map<String, dynamic>> data) { |
145 | if (<UserEntity>[] is M) { | 114 | if (<UserEntity>[] is M) { |
146 | return data | 115 | return data |
147 | .map<UserEntity>((Map<String, dynamic> e) => UserEntity.fromJson(e)) | 116 | .map<UserEntity>((Map<String, dynamic> e) => UserEntity.fromJson(e)) |
148 | .toList() as M; | 117 | .toList() as M; |
149 | } | 118 | } |
119 | + if (<UserData>[] is M) { | ||
120 | + return data | ||
121 | + .map<UserData>((Map<String, dynamic> e) => UserData.fromJson(e)) | ||
122 | + .toList() as M; | ||
123 | + } | ||
124 | + if (<UserError>[] is M) { | ||
125 | + return data | ||
126 | + .map<UserError>((Map<String, dynamic> e) => UserError.fromJson(e)) | ||
127 | + .toList() as M; | ||
128 | + } | ||
150 | if (<CategoryItemEntity>[] is M) { | 129 | if (<CategoryItemEntity>[] is M) { |
151 | return data | 130 | return data |
152 | .map<CategoryItemEntity>( | 131 | .map<CategoryItemEntity>( |
... | @@ -232,18 +211,17 @@ class JsonConvert { | ... | @@ -232,18 +211,17 @@ class JsonConvert { |
232 | .toList() as M; | 211 | .toList() as M; |
233 | } | 212 | } |
234 | 213 | ||
235 | - print("${M.toString()} not found"); | 214 | + debugPrint("${M.toString()} not found"); |
236 | - | 215 | + |
237 | - return null; | 216 | + return null; |
238 | -} | 217 | + } |
239 | 218 | ||
240 | static M? fromJsonAsT<M>(dynamic json) { | 219 | static M? fromJsonAsT<M>(dynamic json) { |
241 | - if(json == null){ | 220 | + if (json is List) { |
242 | - return null; | 221 | + return _getListChildType<M>( |
243 | - } if (json is List) { | 222 | + json.map((e) => e as Map<String, dynamic>).toList()); |
244 | - return _getListChildType<M>(json.map((e) => e as Map<String, dynamic>).toList()); | 223 | + } else { |
245 | - } else { | 224 | + return jsonConvert.asT<M>(json); |
246 | - return _fromJsonSingle<M>(json as Map<String, dynamic>); | 225 | + } |
247 | - } | 226 | + } |
248 | - } | ||
249 | } | 227 | } |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -3,25 +3,110 @@ import 'package:Parlando/account/models/user_entity.dart'; | ... | @@ -3,25 +3,110 @@ import 'package:Parlando/account/models/user_entity.dart'; |
3 | 3 | ||
4 | UserEntity $UserEntityFromJson(Map<String, dynamic> json) { | 4 | UserEntity $UserEntityFromJson(Map<String, dynamic> json) { |
5 | final UserEntity userEntity = UserEntity(); | 5 | final UserEntity userEntity = UserEntity(); |
6 | + final String? status = jsonConvert.convert<String>(json['status']); | ||
7 | + if (status != null) { | ||
8 | + userEntity.status = status; | ||
9 | + } | ||
10 | + final int? code = jsonConvert.convert<int>(json['code']); | ||
11 | + if (code != null) { | ||
12 | + userEntity.code = code; | ||
13 | + } | ||
14 | + final String? message = jsonConvert.convert<String>(json['message']); | ||
15 | + if (message != null) { | ||
16 | + userEntity.message = message; | ||
17 | + } | ||
18 | + final UserData? data = jsonConvert.convert<UserData>(json['data']); | ||
19 | + if (data != null) { | ||
20 | + userEntity.data = data; | ||
21 | + } | ||
22 | + final UserError? error = jsonConvert.convert<UserError>(json['error']); | ||
23 | + if (error != null) { | ||
24 | + userEntity.error = error; | ||
25 | + } | ||
26 | + return userEntity; | ||
27 | +} | ||
28 | + | ||
29 | +Map<String, dynamic> $UserEntityToJson(UserEntity entity) { | ||
30 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
31 | + data['status'] = entity.status; | ||
32 | + data['code'] = entity.code; | ||
33 | + data['message'] = entity.message; | ||
34 | + data['data'] = entity.data?.toJson(); | ||
35 | + data['error'] = entity.error?.toJson(); | ||
36 | + return data; | ||
37 | +} | ||
38 | + | ||
39 | +UserData $UserDataFromJson(Map<String, dynamic> json) { | ||
40 | + final UserData userData = UserData(); | ||
6 | final int? id = jsonConvert.convert<int>(json['id']); | 41 | final int? id = jsonConvert.convert<int>(json['id']); |
7 | if (id != null) { | 42 | if (id != null) { |
8 | - userEntity.id = id; | 43 | + userData.id = id; |
44 | + } | ||
45 | + final dynamic? nickname = jsonConvert.convert<dynamic>(json['nickname']); | ||
46 | + if (nickname != null) { | ||
47 | + userData.nickname = nickname; | ||
48 | + } | ||
49 | + final dynamic? mobile = jsonConvert.convert<dynamic>(json['mobile']); | ||
50 | + if (mobile != null) { | ||
51 | + userData.mobile = mobile; | ||
9 | } | 52 | } |
10 | - final String? name = jsonConvert.convert<String>(json['name']); | 53 | + final String? email = jsonConvert.convert<String>(json['email']); |
11 | - if (name != null) { | 54 | + if (email != null) { |
12 | - userEntity.name = name; | 55 | + userData.email = email; |
13 | } | 56 | } |
14 | final String? avatar = jsonConvert.convert<String>(json['avatar']); | 57 | final String? avatar = jsonConvert.convert<String>(json['avatar']); |
15 | if (avatar != null) { | 58 | if (avatar != null) { |
16 | - userEntity.avatar = avatar; | 59 | + userData.avatar = avatar; |
17 | } | 60 | } |
18 | - return userEntity; | 61 | + final String? gender = jsonConvert.convert<String>(json['gender']); |
62 | + if (gender != null) { | ||
63 | + userData.gender = gender; | ||
64 | + } | ||
65 | + final dynamic? provider = jsonConvert.convert<dynamic>(json['provider']); | ||
66 | + if (provider != null) { | ||
67 | + userData.provider = provider; | ||
68 | + } | ||
69 | + final dynamic? providerId = jsonConvert.convert<dynamic>(json['provider_id']); | ||
70 | + if (providerId != null) { | ||
71 | + userData.providerId = providerId; | ||
72 | + } | ||
73 | + final String? state = jsonConvert.convert<String>(json['state']); | ||
74 | + if (state != null) { | ||
75 | + userData.state = state; | ||
76 | + } | ||
77 | + final String? createdAt = jsonConvert.convert<String>(json['created_at']); | ||
78 | + if (createdAt != null) { | ||
79 | + userData.createdAt = createdAt; | ||
80 | + } | ||
81 | + final String? updatedAt = jsonConvert.convert<String>(json['updated_at']); | ||
82 | + if (updatedAt != null) { | ||
83 | + userData.updatedAt = updatedAt; | ||
84 | + } | ||
85 | + return userData; | ||
19 | } | 86 | } |
20 | 87 | ||
21 | -Map<String, dynamic> $UserEntityToJson(UserEntity entity) { | ||
22 | - final Map<String, dynamic> data = <String, dynamic>{}; | ||
23 | - data['id'] = entity.id; | ||
24 | - data['name'] = entity.name; | ||
25 | - data['avatar'] = entity.avatar; | ||
26 | - return data; | ||
27 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
88 | +Map<String, dynamic> $UserDataToJson(UserData entity) { | ||
89 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
90 | + data['id'] = entity.id; | ||
91 | + data['nickname'] = entity.nickname; | ||
92 | + data['mobile'] = entity.mobile; | ||
93 | + data['email'] = entity.email; | ||
94 | + data['avatar'] = entity.avatar; | ||
95 | + data['gender'] = entity.gender; | ||
96 | + data['provider'] = entity.provider; | ||
97 | + data['provider_id'] = entity.providerId; | ||
98 | + data['state'] = entity.state; | ||
99 | + data['created_at'] = entity.createdAt; | ||
100 | + data['updated_at'] = entity.updatedAt; | ||
101 | + return data; | ||
102 | +} | ||
103 | + | ||
104 | +UserError $UserErrorFromJson(Map<String, dynamic> json) { | ||
105 | + final UserError userError = UserError(); | ||
106 | + return userError; | ||
107 | +} | ||
108 | + | ||
109 | +Map<String, dynamic> $UserErrorToJson(UserError entity) { | ||
110 | + final Map<String, dynamic> data = <String, dynamic>{}; | ||
111 | + return data; | ||
112 | +} | ... | ... |
1 | import 'dart:convert'; | 1 | import 'dart:convert'; |
2 | import 'package:Parlando/generated/json/base/json_field.dart'; | 2 | import 'package:Parlando/generated/json/base/json_field.dart'; |
3 | -import 'package:Parlando/generated/json/login_entity.g.dart'; | 3 | +import 'package:Parlando/generated/json/auth_entity.g.dart'; |
4 | 4 | ||
5 | @JsonSerializable() | 5 | @JsonSerializable() |
6 | class AuthEntity { | 6 | class AuthEntity { |
... | @@ -13,9 +13,9 @@ class AuthEntity { | ... | @@ -13,9 +13,9 @@ class AuthEntity { |
13 | AuthEntity(); | 13 | AuthEntity(); |
14 | 14 | ||
15 | factory AuthEntity.fromJson(Map<String, dynamic> json) => | 15 | factory AuthEntity.fromJson(Map<String, dynamic> json) => |
16 | - $LoginEntityFromJson(json); | 16 | + $AuthEntityFromJson(json); |
17 | 17 | ||
18 | - Map<String, dynamic> toJson() => $LoginEntityToJson(this); | 18 | + Map<String, dynamic> toJson() => $AuthEntityToJson(this); |
19 | 19 | ||
20 | @override | 20 | @override |
21 | String toString() { | 21 | String toString() { |
... | @@ -30,9 +30,9 @@ class AuthData { | ... | @@ -30,9 +30,9 @@ class AuthData { |
30 | AuthData(); | 30 | AuthData(); |
31 | 31 | ||
32 | factory AuthData.fromJson(Map<String, dynamic> json) => | 32 | factory AuthData.fromJson(Map<String, dynamic> json) => |
33 | - $LoginDataFromJson(json); | 33 | + $AuthDataFromJson(json); |
34 | 34 | ||
35 | - Map<String, dynamic> toJson() => $LoginDataToJson(this); | 35 | + Map<String, dynamic> toJson() => $AuthDataToJson(this); |
36 | 36 | ||
37 | @override | 37 | @override |
38 | String toString() { | 38 | String toString() { |
... | @@ -45,12 +45,12 @@ class AuthError { | ... | @@ -45,12 +45,12 @@ class AuthError { |
45 | AuthError(); | 45 | AuthError(); |
46 | 46 | ||
47 | factory AuthError.fromJson(Map<String, dynamic> json) => | 47 | factory AuthError.fromJson(Map<String, dynamic> json) => |
48 | - $LoginErrorFromJson(json); | 48 | + $AuthErrorFromJson(json); |
49 | 49 | ||
50 | - Map<String, dynamic> toJson() => $LoginErrorToJson(this); | 50 | + Map<String, dynamic> toJson() => $AuthErrorToJson(this); |
51 | 51 | ||
52 | @override | 52 | @override |
53 | String toString() { | 53 | String toString() { |
54 | return jsonEncode(this); | 54 | return jsonEncode(this); |
55 | } | 55 | } |
56 | -} | 56 | +} |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
1 | +import 'package:Parlando/account/view_models/account_view_model.dart'; | ||
1 | import 'package:dio/dio.dart'; | 2 | import 'package:dio/dio.dart'; |
2 | import 'package:flustars/flustars.dart'; | 3 | import 'package:flustars/flustars.dart'; |
3 | import 'package:flutter/material.dart'; | 4 | import 'package:flutter/material.dart'; |
... | @@ -88,15 +89,10 @@ class MyApp extends StatelessWidget { | ... | @@ -88,15 +89,10 @@ class MyApp extends StatelessWidget { |
88 | /// 统一添加身份验证请求头 | 89 | /// 统一添加身份验证请求头 |
89 | interceptors.add(AuthInterceptor()); | 90 | interceptors.add(AuthInterceptor()); |
90 | 91 | ||
91 | - /// 刷新Token | ||
92 | - interceptors.add(TokenInterceptor()); | ||
93 | - | ||
94 | /// 打印Log(生产模式去除) | 92 | /// 打印Log(生产模式去除) |
95 | if (!Constant.inProduction) { | 93 | if (!Constant.inProduction) { |
96 | interceptors.add(LoggingInterceptor()); | 94 | interceptors.add(LoggingInterceptor()); |
97 | } | 95 | } |
98 | - | ||
99 | - /// 适配数据(根据自己的数据结构,可自行选择添加) | ||
100 | interceptors.add(AdapterInterceptor()); | 96 | interceptors.add(AdapterInterceptor()); |
101 | configDio( | 97 | configDio( |
102 | baseUrl: 'http://www.yiyan.pub/api/v1/', | 98 | baseUrl: 'http://www.yiyan.pub/api/v1/', |
... | @@ -131,7 +127,8 @@ class MyApp extends StatelessWidget { | ... | @@ -131,7 +127,8 @@ class MyApp extends StatelessWidget { |
131 | final Widget app = MultiProvider( | 127 | final Widget app = MultiProvider( |
132 | providers: [ | 128 | providers: [ |
133 | ChangeNotifierProvider(create: (_) => ThemeProvider()), | 129 | ChangeNotifierProvider(create: (_) => ThemeProvider()), |
134 | - ChangeNotifierProvider(create: (_) => LocaleProvider()) | 130 | + ChangeNotifierProvider(create: (_) => LocaleProvider()), |
131 | + ChangeNotifierProvider(create: (_) => AccountViewProvider()) | ||
135 | ], | 132 | ], |
136 | child: Consumer2<ThemeProvider, LocaleProvider>( | 133 | child: Consumer2<ThemeProvider, LocaleProvider>( |
137 | builder: | 134 | builder: |
... | @@ -145,14 +142,13 @@ class MyApp extends StatelessWidget { | ... | @@ -145,14 +142,13 @@ class MyApp extends StatelessWidget { |
145 | return OKToast( | 142 | return OKToast( |
146 | backgroundColor: Colors.black54, | 143 | backgroundColor: Colors.black54, |
147 | textPadding: | 144 | textPadding: |
148 | - const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10.0), | 145 | + const EdgeInsets.symmetric(horizontal: 16.0, vertical: 10.0), |
149 | radius: 20.0, | 146 | radius: 20.0, |
150 | position: ToastPosition.bottom, | 147 | position: ToastPosition.bottom, |
151 | child: app); | 148 | child: app); |
152 | } | 149 | } |
153 | 150 | ||
154 | - Widget _buildMaterialApp( | 151 | + Widget _buildMaterialApp(ThemeProvider provider, LocaleProvider localeProvider) { |
155 | - ThemeProvider provider, LocaleProvider localeProvider) { | ||
156 | return MaterialApp( | 152 | return MaterialApp( |
157 | title: '一言', | 153 | title: '一言', |
158 | // showPerformanceOverlay: true, //显示性能标签 | 154 | // showPerformanceOverlay: true, //显示性能标签 | ... | ... |
... | @@ -120,6 +120,33 @@ class DioUtils { | ... | @@ -120,6 +120,33 @@ class DioUtils { |
120 | return options; | 120 | return options; |
121 | } | 121 | } |
122 | 122 | ||
123 | + Future request<T>( | ||
124 | + String method, | ||
125 | + String url, { | ||
126 | + Object? data, | ||
127 | + Map<String, dynamic>? queryParameters, | ||
128 | + CancelToken? cancelToken, | ||
129 | + Options? options, | ||
130 | + }) async { | ||
131 | + final Response<String> response = await _dio.request<String>( | ||
132 | + url, | ||
133 | + data: data, | ||
134 | + queryParameters: queryParameters, | ||
135 | + options: _checkOptions(method, options), | ||
136 | + cancelToken: cancelToken, | ||
137 | + ); | ||
138 | + try { | ||
139 | + final String data = response.data.toString(); | ||
140 | + final bool isCompute = !Constant.isDriverTest && data.length > 10 * 1024; | ||
141 | + final Map<String, dynamic> _map = | ||
142 | + isCompute ? await compute(parseData, data) : parseData(data); | ||
143 | + return BaseEntity<T>.fromJson(_map); | ||
144 | + } catch (e) { | ||
145 | + debugPrint(e.toString()); | ||
146 | + return BaseEntity<T>(ExceptionHandle.parse_error, '数据解析错误!', null); | ||
147 | + } | ||
148 | + } | ||
149 | + | ||
123 | Future requestNetwork<T>( | 150 | Future requestNetwork<T>( |
124 | Method method, | 151 | Method method, |
125 | String url, { | 152 | String url, { | ... | ... |
... | @@ -3,6 +3,7 @@ class HttpApi { | ... | @@ -3,6 +3,7 @@ class HttpApi { |
3 | static const String register = 'register'; | 3 | static const String register = 'register'; |
4 | static const String verify = 'verify'; | 4 | static const String verify = 'verify'; |
5 | static const String login = 'login'; | 5 | static const String login = 'login'; |
6 | + static const String user = 'user'; | ||
6 | static const String search = 'search/repositories'; | 7 | static const String search = 'search/repositories'; |
7 | static const String subscriptions = 'users/simplezhli/subscriptions'; | 8 | static const String subscriptions = 'users/simplezhli/subscriptions'; |
8 | static const String upload = 'uuc/upload-inco'; | 9 | static const String upload = 'uuc/upload-inco'; | ... | ... |
... | @@ -14,12 +14,11 @@ import 'error_handle.dart'; | ... | @@ -14,12 +14,11 @@ import 'error_handle.dart'; |
14 | class AuthInterceptor extends Interceptor { | 14 | class AuthInterceptor extends Interceptor { |
15 | @override | 15 | @override |
16 | void onRequest(RequestOptions options, RequestInterceptorHandler handler) { | 16 | void onRequest(RequestOptions options, RequestInterceptorHandler handler) { |
17 | - final String accessToken = SpUtil.getString(Constant.accessToken).nullSafe; | 17 | + final String accessToken = SpUtil.getString(Constant.userToken).nullSafe; |
18 | if (accessToken.isNotEmpty) { | 18 | if (accessToken.isNotEmpty) { |
19 | - options.headers['Authorization'] = 'token $accessToken'; | 19 | + options.headers['Authorization'] = 'Bearer $accessToken'; |
20 | } | 20 | } |
21 | if (!Device.isWeb) { | 21 | if (!Device.isWeb) { |
22 | - // https://developer.github.com/v3/#user-agent-required | ||
23 | options.headers['User-Agent'] = 'Mozilla/5.0'; | 22 | options.headers['User-Agent'] = 'Mozilla/5.0'; |
24 | } | 23 | } |
25 | super.onRequest(options, handler); | 24 | super.onRequest(options, handler); | ... | ... |
... | @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev | ... | @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev |
18 | version: 1.0.0+1 | 18 | version: 1.0.0+1 |
19 | 19 | ||
20 | environment: | 20 | environment: |
21 | - sdk: ">=2.14.0 <3.0.0" | 21 | + sdk: ">=2.16.2 <3.0.0" |
22 | flutter: ">=2.5.0" | 22 | flutter: ">=2.5.0" |
23 | 23 | ||
24 | # Dependencies specify other packages that your package needs in poem to work. | 24 | # Dependencies specify other packages that your package needs in poem to work. | ... | ... |
-
Please register or login to post a comment