|
|
|
@ -84,6 +84,7 @@ class _CallScreenState extends State<CallScreen> {
|
|
|
|
Color chatTextColor = const Color(0xFFAAAAAA);
|
|
|
|
Color chatTextColor = const Color(0xFFAAAAAA);
|
|
|
|
Widget changeNamePopup;
|
|
|
|
Widget changeNamePopup;
|
|
|
|
final args = ModalRoute.of(context)!.settings.arguments as CallArguments;
|
|
|
|
final args = ModalRoute.of(context)!.settings.arguments as CallArguments;
|
|
|
|
|
|
|
|
var isFrontCamera = useState(true);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() {
|
|
|
|
useEffect(() {
|
|
|
|
Future<void>.microtask(() async {
|
|
|
|
Future<void>.microtask(() async {
|
|
|
|
@ -93,8 +94,11 @@ class _CallScreenState extends State<CallScreen> {
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
Map<String, bool> SDKaudioOptions = {"connect": true, "mute": false, "autoAdjustSpeakerVolume": false};
|
|
|
|
Map<String, bool> SDKaudioOptions = {"connect": true, "mute": false, "autoAdjustSpeakerVolume": false};
|
|
|
|
|
|
|
|
// Map<String, bool> SDKvideoOptions = {
|
|
|
|
|
|
|
|
// "localVideoOn": true,
|
|
|
|
|
|
|
|
// };
|
|
|
|
Map<String, bool> SDKvideoOptions = {
|
|
|
|
Map<String, bool> SDKvideoOptions = {
|
|
|
|
"localVideoOn": true,
|
|
|
|
"localVideoOn": args.callType == 1 ? true : false,
|
|
|
|
};
|
|
|
|
};
|
|
|
|
JoinSessionConfig joinSession = JoinSessionConfig(
|
|
|
|
JoinSessionConfig joinSession = JoinSessionConfig(
|
|
|
|
sessionName: args.sessionName,
|
|
|
|
sessionName: args.sessionName,
|
|
|
|
@ -302,6 +306,19 @@ class _CallScreenState extends State<CallScreen> {
|
|
|
|
List<ZoomVideoSdkUser>? remoteUserList = await zoom.session.getRemoteUsers();
|
|
|
|
List<ZoomVideoSdkUser>? remoteUserList = await zoom.session.getRemoteUsers();
|
|
|
|
var leftUserListJson = jsonDecode(data['leftUsers']) as List;
|
|
|
|
var leftUserListJson = jsonDecode(data['leftUsers']) as List;
|
|
|
|
List<ZoomVideoSdkUser> leftUserLis = leftUserListJson.map((userJson) => ZoomVideoSdkUser.fromJson(userJson)).toList();
|
|
|
|
List<ZoomVideoSdkUser> leftUserLis = leftUserListJson.map((userJson) => ZoomVideoSdkUser.fromJson(userJson)).toList();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// If no remote users remain, the other participant has left — end the session
|
|
|
|
|
|
|
|
if (remoteUserList == null || remoteUserList.isEmpty) {
|
|
|
|
|
|
|
|
await zoom.leaveSession(true);
|
|
|
|
|
|
|
|
Navigator.pushAndRemoveUntil(
|
|
|
|
|
|
|
|
context,
|
|
|
|
|
|
|
|
CustomPageRoute(
|
|
|
|
|
|
|
|
page: LandingNavigation(),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
(r) => false);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (fullScreenUser.value != null) {
|
|
|
|
if (fullScreenUser.value != null) {
|
|
|
|
for (var user in leftUserLis) {
|
|
|
|
for (var user in leftUserLis) {
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -313,8 +330,8 @@ class _CallScreenState extends State<CallScreen> {
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
fullScreenUser.value = mySelf;
|
|
|
|
fullScreenUser.value = mySelf;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
remoteUserList?.add(mySelf!);
|
|
|
|
remoteUserList.add(mySelf!);
|
|
|
|
users.value = remoteUserList!;
|
|
|
|
users.value = remoteUserList;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
final userNameChangedListener = eventListener.addListener(EventType.onUserNameChanged, (data) async {
|
|
|
|
final userNameChangedListener = eventListener.addListener(EventType.onUserNameChanged, (data) async {
|
|
|
|
@ -817,63 +834,38 @@ class _CallScreenState extends State<CallScreen> {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void onPressCameraList() async {
|
|
|
|
void onPressCameraList() async {
|
|
|
|
List<ListTile> options = [];
|
|
|
|
|
|
|
|
List<ZoomVideoSdkCameraDevice> cameraList = await zoom.videoHelper.getCameraList();
|
|
|
|
List<ZoomVideoSdkCameraDevice> cameraList = await zoom.videoHelper.getCameraList();
|
|
|
|
for (var camera in cameraList) {
|
|
|
|
if (cameraList.isEmpty) return;
|
|
|
|
options.add(
|
|
|
|
|
|
|
|
ListTile(
|
|
|
|
// Find the target camera by toggling between front and back
|
|
|
|
title: Text(
|
|
|
|
ZoomVideoSdkCameraDevice? targetCamera;
|
|
|
|
camera.deviceName,
|
|
|
|
try {
|
|
|
|
style: const TextStyle(
|
|
|
|
if (isFrontCamera.value) {
|
|
|
|
fontSize: 14,
|
|
|
|
// Currently front, switch to back
|
|
|
|
fontWeight: FontWeight.normal,
|
|
|
|
targetCamera = cameraList.firstWhere(
|
|
|
|
color: Colors.black,
|
|
|
|
(c) => c.deviceName.toLowerCase().contains('back') || c.deviceName.toLowerCase().contains('rear'),
|
|
|
|
),
|
|
|
|
);
|
|
|
|
),
|
|
|
|
} else {
|
|
|
|
onTap: () async => {
|
|
|
|
// Currently back, switch to front
|
|
|
|
await zoom.videoHelper.switchCamera(camera.deviceId),
|
|
|
|
targetCamera = cameraList.firstWhere(
|
|
|
|
Navigator.of(context).pop(),
|
|
|
|
(c) => c.deviceName.toLowerCase().contains('front') || c.deviceName.toLowerCase().contains('facing'),
|
|
|
|
},
|
|
|
|
);
|
|
|
|
),
|
|
|
|
}
|
|
|
|
);
|
|
|
|
} catch (_) {
|
|
|
|
|
|
|
|
targetCamera = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Fallback: if we can't identify by name, just pick the other camera
|
|
|
|
|
|
|
|
if (targetCamera == null && cameraList.length >= 2) {
|
|
|
|
|
|
|
|
final currentIndex = isFrontCamera.value ? 0 : 1;
|
|
|
|
|
|
|
|
final nextIndex = (currentIndex + 1) % cameraList.length;
|
|
|
|
|
|
|
|
targetCamera = cameraList[nextIndex];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (targetCamera != null) {
|
|
|
|
|
|
|
|
await zoom.videoHelper.switchCamera(targetCamera.deviceId);
|
|
|
|
|
|
|
|
isFrontCamera.value = !isFrontCamera.value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
options.add(
|
|
|
|
|
|
|
|
ListTile(
|
|
|
|
|
|
|
|
title: Text(
|
|
|
|
|
|
|
|
"Cancel",
|
|
|
|
|
|
|
|
style: const TextStyle(
|
|
|
|
|
|
|
|
fontSize: 14,
|
|
|
|
|
|
|
|
fontWeight: FontWeight.normal,
|
|
|
|
|
|
|
|
color: Colors.black,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
onTap: () async => {
|
|
|
|
|
|
|
|
Navigator.of(context).pop(),
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
showDialog(
|
|
|
|
|
|
|
|
context: context,
|
|
|
|
|
|
|
|
builder: (context) {
|
|
|
|
|
|
|
|
return Dialog(
|
|
|
|
|
|
|
|
elevation: 0.0,
|
|
|
|
|
|
|
|
insetPadding: const EdgeInsets.symmetric(horizontal: 40),
|
|
|
|
|
|
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
|
|
|
|
|
|
|
child: SizedBox(
|
|
|
|
|
|
|
|
height: options.length * 60,
|
|
|
|
|
|
|
|
child: Scrollbar(
|
|
|
|
|
|
|
|
child: ListView(
|
|
|
|
|
|
|
|
shrinkWrap: true,
|
|
|
|
|
|
|
|
scrollDirection: Axis.vertical,
|
|
|
|
|
|
|
|
children: ListTile.divideTiles(
|
|
|
|
|
|
|
|
context: context,
|
|
|
|
|
|
|
|
tiles: options,
|
|
|
|
|
|
|
|
).toList(),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Future<void> onPressMore() async {
|
|
|
|
// Future<void> onPressMore() async {
|
|
|
|
|