w-R
3 years ago
43 changed files with 2258 additions and 1981 deletions
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,236 @@ |
|||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; |
||||||
|
import 'package:huixiang/generated/l10n.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/sign_info.dart'; |
||||||
|
import 'package:huixiang/utils/font_weight.dart'; |
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||||
|
import 'package:huixiang/view_widget/round_button.dart'; |
||||||
|
|
||||||
|
|
||||||
|
class InForPoints extends StatefulWidget { |
||||||
|
|
||||||
|
final SignInfo signInfo; |
||||||
|
final Function signIn; |
||||||
|
|
||||||
|
InForPoints(this.signInfo, this.signIn); |
||||||
|
|
||||||
|
@override |
||||||
|
State<StatefulWidget> createState() { |
||||||
|
return _InForPoints(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class _InForPoints extends State<InForPoints> { |
||||||
|
|
||||||
|
@override |
||||||
|
Widget build(BuildContext context) { |
||||||
|
return Container( |
||||||
|
width: double.infinity, |
||||||
|
margin: EdgeInsets.symmetric(horizontal: 16.w, vertical: 6.h), |
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 20.h), |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Colors.white, |
||||||
|
borderRadius: BorderRadius.circular(8), |
||||||
|
boxShadow: [ |
||||||
|
BoxShadow( |
||||||
|
color: Colors.black.withAlpha(12), |
||||||
|
offset: Offset(0, 3), |
||||||
|
blurRadius: 14, |
||||||
|
spreadRadius: 0, |
||||||
|
) |
||||||
|
], |
||||||
|
), |
||||||
|
child: Column( |
||||||
|
mainAxisAlignment: MainAxisAlignment.center, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
S.of(context).qiandaolingjifen, |
||||||
|
style: TextStyle( |
||||||
|
fontWeight: MyFontWeight.medium, |
||||||
|
fontSize: 16.sp, |
||||||
|
color: Color(0xFF353535), |
||||||
|
), |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
height: 10.h, |
||||||
|
), |
||||||
|
Text( |
||||||
|
S.of(context).lianxuqiandaolingqushuangbeijifen, |
||||||
|
style: TextStyle( |
||||||
|
fontWeight: MyFontWeight.medium, |
||||||
|
fontSize: 11.sp, |
||||||
|
color: Color(0xFF727272), |
||||||
|
), |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
height: 32.h, |
||||||
|
), |
||||||
|
StaggeredGridView.countBuilder( |
||||||
|
crossAxisCount: 4, |
||||||
|
shrinkWrap: true, |
||||||
|
itemCount: 7, |
||||||
|
mainAxisSpacing: 8, |
||||||
|
crossAxisSpacing: 18, |
||||||
|
padding: EdgeInsets.only(bottom: 32), |
||||||
|
physics: NeverScrollableScrollPhysics(), |
||||||
|
itemBuilder: (context, position) { |
||||||
|
return signInItem(position); |
||||||
|
}, |
||||||
|
staggeredTileBuilder: (position) { |
||||||
|
return StaggeredTile.count(position == 6 ? 2 : 1, 1.28); |
||||||
|
}, |
||||||
|
), |
||||||
|
InkWell( |
||||||
|
onTap: widget.signIn, |
||||||
|
child: Container( |
||||||
|
alignment: Alignment.center, |
||||||
|
child: RoundButton( |
||||||
|
width: 106.w, |
||||||
|
height: 34.h, |
||||||
|
text: (widget.signInfo != null && widget.signInfo.todayHasSignin) |
||||||
|
? S.of(context).yiqiandao |
||||||
|
: S.of(context).lijiqiandao, |
||||||
|
textColor: Colors.white, |
||||||
|
backgroup: (widget.signInfo != null && widget.signInfo.todayHasSignin) |
||||||
|
? Colors.grey |
||||||
|
: Color(0xFF32A060), |
||||||
|
fontSize: 16.sp, |
||||||
|
fontWeight: MyFontWeight.regular, |
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 6.h), |
||||||
|
radius: 4.w, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
Widget signInItem(position) { |
||||||
|
if (position == 6) { |
||||||
|
return Container( |
||||||
|
padding: EdgeInsets.all(4), |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Color(0xFFF0F0F2), |
||||||
|
borderRadius: BorderRadius.circular(4), |
||||||
|
), |
||||||
|
child: Row( |
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Expanded( |
||||||
|
child: Column( |
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
"0${position + 1}", |
||||||
|
style: TextStyle( |
||||||
|
color: Color(0xFF353535), |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: MyFontWeight.medium, |
||||||
|
), |
||||||
|
), |
||||||
|
Container( |
||||||
|
alignment: Alignment.center, |
||||||
|
height: 30.h, |
||||||
|
child: Text( |
||||||
|
S.of(context).shenmijifendali, |
||||||
|
style: TextStyle( |
||||||
|
color: Color(0xFF727272), |
||||||
|
fontWeight: FontWeight.bold, |
||||||
|
fontSize: 10.sp, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
Text( |
||||||
|
"", |
||||||
|
style: TextStyle( |
||||||
|
color: Color(0xFF353535), |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: MyFontWeight.medium, |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
flex: 1, |
||||||
|
), |
||||||
|
Container( |
||||||
|
alignment: Alignment.center, |
||||||
|
child: Image.asset( |
||||||
|
"assets/image/icon_gold_blessing.png", |
||||||
|
width: 59.w, |
||||||
|
height: 59.h, |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} else { |
||||||
|
return Container( |
||||||
|
padding: EdgeInsets.all(4), |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: (widget.signInfo != null && |
||||||
|
widget.signInfo.signInList != null && |
||||||
|
widget.signInfo.signInList.length > position) |
||||||
|
? Color(0xFF32A060) |
||||||
|
: Color(0xFFF0F0F2), |
||||||
|
borderRadius: BorderRadius.circular(4), |
||||||
|
), |
||||||
|
child: Column( |
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
"0${position + 1}", |
||||||
|
style: TextStyle( |
||||||
|
color: (widget.signInfo != null && |
||||||
|
widget.signInfo.signInList != null && |
||||||
|
widget.signInfo.signInList.length > position) |
||||||
|
? Colors.white |
||||||
|
: Color(0xFF353535), |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: MyFontWeight.medium, |
||||||
|
), |
||||||
|
), |
||||||
|
Container( |
||||||
|
alignment: Alignment.center, |
||||||
|
child: Image.asset( |
||||||
|
"assets/image/icon_gold_coin.png", |
||||||
|
width: 30.w, |
||||||
|
height: 30.h, |
||||||
|
), |
||||||
|
), |
||||||
|
Container( |
||||||
|
alignment: Alignment.center, |
||||||
|
margin: EdgeInsets.only( |
||||||
|
top: 2.h, |
||||||
|
), |
||||||
|
child: Text( |
||||||
|
(widget.signInfo != null && |
||||||
|
widget.signInfo.rewardList != null && |
||||||
|
widget.signInfo.rewardList.length > position) |
||||||
|
? "+${widget.signInfo.rewardList[position]}" |
||||||
|
: "+10", |
||||||
|
style: TextStyle( |
||||||
|
color: (widget.signInfo != null && |
||||||
|
widget.signInfo.signInList != null && |
||||||
|
widget.signInfo.signInList.length > position) |
||||||
|
? Colors.white |
||||||
|
: Color(0xFF727272), |
||||||
|
fontSize: 12.sp, |
||||||
|
fontWeight: MyFontWeight.regular, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,202 @@ |
|||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:flutter_swiper/flutter_swiper.dart'; |
||||||
|
import 'package:huixiang/generated/l10n.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/sign_info.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/task.dart'; |
||||||
|
import 'package:huixiang/utils/font_weight.dart'; |
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||||
|
import 'package:huixiang/view_widget/round_button.dart'; |
||||||
|
|
||||||
|
class IntegralTask extends StatefulWidget { |
||||||
|
final SignInfo signInfo; |
||||||
|
|
||||||
|
IntegralTask(this.signInfo); |
||||||
|
|
||||||
|
@override |
||||||
|
State<StatefulWidget> createState() { |
||||||
|
return _IntegralTask(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class _IntegralTask extends State<IntegralTask> { |
||||||
|
@override |
||||||
|
Widget build(BuildContext context) { |
||||||
|
return Container( |
||||||
|
width: MediaQuery.of(context).size.width - 32, |
||||||
|
height: 300.h, |
||||||
|
margin: EdgeInsets.all(16), |
||||||
|
padding: EdgeInsets.symmetric( |
||||||
|
horizontal: 10.w, |
||||||
|
vertical: 20.h, |
||||||
|
), |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Colors.white, |
||||||
|
borderRadius: BorderRadius.circular(8), |
||||||
|
boxShadow: [ |
||||||
|
BoxShadow( |
||||||
|
color: Colors.black.withAlpha(12), |
||||||
|
offset: Offset(0, 3), |
||||||
|
blurRadius: 14, |
||||||
|
spreadRadius: 0, |
||||||
|
) |
||||||
|
], |
||||||
|
), |
||||||
|
child: Column( |
||||||
|
mainAxisAlignment: MainAxisAlignment.start, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Container( |
||||||
|
margin: EdgeInsets.only(left: 10.w), |
||||||
|
child: Text( |
||||||
|
S.of(context).zuorenwudejifen, |
||||||
|
style: TextStyle( |
||||||
|
color: Color(0xFF353535), |
||||||
|
fontWeight: MyFontWeight.medium, |
||||||
|
fontSize: 16.sp, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
Expanded( |
||||||
|
child: Container( |
||||||
|
child: Swiper( |
||||||
|
loop: false, |
||||||
|
physics: BouncingScrollPhysics(), |
||||||
|
pagination: SwiperPagination( |
||||||
|
alignment: Alignment.bottomCenter, |
||||||
|
builder: DotSwiperPaginationBuilder( |
||||||
|
size: 8, |
||||||
|
activeSize: 8, |
||||||
|
space: 5, |
||||||
|
activeColor: Colors.black, |
||||||
|
color: Colors.black.withAlpha(76), |
||||||
|
), |
||||||
|
), |
||||||
|
itemBuilder: (context, position) { |
||||||
|
return taskPage(position); |
||||||
|
}, |
||||||
|
itemCount: (widget.signInfo != null && |
||||||
|
widget.signInfo.taskList != null && |
||||||
|
widget.signInfo.taskList.length > 0) |
||||||
|
? (widget.signInfo.taskList.length < 3 |
||||||
|
? 1 |
||||||
|
: (widget.signInfo.taskList.length ~/ 3 + |
||||||
|
(widget.signInfo.taskList.length % 3 > 0 |
||||||
|
? 1 |
||||||
|
: 0))) |
||||||
|
: 1), |
||||||
|
), |
||||||
|
flex: 1, |
||||||
|
) |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
Widget taskPage(position) { |
||||||
|
if (widget.signInfo == null || widget.signInfo.taskList == null) |
||||||
|
return Container(); |
||||||
|
return Container( |
||||||
|
margin: EdgeInsets.only(left: 10.w, right: 10.w, top: 16.h), |
||||||
|
child: Column( |
||||||
|
children: [ |
||||||
|
tashItem(widget.signInfo.taskList[position * 3 + 0]), |
||||||
|
if (widget.signInfo.taskList.length > (position * 3 + 1)) |
||||||
|
tashItem(widget.signInfo.taskList[position * 3 + 1]), |
||||||
|
if (widget.signInfo.taskList.length > (position * 3 + 2)) |
||||||
|
tashItem(widget.signInfo.taskList[position * 3 + 2]), |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
taskImg(String taskType) { |
||||||
|
switch (taskType) { |
||||||
|
case "bill_type_point_login": |
||||||
|
return "assets/image/icon_integral_share.png"; |
||||||
|
break; |
||||||
|
case "bill_type_point_order": |
||||||
|
return "assets/image/icon_integral_order.png"; |
||||||
|
break; |
||||||
|
case "bill_type_point_signin": |
||||||
|
return "assets/image/icon_integral_sign.png"; |
||||||
|
break; |
||||||
|
} |
||||||
|
return "assets/image/icon_integral_share.png"; |
||||||
|
} |
||||||
|
|
||||||
|
Widget tashItem(Task task) { |
||||||
|
return Container( |
||||||
|
margin: EdgeInsets.only(top: 8.h, bottom: 8.h), |
||||||
|
alignment: Alignment.center, |
||||||
|
child: Row( |
||||||
|
children: [ |
||||||
|
Image.asset( |
||||||
|
taskImg(task.type), |
||||||
|
width: 24.w, |
||||||
|
height: 24.h, |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
width: 21.w, |
||||||
|
), |
||||||
|
Expanded( |
||||||
|
flex: 1, |
||||||
|
child: Column( |
||||||
|
mainAxisAlignment: MainAxisAlignment.start, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
task.name, |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: MyFontWeight.regular, |
||||||
|
color: Color(0xFF353535), |
||||||
|
), |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
height: 7.h, |
||||||
|
), |
||||||
|
Row( |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
"+${double.tryParse(task.rewardValue).toInt()}", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
fontWeight: MyFontWeight.regular, |
||||||
|
color: Color(0xFF727272), |
||||||
|
), |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
width: 20.w, |
||||||
|
), |
||||||
|
Text( |
||||||
|
S.of(context).wancheng_( |
||||||
|
"${task.complateNum ?? task.conplateNum}/${task.limitDay}"), |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
fontWeight: MyFontWeight.regular, |
||||||
|
color: Color(0xFF727272), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
RoundButton( |
||||||
|
text: task.limitDay == (task.complateNum ?? task.conplateNum) |
||||||
|
? S.of(context).yiwancheng |
||||||
|
: S.of(context).quwancheng, |
||||||
|
textColor: Colors.white, |
||||||
|
backgroup: task.limitDay == (task.complateNum ?? task.conplateNum) |
||||||
|
? Color(0xFFA0A0A0) |
||||||
|
: Color(0xFF32A060), |
||||||
|
radius: 12.w, |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: FontWeight.bold, |
||||||
|
padding: EdgeInsets.symmetric(vertical: 4.h, horizontal: 12.w), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,132 @@ |
|||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:huixiang/generated/l10n.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/sign_info.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/user_info.dart'; |
||||||
|
import 'package:huixiang/utils/font_weight.dart'; |
||||||
|
import 'package:shared_preferences/shared_preferences.dart'; |
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||||
|
|
||||||
|
class IntegralVip extends StatefulWidget { |
||||||
|
|
||||||
|
final SignInfo signInfo; |
||||||
|
final UserInfo userinfo; |
||||||
|
final rankLevel; |
||||||
|
|
||||||
|
IntegralVip(this.rankLevel, this.signInfo, this.userinfo); |
||||||
|
|
||||||
|
@override |
||||||
|
State<StatefulWidget> createState() { |
||||||
|
return _IntegralVip(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class _IntegralVip extends State<IntegralVip> { |
||||||
|
@override |
||||||
|
Widget build(BuildContext context) { |
||||||
|
return Container( |
||||||
|
padding: EdgeInsets.symmetric(vertical: 16.h), |
||||||
|
child: Row( |
||||||
|
children: [ |
||||||
|
Expanded( |
||||||
|
flex: 1, |
||||||
|
child: Column( |
||||||
|
mainAxisAlignment: MainAxisAlignment.center, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
widget.signInfo != null ? "${widget.signInfo.point}" : "0", |
||||||
|
style: TextStyle( |
||||||
|
fontWeight: MyFontWeight.medium, |
||||||
|
fontSize: 21.sp, |
||||||
|
color: Colors.white, |
||||||
|
), |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
height: 6.h, |
||||||
|
), |
||||||
|
Text( |
||||||
|
S.of(context).wodejifenzhi, |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
fontWeight: MyFontWeight.regular, |
||||||
|
color: Color(0xFFF2F2F2), |
||||||
|
), |
||||||
|
) |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
Container( |
||||||
|
width: 2.w, |
||||||
|
height: 32.h, |
||||||
|
color: Color(0xFFFFFFFF), |
||||||
|
), |
||||||
|
Expanded( |
||||||
|
flex: 1, |
||||||
|
child: InkWell( |
||||||
|
onTap: () { |
||||||
|
SharedPreferences.getInstance().then((value) { |
||||||
|
if (value.getString("token") != null && |
||||||
|
value.getString("token") != "") { |
||||||
|
Navigator.of(context) |
||||||
|
.pushNamed('/router/mine_vip_level_page', arguments: { |
||||||
|
"rankLevel": widget.rankLevel, |
||||||
|
"createTime": |
||||||
|
(widget.userinfo != null) ? "${widget.userinfo.createTime}" : "", |
||||||
|
"points": (widget.userinfo != null) |
||||||
|
? int.tryParse(widget.userinfo.points) |
||||||
|
: 0, |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
}, |
||||||
|
child: Column( |
||||||
|
mainAxisAlignment: MainAxisAlignment.center, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
(widget.signInfo != null && widget.signInfo.rank != null) |
||||||
|
? "${widget.signInfo.rank.rankName.replaceAll("会员", "")}" |
||||||
|
: "", |
||||||
|
style: TextStyle( |
||||||
|
fontWeight: MyFontWeight.medium, |
||||||
|
fontSize: 21.sp, |
||||||
|
color: Colors.white, |
||||||
|
), |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
height: 6.h, |
||||||
|
), |
||||||
|
Row( |
||||||
|
mainAxisAlignment: MainAxisAlignment.center, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
S.of(context).wodehuiyuandengji, |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
fontWeight: MyFontWeight.regular, |
||||||
|
color: Color(0xFFF2F2F2), |
||||||
|
), |
||||||
|
), |
||||||
|
Icon( |
||||||
|
Icons.keyboard_arrow_right, |
||||||
|
color: Colors.white, |
||||||
|
size: 15, |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,318 @@ |
|||||||
|
import 'dart:io'; |
||||||
|
import 'dart:ui'; |
||||||
|
|
||||||
|
import 'package:dio/dio.dart'; |
||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:flutter/rendering.dart'; |
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||||
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; |
||||||
|
import 'package:huixiang/generated/l10n.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/activity.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/article.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/base_data.dart'; |
||||||
|
import 'package:huixiang/retrofit/retrofit_api.dart'; |
||||||
|
import 'package:huixiang/view_widget/my_appbar.dart'; |
||||||
|
import 'package:huixiang/view_widget/share_dialog.dart'; |
||||||
|
import 'package:huixiang/view_widget/tips_dialog.dart'; |
||||||
|
import 'package:huixiang/web/web_view/comment_list.dart'; |
||||||
|
import 'package:huixiang/web/web_view/input_comment.dart'; |
||||||
|
import 'package:huixiang/web/web_view/web_content.dart'; |
||||||
|
import 'package:huixiang/web/web_view/web_header.dart'; |
||||||
|
import 'package:shared_preferences/shared_preferences.dart'; |
||||||
|
import 'package:sharesdk_plugin/sharesdk_defines.dart'; |
||||||
|
import 'package:sharesdk_plugin/sharesdk_interface.dart'; |
||||||
|
import 'package:sharesdk_plugin/sharesdk_map.dart'; |
||||||
|
import 'package:webview_flutter/webview_flutter.dart'; |
||||||
|
import 'package:flutter/cupertino.dart'; |
||||||
|
|
||||||
|
class WebPage extends StatefulWidget { |
||||||
|
final Map<String, dynamic> arguments; |
||||||
|
|
||||||
|
///富文本 文章 活动 |
||||||
|
WebPage({this.arguments}); |
||||||
|
|
||||||
|
@override |
||||||
|
State<StatefulWidget> createState() { |
||||||
|
return _WebPage(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class _WebPage extends State<WebPage> with WidgetsBindingObserver { |
||||||
|
ApiService apiService; |
||||||
|
int commentTotal = 0; |
||||||
|
String hintText = S.current.liuxianinjingcaidepinglunba; |
||||||
|
var commentFocus = FocusNode(); |
||||||
|
String parenId = "0"; |
||||||
|
|
||||||
|
Activity activity; |
||||||
|
Article article; |
||||||
|
final GlobalKey commentKey = GlobalKey(); |
||||||
|
final GlobalKey inputKey = GlobalKey(); |
||||||
|
final ScrollController scrollController = ScrollController(); |
||||||
|
|
||||||
|
@override |
||||||
|
void initState() { |
||||||
|
super.initState(); |
||||||
|
WidgetsBinding.instance.addObserver(this); |
||||||
|
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView(); |
||||||
|
|
||||||
|
queryHtml(); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
bool isKeyBoardShow = false; |
||||||
|
|
||||||
|
@override |
||||||
|
void didChangeMetrics() { |
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) { |
||||||
|
if (MediaQuery.of(context).viewInsets.bottom == 0) { |
||||||
|
if (isKeyBoardShow) { |
||||||
|
FocusScope.of(context).requestFocus(FocusNode()); |
||||||
|
setState(() { |
||||||
|
hintText = S.current.liuxianinjingcaidepinglunba; |
||||||
|
isKeyBoardShow = false; |
||||||
|
}); |
||||||
|
} |
||||||
|
} else { |
||||||
|
setState(() { |
||||||
|
isKeyBoardShow = true; |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
@override |
||||||
|
void dispose() { |
||||||
|
WidgetsBinding.instance.removeObserver(this); |
||||||
|
super.dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
queryHtml() async { |
||||||
|
SharedPreferences value = await SharedPreferences.getInstance(); |
||||||
|
if (apiService == null) |
||||||
|
apiService = ApiService(Dio(), context: context, token: value.getString("token")); |
||||||
|
|
||||||
|
if (widget.arguments["activityId"] != null) { |
||||||
|
BaseData<Activity> baseData = await apiService.activityInfo(widget.arguments["activityId"]).catchError((onError){}); |
||||||
|
if (baseData != null && baseData.isSuccess) { |
||||||
|
activity = baseData.data; |
||||||
|
setState(() {}); |
||||||
|
} |
||||||
|
} |
||||||
|
if (widget.arguments["articleId"] != null) { |
||||||
|
BaseData<Article> baseData = await apiService.informationInfo(widget.arguments["articleId"]).catchError((onError){}); |
||||||
|
if (baseData != null && baseData.isSuccess) { |
||||||
|
article = baseData.data; |
||||||
|
setState(() {}); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
//发布评论 |
||||||
|
_queryMemberComment(String content) async { |
||||||
|
BaseData baseData = await apiService.memberComment({ |
||||||
|
"content": content, |
||||||
|
"parentId": parenId, |
||||||
|
"relationalId": |
||||||
|
widget.arguments["activityId"] ?? widget.arguments["articleId"], |
||||||
|
"relationalType": 1 |
||||||
|
}).catchError((error) {}); |
||||||
|
if (baseData != null && baseData.isSuccess) { |
||||||
|
_toComment(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
share() async { |
||||||
|
SSDKMap params = SSDKMap() |
||||||
|
..setGeneral( |
||||||
|
activity != null |
||||||
|
? activity.mainTitle |
||||||
|
: article != null |
||||||
|
? article.mainTitle |
||||||
|
: "", |
||||||
|
activity != null |
||||||
|
? activity.viceTitle |
||||||
|
: article != null |
||||||
|
? article.viceTitle |
||||||
|
: "", |
||||||
|
[ |
||||||
|
activity != null |
||||||
|
? activity.coverImg |
||||||
|
: article != null |
||||||
|
? article.coverImg |
||||||
|
: "", |
||||||
|
], |
||||||
|
activity != null |
||||||
|
? activity.coverImg |
||||||
|
: article != null |
||||||
|
? article.coverImg |
||||||
|
: "", |
||||||
|
"", buildShareUrl(), "", "", "", "", |
||||||
|
SSDKContentTypes.webpage, |
||||||
|
); |
||||||
|
|
||||||
|
showModalBottomSheet( |
||||||
|
context: context, |
||||||
|
backgroundColor: Colors.transparent, |
||||||
|
builder: (context) { |
||||||
|
return ShareDialog((platform) { |
||||||
|
if (platform == ShareSDKPlatforms.line) { |
||||||
|
params.map["type"] = SSDKContentTypes.text.value; |
||||||
|
params.map["text"] = |
||||||
|
"${activity != null ? activity.viceTitle : article != null ? article.viceTitle : ""} ${buildShareUrl()}"; |
||||||
|
} |
||||||
|
SharesdkPlugin.share(platform, params, |
||||||
|
(state, userData, contentEntity, error) { |
||||||
|
print("share!$state"); |
||||||
|
}); |
||||||
|
}); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
String buildShareUrl() { |
||||||
|
return "https://hx.lotus-wallet.com/index.html?id=${widget.arguments["activityId"] ?? widget.arguments["articleId"]}&type=${activity != null ? "activity" : article != null ? "article" : ""}"; |
||||||
|
} |
||||||
|
|
||||||
|
//给文章/活动点赞 |
||||||
|
_queryInformationLikes() async { |
||||||
|
BaseData baseData = await apiService.informationLikes( |
||||||
|
widget.arguments["activityId"] ?? widget.arguments["articleId"]); |
||||||
|
if (baseData != null && baseData.isSuccess) { |
||||||
|
if (article != null) { |
||||||
|
if (article.liked) { |
||||||
|
article.likes -= 1; |
||||||
|
} else { |
||||||
|
article.likes += 1; |
||||||
|
} |
||||||
|
article.liked = !article.liked; |
||||||
|
} else if (activity != null) { |
||||||
|
if (activity.liked) { |
||||||
|
activity.likes -= 1; |
||||||
|
} else { |
||||||
|
activity.likes += 1; |
||||||
|
} |
||||||
|
activity.liked = !activity.liked; |
||||||
|
} |
||||||
|
} else { |
||||||
|
SmartDialog.showToast(baseData.msg, alignment: Alignment.center); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@override |
||||||
|
Widget build(BuildContext context) { |
||||||
|
return Scaffold( |
||||||
|
appBar: MyAppBar( |
||||||
|
action: Container( |
||||||
|
margin: EdgeInsets.only(right: 10), |
||||||
|
child: GestureDetector( |
||||||
|
onTap: () { |
||||||
|
share(); |
||||||
|
}, |
||||||
|
child: Icon( |
||||||
|
Icons.share, |
||||||
|
size: 24, |
||||||
|
color: Colors.black, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
background: Color(0xFFF7F7F7), |
||||||
|
leadingColor: Colors.black, |
||||||
|
title: activity != null |
||||||
|
? activity.mainTitle |
||||||
|
: article != null |
||||||
|
? article.mainTitle |
||||||
|
: "", |
||||||
|
titleSize: 18.sp, |
||||||
|
titleColor: Colors.black, |
||||||
|
), |
||||||
|
body: Container( |
||||||
|
child: Column( |
||||||
|
children: [ |
||||||
|
Expanded( |
||||||
|
child: GestureDetector( |
||||||
|
onTap: () { |
||||||
|
commentFocus.unfocus(); |
||||||
|
hintText = S.of(context).liuxianinjingcaidepinglunba; |
||||||
|
inputKey.currentState.setState(() {});; |
||||||
|
parenId = "0"; |
||||||
|
}, |
||||||
|
child: SingleChildScrollView( |
||||||
|
controller: scrollController, |
||||||
|
physics: BouncingScrollPhysics(), |
||||||
|
child: Column( |
||||||
|
children: [ |
||||||
|
/// 富文本的头部 |
||||||
|
WebHeader(widget.arguments, activity, article), |
||||||
|
|
||||||
|
/// 富文本的内容 |
||||||
|
WebContent(activity, article), |
||||||
|
|
||||||
|
/// 富文本的评论 |
||||||
|
CommentList( |
||||||
|
commentKey, |
||||||
|
widget.arguments, |
||||||
|
activity, |
||||||
|
article, |
||||||
|
isKeyBoardShow, |
||||||
|
_reply, |
||||||
|
_delCommentTips, |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
flex: 1, |
||||||
|
), |
||||||
|
|
||||||
|
/// 富文本评论的输入框 |
||||||
|
InputComment( |
||||||
|
inputKey, |
||||||
|
hintText, |
||||||
|
activity, |
||||||
|
article, |
||||||
|
isKeyBoardShow, |
||||||
|
commentFocus, |
||||||
|
_toComment, |
||||||
|
_queryMemberComment, |
||||||
|
_queryInformationLikes, |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
_delCommentTips() { |
||||||
|
SmartDialog.show(widget: Tips(() { |
||||||
|
delComment(); |
||||||
|
})); |
||||||
|
} |
||||||
|
|
||||||
|
delComment() async { |
||||||
|
BaseData baseData = await apiService.delComment( |
||||||
|
widget.arguments["activityId"] ?? widget.arguments["articleId"]); |
||||||
|
if (baseData != null && baseData.isSuccess) { |
||||||
|
commentKey.currentState.setState(() {}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
_reply(memberComment) { |
||||||
|
FocusScope.of(context).requestFocus(commentFocus); |
||||||
|
parenId = memberComment.id; |
||||||
|
hintText = S.of(context).huifu_("${memberComment.username}"); |
||||||
|
} |
||||||
|
|
||||||
|
_toComment() { |
||||||
|
if (commentKey.currentContext == null) return; |
||||||
|
RenderBox firstRenderBox = commentKey.currentContext.findRenderObject(); |
||||||
|
Offset first = firstRenderBox.localToGlobal(Offset.zero); |
||||||
|
scrollController.animateTo( |
||||||
|
first.dy + |
||||||
|
scrollController.offset - |
||||||
|
(kToolbarHeight + MediaQuery.of(context).padding.top), |
||||||
|
duration: Duration(milliseconds: 1000), |
||||||
|
curve: Curves.easeIn); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -0,0 +1,422 @@ |
|||||||
|
import 'package:dio/dio.dart'; |
||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; |
||||||
|
import 'package:huixiang/generated/l10n.dart'; |
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/activity.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/article.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/base_data.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/member_comment_list.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/page.dart'; |
||||||
|
import 'package:huixiang/retrofit/retrofit_api.dart'; |
||||||
|
import 'package:huixiang/view_widget/comment_menu.dart'; |
||||||
|
import 'package:huixiang/view_widget/custom_image.dart'; |
||||||
|
import 'package:huixiang/view_widget/login_tips_dialog.dart'; |
||||||
|
import 'package:like_button/like_button.dart'; |
||||||
|
import 'package:shared_preferences/shared_preferences.dart'; |
||||||
|
|
||||||
|
class CommentList extends StatefulWidget { |
||||||
|
final Map arguments; |
||||||
|
final Activity activity; |
||||||
|
final Article article; |
||||||
|
final bool isKeyBoardShow; |
||||||
|
final Function reply; |
||||||
|
final Function delCommentTips; |
||||||
|
|
||||||
|
CommentList( |
||||||
|
Key key, |
||||||
|
this.arguments, |
||||||
|
this.activity, |
||||||
|
this.article, |
||||||
|
this.isKeyBoardShow, |
||||||
|
this.reply, |
||||||
|
this.delCommentTips, |
||||||
|
) : super(key: key); |
||||||
|
|
||||||
|
@override |
||||||
|
State<StatefulWidget> createState() { |
||||||
|
return _CommentList(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class _CommentList extends State<CommentList> { |
||||||
|
int commentTotal = 0; |
||||||
|
List<MemberCommentList> memberList = []; |
||||||
|
ApiService apiService; |
||||||
|
|
||||||
|
//评论点赞 |
||||||
|
queryCommentLike(String id) async { |
||||||
|
SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); |
||||||
|
String token = sharedPreferences.getString("token"); |
||||||
|
if (token == null || token == "") { |
||||||
|
LoginTipsDialog().show(context); |
||||||
|
return; |
||||||
|
} |
||||||
|
BaseData baseData = |
||||||
|
await apiService.commentLike(id).catchError((onError) {}); |
||||||
|
if (baseData != null && baseData.isSuccess) { |
||||||
|
memberList.forEach((element) { |
||||||
|
if (element.id == id) { |
||||||
|
if (element.liked) { |
||||||
|
element.likes -= 1; |
||||||
|
element.liked = false; |
||||||
|
} else { |
||||||
|
element.likes += 1; |
||||||
|
element.liked = true; |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@override |
||||||
|
void initState() { |
||||||
|
super.initState(); |
||||||
|
queryMemberCommentList(); |
||||||
|
} |
||||||
|
|
||||||
|
@override |
||||||
|
Widget build(BuildContext context) { |
||||||
|
return Column( |
||||||
|
children: [ |
||||||
|
Container( |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Colors.white, |
||||||
|
boxShadow: [ |
||||||
|
BoxShadow( |
||||||
|
color: Colors.black.withAlpha(12), |
||||||
|
offset: Offset(0, 2), |
||||||
|
blurRadius: 14, |
||||||
|
spreadRadius: 0, |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
child: Column( |
||||||
|
mainAxisAlignment: MainAxisAlignment.start, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Container( |
||||||
|
padding: EdgeInsets.all(16), |
||||||
|
child: Row( |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
S.of(context).pinglun_(commentTotal.toString()), |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 16.sp, |
||||||
|
fontWeight: FontWeight.bold, |
||||||
|
color: Color(0xff1A1A1A), |
||||||
|
), |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
width: 16.w, |
||||||
|
), |
||||||
|
Text( |
||||||
|
S.of(context).xihuan_( |
||||||
|
"${widget.article?.likes ?? widget.activity?.likes ?? "0"}"), |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 16.sp, |
||||||
|
fontWeight: FontWeight.bold, |
||||||
|
color: Color(0xff1A1A1A), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
if (memberList != null && memberList.length > 0) |
||||||
|
ListView.builder( |
||||||
|
shrinkWrap: true, |
||||||
|
physics: NeverScrollableScrollPhysics(), |
||||||
|
itemCount: memberList != null ? memberList.length : 0, |
||||||
|
scrollDirection: Axis.vertical, |
||||||
|
itemBuilder: (context, position) { |
||||||
|
return Material( |
||||||
|
color: Colors.white, |
||||||
|
child: InkWell( |
||||||
|
onTap: () { |
||||||
|
showPressMenu(memberList[position].createUser, |
||||||
|
memberList[position]); |
||||||
|
}, |
||||||
|
child: commentItem( |
||||||
|
memberList[position], position, memberList.length), |
||||||
|
), |
||||||
|
); |
||||||
|
}, |
||||||
|
), |
||||||
|
if (memberList != null && memberList.length > 0) |
||||||
|
Container( |
||||||
|
height: 63.h, |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Color(0xFFF2F2F2), |
||||||
|
boxShadow: [ |
||||||
|
BoxShadow( |
||||||
|
color: Colors.black.withAlpha(12), |
||||||
|
offset: Offset(0, 2), |
||||||
|
blurRadius: 14, |
||||||
|
spreadRadius: 0, |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
alignment: Alignment.center, |
||||||
|
child: Text( |
||||||
|
S.of(context).yixiansquanbupinglun, |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xff353535), |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
if (memberList == null || memberList.length == 0) |
||||||
|
Container( |
||||||
|
width: double.infinity, |
||||||
|
height: 80.h, |
||||||
|
alignment: Alignment.center, |
||||||
|
child: Text( |
||||||
|
S.of(context).zanwupinglun, |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
fontWeight: FontWeight.bold, |
||||||
|
color: Color(0xFFA0A0A0), |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
height: 12.h, |
||||||
|
), |
||||||
|
], |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
//评论列表 |
||||||
|
queryMemberCommentList() async { |
||||||
|
SharedPreferences sharedPreferences = await SharedPreferences.getInstance(); |
||||||
|
if (apiService == null) |
||||||
|
apiService = ApiService(Dio(), |
||||||
|
context: context, token: sharedPreferences.getString("token")); |
||||||
|
BaseData<PageInfo<MemberCommentList>> baseData = |
||||||
|
await apiService.memberCommentList({ |
||||||
|
"pageNum": 1, |
||||||
|
"pageSize": 100, |
||||||
|
"relationalId": |
||||||
|
widget.arguments["activityId"] ?? widget.arguments["articleId"], |
||||||
|
"relationalType": 1, |
||||||
|
}).catchError((error) {}); |
||||||
|
if (baseData != null && baseData.isSuccess) { |
||||||
|
commentTotal = baseData.data.size; |
||||||
|
memberList = baseData.data.list; |
||||||
|
setState(() {}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
showPressMenu(String userId, memberComment) { |
||||||
|
if (widget.isKeyBoardShow) { |
||||||
|
FocusScope.of(context).requestFocus(FocusNode()); |
||||||
|
return; |
||||||
|
} |
||||||
|
SharedPreferences.getInstance().then((value) { |
||||||
|
// showModalBottomSheet( |
||||||
|
// context: context, |
||||||
|
// backgroundColor: Colors.transparent, |
||||||
|
// builder: (context) { |
||||||
|
// return CommentMenu( |
||||||
|
// (type) { |
||||||
|
// print("click: $type"); |
||||||
|
// if (type == "huifu") { |
||||||
|
// widget.reply(memberComment); |
||||||
|
// } else if (type == "shanchu") { |
||||||
|
// widget.delCommentTips(); |
||||||
|
// } |
||||||
|
// }, |
||||||
|
// isSelf: userId == value.getString("userId"), |
||||||
|
// ); |
||||||
|
// }, |
||||||
|
// ); |
||||||
|
|
||||||
|
SmartDialog.show( |
||||||
|
widget: CommentMenu((type) { |
||||||
|
SmartDialog.dismiss(); |
||||||
|
if (type == "huifu") { |
||||||
|
widget.reply(memberComment); |
||||||
|
} else if (type == "shanchu") { |
||||||
|
widget.delCommentTips(); |
||||||
|
} |
||||||
|
}, |
||||||
|
isSelf: userId == value.getString("userId"), |
||||||
|
), |
||||||
|
alignmentTemp: Alignment.bottomCenter, |
||||||
|
isUseAnimationTemp: true, |
||||||
|
animationDurationTemp: Duration(milliseconds: 300), |
||||||
|
); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
Widget commentItem(MemberCommentList memberList, int index, int max) { |
||||||
|
return Container( |
||||||
|
padding: EdgeInsets.symmetric(vertical: 8.w), |
||||||
|
child: Column( |
||||||
|
children: [ |
||||||
|
Container( |
||||||
|
padding: EdgeInsets.symmetric(horizontal: 16.w), |
||||||
|
child: Row( |
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.center, |
||||||
|
children: [ |
||||||
|
MImage( |
||||||
|
memberList.userAvatarUrl ?? "", |
||||||
|
fit: BoxFit.cover, |
||||||
|
isCircle: true, |
||||||
|
width: 40, |
||||||
|
height: 40, |
||||||
|
fadeSrc: "assets/image/default_user.png", |
||||||
|
errorSrc: "assets/image/default_user.png", |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
width: 12.w, |
||||||
|
), |
||||||
|
Expanded( |
||||||
|
child: Container( |
||||||
|
height: 60.h, |
||||||
|
child: Column( |
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Text.rich( |
||||||
|
TextSpan( |
||||||
|
children: [ |
||||||
|
TextSpan( |
||||||
|
text: memberList.username, |
||||||
|
style: TextStyle( |
||||||
|
fontWeight: FontWeight.bold, |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Colors.black, |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
textDirection: TextDirection.ltr, |
||||||
|
), |
||||||
|
Text( |
||||||
|
memberList.createTime, |
||||||
|
overflow: TextOverflow.ellipsis, |
||||||
|
maxLines: 2, |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
color: Color(0xff808080), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
flex: 1, |
||||||
|
), |
||||||
|
Container( |
||||||
|
alignment: Alignment.topRight, |
||||||
|
child: LikeButton( |
||||||
|
padding: EdgeInsets.all(10), |
||||||
|
circleSize: 16, |
||||||
|
circleColor: CircleColor( |
||||||
|
start: Color(0xff00ddff), |
||||||
|
end: Color(0xff0099cc), |
||||||
|
), |
||||||
|
bubblesColor: BubblesColor( |
||||||
|
dotPrimaryColor: Color(0xff33b5e5), |
||||||
|
dotSecondaryColor: Color(0xff0099cc), |
||||||
|
), |
||||||
|
bubblesSize: 15, |
||||||
|
likeBuilder: (bool isLiked) { |
||||||
|
return isLiked |
||||||
|
? Image.asset( |
||||||
|
"assets/image/icon_like.png", |
||||||
|
width: 16, |
||||||
|
height: 16, |
||||||
|
) |
||||||
|
: Image.asset( |
||||||
|
"assets/image/icon_like_h.png", |
||||||
|
width: 16, |
||||||
|
height: 16, |
||||||
|
); |
||||||
|
}, |
||||||
|
isLiked: memberList.liked ?? false, |
||||||
|
onTap: (isLiked) async { |
||||||
|
await queryCommentLike(memberList.id); |
||||||
|
return (memberList == null || memberList.liked == null) |
||||||
|
? false |
||||||
|
: memberList.liked; |
||||||
|
}, |
||||||
|
likeCount: memberList.likes, |
||||||
|
countBuilder: (int count, bool isLiked, String text) { |
||||||
|
return Text( |
||||||
|
text, |
||||||
|
style: TextStyle( |
||||||
|
color: Color(0xFF1A1A1A), |
||||||
|
fontSize: 12.sp, |
||||||
|
), |
||||||
|
); |
||||||
|
}, |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
Container( |
||||||
|
padding: EdgeInsets.only( |
||||||
|
left: 68, |
||||||
|
right: 16, |
||||||
|
top: 16.h, |
||||||
|
bottom: 16.h, |
||||||
|
), |
||||||
|
child: Align( |
||||||
|
alignment: Alignment.centerLeft, |
||||||
|
child: Text( |
||||||
|
memberList.content, |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xff1A1A1A), |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
height: 12.h, |
||||||
|
), |
||||||
|
if (memberList.parentContent != null) |
||||||
|
Container( |
||||||
|
margin: EdgeInsets.only(left: 68.w, right: 16.w), |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Color(0xffF2F2F2), |
||||||
|
borderRadius: BorderRadius.circular(2.0), |
||||||
|
), |
||||||
|
child: Padding( |
||||||
|
padding: EdgeInsets.only(left: 4.w, top: 4.h, bottom: 4.h), |
||||||
|
child: Row( |
||||||
|
mainAxisAlignment: MainAxisAlignment.center, |
||||||
|
crossAxisAlignment: CrossAxisAlignment.start, |
||||||
|
children: [ |
||||||
|
Text( |
||||||
|
"${memberList.parentUserName}:" ?? "", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
color: Color(0xff808080), |
||||||
|
), |
||||||
|
), |
||||||
|
Expanded( |
||||||
|
flex: 1, |
||||||
|
child: Text( |
||||||
|
memberList.parentContent ?? "", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 12.sp, |
||||||
|
color: Color(0xff808080), |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,178 @@ |
|||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||||
|
import 'package:huixiang/generated/l10n.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/activity.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/article.dart'; |
||||||
|
import 'package:like_button/like_button.dart'; |
||||||
|
|
||||||
|
class InputComment extends StatefulWidget { |
||||||
|
final String hintText; |
||||||
|
final Activity activity; |
||||||
|
final Article article; |
||||||
|
final bool isKeyBoardShow; |
||||||
|
final FocusNode commentFocus; |
||||||
|
final Function toComment; |
||||||
|
final Function(String text) queryMemberComment; |
||||||
|
final Function() queryInformationLikes; |
||||||
|
|
||||||
|
InputComment( |
||||||
|
Key key, |
||||||
|
this.hintText, |
||||||
|
this.activity, |
||||||
|
this.article, |
||||||
|
this.isKeyBoardShow, |
||||||
|
this.commentFocus, |
||||||
|
this.toComment, |
||||||
|
this.queryMemberComment, |
||||||
|
this.queryInformationLikes, |
||||||
|
) : super(key: key); |
||||||
|
|
||||||
|
@override |
||||||
|
State<StatefulWidget> createState() { |
||||||
|
return _InputComment(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class _InputComment extends State<InputComment> { |
||||||
|
|
||||||
|
var commentTextController = TextEditingController(); |
||||||
|
|
||||||
|
@override |
||||||
|
Widget build(BuildContext context) { |
||||||
|
return Container( |
||||||
|
padding: EdgeInsets.all(16), |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Colors.white, |
||||||
|
boxShadow: [ |
||||||
|
BoxShadow( |
||||||
|
color: Colors.black.withAlpha(12), |
||||||
|
offset: Offset(0, 2), |
||||||
|
blurRadius: 14, |
||||||
|
spreadRadius: 0, |
||||||
|
), |
||||||
|
], |
||||||
|
borderRadius: BorderRadius.vertical( |
||||||
|
top: Radius.circular(8), |
||||||
|
), |
||||||
|
), |
||||||
|
child: Row( |
||||||
|
children: [ |
||||||
|
Expanded( |
||||||
|
flex: 1, |
||||||
|
child: Container( |
||||||
|
decoration: BoxDecoration( |
||||||
|
color: Color(0xffF2F2F2), |
||||||
|
borderRadius: BorderRadius.circular(2.0), |
||||||
|
), |
||||||
|
child: Column( |
||||||
|
children: [ |
||||||
|
Container( |
||||||
|
margin: EdgeInsets.symmetric(horizontal: 4.w), |
||||||
|
alignment: Alignment.topLeft, |
||||||
|
child: TextField( |
||||||
|
maxLines: 8, |
||||||
|
minLines: 1, |
||||||
|
focusNode: widget.commentFocus, |
||||||
|
controller: commentTextController, |
||||||
|
decoration: InputDecoration( |
||||||
|
border: InputBorder.none, |
||||||
|
hintText: widget.hintText, |
||||||
|
hintStyle: TextStyle( |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Color(0xFF868686), |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
if (widget.isKeyBoardShow) |
||||||
|
GestureDetector( |
||||||
|
onTap: () { |
||||||
|
var commentText = commentTextController.text; |
||||||
|
if (commentText == "") { |
||||||
|
return; |
||||||
|
} |
||||||
|
widget.queryMemberComment(commentText); |
||||||
|
}, |
||||||
|
child: Container( |
||||||
|
padding: EdgeInsets.symmetric(horizontal: 20.w), |
||||||
|
child: Text( |
||||||
|
S.of(context).fasong, |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 16.sp, |
||||||
|
fontWeight: FontWeight.bold, |
||||||
|
color: Color(0XFF1A1A1A), |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
if (!widget.isKeyBoardShow) |
||||||
|
InkWell( |
||||||
|
onTap: widget.toComment, |
||||||
|
child: Container( |
||||||
|
padding: EdgeInsets.only(left: 20.w, right: 10.w), |
||||||
|
child: Image.asset( |
||||||
|
"assets/image/icon_comment.png", |
||||||
|
width: 24, |
||||||
|
height: 24, |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
if (!widget.isKeyBoardShow) |
||||||
|
LikeButton( |
||||||
|
padding: EdgeInsets.all(10), |
||||||
|
size: 24, |
||||||
|
circleSize: 24, |
||||||
|
circleColor: CircleColor( |
||||||
|
start: Color(0xff00ddff), |
||||||
|
end: Color(0xff0099cc), |
||||||
|
), |
||||||
|
bubblesColor: BubblesColor( |
||||||
|
dotPrimaryColor: Color(0xff33b5e5), |
||||||
|
dotSecondaryColor: Color(0xff0099cc), |
||||||
|
), |
||||||
|
bubblesSize: 24, |
||||||
|
likeBuilder: (bool isLiked) { |
||||||
|
return isLiked |
||||||
|
? Image.asset( |
||||||
|
"assets/image/icon_like.png", |
||||||
|
width: 24, |
||||||
|
height: 24, |
||||||
|
) |
||||||
|
: Image.asset( |
||||||
|
"assets/image/icon_like_h.png", |
||||||
|
width: 24, |
||||||
|
height: 24, |
||||||
|
); |
||||||
|
}, |
||||||
|
isLiked: (widget.activity != null |
||||||
|
? widget.activity.liked |
||||||
|
: widget.article != null |
||||||
|
? widget.article.liked |
||||||
|
: false), |
||||||
|
onTap: (isLiked) async { |
||||||
|
await widget.queryInformationLikes(); |
||||||
|
return (widget.activity != null |
||||||
|
? widget.activity.liked |
||||||
|
: widget.article != null |
||||||
|
? widget.article.liked |
||||||
|
: false); |
||||||
|
}, |
||||||
|
countBuilder: (int count, bool isLiked, String text) { |
||||||
|
return Text( |
||||||
|
text, |
||||||
|
style: TextStyle( |
||||||
|
color: Color(0xFF1A1A1A), |
||||||
|
fontSize: 12.sp, |
||||||
|
), |
||||||
|
); |
||||||
|
}, |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,170 @@ |
|||||||
|
|
||||||
|
|
||||||
|
import 'package:chewie/chewie.dart'; |
||||||
|
import 'package:flutter_html/flutter_html.dart'; |
||||||
|
import 'package:flutter_html/image_render.dart'; |
||||||
|
import 'package:chewie/src/chewie_progress_colors.dart' as chewie; |
||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:flutter_html/src/replaced_element.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/activity.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/article.dart'; |
||||||
|
import 'package:video_player/video_player.dart'; |
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||||
|
|
||||||
|
class WebContent extends StatefulWidget { |
||||||
|
|
||||||
|
final Activity activity; |
||||||
|
final Article article; |
||||||
|
|
||||||
|
WebContent(this.activity, this.article); |
||||||
|
|
||||||
|
@override |
||||||
|
State<StatefulWidget> createState() { |
||||||
|
return _WebContent(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class _WebContent extends State<WebContent> { |
||||||
|
@override |
||||||
|
Widget build(BuildContext context) { |
||||||
|
return Html( |
||||||
|
data: widget.activity != null |
||||||
|
? widget.activity.content |
||||||
|
: widget.article != null |
||||||
|
? widget.article.content |
||||||
|
: "", |
||||||
|
customImageRenders: { |
||||||
|
base64DataUriMatcher(): base64ImageRender(), |
||||||
|
assetUriMatcher(): assetImageRender(), |
||||||
|
networkSourceMatcher(extension: "svg"): |
||||||
|
svgNetworkImageRender(), |
||||||
|
networkSourceMatcher(): networkImageRender( |
||||||
|
loadingWidget: () { |
||||||
|
return Container(); |
||||||
|
}, |
||||||
|
), |
||||||
|
}, |
||||||
|
customRender: { |
||||||
|
"video": |
||||||
|
(context, parsedChild, attributes, element) { |
||||||
|
var src = attributes['src']; |
||||||
|
return videoWidget( |
||||||
|
double.tryParse(attributes['width'] ?? ""), |
||||||
|
double.tryParse( |
||||||
|
element.attributes['height'] ?? ""), |
||||||
|
(src != null && |
||||||
|
src != "" && |
||||||
|
src.endsWith(".mp4")) |
||||||
|
? src |
||||||
|
: element |
||||||
|
.children.first.attributes["src"], |
||||||
|
element.attributes["sandbox"]); |
||||||
|
}, |
||||||
|
"iframe": |
||||||
|
(context, parsedChild, attributes, element) { |
||||||
|
var src = attributes['src']; |
||||||
|
return videoWidget( |
||||||
|
double.tryParse(attributes['width'] ?? ""), |
||||||
|
double.tryParse( |
||||||
|
element.attributes['height'] ?? ""), |
||||||
|
(src != null && |
||||||
|
src != "" && |
||||||
|
src.endsWith(".mp4")) |
||||||
|
? src |
||||||
|
: element |
||||||
|
.children.first.attributes["src"], |
||||||
|
element.attributes["sandbox"]); |
||||||
|
}, |
||||||
|
"audio": |
||||||
|
(context, parsedChild, attributes, element) { |
||||||
|
final sources = <String>[ |
||||||
|
if (element.attributes['src'] != null) |
||||||
|
element.attributes['src'], |
||||||
|
]; |
||||||
|
if (sources == null || |
||||||
|
sources.isEmpty || |
||||||
|
sources.first == null) { |
||||||
|
return EmptyContentElement(); |
||||||
|
} |
||||||
|
return audioWidget( |
||||||
|
attributes['controls'] != null, |
||||||
|
attributes['loop'] != null, |
||||||
|
attributes['autoplay'] != null, |
||||||
|
sources, |
||||||
|
context.style.width ?? 300.w, |
||||||
|
); |
||||||
|
}, |
||||||
|
}, |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
VideoPlayerController videoPlayerController; |
||||||
|
ChewieController chewieAudioController; |
||||||
|
Chewie chewies; |
||||||
|
|
||||||
|
Widget videoWidget(double width, double height, src, sandboxMode) { |
||||||
|
print("src : $src"); |
||||||
|
return Container( |
||||||
|
width: MediaQuery.of(context).size.width, |
||||||
|
height: (MediaQuery.of(context).size.width) / (width / height), |
||||||
|
child: chewies = Chewie( |
||||||
|
controller: chewieAudioController = ChewieController( |
||||||
|
videoPlayerController: videoPlayerController = |
||||||
|
VideoPlayerController.network( |
||||||
|
src, |
||||||
|
), |
||||||
|
aspectRatio: width / height, |
||||||
|
//宽高比 |
||||||
|
autoPlay: false, |
||||||
|
//自动播放 |
||||||
|
looping: false, |
||||||
|
//循环播放 |
||||||
|
// 拖动条样式颜色 |
||||||
|
materialProgressColors: chewie.ChewieProgressColors( |
||||||
|
playedColor: Colors.white, |
||||||
|
handleColor: Colors.white, |
||||||
|
backgroundColor: Colors.grey, |
||||||
|
bufferedColor: Colors.transparent, |
||||||
|
), |
||||||
|
autoInitialize: true, |
||||||
|
), |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
Widget audioWidget(showControls, loop, autoplay, src, width) { |
||||||
|
return Container( |
||||||
|
width: width, |
||||||
|
child: chewies = Chewie( |
||||||
|
controller: chewieAudioController = ChewieController( |
||||||
|
videoPlayerController: VideoPlayerController.network( |
||||||
|
src.first ?? "", |
||||||
|
), |
||||||
|
autoPlay: autoplay, |
||||||
|
looping: loop, |
||||||
|
showControls: showControls, |
||||||
|
autoInitialize: true, |
||||||
|
), |
||||||
|
), |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
@override |
||||||
|
void dispose() { |
||||||
|
|
||||||
|
if (chewieAudioController != null) { |
||||||
|
chewieAudioController.pause(); |
||||||
|
chewieAudioController.dispose(); |
||||||
|
chewieAudioController = null; |
||||||
|
} |
||||||
|
|
||||||
|
if (videoPlayerController != null) { |
||||||
|
videoPlayerController.pause(); |
||||||
|
videoPlayerController.dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
super.dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,100 @@ |
|||||||
|
|
||||||
|
import 'package:flutter/material.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/activity.dart'; |
||||||
|
import 'package:huixiang/retrofit/data/article.dart'; |
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||||
|
|
||||||
|
class WebHeader extends StatefulWidget { |
||||||
|
|
||||||
|
final Map arguments; |
||||||
|
final Activity activity; |
||||||
|
final Article article; |
||||||
|
|
||||||
|
WebHeader(this.arguments, this.activity, this.article); |
||||||
|
|
||||||
|
@override |
||||||
|
State<StatefulWidget> createState() { |
||||||
|
return _WebHeader(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
class _WebHeader extends State<WebHeader> { |
||||||
|
@override |
||||||
|
Widget build(BuildContext context) { |
||||||
|
return Column( |
||||||
|
children: [ |
||||||
|
Container( |
||||||
|
color: Color(0xFFF7F7F7), |
||||||
|
padding: EdgeInsets.all(12), |
||||||
|
alignment: Alignment.centerLeft, |
||||||
|
child: Text( |
||||||
|
widget.activity != null |
||||||
|
? widget.activity.mainTitle |
||||||
|
: widget.article != null |
||||||
|
? widget.article.mainTitle |
||||||
|
: "", |
||||||
|
style: TextStyle( |
||||||
|
fontSize: 16.sp, |
||||||
|
fontWeight: FontWeight.bold, |
||||||
|
color: Color(0xFF353535), |
||||||
|
), |
||||||
|
), |
||||||
|
), |
||||||
|
Container( |
||||||
|
padding: EdgeInsets.symmetric(horizontal: 12.w), |
||||||
|
child: Row( |
||||||
|
children: [ |
||||||
|
InkWell( |
||||||
|
child: Text( |
||||||
|
"${widget.activity != null ? (widget.activity.storeName ?? "") : (widget.article != null && widget.article.author != null) ? (widget.article.author.name ?? "") : ""}", |
||||||
|
style: TextStyle( |
||||||
|
fontWeight: FontWeight.normal, |
||||||
|
fontSize: 14.sp, |
||||||
|
color: Colors.blue, |
||||||
|
), |
||||||
|
), |
||||||
|
onTap: () { |
||||||
|
if (widget.activity != null) { |
||||||
|
if (widget.arguments["source"] != null && |
||||||
|
widget.arguments["source"] == |
||||||
|
widget.activity.storeId) { |
||||||
|
Navigator.of(context).pop(); |
||||||
|
} else { |
||||||
|
Navigator.of(context).pushNamed( |
||||||
|
'/router/union_detail_page', |
||||||
|
arguments: { |
||||||
|
"id": widget.activity.storeId, |
||||||
|
"source": |
||||||
|
widget.arguments["activityId"] |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
}, |
||||||
|
), |
||||||
|
SizedBox( |
||||||
|
width: 10.w, |
||||||
|
), |
||||||
|
Text( |
||||||
|
widget.activity != null |
||||||
|
? widget.activity.createTime |
||||||
|
: widget.article != null |
||||||
|
? widget.article.createTime |
||||||
|
: "", |
||||||
|
style: TextStyle( |
||||||
|
fontWeight: FontWeight.normal, |
||||||
|
fontSize: 12.sp, |
||||||
|
color: Colors.grey, |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
), |
||||||
|
), |
||||||
|
], |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in new issue