王子贤 4 months ago
parent
commit
36e80879a3
8 changed files with 309 additions and 60 deletions
  1. 1
      lib/controller/discover/room_controller.dart
  2. 23
      lib/controller/overlay_controller.dart
  3. 32
      lib/main.dart
  4. 2
      lib/pages/discover/dating_page.dart
  5. 10
      lib/pages/discover/live_room_page.dart
  6. 105
      lib/pages/mine/user_help_center_page.dart
  7. 192
      lib/widget/live/draggable_overlay_widget.dart
  8. 4
      lib/widget/live/live_recharge_popup.dart

1
lib/controller/discover/room_controller.dart

@ -285,7 +285,6 @@ class RoomController extends GetxController {
await RTCManager.instance.unpublish(currentRole);
}
currentRole = CurrentRole.normalUser;
;
await RTCManager.instance.leaveChannel();
}

23
lib/controller/overlay_controller.dart

@ -0,0 +1,23 @@
import 'package:get/get.dart';
/// Overlay
class OverlayController extends GetxController {
/// overlay
final showOverlay = false.obs;
/// overlay
void show() {
showOverlay.value = true;
}
/// overlay
void hide() {
showOverlay.value = false;
}
/// overlay
void toggle() {
showOverlay.value = !showOverlay.value;
}
}

32
lib/main.dart

@ -2,12 +2,13 @@ import 'dart:io';
import 'package:dating_touchme_app/config/env_config.dart';
import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/controller/overlay_controller.dart';
import 'package:dating_touchme_app/im/im_manager.dart';
import 'package:dating_touchme_app/network/network_service.dart';
import 'package:dating_touchme_app/pages/main/main_page.dart';
import 'package:dating_touchme_app/pages/mine/login_page.dart';
import 'package:dating_touchme_app/pages/mine/user_info_page.dart';
import 'package:dating_touchme_app/rtc/rtc_manager.dart';
import 'package:dating_touchme_app/widget/live/draggable_overlay_widget.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
@ -31,6 +32,8 @@ void main() async {
Get.put(networkService);
Get.put(networkService.userApi);
Get.put(networkService.homeApi);
// Overlay
Get.put(OverlayController());
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
@ -70,7 +73,30 @@ void main() async {
),
),
),
builder: FlutterSmartDialog.init(),
builder: (context, child) {
final smartDialogBuilder = FlutterSmartDialog.init();
return smartDialogBuilder(
context,
Stack(
children: [
child ?? const SizedBox(),
// overlay
Obx(() {
final overlayController = Get.find<OverlayController>();
return overlayController.showOverlay.value
? DraggableOverlayWidget(
size: 60,
backgroundColor: const Color.fromRGBO(0, 0, 0, 0.6),
onClose: () {
overlayController.hide();
},
)
: const SizedBox.shrink();
}),
],
),
);
},
home: MyApp(),
),
);
@ -100,7 +126,7 @@ class _MyAppState extends State<MyApp> {
doOnIOS: true,
universalLink: 'https://your.univerallink.com/link/',
);
var result = await fluwx.isWeChatInstalled;
await fluwx.isWeChatInstalled;
}
// This widget is the root of your application.

2
lib/pages/discover/dating_page.dart

@ -117,7 +117,7 @@ class _DatingPageState extends State<DatingPage>
'暂无直播频道',
style: TextStyle(
fontSize: 14.w,
color: Colors.white.withOpacity(0.7),
color: Colors.black38,
),
),
);

10
lib/pages/discover/live_room_page.dart

