6 changed files with 516 additions and 2 deletions
Unified View
Diff Options
-
151lib/controller/message/chat_settings_controller.dart
-
1lib/generated/assets.dart
-
34lib/im/im_manager.dart
-
6lib/pages/message/chat_page.dart
-
323lib/pages/message/chat_settings_page.dart
-
3lib/widget/emoji_panel.dart
@ -0,0 +1,151 @@ |
|||||
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
import 'package:im_flutter_sdk/im_flutter_sdk.dart'; |
||||
|
|
||||
|
import '../../im/im_manager.dart'; |
||||
|
import '../../pages/home/report_page.dart'; |
||||
|
|
||||
|
class ChatSettingsController extends GetxController { |
||||
|
final String userId; |
||||
|
|
||||
|
// 用户信息 |
||||
|
final Rx<EMUserInfo?> userInfo = Rx<EMUserInfo?>(null); |
||||
|
|
||||
|
// 是否拉黑 |
||||
|
final RxBool isBlacklisted = RxBool(false); |
||||
|
|
||||
|
// 是否关注 |
||||
|
final RxBool isFollowing = RxBool(false); |
||||
|
|
||||
|
// 备注名 |
||||
|
final RxString remark = RxString(''); |
||||
|
|
||||
|
ChatSettingsController({required this.userId}); |
||||
|
|
||||
|
@override |
||||
|
void onInit() { |
||||
|
super.onInit(); |
||||
|
// 初始化时获取用户信息 |
||||
|
fetchUserInfo(); |
||||
|
// 检查黑名单状态 |
||||
|
checkBlacklistStatus(); |
||||
|
// 检查关注状态 |
||||
|
checkFollowStatus(); |
||||
|
} |
||||
|
|
||||
|
/// 获取用户信息 |
||||
|
Future<void> fetchUserInfo() async { |
||||
|
try { |
||||
|
final EMUserInfo? info = await IMManager.instance.getUserInfo(userId); |
||||
|
if (info != null) { |
||||
|
userInfo.value = info; |
||||
|
if (Get.isLogEnable) { |
||||
|
Get.log('获取用户信息成功: ${info.nickName}'); |
||||
|
} |
||||
|
} else { |
||||
|
if (Get.isLogEnable) { |
||||
|
Get.log('未找到用户信息: $userId'); |
||||
|
} |
||||
|
} |
||||
|
} catch (e) { |
||||
|
if (Get.isLogEnable) { |
||||
|
Get.log('获取用户信息失败: $e'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// 检查黑名单状态 |
||||
|
Future<void> checkBlacklistStatus() async { |
||||
|
try { |
||||
|
// 从服务器获取黑名单列表 |
||||
|
final blacklist = await IMManager.instance.getBlacklist(); |
||||
|
isBlacklisted.value = blacklist.contains(userId); |
||||
|
} catch (e) { |
||||
|
if (Get.isLogEnable) { |
||||
|
Get.log('检查黑名单状态失败: $e'); |
||||
|
} |
||||
|
isBlacklisted.value = false; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// 检查关注状态 |
||||
|
Future<void> checkFollowStatus() async { |
||||
|
try { |
||||
|
// TODO: 调用实际的API检查关注状态 |
||||
|
// 这里暂时模拟 |
||||
|
isFollowing.value = false; |
||||
|
} catch (e) { |
||||
|
if (Get.isLogEnable) { |
||||
|
Get.log('检查关注状态失败: $e'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// 切换黑名单状态 |
||||
|
Future<void> toggleBlacklist(bool value) async { |
||||
|
try { |
||||
|
if (value) { |
||||
|
// 加入黑名单 |
||||
|
await IMManager.instance.addToBlacklist(userId); |
||||
|
isBlacklisted.value = true; |
||||
|
SmartDialog.showToast('已加入黑名单'); |
||||
|
} else { |
||||
|
// 移出黑名单 |
||||
|
await IMManager.instance.removeFromBlacklist(userId); |
||||
|
isBlacklisted.value = false; |
||||
|
SmartDialog.showToast('已移出黑名单'); |
||||
|
} |
||||
|
update(); |
||||
|
} catch (e) { |
||||
|
if (Get.isLogEnable) { |
||||
|
Get.log('操作黑名单失败: $e'); |
||||
|
} |
||||
|
SmartDialog.showToast('操作失败,请重试'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// 切换关注状态 |
||||
|
Future<void> toggleFollow() async { |
||||
|
try { |
||||
|
if (isFollowing.value) { |
||||
|
// 取消关注 |
||||
|
// TODO: 调用实际的取消关注API |
||||
|
isFollowing.value = false; |
||||
|
SmartDialog.showToast('已取消关注'); |
||||
|
} else { |
||||
|
// 关注 |
||||
|
// TODO: 调用实际的关注API |
||||
|
isFollowing.value = true; |
||||
|
SmartDialog.showToast('已关注'); |
||||
|
} |
||||
|
update(); |
||||
|
} catch (e) { |
||||
|
if (Get.isLogEnable) { |
||||
|
Get.log('操作关注失败: $e'); |
||||
|
} |
||||
|
SmartDialog.showToast('操作失败,请重试'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// 设置备注名 |
||||
|
Future<void> setRemark(String newRemark) async { |
||||
|
try { |
||||
|
// TODO: 调用实际的设置备注名API |
||||
|
remark.value = newRemark; |
||||
|
SmartDialog.showToast('备注名设置成功'); |
||||
|
update(); |
||||
|
} catch (e) { |
||||
|
if (Get.isLogEnable) { |
||||
|
Get.log('设置备注名失败: $e'); |
||||
|
} |
||||
|
SmartDialog.showToast('设置失败,请重试'); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// 举报用户 |
||||
|
void reportUser() { |
||||
|
// 跳转到举报页面 |
||||
|
Get.to(() => ReportPage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,323 @@ |
|||||
|
import 'package:dating_touchme_app/extension/ex_widget.dart'; |
||||
|
import 'package:flutter/cupertino.dart'; |
||||
|
import 'package:flutter/material.dart'; |
||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
||||
|
import 'package:get/get.dart'; |
||||
|
|
||||
|
import '../../controller/message/chat_settings_controller.dart'; |
||||
|
import '../../generated/assets.dart'; |
||||
|
|
||||
|
class ChatSettingsPage extends StatelessWidget { |
||||
|
final String userId; |
||||
|
|
||||
|
const ChatSettingsPage({required this.userId, super.key}); |
||||
|
|
||||
|
@override |
||||
|
Widget build(BuildContext context) { |
||||
|
// 初始化控制器 |
||||
|
Get.put(ChatSettingsController(userId: userId)); |
||||
|
|
||||
|
return Scaffold( |
||||
|
backgroundColor: Colors.white, |
||||
|
appBar: AppBar( |
||||
|
title: Text( |
||||
|
'聊天设置', |
||||
|
style: TextStyle( |
||||
|
fontSize: 18.sp, |
||||
|
fontWeight: FontWeight.w500, |
||||
|
color: Colors.black, |
||||
|
), |
||||
|
), |
||||
|
centerTitle: true, |
||||
|
backgroundColor: Colors.white, |
||||
|
elevation: 0, |
||||
|
leading: IconButton( |
||||
|
icon: Icon(Icons.arrow_back_ios, color: Colors.black, size: 20.w), |
||||
|
onPressed: () => Get.back(), |
||||
|
), |
||||
|
), |
||||
|
body: GetBuilder<ChatSettingsController>( |
||||
|
builder: (controller) { |
||||
|
return Column( |
||||
|
children: [ |
||||
|
// 用户信息区域 |
||||
|
_buildUserInfoSection(controller), |
||||
|
|
||||
|
// 分隔线 |
||||
|
Container( |
||||
|
height: 8.h, |
||||
|
color: Color(0xFFF5F5F5), |
||||
|
), |
||||
|
|
||||
|
// 设置选项 |
||||
|
_buildSettingsList(controller), |
||||
|
|
||||
|
// 间隔 |
||||
|
SizedBox(height: 17.h), |
||||
|
|
||||
|
// 关注按钮 |
||||
|
_buildFollowButton(controller), |
||||
|
|
||||
|
SizedBox(height: MediaQuery.of(context).padding.bottom + 20.h), |
||||
|
], |
||||
|
); |
||||
|
}, |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// 用户信息区域 |
||||
|
Widget _buildUserInfoSection(ChatSettingsController controller) { |
||||
|
return Container( |
||||
|
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), |
||||
|
child: Row( |
||||
|
children: [ |
||||
|
// 头像 |
||||
|
Obx(() { |
||||
|
final userInfo = controller.userInfo.value; |
||||
|
return ClipOval( |
||||
|
child: userInfo?.avatarUrl != null && userInfo!.avatarUrl!.isNotEmpty |
||||
|
? Image.network( |
||||
|
userInfo.avatarUrl!, |
||||
|
width: 50.w, |
||||
|
height: 50.w, |
||||
|
fit: BoxFit.cover, |
||||
|
errorBuilder: (context, error, stackTrace) { |
||||
|
return Image.asset( |
||||
|
Assets.imagesAvatarsExample, |
||||
|
width: 50.w, |
||||
|
height: 50.w, |
||||
|
fit: BoxFit.cover, |
||||
|
); |
||||
|
}, |
||||
|
) |
||||
|
: Image.asset( |
||||
|
Assets.imagesAvatarsExample, |
||||
|
width: 50.w, |
||||
|
height: 50.w, |
||||
|
fit: BoxFit.cover, |
||||
|
), |
||||
|
); |
||||
|
}), |
||||
|
|
||||
|
SizedBox(width: 12.w), |
||||
|
|
||||
|
// 昵称 |
||||
|
Expanded( |
||||
|
child: Obx(() { |
||||
|
final userInfo = controller.userInfo.value; |
||||
|
return Text( |
||||
|
userInfo?.nickName ?? '加载中...', |
||||
|
style: TextStyle( |
||||
|
fontSize: 16.sp, |
||||
|
fontWeight: FontWeight.w500, |
||||
|
color: Colors.black, |
||||
|
), |
||||
|
); |
||||
|
}), |
||||
|
), |
||||
|
|
||||
|
// 右箭头 |
||||
|
Icon( |
||||
|
Icons.arrow_forward_ios, |
||||
|
size: 16.w, |
||||
|
color: Color(0xFF999999), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
).onTap(() { |
||||
|
// 点击跳转到用户详情页 |
||||
|
// TODO: 导航到用户详情页 |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// 设置选项列表 |
||||
|
Widget _buildSettingsList(ChatSettingsController controller) { |
||||
|
return Column( |
||||
|
children: [ |
||||
|
// 设置备注名 |
||||
|
_buildSettingItem( |
||||
|
title: '设置备注名', |
||||
|
showArrow: true, |
||||
|
onTap: () { |
||||
|
// TODO: 打开设置备注名弹窗 |
||||
|
_showSetRemarkDialog(controller); |
||||
|
}, |
||||
|
), |
||||
|
|
||||
|
_buildDivider(), |
||||
|
|
||||
|
// 加入黑名单 |
||||
|
_buildSwitchItem( |
||||
|
title: '加入黑名单', |
||||
|
value: controller.isBlacklisted.value, |
||||
|
onChanged: (value) { |
||||
|
controller.toggleBlacklist(value); |
||||
|
}, |
||||
|
), |
||||
|
|
||||
|
_buildDivider(), |
||||
|
|
||||
|
// 举报 |
||||
|
_buildSettingItem( |
||||
|
title: '举报', |
||||
|
showArrow: true, |
||||
|
onTap: () { |
||||
|
// TODO: 跳转到举报页面 |
||||
|
controller.reportUser(); |
||||
|
}, |
||||
|
), |
||||
|
|
||||
|
_buildDivider(), |
||||
|
|
||||
|
], |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// 设置项(带箭头) |
||||
|
Widget _buildSettingItem({ |
||||
|
required String title, |
||||
|
bool showArrow = false, |
||||
|
VoidCallback? onTap, |
||||
|
}) { |
||||
|
return Container( |
||||
|
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), |
||||
|
child: Row( |
||||
|
children: [ |
||||
|
Expanded( |
||||
|
child: Text( |
||||
|
title, |
||||
|
style: TextStyle( |
||||
|
fontSize: 16.sp, |
||||
|
color: Colors.black, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
if (showArrow) |
||||
|
Icon( |
||||
|
Icons.arrow_forward_ios, |
||||
|
size: 16.w, |
||||
|
color: Color(0xFF999999), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
).onTap(onTap); |
||||
|
} |
||||
|
|
||||
|
// 开关项 |
||||
|
Widget _buildSwitchItem({ |
||||
|
required String title, |
||||
|
required bool value, |
||||
|
required ValueChanged<bool> onChanged, |
||||
|
}) { |
||||
|
return Container( |
||||
|
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 12.h), |
||||
|
child: Row( |
||||
|
children: [ |
||||
|
Expanded( |
||||
|
child: Text( |
||||
|
title, |
||||
|
style: TextStyle( |
||||
|
fontSize: 16.sp, |
||||
|
color: Colors.black, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
Obx(() { |
||||
|
final controller = Get.find<ChatSettingsController>(); |
||||
|
return CupertinoSwitch( |
||||
|
value: controller.isBlacklisted.value, |
||||
|
onChanged: onChanged, |
||||
|
activeColor: Color.fromRGBO(117, 98, 249, 1), |
||||
|
); |
||||
|
}), |
||||
|
], |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// 分隔线 |
||||
|
Widget _buildDivider() { |
||||
|
return Container( |
||||
|
margin: EdgeInsets.only(left: 16.w), |
||||
|
height: 1.h, |
||||
|
color: Color(0xFFF5F5F5), |
||||
|
); |
||||
|
} |
||||
|
|
||||
|
// 关注按钮 |
||||
|
Widget _buildFollowButton(ChatSettingsController controller) { |
||||
|
return Obx(() { |
||||
|
final isFollowing = controller.isFollowing.value; |
||||
|
return Container( |
||||
|
margin: EdgeInsets.symmetric(horizontal: 25.w), |
||||
|
width: double.infinity, |
||||
|
height: 50.h, |
||||
|
child: ElevatedButton( |
||||
|
onPressed: () { |
||||
|
controller.toggleFollow(); |
||||
|
}, |
||||
|
style: ElevatedButton.styleFrom( |
||||
|
backgroundColor: Color.fromRGBO(117, 98, 249, 1), |
||||
|
foregroundColor: Colors.white, |
||||
|
shape: RoundedRectangleBorder( |
||||
|
borderRadius: BorderRadius.circular(24.r), |
||||
|
), |
||||
|
elevation: 0, |
||||
|
), |
||||
|
child: Text( |
||||
|
isFollowing ? '已关注' : '关注', |
||||
|
style: TextStyle( |
||||
|
fontSize: 18.sp, |
||||
|
fontWeight: FontWeight.w500, |
||||
|
), |
||||
|
), |
||||
|
), |
||||
|
); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
// 设置备注名对话框 |
||||
|
void _showSetRemarkDialog(ChatSettingsController controller) { |
||||
|
final TextEditingController textController = TextEditingController(); |
||||
|
|
||||
|
Get.dialog( |
||||
|
AlertDialog( |
||||
|
title: Text('设置备注名'), |
||||
|
content: TextField( |
||||
|
controller: textController, |
||||
|
decoration: InputDecoration( |
||||
|
hintText: '请输入备注名', |
||||
|
border: OutlineInputBorder( |
||||
|
borderRadius: BorderRadius.circular(8.r), |
||||
|
), |
||||
|
), |
||||
|
autofocus: true, |
||||
|
), |
||||
|
actions: [ |
||||
|
TextButton( |
||||
|
onPressed: () => Get.back(), |
||||
|
child: Text( |
||||
|
'取消', |
||||
|
style: TextStyle(color: Color(0xFF999999)), |
||||
|
), |
||||
|
), |
||||
|
TextButton( |
||||
|
onPressed: () { |
||||
|
final remark = textController.text.trim(); |
||||
|
if (remark.isNotEmpty) { |
||||
|
controller.setRemark(remark); |
||||
|
Get.back(); |
||||
|
} |
||||
|
}, |
||||
|
child: Text( |
||||
|
'确定', |
||||
|
style: TextStyle(color: Color(0xFFA05CFF)), |
||||
|
), |
||||
|
), |
||||
|
], |
||||
|
), |
||||
|
); |
||||
|
} |
||||
|
} |
||||
|
|
||||
Write
Preview
Loading…
Cancel
Save