Browse Source

优化功能,优化隐私弹窗

dev-2.0
王子贤 1 month ago
parent
commit
aa331434a3
4 changed files with 472 additions and 408 deletions
  1. 2
      lib/controller/discover/room_controller.dart
  2. 4
      lib/controller/mine/deactivate_controller.dart
  3. 385
      lib/main.dart
  4. 489
      lib/pages/discover/live_room_page.dart

2
lib/controller/discover/room_controller.dart

@ -103,6 +103,7 @@ class RoomController extends GetxController with WidgetsBindingObserver {
if (value?.femaleInfo != null) {
print("获取数据");
getUserData(value?.femaleInfo?.miId ?? "", 1);
} else {
print("清除数据");
femaleData.value = null;
@ -130,6 +131,7 @@ class RoomController extends GetxController with WidgetsBindingObserver {
} else {
maleData.value = response.data.data!;
}
update();
} else {
//
final errorMsg = response.data.message ?? '获取数据失败';

4
lib/controller/mine/deactivate_controller.dart

@ -45,7 +45,9 @@ class DeactivateController extends GetxController {
conversationController.clearConversations();
}
//
storage.erase();
// storage.erase();
storage.remove('userId');
storage.remove('token');
//
GlobalData().logout();
}

385
lib/main.dart

@ -25,195 +25,136 @@ import 'package:get_storage/get_storage.dart';
import 'extension/my_cupertino_localizations.dart';
void main() async {
//
FlutterError.onError = (FlutterErrorDetails details) {
FlutterError.presentError(details);
if (kReleaseMode) {
//
print('Flutter Error: ${details.exception}');
}
};
//
PlatformDispatcher.instance.onError = (error, stack) {
print('Platform Error: $error');
print('Stack: $stack');
return true;
};
try {
WidgetsFlutterBinding.ensureInitialized();
// GetStorage
await GetStorage.init();
// - release模式
EnvConfig.setEnvironment(Environment.dev);
// RTC
try {
await RTCManager.instance.initialize(appId: '4c2ea9dcb4c5440593a418df0fdd512d');
} catch (e) {
print('RTC初始化失败: $e');
}
// IM初始化改为异步
// IM初始化将在 MyApp initState
//
final networkService = NetworkService();
Get.put(networkService);
Get.put(networkService.userApi);
Get.put(networkService.homeApi);
// Overlay
Get.put(OverlayController());
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
systemNavigationBarColor: Colors.white,
systemNavigationBarIconBrightness: Brightness.dark,
),
);
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
if (Platform.isIOS) {
SystemChrome.setEnabledSystemUIMode(
SystemUiMode.manual,
overlays: [SystemUiOverlay.top],
);
}
} catch (e, stackTrace) {
print('应用初始化失败: $e');
print('堆栈跟踪: $stackTrace');
// 使
}
// Overlay
Get.put(OverlayController());
// GetStorage
await GetStorage.init();
runApp(
GetMaterialApp(
locale: Locale('zh', 'CN'), // 使GetX的locale
supportedLocales: const [Locale('zh', 'CN')],
///
localizationsDelegates: const [
ChineseArabicMonthDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate, // iOS
],
theme: ThemeData(
scaffoldBackgroundColor: Colors.white,
//
appBarTheme: AppBarTheme(
systemOverlayStyle: SystemUiOverlayStyle(
systemNavigationBarColor: Colors.white,
systemNavigationBarIconBrightness: Brightness.light,
ScreenUtilInit(
designSize: const Size(375, 812),
minTextAdapt: true,
builder: (_, child) {
return GetMaterialApp(
locale: Locale('zh', 'CN'), // 使GetX的locale
supportedLocales: const [Locale('zh', 'CN')],
///
localizationsDelegates: const [
ChineseArabicMonthDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
GlobalCupertinoLocalizations.delegate, // iOS
],
theme: ThemeData(
scaffoldBackgroundColor: Colors.white,
//
appBarTheme: AppBarTheme(
systemOverlayStyle: SystemUiOverlayStyle(
systemNavigationBarColor: Colors.white,
systemNavigationBarIconBrightness: Brightness.light,
),
),
),
),
),
builder: (context, child) {
final smartDialogBuilder = FlutterSmartDialog.init();
return smartDialogBuilder(
context,
Stack(
children: [
child ?? const SizedBox(),
// overlay
Obx(() {
try {
if (Get.isRegistered<OverlayController>()) {
final overlayController = Get.find<OverlayController>();
//
if (overlayController.showVideoCallOverlay.value) {
return VideoCallOverlayWidget(
targetUserId: overlayController.videoCallTargetUserId ?? '',
targetUserName: overlayController.videoCallTargetUserName,
targetAvatarUrl: overlayController.videoCallTargetAvatarUrl,
message: overlayController.videoCallTargetMessage,
onClose: () {
overlayController.hideVideoCall();
},
);
}
//
if (overlayController.showOverlay.value) {
return DraggableOverlayWidget(
size: 60,
backgroundColor: const Color.fromRGBO(0, 0, 0, 0.6),
onClose: () {
overlayController.hide();
},
);
builder: (context, child) {
final smartDialogBuilder = FlutterSmartDialog.init();
return smartDialogBuilder(
context,
Stack(
children: [
child ?? const SizedBox(),
// overlay
Obx(() {
try {
if (Get.isRegistered<OverlayController>()) {
final overlayController = Get.find<OverlayController>();
//
if (overlayController.showVideoCallOverlay.value) {
return VideoCallOverlayWidget(
targetUserId: overlayController.videoCallTargetUserId ?? '',
targetUserName: overlayController.videoCallTargetUserName,
targetAvatarUrl: overlayController.videoCallTargetAvatarUrl,
message: overlayController.videoCallTargetMessage,
onClose: () {
overlayController.hideVideoCall();
},
);
}
//
if (overlayController.showOverlay.value) {
return DraggableOverlayWidget(
size: 60,
backgroundColor: const Color.fromRGBO(0, 0, 0, 0.6),
onClose: () {
overlayController.hide();
},
);
}
}
} catch (e) {
Get.log('获取OverlayController失败: $e');
}
}
} catch (e) {
Get.log('获取OverlayController失败: $e');
}
return const SizedBox.shrink();
}),
],
),
return const SizedBox.shrink();
}),
],
),
);
},
home: Agreement(),
);
},
home: MyApp(),
),
)
);
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
class Agreement extends StatefulWidget {
const Agreement({super.key});
@override
State<MyApp> createState() => _MyAppState();
State<Agreement> createState() => _AgreementState();
}
class _MyAppState extends State<MyApp> {
Fluwx fluwx = Fluwx();
bool _screenUtilInitialized = false;
bool _showAgreementDialog = false;
class _AgreementState extends State<Agreement> {
bool show = false;
final storage = GetStorage();
@override
void initState() {
super.initState();
_initFluwx();
// IM
_initIMAsync();
//
_checkAgreement();
}
///
void _checkAgreement() {
final storage = GetStorage();
void _checkAgreement() async {
//
final hasAgreed = storage.read<bool>('hasAgreedUserAgreement') ?? false;
print(hasAgreed);
print("hasAgreed");
if (!hasAgreed) {
// UI已初始化
WidgetsBinding.instance.addPostFrameCallback((_) {
if (mounted) {
setState(() {
_showAgreementDialog = true;
});
}
show = true;
setState(() {
});
} else {
//
_showAgreementDialog = false;
await initApp();
Get.offAll(() => StartPage(), );
}
}
///
void _onAgreeAgreement() {
final storage = GetStorage();
void _onAgreeAgreement() async {
//
storage.write('hasAgreedUserAgreement', true);
if (mounted) {
setState(() {
_showAgreementDialog = false;
});
}
await storage.write('hasAgreedUserAgreement', true);
final hasAgreed = storage.read<bool>('hasAgreedUserAgreement') ?? false;
print(hasAgreed);
print("hasAgreed");
await initApp();
Get.offAll(() => StartPage(), );
}
/// - 退
@ -227,6 +168,125 @@ class _MyAppState extends State<MyApp> {
}
}
initApp() async {
//
FlutterError.onError = (FlutterErrorDetails details) {
FlutterError.presentError(details);
if (kReleaseMode) {
//
print('Flutter Error: ${details.exception}');
}
};
//
PlatformDispatcher.instance.onError = (error, stack) {
print('Platform Error: $error');
print('Stack: $stack');
return true;
};
try {
WidgetsFlutterBinding.ensureInitialized();
// - release模式
EnvConfig.setEnvironment(Environment.dev);
// RTC
try {
await RTCManager.instance.initialize(appId: '4c2ea9dcb4c5440593a418df0fdd512d');
} catch (e) {
print('RTC初始化失败: $e');
}
// IM初始化改为异步
// IM初始化将在 MyApp initState
//
final networkService = NetworkService();
Get.put(networkService);
Get.put(networkService.userApi);
Get.put(networkService.homeApi);
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.dark,
statusBarBrightness: Brightness.light,
systemNavigationBarColor: Colors.white,
systemNavigationBarIconBrightness: Brightness.dark,
),
);
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
if (Platform.isIOS) {
SystemChrome.setEnabledSystemUIMode(
SystemUiMode.manual,
overlays: [SystemUiOverlay.top],
);
}
} catch (e, stackTrace) {
print('应用初始化失败: $e');
print('堆栈跟踪: $stackTrace');
// 使
}
}
@override
Widget build(BuildContext context) {
return Container(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
color: Colors.white,
child: show ? UserAgreementDialog(
onAgree: _onAgreeAgreement,
onDisagree: _onDisagreeAgreement,
) : SizedBox(),
);
}
}
class StartPage extends StatefulWidget {
const StartPage({super.key});
@override
State<StartPage> createState() => _StartPageState();
}
class _StartPageState extends State<StartPage> {
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return MyApp();
}
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Fluwx fluwx = Fluwx();
// bool _screenUtilInitialized = false;
bool _showAgreementDialog = false;
@override
void initState() {
super.initState();
_initFluwx();
// IM
_initIMAsync();
}
/// IM SDK
void _initIMAsync() {
// 使 Future.delayed
@ -278,10 +338,10 @@ class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
// ScreenUtil.init build时调用
if (!_screenUtilInitialized) {
ScreenUtil.init(context, designSize: const Size(375, 812));
_screenUtilInitialized = true;
}
// if (!_screenUtilInitialized) {
// ScreenUtil.init(context, designSize: const Size(375, 812));
// _screenUtilInitialized = true;
// }
// token是否为空
final storage = GetStorage();
@ -305,10 +365,7 @@ class _MyAppState extends State<MyApp> {
return Stack(
children: [
homeWidget,
UserAgreementDialog(
onAgree: _onAgreeAgreement,
onDisagree: _onDisagreeAgreement,
),
],
);
}

489
lib/pages/discover/live_room_page.dart

@ -241,12 +241,6 @@ class _LiveRoomPageState extends State<LiveRoomPage> {
final isHost = _roomController.currentRole == CurrentRole.broadcaster;
//
final hasGuests =
_roomController.rtcChannelDetail.value?.maleInfo !=
null ||
_roomController.rtcChannelDetail.value?.femaleInfo !=
null;
// build 使 addPostFrameCallback build setState
WidgetsBinding.instance.addPostFrameCallback((_) {
@ -392,257 +386,266 @@ class _LiveRoomPageState extends State<LiveRoomPage> {
if (isHost) Positioned(
right: 15.w,
top: 95.w,
child: Column(
children: [
if (hasGuests) Container(
width: 44.w,
height: 44.w,
margin: EdgeInsets.only(bottom: 5.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6.w)),
color: const Color.fromRGBO(0, 0, 0, .3)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
Assets.imagesMicManage,
width: 17.w,
height: 18.w,
),
Text(
"连麦管理",
style: TextStyle(
fontSize: 9.w,
color: Colors.white
child: Obx((){
//
final hasGuests =
_roomController.rtcChannelDetail.value?.maleInfo !=
null ||
_roomController.rtcChannelDetail.value?.femaleInfo !=
null;
return Column(
children: [
if (hasGuests) Container(
width: 44.w,
height: 44.w,
margin: EdgeInsets.only(bottom: 5.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6.w)),
color: const Color.fromRGBO(0, 0, 0, .3)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
Assets.imagesMicManage,
width: 17.w,
height: 18.w,
),
)
],
),
).onTap(() {
//
SmartDialog.dismiss();
//
_roomController.setDialogDismiss(true);
SmartDialog.show(
onDismiss: (){
_roomController.setDialogDismiss(false);
},
builder: (context) {
return DisconnectMicDialog();
},
);
}),
Container(
width: 44.w,
height: 44.w,
margin: EdgeInsets.only(bottom: 5.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6.w)),
color: const Color.fromRGBO(0, 0, 0, .3)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
Assets.imagesKickUser,
width: 19.w,
height: 18.w,
),
Text(
"踢出房间",
style: TextStyle(
fontSize: 9.w,
color: Colors.white
Text(
"连麦管理",
style: TextStyle(
fontSize: 9.w,
color: Colors.white
),
)
],
),
).onTap(() {
//
SmartDialog.dismiss();
//
_roomController.setDialogDismiss(true);
SmartDialog.show(
onDismiss: (){
_roomController.setDialogDismiss(false);
},
builder: (context) {
return DisconnectMicDialog();
},
);
}),
Container(
width: 44.w,
height: 44.w,
margin: EdgeInsets.only(bottom: 5.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6.w)),
color: const Color.fromRGBO(0, 0, 0, .3)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
Assets.imagesKickUser,
width: 19.w,
height: 18.w,
),
)
],
),
).onTap(() async {
_roomController.audienceList.clear();
await _roomController.getAudienceList(null);
//
FocusScope.of(context).unfocus();
// overlay
SmartDialog.dismiss();
_roomController.setDialogDismiss(true);
SmartDialog.show(
alignment: Alignment.bottomCenter,
maskColor: TDTheme.of(context).fontGyColor2,
onDismiss: (){
_roomController.setDialogDismiss(false);
},
builder: (_) {
return KickList();
},
);
}),
Container(
width: 44.w,
height: 44.w,
margin: EdgeInsets.only(bottom: 5.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6.w)),
color: const Color.fromRGBO(0, 0, 0, .3)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
Assets.imagesCloseLive,
width: 15.w,
height: 16.w,
),
Text(
"结束直播",
style: TextStyle(
fontSize: 9.w,
color: Colors.white
Text(
"踢出房间",
style: TextStyle(
fontSize: 9.w,
color: Colors.white
),
)
],
),
).onTap(() async {
_roomController.audienceList.clear();
await _roomController.getAudienceList(null);
//
FocusScope.of(context).unfocus();
// overlay
SmartDialog.dismiss();
_roomController.setDialogDismiss(true);
SmartDialog.show(
alignment: Alignment.bottomCenter,
maskColor: TDTheme.of(context).fontGyColor2,
onDismiss: (){
_roomController.setDialogDismiss(false);
},
builder: (_) {
return KickList();
},
);
}),
Container(
width: 44.w,
height: 44.w,
margin: EdgeInsets.only(bottom: 5.w),
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(6.w)),
color: const Color.fromRGBO(0, 0, 0, .3)
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
Assets.imagesCloseLive,
width: 15.w,
height: 16.w,
),
)
],
),
).onTap(() async {
await _roomController.getDurationMins();
// overlay
SmartDialog.dismiss();
SmartDialog.show(
onDismiss: (){
_roomController.setDialogDismiss(false);
},
builder: (context) {
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(16.w)),
child: Material(
color: Colors.white,
child: Container(
width: 311.w,
height: 189.w,
padding: EdgeInsets.symmetric(
vertical: 20.w,
horizontal: 27.w
),
child: Column(
children: [
Text(
"您当前正在视频相亲中\n"
"确定要退出吗?",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.w
),
),
Container(
margin: EdgeInsets.only(top: 9.w, bottom: 18.w),
height: 23.w,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft, // 90deg =
end: Alignment.centerRight,
colors: [
Color.fromRGBO(117, 98, 249, 0),
Color.fromRGBO(117, 98, 249, 0.2),
Color.fromRGBO(117, 98, 249, 0.2),
Color.fromRGBO(117, 98, 249, 0.2),
Color.fromRGBO(117, 98, 249, 0),
],
stops: [
0.0,
0.2931,
0.5389,
0.7708,
1.0,
],
Text(
"结束直播",
style: TextStyle(
fontSize: 9.w,
color: Colors.white
),
)
],
),
).onTap(() async {
await _roomController.getDurationMins();
// overlay
SmartDialog.dismiss();
SmartDialog.show(
onDismiss: (){
_roomController.setDialogDismiss(false);
},
builder: (context) {
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(16.w)),
child: Material(
color: Colors.white,
child: Container(
width: 311.w,
height: 189.w,
padding: EdgeInsets.symmetric(
vertical: 20.w,
horizontal: 27.w
),
child: Column(
children: [
Text(
"您当前正在视频相亲中\n"
"确定要退出吗?",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 18.w
),
),
child: Center(
child: Text(
"本场有效露脸开播时长${_roomController.durationMins.value}分钟",
style: TextStyle(
fontSize: 12.w,
color: const Color.fromRGBO(117, 98, 249, 1)
Container(
margin: EdgeInsets.only(top: 9.w, bottom: 18.w),
height: 23.w,
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerLeft, // 90deg =
end: Alignment.centerRight,
colors: [
Color.fromRGBO(117, 98, 249, 0),
Color.fromRGBO(117, 98, 249, 0.2),
Color.fromRGBO(117, 98, 249, 0.2),
Color.fromRGBO(117, 98, 249, 0.2),
Color.fromRGBO(117, 98, 249, 0),
],
stops: [
0.0,
0.2931,
0.5389,
0.7708,
1.0,
],
),
),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 128.w,
height: 40.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12.w)),
color: const Color.fromRGBO(237, 237, 237, 1)
child: Center(
child: Text(
"本场有效露脸开播时长${_roomController.durationMins.value}分钟",
style: TextStyle(
fontSize: 12.w,
color: const Color.fromRGBO(117, 98, 249, 1)
),
),
child: Center(
child: Text(
"取消",
style: TextStyle(
fontSize: 15.w,
fontWeight: FontWeight.w400
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 128.w,
height: 40.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12.w)),
color: const Color.fromRGBO(237, 237, 237, 1)
),
child: Center(
child: Text(
"取消",
style: TextStyle(
fontSize: 15.w,
fontWeight: FontWeight.w400
),
),
),
),
).onTap(() {
SmartDialog.dismiss();
}),
Container(
width: 128.w,
height: 40.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12.w)),
color: const Color.fromRGBO(117, 98, 249, 1)
),
child: Center(
child: Text(
"确认",
style: TextStyle(
color: Colors.white,
fontSize: 15.w,
fontWeight: FontWeight.w400
).onTap(() {
SmartDialog.dismiss();
}),
Container(
width: 128.w,
height: 40.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(12.w)),
color: const Color.fromRGBO(117, 98, 249, 1)
),
child: Center(
child: Text(
"确认",
style: TextStyle(
color: Colors.white,
fontSize: 15.w,
fontWeight: FontWeight.w400
),
),
),
),
).onTap(() async {
// 退RTM消息
await _roomController.leaveChannel();
await _roomController.getLiveData();
await _roomController.getLiveIncome();
SmartDialog.dismiss();
if (Get.isRegistered<RoomController>()) {
final roomController = Get.find<RoomController>();
roomController.chatMessages.clear();
}
// pop Get.back()
Get.off(() => SettlementPage());
//
Future.delayed(const Duration(milliseconds: 200), () {
_overlayController.hide();
});
}),
],
)
],
).onTap(() async {
// 退RTM消息
await _roomController.leaveChannel();
await _roomController.getLiveData();
await _roomController.getLiveIncome();
SmartDialog.dismiss();
if (Get.isRegistered<RoomController>()) {
final roomController = Get.find<RoomController>();
roomController.chatMessages.clear();
}
// pop Get.back()
Get.off(() => SettlementPage());
//
Future.delayed(const Duration(milliseconds: 200), () {
_overlayController.hide();
});
}),
],
)
],
),
),
),
),
);
},
);
}),
],
),
);
},
);
}),
],
);
}),
),
// SVGA
const SvgaPlayerWidget(),

Loading…
Cancel
Save