1
This commit is contained in:
@@ -3,7 +3,7 @@ import 'package:app/config/config.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../viewmodel/students_view_model.dart';
|
||||
import '../viewmodel/tch_room_vm.dart';
|
||||
import 'student_item.dart';
|
||||
|
||||
class ContentView extends StatefulWidget {
|
||||
@@ -14,19 +14,24 @@ class ContentView extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ContentViewState extends State<ContentView> {
|
||||
// bool isLoading = true;
|
||||
|
||||
//声网数据
|
||||
RtcEngine? _engine;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
// _initRtc();
|
||||
}
|
||||
|
||||
void _initRtc() async {
|
||||
final vm = context.read<StudentsViewModel>();
|
||||
final vm = context.read<TchRoomVM>();
|
||||
_engine = createAgoraRtcEngine();
|
||||
//初始化 RtcEngine,设置频道场景为 channelProfileLiveBroadcasting(直播场景)
|
||||
await _engine!.initialize(
|
||||
RtcEngineContext(
|
||||
appId: Config.swAppId,
|
||||
channelProfile: ChannelProfileType.channelProfileLiveBroadcasting,
|
||||
channelProfile: ChannelProfileType.channelProfileCommunication,
|
||||
),
|
||||
);
|
||||
//添加回调
|
||||
@@ -39,7 +44,8 @@ class _ContentViewState extends State<ContentView> {
|
||||
// 远端用户或主播加入当前频道回调
|
||||
onUserJoined: (RtcConnection connection, int remoteUid, int elapsed) {},
|
||||
// 远端用户或主播离开当前频道回调
|
||||
onUserOffline: (RtcConnection connection, int remoteUid, UserOfflineReasonType reason) {},
|
||||
onUserOffline:
|
||||
(RtcConnection connection, int remoteUid, UserOfflineReasonType reason) {},
|
||||
),
|
||||
);
|
||||
//启动视频模块
|
||||
@@ -48,7 +54,7 @@ class _ContentViewState extends State<ContentView> {
|
||||
await _engine!.joinChannel(
|
||||
token: vm.rtcToken!.token,
|
||||
channelId: vm.rtcToken!.channel,
|
||||
uid: int.parse(vm.rtcToken!.uid),
|
||||
uid: vm.rtcToken!.uid,
|
||||
options: ChannelMediaOptions(
|
||||
// 自动订阅所有视频流
|
||||
autoSubscribeVideo: true,
|
||||
@@ -64,22 +70,13 @@ class _ContentViewState extends State<ContentView> {
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void didChangeDependencies() {
|
||||
super.didChangeDependencies();
|
||||
final vm = context.read<StudentsViewModel>();
|
||||
if (_engine == null && vm.students.isNotEmpty) {
|
||||
_initRtc();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Consumer<StudentsViewModel>(
|
||||
return Consumer<TchRoomVM>(
|
||||
builder: (context, vm, _) {
|
||||
if (vm.students.isEmpty) {
|
||||
return Center(
|
||||
child: Text('无学生在场,请通知学生入场'),
|
||||
child: Text('准备中'),
|
||||
);
|
||||
}
|
||||
//选中的学生
|
||||
@@ -96,6 +93,7 @@ class _ContentViewState extends State<ContentView> {
|
||||
Expanded(
|
||||
child: StudentItem(
|
||||
user: activeStudent,
|
||||
engine: _engine,
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
@@ -107,6 +105,7 @@ class _ContentViewState extends State<ContentView> {
|
||||
height: 250,
|
||||
child: StudentItem(
|
||||
user: item,
|
||||
engine: _engine,
|
||||
),
|
||||
);
|
||||
},
|
||||
|
||||
@@ -5,7 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'content_view.dart';
|
||||
import '../viewmodel/students_view_model.dart';
|
||||
import '../viewmodel/tch_room_vm.dart';
|
||||
|
||||
class StatusView extends StatefulWidget {
|
||||
const StatusView({super.key});
|
||||
@@ -26,6 +26,8 @@ class _StatusViewState extends State<StatusView> {
|
||||
void initState() {
|
||||
super.initState();
|
||||
_init();
|
||||
final vm = context.read<TchRoomVM>();
|
||||
vm.addListener(openRoom);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -36,10 +38,11 @@ class _StatusViewState extends State<StatusView> {
|
||||
}
|
||||
|
||||
void _init() {
|
||||
final vm = context.read<StudentsViewModel>();
|
||||
//如果房间可以开始
|
||||
final vm = context.read<TchRoomVM>();
|
||||
//如果房间到点可以开始
|
||||
if (vm.canEnterRoom) {
|
||||
status = RoomStatus.start;
|
||||
// openRoom();
|
||||
} else {
|
||||
status = RoomStatus.waiting;
|
||||
startCountDown();
|
||||
@@ -48,12 +51,12 @@ class _StatusViewState extends State<StatusView> {
|
||||
|
||||
///开始倒计时
|
||||
void startCountDown() {
|
||||
final vm = context.read<StudentsViewModel>();
|
||||
final vm = context.read<TchRoomVM>();
|
||||
//当前时间
|
||||
DateTime now = DateTime.now();
|
||||
//远端时间
|
||||
setState(() {
|
||||
_seconds = vm.startTime.difference(now).inSeconds;
|
||||
_seconds = parseTime(vm.roomInfo.startTime).difference(now).inSeconds;
|
||||
});
|
||||
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
|
||||
setState(() {
|
||||
@@ -71,8 +74,9 @@ class _StatusViewState extends State<StatusView> {
|
||||
|
||||
///开启自习室
|
||||
void openRoom() {
|
||||
final vm = context.read<StudentsViewModel>();
|
||||
final vm = context.read<TchRoomVM>();
|
||||
vm.toggleRoom(isOpen: true);
|
||||
vm.removeListener(openRoom);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import 'package:agora_rtc_engine/agora_rtc_engine.dart';
|
||||
import 'package:app/pages/teacher/room/viewmodel/type.dart';
|
||||
import 'package:app/request/dto/room/room_user_dto.dart';
|
||||
import 'package:app/widgets/room/file_drawer.dart';
|
||||
import 'package:app/widgets/room/video_surface.dart';
|
||||
@@ -5,14 +7,16 @@ import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:remixicon/remixicon.dart';
|
||||
|
||||
import '../viewmodel/students_view_model.dart';
|
||||
import '../viewmodel/tch_room_vm.dart';
|
||||
|
||||
class StudentItem extends StatefulWidget {
|
||||
final RoomUserDto user;
|
||||
final RtcEngine? engine;
|
||||
|
||||
const StudentItem({
|
||||
super.key,
|
||||
required this.user,
|
||||
this.engine,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -27,12 +31,16 @@ class _StudentItemState extends State<StudentItem> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final vm = context.read<StudentsViewModel>();
|
||||
final vm = context.read<TchRoomVM>();
|
||||
//摄像头是否开启
|
||||
bool isCameraOpen = widget.user.cameraStatus == 1;
|
||||
|
||||
///麦克风是否开启
|
||||
bool isMicOpen = widget.user.microphoneStatus == 1;
|
||||
|
||||
///声音是否开启
|
||||
bool isSpeakerOpen = widget.user.speekerStatus == 1;
|
||||
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
child: Container(
|
||||
@@ -44,6 +52,13 @@ class _StudentItemState extends State<StudentItem> {
|
||||
width: double.infinity,
|
||||
child: Stack(
|
||||
children: [
|
||||
if (widget.engine != null)
|
||||
AgoraVideoView(
|
||||
controller: VideoViewController(
|
||||
rtcEngine: widget.engine!,
|
||||
canvas: VideoCanvas(uid: widget.user.rtcUid),
|
||||
),
|
||||
),
|
||||
// VideoSurface(),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
@@ -95,14 +110,35 @@ class _StudentItemState extends State<StudentItem> {
|
||||
_actionItem(
|
||||
icon: isCameraOpen ? RemixIcons.video_on_fill : RemixIcons.video_off_fill,
|
||||
isActive: isCameraOpen,
|
||||
onTap: () {
|
||||
vm.closeStudentAction(
|
||||
uId: widget.user.userId,
|
||||
action: StudentAction.camera,
|
||||
);
|
||||
},
|
||||
),
|
||||
_actionItem(
|
||||
icon: isMicOpen ? RemixIcons.mic_fill : RemixIcons.mic_off_fill,
|
||||
isActive: isMicOpen,
|
||||
onTap: () {
|
||||
vm.closeStudentAction(
|
||||
uId: widget.user.userId,
|
||||
action: StudentAction.microphone,
|
||||
);
|
||||
},
|
||||
),
|
||||
_actionItem(
|
||||
icon: isSpeakerOpen
|
||||
? RemixIcons.volume_up_fill
|
||||
: RemixIcons.volume_mute_fill,
|
||||
isActive: isSpeakerOpen,
|
||||
onTap: () {
|
||||
vm.closeStudentAction(
|
||||
uId: widget.user.userId,
|
||||
action: StudentAction.speaker,
|
||||
);
|
||||
},
|
||||
),
|
||||
// _actionItem(
|
||||
// icon: RemixIcons.volume_mute_fill,
|
||||
// ),
|
||||
_actionItem(icon: RemixIcons.file_list_3_fill, onTap: _openFileList),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user