253 lines
8.2 KiB
Dart
253 lines
8.2 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:yumi/app/constants/sc_global_config.dart';
|
|
|
|
import 'package:yumi/ui_kit/components/sc_compontent.dart';
|
|
import 'package:yumi/ui_kit/components/text/sc_text.dart';
|
|
import 'package:yumi/shared/business_logic/models/res/login_res.dart';
|
|
import 'package:yumi/shared/tools/sc_lk_dialog_util.dart';
|
|
import 'package:yumi/services/room/rc_room_manager.dart';
|
|
import 'package:yumi/services/audio/rtc_manager.dart';
|
|
import 'package:yumi/modules/room/online/room_online_page.dart';
|
|
import 'package:yumi/modules/room/rank/room_gift_rank_page.dart';
|
|
|
|
class RoomOnlineUserWidget extends StatefulWidget {
|
|
const RoomOnlineUserWidget({super.key});
|
|
|
|
@override
|
|
State<RoomOnlineUserWidget> createState() => _RoomOnlineUserWidgetState();
|
|
}
|
|
|
|
class _RoomOnlineUserWidgetState extends State<RoomOnlineUserWidget> {
|
|
double get _onlineUsersShellHeight => 27.w;
|
|
|
|
double get _onlineUsersAvatarsWidth => 58.w;
|
|
|
|
double get _onlineUsersCounterWidth => 18.w;
|
|
|
|
double get _onlineUsersShellWidth =>
|
|
_onlineUsersAvatarsWidth + _onlineUsersCounterWidth;
|
|
|
|
void _openRoomOnlinePage() {
|
|
showBottomInBottomDialog(
|
|
context,
|
|
RoomOnlinePage(
|
|
roomId:
|
|
context
|
|
.read<RtcProvider>()
|
|
.currenRoom
|
|
?.roomProfile
|
|
?.roomProfile
|
|
?.id,
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Selector<RtcProvider, _RoomOnlineUsersSnapshot>(
|
|
selector:
|
|
(context, provider) => _RoomOnlineUsersSnapshot(
|
|
onlineUsers: List<SocialChatUserProfile>.unmodifiable(
|
|
provider.onlineUsers,
|
|
),
|
|
),
|
|
builder: (context, onlineSnapshot, child) {
|
|
final onlineUsers = onlineSnapshot.onlineUsers;
|
|
return Row(
|
|
children: [
|
|
_buildExperience(),
|
|
SizedBox(width: 15.w),
|
|
Expanded(
|
|
child: Align(
|
|
alignment: Alignment.centerRight,
|
|
child:
|
|
onlineUsers.isNotEmpty
|
|
? _buildOnlineUsers(onlineUsers)
|
|
: _buildOnlineUsersPlaceholder(),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
Widget _buildOnlineUsers(List<SocialChatUserProfile> onlineUsers) {
|
|
return Padding(
|
|
padding: EdgeInsets.only(right: 5.w),
|
|
child: GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onTap: _openRoomOnlinePage,
|
|
child: SizedBox(
|
|
width: _onlineUsersShellWidth,
|
|
height: _onlineUsersShellHeight,
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
SizedBox(
|
|
width: _onlineUsersAvatarsWidth,
|
|
height: 25.w,
|
|
child: Align(
|
|
alignment: Alignment.centerRight,
|
|
child: SingleChildScrollView(
|
|
scrollDirection: Axis.horizontal,
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: List.generate(onlineUsers.length, (index) {
|
|
return Transform.translate(
|
|
offset: Offset(-3.w * index, 0),
|
|
child: Padding(
|
|
padding: EdgeInsets.only(right: 0.w),
|
|
child: netImage(
|
|
url: onlineUsers[index].userAvatar ?? "",
|
|
width: 23.w,
|
|
height: 23.w,
|
|
defaultImg:
|
|
SCGlobalConfig.businessLogicStrategy
|
|
.getMePageDefaultAvatarImage(),
|
|
shape: BoxShape.circle,
|
|
border: Border.all(
|
|
color: Colors.white,
|
|
width: 1.w,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
SizedBox(
|
|
width: _onlineUsersCounterWidth,
|
|
child: Container(
|
|
padding: EdgeInsets.symmetric(horizontal: 3.w, vertical: 1.w),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Image.asset(
|
|
"sc_images/room/sc_icon_online_peple.png",
|
|
width: 12.w,
|
|
height: 12.sp,
|
|
),
|
|
text("${onlineUsers.length}", fontSize: 9, lineHeight: 1),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildOnlineUsersPlaceholder() {
|
|
return Padding(
|
|
padding: EdgeInsets.only(right: 5.w),
|
|
child: SizedBox(
|
|
width: _onlineUsersShellWidth,
|
|
height: _onlineUsersShellHeight,
|
|
),
|
|
);
|
|
}
|
|
|
|
///房间榜单入口
|
|
_buildExperience() {
|
|
return Consumer<SocialChatRoomManager>(
|
|
builder: (context, ref, child) {
|
|
return GestureDetector(
|
|
child: Container(
|
|
constraints: BoxConstraints(minWidth: 90.w, maxWidth: 104.w),
|
|
height: 27.w,
|
|
padding: EdgeInsetsDirectional.only(start: 8.w, end: 4.w),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white10,
|
|
borderRadius: BorderRadiusDirectional.only(
|
|
topEnd: Radius.circular(20.w),
|
|
bottomEnd: Radius.circular(20.w),
|
|
),
|
|
),
|
|
alignment: AlignmentDirectional.center,
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: [
|
|
Image.asset(
|
|
"sc_images/room/sc_icon_room_contribute.png",
|
|
width: 18.w,
|
|
height: 18.w,
|
|
),
|
|
SizedBox(width: 4.w),
|
|
Expanded(
|
|
child: FittedBox(
|
|
fit: BoxFit.scaleDown,
|
|
alignment: Alignment.centerLeft,
|
|
child: text(
|
|
"${ref.roomContributeLevelRes?.thisWeekIntegral ?? 0}",
|
|
fontSize: 13.sp,
|
|
textColor: Colors.orangeAccent,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
Icon(
|
|
Icons.chevron_right,
|
|
size: 13.w,
|
|
color: Colors.orangeAccent,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
onTap: () {
|
|
SmartDialog.show(
|
|
tag: "showRoomGiftRankPage",
|
|
alignment: Alignment.bottomCenter,
|
|
animationType: SmartAnimationType.fade,
|
|
builder: (_) {
|
|
return RoomGiftRankPage();
|
|
},
|
|
);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
}
|
|
}
|
|
|
|
class _RoomOnlineUsersSnapshot {
|
|
const _RoomOnlineUsersSnapshot({required this.onlineUsers});
|
|
|
|
final List<SocialChatUserProfile> onlineUsers;
|
|
|
|
@override
|
|
bool operator ==(Object other) {
|
|
if (identical(this, other)) {
|
|
return true;
|
|
}
|
|
if (other is! _RoomOnlineUsersSnapshot ||
|
|
other.onlineUsers.length != onlineUsers.length) {
|
|
return false;
|
|
}
|
|
for (int index = 0; index < onlineUsers.length; index++) {
|
|
final currentUser = onlineUsers[index];
|
|
final otherUser = other.onlineUsers[index];
|
|
if (currentUser.id != otherUser.id ||
|
|
currentUser.userAvatar != otherUser.userAvatar ||
|
|
currentUser.userNickname != otherUser.userNickname ||
|
|
currentUser.roles != otherUser.roles ||
|
|
currentUser.heartbeatVal != otherUser.heartbeatVal) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
@override
|
|
int get hashCode => Object.hashAll(
|
|
onlineUsers.map((user) => Object.hash(user.id, user.userAvatar)),
|
|
);
|
|
}
|