addVideosGrid function

Future<void> addVideosGrid(
  1. AddVideosGridOptions options
)

Adds video and audio streams of participants to the main and alternate grids based on specified options.

This function manages the layout and styling of participant video, audio, and mini-cards in the main and alternate grids, with customizations based on event type, background, and layout settings. It dynamically updates the UI by adding or removing components in real-time, handling both the main and alternate grids.

  • The function creates VideoCard widgets for participants with active video streams and AudioCard widgets for participants with audio streams but without video.
  • For participants who don’t have active audio or video, a MiniCard is generated, displaying participant initials.

This function is typically called when the user joins or leaves the room, changes display settings, or new streams become available.

Parameters:

  • options: AddVideosGridOptions containing layout details like the number of rows and columns, lists of main and alternate grid streams, flags for removing alternate grids, and other stream-related parameters.

Example:

await addVideosGrid(AddVideosGridOptions(
  mainGridStreams: [/* main stream participants */],
  altGridStreams: [/* alternate stream participants */],
  numRows: 2,
  numCols: 2,
  actualRows: 2,
  lastRowCols: 1,
  removeAltGrid: true,
  parameters: gridParams,
));

Implementation

Future<void> addVideosGrid(AddVideosGridOptions options) async {
  try {
    // Retrieve updated parameters
    AddVideosGridParameters parameters =
        options.parameters.getUpdatedAllParams();

    // Extract all necessary properties from parameters
    final eventType = parameters.eventType;
    final updateAddAltGrid = parameters.updateAddAltGrid;
    List<Participant> refParticipants = List.from(parameters.refParticipants);
    final islevel = parameters.islevel;
    final videoAlreadyOn = parameters.videoAlreadyOn;
    final localStreamVideo = parameters.localStreamVideo;
    final keepBackground = parameters.keepBackground;
    final virtualStream = parameters.virtualStream;
    final forceFullDisplay = parameters.forceFullDisplay;
    final member = parameters.member;
    List<List<Widget>> otherGridStreams =
        List.from(parameters.otherGridStreams);
    final updateOtherGridStreams = parameters.updateOtherGridStreams;
    final updateMiniCardsGrid = parameters.updateMiniCardsGrid;

    // Extract custom component builders
    final customVideoCard = parameters.customVideoCard;
    final customAudioCard = parameters.customAudioCard;
    final customMiniCard = parameters.customMiniCard;

    // Initialize new components
    List<List<Widget>> newComponents = [[], []];
    Stream participant;
    String remoteProducerId = "";

    // Update number to add based on mainGridStreams length
    int numToAdd = options.mainGridStreams.length;

    if (options.removeAltGrid) {
      updateAddAltGrid(false);
    }

    // Add participants to the main grid
    for (int i = 0; i < numToAdd; i++) {
      participant = options.mainGridStreams[i];
      remoteProducerId = participant.producerId;

      bool pseudoName = remoteProducerId.isEmpty;

      if (pseudoName) {
        remoteProducerId = participant.name ?? '';

        if (participant.audioID != null && participant.audioID!.isNotEmpty) {
          final actualParticipant = refParticipants.firstWhere(
            (obj) => obj.audioID == participant.audioID,
            orElse: () =>
                Participant(id: '', name: '', videoID: '', audioID: ''),
          );

          // Use custom AudioCard builder if available
          if (customAudioCard != null) {
            newComponents[0].add(customAudioCard(
              name: participant.name ?? "",
              barColor: true, // This maps to the red color
              textColor: Colors.white,
              imageSource: "", // You may need to add actual image source
              roundedImage: 1.0,
              imageStyle: Colors.transparent,
              parameters: parameters,
            ));
          } else {
            newComponents[0].add(AudioCard(
                options: AudioCardOptions(
              name: participant.name ?? "",
              barColor: Colors.red,
              textColor: Colors.white,
              customStyle: BoxDecoration(
                color: Colors.transparent,
                border: Border.all(
                  color: eventType != EventType.broadcast
                      ? Colors.black
                      : Colors.transparent,
                  width: eventType != EventType.broadcast ? 2.0 : 0.0,
                ),
              ),
              controlsPosition: 'topLeft',
              infoPosition: 'topRight',
              roundedImage: true,
              parameters: parameters,
              backgroundColor: Colors.transparent,
              showControls: eventType != EventType.chat,
              participant: actualParticipant,
            )));
          }
        } else {
          // Use custom MiniCard builder if available
          if (customMiniCard != null) {
            newComponents[0].add(customMiniCard(
              initials: participant.name ?? "",
              fontSize: "20",
              customStyle: false,
              name: participant.name ?? "",
              showVideoIcon: false,
              showAudioIcon: false,
              imageSource: "",
              roundedImage: 1.0,
              imageStyle: Colors.transparent,
              parameters: parameters,
            ));
          } else {
            newComponents[0].add(
              MiniCard(
                  options: MiniCardOptions(
                initials: participant.name ?? "",
                fontSize: 20,
                customStyle: BoxDecoration(
                  color: Colors.transparent,
                  border: Border.all(
                    color: eventType != EventType.broadcast
                        ? Colors.black
                        : Colors.transparent,
                    width: eventType != EventType.broadcast ? 2.0 : 0.0,
                  ),
                ),
              )),
            );
          }
        }
      } else {
        if (remoteProducerId == 'youyou' || remoteProducerId == 'youyouyou') {
          String name = 'You';
          if (islevel == '2' && eventType != EventType.chat) {
            name = 'You (Host)';
          }

          if (!videoAlreadyOn) {
            // Use custom MiniCard builder if available
            if (customMiniCard != null) {
              newComponents[0].add(customMiniCard(
                initials: name,
                fontSize: "20",
                customStyle: false,
                name: name,
                showVideoIcon: false,
                showAudioIcon: false,
                imageSource: "",
                roundedImage: 1.0,
                imageStyle: Colors.transparent,
                parameters: parameters,
              ));
            } else {
              newComponents[0].add(
                MiniCard(
                    options: MiniCardOptions(
                  initials: name,
                  fontSize: 20,
                  customStyle: BoxDecoration(
                    color: Colors.transparent,
                    border: Border.all(
                      color: eventType != EventType.broadcast
                          ? Colors.black
                          : Colors.transparent,
                      width: eventType != EventType.broadcast ? 2.0 : 0.0,
                    ),
                  ),
                )),
              );
            }
          } else {
            participant = Stream(
              id: 'youyouyou',
              stream: keepBackground && virtualStream != null
                  ? virtualStream
                  : localStreamVideo,
              name: 'youyouyou',
              producerId: 'youyouyou',
            );

            final actualParticipant = refParticipants.firstWhere(
              (obj) => obj.name == member,
              orElse: () =>
                  Participant(id: '', name: '', videoID: '', audioID: ''),
            );

            // Use custom VideoCard builder if available
            if (customVideoCard != null) {
              newComponents[0].add(customVideoCard(
                participant: actualParticipant,
                stream: participant,
                width: 100.0, // You may need to calculate actual width
                height: 100.0, // You may need to calculate actual height
                imageSize: null,
                doMirror: "true",
                showControls: false,
                showInfo: false,
                name: participant.name ?? '',
                backgroundColor: Colors.transparent,
                onVideoPress: null,
                parameters: parameters,
              ));
            } else {
              newComponents[0].add(
                VideoCard(
                    options: VideoCardOptions(
                  videoStream: participant.stream,
                  remoteProducerId: participant.stream?.id ?? '',
                  eventType: eventType,
                  forceFullDisplay:
                      eventType == EventType.webinar ? false : forceFullDisplay,
                  participant: actualParticipant,
                  backgroundColor: Colors.transparent,
                  showControls: false,
                  showInfo: false,
                  name: participant.name ?? '',
                  doMirror: true,
                  parameters: parameters,
                )),
              );
            }
          }
        } else {
          Participant? participant_ = refParticipants.firstWhere(
            (obj) => obj.videoID == remoteProducerId,
            orElse: () =>
                Participant(id: '', name: '', videoID: '', audioID: ''),
          );

          if (participant_.name.isNotEmpty) {
            // Use custom VideoCard builder if available
            if (customVideoCard != null) {
              newComponents[0].add(customVideoCard(
                participant: participant_,
                stream: participant,
                width: 100.0, // You may need to calculate actual width
                height: 100.0, // You may need to calculate actual height
                imageSize: null,
                doMirror: "false",
                showControls: eventType != EventType.chat,
                showInfo: true,
                name: participant_.name,
                backgroundColor: Colors.transparent,
                onVideoPress: null,
                parameters: parameters,
              ));
            } else {
              newComponents[0].add(VideoCard(
                options: VideoCardOptions(
                  videoStream: participant.stream,
                  remoteProducerId: remoteProducerId,
                  eventType: eventType,
                  forceFullDisplay: forceFullDisplay,
                  participant: participant_,
                  backgroundColor: Colors.transparent,
                  showControls: eventType != EventType.chat,
                  showInfo: true,
                  name: participant_.name,
                  doMirror: false,
                  parameters: parameters,
                ),
              ));
            }
          }
        }
      }

      // Update grids at the end of the loop
      if (i == numToAdd - 1) {
        otherGridStreams[0] = List<Widget>.from(newComponents[0]);
        final optionsUpdate = UpdateMiniCardsGridOptions(
            rows: options.numRows,
            cols: options.numCols,
            defal: true,
            actualRows: options.actualRows,
            parameters: parameters);
        await updateMiniCardsGrid(
          optionsUpdate,
        );
        updateOtherGridStreams(otherGridStreams);
        await updateMiniCardsGrid(
          optionsUpdate,
        );
      }
    }

    // Handle the alternate grid streams
    if (!options.removeAltGrid) {
      for (int i = 0; i < options.altGridStreams.length; i++) {
        participant = options.altGridStreams[i];
        remoteProducerId = participant.producerId;

        bool pseudoName = remoteProducerId.isEmpty;

        if (pseudoName) {
          remoteProducerId = participant.name ?? '';

          if (participant.audioID != null && participant.audioID!.isNotEmpty) {
            final actualParticipant = refParticipants.firstWhere(
              (obj) => obj.audioID == participant.audioID,
              orElse: () =>
                  Participant(id: '', name: '', videoID: '', audioID: ''),
            );

            // Use custom AudioCard builder if available
            if (customAudioCard != null) {
              newComponents[1].add(customAudioCard(
                name: participant.name ?? "",
                barColor: true, // This maps to the red color
                textColor: Colors.white,
                imageSource: "", // You may need to add actual image source
                roundedImage: 1.0,
                imageStyle: Colors.transparent,
                parameters: parameters,
              ));
            } else {
              newComponents[1].add(
                AudioCard(
                    options: AudioCardOptions(
                  name: participant.name ?? "",
                  barColor: Colors.red,
                  textColor: Colors.white,
                  customStyle: BoxDecoration(
                    color: Colors.transparent,
                    border: Border.all(
                      color: eventType != EventType.broadcast
                          ? Colors.black
                          : Colors.transparent,
                      width: eventType != EventType.broadcast ? 2.0 : 0.0,
                    ),
                  ),
                  controlsPosition: 'topLeft',
                  infoPosition: 'topRight',
                  roundedImage: true,
                  parameters: parameters,
                  backgroundColor: Colors.transparent,
                  showControls: eventType != EventType.chat,
                  participant: actualParticipant,
                )),
              );
            }
          } else {
            // Use custom MiniCard builder if available
            if (customMiniCard != null) {
              newComponents[1].add(customMiniCard(
                initials: participant.name ?? "",
                fontSize: "20",
                customStyle: false,
                name: participant.name ?? "",
                showVideoIcon: false,
                showAudioIcon: false,
                imageSource: "",
                roundedImage: 1.0,
                imageStyle: Colors.transparent,
                parameters: parameters,
              ));
            } else {
              newComponents[1].add(
                MiniCard(
                    options: MiniCardOptions(
                  initials: participant.name ?? "",
                  fontSize: 20,
                  customStyle: BoxDecoration(
                    color: Colors.transparent,
                    border: Border.all(
                      color: eventType != EventType.broadcast
                          ? Colors.black
                          : Colors.transparent,
                      width: eventType != EventType.broadcast ? 2.0 : 0.0,
                    ),
                  ),
                )),
              );
            }
          }
        } else {
          Participant? participant_ = refParticipants.firstWhere(
            (obj) => obj.videoID == remoteProducerId,
            orElse: () =>
                Participant(id: '', name: '', videoID: '', audioID: ''),
          );

          if (participant_.name.isNotEmpty) {
            // Use custom VideoCard builder if available
            if (customVideoCard != null) {
              newComponents[1].add(customVideoCard(
                participant: participant_,
                stream: participant,
                width: 100.0, // You may need to calculate actual width
                height: 100.0, // You may need to calculate actual height
                imageSize: null,
                doMirror: "false",
                showControls: eventType != EventType.chat,
                showInfo: true,
                name: participant_.name,
                backgroundColor: Colors.transparent,
                onVideoPress: null,
                parameters: parameters,
              ));
            } else {
              newComponents[1].add(
                VideoCard(
                    options: VideoCardOptions(
                  videoStream: participant.stream,
                  remoteProducerId: remoteProducerId,
                  eventType: eventType,
                  forceFullDisplay: forceFullDisplay,
                  participant: participant_,
                  backgroundColor: Colors.transparent,
                  showControls: eventType != EventType.chat,
                  showInfo: true,
                  name: participant_.name,
                  doMirror: false,
                  parameters: parameters,
                )),
              );
            }
          }
        }

        // Update alternate grid at the end of the loop
        if (i == options.altGridStreams.length - 1) {
          otherGridStreams[1] = List<Widget>.from(newComponents[1]);

          final optionsUpdate = UpdateMiniCardsGridOptions(
              rows: options.numRows,
              cols: options.numCols,
              defal: false,
              actualRows: options.actualRows,
              parameters: parameters);

          await updateMiniCardsGrid(
            optionsUpdate,
          );
          updateOtherGridStreams(otherGridStreams);
          await updateMiniCardsGrid(
            optionsUpdate,
          );
        }
      }
    } else {
      // Remove alternate grid
      parameters.updateAddAltGrid(false);
      otherGridStreams[1] = <Widget>[]; // Clear the alternate grid

      final optionsUpdate = UpdateMiniCardsGridOptions(
          rows: 0,
          cols: 0,
          defal: false,
          actualRows: options.actualRows,
          parameters: parameters);
      await updateMiniCardsGrid(
        optionsUpdate,
      );
      updateOtherGridStreams(otherGridStreams);
      await updateMiniCardsGrid(
        optionsUpdate,
      );
    }
  } catch (error) {
    if (kDebugMode) {
      print('Error in addVideosGrid: $error');
    }
  }
}