891 lines
27 KiB
Dart
891 lines
27 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
|
|
import 'package:yumi/ui_kit/components/sc_compontent.dart';
|
|
import 'package:yumi/ui_kit/components/sc_tts.dart';
|
|
import 'package:yumi/shared/tools/sc_loading_manager.dart';
|
|
import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart';
|
|
import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
|
|
import 'package:yumi/services/audio/rtc_manager.dart';
|
|
import 'package:provider/provider.dart';
|
|
import 'package:yumi/app_localizations.dart';
|
|
import 'package:yumi/ui_kit/components/dialog/dialog_base.dart';
|
|
import 'package:yumi/app/routes/sc_fluro_navigator.dart';
|
|
import 'package:yumi/app/constants/sc_room_msg_type.dart';
|
|
import 'package:yumi/shared/tools/sc_pick_utils.dart';
|
|
import 'package:yumi/services/room/rc_room_manager.dart';
|
|
import 'package:yumi/services/audio/rtm_manager.dart';
|
|
import 'package:yumi/ui_kit/theme/socialchat_theme.dart';
|
|
import 'package:yumi/ui_kit/widgets/room/room_msg_item.dart';
|
|
import '../../../shared/tools/sc_lk_dialog_util.dart';
|
|
import '../../../shared/data_sources/models/enum/sc_room_info_event_type.dart';
|
|
import '../../../shared/business_logic/usecases/sc_accurate_length_limiting_textInput_formatter.dart';
|
|
import '../../../ui_kit/widgets/room/switch_model/room_mic_switch_page.dart';
|
|
import '../block/blocked_list_page.dart';
|
|
import '../voice_room_route.dart';
|
|
|
|
///编辑房间信息
|
|
class RoomEditPage extends StatefulWidget {
|
|
final String needRestCurrentRoomInfo;
|
|
final RoomEntryPreviewData? setupPreviewData;
|
|
|
|
const RoomEditPage({
|
|
super.key,
|
|
this.needRestCurrentRoomInfo = "false",
|
|
this.setupPreviewData,
|
|
});
|
|
|
|
@override
|
|
State<RoomEditPage> createState() => _RoomEditPageState();
|
|
}
|
|
|
|
class _RoomEditPageState extends State<RoomEditPage> {
|
|
static const Set<int> _roomGroupReadyCodes = {0, 10021, 10025};
|
|
static const Color _backgroundColor = Color(0xff071E1D);
|
|
static const Color _fieldColor = Color(0xff08251E);
|
|
static const Color _fieldBorderColor = Color(0xffB2FBCC);
|
|
static const Color _dangerColor = Color(0xffff0000);
|
|
|
|
RtcProvider? rtcProvider;
|
|
bool isEdit = false;
|
|
bool _isBasicInfoEditing = false;
|
|
final TextEditingController _roomNameController = TextEditingController();
|
|
final TextEditingController _roomAnnouncementController =
|
|
TextEditingController();
|
|
final TextEditingController _roomLockPasswordController =
|
|
TextEditingController();
|
|
final int _roomNameMaxLength = 24;
|
|
int _roomNameCurrentLength = 0;
|
|
String roomCover = "";
|
|
final int _roomAnnouncementMaxLength = 200;
|
|
int _roomAnnouncementCurrentLength = 0;
|
|
bool _initialRoomLocked = false;
|
|
bool _isRoomPrivate = false;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
rtcProvider = Provider.of<RtcProvider>(context, listen: false);
|
|
_roomNameController.addListener(() {
|
|
setState(() {
|
|
_roomNameCurrentLength = _getActualCharacterCount(
|
|
_roomNameController.text,
|
|
);
|
|
});
|
|
});
|
|
_roomAnnouncementController.addListener(() {
|
|
setState(() {
|
|
_roomAnnouncementCurrentLength = _getActualCharacterCount(
|
|
_roomAnnouncementController.text,
|
|
);
|
|
});
|
|
});
|
|
final setupPreviewData = widget.setupPreviewData;
|
|
_roomNameController.text =
|
|
setupPreviewData?.roomName ??
|
|
rtcProvider?.currenRoom?.roomProfile?.roomProfile?.roomName ??
|
|
"";
|
|
_roomNameCurrentLength = _getActualCharacterCount(_roomNameController.text);
|
|
_roomAnnouncementController.text =
|
|
setupPreviewData?.roomDesc ??
|
|
rtcProvider?.currenRoom?.roomProfile?.roomProfile?.roomDesc ??
|
|
"";
|
|
_roomAnnouncementCurrentLength = _getActualCharacterCount(
|
|
_roomAnnouncementController.text,
|
|
);
|
|
roomCover =
|
|
setupPreviewData?.roomCover ??
|
|
rtcProvider?.currenRoom?.roomProfile?.roomProfile?.roomCover ??
|
|
"";
|
|
final roomPassword =
|
|
setupPreviewData?.roomSetting?.password?.trim() ??
|
|
rtcProvider?.currenRoom?.roomProfile?.roomSetting?.password?.trim() ??
|
|
"";
|
|
_initialRoomLocked = roomPassword.isNotEmpty;
|
|
_isRoomPrivate = _initialRoomLocked;
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
_roomNameController.dispose();
|
|
_roomAnnouncementController.dispose();
|
|
_roomLockPasswordController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return PopScope(
|
|
canPop: false,
|
|
onPopInvokedWithResult: (didPop, result) {
|
|
if (didPop) {
|
|
return;
|
|
}
|
|
_handleSystemBack();
|
|
},
|
|
child: AnnotatedRegion<SystemUiOverlayStyle>(
|
|
value: SystemUiOverlayStyle.light,
|
|
child: Scaffold(
|
|
resizeToAvoidBottomInset: false,
|
|
backgroundColor: _backgroundColor,
|
|
body: _buildBody(context),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildBody(BuildContext context) {
|
|
final mediaQuery = MediaQuery.of(context);
|
|
final bottomPadding =
|
|
mediaQuery.viewPadding.bottom > 34.w
|
|
? 34.w
|
|
: mediaQuery.viewPadding.bottom;
|
|
return Column(
|
|
children: [
|
|
SizedBox(height: mediaQuery.viewPadding.top),
|
|
_buildNavigationBar(context),
|
|
Expanded(
|
|
child: SingleChildScrollView(
|
|
keyboardDismissBehavior: ScrollViewKeyboardDismissBehavior.onDrag,
|
|
padding: EdgeInsets.only(bottom: bottomPadding + 24.w),
|
|
child: _buildForm(context),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildNavigationBar(BuildContext context) {
|
|
return SizedBox(
|
|
width: double.infinity,
|
|
height: 44.w,
|
|
child: Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
Positioned(
|
|
left: 0,
|
|
top: 0,
|
|
bottom: 0,
|
|
child: GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onTap: _handleBack,
|
|
child: SizedBox(
|
|
width: 56.w,
|
|
height: 44.w,
|
|
child: Padding(
|
|
padding: EdgeInsets.only(left: 16.w),
|
|
child: Align(
|
|
alignment: Alignment.centerLeft,
|
|
child: Icon(
|
|
Icons.keyboard_arrow_left,
|
|
size: 24.w,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
Text(
|
|
"Room Setup",
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 18.sp,
|
|
fontWeight: FontWeight.w500,
|
|
height: 1,
|
|
),
|
|
),
|
|
PositionedDirectional(
|
|
end: 16.w,
|
|
top: 0,
|
|
bottom: 0,
|
|
child: _buildNavigationAction(context),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildNavigationAction(BuildContext context) {
|
|
final label =
|
|
_isBasicInfoEditing || isEdit
|
|
? SCAppLocalizations.of(context)!.save
|
|
: SCAppLocalizations.of(context)!.edit;
|
|
return SCDebounceWidget(
|
|
onTap: () {
|
|
if (!_isBasicInfoEditing && !isEdit) {
|
|
setState(() {
|
|
_isBasicInfoEditing = true;
|
|
});
|
|
return;
|
|
}
|
|
submit(context);
|
|
},
|
|
child: SizedBox(
|
|
height: 44.w,
|
|
child: Center(
|
|
child: Text(
|
|
label,
|
|
textAlign: TextAlign.center,
|
|
style: TextStyle(
|
|
color: SocialChatTheme.primaryColor,
|
|
fontSize: 14.sp,
|
|
fontWeight: FontWeight.w600,
|
|
height: 1,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildForm(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
SizedBox(height: 16.w),
|
|
_buildRoomAvatar(),
|
|
SizedBox(height: 20.w),
|
|
_buildTextInput(
|
|
controller: _roomNameController,
|
|
height: 40.w,
|
|
hintText: "Please enter a name",
|
|
counterText: '$_roomNameCurrentLength/$_roomNameMaxLength',
|
|
readOnly: !_isBasicInfoEditing,
|
|
inputFormatters: [
|
|
SCAccurateLengthLimitingTextInputFormatter(_roomNameMaxLength),
|
|
],
|
|
onChanged: (_) {
|
|
_markEdited();
|
|
},
|
|
),
|
|
SizedBox(height: 16.w),
|
|
_buildSectionHeader(
|
|
title: "Notice",
|
|
counterText:
|
|
'$_roomAnnouncementCurrentLength/$_roomAnnouncementMaxLength',
|
|
),
|
|
SizedBox(height: 12.w),
|
|
_buildTextInput(
|
|
controller: _roomAnnouncementController,
|
|
height: 135.w,
|
|
hintText: "Please enter a name",
|
|
maxLines: null,
|
|
expands: true,
|
|
readOnly: !_isBasicInfoEditing,
|
|
inputFormatters: [
|
|
SCAccurateLengthLimitingTextInputFormatter(
|
|
_roomAnnouncementMaxLength,
|
|
),
|
|
],
|
|
onChanged: (_) {
|
|
_markEdited();
|
|
},
|
|
),
|
|
SizedBox(height: 16.w),
|
|
_buildLockHeader(),
|
|
Visibility(
|
|
visible: _isRoomPrivate,
|
|
child: Column(
|
|
children: [
|
|
SizedBox(height: 8.w),
|
|
_buildTextInput(
|
|
controller: _roomLockPasswordController,
|
|
height: 40.w,
|
|
hintText: "Please enter password",
|
|
keyboardType: TextInputType.visiblePassword,
|
|
obscureText: true,
|
|
onChanged: (_) {
|
|
_markEdited();
|
|
},
|
|
),
|
|
SizedBox(height: 8.w),
|
|
_buildLockTips(),
|
|
],
|
|
),
|
|
),
|
|
if (widget.needRestCurrentRoomInfo != "true") ...[
|
|
SizedBox(height: 16.w),
|
|
_buildSettingRow(
|
|
icon: Icons.dashboard_rounded,
|
|
title: SCAppLocalizations.of(context)!.roomTheme2,
|
|
onTap: () {
|
|
VoiceRoomRoute.openRoomTheme(context);
|
|
},
|
|
),
|
|
SizedBox(height: 8.w),
|
|
_buildSettingRow(
|
|
icon: Icons.mic_none_rounded,
|
|
title: "Microphone Settings",
|
|
onTap: () {
|
|
SmartDialog.show(
|
|
tag: "showRoomMicSwitch",
|
|
alignment: Alignment.bottomCenter,
|
|
animationType: SmartAnimationType.fade,
|
|
debounce: true,
|
|
builder: (_) {
|
|
return RoomMicSwitchPage();
|
|
},
|
|
);
|
|
},
|
|
),
|
|
SizedBox(height: 8.w),
|
|
_buildSettingRow(
|
|
icon: Icons.person_off_rounded,
|
|
title: "Block List",
|
|
onTap: () {
|
|
showBottomInBottomDialog(
|
|
context,
|
|
BlockedListPage(
|
|
roomId:
|
|
Provider.of<RtcProvider>(
|
|
context,
|
|
listen: false,
|
|
).currenRoom?.roomProfile?.roomProfile?.id ??
|
|
"",
|
|
),
|
|
);
|
|
},
|
|
),
|
|
],
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildRoomAvatar() {
|
|
return GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onTap: () {
|
|
SCPickUtils.pickImage(context, (bool success, String url) {
|
|
if (success) {
|
|
setState(() {
|
|
roomCover = url;
|
|
isEdit = true;
|
|
});
|
|
}
|
|
});
|
|
},
|
|
child: ClipOval(
|
|
child: netImage(
|
|
url: roomCover,
|
|
defaultImg: kRoomCoverDefaultImg,
|
|
width: 90.w,
|
|
height: 90.w,
|
|
fit: BoxFit.cover,
|
|
shape: BoxShape.circle,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildTextInput({
|
|
required TextEditingController controller,
|
|
required double height,
|
|
required String hintText,
|
|
String? counterText,
|
|
int? maxLines = 1,
|
|
bool expands = false,
|
|
bool obscureText = false,
|
|
TextInputType? keyboardType,
|
|
List<TextInputFormatter>? inputFormatters,
|
|
ValueChanged<String>? onChanged,
|
|
bool readOnly = false,
|
|
}) {
|
|
final isMultiline = maxLines == null || expands;
|
|
return Container(
|
|
height: height,
|
|
margin: EdgeInsets.symmetric(horizontal: 10.w),
|
|
decoration: BoxDecoration(
|
|
color: _fieldColor,
|
|
borderRadius: BorderRadius.circular(8.w),
|
|
border: Border.all(color: _fieldBorderColor, width: 1),
|
|
),
|
|
child: Stack(
|
|
alignment: isMultiline ? Alignment.topLeft : Alignment.centerLeft,
|
|
children: [
|
|
Padding(
|
|
padding: EdgeInsets.only(
|
|
left: 12.w,
|
|
right: counterText == null ? 12.w : 56.w,
|
|
top: isMultiline ? 10.w : 0,
|
|
bottom: isMultiline ? 10.w : 0,
|
|
),
|
|
child: TextField(
|
|
controller: controller,
|
|
cursorColor: SocialChatTheme.primaryColor,
|
|
keyboardType: keyboardType,
|
|
obscureText: obscureText,
|
|
readOnly: readOnly,
|
|
enableInteractiveSelection: !readOnly,
|
|
showCursor: !readOnly,
|
|
inputFormatters: inputFormatters,
|
|
maxLines: maxLines,
|
|
expands: expands,
|
|
onChanged: onChanged,
|
|
textAlignVertical:
|
|
isMultiline
|
|
? TextAlignVertical.top
|
|
: TextAlignVertical.center,
|
|
decoration: InputDecoration(
|
|
hintText: hintText,
|
|
hintStyle: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 14.sp,
|
|
height: 16 / 14,
|
|
),
|
|
filled: true,
|
|
fillColor: Colors.transparent,
|
|
border: InputBorder.none,
|
|
enabledBorder: InputBorder.none,
|
|
focusedBorder: InputBorder.none,
|
|
disabledBorder: InputBorder.none,
|
|
errorBorder: InputBorder.none,
|
|
focusedErrorBorder: InputBorder.none,
|
|
counterText: '',
|
|
isDense: true,
|
|
isCollapsed: !isMultiline,
|
|
contentPadding: EdgeInsets.zero,
|
|
),
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
backgroundColor: Colors.transparent,
|
|
fontSize: 14.sp,
|
|
fontWeight: FontWeight.w400,
|
|
height: 16 / 14,
|
|
),
|
|
),
|
|
),
|
|
if (counterText != null)
|
|
PositionedDirectional(
|
|
end: 12.w,
|
|
top: 0,
|
|
bottom: 0,
|
|
child: Center(
|
|
child: Text(
|
|
counterText,
|
|
textAlign: TextAlign.right,
|
|
style: TextStyle(
|
|
color: Colors.white.withValues(alpha: 0.6),
|
|
fontSize: 14.sp,
|
|
fontWeight: FontWeight.w400,
|
|
height: 16 / 14,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
void _markEdited() {
|
|
if (isEdit) {
|
|
return;
|
|
}
|
|
setState(() {
|
|
isEdit = true;
|
|
});
|
|
}
|
|
|
|
Widget _buildSectionHeader({required String title, String? counterText}) {
|
|
return Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 10.w),
|
|
child: SizedBox(
|
|
height: 16.w,
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 16.sp,
|
|
fontWeight: FontWeight.w500,
|
|
height: 1,
|
|
),
|
|
),
|
|
const Spacer(),
|
|
if (counterText != null)
|
|
Text(
|
|
counterText,
|
|
style: TextStyle(
|
|
color: Colors.white.withValues(alpha: 0.6),
|
|
fontSize: 12.sp,
|
|
fontWeight: FontWeight.w400,
|
|
height: 1,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildLockHeader() {
|
|
return Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 10.w),
|
|
child: SizedBox(
|
|
height: 20.w,
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
Text(
|
|
"Room lock",
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 16.sp,
|
|
fontWeight: FontWeight.w500,
|
|
height: 1,
|
|
),
|
|
),
|
|
const Spacer(),
|
|
_buildLockOption(
|
|
selected: !_isRoomPrivate,
|
|
label: "Public",
|
|
onTap: () {
|
|
setState(() {
|
|
if (_isRoomPrivate) {
|
|
isEdit = true;
|
|
}
|
|
_isRoomPrivate = false;
|
|
});
|
|
},
|
|
),
|
|
SizedBox(width: 8.w),
|
|
_buildLockOption(
|
|
selected: _isRoomPrivate,
|
|
label: "Private",
|
|
onTap: () {
|
|
setState(() {
|
|
if (!_isRoomPrivate) {
|
|
isEdit = true;
|
|
}
|
|
_isRoomPrivate = true;
|
|
});
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildLockOption({
|
|
required bool selected,
|
|
required String label,
|
|
required VoidCallback onTap,
|
|
}) {
|
|
return GestureDetector(
|
|
behavior: HitTestBehavior.opaque,
|
|
onTap: onTap,
|
|
child: SizedBox(
|
|
height: 20.w,
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
SizedBox(
|
|
width: 20.w,
|
|
height: 20.w,
|
|
child: Center(
|
|
child: Container(
|
|
width: 14.w,
|
|
height: 14.w,
|
|
decoration: BoxDecoration(
|
|
color:
|
|
selected
|
|
? SocialChatTheme.primaryColor
|
|
: Colors.transparent,
|
|
borderRadius: BorderRadius.circular(2.w),
|
|
border: Border.all(
|
|
color: SocialChatTheme.primaryColor,
|
|
width: 1.w,
|
|
),
|
|
),
|
|
child:
|
|
selected
|
|
? Icon(Icons.check, color: Colors.white, size: 11.w)
|
|
: null,
|
|
),
|
|
),
|
|
),
|
|
SizedBox(width: 4.w),
|
|
Text(
|
|
label,
|
|
style: TextStyle(
|
|
color:
|
|
selected
|
|
? Colors.white
|
|
: Colors.white.withValues(alpha: 0.6),
|
|
fontSize: 12.sp,
|
|
fontWeight: FontWeight.w400,
|
|
height: 1,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildLockTips() {
|
|
return Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 10.w),
|
|
child: SizedBox(
|
|
width: double.infinity,
|
|
child: Text(
|
|
"After locking the door, enter the correct password to enter the room.",
|
|
maxLines: 2,
|
|
style: TextStyle(
|
|
color: _dangerColor,
|
|
fontSize: 14.sp,
|
|
fontWeight: FontWeight.w400,
|
|
height: 16 / 14,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildSettingRow({
|
|
required IconData icon,
|
|
required String title,
|
|
required VoidCallback onTap,
|
|
}) {
|
|
return Padding(
|
|
padding: EdgeInsets.symmetric(horizontal: 10.w),
|
|
child: SCDebounceWidget(
|
|
onTap: onTap,
|
|
child: Container(
|
|
height: 40.w,
|
|
decoration: BoxDecoration(
|
|
color: _fieldColor,
|
|
borderRadius: BorderRadius.circular(8.w),
|
|
border: Border.all(color: _fieldBorderColor, width: 1),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
SizedBox(width: 8.w),
|
|
Icon(icon, color: Colors.white, size: 24.w),
|
|
SizedBox(width: 4.w),
|
|
Expanded(
|
|
child: Text(
|
|
title,
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 14.sp,
|
|
fontWeight: FontWeight.w400,
|
|
height: 16 / 14,
|
|
),
|
|
),
|
|
),
|
|
Icon(Icons.keyboard_arrow_right, color: Colors.white, size: 24.w),
|
|
SizedBox(width: 8.w),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
void _handleBack() {
|
|
if (widget.needRestCurrentRoomInfo == "true" &&
|
|
widget.setupPreviewData == null) {
|
|
Provider.of<RtcProvider>(context, listen: false).currenRoom = null;
|
|
}
|
|
Navigator.pop(context);
|
|
}
|
|
|
|
void _handleSystemBack() {
|
|
if (!isEdit) {
|
|
SCNavigatorUtils.goBack(context);
|
|
return;
|
|
}
|
|
SmartDialog.show(
|
|
tag: "showConfirmDialog",
|
|
alignment: Alignment.center,
|
|
debounce: true,
|
|
animationType: SmartAnimationType.fade,
|
|
builder: (_) {
|
|
return MsgDialog(
|
|
title: SCAppLocalizations.of(context)!.tips,
|
|
msg: SCAppLocalizations.of(context)!.theModificationsMade,
|
|
onEnsure: () {
|
|
SCNavigatorUtils.goBack(context);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
int _getActualCharacterCount(String text) {
|
|
return text.characters.length;
|
|
}
|
|
|
|
String _preferNonEmpty(String? primary, String fallback) {
|
|
if ((primary ?? "").trim().isNotEmpty) {
|
|
return primary!;
|
|
}
|
|
return fallback;
|
|
}
|
|
|
|
void submit(BuildContext context) async {
|
|
final roomManager = Provider.of<SocialChatRoomManager>(
|
|
context,
|
|
listen: false,
|
|
);
|
|
final currentRtcProvider = Provider.of<RtcProvider>(context, listen: false);
|
|
final currentRtmProvider = Provider.of<RtmProvider>(context, listen: false);
|
|
final setupPreviewData = widget.setupPreviewData;
|
|
final currentRoomProfile =
|
|
rtcProvider?.currenRoom?.roomProfile?.roomProfile;
|
|
final currentRoom = rtcProvider?.currenRoom?.roomProfile;
|
|
final submittedRoomName = _roomNameController.text.trim();
|
|
final submittedRoomDesc = _roomAnnouncementController.text.trim();
|
|
final submittedRoomCover = roomCover.trim();
|
|
final submittedRoomPassword = _roomLockPasswordController.text.trim();
|
|
final roomId = setupPreviewData?.roomId ?? currentRoomProfile?.id ?? "";
|
|
final roomAccount =
|
|
setupPreviewData?.roomAccount ?? currentRoomProfile?.roomAccount ?? "";
|
|
final roomUserId = setupPreviewData?.userId ?? currentRoomProfile?.userId;
|
|
final roomSetting =
|
|
setupPreviewData?.roomSetting ?? currentRoom?.roomSetting;
|
|
final ownerProfile =
|
|
setupPreviewData?.ownerProfile ?? currentRoom?.userProfile;
|
|
final roomAdminCount =
|
|
setupPreviewData?.roomAdminCount ??
|
|
currentRoom?.roomCounter?.adminCount;
|
|
final roomMemberCount =
|
|
setupPreviewData?.roomMemberCount ??
|
|
currentRoom?.roomCounter?.memberCount;
|
|
final entrantsRole =
|
|
setupPreviewData?.entrantsRole ??
|
|
rtcProvider?.currenRoom?.entrants?.roles;
|
|
if (roomId.trim().isEmpty || roomAccount.trim().isEmpty) {
|
|
SCTts.show("Room data is not ready");
|
|
return;
|
|
}
|
|
if (submittedRoomName.isEmpty) {
|
|
SCTts.show("Room name not empty!");
|
|
return;
|
|
}
|
|
if (submittedRoomDesc.isEmpty) {
|
|
SCTts.show("Room announcement not empty!");
|
|
return;
|
|
}
|
|
if (_isRoomPrivate &&
|
|
(!_initialRoomLocked || submittedRoomPassword.isNotEmpty) &&
|
|
submittedRoomPassword.isEmpty) {
|
|
SCTts.show("Please enter password");
|
|
return;
|
|
}
|
|
SCLoadingManager.show(context: context);
|
|
var roomInfo = await SCAccountRepository().editRoomInfo(
|
|
roomId,
|
|
submittedRoomCover,
|
|
submittedRoomName,
|
|
submittedRoomDesc,
|
|
SCRoomInfoEventType.AVAILABLE.name,
|
|
);
|
|
await _submitRoomLockSetting(roomId, submittedRoomPassword);
|
|
if (!context.mounted) {
|
|
SCLoadingManager.hide();
|
|
return;
|
|
}
|
|
final mergedRoomInfo = roomInfo.copyWith(
|
|
id: _preferNonEmpty(roomInfo.id, roomId),
|
|
roomAccount: _preferNonEmpty(roomInfo.roomAccount, roomAccount),
|
|
userId: roomInfo.userId ?? roomUserId,
|
|
roomCover: _preferNonEmpty(roomInfo.roomCover, submittedRoomCover),
|
|
roomName: _preferNonEmpty(roomInfo.roomName, submittedRoomName),
|
|
roomDesc: _preferNonEmpty(roomInfo.roomDesc, submittedRoomDesc),
|
|
);
|
|
currentRtcProvider.updateCurrentRoomBasicInfo(
|
|
roomCover: mergedRoomInfo.roomCover,
|
|
roomName: mergedRoomInfo.roomName,
|
|
roomDesc: mergedRoomInfo.roomDesc,
|
|
);
|
|
roomManager.updateMyRoomInfo(mergedRoomInfo);
|
|
if (widget.needRestCurrentRoomInfo != "true") {
|
|
currentRtmProvider.dispatchMessage(
|
|
Msg(
|
|
groupId:
|
|
rtcProvider?.currenRoom?.roomProfile?.roomProfile?.roomAccount ??
|
|
"",
|
|
msg:
|
|
mergedRoomInfo.id ??
|
|
rtcProvider?.currenRoom?.roomProfile?.roomProfile?.id ??
|
|
"",
|
|
type: SCRoomMsgType.roomSettingUpdate,
|
|
),
|
|
addLocal: false,
|
|
);
|
|
}
|
|
if (widget.needRestCurrentRoomInfo == "true") {
|
|
///需要创建群组
|
|
var c = await currentRtmProvider.createRoomGroup(
|
|
roomAccount,
|
|
mergedRoomInfo.roomName ?? submittedRoomName,
|
|
);
|
|
if (!context.mounted) {
|
|
SCLoadingManager.hide();
|
|
return;
|
|
}
|
|
if (_roomGroupReadyCodes.contains(c.code)) {
|
|
SCLoadingManager.hide();
|
|
SCTts.show(SCAppLocalizations.of(context)!.createRoomSuccsess);
|
|
SCNavigatorUtils.goBack(context);
|
|
currentRtcProvider.joinVoiceRoomSession(
|
|
context,
|
|
mergedRoomInfo.id ?? roomId,
|
|
clearRoomData: setupPreviewData == null,
|
|
previewData: RoomEntryPreviewData(
|
|
roomId: mergedRoomInfo.id ?? roomId,
|
|
roomAccount: mergedRoomInfo.roomAccount ?? roomAccount,
|
|
userId: mergedRoomInfo.userId ?? roomUserId,
|
|
roomCover: mergedRoomInfo.roomCover,
|
|
roomName: mergedRoomInfo.roomName ?? submittedRoomName,
|
|
roomDesc: mergedRoomInfo.roomDesc ?? submittedRoomDesc,
|
|
roomSetting: roomSetting,
|
|
existsPassword: _isRoomPrivate,
|
|
ownerProfile: ownerProfile,
|
|
roomAdminCount: roomAdminCount,
|
|
roomMemberCount: roomMemberCount,
|
|
entrantsRole: entrantsRole,
|
|
),
|
|
);
|
|
} else {
|
|
SCLoadingManager.hide();
|
|
SCTts.show("${c.code}");
|
|
}
|
|
} else {
|
|
currentRtcProvider.loadRoomInfo(
|
|
mergedRoomInfo.id ??
|
|
rtcProvider?.currenRoom?.roomProfile?.roomProfile?.id ??
|
|
"",
|
|
);
|
|
SCLoadingManager.hide();
|
|
SCNavigatorUtils.goBack(context);
|
|
}
|
|
}
|
|
|
|
Future<void> _submitRoomLockSetting(String roomId, String password) async {
|
|
final normalizedRoomId = roomId.trim();
|
|
if (normalizedRoomId.isEmpty) {
|
|
return;
|
|
}
|
|
if (_isRoomPrivate) {
|
|
if (!_initialRoomLocked || password.isNotEmpty) {
|
|
await SCChatRoomRepository().roomLocked(normalizedRoomId, password);
|
|
}
|
|
} else if (_initialRoomLocked) {
|
|
await SCChatRoomRepository().roomUnlocked(normalizedRoomId);
|
|
}
|
|
_initialRoomLocked = _isRoomPrivate;
|
|
_roomLockPasswordController.clear();
|
|
}
|
|
}
|