@ -1,5 +1,5 @@
import 'package:dating_touchme_app/controller/discover/room_controller.dart';
import 'package:dating_touchme_app/controller/global.dart';
import 'package:dating_touchme_app/controller/overlay_controller.dart';
import 'package:dating_touchme_app/generated/assets.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
@ -8,7 +8,6 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart';
import 'package:dating_touchme_app/widget/live/live_room_user_header.dart';
import 'package:dating_touchme_app/widget/live/live_room_anchor_showcase.dart';
import 'package:dating_touchme_app/widget/live/live_room_seat_list.dart';
import 'package:dating_touchme_app/widget/live/live_room_active_speaker.dart';
import 'package:dating_touchme_app/widget/live/live_room_notice_chat_panel.dart';
import 'package:dating_touchme_app/widget/live/live_room_action_bar.dart';
@ -25,6 +24,7 @@ class LiveRoomPage extends StatefulWidget {
class _LiveRoomPageState extends State<LiveRoomPage> {
late final RoomController _roomController;
late final OverlayController _overlayController;
String message = '';
final TextEditingController _messageController = TextEditingController();
@ -71,11 +71,11 @@ class _LiveRoomPageState extends State<LiveRoomPage> {
_roomController = Get.isRegistered<RoomController>()
? Get.find<RoomController>()
: Get.put(RoomController());
_overlayController = Get.find<OverlayController>();
}
@override
void dispose() {
_roomController.leaveChannel();
_messageController.dispose();
super.dispose();
}
@ -171,6 +171,10 @@ class _LiveRoomPageState extends State<LiveRoomPage> {
userName: userName,
popularityText: popularityText,
avatarAsset: avatarAsset,
onCloseTap: () {
Get.back();
_overlayController.toggle();
},
);
}),
SizedBox(height: 7.w),

105
lib/pages/mine/user_help_center_page.dart

@ -245,60 +245,63 @@ class _UserHelpCenterPageState extends State<UserHelpCenterPage> {
],
),
),
Container(
height: 40.w,
padding: EdgeInsets.symmetric(
vertical: 10.w
),
child: Row(
children: [
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
Assets.imagesEdit,
width: 15.w,
),
SizedBox(width: 9.w,),
Text(
"意见反馈",
style: TextStyle(
fontSize: 16.w,
fontWeight: FontWeight.w500
),
)
],
],
),
),
bottomNavigationBar:
SafeArea(
child: SizedBox(
height: 40.w,
child: Row(
children: [
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
Assets.imagesEdit,
width: 15.w,
),
),
Container(
width: 1,
height: 20.w,
color: const Color.fromRGBO(230, 230, 230, 1),
),
Expanded(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
Assets.imagesCustomer,
width: 15.w,
),
SizedBox(width: 9.w,),
Text(
"联系客服",
style: TextStyle(
fontSize: 16.w,
fontWeight: FontWeight.w500
),
)
],
SizedBox(width: 8.w,),
Text(
"意见反馈",
style: TextStyle(
fontSize: 16.w,
fontWeight: FontWeight.w500
),
)
],
),
),
Container(
width: 1,
height: 20.w,
color: const Color.fromRGBO(230, 230, 230, 1),
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
Assets.imagesCustomer,
width: 20.w,
height: 20.w,
),
),
],
SizedBox(width: 4.w,),
Text(
"联系客服",
style: TextStyle(
fontSize: 16.w,
fontWeight: FontWeight.w500
),
)
],
),
),
)
],
],
),
),
),
)

192
lib/widget/live/draggable_overlay_widget.dart

