diff --git a/.gitignore b/.gitignore
index 0c8565dec..0c4dd3865 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,36 +1,56 @@
-sample apps/hms-callkit-app/.dart_tool/flutter_build/
-.dart_tool/package_config.json
-.dart_tool/package_config_subset
-.dart_tool/version
-android/.gradle/6.8.3/gc.properties
-android/.gradle/6.8.3/fileChanges/last-build.bin
-android/.gradle/6.8.3/fileHashes/fileHashes.lock
-android/.gradle/buildOutputCleanup/buildOutputCleanup.lock
-android/.gradle/buildOutputCleanup/cache.properties
-android/.gradle/checksums/checksums.lock
-android/.gradle/checksums/sha1-checksums.bin
-android/.gradle/configuration-cache/gc.properties
-android/.gradle/vcs-1/gc.properties
-android/.idea/.name
-android/.idea/gradle.xml
-android/.idea/misc.xml
-android/.idea/workspace.xml
-example/.flutter-plugins
-example/.flutter-plugins-dependencies
-example/.dart_tool/package_config.json
-example/.dart_tool/package_config_subset
-example/.dart_tool/flutter_build/
-example/android/.gradle/
-example/android/.idea/
-example/ios/.symlinks/
-example/ios/Pods/
-sample apps/flutter-quickstart-app/.dart_tool/
-sample apps/hms-callkit-app/.dart_tool/
-sample apps/flutter-quickstart-app/build/ios/Pods.build/
-packages/hms_room_kit/.dart_tool
+## HMSSDK
+packages/hmssdk_flutter/example/android/.gradle/6.8.3/gc.properties
+packages/hmssdk_flutter/example/android/.gradle/6.8.3/fileChanges/last-build.bin
+packages/hmssdk_flutter/example/android/.gradle/6.8.3/fileHashes/fileHashes.lock
+packages/hmssdk_flutter/example/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock
+packages/hmssdk_flutter/example/android/.gradle/buildOutputCleanup/cache.properties
+packages/hmssdk_flutter/example/android/.gradle/checksums/checksums.lock
+packages/hmssdk_flutter/example/android/.gradle/checksums/sha1-checksums.bin
+packages/hmssdk_flutter/example/android/.gradle/configuration-cache/gc.properties
+packages/hmssdk_flutter/example/android/.gradle/vcs-1/gc.properties
+packages/hmssdk_flutter/example/android/.idea/.name
+packages/hmssdk_flutter/example/android/local.properties
+packages/hmssdk_flutter/example/android/.idea/gradle.xml
+packages/hmssdk_flutter/example/android/.idea/misc.xml
+packages/hmssdk_flutter/example/android/.idea/workspace.xml
+packages/hmssdk_flutter/example/.flutter-plugins
+packages/hmssdk_flutter/example/.flutter-plugins-dependencies
+packages/hmssdk_flutter/example/.dart_tool/package_config.json
+packages/hmssdk_flutter/example/.dart_tool/package_config_subset
+packages/hmssdk_flutter/example/.dart_tool/flutter_build/
+packages/hmssdk_flutter/example/android/.gradle/
+packages/hmssdk_flutter/example/android/.idea/
+packages/hmssdk_flutter/example/ios/.symlinks/
+packages/hmssdk_flutter/example/ios/Pods/
packages/hmssdk_flutter/.dart_tool
packages/hmssdk_flutter/example/.dart_tool
packages/hmssdk_flutter/example/android/fastlane
packages/hmssdk_flutter/example/build
packages/hmssdk_flutter/example/ios/fastlane
-packages/hmssdk_flutter/example/android/app/google-services.json
\ No newline at end of file
+packages/hmssdk_flutter/example/ios/flutter-hms-4aea6d38fd2a.json
+packages/hmssdk_flutter/example/android/app/google-services.json
+packages/hmssdk_flutter/example/android/flutter-hms-4aea6d38fd2a.json
+packages/hmssdk_flutter/build/
+
+##HMS ROOM KIT
+packages/hms_room_kit/.dart_tool
+packages/hms_room_kit/.DS_Store
+packages/hms_room_kit/.flutter-plugins
+packages/hms_room_kit/.flutter-plugins-dependencies
+packages/hms_room_kit/android/local.properties
+packages/hms_room_kit/ios/Flutter/flutter_export_environment.sh
+packages/hms_room_kit/ios/Flutter/Generated.xcconfig
+
+##Sample apps
+sample apps/flutter-quickstart-app/.dart_tool/
+sample apps/hms-callkit-app/.dart_tool/
+sample apps/flutter-quickstart-app/build/ios/Pods.build/
+sample apps/hms-callkit-app/.dart_tool/flutter_build/
+
+##GIT Files
+.dart_tool/package_config.json
+.dart_tool/package_config_subset
+.dart_tool/version
+.DS_Store
+packages/.DS_Store
+Runner.ipa
diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
index 9c3868223..541bca47f 100644
--- a/.trunk/trunk.yaml
+++ b/.trunk/trunk.yaml
@@ -1,18 +1,18 @@
version: 0.1
cli:
- version: 1.16.1
+ version: 1.16.2
plugins:
sources:
- id: trunk
- ref: v1.2.4
+ ref: v1.2.5
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- actionlint@1.6.26
- - checkov@2.4.9
- - osv-scanner@1.4.0
+ - checkov@2.5.7
+ - osv-scanner@1.4.1
- trivy@0.45.1
- - trufflehog@3.57.0
+ - trufflehog@3.59.0
- oxipng@8.0.0
- yamllint@1.32.0
- markdownlint@0.37.0
diff --git a/packages/hms_room_kit/CHANGELOG.md b/packages/hms_room_kit/CHANGELOG.md
index e89076961..80b91571f 100644
--- a/packages/hms_room_kit/CHANGELOG.md
+++ b/packages/hms_room_kit/CHANGELOG.md
@@ -5,6 +5,21 @@
| hms_room_kit | [![Pub Version](https://img.shields.io/pub/v/hms_room_kit)](https://pub.dev/packages/hms_room_kit) |
| hmssdk_flutter | [![Pub Version](https://img.shields.io/pub/v/hmssdk_flutter)](https://pub.dev/packages/hmssdk_flutter) |
+## 1.0.3 - 2023-10-16
+
+### 🚀 Added
+
+- Large Room Support
+ - Enhanced Participants list to accommodate up to 20,000 peers in a room.
+
+- Added recording state indicator: showcasing "initializing" and "running" states.
+- Added `Lower Hand` Capability in Participant list
+
+### Fixed
+
+- Fixed `userid` bug, where `userid` was not getting passed to SDK
+- Fixed UI bugs
+
## 1.0.2 - 2023-09-22
### 🚀 Added
diff --git a/packages/hms_room_kit/example/ios/Podfile.lock b/packages/hms_room_kit/example/ios/Podfile.lock
index b1a42a426..5014e3d77 100644
--- a/packages/hms_room_kit/example/ios/Podfile.lock
+++ b/packages/hms_room_kit/example/ios/Podfile.lock
@@ -6,14 +6,14 @@ PODS:
- HMSBroadcastExtensionSDK (0.0.9)
- HMSHLSPlayerSDK (0.0.2):
- HMSAnalyticsSDK (= 0.0.2)
- - HMSSDK (0.9.12):
+ - HMSSDK (1.1.0):
- HMSAnalyticsSDK (= 0.0.2)
- HMSWebRTC (= 1.0.5116)
- - hmssdk_flutter (1.8.0):
+ - hmssdk_flutter (1.9.0):
- Flutter
- HMSBroadcastExtensionSDK (= 0.0.9)
- HMSHLSPlayerSDK (= 0.0.2)
- - HMSSDK (= 0.9.12)
+ - HMSSDK (= 1.1.0)
- HMSWebRTC (1.0.5116)
- path_provider_foundation (0.0.1):
- Flutter
@@ -70,8 +70,8 @@ SPEC CHECKSUMS:
HMSAnalyticsSDK: 4d2a88a729b1eb42f3d25f217c28937ec318a5b7
HMSBroadcastExtensionSDK: d80fe325f6c928bd8e5176290b5a4b7ae15d6fbb
HMSHLSPlayerSDK: 6a54ad4d12f3dc2270d1ecd24019d71282a4f6a3
- HMSSDK: 65c1445ad2aac04deb127fe7611f65b8e7447752
- hmssdk_flutter: 806162401c1c9dd1fca07d913b9ee5f1e1d36930
+ HMSSDK: 49e3ac665ceb8904d41787ddf99742e8d7d6529a
+ hmssdk_flutter: 414edcdff09f1587f53b04e9b93b39e6174a61cd
HMSWebRTC: ae54e9dd91b869051b283b43b14f57d43b7bf8e1
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
@@ -81,4 +81,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: cc1f88378b4bfcf93a6ce00d2c587857c6008d3b
-COCOAPODS: 1.12.1
+COCOAPODS: 1.13.0
diff --git a/packages/hms_room_kit/example/pubspec.lock b/packages/hms_room_kit/example/pubspec.lock
index a7d284686..cd05b0146 100644
--- a/packages/hms_room_kit/example/pubspec.lock
+++ b/packages/hms_room_kit/example/pubspec.lock
@@ -222,15 +222,14 @@ packages:
path: ".."
relative: true
source: path
- version: "1.0.2"
+ version: "1.0.3"
hmssdk_flutter:
dependency: transitive
description:
- name: hmssdk_flutter
- sha256: fb6cdad295b0c76be408beb9cef0fe3fab9aa25c775779943a68fab4e675628b
- url: "https://pub.dev"
- source: hosted
- version: "1.8.0"
+ path: "../../hmssdk_flutter"
+ relative: true
+ source: path
+ version: "1.9.0"
http:
dependency: transitive
description:
diff --git a/packages/hms_room_kit/example/pubspec.yaml b/packages/hms_room_kit/example/pubspec.yaml
index cea24629d..598433295 100644
--- a/packages/hms_room_kit/example/pubspec.yaml
+++ b/packages/hms_room_kit/example/pubspec.yaml
@@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
-version: 1.0.1
+version: 1.0.3
environment:
sdk: ">=2.19.6 <3.0.0"
diff --git a/packages/hms_room_kit/lib/src/assets/icons/arrow.svg b/packages/hms_room_kit/lib/src/assets/icons/arrow.svg
deleted file mode 100644
index 40cd50ff7..000000000
--- a/packages/hms_room_kit/lib/src/assets/icons/arrow.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/packages/hms_room_kit/lib/src/assets/icons/left_arrow.svg b/packages/hms_room_kit/lib/src/assets/icons/left_arrow.svg
new file mode 100644
index 000000000..43ddf899a
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/left_arrow.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/hms_room_kit/lib/src/assets/icons/lower_hand.svg b/packages/hms_room_kit/lib/src/assets/icons/lower_hand.svg
new file mode 100644
index 000000000..4df2a263b
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/lower_hand.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/hms_room_kit/lib/src/assets/icons/right_arrow.svg b/packages/hms_room_kit/lib/src/assets/icons/right_arrow.svg
new file mode 100644
index 000000000..4814fb7c6
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/right_arrow.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_bottom_navigation_bar.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_bottom_navigation_bar.dart
index 733d45e9a..da98a8a7e 100644
--- a/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_bottom_navigation_bar.dart
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_bottom_navigation_bar.dart
@@ -95,7 +95,7 @@ class HLSViewerBottomNavigationBar extends StatelessWidget {
onTap: () => {
context
.read()
- .changeMetadata(),
+ .toggleLocalPeerHandRaise(),
},
enabledBorderColor: HMSThemeColors
.backgroundDim
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_header.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_header.dart
index e2d2e6295..6f9e42d6b 100644
--- a/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_header.dart
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_header.dart
@@ -1,8 +1,7 @@
///Dart imports
import 'dart:io';
-///Package imports
-import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:hms_room_kit/src/common/utility_functions.dart';
import 'package:provider/provider.dart';
@@ -85,12 +84,14 @@ class HLSViewerHeader extends StatelessWidget {
///We render the recording icon based on the recording status
///If the recording is started we show the recording icon
///If the recording is not started we show nothing
- Selector>(
- selector: (_, meetingStore) => Tuple3(
- meetingStore.recordingType["browser"] ?? false,
- meetingStore.recordingType["server"] ?? false,
- meetingStore.recordingType["hls"] ?? false,
- ),
+ ///
+ ///If recording initialising state is true we show the loader
+ Selector>(
+ selector: (_, meetingStore) => Tuple4(
+ meetingStore.recordingType["browser"] ?? false,
+ meetingStore.recordingType["server"] ?? false,
+ meetingStore.recordingType["hls"] ?? false,
+ meetingStore.isRecordingInInitialisingState),
builder: (_, data, __) {
return (data.item1 || data.item2 || data.item3)
? SvgPicture.asset(
@@ -101,7 +102,15 @@ class HLSViewerHeader extends StatelessWidget {
HMSThemeColors.alertErrorDefault,
BlendMode.srcIn),
)
- : Container();
+ : data.item4
+ ? SizedBox(
+ height: 24,
+ width: 24,
+ child: CircularProgressIndicator(
+ strokeWidth: 1,
+ color: HMSThemeColors.onSurfaceHighEmphasis,
+ ))
+ : Container();
}),
const SizedBox(
width: 8,
@@ -113,7 +122,7 @@ class HLSViewerHeader extends StatelessWidget {
Selector>(
selector: (_, meetingStore) => Tuple2(
meetingStore.streamingType['hls'] ?? false,
- meetingStore.peers.length),
+ meetingStore.peersInRoom),
builder: (_, data, __) {
return data.item1
? Container(
diff --git a/packages/hms_room_kit/lib/src/hmssdk_interactor.dart b/packages/hms_room_kit/lib/src/hmssdk_interactor.dart
index 19c8b9107..558007313 100644
--- a/packages/hms_room_kit/lib/src/hmssdk_interactor.dart
+++ b/packages/hms_room_kit/lib/src/hmssdk_interactor.dart
@@ -392,4 +392,25 @@ class HMSSDKInteractor {
Future cancelPreview() async {
return await hmsSDK.cancelPreview();
}
+
+ Future getPeerListIterator(
+ {PeerListIteratorOptions? peerListIteratorOptions}) async {
+ return await hmsSDK.getPeerListIterator(
+ peerListIteratorOptions: peerListIteratorOptions);
+ }
+
+ void lowerLocalPeerHand({HMSActionResultListener? hmsActionResultListener}) {
+ hmsSDK.lowerLocalPeerHand(hmsActionResultListener: hmsActionResultListener);
+ }
+
+ void raiseLocalPeerHand({HMSActionResultListener? hmsActionResultListener}) {
+ hmsSDK.raiseLocalPeerHand(hmsActionResultListener: hmsActionResultListener);
+ }
+
+ void lowerRemotePeerHand(
+ {required HMSPeer forPeer,
+ HMSActionResultListener? hmsActionResultListener}) {
+ hmsSDK.lowerRemotePeerHand(
+ forPeer: forPeer, hmsActionResultListener: hmsActionResultListener);
+ }
}
diff --git a/packages/hms_room_kit/lib/src/layout_api/hms_room_layout.dart b/packages/hms_room_kit/lib/src/layout_api/hms_room_layout.dart
index 7c697787b..6394e0201 100644
--- a/packages/hms_room_kit/lib/src/layout_api/hms_room_layout.dart
+++ b/packages/hms_room_kit/lib/src/layout_api/hms_room_layout.dart
@@ -216,6 +216,7 @@ class HMSRoomLayout {
static Chat? chatData;
static bool isParticipantsListEnabled = true;
static bool isBRBEnabled = true;
+ static List? offStageRoles = [];
static Future getRoomLayout(
{required HMSSDKInteractor hmsSDKInteractor,
@@ -234,14 +235,20 @@ class HMSRoomLayout {
if (roleName != null) {
int? roleIndex =
data?.indexWhere((layoutData) => layoutData.role == roleName);
+
+ ///Check if that role theme is present
+ ///If not we assign the theme at 0th index
if (roleIndex != null && roleIndex != -1) {
HMSThemeColors.applyLayoutColors(data?[roleIndex].themes?[0].palette);
roleLayoutData = data?[roleIndex];
- return;
+ } else {
+ HMSThemeColors.applyLayoutColors(data?[0].themes?[0].palette);
+ roleLayoutData = data?[0];
}
+ } else {
+ HMSThemeColors.applyLayoutColors(data?[0].themes?[0].palette);
+ roleLayoutData = data?[0];
}
- HMSThemeColors.applyLayoutColors(data?[0].themes?[0].palette);
- roleLayoutData = data?[0];
peerType = roleLayoutData?.screens?.conferencing?.hlsLiveStreaming != null
? PeerRoleType.hlsViewer
: PeerRoleType.conferencing;
@@ -254,6 +261,8 @@ class HMSRoomLayout {
isBRBEnabled =
roleLayoutData?.screens?.conferencing?.defaultConf?.elements?.brb !=
null;
+ offStageRoles = roleLayoutData?.screens?.conferencing?.defaultConf
+ ?.elements?.onStageExp?.offStageRoles;
} else {
chatData = roleLayoutData
?.screens?.conferencing?.hlsLiveStreaming?.elements?.chat;
@@ -263,6 +272,8 @@ class HMSRoomLayout {
isBRBEnabled = roleLayoutData
?.screens?.conferencing?.hlsLiveStreaming?.elements?.brb !=
null;
+ offStageRoles = roleLayoutData?.screens?.conferencing?.hlsLiveStreaming
+ ?.elements?.onStageExp?.offStageRoles;
}
}
diff --git a/packages/hms_room_kit/lib/src/meeting/meeting_header.dart b/packages/hms_room_kit/lib/src/meeting/meeting_header.dart
index 1e53e22e4..57e994d19 100644
--- a/packages/hms_room_kit/lib/src/meeting/meeting_header.dart
+++ b/packages/hms_room_kit/lib/src/meeting/meeting_header.dart
@@ -60,6 +60,8 @@ class _MeetingHeaderState extends State {
///else we render an empty Container
///
///For hls streaming status we use the streamingType map from the [MeetingStore]
+ ///
+ ///If recording initialising state is true we show the loader
Selector(
selector: (_, meetingStore) =>
meetingStore.streamingType['hls'] ?? false,
@@ -91,12 +93,12 @@ class _MeetingHeaderState extends State {
///else we render an empty Container
///
///For recording status we use the recordingType map from the [MeetingStore]
- Selector>(
- selector: (_, meetingStore) => Tuple3(
- meetingStore.recordingType["browser"] ?? false,
- meetingStore.recordingType["server"] ?? false,
- meetingStore.recordingType["hls"] ?? false,
- ),
+ Selector>(
+ selector: (_, meetingStore) => Tuple4(
+ meetingStore.recordingType["browser"] ?? false,
+ meetingStore.recordingType["server"] ?? false,
+ meetingStore.recordingType["hls"] ?? false,
+ meetingStore.isRecordingInInitialisingState),
builder: (_, data, __) {
return (data.item1 || data.item2 || data.item3)
? SvgPicture.asset(
@@ -107,7 +109,15 @@ class _MeetingHeaderState extends State {
HMSThemeColors.alertErrorDefault,
BlendMode.srcIn),
)
- : Container();
+ : data.item4
+ ? SizedBox(
+ height: 24,
+ width: 24,
+ child: CircularProgressIndicator(
+ strokeWidth: 2,
+ color: HMSThemeColors.onSurfaceHighEmphasis,
+ ))
+ : Container();
}),
const SizedBox(
width: 8,
@@ -119,7 +129,7 @@ class _MeetingHeaderState extends State {
Selector>(
selector: (_, meetingStore) => Tuple2(
meetingStore.streamingType['hls'] ?? false,
- meetingStore.peers.length),
+ meetingStore.peersInRoom),
builder: (_, data, __) {
return data.item1
? Container(
diff --git a/packages/hms_room_kit/lib/src/meeting/meeting_page.dart b/packages/hms_room_kit/lib/src/meeting/meeting_page.dart
index 05536865d..8ed2bbd2d 100644
--- a/packages/hms_room_kit/lib/src/meeting/meeting_page.dart
+++ b/packages/hms_room_kit/lib/src/meeting/meeting_page.dart
@@ -1,15 +1,10 @@
//Dart imports
import 'dart:io';
+import 'dart:math';
///Package imports
import 'package:flutter/material.dart';
import 'package:flutter_foreground_task/flutter_foreground_task.dart';
-import 'package:hms_room_kit/src/preview_for_role/preview_for_role_bottom_sheet.dart';
-import 'package:hms_room_kit/src/preview_for_role/preview_for_role_header.dart';
-import 'package:hms_room_kit/src/widgets/common_widgets/hms_circular_avatar.dart';
-import 'package:hms_room_kit/src/widgets/common_widgets/hms_left_room_screen.dart';
-import 'package:hms_room_kit/src/widgets/meeting_modes/custom_one_to_one_grid.dart';
-import 'package:hms_room_kit/src/widgets/toasts/hms_recording_error_toast.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import 'package:hmssdk_flutter/hmssdk_flutter.dart';
@@ -32,6 +27,12 @@ import 'package:hms_room_kit/src/widgets/app_dialogs/audio_device_change_dialog.
import 'package:hms_room_kit/src/widgets/meeting_modes/one_to_one_mode.dart';
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
import 'package:hms_room_kit/src/meeting/pip_view.dart';
+import 'package:hms_room_kit/src/preview_for_role/preview_for_role_bottom_sheet.dart';
+import 'package:hms_room_kit/src/preview_for_role/preview_for_role_header.dart';
+import 'package:hms_room_kit/src/widgets/common_widgets/hms_circular_avatar.dart';
+import 'package:hms_room_kit/src/widgets/common_widgets/hms_left_room_screen.dart';
+import 'package:hms_room_kit/src/widgets/meeting_modes/custom_one_to_one_grid.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_recording_error_toast.dart';
///[MeetingPage] is the main page of the meeting
///It takes the following parameters:
@@ -497,8 +498,7 @@ class _MeetingPageState extends State {
int>>(
selector: (_, meetingStore) =>
Tuple2(
- meetingStore.toasts
- .toList(),
+ meetingStore.toasts,
meetingStore
.toasts.length),
builder: (_, toastsItem, __) {
@@ -507,6 +507,12 @@ class _MeetingPageState extends State {
}
return Stack(
children: toastsItem.item1
+ .sublist(
+ 0,
+ min(
+ 3,
+ toastsItem
+ .item2))
.asMap()
.entries
.map((toasts) {
diff --git a/packages/hms_room_kit/lib/src/meeting/meeting_store.dart b/packages/hms_room_kit/lib/src/meeting/meeting_store.dart
index 36245329f..151fc3255 100644
--- a/packages/hms_room_kit/lib/src/meeting/meeting_store.dart
+++ b/packages/hms_room_kit/lib/src/meeting/meeting_store.dart
@@ -216,6 +216,21 @@ class MeetingStore extends ChangeNotifier
int currentScreenSharePage = 0;
+ ///PeerList iterators
+ ///This is a map with key as role and value as the iterator for that role
+ Map peerListIterators = {};
+
+ ///This checks whether to refresh peerlist or not
+ ///This is used in case when we are looking at a specific viewer role peerlist
+ ///i.e we are using the View All button functionalities.
+ bool disablePeerListRefresh = false;
+
+ ///This stores the number of peers in the room
+ int peersInRoom = 0;
+
+ ///Check whether recording is in intialising state
+ bool isRecordingInInitialisingState = false;
+
Future join(String userName, String roomCode,
{HMSConfig? roomConfig}) async {
//If roomConfig is null then only we call the methods to get the authToken
@@ -224,7 +239,9 @@ class MeetingStore extends ChangeNotifier
if (roomConfig == null) {
//We use this to get the auth token from room code
dynamic tokenData = await _hmsSDKInteractor.getAuthTokenByRoomCode(
- roomCode: Constant.roomCode, endPoint: Constant.tokenEndPoint);
+ userId: Constant.prebuiltOptions?.userId,
+ roomCode: Constant.roomCode,
+ endPoint: Constant.tokenEndPoint);
///If the tokenData is String then we set the authToken in the roomConfig
///and then we join the room
@@ -253,6 +270,13 @@ class MeetingStore extends ChangeNotifier
return null;
}
+ ///This method reapplies the theme layout based on the role name
+ void resetLayout(String roleName) {
+ HMSRoomLayout.resetLayout(roleName);
+ setMeetingModeUsingLayoutApi();
+ notifyListeners();
+ }
+
///This method is used to set the meeting mode using the layout api
void setMeetingModeUsingLayoutApi() {
if (HMSRoomLayout.peerType == PeerRoleType.conferencing) {
@@ -499,6 +523,8 @@ class MeetingStore extends ChangeNotifier
meetingUrl: meetingUrl, toRecord: toRecord, rtmpUrls: rtmpUrls);
_hmsSDKInteractor.startRtmpOrRecording(hmsRecordingConfig, this);
+ isRecordingInInitialisingState = true;
+ notifyListeners();
}
void cancelPreview() async {
@@ -508,7 +534,7 @@ class MeetingStore extends ChangeNotifier
return;
}
if (isRaisedHand) {
- changeMetadata();
+ toggleLocalPeerHandRaise();
}
if (currentRoleChangeRequest?.suggestedBy != null) {
_hmsSDKInteractor.sendDirectMessage(
@@ -567,25 +593,29 @@ class MeetingStore extends ChangeNotifier
return await _hmsSDKInteractor.getPeer(peerId: peerId);
}
- void changeMetadata() {
- isRaisedHand = !isRaisedHand;
- isBRB = false;
- String value = isRaisedHand ? "true" : "false";
- _hmsSDKInteractor.changeMetadata(
- metadata:
- "{\"isHandRaised\":$value,\"isBRBOn\":false,\"prevRole\":\"$previousRole\"}",
- hmsActionResultListener: this);
+ void toggleLocalPeerHandRaise() {
+ if (isRaisedHand) {
+ _hmsSDKInteractor.lowerLocalPeerHand(hmsActionResultListener: this);
+ } else {
+ _hmsSDKInteractor.raiseLocalPeerHand(hmsActionResultListener: this);
+ }
+ }
+
+ void lowerRemotePeerHand(HMSPeer forPeer) {
+ _hmsSDKInteractor.lowerRemotePeerHand(
+ forPeer: forPeer, hmsActionResultListener: this);
}
bool isBRB = false;
void changeMetadataBRB() {
isBRB = !isBRB;
- isRaisedHand = false;
+ if (isRaisedHand) {
+ _hmsSDKInteractor.lowerLocalPeerHand(hmsActionResultListener: this);
+ }
String value = isBRB ? "true" : "false";
_hmsSDKInteractor.changeMetadata(
- metadata:
- "{\"isHandRaised\":false,\"isBRBOn\":$value,\"prevRole\":\"$previousRole\"}",
+ metadata: "{\"isBRBOn\":$value,\"prevRole\":\"$previousRole\"}",
hmsActionResultListener: this);
if (isMicOn) {
toggleMicMuteState();
@@ -603,16 +633,14 @@ class MeetingStore extends ChangeNotifier
if (localPeer != null) {
previousRole = localPeer?.role.name;
if (isRaisedHand) {
- changeMetadata();
- } else {
- ///Setting the previous role
- String value = isRaisedHand ? "true" : "false";
- _hmsSDKInteractor.changeMetadata(
- metadata:
- "{\"isHandRaised\":$value,\"isBRBOn\":false,\"prevRole\":\"$previousRole\"}",
- hmsActionResultListener: this);
+ toggleLocalPeerHandRaise();
}
- HMSRoomLayout.resetLayout(hmsRoleChangeRequest.suggestedRole.name);
+
+ ///Setting the previous role
+ _hmsSDKInteractor.changeMetadata(
+ metadata: "{\"isBRBOn\":false,\"prevRole\":\"$previousRole\"}",
+ hmsActionResultListener: this);
+ // resetLayout(hmsRoleChangeRequest.suggestedRole.name);
currentRoleChangeRequest = null;
notifyListeners();
}
@@ -653,6 +681,56 @@ class MeetingStore extends ChangeNotifier
}
}
+ void nextPeersForRole(String role) async {
+ dynamic nextSetOfPeers = await peerListIterators[role]?.next();
+ if (nextSetOfPeers is List && nextSetOfPeers.isNotEmpty) {
+ for (var peer in nextSetOfPeers) {
+ addPeer(peer);
+ }
+ }
+ }
+
+ ///This method is used to disable the peer list refresh
+ void disableRefresh() {
+ disablePeerListRefresh = true;
+ }
+
+ ///This method is used to enable the peer list refresh
+ void enableRefresh() {
+ disablePeerListRefresh = false;
+ }
+
+ ///This method is used to refresh the peer list
+ void refreshPeerList() async {
+ ///If the peer list refresh is disabled then we return
+ if (disablePeerListRefresh) {
+ return;
+ }
+ log("Calling refresh PeerList Method $peerListIterators");
+ peerListIterators.clear();
+ List? offStageRoles = HMSRoomLayout.roleLayoutData?.screens
+ ?.conferencing?.defaultConf?.elements?.onStageExp?.offStageRoles;
+ offStageRoles?.forEach((role) async {
+ var peerListIterator = await _hmsSDKInteractor.getPeerListIterator(
+ peerListIteratorOptions:
+ PeerListIteratorOptions(limit: 10, byRoleName: role));
+ if (peerListIterator != null && peerListIterator is HMSPeerListIterator) {
+ peerListIterators[role] = peerListIterator;
+ participantsInMeeting -= participantsInMeetingMap[role]?.length ?? 0;
+ participantsInMeetingMap[role]?.clear();
+ dynamic nonRealTimePeers = await peerListIterator.next();
+ if (nonRealTimePeers is List) {
+ log("Calling refresh PeerList Method $nonRealTimePeers");
+ if (nonRealTimePeers.isNotEmpty) {
+ for (var peer in nonRealTimePeers) {
+ addPeer(peer);
+ }
+ }
+ }
+ }
+ });
+ }
+
Future?> getPeers() async {
return await _hmsSDKInteractor.getPeers();
}
@@ -801,10 +879,13 @@ class MeetingStore extends ChangeNotifier
@override
void onRoomUpdate({required HMSRoom room, required HMSRoomUpdate update}) {
log("onRoomUpdate-> room: ${room.toString()} update: ${update.name}");
+ peersInRoom = room.peerCount;
switch (update) {
case HMSRoomUpdate.browserRecordingStateUpdated:
recordingType["browser"] =
room.hmsBrowserRecordingState?.running ?? false;
+ isRecordingInInitialisingState =
+ room.hmsBrowserRecordingState?.initialising ?? false;
break;
case HMSRoomUpdate.serverRecordingStateUpdated:
recordingType["server"] =
@@ -827,11 +908,8 @@ class MeetingStore extends ChangeNotifier
? "HLS Streaming Started"
: "HLS Streaming Stopped");
break;
- case HMSRoomUpdate.roomPeerCountUpdated:
- hmsRoom = room;
- return;
default:
- return;
+ break;
}
hmsRoom = room;
notifyListeners();
@@ -932,19 +1010,16 @@ class MeetingStore extends ChangeNotifier
void onMessage({required HMSMessage message}) {
log("onMessage-> sender: ${message.sender} message: ${message.message} time: ${message.time}, type: ${message.type}");
switch (message.type) {
- case "metadata":
- break;
- case "EMOJI_REACTION":
- break;
case "role_change_declined":
toggleRequestDeclined(message.sender);
break;
- default:
+ case "chat":
addMessage(message);
isNewMessageReceived = true;
Utilities.showNotification(
"New message from ${message.sender?.name ?? ""}", "message");
notifyListeners();
+ default:
break;
}
}
@@ -952,8 +1027,10 @@ class MeetingStore extends ChangeNotifier
@override
void onRoleChangeRequest({required HMSRoleChangeRequest roleChangeRequest}) {
log("onRoleChangeRequest-> sender: ${roleChangeRequest.suggestedBy} role: ${roleChangeRequest.suggestedRole}");
- currentRoleChangeRequest = roleChangeRequest;
- previewForRole(roleChangeRequest.suggestedRole.name);
+ if (currentRoleChangeRequest == null) {
+ currentRoleChangeRequest = roleChangeRequest;
+ previewForRole(roleChangeRequest.suggestedRole.name);
+ }
}
void setCurrentPage(int newPage) {
@@ -1233,10 +1310,9 @@ class MeetingStore extends ChangeNotifier
participantsInMeetingMap[peer.role.name]
?.removeWhere((oldPeer) => oldPeer.peer.peerId == peer.peerId);
participantsInMeeting--;
- if (peer.metadata?.contains("\"isHandRaised\":true") ?? false) {
+ if (peer.isHandRaised) {
participantsInMeetingMap["Hand Raised"]
?.removeWhere((oldPeer) => oldPeer.peer.peerId == peer.peerId);
- participantsInMeeting--;
}
notifyListeners();
}
@@ -1250,10 +1326,9 @@ class MeetingStore extends ChangeNotifier
?.add(ParticipantsStore(peer: peer));
participantsInMeeting++;
}
- if (peer.metadata?.contains("\"isHandRaised\":true") ?? false) {
+ if (peer.isHandRaised) {
participantsInMeetingMap["Hand Raised"]
?.add(ParticipantsStore(peer: peer));
- participantsInMeeting++;
}
notifyListeners();
}
@@ -1278,7 +1353,7 @@ class MeetingStore extends ChangeNotifier
if (index != null && index != -1) {
if ((peerUpdate == HMSPeerUpdate.nameChanged)) {
participantsInMeetingMap[peer.role.name]?[index].updatePeer(peer);
- if ((peer.metadata?.contains("\"isHandRaised\":true") ?? false)) {
+ if (peer.isHandRaised) {
int? peerIndex = participantsInMeetingMap["Hand Raised"]
?.indexWhere((element) => element.peer.peerId == peer.peerId);
if (peerIndex != null && peerIndex != -1) {
@@ -1286,21 +1361,18 @@ class MeetingStore extends ChangeNotifier
.updatePeer(peer);
}
}
- } else if (peerUpdate == HMSPeerUpdate.metadataChanged) {
- if ((peer.metadata?.contains("\"isHandRaised\":true") ?? false)) {
+ } else if (peerUpdate == HMSPeerUpdate.handRaiseUpdated) {
+ if (peer.isHandRaised) {
if (participantsInMeetingMap["Hand Raised"]?.indexWhere(
(element) => element.peer.peerId == peer.peerId) ==
-1) {
participantsInMeetingMap["Hand Raised"]
?.add(ParticipantsStore(peer: peer));
- participantsInMeeting++;
}
participantsInMeetingMap[peer.role.name]?[index].updatePeer(peer);
- } else if ((peer.metadata?.contains("\"isHandRaised\":false") ??
- false)) {
+ } else {
participantsInMeetingMap["Hand Raised"]?.removeWhere(
(handDownPeer) => handDownPeer.peer.peerId == peer.peerId);
- participantsInMeeting--;
participantsInMeetingMap[peer.role.name]?[index].updatePeer(peer);
}
notifyListeners();
@@ -1363,7 +1435,7 @@ class MeetingStore extends ChangeNotifier
case HMSPeerUpdate.roleUpdated:
if (peer.isLocal) {
getSpotlightPeer();
- HMSRoomLayout.resetLayout(peer.role.name);
+ resetLayout(peer.role.name);
localPeer = peer;
}
if (HMSRoomLayout
@@ -1411,10 +1483,21 @@ class MeetingStore extends ChangeNotifier
if (index != -1) {
PeerTrackNode peerTrackNode = peerTracks[index];
peerTrackNode.peer = peer;
- if (peer.metadata?.contains("\"isHandRaised\":true") ?? false) {
- Utilities.showNotification(
- "${peer.name} raised hand", "hand-raise");
- }
+ peerTrackNode.notify();
+ }
+ updatePeerAt(peer);
+ updatePeerMap(update, peer);
+ break;
+
+ case HMSPeerUpdate.handRaiseUpdated:
+ if (peer.isLocal) {
+ localPeer = peer;
+ }
+ int index = peerTracks
+ .indexWhere((element) => element.uid == "${peer.peerId}mainVideo");
+ if (index != -1) {
+ PeerTrackNode peerTrackNode = peerTracks[index];
+ peerTrackNode.peer = peer;
peerTrackNode.notify();
} else {
if (HMSRoomLayout.peerType == PeerRoleType.conferencing) {
@@ -1894,11 +1977,11 @@ class MeetingStore extends ChangeNotifier
/// Method to toggle the role change toast
///
void addRemoveToastsForRoleChange({required HMSPeer peer}) {
- if (peer.metadata?.contains("\"isHandRaised\":true") ?? false) {
+ if (peer.isHandRaised) {
toasts.add(
HMSToastModel(peer, hmsToastType: HMSToastsType.roleChangeToast));
notifyListeners();
- } else if (peer.metadata?.contains("\"isHandRaised\":false") ?? false) {
+ } else {
toasts.removeWhere((toast) =>
toast.hmsToastType == HMSToastsType.roleChangeToast &&
peer.peerId == toast.toastData.peerId);
@@ -2034,6 +2117,18 @@ class MeetingStore extends ChangeNotifier
case HMSActionResultListenerMethod.sendHLSTimedMetadata:
Utilities.showToast("Metadata sent successfully");
break;
+ case HMSActionResultListenerMethod.lowerLocalPeerHand:
+ isRaisedHand = false;
+ isBRB = false;
+ notifyListeners();
+ break;
+ case HMSActionResultListenerMethod.raiseLocalPeerHand:
+ isRaisedHand = true;
+ isBRB = false;
+ notifyListeners();
+ break;
+ case HMSActionResultListenerMethod.lowerRemotePeerHand:
+ break;
default:
log("ActionResultListener onException-> method: ${methodType.toString()}Could not find a valid case while switching");
break;
@@ -2068,6 +2163,7 @@ class MeetingStore extends ChangeNotifier
case HMSActionResultListenerMethod.startRtmpOrRecording:
toasts.add(HMSToastModel(hmsException,
hmsToastType: HMSToastsType.errorToast));
+ isRecordingInInitialisingState = false;
notifyListeners();
break;
case HMSActionResultListenerMethod.stopRtmpAndRecording:
@@ -2110,6 +2206,12 @@ class MeetingStore extends ChangeNotifier
case HMSActionResultListenerMethod.sendHLSTimedMetadata:
// TODO: Handle this case.
break;
+ case HMSActionResultListenerMethod.lowerLocalPeerHand:
+ break;
+ case HMSActionResultListenerMethod.raiseLocalPeerHand:
+ break;
+ case HMSActionResultListenerMethod.lowerRemotePeerHand:
+ break;
default:
log("ActionResultListener onException-> method: ${methodType.toString()} Could not find a valid case while switching");
break;
@@ -2271,4 +2373,14 @@ class MeetingStore extends ChangeNotifier
}
notifyListeners();
}
+
+ @override
+ void onPeerListUpdate(
+ {required List addedPeers,
+ required List removedPeers}) {
+ log("onPeerListUpdate -> addedPeers: $addedPeers removedPeers: $removedPeers");
+ for (var peer in addedPeers) {
+ addPeer(peer);
+ }
+ }
}
diff --git a/packages/hms_room_kit/lib/src/preview/preview_page.dart b/packages/hms_room_kit/lib/src/preview/preview_page.dart
index 49c4f3b20..64d0a8edd 100644
--- a/packages/hms_room_kit/lib/src/preview/preview_page.dart
+++ b/packages/hms_room_kit/lib/src/preview/preview_page.dart
@@ -41,13 +41,14 @@ class PreviewPage extends StatefulWidget {
class _PreviewPageState extends State {
late MeetingStore _meetingStore;
- TextEditingController nameController = TextEditingController();
+ late TextEditingController nameController;
bool isJoiningRoom = false;
bool isHLSStarting = false;
@override
void initState() {
super.initState();
+ nameController = TextEditingController(text: widget.name);
}
@override
@@ -66,7 +67,7 @@ class _PreviewPageState extends State {
///This function joins the room only if the name is not empty
void _joinMeeting(PreviewStore previewStore) async {
- if (nameController.text.isNotEmpty) {
+ if (nameController.text.trim().isNotEmpty) {
FocusManager.instance.primaryFocus?.unfocus();
setState(() {
isJoiningRoom = true;
@@ -76,8 +77,8 @@ class _PreviewPageState extends State {
_setMeetingStore(previewStore);
/// We join the room here
- HMSException? ans =
- await _meetingStore.join(nameController.text, Constant.roomCode);
+ HMSException? ans = await _meetingStore.join(
+ nameController.text.trim(), Constant.roomCode);
///If the room join fails we show the error dialog
if (ans != null && mounted) {
@@ -403,7 +404,9 @@ class _PreviewPageState extends State {
PreviewJoinButton(
isEmpty:
nameController
- .text.isEmpty,
+ .text
+ .trim()
+ .isEmpty,
previewStore:
previewStore,
isJoining:
diff --git a/packages/hms_room_kit/lib/src/preview/preview_store.dart b/packages/hms_room_kit/lib/src/preview/preview_store.dart
index 7a38dd8ea..594723366 100644
--- a/packages/hms_room_kit/lib/src/preview/preview_store.dart
+++ b/packages/hms_room_kit/lib/src/preview/preview_store.dart
@@ -111,7 +111,9 @@ class PreviewStore extends ChangeNotifier
{required String userName, required String roomCode}) async {
//We use this to get the auth token from room code
dynamic tokenData = await hmsSDKInteractor.getAuthTokenByRoomCode(
- roomCode: roomCode, endPoint: Constant.tokenEndPoint);
+ userId: Constant.prebuiltOptions?.userId,
+ roomCode: roomCode,
+ endPoint: Constant.tokenEndPoint);
if ((tokenData is String?) && tokenData != null) {
roomConfig = HMSConfig(
@@ -349,4 +351,9 @@ class PreviewStore extends ChangeNotifier
@override
void onUpdateSpeakers({required List updateSpeakers}) {}
+
+ @override
+ void onPeerListUpdate(
+ {required List addedPeers,
+ required List removedPeers}) {}
}
diff --git a/packages/hms_room_kit/lib/src/preview_for_role/preview_for_role_header.dart b/packages/hms_room_kit/lib/src/preview_for_role/preview_for_role_header.dart
index 5cf98a9e6..0b1571cf5 100644
--- a/packages/hms_room_kit/lib/src/preview_for_role/preview_for_role_header.dart
+++ b/packages/hms_room_kit/lib/src/preview_for_role/preview_for_role_header.dart
@@ -104,7 +104,7 @@ class _PreviewForRoleHeaderState extends State {
Selector>(
selector: (_, meetingStore) => Tuple2(
meetingStore.streamingType['hls'] ?? false,
- meetingStore.peers.length),
+ meetingStore.peersInRoom),
builder: (_, data, __) {
return data.item1
? Container(
diff --git a/packages/hms_room_kit/lib/src/screen_controller.dart b/packages/hms_room_kit/lib/src/screen_controller.dart
index 83853aeae..74da385e9 100644
--- a/packages/hms_room_kit/lib/src/screen_controller.dart
+++ b/packages/hms_room_kit/lib/src/screen_controller.dart
@@ -110,7 +110,7 @@ class _ScreenControllerState extends State {
await _hmsSDKInteractor.build();
_previewStore = PreviewStore(hmsSDKInteractor: _hmsSDKInteractor);
HMSException? ans = await _previewStore.startPreview(
- userName: "", roomCode: Constant.roomCode);
+ userName: widget.options?.userName ?? "", roomCode: Constant.roomCode);
///If preview fails then we show the error dialog
///with the error message and description
@@ -156,7 +156,7 @@ class _ScreenControllerState extends State {
value: _previewStore,
child: PreviewPage(
roomCode: Constant.roomCode,
- name: "",
+ name: widget.options?.userName ?? "",
options: widget.options,
))
: PreviewPermissions(
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart
index 63725c3ef..c43e57643 100644
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart
@@ -2,20 +2,18 @@
import 'package:badges/badges.dart' as badge;
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
+import 'package:provider/provider.dart';
+
+///Project imports
+import 'package:hms_room_kit/src/widgets/common_widgets/more_option_item.dart';
+import 'package:hms_room_kit/src/meeting/meeting_store.dart';
+import 'package:hms_room_kit/hms_room_kit.dart';
import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
import 'package:hms_room_kit/src/widgets/bottom_sheets/end_service_bottom_sheet.dart';
import 'package:hms_room_kit/src/widgets/bottom_sheets/overlay_participants_bottom_sheet.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_cross_button.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart';
import 'package:hms_room_kit/src/widgets/tab_widgets/chat_participants_tab_bar.dart';
-import 'package:provider/provider.dart';
-
-///Project imports
-import 'package:hms_room_kit/src/layout_api/hms_theme_colors.dart';
-import 'package:hms_room_kit/src/widgets/common_widgets/more_option_item.dart';
-import 'package:hms_room_kit/src/common/constants.dart';
-import 'package:hms_room_kit/src/widgets/common_widgets/hms_title_text.dart';
-import 'package:hms_room_kit/src/meeting/meeting_store.dart';
///This renders the app utilities bottom sheet for webRTC or broadcaster
///It contains the participants, screen share, brb, raise hand and recording
@@ -100,17 +98,11 @@ class _AppUtilitiesBottomSheetState extends State {
},
optionIcon: badge.Badge(
badgeStyle: badge.BadgeStyle(
- badgeColor: HMSThemeColors.surfaceDefault,
- padding: EdgeInsets.all(
- context.read().peers.length < 1000
- ? 5
- : 8)),
+ badgeColor: HMSThemeColors.surfaceDefault,
+ ),
badgeContent: HMSTitleText(
- text: context
- .read()
- .peers
- .length
- .toString(),
+ text: Utilities.formatNumber(
+ context.read().peersInRoom),
textColor: HMSThemeColors.onSurfaceHighEmphasis,
fontSize: 10,
lineHeight: 16,
@@ -118,11 +110,15 @@ class _AppUtilitiesBottomSheetState extends State {
),
child: Padding(
padding: EdgeInsets.symmetric(
- horizontal:
- (context.read().peers.length <
- 1000
- ? 5
- : 10)),
+ horizontal: context
+ .read()
+ .peersInRoom <
+ 1000
+ ? 15
+ : context.read().peersInRoom <
+ 10000
+ ? 20
+ : 30),
child: SvgPicture.asset(
"packages/hms_room_kit/lib/src/assets/icons/participants.svg",
height: 20,
@@ -182,7 +178,7 @@ class _AppUtilitiesBottomSheetState extends State {
,
MoreOptionItem(
onTap: () async {
- context.read().changeMetadata();
+ context.read().toggleLocalPeerHandRaise();
Navigator.pop(context);
},
isActive: meetingStore.isRaisedHand,
@@ -203,10 +199,15 @@ class _AppUtilitiesBottomSheetState extends State {
///start/stop browser recording
///
///The recording permission is checked using the role of the local peer
+ ///
+ ///If Streaming is already running we disable the recording option
if (meetingStore.localPeer?.role.permissions.browserRecording ??
false)
+
+ ///If streaming is on or in initialising state disable the button
((meetingStore.streamingType["hls"] ?? false) ||
- (meetingStore.streamingType["rtmp"] ?? false))
+ (meetingStore.streamingType["rtmp"] ?? false) ||
+ meetingStore.isRecordingInInitialisingState)
? MoreOptionItem(
onTap: () {},
isActive: false,
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/hls_more_options.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/hls_more_options.dart
index fc457bf89..71cfa12b9 100644
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/hls_more_options.dart
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/hls_more_options.dart
@@ -1,9 +1,6 @@
///Package imports
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
-import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
-import 'package:hms_room_kit/src/widgets/bottom_sheets/overlay_participants_bottom_sheet.dart';
-import 'package:hms_room_kit/src/widgets/tab_widgets/chat_participants_tab_bar.dart';
import 'package:provider/provider.dart';
import 'package:badges/badges.dart' as badge;
@@ -13,6 +10,9 @@ import 'package:hms_room_kit/src/widgets/bottom_sheets/change_name_bottom_sheet.
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_cross_button.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/more_option_item.dart';
+import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
+import 'package:hms_room_kit/src/widgets/bottom_sheets/overlay_participants_bottom_sheet.dart';
+import 'package:hms_room_kit/src/widgets/tab_widgets/chat_participants_tab_bar.dart';
///[HLSMoreOptionsBottomSheet] is a bottom sheet that is used to show more options in the meeting
class HLSMoreOptionsBottomSheet extends StatefulWidget {
@@ -96,17 +96,11 @@ class _HLSMoreOptionsBottomSheetBottomSheetState
},
optionIcon: badge.Badge(
badgeStyle: badge.BadgeStyle(
- badgeColor: HMSThemeColors.surfaceDefault,
- padding: EdgeInsets.all(
- context.read().peers.length < 1000
- ? 5
- : 8)),
+ badgeColor: HMSThemeColors.surfaceDefault,
+ ),
badgeContent: HMSTitleText(
- text: context
- .read()
- .peers
- .length
- .toString(),
+ text: Utilities.formatNumber(
+ context.read().peersInRoom),
textColor: HMSThemeColors.onSurfaceHighEmphasis,
fontSize: 10,
lineHeight: 16,
@@ -114,11 +108,15 @@ class _HLSMoreOptionsBottomSheetBottomSheetState
),
child: Padding(
padding: EdgeInsets.symmetric(
- horizontal:
- (context.read().peers.length <
- 1000
- ? 5
- : 10)),
+ horizontal: context
+ .read()
+ .peersInRoom <
+ 1000
+ ? 15
+ : context.read().peersInRoom <
+ 10000
+ ? 20
+ : 30),
child: SvgPicture.asset(
"packages/hms_room_kit/lib/src/assets/icons/participants.svg",
height: 20,
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/more_settings_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/more_settings_bottom_sheet.dart
index 0e32fa6c5..4359f54bb 100644
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/more_settings_bottom_sheet.dart
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/more_settings_bottom_sheet.dart
@@ -303,7 +303,7 @@ class _MoreSettingsBottomSheetState extends State {
ListTile(
horizontalTitleGap: 2,
onTap: () async {
- context.read().changeMetadata();
+ context.read().toggleLocalPeerHandRaise();
Navigator.pop(context);
},
contentPadding: EdgeInsets.zero,
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/overlay_participants_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/overlay_participants_bottom_sheet.dart
index 837145ea4..8f3ca83c5 100644
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/overlay_participants_bottom_sheet.dart
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/overlay_participants_bottom_sheet.dart
@@ -22,11 +22,10 @@ class OverlayParticipantsBottomSheet extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Selector(
- selector: (_, meetingStore) =>
- meetingStore.participantsInMeeting,
- builder: (_, participantsInMeeting, __) {
+ selector: (_, meetingStore) => meetingStore.peersInRoom,
+ builder: (_, peersInRoom, __) {
return HMSSubheadingText(
- text: "Participants ($participantsInMeeting)",
+ text: "Participants ($peersInRoom)",
textColor: HMSThemeColors.onSurfaceHighEmphasis,
fontWeight: FontWeight.w600,
);
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/participants_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/participants_bottom_sheet.dart
index 568d29657..858278a11 100644
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/participants_bottom_sheet.dart
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/participants_bottom_sheet.dart
@@ -1,11 +1,14 @@
-///Package imports
+///Dart imports
+import 'dart:async';
import 'dart:convert';
import 'dart:developer';
+///Package imports
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
+import 'package:hmssdk_flutter/hmssdk_flutter.dart';
///Project imports
import 'package:hms_room_kit/src/widgets/toasts/hms_toasts_type.dart';
@@ -13,7 +16,7 @@ import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
import 'package:hms_room_kit/src/layout_api/hms_theme_colors.dart';
import 'package:hms_room_kit/src/model/participant_store.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart';
-import 'package:hmssdk_flutter/hmssdk_flutter.dart';
+import 'package:hms_room_kit/src/widgets/bottom_sheets/participants_view_all_bottom_sheet.dart';
import 'package:hms_room_kit/src/model/peer_track_node.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_title_text.dart';
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
@@ -29,6 +32,35 @@ class ParticipantsBottomSheet extends StatefulWidget {
}
class _ParticipantsBottomSheetState extends State {
+ Timer? timer;
+
+ @override
+ void initState() {
+ super.initState();
+ timer = Timer.periodic(const Duration(seconds: 5),
+ (Timer t) => context.read().refreshPeerList());
+ }
+
+ @override
+ void dispose() {
+ timer?.cancel();
+ super.dispose();
+ }
+
+ void viewAll(String role) {
+ showModalBottomSheet(
+ isScrollControlled: true,
+ backgroundColor: HMSThemeColors.surfaceDim,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(20),
+ ),
+ context: context,
+ builder: (ctx) => ChangeNotifierProvider.value(
+ value: context.read(),
+ child: ParticipantsViewAllBottomSheet(role: role)),
+ );
+ }
+
Widget _kebabMenu(HMSPeer peer) {
final meetingStore = context.read();
PeerTrackNode? peerTrackNode;
@@ -97,6 +129,7 @@ class _ParticipantsBottomSheetState extends State {
return;
} catch (e) {
log(e.toString());
+ return;
}
}
}
@@ -112,6 +145,11 @@ class _ParticipantsBottomSheetState extends State {
break;
case 2:
+ ///Here we lower the remote peer hand
+ meetingStore.lowerRemotePeerHand(peer);
+ break;
+ case 3:
+
///Here we check whether the video track is null or not
if (peerTrackNode?.track == null) {
return;
@@ -119,7 +157,7 @@ class _ParticipantsBottomSheetState extends State {
meetingStore.changeTrackState(
peerTrackNode!.track!, !peerTrackNode.track!.isMute);
break;
- case 3:
+ case 4:
///Here we check whether the audio track is null or not
if (peerTrackNode?.audioTrack == null) {
@@ -128,7 +166,7 @@ class _ParticipantsBottomSheetState extends State {
meetingStore.changeTrackState(peerTrackNode!.audioTrack!,
!peerTrackNode.audioTrack!.isMute);
break;
- case 4:
+ case 5:
///This is called when someone clicks on remove Participant
meetingStore.removePeerFromRoom(peer);
@@ -170,11 +208,34 @@ class _ParticipantsBottomSheetState extends State {
),
]),
),
+ if (peer.isHandRaised)
+ PopupMenuItem(
+ value: 2,
+ child: Row(children: [
+ SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/lower_hand.svg",
+ width: 18,
+ height: 18,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn)),
+ const SizedBox(
+ width: 8,
+ ),
+ HMSTitleText(
+ text: "Lower Hand",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ fontSize: 14,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ ),
+ ]),
+ ),
if (mutePermission &&
peerTrackNode != null &&
!peerTrackNode.peer.isLocal)
PopupMenuItem(
- value: 2,
+ value: 3,
child: Row(children: [
SvgPicture.asset(
peerTrackNode.track?.isMute ?? false
@@ -203,7 +264,7 @@ class _ParticipantsBottomSheetState extends State {
peerTrackNode != null &&
!peerTrackNode.peer.isLocal)
PopupMenuItem(
- value: 3,
+ value: 4,
child: Row(children: [
SvgPicture.asset(
peerTrackNode.audioTrack?.isMute ?? false
@@ -230,7 +291,7 @@ class _ParticipantsBottomSheetState extends State {
),
if (removePeerPermission)
PopupMenuItem(
- value: 4,
+ value: 5,
child: Row(children: [
SvgPicture.asset(
"packages/hms_room_kit/lib/src/assets/icons/peer_remove.svg",
@@ -315,7 +376,7 @@ class _ParticipantsBottomSheetState extends State {
.onSurfaceHighEmphasis,
title: HMSSubheadingText(
text:
- "${data.item1.keys.elementAt(index)} (${data.item1[role]?.length})",
+ "${data.item1.keys.elementAt(index)} (${(HMSRoomLayout.offStageRoles?.contains(role) ?? false) ? context.read().peerListIterators[role]?.totalCount ?? 0 : data.item1[role]?.length}) ",
textColor: HMSThemeColors
.onSurfaceMediumEmphasis,
letterSpacing: 0.1,
@@ -325,7 +386,7 @@ class _ParticipantsBottomSheetState extends State {
height: data.item1[role] == null
? 0
: (data.item1[role]!.length) *
- 60,
+ 54,
child: Center(
child: ListView.builder(
physics:
@@ -422,8 +483,9 @@ class _ParticipantsBottomSheetState extends State {
Selector<
ParticipantsStore,
bool>(
- selector: (_, participantsStore) => (participantsStore.peer.metadata?.contains("\"isHandRaised\":true") ??
- false),
+ selector: (_, participantsStore) => (participantsStore
+ .peer
+ .isHandRaised),
builder: (_,
isHandRaised,
__) {
@@ -457,7 +519,68 @@ class _ParticipantsBottomSheetState extends State {
);
}),
),
- )
+ ),
+ if ((HMSRoomLayout.offStageRoles
+ ?.contains(role) ??
+ false) &&
+ ((context
+ .read()
+ .peerListIterators[
+ role]
+ ?.totalCount ??
+ 0) >
+ 10))
+ Column(
+ children: [
+ Divider(
+ height: 5,
+ color: HMSThemeColors
+ .borderDefault,
+ ),
+ Padding(
+ padding:
+ const EdgeInsets.fromLTRB(
+ 16, 12, 16, 12),
+ child: GestureDetector(
+ onTap: () {
+ viewAll(role);
+ },
+ child: Row(
+ mainAxisAlignment:
+ MainAxisAlignment.end,
+ children: [
+ Row(
+ children: [
+ HMSSubheadingText(
+ text:
+ "View All",
+ textColor:
+ HMSThemeColors
+ .onSurfaceHighEmphasis),
+ Padding(
+ padding:
+ const EdgeInsets
+ .only(
+ left:
+ 4.0),
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/right_arrow.svg",
+ width: 24,
+ height: 24,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors
+ .onSurfaceHighEmphasis,
+ BlendMode
+ .srcIn)),
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
],
),
),
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/participants_view_all_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/participants_view_all_bottom_sheet.dart
new file mode 100644
index 000000000..2a0ecb79e
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/participants_view_all_bottom_sheet.dart
@@ -0,0 +1,582 @@
+///Dart imports
+import 'dart:convert';
+import 'dart:developer';
+
+///Package imports
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:hmssdk_flutter/hmssdk_flutter.dart';
+import 'package:provider/provider.dart';
+import 'package:tuple/tuple.dart';
+
+///Project imports
+import 'package:hms_room_kit/hms_room_kit.dart';
+import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
+import 'package:hms_room_kit/src/meeting/meeting_store.dart';
+import 'package:hms_room_kit/src/model/participant_store.dart';
+import 'package:hms_room_kit/src/model/peer_track_node.dart';
+import 'package:hms_room_kit/src/widgets/common_widgets/hms_cross_button.dart';
+import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_toasts_type.dart';
+
+///[ParticipantsViewAllBottomSheet] is a bottom sheet that is used to show all the participants of viewer groups for large rooms
+///This uses the [peerListIterator] next method to get the next set of peers
+class ParticipantsViewAllBottomSheet extends StatefulWidget {
+ final String role;
+
+ const ParticipantsViewAllBottomSheet({Key? key, required this.role})
+ : super(key: key);
+
+ @override
+ State createState() =>
+ _ParticipantsViewAllBottomSheetState();
+}
+
+class _ParticipantsViewAllBottomSheetState
+ extends State {
+ final ScrollController _scrollController = ScrollController();
+
+ @override
+ void initState() {
+ super.initState();
+ context.read().disableRefresh();
+ _scrollController.addListener(() {
+ if (_scrollController.position.pixels ==
+ _scrollController.position.maxScrollExtent) {
+ context.read().nextPeersForRole(widget.role);
+ }
+ });
+ }
+
+ @override
+ void dispose() {
+ _scrollController.dispose();
+ super.dispose();
+ }
+
+ Widget _kebabMenu(HMSPeer peer) {
+ final meetingStore = context.read();
+ PeerTrackNode? peerTrackNode;
+ try {
+ peerTrackNode = meetingStore.peerTracks
+ .firstWhere((element) => element.uid == "${peer.peerId}mainVideo");
+ } catch (e) {
+ peerTrackNode = null;
+ }
+
+ bool mutePermission =
+ meetingStore.localPeer?.role.permissions.mute ?? false;
+ bool removePeerPermission =
+ meetingStore.localPeer?.role.permissions.removeOthers ?? false;
+ bool changeRolePermission =
+ meetingStore.localPeer?.role.permissions.changeRole ?? false;
+ bool isOnStageRole = meetingStore.getOnStageRole()?.name == peer.role.name;
+ bool isOnStageExpPresent = HMSRoomLayout.peerType == PeerRoleType.hlsViewer
+ ? HMSRoomLayout.roleLayoutData?.screens?.conferencing?.hlsLiveStreaming
+ ?.elements?.onStageExp !=
+ null
+ : HMSRoomLayout.roleLayoutData?.screens?.conferencing?.defaultConf
+ ?.elements?.onStageExp !=
+ null;
+ bool isOffStageRole = meetingStore.isOffStageRole(peer.role.name);
+
+ ///Here we check whether to show three dots or not
+ ///We show three dots if the peer is not local
+ ///and the local peer has any of the following permissions:
+ ///changeRole, removeOthers, mute/unmute others
+ return (!peer.isLocal &&
+ (changeRolePermission || removePeerPermission || mutePermission))
+ ? PopupMenuButton(
+ padding: EdgeInsets.zero,
+ position: PopupMenuPosition.under,
+ color: HMSThemeColors.surfaceDefault,
+ shape:
+ RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
+ onSelected: (int value) async {
+ ///Here we have defined the functions to be executed on clicking the options
+ switch (value) {
+ case 1:
+
+ ///If the peer is onStage already we show the option to remove from stage
+ ///and the peer's role is changed to it's previous role
+ ///
+ ///If the peer is offStage we show the option to bring on stage
+ ///and the peer 's role is changed to offStageRole from layout api
+ ///We also update the peer metadata with the previous role
+ ///which will be used while removing the peer from stage
+ if (isOnStageRole) {
+ if (peer.metadata != null) {
+ String? peerMetadata = peer.metadata;
+ if (peerMetadata?.contains("prevRole") ?? false) {
+ String? previousRole =
+ jsonDecode(peer.metadata!)["prevRole"];
+ if (previousRole != null) {
+ try {
+ HMSRole? offStageRole = meetingStore.roles
+ .firstWhere(
+ (element) => element.name == previousRole);
+ meetingStore.changeRoleOfPeer(
+ peer: peer,
+ roleName: offStageRole,
+ forceChange: true);
+ return;
+ } catch (e) {
+ log(e.toString());
+ return;
+ }
+ }
+ }
+ }
+ }
+ HMSRole? onStageRole = meetingStore.getOnStageRole();
+ if (onStageRole != null) {
+ meetingStore.changeRoleOfPeer(
+ peer: peer, roleName: onStageRole, forceChange: false);
+ meetingStore.removeToast(HMSToastsType.roleChangeToast,
+ data: peer);
+ }
+ break;
+ case 2:
+
+ ///Here we lower the remote peer hand
+ meetingStore.lowerRemotePeerHand(peer);
+ break;
+ case 3:
+
+ ///Here we check whether the video track is null or not
+ if (peerTrackNode?.track == null) {
+ return;
+ }
+ meetingStore.changeTrackState(
+ peerTrackNode!.track!, !peerTrackNode.track!.isMute);
+ break;
+ case 4:
+
+ ///Here we check whether the audio track is null or not
+ if (peerTrackNode?.audioTrack == null) {
+ return;
+ }
+ meetingStore.changeTrackState(peerTrackNode!.audioTrack!,
+ !peerTrackNode.audioTrack!.isMute);
+ break;
+ case 5:
+
+ ///This is called when someone clicks on remove Participant
+ meetingStore.removePeerFromRoom(peer);
+ break;
+ default:
+ break;
+ }
+ },
+ child: Icon(
+ Icons.more_vert_rounded,
+ size: 20,
+ color: HMSThemeColors.onSurfaceHighEmphasis,
+ ),
+ itemBuilder: (context) => [
+ if (changeRolePermission &&
+ isOnStageExpPresent &&
+ (isOffStageRole || isOnStageRole))
+ PopupMenuItem(
+ value: 1,
+ child: Row(children: [
+ SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/change_role.svg",
+ width: 20,
+ height: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn)),
+ const SizedBox(
+ width: 8,
+ ),
+ HMSTitleText(
+ text: isOnStageRole
+ ? "Remove from Stage"
+ : "Bring on Stage",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ fontSize: 14,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ ),
+ ]),
+ ),
+ if (peer.isHandRaised)
+ PopupMenuItem(
+ value: 2,
+ child: Row(children: [
+ SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/lower_hand.svg",
+ width: 18,
+ height: 18,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn)),
+ const SizedBox(
+ width: 8,
+ ),
+ HMSTitleText(
+ text: "Lower Hand",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ fontSize: 14,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ ),
+ ]),
+ ),
+ if (mutePermission &&
+ peerTrackNode != null &&
+ !peerTrackNode.peer.isLocal)
+ PopupMenuItem(
+ value: 3,
+ child: Row(children: [
+ SvgPicture.asset(
+ peerTrackNode.track?.isMute ?? false
+ ? "packages/hms_room_kit/lib/src/assets/icons/cam_state_on.svg"
+ : "packages/hms_room_kit/lib/src/assets/icons/cam_state_off.svg",
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn),
+ width: 20,
+ height: 20,
+ ),
+ const SizedBox(
+ width: 8,
+ ),
+ HMSTitleText(
+ text:
+ "${peerTrackNode.track?.isMute ?? false ? "Unmute" : "Mute"} Video",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ fontSize: 14,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ ),
+ ]),
+ ),
+ if (mutePermission &&
+ peerTrackNode != null &&
+ !peerTrackNode.peer.isLocal)
+ PopupMenuItem(
+ value: 4,
+ child: Row(children: [
+ SvgPicture.asset(
+ peerTrackNode.audioTrack?.isMute ?? false
+ ? "packages/hms_room_kit/lib/src/assets/icons/mic_state_on.svg"
+ : "packages/hms_room_kit/lib/src/assets/icons/mic_state_off.svg",
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn),
+ width: 20,
+ height: 20,
+ ),
+ const SizedBox(
+ width: 8,
+ ),
+ HMSTitleText(
+ text:
+ "${peerTrackNode.audioTrack?.isMute ?? false ? "Unmute" : "Mute"} Audio",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ fontSize: 14,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ ),
+ ]),
+ ),
+ if (removePeerPermission)
+ PopupMenuItem(
+ value: 5,
+ child: Row(children: [
+ SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/peer_remove.svg",
+ width: 20,
+ height: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.alertErrorDefault,
+ BlendMode.srcIn)),
+ const SizedBox(
+ width: 8,
+ ),
+ HMSTitleText(
+ text: "Remove Participant",
+ textColor: HMSThemeColors.alertErrorDefault,
+ fontSize: 14,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ ),
+ ]),
+ ),
+ ])
+ : const SizedBox();
+ }
+
+ void resetData() {
+ context.read().enableRefresh();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return WillPopScope(
+ onWillPop: () async {
+ resetData();
+ return true;
+ },
+ child: SafeArea(
+ child: FractionallySizedBox(
+ heightFactor: 0.6,
+ child: Padding(
+ padding: const EdgeInsets.only(top: 12.0, left: 16, right: 16),
+ child: Column(
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ children: [
+ InkWell(
+ onTap: () {
+ resetData();
+ Navigator.pop(context);
+ },
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/left_arrow.svg",
+ width: 24,
+ height: 24,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn)),
+ ),
+ Padding(
+ padding: const EdgeInsets.only(left: 8.0),
+ child: HMSTitleText(
+ text: "Participants",
+ letterSpacing: 0.15,
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ ),
+ ),
+ ],
+ ),
+ HMSCrossButton(onPressed: () => resetData()),
+ ],
+ ),
+ Expanded(
+ child:
+ Selector>, int>>(
+ selector: (_, meetingStore) => Tuple2(
+ meetingStore.participantsInMeetingMap,
+ meetingStore.participantsInMeeting),
+ builder: (_, data, __) {
+ return ClipRRect(
+ borderRadius: BorderRadius.circular(8),
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: const BorderRadius.all(
+ Radius.circular(8)),
+ border: Border.fromBorderSide(
+ BorderSide(
+ color: HMSThemeColors.borderDefault,
+ width: 1),
+ )),
+ child: Column(
+ children: [
+ Row(
+ children: [
+ Padding(
+ padding: const EdgeInsets.symmetric(
+ horizontal: 16.0, vertical: 12),
+ child: HMSSubheadingText(
+ fontWeight: FontWeight.w600,
+ text: widget.role,
+ textColor: HMSThemeColors
+ .onSurfaceMediumEmphasis,
+ letterSpacing: 0.1,
+ ),
+ ),
+ ],
+ ),
+ Divider(
+ height: 5,
+ color: HMSThemeColors.borderDefault,
+ ),
+ Expanded(
+ child: ListView.builder(
+ controller: _scrollController,
+
+ ///We apply the check for showing loader here
+ itemCount: (data.item1[widget.role]
+ ?.length ??
+ 0) +
+ ((context
+ .read<
+ MeetingStore>()
+ .peerListIterators[
+ widget.role]
+ ?.totalCount ??
+ 0) >
+ (data.item1[widget.role]
+ ?.length ??
+ 0)
+ ? 1
+ : 0),
+ itemBuilder: (context, peerIndex) {
+ if (peerIndex ==
+ data.item1[widget.role]?.length) {
+ return Padding(
+ padding:
+ const EdgeInsets.symmetric(
+ vertical: 2.0),
+ child: Center(
+ child:
+ CircularProgressIndicator(
+ strokeWidth: 1,
+ color: HMSThemeColors
+ .primaryDefault,
+ ),
+ ),
+ );
+ }
+ ParticipantsStore currentPeer = data
+ .item1[widget.role]![peerIndex];
+ return Padding(
+ padding:
+ const EdgeInsets.only(top: 8.0),
+ child: Column(
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
+ children: [
+ Padding(
+ padding:
+ const EdgeInsets.fromLTRB(
+ 16, 8, 16, 16),
+ child:
+ ListenableProvider.value(
+ value: currentPeer,
+ child: Row(
+ mainAxisAlignment:
+ MainAxisAlignment
+ .spaceBetween,
+ children: [
+ Selector<
+ ParticipantsStore,
+ String>(
+ selector: (_,
+ participantsStore) =>
+ participantsStore
+ .peer.name,
+ builder: (_,
+ peerName, __) {
+ return HMSTitleText(
+ text: peerName +
+ ((data.item1[widget.role]![peerIndex].peer.isLocal)
+ ? " (You)"
+ : ""),
+ fontSize: 14,
+ lineHeight:
+ 20,
+ letterSpacing:
+ 0.1,
+ textColor:
+ HMSThemeColors
+ .onSurfaceHighEmphasis);
+ }),
+
+ ///This contains the network quality, hand raise icon and kebab menu
+ Row(
+ children: [
+ Selector<
+ ParticipantsStore,
+ int>(
+ selector: (_,
+ participantsStore) =>
+ (participantsStore
+ .peer
+ .networkQuality
+ ?.quality ??
+ -1),
+ builder: (_,
+ networkQuality,
+ __) {
+ return networkQuality !=
+ -1 &&
+ networkQuality <
+ 3
+ ? Padding(
+ padding: const EdgeInsets
+ .only(
+ right: 16.0),
+ child:
+ CircleAvatar(
+ radius:
+ 16,
+ backgroundColor:
+ HMSThemeColors.surfaceDefault,
+ child:
+ SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/network_$networkQuality.svg",
+ height: 16,
+ width: 16,
+ ),
+ ),
+ )
+ : Container();
+ }),
+ Selector<
+ ParticipantsStore,
+ bool>(
+ selector: (_,
+ participantsStore) =>
+ (participantsStore
+ .peer
+ .isHandRaised),
+ builder: (_,
+ isHandRaised,
+ __) {
+ return isHandRaised
+ ? Padding(
+ padding: const EdgeInsets
+ .only(
+ right: 16.0),
+ child:
+ CircleAvatar(
+ radius:
+ 16,
+ backgroundColor:
+ HMSThemeColors.surfaceDefault,
+ child:
+ SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/hand_outline.svg",
+ height: 16,
+ width: 16,
+ colorFilter: ColorFilter.mode(HMSThemeColors.onSurfaceHighEmphasis, BlendMode.srcIn),
+ ),
+ ),
+ )
+ : Container();
+ }),
+ _kebabMenu(
+ currentPeer
+ .peer)
+ ],
+ )
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }),
+ ),
+ ],
+ ),
+ ),
+ );
+ }),
+ )
+ ],
+ ),
+ ),
+ )),
+ );
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/remote_peer_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/remote_peer_bottom_sheet.dart
index e0f134fe2..709b7a608 100644
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/remote_peer_bottom_sheet.dart
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/remote_peer_bottom_sheet.dart
@@ -142,62 +142,67 @@ class _RemotePeerBottomSheetState extends State {
// text: "Spotlight Tile for Everyone",
// textColor: HMSThemeColors.onSurfaceHighEmphasis)),
- ListTile(
- horizontalTitleGap: 2,
- onTap: () async {
- Navigator.pop(context);
- if (widget.peerTrackNode.audioTrack != null) {
- widget.meetingStore.changeTrackState(
- widget.peerTrackNode.audioTrack!,
- !(widget.peerTrackNode.audioTrack!.isMute));
- }
- },
- contentPadding: EdgeInsets.zero,
- leading: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/${(widget.peerTrackNode.audioTrack?.isMute ?? true) ? "mic_state_on" : "mic_state_off"}.svg",
- semanticsLabel: "fl_mic_toggle",
- height: 20,
- width: 20,
- colorFilter: ColorFilter.mode(
- widget.peerTrackNode.audioTrack == null
+ if (widget.meetingStore.localPeer?.role.permissions.mute ??
+ false)
+ ListTile(
+ horizontalTitleGap: 2,
+ onTap: () async {
+ Navigator.pop(context);
+ if (widget.peerTrackNode.audioTrack != null) {
+ widget.meetingStore.changeTrackState(
+ widget.peerTrackNode.audioTrack!,
+ !(widget.peerTrackNode.audioTrack!.isMute));
+ }
+ },
+ contentPadding: EdgeInsets.zero,
+ leading: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/${(widget.peerTrackNode.audioTrack?.isMute ?? true) ? "mic_state_on" : "mic_state_off"}.svg",
+ semanticsLabel: "fl_mic_toggle",
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ widget.peerTrackNode.audioTrack == null
+ ? HMSThemeColors.onSurfaceLowEmphasis
+ : HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn),
+ ),
+ title: HMSSubheadingText(
+ text:
+ "${(widget.peerTrackNode.audioTrack?.isMute ?? true) ? "Unmute" : "Mute"} Audio",
+ textColor: widget.peerTrackNode.audioTrack == null
? HMSThemeColors.onSurfaceLowEmphasis
- : HMSThemeColors.onSurfaceHighEmphasis,
- BlendMode.srcIn),
- ),
- title: HMSSubheadingText(
- text:
- "${(widget.peerTrackNode.audioTrack?.isMute ?? true) ? "Unmute" : "Mute"} Audio",
- textColor: widget.peerTrackNode.audioTrack == null
- ? HMSThemeColors.onSurfaceLowEmphasis
- : HMSThemeColors.onSurfaceHighEmphasis)),
- ListTile(
- horizontalTitleGap: 2,
- onTap: () async {
- Navigator.pop(context);
- if (widget.peerTrackNode.track != null) {
- widget.meetingStore.changeTrackState(
- widget.peerTrackNode.track!,
- !(widget.peerTrackNode.track!.isMute));
- }
- },
- contentPadding: EdgeInsets.zero,
- leading: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/${(widget.peerTrackNode.track?.isMute ?? true) ? "cam_state_on" : "cam_state_off"}.svg",
- semanticsLabel: "fl_camera_toggle",
- height: 20,
- width: 20,
- colorFilter: ColorFilter.mode(
- widget.peerTrackNode.track == null
+ : HMSThemeColors.onSurfaceHighEmphasis)),
+
+ if (widget.meetingStore.localPeer?.role.permissions.mute ??
+ false)
+ ListTile(
+ horizontalTitleGap: 2,
+ onTap: () async {
+ Navigator.pop(context);
+ if (widget.peerTrackNode.track != null) {
+ widget.meetingStore.changeTrackState(
+ widget.peerTrackNode.track!,
+ !(widget.peerTrackNode.track!.isMute));
+ }
+ },
+ contentPadding: EdgeInsets.zero,
+ leading: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/${(widget.peerTrackNode.track?.isMute ?? true) ? "cam_state_on" : "cam_state_off"}.svg",
+ semanticsLabel: "fl_camera_toggle",
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ widget.peerTrackNode.track == null
+ ? HMSThemeColors.onSurfaceLowEmphasis
+ : HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn),
+ ),
+ title: HMSSubheadingText(
+ text:
+ "${(widget.peerTrackNode.track?.isMute ?? true) ? "Unmute" : "Mute"} Video",
+ textColor: widget.peerTrackNode.track == null
? HMSThemeColors.onSurfaceLowEmphasis
- : HMSThemeColors.onSurfaceHighEmphasis,
- BlendMode.srcIn),
- ),
- title: HMSSubheadingText(
- text:
- "${(widget.peerTrackNode.track?.isMute ?? true) ? "Unmute" : "Mute"} Video",
- textColor: widget.peerTrackNode.track == null
- ? HMSThemeColors.onSurfaceLowEmphasis
- : HMSThemeColors.onSurfaceHighEmphasis)),
+ : HMSThemeColors.onSurfaceHighEmphasis)),
// ListTile(
// horizontalTitleGap: 2,
// onTap: () async {
@@ -216,25 +221,29 @@ class _RemotePeerBottomSheetState extends State {
// title: HMSSubheadingText(
// text: "Volume",
// textColor: HMSThemeColors.onSurfaceHighEmphasis)),
- ListTile(
- horizontalTitleGap: 2,
- onTap: () async {
- Navigator.pop(context);
- widget.meetingStore
- .removePeerFromRoom(widget.peerTrackNode.peer);
- },
- contentPadding: EdgeInsets.zero,
- leading: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/peer_remove.svg",
- semanticsLabel: "fl_remove_peer",
- height: 20,
- width: 20,
- colorFilter: ColorFilter.mode(
- HMSThemeColors.alertErrorDefault, BlendMode.srcIn),
- ),
- title: HMSSubheadingText(
- text: "Remove Participant",
- textColor: HMSThemeColors.alertErrorDefault)),
+ if (widget.meetingStore.localPeer?.role.permissions
+ .removeOthers ??
+ false)
+ ListTile(
+ horizontalTitleGap: 2,
+ onTap: () async {
+ Navigator.pop(context);
+ widget.meetingStore
+ .removePeerFromRoom(widget.peerTrackNode.peer);
+ },
+ contentPadding: EdgeInsets.zero,
+ leading: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/peer_remove.svg",
+ semanticsLabel: "fl_remove_peer",
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.alertErrorDefault,
+ BlendMode.srcIn),
+ ),
+ title: HMSSubheadingText(
+ text: "Remove Participant",
+ textColor: HMSThemeColors.alertErrorDefault)),
],
),
),
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/viewer_settings_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/viewer_settings_bottom_sheet.dart
deleted file mode 100644
index 538a11b46..000000000
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/viewer_settings_bottom_sheet.dart
+++ /dev/null
@@ -1,317 +0,0 @@
-import 'dart:io';
-
-import 'package:flutter/material.dart';
-import 'package:flutter_svg/flutter_svg.dart';
-import 'package:hms_room_kit/src/widgets/common_widgets/hms_text_style.dart';
-import 'package:hms_room_kit/src/common/app_color.dart';
-import 'package:hms_room_kit/src/common/utility_components.dart';
-import 'package:hms_room_kit/src/widgets/app_dialogs/hls_aspect_ratio_option_dialog.dart';
-import 'package:hms_room_kit/src/widgets/bottom_sheets/participants_bottom_sheet.dart';
-import 'package:hms_room_kit/src/meeting/meeting_store.dart';
-import 'package:provider/provider.dart';
-import 'package:badges/badges.dart' as badge;
-
-import 'notification_settings_bottom_sheet.dart';
-
-class ViewerSettingsBottomSheet extends StatefulWidget {
- const ViewerSettingsBottomSheet({super.key});
-
- @override
- State createState() =>
- _ViewerSettingsBottomSheetState();
-}
-
-class _ViewerSettingsBottomSheetState extends State {
- bool isStatsEnabled = true;
- @override
- void initState() {
- super.initState();
- }
-
- @override
- Widget build(BuildContext context) {
- return FractionallySizedBox(
- heightFactor: 0.5,
- child: Padding(
- padding: const EdgeInsets.only(top: 20.0, left: 15, right: 15),
- child: SingleChildScrollView(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Row(
- children: [
- Text(
- "More Options",
- style: HMSTextStyle.setTextStyle(
- fontSize: 16,
- color: themeDefaultColor,
- letterSpacing: 0.15,
- fontWeight: FontWeight.w600),
- ),
- ],
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [
- IconButton(
- icon: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/close_button.svg",
- width: 40,
- ),
- onPressed: () {
- Navigator.pop(context);
- },
- ),
- ],
- )
- ],
- ),
- Padding(
- padding: const EdgeInsets.only(top: 15, bottom: 10),
- child: Divider(
- color: dividerColor,
- height: 5,
- ),
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- InkWell(
- onTap: () async {
- Navigator.pop(context);
- showModalBottomSheet(
- isScrollControlled: true,
- backgroundColor: themeBottomSheetColor,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(20),
- ),
- context: context,
- builder: (ctx) => ChangeNotifierProvider.value(
- value: context.read(),
- child: const ParticipantsBottomSheet()),
- );
- },
- child: Container(
- decoration: BoxDecoration(
- color: moreSettingsButtonColor,
- borderRadius: BorderRadius.circular(10)),
- height: 100,
- width: 150,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- badge.Badge(
- badgeStyle: badge.BadgeStyle(
- badgeColor: hmsdefaultColor,
- padding: EdgeInsets.all(
- context.read().peers.length <
- 1000
- ? 5
- : 8)),
- badgeContent: Text(context
- .read()
- .peers
- .length
- .toString()),
- child: Padding(
- padding: EdgeInsets.all(
- (context.read().peers.length <
- 1000
- ? 5
- : 10)),
- child: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/participants.svg",
- colorFilter: ColorFilter.mode(
- themeDefaultColor, BlendMode.srcIn),
- ),
- ),
- ),
- const SizedBox(height: 10),
- Text(
- "Participants",
- semanticsLabel: "participants_button",
- style: HMSTextStyle.setTextStyle(
- fontSize: 14,
- color: themeDefaultColor,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w600),
- )
- ],
- ),
- ),
- ),
- InkWell(
- onTap: () async {
- Navigator.pop(context);
- showDialog(
- context: context,
- builder: (_) => AspectRatioOptionDialog(
- //Default mode takes the height and width of the device and
- //sets up the player according to device height and width
- availableAspectRatios: const [
- "Default",
- "16:9",
- "4:3",
- "1:1",
- "3:4",
- "9:16"
- ],
- meetingStore: context.read(),
- ));
- },
- child: Container(
- decoration: BoxDecoration(
- color: moreSettingsButtonColor,
- borderRadius: BorderRadius.circular(10)),
- height: 100,
- width: 150,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/aspect_ratio.svg",
- colorFilter: ColorFilter.mode(
- themeDefaultColor, BlendMode.srcIn),
- ),
- const SizedBox(
- height: 10,
- ),
- Text(
- "Set Aspect Ratio",
- semanticsLabel: "fl_aspect_ratio",
- style: HMSTextStyle.setTextStyle(
- fontSize: 14,
- color: themeDefaultColor,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w600),
- ),
- ],
- ),
- ),
- )
- ],
- ),
- const SizedBox(
- height: 10,
- ),
- ListTile(
- horizontalTitleGap: 2,
- onTap: () async {
- FocusManager.instance.primaryFocus?.unfocus();
- String name = await UtilityComponents.showNameChangeDialog(
- context: context,
- placeholder: "Enter Name",
- prefilledValue:
- context.read().localPeer?.name ?? "");
-
- if (name.isNotEmpty && mounted) {
- context.read().changeName(name: name);
- }
- if (mounted) {
- Navigator.pop(context);
- }
- },
- contentPadding: EdgeInsets.zero,
- leading: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/pencil.svg",
- fit: BoxFit.scaleDown,
- ),
- title: Text(
- "Change Name",
- style: HMSTextStyle.setTextStyle(
- fontSize: 14,
- color: themeDefaultColor,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w600),
- ),
- ),
- ListTile(
- horizontalTitleGap: 2,
- onTap: () async {
- context.read().changeMetadata();
- Navigator.pop(context);
- },
- contentPadding: EdgeInsets.zero,
- leading: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/hand_outline.svg",
- fit: BoxFit.scaleDown,
- colorFilter: ColorFilter.mode(
- context.read().isRaisedHand
- ? errorColor
- : themeDefaultColor,
- BlendMode.srcIn),
- ),
- title: Text(
- "Raise Hand",
- semanticsLabel: "hand_raise_button",
- style: HMSTextStyle.setTextStyle(
- fontSize: 14,
- color: context.read().isRaisedHand
- ? errorColor
- : themeDefaultColor,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w600),
- )),
- ListTile(
- horizontalTitleGap: 2,
- onTap: () async {
- Navigator.pop(context);
- showModalBottomSheet(
- isScrollControlled: true,
- backgroundColor: themeBottomSheetColor,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(20),
- ),
- context: context,
- builder: (ctx) =>
- const NotificationSettingsBottomSheet());
- },
- contentPadding: EdgeInsets.zero,
- leading: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/notification.svg",
- fit: BoxFit.scaleDown,
- colorFilter:
- ColorFilter.mode(themeDefaultColor, BlendMode.srcIn),
- ),
- title: Text(
- "Modify Notifications",
- semanticsLabel: "fl_notification_setting",
- style: HMSTextStyle.setTextStyle(
- fontSize: 14,
- color: themeDefaultColor,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w600),
- )),
- if (Platform.isAndroid)
- ListTile(
- horizontalTitleGap: 2,
- onTap: () async {
- Navigator.pop(context);
- // context.read().enterPipModeOnAndroid();
- },
- contentPadding: EdgeInsets.zero,
- leading: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/screen_share.svg",
- fit: BoxFit.scaleDown,
- colorFilter:
- ColorFilter.mode(themeDefaultColor, BlendMode.srcIn),
- ),
- title: Text(
- "Enter Pip Mode",
- semanticsLabel: "fl_pip_mode",
- style: HMSTextStyle.setTextStyle(
- fontSize: 14,
- color: themeDefaultColor,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w600),
- )),
- ],
- ),
- ),
- ),
- );
- }
-}
diff --git a/packages/hms_room_kit/lib/src/widgets/peer_widgets/hand_raise.dart b/packages/hms_room_kit/lib/src/widgets/peer_widgets/hand_raise.dart
index 39a991484..bffabf294 100644
--- a/packages/hms_room_kit/lib/src/widgets/peer_widgets/hand_raise.dart
+++ b/packages/hms_room_kit/lib/src/widgets/peer_widgets/hand_raise.dart
@@ -13,9 +13,9 @@ class HandRaise extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return Selector(
- builder: (_, metadata, __) {
- return metadata?.contains("\"isHandRaised\":true") ?? false
+ return Selector(
+ builder: (_, isHandRaised, __) {
+ return isHandRaised
? Positioned(
top: 5,
left: 5,
@@ -45,6 +45,6 @@ class HandRaise extends StatelessWidget {
)
: Container();
},
- selector: (_, peerTrackNode) => peerTrackNode.peer.metadata);
+ selector: (_, peerTrackNode) => peerTrackNode.peer.isHandRaised);
}
}
diff --git a/packages/hms_room_kit/lib/src/widgets/peer_widgets/more_option.dart b/packages/hms_room_kit/lib/src/widgets/peer_widgets/more_option.dart
index 3bdce2dfe..41b70925c 100644
--- a/packages/hms_room_kit/lib/src/widgets/peer_widgets/more_option.dart
+++ b/packages/hms_room_kit/lib/src/widgets/peer_widgets/more_option.dart
@@ -22,53 +22,61 @@ class _MoreOptionState extends State {
@override
Widget build(BuildContext context) {
MeetingStore meetingStore = context.read();
+ bool mutePermission =
+ meetingStore.localPeer?.role.permissions.mute ?? false;
+ bool removeOthers =
+ meetingStore.localPeer?.role.permissions.removeOthers ?? false;
- return Positioned(
- bottom: 5,
- right: 5,
- child: GestureDetector(
- onTap: () {
- ///[peerTrackNode] is the peerTrackNode of the peer whose more option is clicked
- ///We only show the modal bottom sheet if the peer is not the local peer
- var peerTrackNode = context.read();
- if (peerTrackNode.peer.peerId != meetingStore.localPeer!.peerId) {
- showModalBottomSheet(
- isScrollControlled: true,
- backgroundColor: HMSThemeColors.surfaceDim,
- shape: const RoundedRectangleBorder(
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(16),
- topRight: Radius.circular(16)),
+ return (mutePermission || removeOthers)
+ ? Positioned(
+ bottom: 5,
+ right: 5,
+ child: GestureDetector(
+ onTap: () {
+ ///[peerTrackNode] is the peerTrackNode of the peer whose more option is clicked
+ ///We only show the modal bottom sheet if the peer is not the local peer
+ var peerTrackNode = context.read();
+ if (peerTrackNode.peer.peerId !=
+ meetingStore.localPeer!.peerId) {
+ showModalBottomSheet(
+ isScrollControlled: true,
+ backgroundColor: HMSThemeColors.surfaceDim,
+ shape: const RoundedRectangleBorder(
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(16),
+ topRight: Radius.circular(16)),
+ ),
+ context: context,
+ builder: (ctx) => ChangeNotifierProvider.value(
+ value: context.read(),
+ child: RemotePeerBottomSheet(
+ meetingStore: meetingStore,
+ peerTrackNode: peerTrackNode,
+ )),
+ );
+ }
+ },
+ child: Semantics(
+ label:
+ "fl_${context.read().peer.name}more_option",
+ child: Container(
+ height: 28,
+ width: 28,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8),
+ color: HMSThemeColors.backgroundDim.withOpacity(0.64),
+ ),
+ child: Center(
+ child: Icon(
+ Icons.more_vert,
+ color: HMSThemeColors.onSurfaceHighEmphasis,
+ size: 20,
+ ),
+ ),
+ ),
),
- context: context,
- builder: (ctx) => ChangeNotifierProvider.value(
- value: context.read(),
- child: RemotePeerBottomSheet(
- meetingStore: meetingStore,
- peerTrackNode: peerTrackNode,
- )),
- );
- }
- },
- child: Semantics(
- label: "fl_${context.read().peer.name}more_option",
- child: Container(
- height: 28,
- width: 28,
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(8),
- color: HMSThemeColors.backgroundDim.withOpacity(0.64),
),
- child: Center(
- child: Icon(
- Icons.more_vert,
- color: HMSThemeColors.onSurfaceHighEmphasis,
- size: 20,
- ),
- ),
- ),
- ),
- ),
- );
+ )
+ : Container();
}
}
diff --git a/packages/hms_room_kit/pubspec.lock b/packages/hms_room_kit/pubspec.lock
index a10f942b1..550e656a5 100644
--- a/packages/hms_room_kit/pubspec.lock
+++ b/packages/hms_room_kit/pubspec.lock
@@ -212,10 +212,10 @@ packages:
dependency: "direct main"
description:
name: hmssdk_flutter
- sha256: fb6cdad295b0c76be408beb9cef0fe3fab9aa25c775779943a68fab4e675628b
+ sha256: e8b12fbdde193bc0bfbf0ef40086840c0b8d056778f01c53f4efa15849f35e38
url: "https://pub.dev"
source: hosted
- version: "1.8.0"
+ version: "1.9.0"
http:
dependency: transitive
description:
diff --git a/packages/hms_room_kit/pubspec.yaml b/packages/hms_room_kit/pubspec.yaml
index 9bbe262dd..198e557e3 100644
--- a/packages/hms_room_kit/pubspec.yaml
+++ b/packages/hms_room_kit/pubspec.yaml
@@ -1,6 +1,6 @@
name: hms_room_kit
description: 100ms Room Kit provides simple & easy to use UI components to build Live Streaming & Video Conferencing experiences in your apps.
-version: 1.0.2
+version: 1.0.3
homepage: https://www.100ms.live/
repository: https://github.com/100mslive/100ms-flutter
issue_tracker: https://github.com/100mslive/100ms-flutter/issues
@@ -14,7 +14,7 @@ dependencies:
flutter:
sdk: flutter
- hmssdk_flutter: ^1.8.0
+ hmssdk_flutter: ^1.9.0
intl: ^0.18.1
permission_handler: ^11.0.0
provider: ^6.0.5
diff --git a/packages/hmssdk_flutter/CHANGELOG.md b/packages/hmssdk_flutter/CHANGELOG.md
index 1e50505cc..c22ac044e 100644
--- a/packages/hmssdk_flutter/CHANGELOG.md
+++ b/packages/hmssdk_flutter/CHANGELOG.md
@@ -5,6 +5,24 @@
| hms_room_kit | [![Pub Version](https://img.shields.io/pub/v/hms_room_kit)](https://pub.dev/packages/hms_room_kit) |
| hmssdk_flutter | [![Pub Version](https://img.shields.io/pub/v/hmssdk_flutter)](https://pub.dev/packages/hmssdk_flutter) |
+## 1.9.0 - 2023-10-16
+
+### Added
+
+- Large Room Support
+ - Added first class "Hand Raise" apis: `raiseLocalPeerHand`, `lowerLocalPeerHand`, `lowerRemotePeerHand`
+ - Added `onPeerListUpdate` event on `HMSUpdateListener`, This requires overriding the `onPeerListUpdate` method in all implementations of HMSUpdateListener.
+ - Added "Peer List Iterator" APIs - `getPeerListIterator`
+
+ For more details refer [here](https://www.100ms.live/docs/flutter/v2/how-to-guides/interact-with-room/peer/large-room)
+
+- Added `isHandRaised` property on `HMSPeer` class instance
+
+- Added `initialising` property on `HMSBrowserRecordingState` class instance
+
+Updated to Android SDK 2.7.7 & iOS SDK 1.1.0
+
+**Full Changelog**: [1.8.0...1.9.0](https://github.com/100mslive/100ms-flutter/compare/1.8.0...1.9.0)
## 1.8.0 - 2023-09-15
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSHLSVariantExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSHLSVariantExtension.kt
index ecd84e17c..823ea8296 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSHLSVariantExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSHLSVariantExtension.kt
@@ -11,8 +11,9 @@ class HMSHLSVariantExtension {
args["hls_stream_url"] = hmshlsVariant.hlsStreamUrl ?: ""
args["meeting_url"] = hmshlsVariant.meetingUrl ?: ""
args["metadata"] = hmshlsVariant.metadata ?: ""
- args["started_at"] =
- SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(hmshlsVariant.startedAt).toString()
+ hmshlsVariant.startedAt?.let {
+ args["started_at"] = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(it).toString()
+ }
return args
}
}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSPeerExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSPeerExtension.kt
index 603057d0c..60dbae826 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSPeerExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSPeerExtension.kt
@@ -15,6 +15,7 @@ class HMSPeerExtension {
args["is_local"] = peer.isLocal
args["role"] = HMSRoleExtension.toDictionary(peer.hmsRole)
args["metadata"] = peer.metadata
+ args["is_hand_raised"] = peer.isHandRaised
args["customer_user_id"] = peer.customerUserID
args["audio_track"] = HMSTrackExtension.toDictionary(peer.audioTrack)
args["video_track"] = HMSTrackExtension.toDictionary(peer.videoTrack)
@@ -41,6 +42,7 @@ class HMSPeerExtension {
HMSPeerUpdate.NETWORK_QUALITY_UPDATED -> "networkQualityUpdated"
HMSPeerUpdate.BECAME_DOMINANT_SPEAKER -> "becameDominantSpeaker"
HMSPeerUpdate.NO_DOMINANT_SPEAKER -> "noDominantSpeaker"
+ HMSPeerUpdate.HAND_RAISED_CHANGED -> "handRaiseUpdated"
else -> "defaultUpdate"
}
}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRtmpStreamingState.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRtmpStreamingState.kt
index 4c017f19c..e901b30ad 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRtmpStreamingState.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRtmpStreamingState.kt
@@ -36,7 +36,7 @@ class HMSStreamingState {
if (hmsBrowserRecordingState.running) {
map["started_at"] = SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(hmsBrowserRecordingState.startedAt).toString()
}
- map["initialising"] = false
+ map["initialising"] = hmsBrowserRecordingState.initialising
return map
}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt
index 48cde7094..224b55a5d 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt
@@ -164,8 +164,8 @@ class HmssdkFlutterPlugin :
}
// MARK: Peer Actions
- "change_metadata", "change_name" -> {
- peerActions(call, result)
+ "change_metadata", "change_name", "raise_local_peer_hand", "lower_local_peer_hand", "lower_remote_peer_hand" -> {
+ HMSPeerAction.peerActions(call, result, hmssdk!!)
}
// MARK: Recording
@@ -241,6 +241,9 @@ class HmssdkFlutterPlugin :
"get_room_layout" -> {
getRoomLayout(call, result)
}
+ "get_peer_list_iterator", "peer_list_iterator_has_next", "peer_list_iterator_next" -> {
+ HMSPeerListIteratorAction.peerListIteratorAction(call, result, hmssdk!!)
+ }
else -> {
result.notImplemented()
}
@@ -322,25 +325,6 @@ class HmssdkFlutterPlugin :
}
}
- // MARK: Peer Actions
- private fun peerActions(
- call: MethodCall,
- result: Result,
- ) {
- when (call.method) {
- "change_metadata" -> {
- changeMetadata(call, result)
- }
- "change_name" -> {
- changeName(call, result)
- }
-
- else -> {
- result.notImplemented()
- }
- }
- }
-
// MARK: Logger
private fun loggerActions(
call: MethodCall,
@@ -539,6 +523,7 @@ class HmssdkFlutterPlugin :
private fun leave(result: Result) {
hmssdk!!.leave(hmsActionResultListener = HMSCommonAction.getActionListener(result))
HMSPipAction.disposePIP(activity)
+ HMSPeerListIteratorAction.clearIteratorMap()
removeAllKeyChangeListener()
}
@@ -884,6 +869,7 @@ class HmssdkFlutterPlugin :
hmsActionResultListener = HMSCommonAction.getActionListener(result),
)
HMSPipAction.disposePIP(activity)
+ HMSPeerListIteratorAction.clearIteratorMap()
removeAllKeyChangeListener()
}
@@ -975,21 +961,6 @@ class HmssdkFlutterPlugin :
result.success(true)
}
- private var hasChangedMetadata: Boolean = false
-
- private fun changeMetadata(
- call: MethodCall,
- result: Result,
- ) {
- hasChangedMetadata = !hasChangedMetadata
- val metadata = call.argument("metadata")
-
- hmssdk!!.changeMetadata(
- metadata!!,
- hmsActionResultListener = HMSCommonAction.getActionListener(result),
- )
- }
-
private val hmsUpdateListener =
object : HMSUpdateListener {
override fun onChangeTrackStateRequest(details: HMSChangeTrackStateRequest) {
@@ -1137,6 +1108,7 @@ class HmssdkFlutterPlugin :
if (HMSPipAction.isPIPActive(activity)) {
activity.moveTaskToBack(true)
HMSPipAction.disposePIP(activity)
+ HMSPeerListIteratorAction.clearIteratorMap()
removeAllKeyChangeListener()
}
if (args["data"] != null) {
@@ -1183,6 +1155,37 @@ class HmssdkFlutterPlugin :
eventSink?.success(args)
}
}
+
+ override fun peerListUpdated(
+ addedPeers: ArrayList?,
+ removedPeers: ArrayList?,
+ ) {
+ val args = HashMap()
+ args["event_name"] = "on_peer_list_update"
+ val parameters = HashMap()
+ val peersAdded = ArrayList?>()
+ val peersRemoved = ArrayList?>()
+ /**
+ * Here we add peers to the list after parsing the
+ * peer object
+ */
+ addedPeers?.forEach { peer ->
+ peersAdded.add(HMSPeerExtension.toDictionary(peer))
+ }
+
+ removedPeers?.forEach { peer ->
+ peersRemoved.add(HMSPeerExtension.toDictionary(peer))
+ }
+
+ parameters["added_peers"] = peersAdded
+ parameters["removed_peers"] = peersRemoved
+
+ args["data"] = parameters
+
+ CoroutineScope(Dispatchers.Main).launch {
+ eventSink?.success(args)
+ }
+ }
}
private val hmsPreviewListener =
@@ -1302,17 +1305,6 @@ class HmssdkFlutterPlugin :
logsBuffer.clear()
}
- private fun changeName(
- call: MethodCall,
- result: Result,
- ) {
- val name = call.argument("name")
- hmssdk!!.changeName(
- name = name!!,
- hmsActionResultListener = HMSCommonAction.getActionListener(result),
- )
- }
-
fun onVideoViewError(
methodName: String,
error: String,
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/PeerListIteratorExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/PeerListIteratorExtension.kt
new file mode 100644
index 000000000..63fc4142a
--- /dev/null
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/PeerListIteratorExtension.kt
@@ -0,0 +1,20 @@
+package live.hms.hmssdk_flutter
+
+import live.hms.video.sdk.models.PeerListIterator
+
+class PeerListIteratorExtension {
+ companion object {
+ fun toDictionary(
+ peerListIterator: PeerListIterator,
+ uid: String,
+ ): HashMap {
+ val map = HashMap()
+
+ map["limit"] = peerListIterator.limit
+ map["total_count"] = peerListIterator.totalCount
+ map["uid"] = uid
+
+ return map
+ }
+ }
+}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPeerAction.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPeerAction.kt
new file mode 100644
index 000000000..03c6bd0c2
--- /dev/null
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPeerAction.kt
@@ -0,0 +1,103 @@
+package live.hms.hmssdk_flutter.methods
+
+import io.flutter.plugin.common.MethodCall
+import io.flutter.plugin.common.MethodChannel
+import live.hms.hmssdk_flutter.HMSCommonAction
+import live.hms.video.sdk.HMSSDK
+import live.hms.video.sdk.models.HMSPeer
+
+class HMSPeerAction {
+ companion object {
+ // MARK: Peer Actions
+ fun peerActions(
+ call: MethodCall,
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
+ when (call.method) {
+ "change_metadata" -> {
+ changeMetadata(call, result, hmssdk)
+ }
+ "change_name" -> {
+ changeName(call, result, hmssdk)
+ }
+ "raise_local_peer_hand" -> {
+ raiseLocalPeerHand(result, hmssdk)
+ }
+ "lower_local_peer_hand" -> {
+ lowerLocalPeerHand(result, hmssdk)
+ }
+ "lower_remote_peer_hand" -> {
+ lowerRemotePeerHand(call, result, hmssdk)
+ }
+ else -> {
+ result.notImplemented()
+ }
+ }
+ }
+
+ private fun changeMetadata(
+ call: MethodCall,
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
+ val metadata = call.argument("metadata")
+
+ metadata?.let {
+ hmssdk.changeMetadata(
+ it,
+ hmsActionResultListener = HMSCommonAction.getActionListener(result),
+ )
+ }
+ }
+
+ private fun changeName(
+ call: MethodCall,
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
+ val name = call.argument("name")
+
+ name?.let {
+ hmssdk.changeName(
+ name = name,
+ hmsActionResultListener = HMSCommonAction.getActionListener(result),
+ )
+ }
+ }
+
+ private fun lowerLocalPeerHand(
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
+ hmssdk.lowerLocalPeerHand(HMSCommonAction.getActionListener(result))
+ }
+
+ private fun raiseLocalPeerHand(
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
+ hmssdk.raiseLocalPeerHand(HMSCommonAction.getActionListener(result))
+ }
+
+ private fun lowerRemotePeerHand(
+ call: MethodCall,
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
+ val peerId = call.argument("peer_id")
+ peerId?.let {
+ var forPeer: HMSPeer? = null
+ hmssdk.getPeers().forEach { peer ->
+ if (peer.peerID == peerId) {
+ forPeer = peer
+ return@forEach
+ }
+ }
+ forPeer?.let {
+ hmssdk.lowerRemotePeerHand(it, HMSCommonAction.getActionListener(result))
+ }
+ }
+ }
+ }
+}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPeerListIteratorAction.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPeerListIteratorAction.kt
new file mode 100644
index 000000000..8bc585269
--- /dev/null
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPeerListIteratorAction.kt
@@ -0,0 +1,161 @@
+package live.hms.hmssdk_flutter.methods
+
+import io.flutter.plugin.common.MethodCall
+import io.flutter.plugin.common.MethodChannel
+import live.hms.hmssdk_flutter.*
+import live.hms.video.error.HMSException
+import live.hms.video.sdk.HMSSDK
+import live.hms.video.sdk.listeners.PeerListResultListener
+import live.hms.video.sdk.models.HMSPeer
+import live.hms.video.sdk.models.PeerListIterator
+import live.hms.video.sdk.models.PeerListIteratorOptions
+
+class HMSPeerListIteratorAction {
+ companion object {
+ /**
+ * [peerListIterators] stores the iterators with unique id's.
+ * This is used whenever we call [peerListIteratorHasNext], or [peerListIteratorNext]
+ * we fetch the respective peerListIterator based on the uid passed from flutter channel
+ * and execute the method based on it.
+ */
+ private var peerListIterators = HashMap()
+
+ fun peerListIteratorAction(
+ call: MethodCall,
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
+ when (call.method) {
+ "get_peer_list_iterator" -> {
+ getPeerListIterator(call, result, hmssdk)
+ }
+ "peer_list_iterator_has_next" -> {
+ peerListIteratorHasNext(call, result)
+ }
+ "peer_list_iterator_next" -> {
+ peerListIteratorNext(call, result)
+ }
+ }
+ }
+
+ /**
+ * This method returns the peer list iterator based on the parameter we pass from flutter channel
+ */
+ private fun getPeerListIterator(
+ call: MethodCall,
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
+ val uid = call.argument("uid")
+
+ uid?.let { id ->
+ val peerListOptionsMap = call.argument?>("peer_list_iterator_options")
+
+ var peerListIteratorOptions: PeerListIteratorOptions? = null
+
+ peerListOptionsMap?.let {
+ val limit = it["limit"] as Int?
+
+ limit?.let { limitValue ->
+ peerListIteratorOptions =
+ PeerListIteratorOptions(
+ byRoleName = it["by_role_name"] as String?,
+ byPeerIds = it["by_peer_ids"] as ArrayList?, limit = limitValue,
+ )
+ } ?: run {
+ HMSErrorLogger.returnHMSException("getPeerListIterator", "limit parameter is null while peerListIteratorOptions is non-null", "NULL Error", result)
+ }
+ }
+
+ val peerListIterator = hmssdk.getPeerListIterator(peerListIteratorOptions)
+
+ /**
+ * We store the iterator in [peerListIterators] map for later operations with key as [id] which unique
+ * id for the iterator
+ */
+ peerListIterators[id] = peerListIterator
+
+ result.success(HMSResultExtension.toDictionary(true, PeerListIteratorExtension.toDictionary(peerListIterator, id)))
+ } ?: run {
+ HMSErrorLogger.returnHMSException("getPeerListIterator", "uid is null", "NULL Error", result)
+ }
+ }
+
+ /**
+ * Method to check whether iterator has next set of peers or not
+ */
+ private fun peerListIteratorHasNext(
+ call: MethodCall,
+ result: MethodChannel.Result,
+ ) {
+ val uid = call.argument("uid")
+
+ uid?.let {
+ /**
+ * Here we find the iterator with [uid] passed from flutter channel
+ * Since we need to perform the operation on that specific iterator
+ */
+ val peerListIterator = peerListIterators[it]
+
+ peerListIterator?.let { iterator ->
+ result.success(HMSResultExtension.toDictionary(true, iterator.hasNext()))
+ } ?: run {
+ HMSErrorLogger.returnHMSException("peerListIteratorHasNext", "No peerListIterator with given uid found", "NULL Error", result)
+ }
+ } ?: run {
+ HMSErrorLogger.returnHMSException("peerListIteratorHasNext", "uid is null", "NULL Error", result)
+ }
+ }
+
+ /**
+ * Method to get a list of next set of peers in iterator, the number of peers returned is equal to
+ * the limit.
+ */
+ private fun peerListIteratorNext(
+ call: MethodCall,
+ methodChannelResult: MethodChannel.Result,
+ ) {
+ val uid = call.argument("uid")
+
+ uid?.let {
+ /**
+ * Here we find the iterator with [uid] passed from flutter channel
+ * Since we need to perform the operation on that specific iterator
+ */
+ val peerListIterator = peerListIterators[it]
+
+ peerListIterator?.let { iterator ->
+ iterator.next(
+ object : PeerListResultListener {
+ override fun onError(error: HMSException) {
+ methodChannelResult.success(HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)))
+ }
+
+ override fun onSuccess(result: ArrayList) {
+ val data = HashMap()
+ val peerList = ArrayList()
+ result.forEach { peer ->
+ peerList.add(HMSPeerExtension.toDictionary(peer))
+ }
+ data["peers"] = peerList
+ data["total_count"] = iterator.totalCount
+ methodChannelResult.success(HMSResultExtension.toDictionary(true, data))
+ }
+ },
+ )
+ } ?: run {
+ HMSErrorLogger.returnHMSException("peerListIteratorNext", "No peerListIterator with given uid found", "NULL Error", methodChannelResult)
+ }
+ } ?: run {
+ HMSErrorLogger.returnHMSException("peerListIteratorNext", "uid is null", "NULL Error", methodChannelResult)
+ }
+ }
+
+ /**
+ * This method clears the iterator map on leave, end Room or onRemovedFromRoom method calls
+ */
+ fun clearIteratorMap() {
+ peerListIterators.clear()
+ }
+ }
+}
diff --git a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt
index 081543974..f3ac83c9c 100644
--- a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt
+++ b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt
@@ -1,17 +1,21 @@
-Board: https://github.com/100mslive/100ms-flutter/projects/30
+Board: https://100ms.atlassian.net/jira/software/projects/FLUT/boards/34/
-- Setting the HLS Player aspect ratio as per video stream content
-https://github.com/100mslive/100ms-flutter/pull/1556
+- Fixed userid bug in prebuilt
+https://github.com/100mslive/100ms-flutter/pull/1601
-- Error Toasts as per Figma design
-https://github.com/100mslive/100ms-flutter/issues/1489
+- Added first class api for hand raise and peer list updates
+https://github.com/100mslive/100ms-flutter/pull/1600
-- Added layout honouring of Layout API config
-https://github.com/100mslive/100ms-flutter/pull/1557
+- Added peer list iterator changes for large rooms
+https://github.com/100mslive/100ms-flutter/pull/1602
-- Updated to Android SDK version to 2.7.3 and iOS SDK version to 0.9.11
+Bug fixes:
-Room Kit: 1.0.1
-Core SDK: 1.8.0
-Android SDK: 2.7.6
-iOS SDK: 0.9.12
\ No newline at end of file
+- Fix for local tile inset when inset is disabled after role changed
+
+- VoS joined from flutter cannot be removed from stage
+
+Room Kit: 1.0.3
+Core SDK: 1.9.0
+Android SDK: 2.7.7
+iOS SDK: 1.1.0
\ No newline at end of file
diff --git a/packages/hmssdk_flutter/example/android/app/build.gradle b/packages/hmssdk_flutter/example/android/app/build.gradle
index 1e7216cca..7e316683d 100644
--- a/packages/hmssdk_flutter/example/android/app/build.gradle
+++ b/packages/hmssdk_flutter/example/android/app/build.gradle
@@ -32,8 +32,8 @@ android {
applicationId "live.hms.flutter"
minSdkVersion 21
targetSdkVersion 33
- versionCode 361
- versionName "1.5.61"
+ versionCode 373
+ versionName "1.5.73"
}
signingConfigs {
diff --git a/packages/hmssdk_flutter/example/ios/Podfile.lock b/packages/hmssdk_flutter/example/ios/Podfile.lock
index b2cfc57f3..4f433afa8 100644
--- a/packages/hmssdk_flutter/example/ios/Podfile.lock
+++ b/packages/hmssdk_flutter/example/ios/Podfile.lock
@@ -25,15 +25,15 @@ PODS:
- Firebase/Performance (= 10.9.0)
- firebase_core
- Flutter
- - FirebaseABTesting (10.15.0):
+ - FirebaseABTesting (10.16.0):
- FirebaseCore (~> 10.0)
- FirebaseCore (10.9.0):
- FirebaseCoreInternal (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/Logger (~> 7.8)
- - FirebaseCoreExtension (10.15.0):
+ - FirebaseCoreExtension (10.16.0):
- FirebaseCore (~> 10.0)
- - FirebaseCoreInternal (10.15.0):
+ - FirebaseCoreInternal (10.16.0):
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- FirebaseCrashlytics (10.9.0):
- FirebaseCore (~> 10.5)
@@ -45,7 +45,7 @@ PODS:
- PromisesObjC (~> 2.1)
- FirebaseDynamicLinks (10.9.0):
- FirebaseCore (~> 10.0)
- - FirebaseInstallations (10.15.0):
+ - FirebaseInstallations (10.16.0):
- FirebaseCore (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- GoogleUtilities/UserDefaults (~> 7.8)
@@ -60,13 +60,13 @@ PODS:
- GoogleUtilities/ISASwizzler (~> 7.8)
- GoogleUtilities/MethodSwizzler (~> 7.8)
- nanopb (< 2.30910.0, >= 2.30908.0)
- - FirebaseRemoteConfig (10.15.0):
+ - FirebaseRemoteConfig (10.16.0):
- FirebaseABTesting (~> 10.0)
- FirebaseCore (~> 10.0)
- FirebaseInstallations (~> 10.0)
- GoogleUtilities/Environment (~> 7.8)
- "GoogleUtilities/NSData+zlib (~> 7.8)"
- - FirebaseSessions (10.15.0):
+ - FirebaseSessions (10.16.0):
- FirebaseCore (~> 10.5)
- FirebaseCoreExtension (~> 10.0)
- FirebaseInstallations (~> 10.0)
@@ -95,14 +95,14 @@ PODS:
- HMSBroadcastExtensionSDK (0.0.9)
- HMSHLSPlayerSDK (0.0.2):
- HMSAnalyticsSDK (= 0.0.2)
- - HMSSDK (0.9.12):
+ - HMSSDK (1.1.0):
- HMSAnalyticsSDK (= 0.0.2)
- HMSWebRTC (= 1.0.5116)
- - hmssdk_flutter (1.8.0):
+ - hmssdk_flutter (1.9.0):
- Flutter
- HMSBroadcastExtensionSDK (= 0.0.9)
- HMSHLSPlayerSDK (= 0.0.2)
- - HMSSDK (= 0.9.12)
+ - HMSSDK (= 1.1.0)
- HMSWebRTC (1.0.5116)
- MTBBarcodeScanner (5.0.11)
- nanopb (2.30909.0):
@@ -214,16 +214,16 @@ SPEC CHECKSUMS:
firebase_crashlytics: 9b80d1944507cc07fa1c4455797f7d2eb7c8873f
firebase_dynamic_links: db9f2ebcc3ea646e76a1d3ee37e9e57890ff0a83
firebase_performance: d11d1fd9591547f6b75f325aaadd6550eaf7e090
- FirebaseABTesting: 7fa3bca17f79ac433301d20d5cd33401f7738dca
+ FirebaseABTesting: 03f0a8b88cf618350527f2c6a2234e29b9c65064
FirebaseCore: b68d3616526ec02e4d155166bbafb8eca64af557
- FirebaseCoreExtension: d3f1ea3725fb41f56e8fbfb29eeaff54e7ffb8f6
- FirebaseCoreInternal: 2f4bee5ed00301b5e56da0849268797a2dd31fb4
+ FirebaseCoreExtension: 2dbc745b337eb99d2026a7a309ae037bd873f45e
+ FirebaseCoreInternal: 26233f705cc4531236818a07ac84d20c333e505a
FirebaseCrashlytics: b60329455285aff853e54139d8ddbfe1e5f2b9f9
FirebaseDynamicLinks: 8cb66c4f403aa6ddf86ff3bc3c383a652f344ce9
- FirebaseInstallations: cae95cab0f965ce05b805189de1d4c70b11c76fb
+ FirebaseInstallations: b822f91a61f7d1ba763e5ccc9d4f2e6f2ed3b3ee
FirebasePerformance: eee2f5da94fd7e5d15487649f8fe10a90c87c174
- FirebaseRemoteConfig: 64b6ada098c649304114a817effd7e5f87229b11
- FirebaseSessions: ee59a7811bef4c15f65ef6472f3210faa293f9c8
+ FirebaseRemoteConfig: 17ec974c6cac5cdc6cf8297062c2219851857f06
+ FirebaseSessions: 96e7781e545929cde06dd91088ddbb0841391b43
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
flutter_foreground_task: 21ef182ab0a29a3005cc72cd70e5f45cb7f7f817
GoogleDataTransport: 54dee9d48d14580407f8f5fbf2f496e92437a2f2
@@ -231,8 +231,8 @@ SPEC CHECKSUMS:
HMSAnalyticsSDK: 4d2a88a729b1eb42f3d25f217c28937ec318a5b7
HMSBroadcastExtensionSDK: d80fe325f6c928bd8e5176290b5a4b7ae15d6fbb
HMSHLSPlayerSDK: 6a54ad4d12f3dc2270d1ecd24019d71282a4f6a3
- HMSSDK: 65c1445ad2aac04deb127fe7611f65b8e7447752
- hmssdk_flutter: 806162401c1c9dd1fca07d913b9ee5f1e1d36930
+ HMSSDK: 49e3ac665ceb8904d41787ddf99742e8d7d6529a
+ hmssdk_flutter: 414edcdff09f1587f53b04e9b93b39e6174a61cd
HMSWebRTC: ae54e9dd91b869051b283b43b14f57d43b7bf8e1
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
@@ -249,4 +249,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 919064996fff867cd85dbf9e7730ff45bac23884
-COCOAPODS: 1.12.1
+COCOAPODS: 1.13.0
diff --git a/packages/hmssdk_flutter/example/ios/Runner.xcodeproj/project.pbxproj b/packages/hmssdk_flutter/example/ios/Runner.xcodeproj/project.pbxproj
index 604654b08..b4f14f7ae 100644
--- a/packages/hmssdk_flutter/example/ios/Runner.xcodeproj/project.pbxproj
+++ b/packages/hmssdk_flutter/example/ios/Runner.xcodeproj/project.pbxproj
@@ -199,15 +199,15 @@
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
D769E267F13386F26EC49DC5 /* [CP] Check Pods Manifest.lock */,
+ 9705A1C41CF9048500538489 /* Embed Frameworks */,
+ EC1052BA2858A77D005EAB9E /* Embed App Extensions */,
+ 7B56423DDF1948A38AE2EA10 /* [CP] Embed Pods Frameworks */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
- 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
- 7B56423DDF1948A38AE2EA10 /* [CP] Embed Pods Frameworks */,
CC19BBB77EA3E7F699588CF7 /* [firebase_crashlytics] Crashlytics Upload Symbols */,
- EC1052BA2858A77D005EAB9E /* Embed App Extensions */,
);
buildRules = (
);
@@ -312,7 +312,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
};
402164D3899CD572C6304156 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
@@ -386,7 +386,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
- shellScript = "\"$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" --flutter-project \"$PROJECT_DIR/firebase_app_id_file.json\" ";
+ shellScript = "\"$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" --flutter-project \"$PROJECT_DIR/firebase_app_id_file.json\" \n";
};
D769E267F13386F26EC49DC5 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
diff --git a/packages/hmssdk_flutter/example/ios/Runner/Info.plist b/packages/hmssdk_flutter/example/ios/Runner/Info.plist
index 304eaacf5..208abe8c4 100644
--- a/packages/hmssdk_flutter/example/ios/Runner/Info.plist
+++ b/packages/hmssdk_flutter/example/ios/Runner/Info.plist
@@ -21,7 +21,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 1.5.62
+ 1.5.73
CFBundleSignature
????
CFBundleURLTypes
@@ -48,7 +48,7 @@
CFBundleVersion
- 362
+ 373
ITSAppUsesNonExemptEncryption
LSApplicationCategoryType
diff --git a/packages/hmssdk_flutter/example/lib/main.dart b/packages/hmssdk_flutter/example/lib/main.dart
index 7c237aa56..7f7ae1c85 100644
--- a/packages/hmssdk_flutter/example/lib/main.dart
+++ b/packages/hmssdk_flutter/example/lib/main.dart
@@ -309,6 +309,8 @@ class _HomePageState extends State {
roomCode: Constant.roomCode,
options: HMSPrebuiltOptions(
endPoints: endPoints,
+ userId:
+ "user_flutter", // pass your custom unique user identifier here
iOSScreenshareConfig: HMSIOSScreenshareConfig(
appGroup: "group.flutterhms",
preferredExtension:
diff --git a/packages/hmssdk_flutter/example/pubspec.lock b/packages/hmssdk_flutter/example/pubspec.lock
index 34365429e..3274e9089 100644
--- a/packages/hmssdk_flutter/example/pubspec.lock
+++ b/packages/hmssdk_flutter/example/pubspec.lock
@@ -294,15 +294,14 @@ packages:
path: "../../hms_room_kit"
relative: true
source: path
- version: "1.0.2"
+ version: "1.0.3"
hmssdk_flutter:
dependency: transitive
description:
- name: hmssdk_flutter
- sha256: fb6cdad295b0c76be408beb9cef0fe3fab9aa25c775779943a68fab4e675628b
- url: "https://pub.dev"
- source: hosted
- version: "1.8.0"
+ path: ".."
+ relative: true
+ source: path
+ version: "1.9.0"
http:
dependency: transitive
description:
diff --git a/packages/hmssdk_flutter/example/pubspec.yaml b/packages/hmssdk_flutter/example/pubspec.yaml
index 7fce87ec0..da0a18b7b 100644
--- a/packages/hmssdk_flutter/example/pubspec.yaml
+++ b/packages/hmssdk_flutter/example/pubspec.yaml
@@ -4,7 +4,7 @@ description: Demonstrates how to use the hmssdk_flutter plugin.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: "none" # Remove this line if you wish to publish to pub.dev
-version: 1.8.0
+version: 1.9.0
environment:
sdk: ">=2.16.0 <4.0.0"
diff --git a/packages/hmssdk_flutter/ios/Classes/Actions/HMSPeerAction.swift b/packages/hmssdk_flutter/ios/Classes/Actions/HMSPeerAction.swift
new file mode 100644
index 000000000..c1031131c
--- /dev/null
+++ b/packages/hmssdk_flutter/ios/Classes/Actions/HMSPeerAction.swift
@@ -0,0 +1,110 @@
+//
+// HMSPeerAction.swift
+// hmssdk_flutter
+//
+// Created by Pushpam on 27/09/23.
+//
+
+import Foundation
+import HMSSDK
+
+class HMSPeerAction {
+
+ static func peerActions(_ call: FlutterMethodCall, _ result: @escaping FlutterResult, _ hmsSDK: HMSSDK?) {
+ switch call.method {
+ case "change_metadata":
+ changeMetadata(call, result, hmsSDK)
+
+ case "change_name":
+ changeName(call, result, hmsSDK)
+
+ case "lower_remote_peer_hand":
+ lowerRemotePeerHand(call, result, hmsSDK)
+
+ case "raise_local_peer_hand":
+ raiseLocalPeerHand(result, hmsSDK)
+
+ case "lower_local_peer_hand":
+ lowerLocalPeerHand(result, hmsSDK)
+
+ default:
+ result(FlutterMethodNotImplemented)
+ }
+ }
+
+ static private func changeName(_ call: FlutterMethodCall, _ result: @escaping FlutterResult, _ hmsSDK: HMSSDK?) {
+
+ let arguments = call.arguments as![AnyHashable: Any]
+
+ guard let name = arguments["name"] as? String else {
+ result(HMSErrorExtension.getError("No name found in \(#function)"))
+ return
+ }
+ hmsSDK?.change(name: name) { _, error in
+ if let error = error {
+ result(HMSErrorExtension.toDictionary(error))
+ } else {
+ result(nil)
+ }
+
+ }
+ }
+
+ static private func changeMetadata(_ call: FlutterMethodCall, _ result: @escaping FlutterResult, _ hmsSDK: HMSSDK?) {
+
+ let arguments = call.arguments as! [AnyHashable: Any]
+
+ guard let metadata = arguments["metadata"] as? String else {
+ result(HMSErrorExtension.getError("No metadata found in \(#function)"))
+ return
+ }
+ hmsSDK?.change(metadata: metadata) {_, error in
+ if let error = error {
+ result(HMSErrorExtension.toDictionary(error))
+ return
+ } else {
+ result(nil)
+ }
+ }
+ }
+
+ static private func lowerLocalPeerHand(_ result: @escaping FlutterResult, _ hmsSDK: HMSSDK?) {
+ hmsSDK?.lowerLocalPeerHand {
+ _, error in if let error = error {
+ result(HMSErrorExtension.toDictionary(error))
+ } else {
+ result(nil)
+ }
+ }
+ }
+
+ static private func raiseLocalPeerHand(_ result: @escaping FlutterResult, _ hmsSDK: HMSSDK?) {
+ hmsSDK?.raiseLocalPeerHand {
+ _, error in if let error = error {
+ result(HMSErrorExtension.toDictionary(error))
+ } else {
+ result(nil)
+ }
+ }
+ }
+
+ static private func lowerRemotePeerHand(_ call: FlutterMethodCall, _ result: @escaping FlutterResult, _ hmsSDK: HMSSDK? ) {
+
+ let arguments = call.arguments as? [AnyHashable: Any]
+
+ guard let peerId = arguments?["peer_id"] as? String,
+ let forPeer = HMSCommonAction.getPeer(by: peerId, hmsSDK: hmsSDK)
+ else {
+ HMSErrorLogger.returnArgumentsError("forPeer is null")
+ return
+ }
+
+ hmsSDK?.lowerRemotePeerHand(forPeer) { _, error in
+ if let error = error {
+ result(HMSErrorExtension.toDictionary(error))
+ } else {
+ result(nil)
+ }
+ }
+ }
+}
diff --git a/packages/hmssdk_flutter/ios/Classes/Actions/HMSPeerListIteratorAction.swift b/packages/hmssdk_flutter/ios/Classes/Actions/HMSPeerListIteratorAction.swift
new file mode 100644
index 000000000..8ff02905d
--- /dev/null
+++ b/packages/hmssdk_flutter/ios/Classes/Actions/HMSPeerListIteratorAction.swift
@@ -0,0 +1,166 @@
+//
+// HMSPeerListIteratorAction.swift
+// hmssdk_flutter
+//
+// Created by Pushpam on 04/10/23.
+//
+
+import Foundation
+import HMSSDK
+
+class HMSPeerListIteratorAction {
+
+ /**
+ * [peerListIterators] stores the iterators with unique id's.
+ * This is used whenever we call [peerListIteratorHasNext], or [peerListIteratorNext]
+ * we fetch the respective peerListIterator based on the uid passed from flutter channel
+ * and execute the method based on it.
+ */
+ private static var peerListIterators = [String: HMSPeerListIterator]()
+
+ static func peerListIteratorAction(_ call: FlutterMethodCall, _ result: @escaping FlutterResult, _ hmsSDK: HMSSDK?) {
+ switch call.method {
+
+ case "get_peer_list_iterator":
+ getPeerListIterator(call, result, hmsSDK)
+
+ case "peer_list_iterator_has_next":
+ peerListIteratorHasNext(call, result)
+
+ case "peer_list_iterator_next":
+ peerListIteratorNext(call, result)
+
+ default:
+ result(FlutterMethodNotImplemented)
+ }
+ }
+
+ /**
+ * This method returns the peer list iterator based on the parameter we pass from flutter channel
+ */
+ private static func getPeerListIterator(_ call: FlutterMethodCall, _ result: @escaping FlutterResult, _ hmsSDK: HMSSDK?) {
+
+ let arguments = call.arguments as? [AnyHashable: Any]
+
+ guard let uid = arguments?["uid"] as? String
+ else {
+ HMSErrorLogger.returnHMSException(#function, "uid is null", "NULL Error", result)
+ return
+ }
+
+ var peerListIteratorOptions: HMSPeerListIteratorOptions?
+
+ let peerListOptionsMap = arguments?["peer_list_iterator_options"] as? [String: Any]
+
+ guard let limit = peerListOptionsMap?["limit"] as? Int
+ else {
+ HMSErrorLogger.returnHMSException(#function, "limit parameter is null while peerListIteratorOptions is non-null", "NULL Error", result)
+ return
+ }
+
+ peerListIteratorOptions = HMSPeerListIteratorOptions(filterByRoleName: peerListOptionsMap?["by_role_name"] as? String, filterByPeerIds: peerListOptionsMap?["by_peer_ids"] as? [String], limit: limit)
+
+ var peerListIterator: HMSPeerListIterator?
+
+ if peerListIteratorOptions != nil {
+ peerListIterator = hmsSDK?.getPeerListIterator(options: peerListIteratorOptions!)
+ } else {
+ peerListIterator = hmsSDK?.getPeerListIterator()
+ }
+
+ if peerListIterator != nil {
+
+ /**
+ * We store the iterator in [peerListIterators] map for later operations with key as [id] which unique
+ * id for the iterator
+ */
+ peerListIterators[uid] = peerListIterator
+
+ result(HMSResultExtension.toDictionary(true, HMSPeerListIteratorExtension.toDictionary(peerListIterator!, uid)))
+ } else {
+ HMSErrorLogger.returnHMSException(#function, "peerListIterator is null", "NULL Error", result)
+ return
+ }
+
+ }
+
+ /**
+ * Method to check whether iterator has next set of peers or not
+ */
+ private static func peerListIteratorHasNext(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
+
+ let arguments = call.arguments as? [AnyHashable: Any]
+
+ guard let uid = arguments?["uid"] as? String
+ else {
+ HMSErrorLogger.returnHMSException(#function, "uid is null", "NULL Error", result)
+ return
+ }
+
+ /**
+ * Here we find the iterator with [uid] passed from flutter channel
+ * Since we need to perform the operation on that specific iterator
+ */
+ guard let peerListIterator = peerListIterators[uid]
+ else {
+ HMSErrorLogger.returnHMSException(#function, "No peerListIterator with given uid found", "NULL Error", result)
+ return
+ }
+
+ result(HMSResultExtension.toDictionary(true, peerListIterator.hasNext))
+
+ }
+
+ /**
+ * Method to get a list of next set of peers in iterator, the number of peers returned is equal to
+ * the limit.
+ */
+ private static func peerListIteratorNext(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
+
+ let arguments = call.arguments as? [AnyHashable: Any]
+
+ guard let uid = arguments?["uid"] as? String
+ else {
+ HMSErrorLogger.returnHMSException(#function, "uid is null", "NULL Error", result)
+ return
+ }
+
+ /**
+ * Here we find the iterator with [uid] passed from flutter channel
+ * Since we need to perform the operation on that specific iterator
+ */
+ guard let peerListIterator = peerListIterators[uid]
+ else {
+ HMSErrorLogger.returnHMSException(#function, "No peerListIterator with given uid found", "NULL Error", result)
+ return
+ }
+
+ peerListIterator.next(completion: { peers, error in
+ if let error = error {
+ result(HMSResultExtension.toDictionary(false, HMSErrorExtension.toDictionary(error)))
+ } else {
+ var data = [String: Any]()
+ var peersList = [Any]()
+
+ peers?.forEach {
+ peersList.append(HMSPeerExtension.toDictionary($0))
+ }
+
+ data["peers"] = peersList
+ data["total_count"] = peerListIterator.totalCount
+
+ result(HMSResultExtension.toDictionary(true, data))
+ }
+
+ })
+
+ }
+
+ /**
+ * This method clears the iterator map on leave, end Room or onRemovedFromRoom method calls
+ */
+ static func clearIteratorMap() {
+ peerListIterators.removeAll()
+ }
+
+}
diff --git a/packages/hmssdk_flutter/ios/Classes/Models/HMSPeerExtension.swift b/packages/hmssdk_flutter/ios/Classes/Models/HMSPeerExtension.swift
index c953bc867..556cb731d 100644
--- a/packages/hmssdk_flutter/ios/Classes/Models/HMSPeerExtension.swift
+++ b/packages/hmssdk_flutter/ios/Classes/Models/HMSPeerExtension.swift
@@ -16,6 +16,7 @@ class HMSPeerExtension {
"peer_id": peer.peerID,
"name": peer.name,
"is_local": peer.isLocal,
+ "is_hand_raised": peer.isHandRaised,
"customer_description": peer.metadata ?? "",
"customer_user_id": peer.customerUserID ?? "",
"joined_at": "\(peer.joinedAt)",
@@ -65,6 +66,8 @@ class HMSPeerExtension {
return "metadataChanged"
case .networkQualityUpdated:
return "networkQualityUpdated"
+ case .handRaiseUpdated:
+ return "handRaiseUpdated"
@unknown default:
return "defaultUpdate"
}
diff --git a/packages/hmssdk_flutter/ios/Classes/Models/HMSPeerListIteratorExtension.swift b/packages/hmssdk_flutter/ios/Classes/Models/HMSPeerListIteratorExtension.swift
new file mode 100644
index 000000000..90fa1927f
--- /dev/null
+++ b/packages/hmssdk_flutter/ios/Classes/Models/HMSPeerListIteratorExtension.swift
@@ -0,0 +1,23 @@
+//
+// HMSPeerListIteratorExtension.swift
+// hmssdk_flutter
+//
+// Created by Pushpam on 04/10/23.
+//
+
+import Foundation
+import HMSSDK
+
+class HMSPeerListIteratorExtension {
+
+ static func toDictionary(_ peerListIterator: HMSPeerListIterator, _ uid: String) -> [String: Any] {
+
+ var dict = [
+ "uid": uid,
+ "limit": peerListIterator.options.limit,
+ "total_count": peerListIterator.totalCount
+ ] as [String: Any]
+
+ return dict
+ }
+}
diff --git a/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift b/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift
index fe18c06ad..c4a001ed0 100644
--- a/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift
+++ b/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift
@@ -202,8 +202,8 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene
roleActions(call, result)
// MARK: - Peer Action
- case "change_metadata", "change_name":
- peerActions(call, result)
+ case "change_metadata", "change_name", "raise_local_peer_hand", "lower_local_peer_hand", "lower_remote_peer_hand":
+ HMSPeerAction.peerActions(call, result, hmsSDK)
// MARK: - RTMP
@@ -292,6 +292,9 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene
case "get_room_layout":
getRoomLayout(call, result)
+ case "get_peer_list_iterator", "peer_list_iterator_has_next", "peer_list_iterator_next":
+ HMSPeerListIteratorAction.peerListIteratorAction(call, result, hmsSDK)
+
default:
result(FlutterMethodNotImplemented)
}
@@ -364,20 +367,6 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene
}
}
- // MARK: - Peer Actions
-
- private func peerActions(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
- switch call.method {
- case "change_metadata":
- changeMetadata(call, result)
-
- case "change_name":
- changeName(call, result)
- default:
- result(FlutterMethodNotImplemented)
- }
- }
-
// MARK: - Logging
private func loggingActions(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
switch call.method {
@@ -1057,50 +1046,6 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene
}
}
}
-
- private var hasChangedMetadata = false
-
- private func changeMetadata(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
-
- let arguments = call.arguments as! [AnyHashable: Any]
-
- guard let metadata = arguments["metadata"] as? String else {
- result(HMSErrorExtension.getError("No metadata found in \(#function)"))
- return
- }
-
- hmsSDK?.change(metadata: metadata) { [weak self] _, error in
- if let error = error {
- result(HMSErrorExtension.toDictionary(error))
- return
- } else {
- if let strongSelf = self {
- strongSelf.hasChangedMetadata = !strongSelf.hasChangedMetadata
- }
- result(nil)
- }
- }
- }
-
- private func changeName(_ call: FlutterMethodCall, _ result: @escaping FlutterResult) {
-
- let arguments = call.arguments as![AnyHashable: Any]
-
- guard let name = arguments["name"] as? String else {
- result(HMSErrorExtension.getError("No name found in \(#function)"))
- return
- }
-
- hmsSDK?.change(name: name) { _, error in
- if let error = error {
- result(HMSErrorExtension.toDictionary(error))
- } else {
- result(nil)
- }
-
- }
- }
-
// MARK: - Logging
private var logLevel = HMSLogLevel.off
@@ -1417,6 +1362,28 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene
eventSink?(data)
}
+ public func onPeerListUpdate(added: [HMSPeer], removed: [HMSPeer]) {
+ var parameters = [String: Any]()
+
+ var addedPeers = [Any]()
+ var removedPeers = [Any]()
+
+ added.forEach {
+ addedPeers.append(HMSPeerExtension.toDictionary($0))
+ }
+
+ removed.forEach {
+ removedPeers.append(HMSPeerExtension.toDictionary($0))
+ }
+
+ parameters["added_peers"] = addedPeers
+ parameters["removed_peers"] = removedPeers
+
+ let data = ["event_name": "on_peer_list_update", "data": parameters] as [String: Any]
+
+ eventSink?(data)
+ }
+
// MARK: - RTC Stats Listeners
public func on(localAudioStats: HMSLocalAudioStats, track: HMSAudioTrack, peer: HMSPeer) {
@@ -1590,5 +1557,6 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene
destroyPIPController()
removeAllKeyChangeListener()
removeHMSLogger()
+ HMSPeerListIteratorAction.clearIteratorMap()
}
}
diff --git a/packages/hmssdk_flutter/lib/assets/sdk-versions.json b/packages/hmssdk_flutter/lib/assets/sdk-versions.json
index 92d525d70..1f2bd762e 100644
--- a/packages/hmssdk_flutter/lib/assets/sdk-versions.json
+++ b/packages/hmssdk_flutter/lib/assets/sdk-versions.json
@@ -1,7 +1,7 @@
{
- "flutter": "1.8.0",
- "ios": "0.9.12",
+ "flutter": "1.9.0",
+ "ios": "1.1.0",
"iOSBroadcastExtension": "0.0.9",
"iOSHLSPlayerSDK": "0.0.2",
- "android": "2.7.6"
+ "android": "2.7.7"
}
diff --git a/packages/hmssdk_flutter/lib/hmssdk_flutter.dart b/packages/hmssdk_flutter/lib/hmssdk_flutter.dart
index 365d12f3c..a2ed8ad45 100644
--- a/packages/hmssdk_flutter/lib/hmssdk_flutter.dart
+++ b/packages/hmssdk_flutter/lib/hmssdk_flutter.dart
@@ -98,6 +98,8 @@ export 'src/model/hls_player/hms_hls_player_controller.dart';
export 'src/model/hls_player/hms_hls_player_stats.dart';
export 'src/model/hls_player/hms_hls_cue.dart';
export 'src/model/hls_player/hms_hls_timed_metadata.dart';
+export 'src/model/hms_peer_list_iterator.dart';
+export 'src/model/peer_list_iterator_options.dart';
//Views
export 'src/ui/meeting/hms_video_view.dart';
diff --git a/packages/hmssdk_flutter/lib/src/common/platform_methods.dart b/packages/hmssdk_flutter/lib/src/common/platform_methods.dart
index 0849cdbf7..1e62e30ef 100644
--- a/packages/hmssdk_flutter/lib/src/common/platform_methods.dart
+++ b/packages/hmssdk_flutter/lib/src/common/platform_methods.dart
@@ -187,7 +187,15 @@ enum PlatformMethod {
toggleAlwaysScreenOn,
getRoomLayout,
previewForRole,
- cancelPreview
+ cancelPreview,
+
+ ///PeerListIteratorMethods
+ getPeerListIterator,
+ peerListIteratorHasNext,
+ peerListIteratorNext,
+ lowerLocalPeerHand,
+ lowerRemotePeerHand,
+ raiseLocalPeerHand
}
extension PlatformMethodValues on PlatformMethod {
@@ -465,6 +473,21 @@ extension PlatformMethodValues on PlatformMethod {
return "toggle_always_screen_on";
case PlatformMethod.getRoomLayout:
return "get_room_layout";
+
+ ///Peer list iterator methods
+ case PlatformMethod.getPeerListIterator:
+ return "get_peer_list_iterator";
+ case PlatformMethod.peerListIteratorHasNext:
+ return "peer_list_iterator_has_next";
+ case PlatformMethod.peerListIteratorNext:
+ return "peer_list_iterator_next";
+
+ case PlatformMethod.lowerLocalPeerHand:
+ return "lower_local_peer_hand";
+ case PlatformMethod.lowerRemotePeerHand:
+ return "lower_remote_peer_hand";
+ case PlatformMethod.raiseLocalPeerHand:
+ return "raise_local_peer_hand";
default:
return 'unknown';
}
@@ -744,6 +767,21 @@ extension PlatformMethodValues on PlatformMethod {
return PlatformMethod.toggleAlwaysScreenOn;
case "get_room_layout":
return PlatformMethod.getRoomLayout;
+
+ ///Peer List Iterator methods
+ case "get_peer_list_iterator":
+ return PlatformMethod.getPeerListIterator;
+ case "peer_list_iterator_has_next":
+ return PlatformMethod.peerListIteratorHasNext;
+ case "peer_list_iterator_next":
+ return PlatformMethod.peerListIteratorNext;
+
+ case "lower_local_peer_hand":
+ return PlatformMethod.lowerLocalPeerHand;
+ case "lower_remote_peer_hand":
+ return PlatformMethod.lowerRemotePeerHand;
+ case "raise_local_peer_hand":
+ return PlatformMethod.raiseLocalPeerHand;
default:
return PlatformMethod.unknown;
}
diff --git a/packages/hmssdk_flutter/lib/src/enum/hms_action_result_listener_method.dart b/packages/hmssdk_flutter/lib/src/enum/hms_action_result_listener_method.dart
index 1817b2594..13c400c4b 100644
--- a/packages/hmssdk_flutter/lib/src/enum/hms_action_result_listener_method.dart
+++ b/packages/hmssdk_flutter/lib/src/enum/hms_action_result_listener_method.dart
@@ -23,5 +23,8 @@ enum HMSActionResultListenerMethod {
changeRoleOfPeersWithRoles,
setSessionMetadataForKey,
sendHLSTimedMetadata,
+ lowerLocalPeerHand,
+ lowerRemotePeerHand,
+ raiseLocalPeerHand,
unknown
}
diff --git a/packages/hmssdk_flutter/lib/src/enum/hms_peer_update.dart b/packages/hmssdk_flutter/lib/src/enum/hms_peer_update.dart
index 32711e23e..230fb1b34 100644
--- a/packages/hmssdk_flutter/lib/src/enum/hms_peer_update.dart
+++ b/packages/hmssdk_flutter/lib/src/enum/hms_peer_update.dart
@@ -17,7 +17,10 @@ enum HMSPeerUpdate {
defaultUpdate,
///Peer's network quality updates
- networkQualityUpdated
+ networkQualityUpdated,
+
+ ///Peer's hand raise updates
+ handRaiseUpdated
}
extension HMSPeerUpdateValues on HMSPeerUpdate {
@@ -35,8 +38,8 @@ extension HMSPeerUpdateValues on HMSPeerUpdate {
return HMSPeerUpdate.nameChanged;
case 'networkQualityUpdated':
return HMSPeerUpdate.networkQualityUpdated;
- case 'defaultUpdate':
- return HMSPeerUpdate.defaultUpdate;
+ case 'handRaiseUpdated':
+ return HMSPeerUpdate.handRaiseUpdated;
default:
return HMSPeerUpdate.defaultUpdate;
}
@@ -59,10 +62,14 @@ extension HMSPeerUpdateValues on HMSPeerUpdate {
case HMSPeerUpdate.nameChanged:
return 'nameChanged';
- case HMSPeerUpdate.defaultUpdate:
- return 'defaultUpdate';
+ case HMSPeerUpdate.handRaiseUpdated:
+ return 'handRaiseUpdated';
+
case HMSPeerUpdate.networkQualityUpdated:
return 'networkQualityUpdated';
+
+ default:
+ return 'defaultUpdate';
}
}
}
diff --git a/packages/hmssdk_flutter/lib/src/enum/hms_update_listener_method.dart b/packages/hmssdk_flutter/lib/src/enum/hms_update_listener_method.dart
index 1cac55dfb..e23c1603f 100644
--- a/packages/hmssdk_flutter/lib/src/enum/hms_update_listener_method.dart
+++ b/packages/hmssdk_flutter/lib/src/enum/hms_update_listener_method.dart
@@ -13,6 +13,7 @@ enum HMSUpdateListenerMethod {
onRemovedFromRoom,
onAudioDeviceChanged,
onSessionStoreAvailable,
+ onPeerListUpdate,
unknown
}
@@ -47,6 +48,8 @@ extension HMSUpdateListenerMethodValues on HMSUpdateListenerMethod {
return HMSUpdateListenerMethod.onAudioDeviceChanged;
case 'on_session_store_available':
return HMSUpdateListenerMethod.onSessionStoreAvailable;
+ case 'on_peer_list_update':
+ return HMSUpdateListenerMethod.onPeerListUpdate;
default:
return HMSUpdateListenerMethod.unknown;
}
diff --git a/packages/hmssdk_flutter/lib/src/hmssdk.dart b/packages/hmssdk_flutter/lib/src/hmssdk.dart
index 43819c728..fe28339d6 100644
--- a/packages/hmssdk_flutter/lib/src/hmssdk.dart
+++ b/packages/hmssdk_flutter/lib/src/hmssdk.dart
@@ -1380,6 +1380,100 @@ class HMSSDK {
PlatformService.removeRTCStatsListener(listener);
}
+ /// Method to get the peer list iterator in the room, only in case of large rooms
+ ///
+ /// Checkout the [HMSPeerListIterator] class for more details about the iterator
+ ///
+ /// **Parameters**:
+ ///
+ /// **peerListIteratorOptions** - [peerListIteratorOptions] is the options to get the iterator based on the filter set in [peerListIteratorOptions] parameter
+ Future getPeerListIterator(
+ {PeerListIteratorOptions? peerListIteratorOptions}) async {
+ var result = await PlatformService.invokeMethod(
+ PlatformMethod.getPeerListIterator,
+ arguments: {
+ "uid": DateTime.now().microsecondsSinceEpoch.toString(),
+ "peer_list_iterator_options": peerListIteratorOptions?.toMap()
+ });
+ if (result["success"]) {
+ return HMSPeerListIterator.fromMap(result["data"]);
+ } else {
+ return HMSException.fromMap(result["data"]["error"]);
+ }
+ }
+
+ ///Method to lower hand for local peer
+ ///
+ ///**Parameter**:
+ ///
+ ///**hmsActionResultListener** - [hmsActionResultListener] is a callback instance on which [HMSActionResultListener.onSuccess] and [HMSActionResultListener.onException] will be called.
+ ///
+ ///TODO: Add docs link
+ void lowerLocalPeerHand(
+ {HMSActionResultListener? hmsActionResultListener}) async {
+ final dynamic result =
+ await PlatformService.invokeMethod(PlatformMethod.lowerLocalPeerHand);
+ if (hmsActionResultListener != null) {
+ if (result == null) {
+ hmsActionResultListener.onSuccess(
+ methodType: HMSActionResultListenerMethod.lowerLocalPeerHand);
+ } else {
+ hmsActionResultListener.onException(
+ methodType: HMSActionResultListenerMethod.lowerLocalPeerHand,
+ hmsException: HMSException.fromMap(result["error"]));
+ }
+ }
+ }
+
+ ///Method to raise hand for local peer
+ ///
+ ///**Parameter**:
+ ///
+ ///**hmsActionResultListener** - [hmsActionResultListener] is a callback instance on which [HMSActionResultListener.onSuccess] and [HMSActionResultListener.onException] will be called.
+ ///
+ ///TODO: Add docs link
+ void raiseLocalPeerHand(
+ {HMSActionResultListener? hmsActionResultListener}) async {
+ final dynamic result =
+ await PlatformService.invokeMethod(PlatformMethod.raiseLocalPeerHand);
+ if (hmsActionResultListener != null) {
+ if (result == null) {
+ hmsActionResultListener.onSuccess(
+ methodType: HMSActionResultListenerMethod.raiseLocalPeerHand);
+ } else {
+ hmsActionResultListener.onException(
+ methodType: HMSActionResultListenerMethod.raiseLocalPeerHand,
+ hmsException: HMSException.fromMap(result["error"]));
+ }
+ }
+ }
+
+ ///Method to lower remote peer's hand
+ ///
+ ///**Parameter**:
+ ///
+ ///**forPeer** - [forPeer] the peer whose hand you wish to lower
+ ///**hmsActionResultListener** - [hmsActionResultListener] is a callback instance on which [HMSActionResultListener.onSuccess] and [HMSActionResultListener.onException] will be called.
+ ///
+ ///TODO: Add docs link
+ void lowerRemotePeerHand(
+ {required HMSPeer forPeer,
+ HMSActionResultListener? hmsActionResultListener}) async {
+ final dynamic result = await PlatformService.invokeMethod(
+ PlatformMethod.lowerRemotePeerHand,
+ arguments: {"peer_id": forPeer.peerId});
+ if (hmsActionResultListener != null) {
+ if (result == null) {
+ hmsActionResultListener.onSuccess(
+ methodType: HMSActionResultListenerMethod.lowerRemotePeerHand);
+ } else {
+ hmsActionResultListener.onException(
+ methodType: HMSActionResultListenerMethod.lowerRemotePeerHand,
+ hmsException: HMSException.fromMap(result["error"]));
+ }
+ }
+ }
+
/// To modify local peer's audio & video tracks settings use the [hmsTrackSetting]. Only required for advanced use cases.
HMSTrackSetting? hmsTrackSetting;
diff --git a/packages/hmssdk_flutter/lib/src/model/hms_local_peer.dart b/packages/hmssdk_flutter/lib/src/model/hms_local_peer.dart
index 9ee60cd33..0f7276c25 100644
--- a/packages/hmssdk_flutter/lib/src/model/hms_local_peer.dart
+++ b/packages/hmssdk_flutter/lib/src/model/hms_local_peer.dart
@@ -19,6 +19,7 @@ class HMSLocalPeer extends HMSPeer {
required String name,
required bool isLocal,
required HMSRole role,
+ required bool isHandRaised,
String? customerUserId,
String? metadata,
HMSLocalAudioTrack? audioTrack,
@@ -31,6 +32,7 @@ class HMSLocalPeer extends HMSPeer {
isLocal: isLocal,
name: name,
peerId: peerId,
+ isHandRaised: isHandRaised,
customerUserId: customerUserId,
metadata: metadata,
role: role,
@@ -46,6 +48,7 @@ class HMSLocalPeer extends HMSPeer {
peerId: map['peer_id'],
name: map['name'],
isLocal: map['is_local'],
+ isHandRaised: map['is_hand_raised'],
role: HMSRole.fromMap(map['role']),
metadata: map['metadata'],
customerUserId: map['customer_user_id'],
diff --git a/packages/hmssdk_flutter/lib/src/model/hms_peer.dart b/packages/hmssdk_flutter/lib/src/model/hms_peer.dart
index 9becd7d66..0fa5c7719 100644
--- a/packages/hmssdk_flutter/lib/src/model/hms_peer.dart
+++ b/packages/hmssdk_flutter/lib/src/model/hms_peer.dart
@@ -22,10 +22,8 @@ class HMSPeer {
///returns whether the peer is local or not.
final bool isLocal;
- @override
- String toString() {
- return 'HMSPeer{name: $name, isLocal: $isLocal}';
- }
+ ///returns whether peer's hand is raised or not
+ final bool isHandRaised;
///the current role of the peer in the room
final HMSRole role;
@@ -54,19 +52,21 @@ class HMSPeer {
///updatedAt is the time when the peer object was last updated
final DateTime? updatedAt;
- HMSPeer(
- {required this.peerId,
- required this.name,
- required this.isLocal,
- required this.role,
- this.customerUserId,
- this.metadata,
- this.audioTrack,
- this.videoTrack,
- this.auxiliaryTracks,
- this.networkQuality,
- this.joinedAt,
- this.updatedAt});
+ HMSPeer({
+ required this.peerId,
+ required this.name,
+ required this.isLocal,
+ required this.role,
+ required this.isHandRaised,
+ this.customerUserId,
+ this.metadata,
+ this.audioTrack,
+ this.videoTrack,
+ this.auxiliaryTracks,
+ this.networkQuality,
+ this.joinedAt,
+ this.updatedAt,
+ });
///important to compare using [peerId]
@override
@@ -89,6 +89,7 @@ class HMSPeer {
peerId: map['peer_id'],
name: map['name'],
isLocal: map['is_local'],
+ isHandRaised: map['is_hand_raised'],
role: role,
metadata: map['metadata'],
customerUserId: map['customer_user_id'],
@@ -108,6 +109,7 @@ class HMSPeer {
peerId: map['peer_id'],
name: map['name'],
isLocal: map['is_local'],
+ isHandRaised: map['is_hand_raised'],
role: role,
metadata: map['metadata'],
customerUserId: map['customer_user_id'],
@@ -135,6 +137,11 @@ class HMSPeer {
return peer;
}
+ @override
+ String toString() {
+ return 'HMSPeer{name: $name, isLocal: $isLocal}';
+ }
+
static List fromListOfMap(List peersMap) {
List peers = peersMap.map((e) => HMSPeer.fromMap(e)).toList();
return peers;
diff --git a/packages/hmssdk_flutter/lib/src/model/hms_peer_list_iterator.dart b/packages/hmssdk_flutter/lib/src/model/hms_peer_list_iterator.dart
new file mode 100644
index 000000000..196e47568
--- /dev/null
+++ b/packages/hmssdk_flutter/lib/src/model/hms_peer_list_iterator.dart
@@ -0,0 +1,75 @@
+///Project imports
+import 'package:hmssdk_flutter/hmssdk_flutter.dart';
+import 'package:hmssdk_flutter/src/service/platform_service.dart';
+
+///100ms HMSPeerListIterator
+///
+///[HMSPeerListIterator] contains the info about the peer list iterator
+///
+///[limit] returns the maximum number of peers that can be returned in a single call to next.
+///
+///[totalCount] returns the total number of peers present with the iterator based on the filters applied with [PeerListIteratorOptions] while making
+///[getPeerListIterator] method call
+///
+///[uid] returns the unique id of the peer list iterator
+class HMSPeerListIterator {
+ ///maximum number of peers that can be returned in a single call to next
+ final int limit;
+
+ ///total number of peers present with the iterator based on the filters applied with [PeerListIteratorOptions] while making
+ ///[getPeerListIterator] method call
+ int _totalCount;
+
+ ///unique id of the peer list iterator
+ final String uid;
+
+ int get totalCount => _totalCount;
+
+ HMSPeerListIterator({
+ required this.limit,
+ required this.uid,
+ required totalCount,
+ }) : _totalCount = totalCount;
+
+ factory HMSPeerListIterator.fromMap(Map map) {
+ return HMSPeerListIterator(
+ limit: map['limit'] ?? 0,
+ totalCount: map['total_count'] ?? 0,
+ uid: map['uid'] ?? '',
+ );
+ }
+
+ ///This method is used to check if there are more peers to be returned
+ ///
+ ///returns [true] if there are more peers to be returned else [false]
+ Future hasNext() async {
+ var result = await PlatformService.invokeMethod(
+ PlatformMethod.peerListIteratorHasNext,
+ arguments: {"uid": uid});
+ if (result["success"]) {
+ return result["data"];
+ } else {
+ return HMSException.fromMap(result["data"]["error"]);
+ }
+ }
+
+ ///This method is used to get the next set of peers
+ ///
+ ///returns a list of [HMSPeer] objects, the number of peers in a single call depends on the
+ ///[limit] parameter in [PeerListIteratorOptions] set during the [getPeerListIterator] method call
+ Future next() async {
+ var result = await PlatformService.invokeMethod(
+ PlatformMethod.peerListIteratorNext,
+ arguments: {"uid": uid});
+ if (result["success"]) {
+ List peers = [];
+ _totalCount = result["data"]["total_count"];
+ for (var peer in result["data"]["peers"]) {
+ peers.add(HMSPeer.fromMap(peer));
+ }
+ return peers;
+ } else {
+ return HMSException.fromMap(result["data"]["error"]);
+ }
+ }
+}
diff --git a/packages/hmssdk_flutter/lib/src/model/hms_remote_peer.dart b/packages/hmssdk_flutter/lib/src/model/hms_remote_peer.dart
index 09fcf540e..8f22b400b 100644
--- a/packages/hmssdk_flutter/lib/src/model/hms_remote_peer.dart
+++ b/packages/hmssdk_flutter/lib/src/model/hms_remote_peer.dart
@@ -24,6 +24,7 @@ class HMSRemotePeer extends HMSPeer {
HMSRemotePeer(
{required String peerId,
required String name,
+ required bool isHandRaised,
bool isLocal = false,
required HMSRole role,
String? customerUserId,
@@ -38,6 +39,7 @@ class HMSRemotePeer extends HMSPeer {
peerId: peerId,
name: name,
isLocal: isLocal,
+ isHandRaised: isHandRaised,
role: role,
customerUserId: customerUserId,
metadata: metadata,
@@ -66,6 +68,7 @@ class HMSRemotePeer extends HMSPeer {
peerId: map['peer_id'],
name: map['name'],
isLocal: map['is_local'],
+ isHandRaised: map['is_hand_raised'],
role: role,
metadata: map['metadata'],
customerUserId: map['customer_user_id'],
diff --git a/packages/hmssdk_flutter/lib/src/model/hms_update_listener.dart b/packages/hmssdk_flutter/lib/src/model/hms_update_listener.dart
index 9baf13a25..1e44ec9a4 100644
--- a/packages/hmssdk_flutter/lib/src/model/hms_update_listener.dart
+++ b/packages/hmssdk_flutter/lib/src/model/hms_update_listener.dart
@@ -105,4 +105,10 @@ abstract class HMSUpdateListener {
/// - Parameters:
/// - hmsSessionStore: An instance of HMSSessionStore which will be used to call session metadata methods
void onSessionStoreAvailable({HMSSessionStore? hmsSessionStore});
+
+ ///Upon joining a room with existing peers, onPeerListUpdated will be called with the list of peers present
+ ///in the room instead of getting onPeerUpdate for each peer in the room.
+ ///Subsequent peer joins/leaves would be notified via both onPeerUpdate and onPeerListUpdated
+ void onPeerListUpdate(
+ {required List addedPeers, required List removedPeers});
}
diff --git a/packages/hmssdk_flutter/lib/src/model/peer_list_iterator_options.dart b/packages/hmssdk_flutter/lib/src/model/peer_list_iterator_options.dart
new file mode 100644
index 000000000..ed14bec77
--- /dev/null
+++ b/packages/hmssdk_flutter/lib/src/model/peer_list_iterator_options.dart
@@ -0,0 +1,31 @@
+/// This class is used to set the options for the [getPeerListIterator] method
+///
+/// [byPeerIds] list of peerIds for which peer list is required
+///
+/// [byRoleName] name of the role for which peer list is required
+///
+/// [limit] maximum number of peers to be returned
+class PeerListIteratorOptions {
+ /// list of peerIds for which peer list is required
+ final List? byPeerIds;
+
+ /// name of the role for which peer list is required
+ final String? byRoleName;
+
+ /// maximum number of peers to be returned
+ final int limit;
+
+ PeerListIteratorOptions({
+ required this.limit,
+ this.byPeerIds,
+ this.byRoleName,
+ });
+
+ Map toMap() {
+ return {
+ 'by_peer_ids': this.byPeerIds,
+ 'by_role_name': this.byRoleName,
+ 'limit': this.limit,
+ };
+ }
+}
diff --git a/packages/hmssdk_flutter/lib/src/service/platform_service.dart b/packages/hmssdk_flutter/lib/src/service/platform_service.dart
index f25b6a755..509cf3fb3 100644
--- a/packages/hmssdk_flutter/lib/src/service/platform_service.dart
+++ b/packages/hmssdk_flutter/lib/src/service/platform_service.dart
@@ -286,6 +286,26 @@ class PlatformService {
notifyUpdateListeners(method, {});
break;
+ case HMSUpdateListenerMethod.onPeerListUpdate:
+ List addedPeers = [];
+ List removedPeers = [];
+
+ if (data.containsKey("added_peers") && data["added_peers"] != null) {
+ for (var peer in data["added_peers"]) {
+ addedPeers.add(HMSPeer.fromMap(peer));
+ }
+ }
+
+ if (data.containsKey("removed_peers") &&
+ data["removed_peers"] != null) {
+ for (var peer in data["removed_peers"]) {
+ removedPeers.add(HMSPeer.fromMap(peer));
+ }
+ }
+
+ notifyUpdateListeners(method,
+ {"added_peers": addedPeers, "removed_peers": removedPeers});
+ break;
case HMSUpdateListenerMethod.unknown:
break;
}
@@ -661,6 +681,14 @@ class PlatformService {
e.onSessionStoreAvailable(hmsSessionStore: HMSSessionStore()));
break;
+ case HMSUpdateListenerMethod.onPeerListUpdate:
+ updateListeners.forEach((e) {
+ e.onPeerListUpdate(
+ addedPeers: arguments["added_peers"],
+ removedPeers: arguments["removed_peers"]);
+ });
+ break;
+
case HMSUpdateListenerMethod.unknown:
break;
}
diff --git a/packages/hmssdk_flutter/pubspec.yaml b/packages/hmssdk_flutter/pubspec.yaml
index ceac0638c..f9515341f 100644
--- a/packages/hmssdk_flutter/pubspec.yaml
+++ b/packages/hmssdk_flutter/pubspec.yaml
@@ -1,6 +1,6 @@
name: hmssdk_flutter
description: Add Real Time Audio & Video calls, Interactive Live Streaming & Recording, Chat, HLS, RTMP, PiP, CallKit, VoIP, Video conferencing, Stream Player & WebRTC-based communications API
-version: 1.8.0
+version: 1.9.0
homepage: https://www.100ms.live/
repository: https://github.com/100mslive/100ms-flutter
issue_tracker: https://github.com/100mslive/100ms-flutter/issues
diff --git a/sample apps/bloc/pubspec.lock b/sample apps/bloc/pubspec.lock
index 3d387b3cc..0353333d2 100644
--- a/sample apps/bloc/pubspec.lock
+++ b/sample apps/bloc/pubspec.lock
@@ -45,10 +45,10 @@ packages:
dependency: transitive
description:
name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
- version: "1.18.0"
+ version: "1.17.2"
cupertino_icons:
dependency: "direct main"
description:
@@ -260,18 +260,18 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
@@ -292,10 +292,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
- version: "0.6.1"
+ version: "0.6.0"
typed_data:
dependency: transitive
description:
diff --git a/sample apps/flutter-audio-room-quickstart/pubspec.lock b/sample apps/flutter-audio-room-quickstart/pubspec.lock
index 4cee29067..b9ad621c8 100644
--- a/sample apps/flutter-audio-room-quickstart/pubspec.lock
+++ b/sample apps/flutter-audio-room-quickstart/pubspec.lock
@@ -37,10 +37,10 @@ packages:
dependency: transitive
description:
name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
- version: "1.18.0"
+ version: "1.17.2"
cupertino_icons:
dependency: "direct main"
description:
@@ -188,18 +188,18 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
@@ -220,10 +220,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
- version: "0.6.1"
+ version: "0.6.0"
vector_math:
dependency: transitive
description:
diff --git a/sample apps/flutter-hls-quickstart/pubspec.lock b/sample apps/flutter-hls-quickstart/pubspec.lock
index 011c49784..3cc98b632 100644
--- a/sample apps/flutter-hls-quickstart/pubspec.lock
+++ b/sample apps/flutter-hls-quickstart/pubspec.lock
@@ -37,10 +37,10 @@ packages:
dependency: transitive
description:
name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
- version: "1.18.0"
+ version: "1.17.2"
csslib:
dependency: transitive
description:
@@ -209,18 +209,18 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
@@ -241,10 +241,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
- version: "0.6.1"
+ version: "0.6.0"
vector_math:
dependency: transitive
description:
diff --git a/sample apps/flutter-quickstart-app/pubspec.lock b/sample apps/flutter-quickstart-app/pubspec.lock
index e3a87a5f0..8f4622fce 100644
--- a/sample apps/flutter-quickstart-app/pubspec.lock
+++ b/sample apps/flutter-quickstart-app/pubspec.lock
@@ -37,10 +37,10 @@ packages:
dependency: transitive
description:
name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
- version: "1.18.0"
+ version: "1.17.2"
cupertino_icons:
dependency: "direct main"
description:
@@ -188,18 +188,18 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
@@ -220,10 +220,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
- version: "0.6.1"
+ version: "0.6.0"
vector_math:
dependency: transitive
description:
diff --git a/sample apps/getx/pubspec.lock b/sample apps/getx/pubspec.lock
index 1137ef86a..d775b7e51 100644
--- a/sample apps/getx/pubspec.lock
+++ b/sample apps/getx/pubspec.lock
@@ -45,10 +45,10 @@ packages:
dependency: transitive
description:
name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
- version: "1.18.0"
+ version: "1.17.2"
cupertino_icons:
dependency: "direct main"
description:
@@ -228,18 +228,18 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
@@ -260,10 +260,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
- version: "0.6.1"
+ version: "0.6.0"
typed_data:
dependency: transitive
description:
diff --git a/sample apps/hms-callkit-app/pubspec.lock b/sample apps/hms-callkit-app/pubspec.lock
index 47c7c686a..181a17dfa 100644
--- a/sample apps/hms-callkit-app/pubspec.lock
+++ b/sample apps/hms-callkit-app/pubspec.lock
@@ -69,10 +69,10 @@ packages:
dependency: transitive
description:
name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
- version: "1.18.0"
+ version: "1.17.2"
cross_file:
dependency: transitive
description:
@@ -441,18 +441,18 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
@@ -473,10 +473,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
- version: "0.6.1"
+ version: "0.6.0"
typed_data:
dependency: transitive
description:
diff --git a/sample apps/mobx/pubspec.lock b/sample apps/mobx/pubspec.lock
index 812a91ed9..2fa543676 100644
--- a/sample apps/mobx/pubspec.lock
+++ b/sample apps/mobx/pubspec.lock
@@ -141,10 +141,10 @@ packages:
dependency: transitive
description:
name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
- version: "1.18.0"
+ version: "1.17.2"
convert:
dependency: transitive
description:
@@ -516,18 +516,18 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.1"
stream_transform:
dependency: transitive
description:
@@ -556,10 +556,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
- version: "0.6.1"
+ version: "0.6.0"
timing:
dependency: transitive
description:
diff --git a/sample apps/riverpod/pubspec.lock b/sample apps/riverpod/pubspec.lock
index e7ee6c55c..ecdac52f5 100644
--- a/sample apps/riverpod/pubspec.lock
+++ b/sample apps/riverpod/pubspec.lock
@@ -37,10 +37,10 @@ packages:
dependency: transitive
description:
name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
- version: "1.18.0"
+ version: "1.17.2"
cupertino_icons:
dependency: "direct main"
description:
@@ -220,10 +220,10 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.11.0"
state_notifier:
dependency: transitive
description:
@@ -236,10 +236,10 @@ packages:
dependency: transitive
description:
name: stream_channel
- sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
@@ -260,10 +260,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
- version: "0.6.1"
+ version: "0.6.0"
typed_data:
dependency: transitive
description: