1069 lines
53 KiB
Dart
1069 lines
53 KiB
Dart
import 'dart:convert';
|
||
|
||
import 'package:flutter/cupertino.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||
import 'package:aslan/chatvibe_core/utilities/at_dialog_utils.dart';
|
||
import 'package:aslan/chatvibe_core/utilities/at_loading_manager.dart';
|
||
import 'package:aslan/chatvibe_data/sources/local/user_manager.dart';
|
||
import 'package:aslan/chatvibe_data/sources/repositories/dynamic_repository_imp.dart';
|
||
import 'package:provider/provider.dart';
|
||
import 'package:readmore/readmore.dart';
|
||
|
||
import 'package:aslan/app_localizations.dart';
|
||
import 'package:aslan/chatvibe_ui/components/appbar/chatvibe_appbar.dart';
|
||
import 'package:aslan/chatvibe_ui/components/at_debounce_widget.dart';
|
||
import 'package:aslan/chatvibe_ui/components/dialog/dialog_base.dart';
|
||
import 'package:aslan/chatvibe_ui/components/at_compontent.dart';
|
||
import 'package:aslan/chatvibe_ui/components/text/at_text.dart';
|
||
import 'package:aslan/chatvibe_ui/components/at_tts.dart';
|
||
import 'package:aslan/chatvibe_ui/theme/chatvibe_theme.dart';
|
||
import 'package:aslan/chatvibe_core/routes/at_fluro_navigator.dart';
|
||
import 'package:aslan/chatvibe_core/utilities/at_date_utils.dart';
|
||
import 'package:aslan/chatvibe_data/sources/repositories/user_repository_impl.dart';
|
||
import 'package:aslan/chatvibe_domain/models/res/dynamic_list_res.dart';
|
||
import 'package:aslan/chatvibe_managers/dynamic_content_manager.dart';
|
||
import 'package:aslan/chatvibe_managers/user_profile_manager.dart';
|
||
import 'package:aslan/chatvibe_ui/widgets/dynamic/comment/comment_input.dart';
|
||
import 'package:aslan/chatvibe_features/index/main_route.dart';
|
||
import 'package:aslan/chatvibe_features/dynamic/detail/comment/dynamic_comment_page.dart';
|
||
import 'package:aslan/chatvibe_features/dynamic/detail/gift/dynamic_comment_gift_page.dart';
|
||
import 'package:aslan/chatvibe_features/dynamic/detail/like/dynamic_comment_like_page.dart';
|
||
|
||
import '../../../chatvibe_core/at_lk_event_bus.dart';
|
||
|
||
class DynamicDetailPage extends StatefulWidget {
|
||
String id = "";
|
||
String canGoUserInfo = "";
|
||
|
||
DynamicDetailPage(this.id, this.canGoUserInfo);
|
||
|
||
@override
|
||
_DynamicDetailPageState createState() => _DynamicDetailPageState();
|
||
}
|
||
|
||
class _DynamicDetailPageState extends State<DynamicDetailPage>
|
||
with SingleTickerProviderStateMixin {
|
||
late TabController _tabController;
|
||
Records? detail;
|
||
String? toUserId;
|
||
num? rootCommentId;
|
||
String? commentId;
|
||
String cName = "";
|
||
|
||
// 添加滚动控制器
|
||
final ScrollController _scrollController = ScrollController();
|
||
double _opacity = 0.0;
|
||
|
||
@override
|
||
void initState() {
|
||
super.initState();
|
||
_tabController = TabController(length: 3, vsync: this);
|
||
_tabController.addListener(_handleTabSelection);
|
||
// 监听滚动
|
||
_scrollController.addListener(() {
|
||
if (_scrollController.hasClients) {
|
||
final offset = _scrollController.offset;
|
||
// 当滚动到一定位置时,头像和昵称应该完全显示在AppBar上
|
||
// 这里计算透明度,可以根据需要调整
|
||
final newOpacity = (offset / 150).clamp(0.0, 1.0);
|
||
if (newOpacity != _opacity) {
|
||
setState(() {
|
||
_opacity = newOpacity;
|
||
});
|
||
}
|
||
}
|
||
});
|
||
_loadData();
|
||
}
|
||
|
||
_handleTabSelection() {
|
||
if (!_tabController.indexIsChanging) {
|
||
Provider.of<ChatVibeDynamicContentManager>(
|
||
context,
|
||
listen: false,
|
||
).updateShowEmojiState(false, () {});
|
||
Provider.of<ChatVibeDynamicContentManager>(context, listen: false).updateShowGiftState(
|
||
false,
|
||
() {
|
||
setState(() {});
|
||
},
|
||
);
|
||
}
|
||
}
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return WillPopScope(
|
||
onWillPop: () async {
|
||
if (Provider.of<ChatVibeDynamicContentManager>(context, listen: false).showEmoji) {
|
||
Provider.of<ChatVibeDynamicContentManager>(
|
||
context,
|
||
listen: false,
|
||
).updateShowEmojiState(false, () {
|
||
setState(() {});
|
||
});
|
||
return false;
|
||
}
|
||
|
||
if (Provider.of<ChatVibeDynamicContentManager>(context, listen: false).showGift) {
|
||
Provider.of<ChatVibeDynamicContentManager>(
|
||
context,
|
||
listen: false,
|
||
).updateShowGiftState(false, () {
|
||
setState(() {});
|
||
});
|
||
return false;
|
||
}
|
||
return true;
|
||
},
|
||
child: GestureDetector(
|
||
child: Stack(
|
||
children: [
|
||
Image.asset(
|
||
"atu_images/room/at_icon_room_settig_bg.png",
|
||
width: ScreenUtil().screenWidth,
|
||
height: ScreenUtil().screenHeight,
|
||
fit: BoxFit.fill,
|
||
),
|
||
Scaffold(
|
||
backgroundColor: Colors.transparent,
|
||
resizeToAvoidBottomInset: true,
|
||
appBar: ChatVibeStandardAppBar(
|
||
title: "",
|
||
actions: [
|
||
if (_opacity > 0.5) ...[
|
||
SizedBox(width: 45.w),
|
||
head(
|
||
url: detail?.userAvatar ?? "",
|
||
width: 50.w,
|
||
height: 50.w,
|
||
),
|
||
SizedBox(width: 8.w),
|
||
Container(
|
||
constraints: BoxConstraints(
|
||
maxWidth: 135.w,
|
||
maxHeight: 22.w,
|
||
),
|
||
child: chatvibeNickNameText(
|
||
maxWidth: 135.w,
|
||
detail?.userProfile?.userNickname ?? "",
|
||
fontSize: 16.sp,
|
||
textColor: Colors.black,
|
||
fontWeight: FontWeight.w600,
|
||
type: detail?.userProfile?.getVIP()?.name ?? "",
|
||
needScroll:
|
||
(detail
|
||
?.userProfile
|
||
?.userNickname
|
||
?.characters
|
||
.length ??
|
||
0) >
|
||
13,
|
||
),
|
||
),
|
||
SizedBox(width: 8.w),
|
||
Spacer(),
|
||
detail?.userId !=
|
||
AccountStorage().getCurrentUser()?.userProfile?.id
|
||
? ((detail?.subscription ?? false)
|
||
? Container()
|
||
: ATDebounceWidget(
|
||
child: Container(
|
||
alignment: AlignmentDirectional.center,
|
||
decoration: BoxDecoration(
|
||
borderRadius: BorderRadius.circular(12.w),
|
||
gradient: LinearGradient(
|
||
colors: [
|
||
Color(0xff7726FF),
|
||
Color(0xffC670FF),
|
||
],
|
||
),
|
||
),
|
||
width: 68.w,
|
||
height: 23.w,
|
||
child: text(
|
||
ATAppLocalizations.of(context)!.follow,
|
||
textColor: Colors.white,
|
||
fontWeight: FontWeight.w600,
|
||
fontSize: 13.sp,
|
||
),
|
||
),
|
||
onTap: () {
|
||
AccountRepository()
|
||
.followUser(detail?.userId ?? "")
|
||
.then((result) {
|
||
detail?.setSubscription(true);
|
||
setState(() {});
|
||
});
|
||
},
|
||
))
|
||
: Container(),
|
||
ATDebounceWidget(
|
||
child: Container(
|
||
child: Icon(
|
||
Icons.more_vert,
|
||
color: Colors.black45,
|
||
size: 18.w,
|
||
),
|
||
padding: EdgeInsetsDirectional.all(3.w),
|
||
),
|
||
onTap: () {
|
||
ATDialogUtils.revealDynamicCommentOptDialog(
|
||
context,
|
||
reportCallback:
|
||
detail?.userId !=
|
||
AccountStorage()
|
||
.getCurrentUser()
|
||
?.userProfile
|
||
?.id
|
||
? () {
|
||
ATNavigatorUtils.push(
|
||
context,
|
||
"${MainRoute.report}?type=dynamic&tageId=${detail?.dynamicId}",
|
||
replace: false,
|
||
);
|
||
}
|
||
: null,
|
||
deleteCallback:
|
||
detail?.userId ==
|
||
AccountStorage()
|
||
.getCurrentUser()
|
||
?.userProfile
|
||
?.id ||
|
||
(Provider.of<ChatVibeUserProfileManager>(
|
||
context,
|
||
listen: false,
|
||
).userIdentity?.admin ??
|
||
false)
|
||
? () {
|
||
SmartDialog.show(
|
||
tag: "showConfirmDialog",
|
||
alignment: Alignment.center,
|
||
debounce: true,
|
||
animationType: SmartAnimationType.fade,
|
||
builder: (_) {
|
||
return MsgDialog(
|
||
title:
|
||
ATAppLocalizations.of(
|
||
context,
|
||
)!.tips,
|
||
msg:
|
||
ATAppLocalizations.of(
|
||
context,
|
||
)!.deleteDynamicTips,
|
||
btnText:
|
||
ATAppLocalizations.of(
|
||
context,
|
||
)!.confirm,
|
||
leftConfirm: true,
|
||
isBtnBgFlip: true,
|
||
onEnsure: () {
|
||
_deleteDynamic(
|
||
detail?.dynamicId ?? "",
|
||
);
|
||
},
|
||
);
|
||
},
|
||
);
|
||
}
|
||
: null,
|
||
);
|
||
},
|
||
),
|
||
],
|
||
],
|
||
),
|
||
body: SafeArea(
|
||
top: false,
|
||
child: Stack(
|
||
alignment: Alignment.bottomCenter,
|
||
children: [
|
||
NestedScrollView(
|
||
controller: _scrollController,
|
||
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||
return [
|
||
SliverToBoxAdapter(
|
||
child: Column(
|
||
mainAxisSize: MainAxisSize.min,
|
||
crossAxisAlignment: CrossAxisAlignment.start,
|
||
children: [
|
||
Row(
|
||
children: [
|
||
SizedBox(width: 10.w),
|
||
ATDebounceWidget(
|
||
child: netImage(
|
||
url:
|
||
detail?.userProfile?.userAvatar ??
|
||
"",
|
||
shape: BoxShape.circle,
|
||
height: 45.w,
|
||
width: 45.w,
|
||
),
|
||
onTap: () {
|
||
if (widget.canGoUserInfo == "true") {
|
||
ATNavigatorUtils.push(
|
||
context,
|
||
"${MainRoute.person}?isMe=${AccountStorage().getCurrentUser()?.userProfile?.id == detail?.userProfile?.id}&tageId=${detail?.userProfile?.id}",
|
||
);
|
||
}
|
||
},
|
||
),
|
||
Expanded(
|
||
child: Column(
|
||
crossAxisAlignment:
|
||
CrossAxisAlignment.start,
|
||
children: [
|
||
Row(
|
||
spacing: 3.w,
|
||
children: [
|
||
Container(
|
||
margin:
|
||
EdgeInsetsDirectional.only(
|
||
start: 5.w,
|
||
),
|
||
child:
|
||
chatvibeNickNameText(
|
||
maxWidth: 95.w,
|
||
detail?.userProfile?.userNickname ?? "",
|
||
fontSize: 15.sp,
|
||
textColor: Colors.black,
|
||
fontWeight: FontWeight.w400,
|
||
type: detail?.userProfile?.getVIP()?.name ?? "",
|
||
needScroll:
|
||
(detail
|
||
?.userProfile
|
||
?.userNickname
|
||
?.characters
|
||
.length ??
|
||
0) >
|
||
10,
|
||
)
|
||
|
||
),
|
||
Container(
|
||
width:
|
||
(detail?.userProfile?.age ??
|
||
0) >
|
||
999
|
||
? 58.w
|
||
: 48.w,
|
||
height: 24.w,
|
||
decoration: BoxDecoration(
|
||
image: DecorationImage(
|
||
image: AssetImage(
|
||
detail
|
||
?.userProfile
|
||
?.userSex ==
|
||
0
|
||
? "atu_images/login/at_icon_sex_woman_bg.png"
|
||
: "atu_images/login/at_icon_sex_man_bg.png",
|
||
),
|
||
),
|
||
),
|
||
child: Row(
|
||
crossAxisAlignment:
|
||
CrossAxisAlignment.center,
|
||
mainAxisAlignment:
|
||
MainAxisAlignment.center,
|
||
children: [
|
||
xb(
|
||
detail
|
||
?.userProfile
|
||
?.userSex,
|
||
),
|
||
text(
|
||
"${detail?.userProfile?.age ?? 0}",
|
||
textColor: Colors.white,
|
||
fontSize: 14.sp,
|
||
fontWeight:
|
||
FontWeight.w600,
|
||
),
|
||
SizedBox(width: 3.w),
|
||
],
|
||
),
|
||
),
|
||
getVIPBadge(
|
||
detail?.userProfile
|
||
?.getVIP()
|
||
?.name,
|
||
width: 45.w,
|
||
height: 25.w,
|
||
),
|
||
],
|
||
),
|
||
Container(
|
||
alignment:
|
||
AlignmentDirectional
|
||
.centerStart,
|
||
child: SingleChildScrollView(
|
||
scrollDirection: Axis.horizontal,
|
||
child: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
SizedBox(width: 5.w),
|
||
detail
|
||
?.userProfile
|
||
?.wearBadge
|
||
?.isNotEmpty ??
|
||
false
|
||
? SizedBox(
|
||
height: 28.w,
|
||
child: ListView.separated(
|
||
scrollDirection:
|
||
Axis.horizontal,
|
||
shrinkWrap: true,
|
||
itemCount:
|
||
detail
|
||
?.userProfile
|
||
?.wearBadge
|
||
?.length ??
|
||
0,
|
||
itemBuilder: (
|
||
context,
|
||
index,
|
||
) {
|
||
return netImage(
|
||
width: 28.w,
|
||
height: 28.w,
|
||
url:
|
||
detail
|
||
?.userProfile
|
||
?.wearBadge?[index]
|
||
.selectUrl ??
|
||
"",
|
||
);
|
||
},
|
||
separatorBuilder: (
|
||
BuildContext
|
||
context,
|
||
int index,
|
||
) {
|
||
return SizedBox(
|
||
width: 5.w,
|
||
);
|
||
},
|
||
),
|
||
)
|
||
: Container(),
|
||
SizedBox(width: 5.w),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
SizedBox(width: 5.w),
|
||
detail?.userId !=
|
||
AccountStorage()
|
||
.getCurrentUser()
|
||
?.userProfile
|
||
?.id
|
||
? ((detail?.subscription ?? false)
|
||
? Container()
|
||
: ATDebounceWidget(
|
||
child: Container(
|
||
alignment:
|
||
AlignmentDirectional.center,
|
||
decoration: BoxDecoration(
|
||
borderRadius:
|
||
BorderRadius.circular(
|
||
12.w,
|
||
),
|
||
gradient: LinearGradient(
|
||
colors: [
|
||
Color(0xff7726FF),
|
||
Color(0xffC670FF),
|
||
],
|
||
),
|
||
),
|
||
width: 68.w,
|
||
height: 23.w,
|
||
child: text(
|
||
ATAppLocalizations.of(
|
||
context,
|
||
)!.follow,
|
||
textColor: Colors.white,
|
||
fontWeight: FontWeight.w600,
|
||
fontSize: 13.sp,
|
||
),
|
||
),
|
||
onTap: () {
|
||
AccountRepository()
|
||
.followUser(
|
||
detail?.userId ?? "",
|
||
)
|
||
.then((result) {
|
||
detail?.setSubscription(
|
||
true,
|
||
);
|
||
setState(() {});
|
||
});
|
||
},
|
||
))
|
||
: Container(),
|
||
ATDebounceWidget(
|
||
child: Container(
|
||
child: Icon(
|
||
Icons.more_vert,
|
||
color: Colors.black45,
|
||
size: 18.w,
|
||
),
|
||
padding: EdgeInsetsDirectional.all(3.w),
|
||
),
|
||
onTap: () {
|
||
ATDialogUtils.revealDynamicCommentOptDialog(
|
||
context,
|
||
reportCallback:
|
||
detail?.userId !=
|
||
AccountStorage()
|
||
.getCurrentUser()
|
||
?.userProfile
|
||
?.id
|
||
? () {
|
||
ATNavigatorUtils.push(
|
||
context,
|
||
"${MainRoute.report}?type=dynamic&tageId=${detail?.dynamicId}",
|
||
replace: false,
|
||
);
|
||
}
|
||
: null,
|
||
deleteCallback:
|
||
detail?.userId ==
|
||
AccountStorage()
|
||
.getCurrentUser()
|
||
?.userProfile
|
||
?.id ||
|
||
(Provider.of<
|
||
ChatVibeUserProfileManager
|
||
>(
|
||
context,
|
||
listen: false,
|
||
)
|
||
.userIdentity
|
||
?.admin ??
|
||
false)
|
||
? () {
|
||
SmartDialog.show(
|
||
tag: "showConfirmDialog",
|
||
alignment:
|
||
Alignment.center,
|
||
debounce: true,
|
||
animationType:
|
||
SmartAnimationType
|
||
.fade,
|
||
builder: (_) {
|
||
return MsgDialog(
|
||
title:
|
||
ATAppLocalizations.of(
|
||
context,
|
||
)!.tips,
|
||
msg:
|
||
ATAppLocalizations.of(
|
||
context,
|
||
)!.deleteDynamicTips,
|
||
btnText:
|
||
ATAppLocalizations.of(
|
||
context,
|
||
)!.confirm,
|
||
leftConfirm: true,
|
||
isBtnBgFlip: true,
|
||
onEnsure: () {
|
||
_deleteDynamic(
|
||
detail?.dynamicId ??
|
||
"",
|
||
);
|
||
},
|
||
);
|
||
},
|
||
);
|
||
}
|
||
: null,
|
||
);
|
||
},
|
||
),
|
||
SizedBox(width: 3.w),
|
||
],
|
||
),
|
||
SizedBox(height: 3.w),
|
||
Row(
|
||
crossAxisAlignment: CrossAxisAlignment.end,
|
||
children: [
|
||
Expanded(
|
||
child: Container(
|
||
margin: EdgeInsetsDirectional.symmetric(
|
||
horizontal: 10.w,
|
||
),
|
||
child: ReadMoreText(
|
||
detail?.content ?? "",
|
||
trimLines: 3,
|
||
// 收缩时显示的行数
|
||
trimMode: TrimMode.Line,
|
||
style: TextStyle(
|
||
fontFamily: "MyCustomFont",
|
||
fontSize: 13.sp,
|
||
color: Colors.black,
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
|
||
// 按行截断
|
||
trimCollapsedText:
|
||
ATAppLocalizations.of(
|
||
context,
|
||
)!.showMore,
|
||
// 收缩时按钮文字
|
||
trimExpandedText:
|
||
ATAppLocalizations.of(
|
||
context,
|
||
)!.showLess,
|
||
// 展开时按钮文字
|
||
moreStyle: TextStyle(
|
||
color: ChatVibeTheme.primaryLight,
|
||
fontFamily: "MyCustomFont",
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
lessStyle: TextStyle(
|
||
color: ChatVibeTheme.primaryLight,
|
||
fontFamily: "MyCustomFont",
|
||
fontWeight: FontWeight.w600,
|
||
),
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
SizedBox(height: 5.w),
|
||
(detail?.pictures?.isNotEmpty ?? false)
|
||
? detail?.pictures?.length == 1
|
||
? Container(
|
||
margin: EdgeInsets.symmetric(
|
||
horizontal: 10.w,
|
||
),
|
||
constraints: BoxConstraints(
|
||
maxWidth:
|
||
ScreenUtil().screenWidth / 2,
|
||
),
|
||
child: ATDebounceWidget(
|
||
child: netImage(
|
||
url:
|
||
detail
|
||
?.pictures
|
||
?.first
|
||
.resourceUrl ??
|
||
"",
|
||
borderRadius:
|
||
BorderRadius.circular(8.w),
|
||
),
|
||
onTap: () {
|
||
List<String> ims = [];
|
||
for (var pc
|
||
in detail?.pictures ?? []) {
|
||
String path = pc.resourceUrl;
|
||
if (path.isNotEmpty) {
|
||
ims.add(path);
|
||
}
|
||
}
|
||
String encodedUrls =
|
||
Uri.encodeComponent(
|
||
jsonEncode(ims),
|
||
);
|
||
ATNavigatorUtils.push(
|
||
context,
|
||
"${MainRoute.imagePreview}?imageUrls=$encodedUrls&initialIndex=0",
|
||
);
|
||
},
|
||
),
|
||
)
|
||
: Container(
|
||
child: GridView.builder(
|
||
shrinkWrap: true,
|
||
physics:
|
||
const NeverScrollableScrollPhysics(),
|
||
gridDelegate:
|
||
SliverGridDelegateWithFixedCrossAxisCount(
|
||
crossAxisCount:
|
||
detail
|
||
?.pictures
|
||
?.length ==
|
||
1
|
||
? 1
|
||
: (detail
|
||
?.pictures
|
||
?.length ==
|
||
2
|
||
? 2
|
||
: 3), // 每行2个
|
||
mainAxisSpacing: 10,
|
||
crossAxisSpacing: 10,
|
||
),
|
||
padding: EdgeInsets.all(10),
|
||
itemCount: detail?.pictures?.length,
|
||
itemBuilder: (context, index) {
|
||
return ATDebounceWidget(
|
||
child: netImage(
|
||
url:
|
||
detail
|
||
?.pictures?[index]
|
||
.resourceUrl ??
|
||
"",
|
||
borderRadius:
|
||
BorderRadius.circular(
|
||
8.w,
|
||
),
|
||
),
|
||
onTap: () {
|
||
List<String> ims = [];
|
||
for (var pc
|
||
in detail?.pictures ??
|
||
[]) {
|
||
String path =
|
||
pc.resourceUrl;
|
||
if (path.isNotEmpty) {
|
||
ims.add(path);
|
||
}
|
||
}
|
||
String encodedUrls =
|
||
Uri.encodeComponent(
|
||
jsonEncode(ims),
|
||
);
|
||
ATNavigatorUtils.push(
|
||
context,
|
||
"${MainRoute.imagePreview}?imageUrls=$encodedUrls&initialIndex=$index",
|
||
);
|
||
},
|
||
);
|
||
},
|
||
),
|
||
)
|
||
: Container(),
|
||
SizedBox(height: 5.w),
|
||
Row(
|
||
children: [
|
||
Container(
|
||
margin: EdgeInsetsDirectional.only(
|
||
start: 10.w,
|
||
),
|
||
alignment:
|
||
AlignmentDirectional.centerStart,
|
||
child: text(
|
||
ATMDateUtils.formatMessageTime(
|
||
context,
|
||
DateTime.fromMillisecondsSinceEpoch(
|
||
detail?.createTime ?? 0,
|
||
),
|
||
),
|
||
textColor: Colors.grey,
|
||
fontSize: 12.sp,
|
||
),
|
||
),
|
||
Spacer(),
|
||
],
|
||
),
|
||
SizedBox(height: 5.w),
|
||
],
|
||
),
|
||
),
|
||
SliverPersistentHeader(
|
||
pinned: true, // TabBar 是否固定
|
||
delegate: _SliverAppBarDelegate(
|
||
Container(
|
||
color: Colors.white, // 背景色
|
||
child: TabBar(
|
||
controller: _tabController,
|
||
isScrollable: false,
|
||
indicatorSize: TabBarIndicatorSize.tab,
|
||
tabs: [
|
||
_buildTab(
|
||
0,
|
||
"atu_images/dynamic/at_icon_reply.png",
|
||
"${ATAppLocalizations.of(context)!.comment}(${detail?.commentStrQuantity ?? 0})",
|
||
true,
|
||
),
|
||
_buildTab(
|
||
1,
|
||
(detail?.like ?? false)
|
||
? "atu_images/dynamic/at_icon_like_red.png"
|
||
: "atu_images/dynamic/at_icon_like.png",
|
||
"${ATAppLocalizations.of(context)!.like}(${detail?.likeStrQuantity ?? 0})",
|
||
!(detail?.like ?? false),
|
||
),
|
||
_buildTab(
|
||
2,
|
||
"atu_images/dynamic/at_icon_dy_gift2.png",
|
||
"${ATAppLocalizations.of(context)!.gift}(${detail?.giftStrQuantity ?? 0})",
|
||
false,
|
||
),
|
||
],
|
||
dividerColor: Colors.transparent,
|
||
labelStyle: TextStyle(
|
||
fontSize: 16.sp,
|
||
fontFamily: 'MyCustomFont',
|
||
fontWeight: FontWeight.bold,
|
||
),
|
||
unselectedLabelStyle: TextStyle(
|
||
fontSize: 15.sp,
|
||
fontFamily: 'MyCustomFont',
|
||
color: Colors.grey,
|
||
fontWeight: FontWeight.normal,
|
||
),
|
||
indicator: BoxDecoration(
|
||
gradient: LinearGradient(
|
||
colors: [
|
||
Color(0xff7726FF).withOpacity(0.6),
|
||
Color(0xff7726FF).withOpacity(0.1),
|
||
],
|
||
),
|
||
),
|
||
labelPadding: EdgeInsets.zero,
|
||
),
|
||
),
|
||
),
|
||
),
|
||
];
|
||
},
|
||
body: Container(
|
||
margin: EdgeInsets.only(bottom: 45.w),
|
||
child: TabBarView(
|
||
physics: NeverScrollableScrollPhysics(),
|
||
controller: _tabController,
|
||
children: [
|
||
DynamicCommentPage(
|
||
widget.id,
|
||
num.parse(detail?.commentStrQuantity ?? "0"),
|
||
widget.canGoUserInfo,
|
||
repayCall: (
|
||
cId,
|
||
toUserId,
|
||
rootCommentId,
|
||
toUserName,
|
||
) {
|
||
this.toUserId = toUserId;
|
||
cName = toUserName;
|
||
this.rootCommentId = rootCommentId;
|
||
this.commentId = cId;
|
||
setState(() {});
|
||
},
|
||
deleteCall: (count) {
|
||
setState(() {
|
||
toUserId = null;
|
||
cName = "";
|
||
rootCommentId = null;
|
||
commentId = null;
|
||
num cont =
|
||
int.parse(
|
||
detail?.commentStrQuantity ?? "0",
|
||
) -
|
||
count;
|
||
detail?.setCommentStrQuantity("${cont}");
|
||
setState(() {});
|
||
});
|
||
},
|
||
),
|
||
DynamicCommentLikePage(
|
||
widget.id,
|
||
widget.canGoUserInfo,
|
||
),
|
||
DynamicCommentGiftPage(
|
||
widget.id,
|
||
widget.canGoUserInfo,
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
CommentInput(
|
||
detail?.userId ?? "",
|
||
widget.id,
|
||
toUserName: cName,
|
||
deleteCallBack: () {
|
||
if (rootCommentId == null &&
|
||
toUserId == null &&
|
||
cName.isEmpty) {
|
||
return;
|
||
}
|
||
setState(() {
|
||
toUserId = null;
|
||
cName = "";
|
||
rootCommentId = null;
|
||
commentId = null;
|
||
});
|
||
},
|
||
callBack: (tx) {
|
||
comment(tx);
|
||
},
|
||
sendGiftCallBack: (count) {
|
||
int cont =
|
||
int.parse(detail?.giftStrQuantity ?? "0") + count;
|
||
detail?.setGiftStrQuantity("${cont}");
|
||
setState(() {});
|
||
},
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
onTap: () {
|
||
Provider.of<ChatVibeDynamicContentManager>(
|
||
context,
|
||
listen: false,
|
||
).updateShowEmojiState(false, () {
|
||
setState(() {});
|
||
});
|
||
Provider.of<ChatVibeDynamicContentManager>(
|
||
context,
|
||
listen: false,
|
||
).updateShowGiftState(false, () {
|
||
setState(() {});
|
||
});
|
||
},
|
||
),
|
||
);
|
||
}
|
||
|
||
void _deleteDynamic(String dynamicId) {
|
||
DynamicRepositoryImp()
|
||
.dynamicDelete(dynamicId)
|
||
.then((result) {
|
||
eventBus.fire(UpdateDynamicEvent());
|
||
ATNavigatorUtils.goBack(context);
|
||
ATTts.show(ATAppLocalizations.of(context)!.deleteSuccessful);
|
||
})
|
||
.catchError((e) {});
|
||
}
|
||
|
||
void comment(String text) {
|
||
DynamicRepositoryImp()
|
||
.dynamicComment(
|
||
text,
|
||
widget.id,
|
||
toUserId: toUserId,
|
||
commentId: commentId,
|
||
rootCommentId: rootCommentId,
|
||
)
|
||
.then((res) {
|
||
res.setUserNickname(
|
||
AccountStorage().getCurrentUser()?.userProfile?.userNickname ?? "",
|
||
);
|
||
res.setUserAvatar(
|
||
AccountStorage().getCurrentUser()?.userProfile?.userAvatar ?? "",
|
||
);
|
||
res.setUserSex(
|
||
AccountStorage().getCurrentUser()?.userProfile?.userSex ?? 1,
|
||
);
|
||
if (rootCommentId == null) {
|
||
Provider.of<ChatVibeDynamicContentManager>(
|
||
context,
|
||
listen: false,
|
||
).updateRootComment(res, () {
|
||
setState(() {});
|
||
});
|
||
} else {
|
||
Provider.of<ChatVibeDynamicContentManager>(
|
||
context,
|
||
listen: false,
|
||
).updateChildComment(res, rootCommentId ?? 0, toUserId ?? "", () {
|
||
setState(() {});
|
||
});
|
||
}
|
||
toUserId = null;
|
||
cName = "";
|
||
rootCommentId = null;
|
||
commentId = null;
|
||
FocusScope.of(context).unfocus();
|
||
int cont = int.parse(detail?.commentStrQuantity ?? "0") + 1;
|
||
detail?.setCommentStrQuantity("${cont}");
|
||
setState(() {});
|
||
ATTts.show(ATAppLocalizations.of(context)!.replySucc);
|
||
});
|
||
}
|
||
|
||
Widget _buildTab(
|
||
int index,
|
||
String imagePath,
|
||
String text,
|
||
bool needSwitchImage,
|
||
) {
|
||
bool isSelected = _tabController.index == index;
|
||
return Tab(
|
||
child: Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
if (isSelected)
|
||
Image.asset(
|
||
imagePath, // 原图
|
||
height: 20.w,
|
||
)
|
||
else
|
||
Image.asset(
|
||
imagePath, // 这里可以使用灰色图片路径,或者使用颜色滤镜
|
||
height: 20.w,
|
||
color: needSwitchImage ? Colors.grey : null, // 使用颜色滤镜将图片变为灰色
|
||
),
|
||
SizedBox(width: 3.w),
|
||
Text(
|
||
text,
|
||
style:
|
||
isSelected
|
||
? TextStyle(
|
||
fontSize: 13.sp,
|
||
fontWeight: FontWeight.w600,
|
||
color: Colors.white, // 选中时文字颜色
|
||
)
|
||
: TextStyle(
|
||
fontSize: 13.sp,
|
||
fontWeight: FontWeight.normal,
|
||
color: index == 2 ? ChatVibeTheme.primaryLight : Colors.grey, // 未选中时文字颜色
|
||
),
|
||
),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
|
||
void _loadData() {
|
||
ATLoadingManager.exhibitOperation();
|
||
DynamicRepositoryImp()
|
||
.dynamicDetails(widget.id)
|
||
.then((result) {
|
||
ATLoadingManager.veilRoutine();
|
||
detail = result;
|
||
setState(() {});
|
||
})
|
||
.catchError((_) {
|
||
eventBus.fire(UpdateDynamicEvent());
|
||
ATLoadingManager.veilRoutine();
|
||
ATNavigatorUtils.goBack(context);
|
||
});
|
||
}
|
||
}
|
||
|
||
class _SliverAppBarDelegate extends SliverPersistentHeaderDelegate {
|
||
_SliverAppBarDelegate(this._tabBar);
|
||
|
||
final Widget _tabBar;
|
||
|
||
@override
|
||
double get minExtent => 35.w;
|
||
|
||
@override
|
||
double get maxExtent => 35.w;
|
||
|
||
@override
|
||
Widget build(
|
||
BuildContext context,
|
||
double shrinkOffset,
|
||
bool overlapsContent,
|
||
) {
|
||
return _tabBar;
|
||
}
|
||
|
||
@override
|
||
bool shouldRebuild(_SliverAppBarDelegate oldDelegate) {
|
||
return true;
|
||
}
|
||
}
|