@ -0,0 +1,192 @@
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
import 'package:dating_touchme_app/controller/discover/room_controller.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:dating_touchme_app/rtc/rtc_manager.dart';
/// Overlay
class DraggableOverlayWidget extends StatefulWidget {
final VoidCallback? onClose;
final Widget? child;
final double size;
final Color backgroundColor;
const DraggableOverlayWidget({
super.key,
this.onClose,
this.child,
this.size = 60,
this.backgroundColor = const Color.fromRGBO(0, 0, 0, 0.5),
});
@override
State<DraggableOverlayWidget> createState() => _DraggableOverlayWidgetState();
}
class _DraggableOverlayWidgetState extends State<DraggableOverlayWidget> {
Offset _position = Offset.zero;
bool _isDragging = false;
final RTCManager _rtcManager = RTCManager.instance;
final RoomController _roomController = Get.find<RoomController>();
@override
void initState() {
super.initState();
//
WidgetsBinding.instance.addPostFrameCallback((_) {
final size = MediaQuery.of(context).size;
setState(() {
_position = Offset(
size.width - 100.w, // 使100.w因为用户改了size
100,
);
});
});
}
///
void _snapToEdge(double screenWidth) {
final centerX = screenWidth / 2;
final targetX = _position.dx < centerX
? 0.0 //
: screenWidth - 100.w; // 使100.w因为用户改了size
// 使 setState AnimatedPositioned
setState(() {
_position = Offset(targetX, _position.dy);
_isDragging = false;
});
}
///
Widget _buildAnchorVideo() {
final engine = _rtcManager.engine;
if (_roomController.rtcChannelDetail.value?.anchorInfo == null ||
engine == null) {
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(8.w)),
color: Colors.grey.withOpacity(0.5),
),
child: Center(
child: Text(
'等待主播',
style: TextStyle(
color: Colors.white.withOpacity(0.8),
fontSize: 12.w,
),
),
),
);
}
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(8.w)),
child: _roomController.currentRole == CurrentRole.broadcaster
? AgoraVideoView(
controller: VideoViewController(
rtcEngine: engine,
canvas: const VideoCanvas(uid: 0),
),
)
: AgoraVideoView(
controller: VideoViewController.remote(
rtcEngine: engine,
canvas: VideoCanvas(
uid: _roomController.rtcChannelDetail.value?.anchorInfo?.uid,
),
connection: RtcConnection(
channelId: _rtcManager.currentChannelId ?? '',
),
),
),
);
}
@override
Widget build(BuildContext context) {
final screenSize = MediaQuery.of(context).size;
// 使使
return AnimatedPositioned(
duration: _isDragging
? const Duration(milliseconds: 50) //
: const Duration(milliseconds: 300), //
curve: _isDragging ? Curves.linear : Curves.easeOut,
left: _position.dx,
top: _position.dy,
child: _buildContent(screenSize),
);
}
Widget _buildContent(Size screenSize) {
return GestureDetector(
onPanStart: (details) {
setState(() {
_isDragging = true;
});
},
onPanUpdate: (details) {
setState(() {
_position += details.delta;
// 使100.w因为用户改了size
_position = Offset(
_position.dx.clamp(0.0, screenSize.width - 100.w),
_position.dy.clamp(0.0, screenSize.height - 100.w),
);
});
},
onPanEnd: (details) {
//
_snapToEdge(screenSize.width);
},
child: Obx(() {
return Container(
width: 100.w,
height: 100.w,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.w),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.3),
blurRadius: 8,
offset: const Offset(0, 2),
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(8.w),
child: Stack(
children: [
//
widget.child ?? _buildAnchorVideo(),
//
Positioned(
top: 2.w,
right: 2.w,
child: GestureDetector(
onTap: () async {
await _roomController.leaveChannel();
widget.onClose?.call();
},
child: Container(
width: 20.w,
height: 20.w,
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.5),
shape: BoxShape.circle,
),
child: Icon(Icons.close, color: Colors.white, size: 14.w),
),
),
),
],
),
),
);
}),
);
}
}

4
lib/widget/live/live_recharge_popup.dart

@ -2,6 +2,8 @@ import 'package:dating_touchme_app/generated/assets.dart';
import 'package:dating_touchme_app/widget/live/live_room_pay_item.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:retrofit/http.dart';
class LiveRechargePopup extends StatelessWidget {
const LiveRechargePopup({
@ -47,7 +49,7 @@ class LiveRechargePopup extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
InkWell(
onTap: () => Navigator.maybePop(context),
onTap: () => Get.back(),
child: Icon(
Icons.close,
size: 14.w,

Loading…
Cancel
Save