fix(videocall): apply PR review fixes and add i18n translations
- Replace setState with FutureBuilder in VideoViewWidget - Remove comments from datasource impl - Replace GetIt.I with ref.read(provider) in controllers - Fix state comparison using isTalking getter - Add hangUp/stopAudio/stopCamera cleanup on dispose - Remove duplicate SafeArea from IncomingCallOverlay - Add missedCall error event to enum - Replace Colors.white70 with theme colorScheme - Move VIDEOCALL_INTEGRATION.md to apps/mobile_app/docs/ - Gitignore config JSON files with app keys - Add 28 i18n keys in 6 locales for all videocall strings - Map error events to specific i18n messages
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -24,6 +24,9 @@
|
||||
*.iml
|
||||
.vscode/
|
||||
|
||||
# App config (contains API keys, passed via --dart-define-from-file)
|
||||
apps/mobile_app/config/*.json
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
**/.DS_Store
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"env": "development",
|
||||
"apiBaseUrl": "https://api-neki-b2b.neki.es/gateway/api/",
|
||||
"apiOrigin": "https://neki-b2b.neki.es",
|
||||
"wsUrl": "wss://api-neki-b2b.neki.es/websocket",
|
||||
"juphoonAppKey": "9efcf2d889dc8a0320925096"
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"env": "production",
|
||||
"apiBaseUrl": "https://api-platform.savefamily.app/gateway/api/",
|
||||
"apiOrigin": "https://platform.savefamily.app",
|
||||
"wsUrl": "wss://api-platform.savefamily.app/websocket",
|
||||
"juphoonAppKey": "9efcf2d889dc8a0320925096"
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
{
|
||||
"env": "staging",
|
||||
"apiBaseUrl": "https://api-platform.pre.savefamilygps.net/gateway/api/",
|
||||
"apiOrigin": "https://platform.pre.savefamilygps.net",
|
||||
"wsUrl": "wss://api-platform.pre.savefamilygps.net/websocket",
|
||||
"juphoonAppKey": "9efcf2d889dc8a0320925096"
|
||||
}
|
||||
@@ -13,15 +13,12 @@ class VideocallSignalingDatasourceImpl implements VideocallSignalingDatasource {
|
||||
required String appAccount,
|
||||
required String roomNumber,
|
||||
}) async {
|
||||
// TODO: Implement when backend API spec is available
|
||||
// await _repository.post('/devices/$deviceId/videocall/initiate', body: {...});
|
||||
throw UnimplementedError(
|
||||
'Backend signaling API not yet available. Waiting for endpoint spec.');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> cancelCall({required String deviceId}) async {
|
||||
// TODO: Implement when backend API spec is available
|
||||
throw UnimplementedError(
|
||||
'Backend signaling API not yet available. Waiting for endpoint spec.');
|
||||
}
|
||||
@@ -31,14 +28,12 @@ class VideocallSignalingDatasourceImpl implements VideocallSignalingDatasource {
|
||||
required String deviceId,
|
||||
required String roomNumber,
|
||||
}) async {
|
||||
// TODO: Implement when backend API spec is available
|
||||
throw UnimplementedError(
|
||||
'Backend signaling API not yet available. Waiting for endpoint spec.');
|
||||
}
|
||||
|
||||
@override
|
||||
Future<int> getRoomParticipantCount({required String roomNumber}) async {
|
||||
// TODO: Implement when backend API spec is available
|
||||
throw UnimplementedError(
|
||||
'Backend signaling API not yet available. Waiting for endpoint spec.');
|
||||
}
|
||||
@@ -49,7 +44,6 @@ class VideocallSignalingDatasourceImpl implements VideocallSignalingDatasource {
|
||||
required int count,
|
||||
required int type,
|
||||
}) async {
|
||||
// TODO: Implement when backend API spec is available
|
||||
throw UnimplementedError(
|
||||
'Backend signaling API not yet available. Waiting for endpoint spec.');
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ enum VideocallErrorEvent {
|
||||
authentication,
|
||||
callStart,
|
||||
callAnswer,
|
||||
missedCall,
|
||||
network,
|
||||
cameraPermission,
|
||||
microphonePermission,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:videocall_sdk/videocall_sdk.dart';
|
||||
|
||||
@@ -28,8 +27,8 @@ class GroupCallController extends _$GroupCallController {
|
||||
|
||||
@override
|
||||
GroupCallState build() {
|
||||
_channelService = GetIt.I<VideocallChannelService>();
|
||||
_deviceService = GetIt.I<VideocallDeviceService>();
|
||||
_channelService = ref.read(videocallChannelServiceProvider);
|
||||
_deviceService = ref.read(videocallDeviceServiceProvider);
|
||||
|
||||
ref.onDispose(_disposeSubscriptions);
|
||||
_subscribeToStreams();
|
||||
|
||||
@@ -42,7 +42,7 @@ final class GroupCallControllerProvider
|
||||
}
|
||||
|
||||
String _$groupCallControllerHash() =>
|
||||
r'c8528072cb1b6d2bb15d50b199405938e7d3acd0';
|
||||
r'0d3c5bd234ef3ed76b0b0f7666ddb73c8b98be55';
|
||||
|
||||
abstract class _$GroupCallController extends $Notifier<GroupCallState> {
|
||||
GroupCallState build();
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:get_it/get_it.dart';
|
||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
import 'package:videocall_sdk/videocall_sdk.dart' hide VideocallState;
|
||||
@@ -25,10 +24,10 @@ class VideocallController extends _$VideocallController {
|
||||
|
||||
@override
|
||||
VideocallState build() {
|
||||
_manager = GetIt.I<VideocallSdkManager>();
|
||||
_callService = GetIt.I<VideocallCallService>();
|
||||
_deviceService = GetIt.I<VideocallDeviceService>();
|
||||
_client = GetIt.I<VideocallClient>();
|
||||
_manager = ref.read(videocallManagerProvider);
|
||||
_callService = ref.read(videocallCallServiceProvider);
|
||||
_deviceService = ref.read(videocallDeviceServiceProvider);
|
||||
_client = ref.read(videocallClientProvider);
|
||||
|
||||
final device = ref.read(selectedDeviceProvider).value;
|
||||
final deviceId = device?.identificator ?? '';
|
||||
@@ -79,18 +78,17 @@ class VideocallController extends _$VideocallController {
|
||||
|
||||
void _subscribeToStreams() {
|
||||
_callAddSub = _callService.callItemAddStream.listen(_onCallItemAdd);
|
||||
_callUpdateSub =
|
||||
_callService.callItemUpdateStream.listen(_onCallItemUpdate);
|
||||
_callRemoveSub =
|
||||
_callService.callItemRemoveStream.listen(_onCallItemRemove);
|
||||
_callUpdateSub = _callService.callItemUpdateStream.listen(
|
||||
_onCallItemUpdate,
|
||||
);
|
||||
_callRemoveSub = _callService.callItemRemoveStream.listen(
|
||||
_onCallItemRemove,
|
||||
);
|
||||
_missedCallSub = _callService.missedCallStream.listen(_onMissedCall);
|
||||
_clientStateSub = _client.stateStream.listen(_onClientStateChange);
|
||||
}
|
||||
|
||||
Future<bool> login({
|
||||
required String userId,
|
||||
required String password,
|
||||
}) async {
|
||||
Future<bool> login({required String userId, required String password}) async {
|
||||
final ok = await _client.login(userId: userId, password: password);
|
||||
if (!ref.mounted) return false;
|
||||
if (!ok) {
|
||||
@@ -103,8 +101,9 @@ class VideocallController extends _$VideocallController {
|
||||
|
||||
Future<void> startCall(String remoteUserId) async {
|
||||
final device = ref.read(selectedDeviceProvider).value;
|
||||
final targetUserId =
|
||||
remoteUserId.isNotEmpty ? remoteUserId : 'w_${device?.imei ?? ''}';
|
||||
final targetUserId = remoteUserId.isNotEmpty
|
||||
? remoteUserId
|
||||
: 'w_${device?.imei ?? ''}';
|
||||
|
||||
state = state.copyWith(
|
||||
remoteUserId: targetUserId,
|
||||
@@ -252,7 +251,7 @@ class VideocallController extends _$VideocallController {
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(currentCall: item);
|
||||
|
||||
final isTalking = item.state.name == 'talking';
|
||||
final isTalking = item.isTalking;
|
||||
|
||||
if (isTalking && state.screenMode != VideocallScreenMode.inCall) {
|
||||
state = state.copyWith(
|
||||
@@ -293,9 +292,7 @@ class VideocallController extends _$VideocallController {
|
||||
|
||||
void _onMissedCall(VideocallItem item) {
|
||||
if (!ref.mounted) return;
|
||||
state = state.copyWith(
|
||||
errorEvent: VideocallErrorEvent.callStart,
|
||||
);
|
||||
state = state.copyWith(errorEvent: VideocallErrorEvent.missedCall);
|
||||
}
|
||||
|
||||
void _onClientStateChange(VideocallClientState clientState) {
|
||||
@@ -319,5 +316,10 @@ class VideocallController extends _$VideocallController {
|
||||
_callRemoveSub?.cancel();
|
||||
_missedCallSub?.cancel();
|
||||
_clientStateSub?.cancel();
|
||||
if (state.screenMode != VideocallScreenMode.idle) {
|
||||
_callService.hangUp();
|
||||
_deviceService.stopAudio();
|
||||
_deviceService.stopCamera();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ final class VideocallControllerProvider
|
||||
}
|
||||
|
||||
String _$videocallControllerHash() =>
|
||||
r'2fc967b9e44ca13586fd36e0d3eaab1014d52821';
|
||||
r'910674a27ecef98e5df917d193f97fca1c60ac02';
|
||||
|
||||
abstract class _$VideocallController extends $Notifier<VideocallState> {
|
||||
VideocallState build();
|
||||
|
||||
@@ -42,15 +42,14 @@ class _VideocallScreenState extends ConsumerState<VideocallScreen> {
|
||||
(_, next) {
|
||||
if (next == null) return;
|
||||
final key = switch (next) {
|
||||
VideocallErrorEvent.sdkInitialization ||
|
||||
VideocallErrorEvent.authentication ||
|
||||
VideocallErrorEvent.callStart ||
|
||||
VideocallErrorEvent.callAnswer ||
|
||||
VideocallErrorEvent.cameraPermission ||
|
||||
VideocallErrorEvent.microphonePermission ||
|
||||
VideocallErrorEvent.network ||
|
||||
VideocallErrorEvent.generic =>
|
||||
I18n.errorGeneric,
|
||||
VideocallErrorEvent.sdkInitialization => I18n.videocallErrorSdkInit,
|
||||
VideocallErrorEvent.authentication => I18n.videocallErrorAuth,
|
||||
VideocallErrorEvent.callStart => I18n.videocallErrorCallStart,
|
||||
VideocallErrorEvent.callAnswer => I18n.videocallErrorCallAnswer,
|
||||
VideocallErrorEvent.missedCall => I18n.videocallErrorMissedCall,
|
||||
VideocallErrorEvent.cameraPermission => I18n.videocallErrorCamera,
|
||||
VideocallErrorEvent.microphonePermission => I18n.videocallErrorMic,
|
||||
VideocallErrorEvent.network || VideocallErrorEvent.generic => I18n.errorGeneric,
|
||||
};
|
||||
showErrorDialog(context, key);
|
||||
vm.clearError();
|
||||
@@ -109,7 +108,7 @@ class _IdleView extends StatelessWidget {
|
||||
CircularProgressIndicator(color: colorScheme.onSurface),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Inicializando SDK...',
|
||||
context.translate(I18n.videocallInitializingSdk),
|
||||
style: TextStyle(color: colorScheme.onSurface.withValues(alpha: 0.7)),
|
||||
),
|
||||
],
|
||||
@@ -125,7 +124,7 @@ class _IdleView extends StatelessWidget {
|
||||
Icon(Icons.videocam, color: colorScheme.onSurface, size: 64),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
'Videollamada',
|
||||
context.translate(I18n.videocallTitle),
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurface,
|
||||
fontSize: 24,
|
||||
@@ -137,7 +136,7 @@ class _IdleView extends StatelessWidget {
|
||||
controller: controller,
|
||||
style: TextStyle(color: colorScheme.onSurface),
|
||||
decoration: InputDecoration(
|
||||
hintText: 'User ID del destinatario',
|
||||
hintText: context.translate(I18n.videocallRecipientUserId),
|
||||
hintStyle: TextStyle(color: colorScheme.onSurface.withValues(alpha: 0.38)),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(color: colorScheme.onSurface.withValues(alpha: 0.24)),
|
||||
@@ -162,7 +161,7 @@ class _IdleView extends StatelessWidget {
|
||||
vm.startCall(userId);
|
||||
},
|
||||
icon: const Icon(Icons.videocam),
|
||||
label: const Text('Iniciar videollamada'),
|
||||
label: Text(context.translate(I18n.videocallStart)),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: context.sfColors.legacyPrimary,
|
||||
foregroundColor: colorScheme.onPrimary,
|
||||
@@ -185,7 +184,7 @@ class _IdleView extends StatelessWidget {
|
||||
),
|
||||
if (state.localUserId.isNotEmpty)
|
||||
Text(
|
||||
'Logged in as: ${state.localUserId}',
|
||||
context.translate(I18n.videocallLoggedInAs, args: {'userId': state.localUserId}),
|
||||
style: TextStyle(color: colorScheme.onSurface.withValues(alpha: 0.38), fontSize: 12),
|
||||
),
|
||||
],
|
||||
@@ -252,7 +251,7 @@ class _InCallView extends StatelessWidget {
|
||||
Icon(Icons.person, color: colorScheme.onSurface.withValues(alpha: 0.24), size: 96),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'Esperando video remoto...',
|
||||
context.translate(I18n.videocallWaitingRemoteVideo),
|
||||
style: TextStyle(color: colorScheme.onSurface.withValues(alpha: 0.38)),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
class CallControlsWidget extends StatelessWidget {
|
||||
const CallControlsWidget({
|
||||
@@ -29,7 +30,7 @@ class CallControlsWidget extends StatelessWidget {
|
||||
children: [
|
||||
_ControlButton(
|
||||
icon: isMicEnabled ? Icons.mic : Icons.mic_off,
|
||||
label: isMicEnabled ? 'Mic On' : 'Mic Off',
|
||||
label: context.translate(isMicEnabled ? I18n.videocallMicOn : I18n.videocallMicOff),
|
||||
isActive: isMicEnabled,
|
||||
onPressed: onToggleMic,
|
||||
),
|
||||
@@ -37,19 +38,19 @@ class CallControlsWidget extends StatelessWidget {
|
||||
icon: isSpeakerEnabled
|
||||
? Icons.volume_up
|
||||
: Icons.volume_off,
|
||||
label: isSpeakerEnabled ? 'Speaker' : 'Earpiece',
|
||||
label: context.translate(isSpeakerEnabled ? I18n.videocallSpeaker : I18n.videocallEarpiece),
|
||||
isActive: isSpeakerEnabled,
|
||||
onPressed: onToggleSpeaker,
|
||||
),
|
||||
_ControlButton(
|
||||
icon: Icons.cameraswitch,
|
||||
label: isFrontCamera ? 'Front' : 'Back',
|
||||
label: context.translate(isFrontCamera ? I18n.videocallCameraFront : I18n.videocallCameraBack),
|
||||
isActive: true,
|
||||
onPressed: onSwitchCamera,
|
||||
),
|
||||
_ControlButton(
|
||||
icon: Icons.call_end,
|
||||
label: 'Hang Up',
|
||||
label: context.translate(I18n.videocallHangUp),
|
||||
isActive: false,
|
||||
isDestructive: true,
|
||||
onPressed: onHangUp,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
import '../../domain/entities/videocall_error.dart';
|
||||
|
||||
@@ -17,8 +18,8 @@ class CallStatusIndicator extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final (text, showCancel) = switch (screenMode) {
|
||||
VideocallScreenMode.outgoing => ('Llamando a $remoteUserId...', true),
|
||||
VideocallScreenMode.incoming => ('$remoteUserId te está llamando', false),
|
||||
VideocallScreenMode.outgoing => (context.translate(I18n.videocallCalling, args: {'userId': remoteUserId}), true),
|
||||
VideocallScreenMode.incoming => (context.translate(I18n.videocallUserCalling, args: {'userId': remoteUserId}), false),
|
||||
_ => ('', false),
|
||||
};
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
class IncomingCallOverlay extends StatelessWidget {
|
||||
const IncomingCallOverlay({
|
||||
@@ -20,56 +21,54 @@ class IncomingCallOverlay extends StatelessWidget {
|
||||
|
||||
return Container(
|
||||
color: colorScheme.surface,
|
||||
child: SafeArea(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Spacer(),
|
||||
Icon(
|
||||
isVideo ? Icons.videocam : Icons.call,
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
const Spacer(),
|
||||
Icon(
|
||||
isVideo ? Icons.videocam : Icons.call,
|
||||
color: colorScheme.onSurface,
|
||||
size: 64,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
context.translate(isVideo ? I18n.videocallIncomingVideo : I18n.videocallIncomingAudio),
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurface.withValues(alpha: 0.7),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
callerUserId,
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurface,
|
||||
size: 64,
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
const SizedBox(height: 24),
|
||||
Text(
|
||||
isVideo ? 'Videollamada entrante' : 'Llamada entrante',
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurface.withValues(alpha: 0.7),
|
||||
fontSize: 16,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 64),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
_ActionButton(
|
||||
icon: Icons.call_end,
|
||||
color: colorScheme.error,
|
||||
label: context.translate(I18n.videocallReject),
|
||||
onPressed: onReject,
|
||||
),
|
||||
_ActionButton(
|
||||
icon: isVideo ? Icons.videocam : Icons.call,
|
||||
color: Colors.green,
|
||||
label: context.translate(I18n.videocallAccept),
|
||||
onPressed: onAccept,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
callerUserId,
|
||||
style: TextStyle(
|
||||
color: colorScheme.onSurface,
|
||||
fontSize: 28,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
const Spacer(),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(bottom: 64),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
_ActionButton(
|
||||
icon: Icons.call_end,
|
||||
color: colorScheme.error,
|
||||
label: 'Rechazar',
|
||||
onPressed: onReject,
|
||||
),
|
||||
_ActionButton(
|
||||
icon: isVideo ? Icons.videocam : Icons.call,
|
||||
color: Colors.green,
|
||||
label: 'Aceptar',
|
||||
onPressed: onAccept,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
import '../../domain/entities/videocall_participant.dart';
|
||||
import 'participant_tile_widget.dart';
|
||||
@@ -14,10 +15,12 @@ class ParticipantGridWidget extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (participants.isEmpty) {
|
||||
return const Center(
|
||||
return Center(
|
||||
child: Text(
|
||||
'Esperando participantes...',
|
||||
style: TextStyle(color: Colors.white70),
|
||||
context.translate(I18n.videocallWaitingParticipants),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurface.withValues(alpha: 0.7),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
|
||||
import '../../domain/entities/videocall_participant.dart';
|
||||
import 'video_view_widget.dart';
|
||||
@@ -52,7 +53,7 @@ class ParticipantTileWidget extends StatelessWidget {
|
||||
child: Icon(Icons.mic_off, color: colorScheme.error, size: 14),
|
||||
),
|
||||
Text(
|
||||
participant.isSelf ? 'Tú' : participant.userId,
|
||||
participant.isSelf ? context.translate(I18n.videocallYou) : participant.userId,
|
||||
style: TextStyle(color: colorScheme.onSurface, fontSize: 12),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -3,7 +3,7 @@ import 'dart:io';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:videocall_sdk/videocall_sdk.dart';
|
||||
|
||||
class VideoViewWidget extends StatefulWidget {
|
||||
class VideoViewWidget extends StatelessWidget {
|
||||
const VideoViewWidget({
|
||||
super.key,
|
||||
required this.canvas,
|
||||
@@ -17,52 +17,27 @@ class VideoViewWidget extends StatefulWidget {
|
||||
final double height;
|
||||
final BoxFit fit;
|
||||
|
||||
@override
|
||||
State<VideoViewWidget> createState() => _VideoViewWidgetState();
|
||||
}
|
||||
|
||||
class _VideoViewWidgetState extends State<VideoViewWidget> {
|
||||
Widget? _videoWidget;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_initVideoView();
|
||||
}
|
||||
|
||||
@override
|
||||
void didUpdateWidget(VideoViewWidget oldWidget) {
|
||||
super.didUpdateWidget(oldWidget);
|
||||
if (oldWidget.canvas.videoCanvasId != widget.canvas.videoCanvasId) {
|
||||
_initVideoView();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _initVideoView() async {
|
||||
final Widget videoWidget;
|
||||
Future<Widget> _buildVideoView() {
|
||||
if (Platform.isIOS) {
|
||||
videoWidget = await widget.canvas.getIOSVideoView(
|
||||
(viewId) {},
|
||||
widget.width,
|
||||
widget.height,
|
||||
);
|
||||
} else {
|
||||
videoWidget = await widget.canvas.getAndroidVideoView();
|
||||
}
|
||||
if (mounted) {
|
||||
setState(() => _videoWidget = videoWidget);
|
||||
return canvas.getIOSVideoView((_) {}, width, height);
|
||||
}
|
||||
return canvas.getAndroidVideoView();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
width: widget.width,
|
||||
height: widget.height,
|
||||
child: _videoWidget ??
|
||||
const Center(
|
||||
width: width,
|
||||
height: height,
|
||||
child: FutureBuilder<Widget>(
|
||||
future: _buildVideoView(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.hasData) return snapshot.data!;
|
||||
return const Center(
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,6 +683,34 @@
|
||||
"locationRevealSkip": "Überspringen",
|
||||
"locationDeleteGeofenceConfirm": "Möchten Sie diese sichere Zone wirklich löschen?",
|
||||
"locationDeleteFrequentPlaceConfirm": "Möchten Sie diesen häufigen Ort wirklich löschen?",
|
||||
"videocallTitle": "Videoanruf",
|
||||
"videocallInitializingSdk": "SDK wird initialisiert...",
|
||||
"videocallRecipientUserId": "Benutzer-ID des Empfängers",
|
||||
"videocallStart": "Videoanruf starten",
|
||||
"videocallLoggedInAs": "Angemeldet als: {userId}",
|
||||
"videocallCalling": "{userId} wird angerufen...",
|
||||
"videocallUserCalling": "{userId} ruft dich an",
|
||||
"videocallIncomingVideo": "Eingehender Videoanruf",
|
||||
"videocallIncomingAudio": "Eingehender Anruf",
|
||||
"videocallReject": "Ablehnen",
|
||||
"videocallAccept": "Annehmen",
|
||||
"videocallMicOn": "Mikro an",
|
||||
"videocallMicOff": "Mikro aus",
|
||||
"videocallSpeaker": "Lautsprecher",
|
||||
"videocallEarpiece": "Hörer",
|
||||
"videocallCameraFront": "Vorne",
|
||||
"videocallCameraBack": "Hinten",
|
||||
"videocallHangUp": "Auflegen",
|
||||
"videocallWaitingParticipants": "Warten auf Teilnehmer...",
|
||||
"videocallWaitingRemoteVideo": "Warten auf Remote-Video...",
|
||||
"videocallYou": "Du",
|
||||
"videocallErrorSdkInit": "Fehler beim Initialisieren des Videoanrufs",
|
||||
"videocallErrorAuth": "Authentifizierungsfehler beim Videoanruf",
|
||||
"videocallErrorCallStart": "Fehler beim Starten des Anrufs",
|
||||
"videocallErrorCallAnswer": "Fehler beim Annehmen des Anrufs",
|
||||
"videocallErrorCamera": "Kameraberechtigung erforderlich",
|
||||
"videocallErrorMic": "Mikrofonberechtigung erforderlich",
|
||||
"videocallErrorMissedCall": "Verpasster Anruf",
|
||||
"positionUpdated": "Letzte verfügbare Position aktualisiert",
|
||||
"locationMapStyleLight": "Hell",
|
||||
"locationMapStyleDark": "Dunkel",
|
||||
@@ -757,7 +785,7 @@
|
||||
"frequentPlaceCreated": "Häufiger Ort erstellt",
|
||||
"frequentPlaceUpdated": "Häufiger Ort aktualisiert",
|
||||
"frequentPlaceDeleted": "Häufiger Ort gelöscht",
|
||||
"errorGeneric": "Etwas ist schiefgelaufen. Bitte versuchen Sie es erneut.",
|
||||
"errorGeneric": "Ein unerwarteter Fehler ist aufgetreten.",
|
||||
"pullDownToRetry": "Zum Wiederholen nach unten ziehen",
|
||||
"errorGeofenceCreate": "Die Sicherheitszone konnte nicht erstellt werden",
|
||||
"errorGeofenceUpdate": "Die Sicherheitszone konnte nicht aktualisiert werden",
|
||||
@@ -1060,6 +1088,5 @@
|
||||
"errorSessionExpired": "Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.",
|
||||
"errorValidation": "Die eingegebenen Daten sind ungültig.",
|
||||
"errorScaRequired": "Eine zusätzliche Authentifizierung ist erforderlich.",
|
||||
"errorDeviceNotOwned": "Du hast keine Berechtigung, auf dieses Gerät zuzugreifen.",
|
||||
"errorGeneric": "Ein unerwarteter Fehler ist aufgetreten."
|
||||
"errorDeviceNotOwned": "Du hast keine Berechtigung, auf dieses Gerät zuzugreifen."
|
||||
}
|
||||
|
||||
@@ -863,6 +863,34 @@
|
||||
"locationRevealSkip": "Skip",
|
||||
"locationDeleteGeofenceConfirm": "Are you sure you want to delete this safe zone?",
|
||||
"locationDeleteFrequentPlaceConfirm": "Are you sure you want to delete this frequent place?",
|
||||
"videocallTitle": "Video Call",
|
||||
"videocallInitializingSdk": "Initializing SDK...",
|
||||
"videocallRecipientUserId": "Recipient User ID",
|
||||
"videocallStart": "Start video call",
|
||||
"videocallLoggedInAs": "Logged in as: {userId}",
|
||||
"videocallCalling": "Calling {userId}...",
|
||||
"videocallUserCalling": "{userId} is calling you",
|
||||
"videocallIncomingVideo": "Incoming video call",
|
||||
"videocallIncomingAudio": "Incoming call",
|
||||
"videocallReject": "Reject",
|
||||
"videocallAccept": "Accept",
|
||||
"videocallMicOn": "Mic On",
|
||||
"videocallMicOff": "Mic Off",
|
||||
"videocallSpeaker": "Speaker",
|
||||
"videocallEarpiece": "Earpiece",
|
||||
"videocallCameraFront": "Front",
|
||||
"videocallCameraBack": "Back",
|
||||
"videocallHangUp": "Hang Up",
|
||||
"videocallWaitingParticipants": "Waiting for participants...",
|
||||
"videocallWaitingRemoteVideo": "Waiting for remote video...",
|
||||
"videocallYou": "You",
|
||||
"videocallErrorSdkInit": "Error initializing video call",
|
||||
"videocallErrorAuth": "Video call authentication error",
|
||||
"videocallErrorCallStart": "Error starting the call",
|
||||
"videocallErrorCallAnswer": "Error answering the call",
|
||||
"videocallErrorCamera": "Camera permission required",
|
||||
"videocallErrorMic": "Microphone permission required",
|
||||
"videocallErrorMissedCall": "Missed call",
|
||||
"positionUpdated": "Updated to latest available position",
|
||||
"locationMapStyleLight": "Light",
|
||||
"locationMapStyleDark": "Dark",
|
||||
@@ -931,7 +959,7 @@
|
||||
"frequentPlaceCreated": "Frequent place created",
|
||||
"frequentPlaceUpdated": "Frequent place updated",
|
||||
"frequentPlaceDeleted": "Frequent place deleted",
|
||||
"errorGeneric": "Something went wrong. Please try again.",
|
||||
"errorGeneric": "An unexpected error occurred.",
|
||||
"pullDownToRetry": "Pull down to retry",
|
||||
"errorGeofenceCreate": "Could not create the safety zone",
|
||||
"errorGeofenceUpdate": "Could not update the safety zone",
|
||||
@@ -1060,6 +1088,5 @@
|
||||
"errorSessionExpired": "Your session has expired. Please sign in again.",
|
||||
"errorValidation": "The information you entered is not valid.",
|
||||
"errorScaRequired": "Additional authentication is required to continue.",
|
||||
"errorDeviceNotOwned": "You don't have permission to access this device.",
|
||||
"errorGeneric": "An unexpected error occurred."
|
||||
"errorDeviceNotOwned": "You don't have permission to access this device."
|
||||
}
|
||||
|
||||
@@ -864,6 +864,34 @@
|
||||
"locationRevealSkip": "Saltar",
|
||||
"locationDeleteGeofenceConfirm": "¿Seguro que quieres eliminar esta zona segura?",
|
||||
"locationDeleteFrequentPlaceConfirm": "¿Seguro que quieres eliminar este lugar frecuente?",
|
||||
"videocallTitle": "Videollamada",
|
||||
"videocallInitializingSdk": "Inicializando SDK...",
|
||||
"videocallRecipientUserId": "User ID del destinatario",
|
||||
"videocallStart": "Iniciar videollamada",
|
||||
"videocallLoggedInAs": "Conectado como: {userId}",
|
||||
"videocallCalling": "Llamando a {userId}...",
|
||||
"videocallUserCalling": "{userId} te está llamando",
|
||||
"videocallIncomingVideo": "Videollamada entrante",
|
||||
"videocallIncomingAudio": "Llamada entrante",
|
||||
"videocallReject": "Rechazar",
|
||||
"videocallAccept": "Aceptar",
|
||||
"videocallMicOn": "Mic On",
|
||||
"videocallMicOff": "Mic Off",
|
||||
"videocallSpeaker": "Altavoz",
|
||||
"videocallEarpiece": "Auricular",
|
||||
"videocallCameraFront": "Frontal",
|
||||
"videocallCameraBack": "Trasera",
|
||||
"videocallHangUp": "Colgar",
|
||||
"videocallWaitingParticipants": "Esperando participantes...",
|
||||
"videocallWaitingRemoteVideo": "Esperando video remoto...",
|
||||
"videocallYou": "Tú",
|
||||
"videocallErrorSdkInit": "Error al inicializar videollamada",
|
||||
"videocallErrorAuth": "Error de autenticación de videollamada",
|
||||
"videocallErrorCallStart": "Error al iniciar la llamada",
|
||||
"videocallErrorCallAnswer": "Error al contestar la llamada",
|
||||
"videocallErrorCamera": "Se requiere permiso de cámara",
|
||||
"videocallErrorMic": "Se requiere permiso de micrófono",
|
||||
"videocallErrorMissedCall": "Llamada perdida",
|
||||
"positionUpdated": "Última posición disponible actualizada",
|
||||
"locationMapStyleLight": "Claro",
|
||||
"locationMapStyleDark": "Oscuro",
|
||||
@@ -932,7 +960,7 @@
|
||||
"frequentPlaceCreated": "Lugar frecuente creado",
|
||||
"frequentPlaceUpdated": "Lugar frecuente actualizado",
|
||||
"frequentPlaceDeleted": "Lugar frecuente eliminado",
|
||||
"errorGeneric": "Algo salió mal. Inténtalo de nuevo.",
|
||||
"errorGeneric": "Ha ocurrido un error inesperado.",
|
||||
"pullDownToRetry": "Desliza hacia abajo para reintentar",
|
||||
"errorGeofenceCreate": "No se pudo crear la zona de seguridad",
|
||||
"errorGeofenceUpdate": "No se pudo actualizar la zona de seguridad",
|
||||
@@ -1060,6 +1088,5 @@
|
||||
"errorSessionExpired": "Tu sesión ha caducado. Vuelve a iniciar sesión.",
|
||||
"errorValidation": "Los datos introducidos no son válidos.",
|
||||
"errorScaRequired": "Se requiere autenticación adicional para continuar.",
|
||||
"errorDeviceNotOwned": "No tienes permiso para acceder a este dispositivo.",
|
||||
"errorGeneric": "Ha ocurrido un error inesperado."
|
||||
"errorDeviceNotOwned": "No tienes permiso para acceder a este dispositivo."
|
||||
}
|
||||
|
||||
@@ -683,6 +683,34 @@
|
||||
"locationRevealSkip": "Passer",
|
||||
"locationDeleteGeofenceConfirm": "Voulez-vous supprimer cette zone sûre ?",
|
||||
"locationDeleteFrequentPlaceConfirm": "Voulez-vous supprimer ce lieu fréquent ?",
|
||||
"videocallTitle": "Appel vidéo",
|
||||
"videocallInitializingSdk": "Initialisation du SDK...",
|
||||
"videocallRecipientUserId": "ID utilisateur du destinataire",
|
||||
"videocallStart": "Démarrer l'appel vidéo",
|
||||
"videocallLoggedInAs": "Connecté en tant que : {userId}",
|
||||
"videocallCalling": "Appel de {userId}...",
|
||||
"videocallUserCalling": "{userId} vous appelle",
|
||||
"videocallIncomingVideo": "Appel vidéo entrant",
|
||||
"videocallIncomingAudio": "Appel entrant",
|
||||
"videocallReject": "Rejeter",
|
||||
"videocallAccept": "Accepter",
|
||||
"videocallMicOn": "Micro activé",
|
||||
"videocallMicOff": "Micro désactivé",
|
||||
"videocallSpeaker": "Haut-parleur",
|
||||
"videocallEarpiece": "Écouteur",
|
||||
"videocallCameraFront": "Avant",
|
||||
"videocallCameraBack": "Arrière",
|
||||
"videocallHangUp": "Raccrocher",
|
||||
"videocallWaitingParticipants": "En attente de participants...",
|
||||
"videocallWaitingRemoteVideo": "En attente de la vidéo distante...",
|
||||
"videocallYou": "Vous",
|
||||
"videocallErrorSdkInit": "Erreur d'initialisation de l'appel vidéo",
|
||||
"videocallErrorAuth": "Erreur d'authentification de l'appel vidéo",
|
||||
"videocallErrorCallStart": "Erreur lors du démarrage de l'appel",
|
||||
"videocallErrorCallAnswer": "Erreur lors de la réponse à l'appel",
|
||||
"videocallErrorCamera": "Autorisation de la caméra requise",
|
||||
"videocallErrorMic": "Autorisation du microphone requise",
|
||||
"videocallErrorMissedCall": "Appel manqué",
|
||||
"positionUpdated": "Dernière position disponible mise à jour",
|
||||
"locationMapStyleLight": "Clair",
|
||||
"locationMapStyleDark": "Sombre",
|
||||
@@ -757,7 +785,7 @@
|
||||
"frequentPlaceCreated": "Lieu fréquent créé",
|
||||
"frequentPlaceUpdated": "Lieu fréquent mis à jour",
|
||||
"frequentPlaceDeleted": "Lieu fréquent supprimé",
|
||||
"errorGeneric": "Une erreur est survenue. Veuillez réessayer.",
|
||||
"errorGeneric": "Une erreur inattendue s'est produite.",
|
||||
"pullDownToRetry": "Tirez vers le bas pour réessayer",
|
||||
"errorGeofenceCreate": "Impossible de créer la zone de sécurité",
|
||||
"errorGeofenceUpdate": "Impossible de mettre à jour la zone de sécurité",
|
||||
@@ -1060,6 +1088,5 @@
|
||||
"errorSessionExpired": "Votre session a expiré. Veuillez vous reconnecter.",
|
||||
"errorValidation": "Les données saisies ne sont pas valides.",
|
||||
"errorScaRequired": "Une authentification supplémentaire est requise pour continuer.",
|
||||
"errorDeviceNotOwned": "Vous n'avez pas l'autorisation d'accéder à cet appareil.",
|
||||
"errorGeneric": "Une erreur inattendue s'est produite."
|
||||
"errorDeviceNotOwned": "Vous n'avez pas l'autorisation d'accéder à cet appareil."
|
||||
}
|
||||
|
||||
@@ -683,6 +683,34 @@
|
||||
"locationRevealSkip": "Salta",
|
||||
"locationDeleteGeofenceConfirm": "Sei sicuro di voler eliminare questa zona sicura?",
|
||||
"locationDeleteFrequentPlaceConfirm": "Sei sicuro di voler eliminare questo luogo frequente?",
|
||||
"videocallTitle": "Videochiamata",
|
||||
"videocallInitializingSdk": "Inizializzazione SDK...",
|
||||
"videocallRecipientUserId": "ID utente del destinatario",
|
||||
"videocallStart": "Avvia videochiamata",
|
||||
"videocallLoggedInAs": "Connesso come: {userId}",
|
||||
"videocallCalling": "Chiamata a {userId}...",
|
||||
"videocallUserCalling": "{userId} ti sta chiamando",
|
||||
"videocallIncomingVideo": "Videochiamata in arrivo",
|
||||
"videocallIncomingAudio": "Chiamata in arrivo",
|
||||
"videocallReject": "Rifiuta",
|
||||
"videocallAccept": "Accetta",
|
||||
"videocallMicOn": "Micro attivo",
|
||||
"videocallMicOff": "Micro disattivato",
|
||||
"videocallSpeaker": "Altoparlante",
|
||||
"videocallEarpiece": "Auricolare",
|
||||
"videocallCameraFront": "Anteriore",
|
||||
"videocallCameraBack": "Posteriore",
|
||||
"videocallHangUp": "Riaggancia",
|
||||
"videocallWaitingParticipants": "In attesa di partecipanti...",
|
||||
"videocallWaitingRemoteVideo": "In attesa del video remoto...",
|
||||
"videocallYou": "Tu",
|
||||
"videocallErrorSdkInit": "Errore nell'inizializzazione della videochiamata",
|
||||
"videocallErrorAuth": "Errore di autenticazione della videochiamata",
|
||||
"videocallErrorCallStart": "Errore nell'avvio della chiamata",
|
||||
"videocallErrorCallAnswer": "Errore nel rispondere alla chiamata",
|
||||
"videocallErrorCamera": "Permesso fotocamera richiesto",
|
||||
"videocallErrorMic": "Permesso microfono richiesto",
|
||||
"videocallErrorMissedCall": "Chiamata persa",
|
||||
"positionUpdated": "Ultima posizione disponibile aggiornata",
|
||||
"locationMapStyleLight": "Chiaro",
|
||||
"locationMapStyleDark": "Scuro",
|
||||
@@ -757,7 +785,7 @@
|
||||
"frequentPlaceCreated": "Luogo frequente creato",
|
||||
"frequentPlaceUpdated": "Luogo frequente aggiornato",
|
||||
"frequentPlaceDeleted": "Luogo frequente eliminato",
|
||||
"errorGeneric": "Qualcosa è andato storto. Riprova.",
|
||||
"errorGeneric": "Si è verificato un errore imprevisto.",
|
||||
"pullDownToRetry": "Trascina verso il basso per riprovare",
|
||||
"errorGeofenceCreate": "Impossibile creare la zona di sicurezza",
|
||||
"errorGeofenceUpdate": "Impossibile aggiornare la zona di sicurezza",
|
||||
@@ -1060,6 +1088,5 @@
|
||||
"errorSessionExpired": "La tua sessione è scaduta. Accedi di nuovo.",
|
||||
"errorValidation": "I dati inseriti non sono validi.",
|
||||
"errorScaRequired": "È richiesta un'autenticazione aggiuntiva per continuare.",
|
||||
"errorDeviceNotOwned": "Non hai il permesso di accedere a questo dispositivo.",
|
||||
"errorGeneric": "Si è verificato un errore imprevisto."
|
||||
"errorDeviceNotOwned": "Non hai il permesso di accedere a questo dispositivo."
|
||||
}
|
||||
|
||||
@@ -683,6 +683,34 @@
|
||||
"locationRevealSkip": "Saltar",
|
||||
"locationDeleteGeofenceConfirm": "Tens a certeza que queres eliminar esta zona segura?",
|
||||
"locationDeleteFrequentPlaceConfirm": "Tens a certeza que queres eliminar este lugar frequente?",
|
||||
"videocallTitle": "Videochamada",
|
||||
"videocallInitializingSdk": "A inicializar SDK...",
|
||||
"videocallRecipientUserId": "ID do utilizador destinatário",
|
||||
"videocallStart": "Iniciar videochamada",
|
||||
"videocallLoggedInAs": "Conectado como: {userId}",
|
||||
"videocallCalling": "A ligar para {userId}...",
|
||||
"videocallUserCalling": "{userId} está a ligar-te",
|
||||
"videocallIncomingVideo": "Videochamada recebida",
|
||||
"videocallIncomingAudio": "Chamada recebida",
|
||||
"videocallReject": "Rejeitar",
|
||||
"videocallAccept": "Aceitar",
|
||||
"videocallMicOn": "Micro ligado",
|
||||
"videocallMicOff": "Micro desligado",
|
||||
"videocallSpeaker": "Altifalante",
|
||||
"videocallEarpiece": "Auricular",
|
||||
"videocallCameraFront": "Frontal",
|
||||
"videocallCameraBack": "Traseira",
|
||||
"videocallHangUp": "Desligar",
|
||||
"videocallWaitingParticipants": "A aguardar participantes...",
|
||||
"videocallWaitingRemoteVideo": "A aguardar vídeo remoto...",
|
||||
"videocallYou": "Tu",
|
||||
"videocallErrorSdkInit": "Erro ao inicializar videochamada",
|
||||
"videocallErrorAuth": "Erro de autenticação da videochamada",
|
||||
"videocallErrorCallStart": "Erro ao iniciar a chamada",
|
||||
"videocallErrorCallAnswer": "Erro ao atender a chamada",
|
||||
"videocallErrorCamera": "Permissão de câmara necessária",
|
||||
"videocallErrorMic": "Permissão de microfone necessária",
|
||||
"videocallErrorMissedCall": "Chamada perdida",
|
||||
"positionUpdated": "Última posição disponível atualizada",
|
||||
"locationMapStyleLight": "Claro",
|
||||
"locationMapStyleDark": "Escuro",
|
||||
@@ -757,7 +785,7 @@
|
||||
"frequentPlaceCreated": "Local frequente criado",
|
||||
"frequentPlaceUpdated": "Local frequente atualizado",
|
||||
"frequentPlaceDeleted": "Local frequente eliminado",
|
||||
"errorGeneric": "Algo correu mal. Tente novamente.",
|
||||
"errorGeneric": "Ocorreu um erro inesperado.",
|
||||
"pullDownToRetry": "Deslize para baixo para tentar novamente",
|
||||
"errorGeofenceCreate": "Não foi possível criar a zona de segurança",
|
||||
"errorGeofenceUpdate": "Não foi possível atualizar a zona de segurança",
|
||||
@@ -1060,6 +1088,5 @@
|
||||
"errorSessionExpired": "A tua sessão expirou. Inicia sessão novamente.",
|
||||
"errorValidation": "Os dados introduzidos não são válidos.",
|
||||
"errorScaRequired": "É necessária autenticação adicional para continuar.",
|
||||
"errorDeviceNotOwned": "Não tens permissão para aceder a este dispositivo.",
|
||||
"errorGeneric": "Ocorreu um erro inesperado."
|
||||
"errorDeviceNotOwned": "Não tens permissão para aceder a este dispositivo."
|
||||
}
|
||||
|
||||
@@ -1006,6 +1006,34 @@ class I18n {
|
||||
static const String verifyAccount = 'verifyAccount';
|
||||
static const String vibrationOnly = 'vibrationOnly';
|
||||
static const String videoCall = 'videoCall';
|
||||
static const String videocallAccept = 'videocallAccept';
|
||||
static const String videocallCalling = 'videocallCalling';
|
||||
static const String videocallCameraBack = 'videocallCameraBack';
|
||||
static const String videocallCameraFront = 'videocallCameraFront';
|
||||
static const String videocallEarpiece = 'videocallEarpiece';
|
||||
static const String videocallErrorAuth = 'videocallErrorAuth';
|
||||
static const String videocallErrorCallAnswer = 'videocallErrorCallAnswer';
|
||||
static const String videocallErrorCallStart = 'videocallErrorCallStart';
|
||||
static const String videocallErrorCamera = 'videocallErrorCamera';
|
||||
static const String videocallErrorMic = 'videocallErrorMic';
|
||||
static const String videocallErrorMissedCall = 'videocallErrorMissedCall';
|
||||
static const String videocallErrorSdkInit = 'videocallErrorSdkInit';
|
||||
static const String videocallHangUp = 'videocallHangUp';
|
||||
static const String videocallIncomingAudio = 'videocallIncomingAudio';
|
||||
static const String videocallIncomingVideo = 'videocallIncomingVideo';
|
||||
static const String videocallInitializingSdk = 'videocallInitializingSdk';
|
||||
static const String videocallLoggedInAs = 'videocallLoggedInAs';
|
||||
static const String videocallMicOff = 'videocallMicOff';
|
||||
static const String videocallMicOn = 'videocallMicOn';
|
||||
static const String videocallRecipientUserId = 'videocallRecipientUserId';
|
||||
static const String videocallReject = 'videocallReject';
|
||||
static const String videocallSpeaker = 'videocallSpeaker';
|
||||
static const String videocallStart = 'videocallStart';
|
||||
static const String videocallTitle = 'videocallTitle';
|
||||
static const String videocallUserCalling = 'videocallUserCalling';
|
||||
static const String videocallWaitingParticipants = 'videocallWaitingParticipants';
|
||||
static const String videocallWaitingRemoteVideo = 'videocallWaitingRemoteVideo';
|
||||
static const String videocallYou = 'videocallYou';
|
||||
static const String volumeAlarm = 'volumeAlarm';
|
||||
static const String volumeControl = 'volumeControl';
|
||||
static const String volumeHint = 'volumeHint';
|
||||
|
||||
@@ -18,6 +18,8 @@ class VideocallItem {
|
||||
final bool uploadVideoStreamSelf;
|
||||
final bool uploadVideoStreamOther;
|
||||
|
||||
bool get isTalking => state == VideocallState.talking;
|
||||
|
||||
VideocallItem copyWith({
|
||||
String? userId,
|
||||
bool? isVideo,
|
||||
|
||||
Reference in New Issue
Block a user