ZEGOCLOUD / zego_uikit_prebuilt_call_flutter

MIT License
16 stars 13 forks source link

Custom layout and call control buttons do not work #42

Closed yokawaiik closed 3 months ago

yokawaiik commented 4 months ago

Hi again!

I've been researching the package for several days and still have questions about customization. Perhaps I understand something wrong or what I expect is not what it should be.

I will be glad if you can help me solve the problems. Thank you in advance.

Environment

Technology Version
Flutter version 3.19.5
Plugin version zego_uikit_prebuilt_call: 4.9.0, zego_uikit_signaling_plugin: 2.7.6
Android version API 34
iOS version Not tested
macOS version Not tested
Xcode version Not tested
Google Chrome version Not tested

Device information:

Description

I call from a custom widget that displays uiConfig: ZegoCallInvitationUIConfig(.... callingBackgroundBuilder the following handlers to control the call:

await ZegoUIKitPrebuiltCallInvitationService().accept();
await ZegoUIKitPrebuiltCallInvitationService().cancel(
        callees: calleeUserList,
      );
await ZegoUIKitPrebuiltCallInvitationService().reject();

Expected behavior: The call can be cancelled, accepted, rejected

Current behavior: Nothing happens. It appears in the logs, but in reality, nothing happens in the UI, and the call continues to go on.

Steps to reproduce

  1. I use a service from which I call methods

  2. Created this page (just a widget), which is displayed via callingBackgroundBuilder

    VideocallLobbyWidget (i wanted to use it for incoming/outgoing screen)

import '/backend/backend.dart';
import '/backend/schema/enums/enums.dart';
import '/flutter_flow/flutter_flow_icon_button.dart';
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/global_widgets/widgets/loader/loader_widget.dart';
import '/global_widgets/widgets/network_cached_image/network_cached_image_widget.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:provider/provider.dart';

import 'videocall_lobby_model.dart';
export 'videocall_lobby_model.dart';

class VideocallLobbyWidget extends StatefulWidget {
  const VideocallLobbyWidget({
    super.key,
    this.userRef,
    required this.isIncomingCall,
  });

  final DocumentReference? userRef;

  final bool isIncomingCall;

  @override
  State<VideocallLobbyWidget> createState() => _VideocallLobbyWidgetState();
}

class _VideocallLobbyWidgetState extends State<VideocallLobbyWidget> {
  late final VideocallLobbyModel _model;

  @override
  void setState(VoidCallback callback) {
    super.setState(callback);
    _model.onUpdate();
  }

  @override
  void initState() {
    _model = createModel(context, () => VideocallLobbyModel());
    super.initState();
  }

  @override
  void dispose() {
    _model.maybeDispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    final ctx =
        _model.videocallsService.globalCallNavigatorKey.currentState!.context;

    return Container(
      child: Container(
        width: double.infinity,
        height: double.infinity,
        decoration: BoxDecoration(
          color: FlutterFlowTheme.of(ctx).primaryBackground,
        ),
        child: Column(
          mainAxisSize: MainAxisSize.max,
          children: [
            Expanded(
              child: Stack(
                children: [
                  FutureBuilder<UsersRecord>(
                    future: UsersRecord.getDocumentOnce(widget.userRef!),
                    builder: (context, snapshot) {
                      // Customize what your widget looks like when it's loading.
                      if (!snapshot.hasData) {
                        return Center(
                          child: Container(
                            width: double.infinity,
                            height: double.infinity,
                            child: const LoaderWidget(),
                          ),
                        );
                      }
                      final networkCachedImageUsersRecord = snapshot.data!;
                      return wrapWithModel(
                        model: _model.networkCachedImageModel,
                        updateCallback: () => setState(() {}),
                        child: NetworkCachedImageWidget(
                          imagePathUrl: networkCachedImageUsersRecord
                              .imageMapList.first.imagePath,
                          icon: Icon(
                            FFIcons.kuser,
                            color: FlutterFlowTheme.of(context).greyShades60,
                            size: 256,
                          ),
                          blurHash: networkCachedImageUsersRecord
                              .imageMapList.first.blurHash,
                          boxFit: AppBoxFit.bf_cover,
                        ),
                      );
                    },
                  ),
                  Align(
                    alignment: const AlignmentDirectional(0, 1),
                    child: Padding(
                      padding:
                          const EdgeInsetsDirectional.fromSTEB(16, 0, 16, 16),
                      child: Container(
                        key: const ValueKey('info'),
                        decoration: BoxDecoration(
                          color: FlutterFlowTheme.of(ctx).main40,
                          borderRadius: BorderRadius.circular(32),
                        ),
                        child: Padding(
                          padding: const EdgeInsetsDirectional.fromSTEB(
                              16, 8, 16, 8),
                          child: Text(
                            valueOrDefault<String>(
                              widget.isIncomingCall
                                  ? valueOrDefault<String>(
                                      FFLocalizations.of(ctx).getVariableText(
                                        enText: 'Incoming call',
                                        ruText: 'Входящий вызов',
                                      ),
                                      'Incoming call',
                                    )
                                  : valueOrDefault<String>(
                                      FFLocalizations.of(ctx).getVariableText(
                                        enText: 'Outgoing call',
                                        ruText: 'Исходящий вызов',
                                      ),
                                      'Outgoing call',
                                    ),
                              'Incoming call',
                            ),
                            style: FlutterFlowTheme.of(ctx).bodyMedium.override(
                                  fontFamily: 'Open Sans',
                                  color: FlutterFlowTheme.of(ctx).absoluteWhite,
                                  fontSize: 17,
                                  letterSpacing: 0,
                                  fontWeight: FontWeight.normal,
                                ),
                          ),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            Container(
              height: 140,
              decoration: BoxDecoration(
                color: FlutterFlowTheme.of(context).primaryBackground,
              ),
              child: Row(
                mainAxisSize: MainAxisSize.max,
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  FlutterFlowIconButton(
                    key: const ValueKey('declineButton'),
                    borderColor: FlutterFlowTheme.of(context).alertRed,
                    borderRadius: 100,
                    buttonSize: 64,
                    fillColor: FlutterFlowTheme.of(context).alertRed,
                    icon: Icon(
                      FFIcons.kphonedisconnect,
                      color: FlutterFlowTheme.of(context).primaryText,
                      size: 24,
                    ),
                    onPressed: () async {
                      try {
                        debugPrint("-- VideocallsService -- declineCall");
                        if (widget.isIncomingCall) {
                          _model.videocallsService.rejectCall();
                        } else {
                          _model.videocallsService.cancelCall();
                        }
                      } catch (e) {
                        debugPrint(
                            "-- VideocallsService -- declineCall - error: $e");
                      }
                    },
                  ),
                  if (widget.isIncomingCall)
                    FlutterFlowIconButton(
                      key: const ValueKey('acceptButton'),
                      borderColor: FlutterFlowTheme.of(context).alertGreen,
                      borderRadius: 100,
                      buttonSize: 64,
                      fillColor: FlutterFlowTheme.of(context).alertGreen,
                      icon: Icon(
                        FFIcons.kphonecall,
                        color: FlutterFlowTheme.of(context).primaryText,
                        size: 24,
                      ),
                      onPressed: () async {
                        await _model.videocallsService.acceptCall();
                      },
                    ),
                ].divide(const SizedBox(width: 32)),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

  1. The package is connected with a call invitation

Stacktrace/Logcat

Details

```log {log} {init} {==========================================Logs Configuration added.} {06/05/2024 19:36:28} {INFO} {adapter} {system service} {init system service} {06/05/2024 19:36:28} {INFO} {call} {call invitation service(226049318)} {versions: zego_uikit_prebuilt_call:4.9.0; zego_uikit: 2.22.2; zego_express:3.13.2.37365} {06/05/2024 19:36:29} {INFO} {call} {call invitation service(226049318)} {service init} {06/05/2024 19:36:29} {INFO} {call} {call invitation service(762550654)} {init private, appID:686496317, userID:zGNGK6TftCdQZgFJ4EX9NkM54sf2, userName:Unnamed user, plugins:[IZegoUIKitPlugin:{type:ZegoUIKitPluginType.signaling, version:Instance of 'Future', }], ringtoneConfig:null, config:null, uiConfig:ZegoCallInvitationUIConfig:{prebuiltWithSafeArea:false, declineButton:ZegoCallButtonUIConfig:{visible:true, icon:Icon(IconData(U+0E806), size: 24.0, color: Color(0xffffffff)), }, acceptButton:ZegoCallButtonUIConfig:{visible:true, icon:Icon(IconData(U+0E804), size: 24.0, color: Color(0xffffffff)), }, cancelButton:ZegoCallButtonUIConfig:{visible:true, icon:Icon(IconData(U+0E806), size: 24.0, color: Color(0xffffffff)), }, callingBackgroundBuilder:null, }, notificationConfig:null, } {06/05/2024 19:36:29} {INFO} {call} {call invitation service(762550654)} {Cancel The flutterCallkitIncomingStreamSubscription or not:(null)} {06/05/2024 19:36:29} {INFO} {call} {call invitation service(762550654)} {Close The lookupIsolate or not, needClose:true, hash(436800204), isMainIsolatePort:false} {06/05/2024 19:36:29} {INFO} {call} {call invitation service(762550654)} {isolate: register, _backgroundPort(651036123), _backgroundPort!.sendPort(967700351)} {06/05/2024 19:36:29} {INFO} {call} {call invitation service(762550654)} {isolate: register offline call isolate name server, port:651036123} {06/05/2024 19:36:29} {INFO} {adapter} {system service} {register message handler:911530612} {06/05/2024 19:36:29} {INFO} {call} {call invitation service(762550654)} {update contextQuery in call invitation config} {06/05/2024 19:36:29} {INFO} {call} {notification manager} {init} {06/05/2024 19:36:29} {INFO} {call} {notification manager} {request notification permission result:true} {06/05/2024 19:36:30} {INFO} {call} {notification manager} {request system alert window permission result:true} {06/05/2024 19:36:30} {INFO} {signaling} {channel} {createNotificationChannel:sound source:null, vibrate:true, channel id:CallInvitation, channel name:Call Invitation} {06/05/2024 19:36:30} {INFO} {signaling} {channel} {createNotificationChannel:sound source:null, vibrate:false, channel id:Message, channel name:Message} {06/05/2024 19:36:30} {INFO} {signaling} {channel} {dismissAllNotifications} {06/05/2024 19:36:30} {INFO} {call} {machine} {init} {06/05/2024 19:36:30} {INFO} {call} {machine} {calling machine to be idle} {06/05/2024 19:36:30} {INFO} {call} {machine} {calling, from null to State[CallingState.kIdle]} {06/05/2024 19:36:30} {INFO} {call} {ringtone} {init: prefix:packages/zego_uikit_prebuilt_call/, source path:assets/invitation/audio/outgoing.mp3} {06/05/2024 19:36:30} {INFO} {call} {ringtone} {init: prefix:packages/zego_uikit_prebuilt_call/, source path:assets/invitation/audio/incoming.mp3} {06/05/2024 19:36:30} {INFO} {call} {overlay machine} {init} {06/05/2024 19:36:30} {INFO} {call} {overlay machine} {add listener:Closure: (ZegoCallMiniOverlayPageState) => void from Function 'onMiniOverlayMachineStateChanged':., size:1} {06/05/2024 19:36:30} {INFO} {call} {page manager} {init, appID:686496317, userID:zGNGK6TftCdQZgFJ4EX9NkM54sf2, userName: Unnamed user} {06/05/2024 19:36:30} {INFO} {call} {internal instance} {register, pageManager:Instance of 'ZegoCallInvitationPageManager', callInvitationData:Instance of 'ZegoUIKitPrebuiltCallInvitationData'} {06/05/2024 19:36:30} {INFO} {call} {controller.invitation.p} {init by prebuilt} {06/05/2024 19:36:30} {INFO} {call} {callkit service} {callkit service init} {06/05/2024 19:36:30} {INFO} {call} {callkit internal instance} {register, pageManager:Instance of 'ZegoCallInvitationPageManager'} {06/05/2024 19:36:30} {INFO} {call} {callkit service} {offline callkit call id: null} {06/05/2024 19:36:30} {INFO} {call} {callkit} {clear all callKit calls} {06/05/2024 19:36:30} {INFO} {call} {callkit service} {set callkit variables:{CallKitInnerVariable.callIDVisibility: true, CallKitInnerVariable.showFullScreen: false, CallKitInnerVariable.ringtonePath: null, CallKitInnerVariable.backgroundUrl: }} {06/05/2024 19:36:30} {INFO} {call} {callkit service} {register callkit incoming event listener} {06/05/2024 19:36:30} {INFO} {call} {call invitation service(762550654)} {init plugins} {06/05/2024 19:36:30} {INFO} {call} {plugin} {plugins init} {06/05/2024 19:36:30} {INFO} {uikit} {user attributes} {user in-room init} {06/05/2024 19:36:30} {INFO} {log} {init} {==========================================Logs Configuration added.} {06/05/2024 19:36:30} {INFO} {signaling} {init} {create ZIM} {06/05/2024 19:36:30} {INFO} {uikit} {signaling core data} {create, appID:686496317} {06/05/2024 19:36:30} {INFO} {call} {call invitation service(762550654)} {try enable notification, iOSNotificationConfig:null, enableIOSVoIP:false } {06/05/2024 19:36:30} {INFO} {call} {call invitation service} {setPreferenceString, key:handler_info, value:{"aid":"686496317","uid":"zGNGK6TftCdQZgFJ4EX9NkM54sf2","un":"Unnamed user","isse":null,"eiv":false,"ci":1,"an":"","aci":"CallInvitation","acn":"Call Invitation","ai":"","as":"","av":true,"amci":"Message","amcn":"Message","ams":"","ami":"","amv":false}.} {06/05/2024 19:36:30} {INFO} {uikit} {signaling notification data} {enable notify when app is in the background or quit: true} {06/05/2024 19:36:30} {INFO} {signaling} {notification} {enable Notify When App Running In Background Or Quit, is iOS Sandbox Environment:null, enable iOS VoIP:false, certificate index:ZegoSignalingPluginMultiCertificate.firstCertificate, appName: , androidChannelID: CallInvitation, androidChannelName: Call Invitation, androidSound: } {06/05/2024 19:36:30} {INFO} {call} {plugin} {plugins init done, login...} {06/05/2024 19:36:30} {INFO} {uikit} {signaling core data} {login request, user id:zGNGK6TftCdQZgFJ4EX9NkM54sf2, user name:Unnamed user} {06/05/2024 19:36:30} {INFO} {uikit} {signaling core data} {ready to login.} {06/05/2024 19:36:30} {INFO} {signaling} {user} {connectUser, id:zGNGK6TftCdQZgFJ4EX9NkM54sf2, name:Unnamed user} {06/05/2024 19:36:30} {INFO} {call} {plugin} {plugin-ZegoUIKitPluginType.signaling version: zego_uikit_signaling_plugin: 2.7.6; zim:2.13.1.2279; zpns:2.6.0;} {06/05/2024 19:36:30} {INFO} {signaling} {notification} {register push done} {06/05/2024 19:36:30} {INFO} {call} {call invitation service(762550654)} {enable notification result: {error: null}} {06/05/2024 19:36:30} {INFO} {signaling} {event center} {onRegistered, registerMessage: { pushID:rwABAQYCAwCjVVMxLjBmOFZxOHJwalJNV3ltVXgzQndCZWs2OkFQQTkxYkdzS3JlYlZ1dDVmWkw5eG5YUkVjM1Y0T3BxUEhMMjJPZWtHbTUtRkg4endMX2JFaThncGpsbDlObEZRRjdNMnpNcWUzd3ZHdmxabHdORnRuTW1vWk40ZkZXTkFsc1Y0OUNBSDdoSGxuTnlsNHRlbWpXeWl5WFZEaGxxclFlNmtkUEFWVzhEAAIQAQ==, errorCode:0, pushSourceType:ZPNsPushSourceType.FCM, errorMessage:, commandResult:rwABAQYCAwCjVVMxLjBmOFZxOHJwalJNV3ltVXgzQndCZWs2OkFQQTkxYkdzS3JlYlZ1dDVmWkw5eG5YUkVjM1Y0T3BxUEhMMjJPZWtHbTUtRkg4endMX2JFaThncGpsbDlObEZRRjdNMnpNcWUzd3ZHdmxabHdORnRuTW1vWk40ZkZXTkFsc1Y0OUNBSDdoSGxuTnlsNHRlbWpXeWl5WFZEaGxxclFlNmtkUEFWVzhEAAIQAQ== }} {06/05/2024 19:36:30} {INFO} {uikit} {signaling core data} {notification registered, {pushID: rwABAQYCAwCjVVMxLjBmOFZxOHJwalJNV3ltVXgzQndCZWs2OkFQQTkxYkdzS3JlYlZ1dDVmWkw5eG5YUkVjM1Y0T3BxUEhMMjJPZWtHbTUtRkg4endMX2JFaThncGpsbDlObEZRRjdNMnpNcWUzd3ZHdmxabHdORnRuTW1vWk40ZkZXTkFsc1Y0OUNBSDdoSGxuTnlsNHRlbWpXeWl5WFZEaGxxclFlNmtkUEFWVzhEAAIQAQ==, code: 0}} {06/05/2024 19:36:30} {INFO} {signaling} {event center} {onConnectionStateChanged, state:ZIMConnectionState.connecting, event:ZIMConnectionEvent.activeLogin, extendedData:{}} {06/05/2024 19:36:30} {INFO} {call} {plugin} {[call invitation] onInvitationConnectionState, {state: ZegoSignalingPluginConnectionState.connecting, action: ZegoSignalingPluginConnectionAction.activeLogin, extendedData: {}}} {06/05/2024 19:36:30} {INFO} {uikit} {signaling core data} {connection state changed, {state: ZegoSignalingPluginConnectionState.connecting, action: ZegoSignalingPluginConnectionAction.activeLogin, extendedData: {}}} {06/05/2024 19:36:30} {INFO} {signaling} {event center} {onConnectionStateChanged, state:ZIMConnectionState.connected, event:ZIMConnectionEvent.activeLogin, extendedData:{}} {06/05/2024 19:36:30} {INFO} {call} {plugin} {[call invitation] onInvitationConnectionState, {state: ZegoSignalingPluginConnectionState.connected, action: ZegoSignalingPluginConnectionAction.activeLogin, extendedData: {}}} {06/05/2024 19:36:30} {INFO} {uikit} {signaling core data} {connection state changed, {state: ZegoSignalingPluginConnectionState.connected, action: ZegoSignalingPluginConnectionAction.activeLogin, extendedData: {}}} {06/05/2024 19:36:30} {INFO} {signaling} {user} {connectUser success.} {06/05/2024 19:36:30} {INFO} {uikit} {signaling core data} {login success} {06/05/2024 19:36:30} {INFO} {call} {plugin} {plugins login done} {06/05/2024 19:36:30} {INFO} {call} {call invitation service} {setPreferenceString, key:call_app_sign, value:6a75572f1e345596fa2424c655b735c62482821cb40fe35dd6bec63fd336e3d2.} {06/05/2024 19:36:30} {INFO} {call} {plugin} {plugins init done} {06/05/2024 19:36:30} {INFO} {call} {call invitation service(762550654)} {plugin init finished} {06/05/2024 19:36:30} {INFO} {call} {page manager} {listen stream} {06/05/2024 19:36:30} {INFO} {call} {page manager} {remove stream} {06/05/2024 19:36:30} {INFO} {call} {call invitation service} {init permissions} {06/05/2024 19:36:30} {INFO} {call} {call invitation service(762550654)} {offline callkit param: null} {06/05/2024 19:36:30} {INFO} {call} {call invitation service} {init context} {06/05/2024 19:36:30} {INFO} {uikit} {core data} {login, id:"zGNGK6TftCdQZgFJ4EX9NkM54sf2", name:Unnamed user} {06/05/2024 19:36:30} {INFO} {uikit} {core} {init, appID:686496317, enablePlatformView:null, scenario:ZegoScenario.Default, } {06/05/2024 19:36:30} {INFO} {uikit core} {event} {init} {06/05/2024 19:36:30} {INFO} {uikit core} {event.media} {init} {06/05/2024 19:36:30} {INFO} {} {core data} {init error module} {06/05/2024 19:36:30} {INFO} {uikit} {core} {init event handle} {06/05/2024 19:36:30} {INFO} {uikit core} {event.express} {register, 253256764} {06/05/2024 19:36:30} {INFO} {uikit core} {event.express} {register, 845679775} {06/05/2024 19:36:30} {INFO} {uikit core} {event.express} {register, 916815219} {06/05/2024 19:36:30} {INFO} {uikit core} {event.media} {register, 377315218} {06/05/2024 19:36:30} {INFO} {uikit} {core} {create engine with profile} {06/05/2024 19:36:31} {INFO} {uikit} {core} {engine created} {06/05/2024 19:36:31} {INFO} {uikit} {core} {get network time info} {06/05/2024 19:36:31} {INFO} {uikit} {core} {network time info is init, timestamp:1715024192117, max deviation:111} {06/05/2024 19:36:31} {INFO} {uikit} {core} {turn off zGNGK6TftCdQZgFJ4EX9NkM54sf2 camera} {06/05/2024 19:36:31} {INFO} {uikit} {core} {turn off local camera} {06/05/2024 19:36:31} {INFO} {uikit} {core data} {stop preview} {06/05/2024 19:36:31} {INFO} {uikit} {core data} {startPublishOrNot room id is empty} {06/05/2024 19:36:31} {ERROR} {uikit} {core data} {local user has not publish stream, send sei will be failed} {06/05/2024 19:36:31} {ERROR} ```

So, i have the following issues:

  1. Is it possible with this package to add my own custom layout for outgoing (when another user doesn't accept a call) and incoming screen?

  2. Is it possible to use programmatically controll a call? Like what I showed above.

  3. Is it possible to remove the display of a round avatar and text from the outgoing and incoming call page (it seems that this is on top of the markup) and is it even possible to make your own markup with clickable buttons?

Circled avatars (i would like to remove it)

![Screenshot 2024-05-07 025534](https://github.com/ZEGOCLOUD/zego_uikit_prebuilt_call_flutter/assets/48886721/011226af-bb71-407b-9082-e8944b9f6694) ![Screenshot 2024-05-07 025840](https://github.com/ZEGOCLOUD/zego_uikit_prebuilt_call_flutter/assets/48886721/8f9c116e-6179-45a9-8902-04c18aa58f7c)

yokawaiik commented 3 months ago

This issues has any solution?

yoer commented 3 months ago
  1. not support yet, but it's easy to support.

  2. totally support,after call init of ZegoUIKitPrebuiltCallInvitationService ,you can use

    1. send
    2. cancel
    3. reject
    4. accept
  3. not support yet, but it's easy to support.

yokawaiik commented 3 months ago

@yoer, thanks for the answer!

Is support expected?

yoer commented 3 months ago

it's not on the plan, but i will support in next week

yokawaiik commented 3 months ago

@yoer thanks a lot!

I'll be waiting for it with impatience!

yoer commented 3 months ago

support in v4.10.0

yoer commented 3 months ago

now you can totally custom by foreground or callingPageBuilder

yoer commented 3 months ago

ZegoCallInvitationUIConfig image