diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 7e7a0a435..c47c800ea 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -15,6 +15,7 @@
### Pre-launch Checklist
- [ ] The [Documentation] is updated accordingly, or this PR doesn't require it.
+- [ ] The [ExampleAppChangelog] is updated with related tickets, or this PR doesn't require it.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I listed at least one issue that this PR fixes in the description above.
- [ ] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
@@ -23,5 +24,6 @@
[Documentation]: https://www.100ms.live/docs
+[ExampleAppChangelog]: https://github.com/100mslive/100ms-flutter/blob/main/packages/hmssdk_flutter/example/ExampleAppChangelog.txt
[Flutter Style Guide]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo
[Features we expect every widget to implement]: https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#features-we-expect-every-widget-to-implement
diff --git a/.github/styles/Vocab/HMSVocab/accept.txt b/.github/styles/Vocab/HMSVocab/accept.txt
index f2a8db832..fc81c8bf7 100644
--- a/.github/styles/Vocab/HMSVocab/accept.txt
+++ b/.github/styles/Vocab/HMSVocab/accept.txt
@@ -171,3 +171,26 @@ userid
peerid
ios
android
+iOS
+authToken
+issue_tracker
+publish_to
+bool
+prominentRoles
+isOverlay
+roleName
+forceChange
+previousRole
+peerMetadata
+toRole
+forPeer
+Enum
+rolesWhitelist
+messagePlaceholder
+chatTitle
+isOverlay
+bool
+permission_handler
+intl
+chatState
+pinnedMessages
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index f7f7c355f..f00e2fcf3 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -5,7 +5,7 @@ concurrency:
cancel-in-progress: true
on:
- workflow_dispatch:
+ workflow_dispatch: {}
push:
branches:
- main
diff --git a/.github/workflows/firstinteraction.yml b/.github/workflows/firstinteraction.yml
index dd85a1744..d24652c58 100644
--- a/.github/workflows/firstinteraction.yml
+++ b/.github/workflows/firstinteraction.yml
@@ -1,7 +1,7 @@
name: Appreciate first interaction
on:
- workflow_dispatch:
+ workflow_dispatch: {}
issues:
types: [opened]
pull_request:
diff --git a/.github/workflows/ktlint.yml b/.github/workflows/ktlint.yml
index a1eeec5e2..a696b34de 100644
--- a/.github/workflows/ktlint.yml
+++ b/.github/workflows/ktlint.yml
@@ -1,7 +1,7 @@
name: KtLint
on:
- workflow_dispatch:
+ workflow_dispatch: {}
pull_request:
paths:
- "**/*.kt"
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
index 1030e18fb..246d2fb95 100644
--- a/.github/workflows/stale.yml
+++ b/.github/workflows/stale.yml
@@ -1,6 +1,6 @@
name: Close stale issues and PRs
on:
- workflow_dispatch:
+ workflow_dispatch: {}
schedule:
- cron: "30 1 * * *"
diff --git a/.github/workflows/swiftlint.yml b/.github/workflows/swiftlint.yml
index b88c58a40..e6fc2153a 100644
--- a/.github/workflows/swiftlint.yml
+++ b/.github/workflows/swiftlint.yml
@@ -1,7 +1,7 @@
name: SwiftLint
on:
- workflow_dispatch:
+ workflow_dispatch: {}
pull_request:
paths:
- "**/*.swift"
diff --git a/.github/workflows/vale.yml b/.github/workflows/vale.yml
index 83c1058d2..a7c4c15a1 100644
--- a/.github/workflows/vale.yml
+++ b/.github/workflows/vale.yml
@@ -1,7 +1,7 @@
-name: Vale linter
+name: Vale Linter
on:
- workflow_dispatch:
+ workflow_dispatch: {}
pull_request:
branches:
- develop
diff --git a/.vale.ini b/.vale.ini
index 54b8ace59..bab850d7d 100644
--- a/.vale.ini
+++ b/.vale.ini
@@ -4,13 +4,11 @@ MinAlertLevel = error
Vocab = HMSVocab
-Packages = Google
-
-[*]
+Packages = Google, Readability
+[*.md]
BasedOnStyles = Vale, Google
-
BlockIgnores = (?s) *(\x60\x60\x60[a-z]*\n[\s\S]*?\x60\x60\x60)
TokenIgnores = [a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89aAbB][a-f0-9]{3}-[a-f0-9]{12} , r.M , (^[a-z]|[A-Z])[a-z]* , `{3}([\S]+)?\n([\s\S]+)\n`{3} , .*",
diff --git a/README.md b/README.md
index b4bce227e..a3804bb36 100644
--- a/README.md
+++ b/README.md
@@ -21,6 +21,10 @@ With support for HLS and RTMP Live Streaming and Recording, Picture-in-Picture (
| 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) |
+💻 Checkout the 100ms Flutter SDK [here](https://github.com/100mslive/100ms-flutter/tree/main/packages/hmssdk_flutter)
+
+❤️ Checkout the 100ms Prebuilt [here](https://github.com/100mslive/100ms-flutter/tree/main/packages/hms_room_kit)
+
🧱 The Prebuilt QuickStart Guide is [available here](https://www.100ms.live/docs/flutter/v2/quickstart/prebuilt).
📖 Read the Complete Documentation here: https://www.100ms.live/docs/flutter/v2/guides/quickstart
diff --git a/packages/hms_room_kit/CHANGELOG.md b/packages/hms_room_kit/CHANGELOG.md
index 5ded47fe0..573647237 100644
--- a/packages/hms_room_kit/CHANGELOG.md
+++ b/packages/hms_room_kit/CHANGELOG.md
@@ -5,6 +5,39 @@
| 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.9 - 2024-01-15
+
+| Package | Version |
+| -------------- | ------------------------------------------------------------------------------------------------------ |
+| hms_room_kit | 1.0.9 |
+| hmssdk_flutter | 1.9.6 |
+
+### 🚀 Added
+
+- Enhanced Chat Controls
+
+ - 📌 Pin and Hide Messages
+
+ Elevate your chat experience with our new room kit feature. Effortlessly pin messages to keep them visible at the top of your chat, or hide messages to remove them from view.
+
+ - 🔒 Chat Moderation
+
+ Gain more control over your chat environment. You can now temporarily block peers within a session, preventing them from sending messages.
+
+ - 👥 Recipient Selector
+
+ Communication tailored to your needs. Send broadcast messages, reach specific groups or roles, and initiate direct messages (DMs) to particular peers with ease.
+
+ - 📋 Copy Messages
+
+ Simplify your interactions. Copy any message quickly with just a single tap, enhancing your chat efficiency.
+
+- Added Skip Preview for Role Change functionality
+
+ 100ms Prebuilt now supports skipping preview screen, while changing roles. This can be configured from 100ms dashboard.
+ If preview screen is skipped, then mic and camera will be muted by default.
+
+
## 1.0.8 - 2023-12-15
| Package | Version |
diff --git a/packages/hms_room_kit/README.md b/packages/hms_room_kit/README.md
index 216e2c978..85fb04eed 100644
--- a/packages/hms_room_kit/README.md
+++ b/packages/hms_room_kit/README.md
@@ -1,4 +1,4 @@
-[![100ms-svg](https://user-images.githubusercontent.com/93931528/205858417-8c0a0d1b-2d46-4710-9316-7418092fd3d6.svg)](https://100ms.live/)
+# 100ms Room Kit 🎉
[![Pub Version](https://img.shields.io/pub/v/hms_room_kit)](https://pub.dev/packages/hms_room_kit)
[![License](https://img.shields.io/github/license/100mslive/100ms-flutter)](https://www.100ms.live/)
@@ -9,7 +9,9 @@
[![Activity](https://img.shields.io/github/commit-activity/m/100mslive/100ms-flutter.svg)](https://github.com/100mslive/100ms-flutter/projects/1)
[![Register](https://img.shields.io/badge/Contact-Know%20More-blue)](https://dashboard.100ms.live/register)
-# 100ms Room Kit 🎉
+
+
+
A powerful prebuilt UI library for audio/video conferencing, live streaming, and one-to-one calls.
This package provides developers with a comprehensive set of tools and components to quickly integrate high-quality audio and video communication features into their Flutter applications.
@@ -65,7 +67,23 @@ HMSPrebuilt(
## Overview
-This guide will walk you through simple instructions to create a video conferencing app using 100ms Prebuilt and and test it using an emulator or your mobile phone.
+This guide will walk you through simple instructions to create a video conferencing app using 100ms Prebuilt and and test it using an emulator or your mobile phone. 100ms prebuilt is completely customizable from 100ms dashboard. Following images portray what you get with 100ms prebuilt
+
+
+
+
## Create a sample app
diff --git a/packages/hms_room_kit/example/ios/Podfile.lock b/packages/hms_room_kit/example/ios/Podfile.lock
index 5481e0490..78aee02dc 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 (1.3.1):
+ - HMSSDK (1.4.1):
- HMSAnalyticsSDK (= 0.0.2)
- HMSWebRTC (= 1.0.5116)
- - hmssdk_flutter (1.9.4):
+ - hmssdk_flutter (1.9.6):
- Flutter
- HMSBroadcastExtensionSDK (= 0.0.9)
- HMSHLSPlayerSDK (= 0.0.2)
- - HMSSDK (= 1.3.1)
+ - HMSSDK (= 1.4.1)
- HMSWebRTC (1.0.5116)
- path_provider_foundation (0.0.1):
- Flutter
@@ -70,8 +70,8 @@ SPEC CHECKSUMS:
HMSAnalyticsSDK: 4d2a88a729b1eb42f3d25f217c28937ec318a5b7
HMSBroadcastExtensionSDK: d80fe325f6c928bd8e5176290b5a4b7ae15d6fbb
HMSHLSPlayerSDK: 6a54ad4d12f3dc2270d1ecd24019d71282a4f6a3
- HMSSDK: 04aac0fefd95419cd1b4135156d4295cbcd51216
- hmssdk_flutter: 3876d06f4ad68bf48a2ceb4c797551fedb860bd1
+ HMSSDK: 6a579cb806d4760cda149002150ff0beab03749b
+ hmssdk_flutter: 0b12e79b2f184fa3308fb65dade6e3b022d805c9
HMSWebRTC: ae54e9dd91b869051b283b43b14f57d43b7bf8e1
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
diff --git a/packages/hms_room_kit/example/pubspec.lock b/packages/hms_room_kit/example/pubspec.lock
index 872696dd2..7db874700 100644
--- a/packages/hms_room_kit/example/pubspec.lock
+++ b/packages/hms_room_kit/example/pubspec.lock
@@ -214,15 +214,15 @@ packages:
path: ".."
relative: true
source: path
- version: "1.0.8"
+ version: "1.0.9"
hmssdk_flutter:
dependency: transitive
description:
name: hmssdk_flutter
- sha256: f61fb1ffcaf7296e0e2eeff9bc34d699baf9190136b8570a15cde61819cf3276
+ sha256: "112381755d47a639ef296295ace5b9d73267b89458f33ac767d1b6536a3fc898"
url: "https://pub.dev"
source: hosted
- version: "1.9.5"
+ version: "1.9.6"
http:
dependency: transitive
description:
@@ -243,10 +243,10 @@ packages:
dependency: transitive
description:
name: intl
- sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
+ sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
- version: "0.19.0"
+ version: "0.18.1"
js:
dependency: transitive
description:
@@ -347,10 +347,10 @@ packages:
dependency: transitive
description:
name: path_provider_android
- sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
+ sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
url: "https://pub.dev"
source: hosted
- version: "2.2.1"
+ version: "2.2.2"
path_provider_foundation:
dependency: transitive
description:
@@ -640,10 +640,10 @@ packages:
dependency: transitive
description:
name: url_launcher_linux
- sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd"
+ sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811
url: "https://pub.dev"
source: hosted
- version: "3.1.0"
+ version: "3.1.1"
url_launcher_macos:
dependency: transitive
description:
@@ -672,18 +672,18 @@ packages:
dependency: transitive
description:
name: url_launcher_windows
- sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc"
+ sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
url: "https://pub.dev"
source: hosted
- version: "3.1.0"
+ version: "3.1.1"
uuid:
dependency: transitive
description:
name: uuid
- sha256: df5a4d8f22ee4ccd77f8839ac7cb274ebc11ef9adcce8b92be14b797fe889921
+ sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f"
url: "https://pub.dev"
source: hosted
- version: "4.2.1"
+ version: "4.2.2"
vector_graphics:
dependency: transitive
description:
diff --git a/packages/hms_room_kit/example/pubspec.yaml b/packages/hms_room_kit/example/pubspec.yaml
index f22f2b898..e10ad412c 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.8
+version: 1.0.9
environment:
sdk: ">=2.19.6 <3.0.0"
diff --git a/packages/hms_room_kit/lib/src/assets/icons/block.svg b/packages/hms_room_kit/lib/src/assets/icons/block.svg
new file mode 100644
index 000000000..241f79abc
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/block.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/packages/hms_room_kit/lib/src/assets/icons/copy.svg b/packages/hms_room_kit/lib/src/assets/icons/copy.svg
new file mode 100644
index 000000000..e9de99898
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/copy.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/packages/hms_room_kit/lib/src/assets/icons/everyone.svg b/packages/hms_room_kit/lib/src/assets/icons/everyone.svg
new file mode 100644
index 000000000..cd20fb16d
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/everyone.svg
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/hms_room_kit/lib/src/assets/icons/hide.svg b/packages/hms_room_kit/lib/src/assets/icons/hide.svg
new file mode 100644
index 000000000..d87fb4946
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/hide.svg
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/packages/hms_room_kit/lib/src/assets/icons/resume.svg b/packages/hms_room_kit/lib/src/assets/icons/resume.svg
new file mode 100644
index 000000000..d591a2e2a
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/resume.svg
@@ -0,0 +1,3 @@
+
+
+
diff --git a/packages/hms_room_kit/lib/src/assets/icons/unpin.svg b/packages/hms_room_kit/lib/src/assets/icons/unpin.svg
new file mode 100644
index 000000000..cdd38030c
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/unpin.svg
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
diff --git a/packages/hms_room_kit/lib/src/enums/session_store_keys.dart b/packages/hms_room_kit/lib/src/enums/session_store_keys.dart
index 1cdd7b8af..4d461ad0a 100644
--- a/packages/hms_room_kit/lib/src/enums/session_store_keys.dart
+++ b/packages/hms_room_kit/lib/src/enums/session_store_keys.dart
@@ -1,15 +1,28 @@
//Enum to store the session metadata keys
// PINNED_MESSAGE_SESSION_KEY: for pinning messages
// SPOTLIGHT: for adding spotlight feature in application
-enum SessionStoreKey { pinnedMessageSessionKey, spotlight, unknown }
+enum SessionStoreKey {
+ pinnedMessageSessionKey,
+ spotlight,
+ chatState,
+ chatPeerBlacklist,
+ chatMessageBlacklist,
+ unknown
+}
extension SessionStoreKeyValues on SessionStoreKey {
static String getNameFromMethod(SessionStoreKey method) {
switch (method) {
case SessionStoreKey.pinnedMessageSessionKey:
- return "pinnedMessage";
+ return "pinnedMessages";
case SessionStoreKey.spotlight:
return "spotlight";
+ case SessionStoreKey.chatState:
+ return "chatState";
+ case SessionStoreKey.chatPeerBlacklist:
+ return "chatPeerBlacklist";
+ case SessionStoreKey.chatMessageBlacklist:
+ return "chatMessageBlacklist";
default:
return "";
}
@@ -17,10 +30,16 @@ extension SessionStoreKeyValues on SessionStoreKey {
static SessionStoreKey getMethodFromName(String key) {
switch (key) {
- case "pinnedMessage":
+ case "pinnedMessages":
return SessionStoreKey.pinnedMessageSessionKey;
case "spotlight":
return SessionStoreKey.spotlight;
+ case "chatState":
+ return SessionStoreKey.chatState;
+ case "chatPeerBlacklist":
+ return SessionStoreKey.chatPeerBlacklist;
+ case "chatMessageBlacklist":
+ return SessionStoreKey.chatMessageBlacklist;
default:
return SessionStoreKey.unknown;
}
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_chat.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_chat.dart
deleted file mode 100644
index bd968adb3..000000000
--- a/packages/hms_room_kit/lib/src/hls_viewer/hls_chat.dart
+++ /dev/null
@@ -1,395 +0,0 @@
-//Package imports
-import 'package:flutter/material.dart';
-import 'package:flutter_linkify/flutter_linkify.dart';
-import 'package:flutter_svg/svg.dart';
-import 'package:intl/intl.dart';
-import 'package:provider/provider.dart';
-import 'package:tuple/tuple.dart';
-import 'package:hmssdk_flutter/hmssdk_flutter.dart';
-import 'package:url_launcher/url_launcher.dart';
-
-//Project imports
-import 'package:hms_room_kit/src/common/app_color.dart';
-import 'package:hms_room_kit/src/common/utility_functions.dart';
-import 'package:hms_room_kit/src/enums/session_store_keys.dart';
-import 'package:hms_room_kit/src/layout_api/hms_theme_colors.dart';
-import 'package:hms_room_kit/src/widgets/common_widgets/message_container.dart';
-import 'package:hms_room_kit/src/meeting/meeting_store.dart';
-import 'package:hms_room_kit/src/widgets/common_widgets/hms_text_style.dart';
-
-///[HLSChat] is a widget that is used to display the chat screen
-///It is used to send messages to everyone, to a specific role or to a specific peer
-class HLSChat extends StatefulWidget {
- const HLSChat({super.key});
-
- @override
- State createState() => _HLSChatState();
-}
-
-class _HLSChatState extends State {
- late double widthOfScreen;
- TextEditingController messageTextController = TextEditingController();
- String valueChoose = "Everyone";
- final ScrollController _scrollController = ScrollController();
- final DateFormat formatter = DateFormat('hh:mm a');
-
- @override
- void dispose() {
- messageTextController.dispose();
- _scrollController.dispose();
- super.dispose();
- }
-
- void updateDropDownValue(dynamic newValue) {
- valueChoose = newValue;
- }
-
- ///This function is used to scroll to the end of the chat
- void _scrollToEnd() {
- WidgetsBinding.instance.addPostFrameCallback((_) =>
- _scrollController.animateTo(_scrollController.position.maxScrollExtent,
- duration: const Duration(milliseconds: 200),
- curve: Curves.easeInOut));
- }
-
- ///This function is used to get the sender of the message
- String sender(HMSMessageRecipient hmsMessageRecipient) {
- if ((hmsMessageRecipient.recipientPeer != null) &&
- (hmsMessageRecipient.recipientRoles == null)) {
- return "PRIVATE";
- } else if ((hmsMessageRecipient.recipientPeer == null) &&
- (hmsMessageRecipient.recipientRoles != null)) {
- return hmsMessageRecipient.recipientRoles![0].name;
- }
- return "";
- }
-
- ///This function is used to send the message
- void sendMessage() async {
- MeetingStore meetingStore = context.read();
- List hmsRoles = meetingStore.roles;
- String message = messageTextController.text;
- if (message.isEmpty) return;
-
- List rolesName = [];
- for (int i = 0; i < hmsRoles.length; i++) {
- rolesName.add(hmsRoles[i].name);
- }
-
- if (valueChoose == "Everyone") {
- meetingStore.sendBroadcastMessage(message);
- } else if (rolesName.contains(valueChoose)) {
- List selectedRoles = [];
- selectedRoles
- .add(hmsRoles.firstWhere((role) => role.name == valueChoose));
- meetingStore.sendGroupMessage(message, selectedRoles);
- } else if (meetingStore.localPeer!.peerId != valueChoose) {
- var peer = await meetingStore.getPeer(peerId: valueChoose);
- meetingStore.sendDirectMessage(message, peer!);
- }
- messageTextController.clear();
- }
-
- @override
- Widget build(BuildContext context) {
- widthOfScreen = MediaQuery.of(context).size.width;
-
- return WillPopScope(
- onWillPop: () async {
- context.read().setNewMessageFalse();
- return true;
- },
- child: SafeArea(
- child: Padding(
- padding: MediaQuery.of(context).viewInsets,
- child: Container(
- color: HMSThemeColors.surfaceDefault,
- child: Padding(
- padding: const EdgeInsets.only(
- top: 20.0, left: 10, right: 10, bottom: 10),
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Padding(
- padding: const EdgeInsets.only(left: 14.0),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- "Chat",
- style: HMSTextStyle.setTextStyle(
- color: themeDefaultColor,
- fontSize: 20,
- letterSpacing: 0.15,
- fontWeight: FontWeight.w600),
- ),
- const SizedBox(
- width: 15,
- ),
- ],
- ),
- ),
- ],
- ),
- ],
- ),
- Padding(
- padding: const EdgeInsets.only(top: 20, bottom: 15),
- child: Divider(
- height: 5,
- color: dividerColor,
- ),
- ),
- Selector>(
- selector: (_, meetingStore) => Tuple2(
- meetingStore.isMessageInfoShown,
- meetingStore.sessionMetadata),
- builder: (context, displayFlags, _) {
- if (displayFlags.item1 &&
- (displayFlags.item2 == null)) {
- return Column(
- children: [
- Container(
- padding: const EdgeInsets.all(16),
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(8),
- color: themeSurfaceColor),
- child: Row(
- mainAxisAlignment:
- MainAxisAlignment.spaceBetween,
- children: [
- Row(
- children: [
- SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/info.svg"),
- const SizedBox(width: 18.5),
- SizedBox(
- width: MediaQuery.of(context)
- .size
- .width *
- 0.66,
- child: Text(
- "Messages can only be seen by people in the call and are deleted when the call ends.",
- style: HMSTextStyle.setTextStyle(
- fontWeight: FontWeight.w400,
- color: themeSubHeadingColor,
- letterSpacing: 0.4,
- height: 16 / 12,
- fontSize: 12),
- ),
- ),
- ],
- ),
- GestureDetector(
- onTap: () {
- context
- .read()
- .setMessageInfoFalse();
- },
- child: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/close.svg"))
- ],
- ),
- ),
- const SizedBox(
- height: 15,
- ),
- ],
- );
- } else {
- return const SizedBox();
- }
- }),
- Selector(
- selector: (_, meetingStore) =>
- meetingStore.sessionMetadata,
- builder: (context, sessionMetadata, _) {
- if (sessionMetadata != null && sessionMetadata != "") {
- return Container(
- padding: const EdgeInsets.all(16),
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(8),
- color: themeSurfaceColor),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Row(
- children: [
- SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/pin.svg"),
- const SizedBox(width: 18.5),
- SizedBox(
- width: MediaQuery.of(context).size.width *
- 0.66,
- child: SelectableLinkify(
- text: sessionMetadata,
- onOpen: (link) async {
- Uri url = Uri.parse(link.url);
- if (await canLaunchUrl(url)) {
- await launchUrl(url,
- mode: LaunchMode
- .externalApplication);
- }
- },
- options: const LinkifyOptions(
- humanize: false),
- style: HMSTextStyle.setTextStyle(
- fontSize: 12.0,
- color: themeSubHeadingColor,
- letterSpacing: 0.4,
- height: 16 / 12,
- fontWeight: FontWeight.w400),
- linkStyle: HMSTextStyle.setTextStyle(
- fontSize: 12.0,
- color: hmsdefaultColor,
- letterSpacing: 0.4,
- height: 16 / 12,
- fontWeight: FontWeight.w400),
- ),
- ),
- ],
- ),
- GestureDetector(
- onTap: () {
- context
- .read()
- .setSessionMetadataForKey(
- key: SessionStoreKeyValues
- .getNameFromMethod(SessionStoreKey
- .pinnedMessageSessionKey),
- metadata: null);
- },
- child: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/close.svg"))
- ],
- ),
- );
- } else {
- return const SizedBox();
- }
- }),
- const SizedBox(
- height: 15,
- ),
- Expanded(
- child:
- Selector, int>>(
- selector: (_, meetingStore) => Tuple2(
- meetingStore.messages, meetingStore.messages.length),
- builder: (context, data, _) {
- if (data.item2 == 0) {
- return Center(
- child: Text(
- 'No messages',
- style: HMSTextStyle.setTextStyle(color: iconColor),
- ));
- }
- _scrollToEnd();
- return ListView.builder(
- controller: _scrollController,
- shrinkWrap: true,
- itemCount: data.item1.length,
- itemBuilder: (_, index) {
- return Container(
- padding: EdgeInsets.fromLTRB(
- (data.item1[index].sender?.isLocal ?? false)
- ? 50.0
- : 8.0,
- 10,
- (data.item1[index].sender?.isLocal ?? false)
- ? 8.0
- : 20.0,
- 10,
- ),
- margin:
- const EdgeInsets.symmetric(vertical: 2),
- child: MessageContainer(
- message: data.item1[index].message
- .trim()
- .toString(),
- senderName:
- data.item1[index].sender?.name ??
- "Anonymous",
- date: formatter
- .format(data.item1[index].time),
- role:
- data.item1[index].hmsMessageRecipient ==
- null
- ? ""
- : sender(data.item1[index]
- .hmsMessageRecipient!),
- ));
- });
- },
- ),
- ),
- Container(
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(8),
- color: themeSurfaceColor),
- child: Row(
- children: [
- Container(
- margin: const EdgeInsets.only(bottom: 5.0, left: 5.0),
- width: widthOfScreen - 70,
- child: TextField(
- textCapitalization: TextCapitalization.sentences,
- textInputAction: TextInputAction.done,
- onSubmitted: (value) {
- sendMessage();
- },
- style: HMSTextStyle.setTextStyle(color: iconColor),
- controller: messageTextController,
- decoration: InputDecoration(
- border: InputBorder.none,
- focusedBorder: InputBorder.none,
- enabledBorder: InputBorder.none,
- errorBorder: InputBorder.none,
- disabledBorder: InputBorder.none,
- hintStyle: HMSTextStyle.setTextStyle(
- color: themeHintColor,
- fontSize: 14,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w400),
- contentPadding: const EdgeInsets.only(
- left: 15, bottom: 11, top: 11, right: 15),
- hintText: "Send a message to everyone"),
- ),
- ),
- InkWell(
- onTap: () {
- if (messageTextController.text.isEmpty) {
- Utilities.showToast("Message can't be empty");
- }
- sendMessage();
- },
- child: SizedBox(
- width: 40,
- height: 40,
- child: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/send_message.svg",
- colorFilter: ColorFilter.mode(
- themeDefaultColor, BlendMode.srcIn),
- fit: BoxFit.scaleDown,
- ),
- ))
- ],
- ),
- ),
- ],
- ),
- ),
- ),
- ),
- ),
- );
- }
-}
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_chat_component.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_chat_component.dart
deleted file mode 100644
index f689ac35b..000000000
--- a/packages/hms_room_kit/lib/src/hls_viewer/hls_chat_component.dart
+++ /dev/null
@@ -1,184 +0,0 @@
-///Package imports
-import 'package:flutter/material.dart';
-import 'package:flutter_linkify/flutter_linkify.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';
-import 'package:url_launcher/url_launcher.dart';
-
-///Project imports
-import 'package:hms_room_kit/hms_room_kit.dart';
-import 'package:hms_room_kit/src/meeting/meeting_store.dart';
-
-///[HLSChatComponent] is a component that is used to show the chat
-class HLSChatComponent extends StatefulWidget {
- final double? height;
- const HLSChatComponent({super.key, this.height});
-
- @override
- State createState() => _HLSChatComponentState();
-}
-
-class _HLSChatComponentState extends State {
- TextEditingController messageTextController = TextEditingController();
- final ScrollController _scrollController = ScrollController();
-
- @override
- void dispose() {
- messageTextController.dispose();
- _scrollController.dispose();
- super.dispose();
- }
-
- ///This function scrolls to the end of the list
- void _scrollToEnd() {
- WidgetsBinding.instance.addPostFrameCallback((_) =>
- _scrollController.animateTo(_scrollController.position.maxScrollExtent,
- duration: const Duration(milliseconds: 200),
- curve: Curves.easeInOut));
- }
-
- ///This function sends the message
- void _sendMessage() async {
- MeetingStore meetingStore = context.read();
- String message = messageTextController.text.trim();
- if (message.isEmpty) return;
- meetingStore.sendBroadcastMessage(message);
- messageTextController.clear();
- }
-
- @override
- Widget build(BuildContext context) {
- return Padding(
- padding: const EdgeInsets.all(8.0),
- child: SizedBox(
- height: widget.height ?? MediaQuery.of(context).size.height * 0.2,
- child: Column(
- children: [
- ///Chat Header
- Expanded(
- child: Selector, int>>(
- selector: (_, meetingStore) => Tuple2(
- meetingStore.messages, meetingStore.messages.length),
- builder: (context, data, _) {
- _scrollToEnd();
- return ListView.builder(
- controller: _scrollController,
- shrinkWrap: true,
- itemCount: data.item1.length,
- itemBuilder: (_, index) {
- return Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- HMSTitleText(
- text: data.item1[index].sender?.name ??
- "Anonymous",
- textColor: Colors.white,
- fontSize: 14,
- lineHeight: 20,
- letterSpacing: 0.1,
- ),
- const SizedBox(
- height: 2,
- ),
- SelectableLinkify(
- text: data.item1[index].message,
- onOpen: (link) async {
- Uri url = Uri.parse(link.url);
- if (await canLaunchUrl(url)) {
- await launchUrl(url,
- mode: LaunchMode.externalApplication);
- }
- },
- options: const LinkifyOptions(humanize: false),
- style: HMSTextStyle.setTextStyle(
- color: Colors.white,
- fontSize: 14,
- height: 20 / 14,
- letterSpacing: 0.25,
- ),
- ),
- const SizedBox(
- height: 8,
- )
- ],
- );
- });
- }),
- ),
- const SizedBox(
- height: 8,
- ),
- Container(
- height: 48,
- width: MediaQuery.of(context).size.width - 16,
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(8),
- color: HMSThemeColors.surfaceDim),
- child: TextField(
- textAlignVertical: TextAlignVertical.center,
- keyboardType: TextInputType.text,
- cursorColor: HMSThemeColors.onSurfaceHighEmphasis,
- onTapOutside: (event) =>
- FocusManager.instance.primaryFocus?.unfocus(),
- onChanged: (value) {
- setState(() {});
- },
- onSubmitted: (value) {
- if (messageTextController.text.trim().isEmpty) {
- Utilities.showToast("Message can't be empty");
- return;
- }
- _sendMessage();
- },
- textCapitalization: TextCapitalization.sentences,
- textInputAction: TextInputAction.send,
- style: HMSTextStyle.setTextStyle(
- color: HMSThemeColors.onSurfaceHighEmphasis,
- fontWeight: FontWeight.w400,
- height: 20 / 14,
- fontSize: 14,
- letterSpacing: 0.25),
- controller: messageTextController,
- decoration: InputDecoration(
- suffixIcon: IconButton(
- onPressed: () {
- if (messageTextController.text.trim().isEmpty) {
- Utilities.showToast("Message can't be empty");
- }
- _sendMessage();
- },
- icon: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/send_message.svg",
- height: 24,
- width: 24,
- colorFilter: ColorFilter.mode(
- messageTextController.text.isEmpty
- ? HMSThemeColors.onSurfaceLowEmphasis
- : HMSThemeColors.onSurfaceHighEmphasis,
- BlendMode.srcIn),
- )),
- border: InputBorder.none,
- focusedBorder: OutlineInputBorder(
- borderSide: BorderSide(
- width: 2, color: HMSThemeColors.primaryDefault),
- borderRadius:
- const BorderRadius.all(Radius.circular(8))),
- hintStyle: HMSTextStyle.setTextStyle(
- color: HMSThemeColors.onSurfaceLowEmphasis,
- fontSize: 14,
- height: 0.6,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w400),
- contentPadding: const EdgeInsets.only(
- left: 16, right: 8, top: 0, bottom: 0),
- hintText: "Send a message..."),
- ),
- ),
- ],
- ),
- ),
- );
- }
-}
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 2b5960b60..5b9831978 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
@@ -4,15 +4,15 @@ import 'dart:io';
///Package imports
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
-import 'package:hms_room_kit/hms_room_kit.dart';
import 'package:provider/provider.dart';
///Project imports
import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
+import 'package:hms_room_kit/hms_room_kit.dart';
import 'package:hms_room_kit/src/widgets/bottom_sheets/chat_only_bottom_sheet.dart';
import 'package:hms_room_kit/src/widgets/tab_widgets/chat_participants_tab_bar.dart';
import 'package:hms_room_kit/src/common/utility_components.dart';
-import 'package:hms_room_kit/src/hls_viewer/hls_chat_component.dart';
+import 'package:hms_room_kit/src/hls_viewer/overlay_chat_component.dart';
import 'package:hms_room_kit/src/widgets/bottom_sheets/hls_more_options.dart';
import 'package:hms_room_kit/src/hls_viewer/hls_player_store.dart';
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
@@ -47,7 +47,7 @@ class HLSViewerBottomNavigationBar extends StatelessWidget {
.isNewMessageReceived = false;
}
return isChatOpened
- ? const HLSChatComponent()
+ ? const OverlayChatComponent()
: Container();
}),
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/overlay_chat_component.dart b/packages/hms_room_kit/lib/src/hls_viewer/overlay_chat_component.dart
new file mode 100644
index 000000000..b051cb8c9
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/hls_viewer/overlay_chat_component.dart
@@ -0,0 +1,438 @@
+///Package imports
+import 'package:flutter/material.dart';
+import 'package:flutter_linkify/flutter_linkify.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';
+import 'package:url_launcher/url_launcher.dart';
+
+///Project imports
+import 'package:hms_room_kit/hms_room_kit.dart';
+import 'package:hms_room_kit/src/meeting/meeting_store.dart';
+import 'package:hms_room_kit/src/enums/session_store_keys.dart';
+import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
+import 'package:hms_room_kit/src/widgets/bottom_sheets/chat_utilities_bottom_sheet.dart';
+import 'package:hms_room_kit/src/widgets/chat_widgets/chat_text_field.dart';
+import 'package:hms_room_kit/src/widgets/chat_widgets/pin_chat_widget.dart';
+import 'package:hms_room_kit/src/widgets/chat_widgets/recipient_selector_chip.dart';
+
+///[OverlayChatComponent] is a component that is used to show the chat
+class OverlayChatComponent extends StatefulWidget {
+ final double? height;
+ const OverlayChatComponent({super.key, this.height});
+
+ @override
+ State createState() => _OverlayChatComponentState();
+}
+
+class _OverlayChatComponentState extends State {
+ final ScrollController _scrollController = ScrollController();
+ String currentlySelectedValue = "Choose a Recipient";
+ String? currentlySelectedpeerId;
+
+ @override
+ void dispose() {
+ _scrollController.dispose();
+ super.dispose();
+ }
+
+ @override
+ void initState() {
+ super.initState();
+ setRecipientChipValue();
+ }
+
+ ///This function sets the recipient chip value
+ void setRecipientChipValue() {
+ dynamic currentValue = context.read().recipientSelectorValue;
+ if (currentValue is HMSPeer) {
+ currentlySelectedValue = currentValue.name;
+ currentlySelectedpeerId = currentValue.peerId;
+ } else if (currentValue is HMSRole) {
+ currentlySelectedValue = currentValue.name;
+ } else if (currentValue is String) {
+ currentlySelectedValue = currentValue;
+ }
+ }
+
+ ///This function scrolls to the end of the list
+ void _scrollToEnd() {
+ if (_scrollController.hasClients) {
+ WidgetsBinding.instance.addPostFrameCallback((_) => _scrollController
+ .animateTo(_scrollController.position.maxScrollExtent,
+ duration: const Duration(milliseconds: 200),
+ curve: Curves.easeInOut));
+ }
+ }
+
+ ///This function updates the selected value
+ void _updateValueChoose(String newValue, String? peerId) {
+ currentlySelectedValue = newValue;
+ currentlySelectedpeerId = peerId;
+ }
+
+ ///This function returns the message type text for public, group and private messages
+ String messageTypeText(HMSMessageRecipient? hmsMessageRecipient) {
+ if (hmsMessageRecipient == null) return "";
+ if ((hmsMessageRecipient.recipientPeer != null) &&
+ (hmsMessageRecipient.recipientRoles == null)) {
+ if (hmsMessageRecipient.recipientPeer is HMSLocalPeer) {
+ return "to You (DM)";
+ } else {
+ return "to ${hmsMessageRecipient.recipientPeer?.name} (DM)";
+ }
+ } else if ((hmsMessageRecipient.recipientPeer == null) &&
+ (hmsMessageRecipient.recipientRoles != null)) {
+ return "to ${hmsMessageRecipient.recipientRoles?.first.name} (Group)";
+ }
+ return "";
+ }
+
+ ///This function sends the message
+ void _sendMessage(TextEditingController messageTextController) async {
+ MeetingStore meetingStore = context.read();
+ List hmsRoles = meetingStore.roles;
+ String message = messageTextController.text.trim();
+ if (message.isEmpty) return;
+
+ List rolesName = [];
+ for (int i = 0; i < hmsRoles.length; i++) {
+ rolesName.add(hmsRoles[i].name);
+ }
+
+ if (currentlySelectedValue == "Everyone") {
+ meetingStore.sendBroadcastMessage(message);
+ } else if (rolesName.contains(currentlySelectedValue)) {
+ List selectedRoles = [];
+ selectedRoles.add(
+ hmsRoles.firstWhere((role) => role.name == currentlySelectedValue));
+ meetingStore.sendGroupMessage(message, selectedRoles);
+ } else if (currentlySelectedpeerId != null &&
+ meetingStore.localPeer!.peerId != currentlySelectedpeerId) {
+ var peer = await meetingStore.getPeer(peerId: currentlySelectedpeerId!);
+ if (peer != null) {
+ meetingStore.sendDirectMessage(message, peer);
+ }
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Selector(
+ selector: (_, meetingStore) => meetingStore.pinnedMessages.isNotEmpty,
+ builder: (_, isPinnedMessage, __) {
+ return SizedBox(
+ height: isPinnedMessage
+ ? MediaQuery.of(context).size.height * 0.4
+ : MediaQuery.of(context).size.height * 0.3,
+ child: Column(
+ children: [
+ ///Chat Header
+ Expanded(
+ child: Selector, int>>(
+ selector: (_, meetingStore) => Tuple2(
+ meetingStore.messages,
+ meetingStore.messages.length),
+ builder: (context, data, _) {
+ _scrollToEnd();
+ return ListView.builder(
+ controller: _scrollController,
+ shrinkWrap: true,
+ itemCount: data.item1.length,
+ itemBuilder: (_, index) {
+ return Row(
+ mainAxisAlignment:
+ MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(
+ child: Column(
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ Container(
+ constraints: BoxConstraints(
+ maxWidth:
+ MediaQuery.of(context)
+ .size
+ .width *
+ 0.5),
+ child: HMSTitleText(
+ text: data.item1[index].sender
+ ?.name ??
+ "Anonymous",
+ textColor: Colors.white,
+ fontSize: 14,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ ),
+ ),
+ const SizedBox(
+ width: 4,
+ ),
+ Container(
+ constraints: BoxConstraints(
+ maxWidth:
+ MediaQuery.of(context)
+ .size
+ .width *
+ 0.5),
+ child: HMSSubtitleText(
+ text: messageTypeText(data
+ .item1[index]
+ .hmsMessageRecipient),
+ textColor: HMSThemeColors
+ .onSurfaceMediumEmphasis),
+ ),
+ ],
+ ),
+ const SizedBox(
+ height: 2,
+ ),
+ SelectableLinkify(
+ text: data.item1[index].message,
+ onOpen: (link) async {
+ Uri url = Uri.parse(link.url);
+ if (await canLaunchUrl(url)) {
+ await launchUrl(url,
+ mode: LaunchMode
+ .externalApplication);
+ }
+ },
+ scrollPhysics:
+ const NeverScrollableScrollPhysics(),
+ options: const LinkifyOptions(
+ humanize: false),
+ style: HMSTextStyle.setTextStyle(
+ color: Colors.white,
+ fontSize: 14,
+ height: 20 / 14,
+ letterSpacing: 0.25,
+ ),
+ ),
+ const SizedBox(
+ height: 8,
+ )
+ ],
+ ),
+ ),
+ GestureDetector(
+ onTap: () {
+ 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:
+ ChatUtilitiesBottomSheet(
+ message: data.item1[index],
+ )),
+ );
+ },
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/more.svg",
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors
+ .onSurfaceMediumEmphasis,
+ BlendMode.srcIn),
+ ),
+ )
+ ],
+ );
+ });
+ }),
+ ),
+ const SizedBox(
+ height: 8,
+ ),
+
+ ///This renders the pinned message widget
+ PinChatWidget(
+ backgroundColor: HMSThemeColors.backgroundDim.withAlpha(64),
+ ),
+ Selector(
+ selector: (_, meetingStore) =>
+ meetingStore.chatControls["enabled"],
+ builder: (_, isChatEnabled, __) {
+ return isChatEnabled
+ ? Padding(
+ padding:
+ const EdgeInsets.only(bottom: 8.0, top: 0),
+ child: Row(
+ mainAxisAlignment:
+ MainAxisAlignment.spaceBetween,
+ children: [
+ if ((HMSRoomLayout.chatData
+ ?.isPrivateChatEnabled ??
+ false) ||
+ (HMSRoomLayout.chatData
+ ?.isPublicChatEnabled ??
+ false) ||
+ (HMSRoomLayout.chatData?.rolesWhitelist
+ .isNotEmpty ??
+ false))
+ ReceipientSelectorChip(
+ currentlySelectedValue:
+ currentlySelectedValue,
+ updateSelectedValue: _updateValueChoose,
+ chipColor: HMSThemeColors.backgroundDim
+ .withAlpha(64),
+ ),
+ const SizedBox(),
+ if (HMSRoomLayout.chatData?.realTimeControls
+ ?.canDisableChat ??
+ false)
+ Row(
+ mainAxisAlignment:
+ MainAxisAlignment.end,
+ children: [
+ PopupMenuButton(
+ padding: EdgeInsets.zero,
+ position: PopupMenuPosition.over,
+ color:
+ HMSThemeColors.surfaceDefault,
+ itemBuilder: (context) => [
+ PopupMenuItem(
+ value: 1,
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius:
+ BorderRadius
+ .circular(50)),
+ child: Row(children: [
+ SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/${context.read().chatControls["enabled"] ? "recording_paused" : "resume"}.svg",
+ width: 20,
+ height: 20,
+ colorFilter:
+ ColorFilter.mode(
+ HMSThemeColors
+ .onSurfaceHighEmphasis,
+ BlendMode
+ .srcIn)),
+ const SizedBox(
+ width: 8,
+ ),
+ HMSTitleText(
+ text: context
+ .read<
+ MeetingStore>()
+ .chatControls[
+ "enabled"]
+ ? "Pause Chat"
+ : "Resume Chat",
+ textColor: HMSThemeColors
+ .onSurfaceHighEmphasis,
+ fontSize: 14,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ ),
+ ]),
+ ))
+ ],
+ onSelected: (value) {
+ switch (value) {
+ case 1:
+ context
+ .read()
+ .setSessionMetadataForKey(
+ key: SessionStoreKeyValues
+ .getNameFromMethod(
+ SessionStoreKey
+ .chatState),
+ metadata: {
+ "enabled": context
+ .read<
+ MeetingStore>()
+ .chatControls[
+ "enabled"]
+ ? false
+ : true,
+ "updatedBy": {
+ "peerID": context
+ .read<
+ MeetingStore>()
+ .localPeer
+ ?.peerId,
+ "userID": context
+ .read<
+ MeetingStore>()
+ .localPeer
+ ?.customerUserId,
+ "userName": context
+ .read<
+ MeetingStore>()
+ .localPeer
+ ?.name
+ },
+ "updatedAt": DateTime
+ .now()
+ .millisecondsSinceEpoch //unix timestamp in miliseconds
+ });
+ break;
+ }
+ },
+ child: Container(
+ height: 24,
+ width: 24,
+ decoration: BoxDecoration(
+ borderRadius:
+ const BorderRadius.all(
+ Radius.circular(4)),
+ color: HMSThemeColors
+ .backgroundDim
+ .withOpacity(0.64)),
+ child: Padding(
+ padding:
+ const EdgeInsets.all(4.0),
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/more.svg",
+ height: 16,
+ width: 16,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors
+ .onSurfaceLowEmphasis,
+ BlendMode.srcIn),
+ ),
+ ),
+ ),
+ )
+ ],
+ )
+ ],
+ ),
+ )
+ : const SizedBox();
+ }),
+ if ((HMSRoomLayout.chatData?.isPrivateChatEnabled ?? false) ||
+ (HMSRoomLayout.chatData?.isPublicChatEnabled ?? false) ||
+ (HMSRoomLayout.chatData?.rolesWhitelist.isNotEmpty ??
+ false))
+ ChatTextField(
+ sendMessage: _sendMessage,
+ toastBackgroundColor:
+ HMSThemeColors.backgroundDim.withAlpha(64),
+ )
+ ],
+ ),
+ );
+ }),
+ );
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/layout_api/hms_conferencing_items.dart b/packages/hms_room_kit/lib/src/layout_api/hms_conferencing_items.dart
index 15dd5129a..9c630c695 100644
--- a/packages/hms_room_kit/lib/src/layout_api/hms_conferencing_items.dart
+++ b/packages/hms_room_kit/lib/src/layout_api/hms_conferencing_items.dart
@@ -140,12 +140,14 @@ class OnStageExp {
String? removeFromStageLabel;
String? onStageRole;
List? offStageRoles;
+ bool? skipPreviewForRoleChange;
OnStageExp({
this.bringToStageLabel,
this.removeFromStageLabel,
this.onStageRole,
this.offStageRoles,
+ this.skipPreviewForRoleChange,
});
OnStageExp.fromJson(Map? json) {
@@ -154,6 +156,7 @@ class OnStageExp {
removeFromStageLabel = null;
onStageRole = null;
offStageRoles = null;
+ skipPreviewForRoleChange = null;
return;
}
bringToStageLabel = json['bring_to_stage_label'];
@@ -163,6 +166,9 @@ class OnStageExp {
json.containsKey('off_stage_roles') && json['off_stage_roles'] is List
? List.from(json['off_stage_roles'])
: null;
+ skipPreviewForRoleChange = json.containsKey('skip_preview_for_role_change')
+ ? json['skip_preview_for_role_change']
+ : null;
}
Map toJson() {
@@ -173,6 +179,7 @@ class OnStageExp {
if (offStageRoles != null && offStageRoles!.isNotEmpty) {
data['off_stage_roles'] = offStageRoles;
}
+ data['skip_preview_for_role_change'] = skipPreviewForRoleChange;
return data;
}
}
@@ -218,14 +225,34 @@ class Chat {
bool? isOpenInitially;
bool? isOverlay;
bool? allowPinningMessages;
+ String? chatTitle;
+ String? messagePlaceholder;
+ bool? isPrivateChatEnabled;
+ bool? isPublicChatEnabled;
+ List rolesWhitelist = [];
+ RealTimeControls? realTimeControls;
- Chat({this.isOpenInitially, this.isOverlay, this.allowPinningMessages});
+ Chat(
+ {this.isOpenInitially,
+ this.isOverlay,
+ this.allowPinningMessages,
+ this.chatTitle,
+ this.messagePlaceholder,
+ this.isPrivateChatEnabled,
+ this.isPublicChatEnabled,
+ this.rolesWhitelist = const []});
Chat.fromJson(Map? json) {
if (json == null) {
isOpenInitially = null;
isOverlay = null;
allowPinningMessages = null;
+ chatTitle = "Chat";
+ messagePlaceholder = "Send a message...";
+ isPrivateChatEnabled = false;
+ isPublicChatEnabled = false;
+ rolesWhitelist = [];
+ realTimeControls = null;
return;
}
isOpenInitially = json.containsKey('initial_state')
@@ -237,6 +264,23 @@ class Chat {
allowPinningMessages = json.containsKey('allow_pinning_messages')
? json['allow_pinning_messages']
: null;
+ chatTitle = json.containsKey('chat_title') ? json['chat_title'] : "Chat";
+ messagePlaceholder = json.containsKey('message_placeholder')
+ ? json['message_placeholder']
+ : "Send a message...";
+ isPrivateChatEnabled = json.containsKey('private_chat_enabled')
+ ? json['private_chat_enabled']
+ : false;
+ isPublicChatEnabled = json.containsKey('public_chat_enabled')
+ ? json['public_chat_enabled']
+ : false;
+ rolesWhitelist =
+ json.containsKey('roles_whitelist') && json['roles_whitelist'] is List
+ ? List.from(json['roles_whitelist'])
+ : [];
+ realTimeControls = json.containsKey('real_time_controls')
+ ? RealTimeControls.fromJson(json['real_time_controls'])
+ : null;
}
Map toJson() {
@@ -250,6 +294,62 @@ class Chat {
if (allowPinningMessages != null) {
data['allow_pinning_messages'] = allowPinningMessages;
}
+ if (chatTitle != null) {
+ data['chat_title'] = chatTitle;
+ }
+ if (messagePlaceholder != null) {
+ data['message_placeholder'] = messagePlaceholder;
+ }
+ if (isPrivateChatEnabled != null) {
+ data['private_chat_enabled'] = isPrivateChatEnabled;
+ }
+ if (isPublicChatEnabled != null) {
+ data['public_chat_enabled'] = isPublicChatEnabled;
+ }
+ if (rolesWhitelist.isNotEmpty) {
+ data['roles_whitelist'] = rolesWhitelist;
+ }
+ if (realTimeControls != null) {
+ data['real_time_controls'] = realTimeControls!.toJson();
+ }
+ return data;
+ }
+}
+
+class RealTimeControls {
+ bool? canBlockUser;
+ bool? canDisableChat;
+ bool? canHideMessage;
+
+ RealTimeControls(
+ {this.canBlockUser, this.canDisableChat, this.canHideMessage});
+
+ RealTimeControls.fromJson(Map? json) {
+ if (json == null) {
+ canBlockUser = null;
+ canDisableChat = null;
+ canHideMessage = null;
+ return;
+ }
+ canBlockUser =
+ json.containsKey("can_block_user") ? json["can_block_user"] : false;
+ canDisableChat =
+ json.containsKey("can_disable_chat") ? json["can_disable_chat"] : false;
+ canHideMessage =
+ json.containsKey("can_hide_message") ? json["can_hide_message"] : false;
+ }
+
+ Map toJson() {
+ final Map data = {};
+ if (canBlockUser != null) {
+ data["can_block_user"] = canBlockUser;
+ }
+ if (canDisableChat != null) {
+ data["can_disable_chat"] = canDisableChat;
+ }
+ if (canHideMessage != null) {
+ data["can_hide_message"] = canHideMessage;
+ }
return data;
}
}
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 6394e0201..8265bd311 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
@@ -217,6 +217,7 @@ class HMSRoomLayout {
static bool isParticipantsListEnabled = true;
static bool isBRBEnabled = true;
static List? offStageRoles = [];
+ static bool skipPreviewForRole = false;
static Future getRoomLayout(
{required HMSSDKInteractor hmsSDKInteractor,
@@ -263,6 +264,9 @@ class HMSRoomLayout {
null;
offStageRoles = roleLayoutData?.screens?.conferencing?.defaultConf
?.elements?.onStageExp?.offStageRoles;
+ skipPreviewForRole = roleLayoutData?.screens?.conferencing?.defaultConf
+ ?.elements?.onStageExp?.skipPreviewForRoleChange ??
+ false;
} else {
chatData = roleLayoutData
?.screens?.conferencing?.hlsLiveStreaming?.elements?.chat;
@@ -274,6 +278,14 @@ class HMSRoomLayout {
null;
offStageRoles = roleLayoutData?.screens?.conferencing?.hlsLiveStreaming
?.elements?.onStageExp?.offStageRoles;
+ skipPreviewForRole = roleLayoutData
+ ?.screens
+ ?.conferencing
+ ?.hlsLiveStreaming
+ ?.elements
+ ?.onStageExp
+ ?.skipPreviewForRoleChange ??
+ false;
}
}
diff --git a/packages/hms_room_kit/lib/src/meeting/meeting_bottom_navigation_bar.dart b/packages/hms_room_kit/lib/src/meeting/meeting_bottom_navigation_bar.dart
index bd33747a2..b86cb3a40 100644
--- a/packages/hms_room_kit/lib/src/meeting/meeting_bottom_navigation_bar.dart
+++ b/packages/hms_room_kit/lib/src/meeting/meeting_bottom_navigation_bar.dart
@@ -6,14 +6,13 @@ import 'package:tuple/tuple.dart';
///Project imports
import 'package:hms_room_kit/src/meeting/meeting_navigation_visibility_controller.dart';
-import 'package:hms_room_kit/src/hls_viewer/hls_chat_component.dart';
+import 'package:hms_room_kit/src/hls_viewer/overlay_chat_component.dart';
import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
import 'package:hms_room_kit/src/widgets/bottom_sheets/chat_only_bottom_sheet.dart';
import 'package:hms_room_kit/src/widgets/tab_widgets/chat_participants_tab_bar.dart';
import 'package:hms_room_kit/hms_room_kit.dart';
import 'package:hms_room_kit/src/common/utility_components.dart';
import 'package:hms_room_kit/src/enums/meeting_mode.dart';
-import 'package:hms_room_kit/src/enums/session_store_keys.dart';
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
import 'package:hms_room_kit/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_embedded_button.dart';
@@ -54,9 +53,7 @@ class _MeetingBottomNavigationBarState
padding: EdgeInsets.only(
bottom: MediaQuery.of(context).viewInsets.bottom +
15),
- child: HLSChatComponent(
- height: MediaQuery.of(context).size.height * 0.3,
- ),
+ child: const OverlayChatComponent(),
))
: const SizedBox();
}),
@@ -190,13 +187,6 @@ class _MeetingBottomNavigationBarState
}
else
{
- context
- .read()
- .getSessionMetadata(
- SessionStoreKeyValues
- .getNameFromMethod(
- SessionStoreKey
- .pinnedMessageSessionKey)),
context
.read()
.setNewMessageFalse(),
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 e4d869fa2..27bf239bc 100644
--- a/packages/hms_room_kit/lib/src/meeting/meeting_page.dart
+++ b/packages/hms_room_kit/lib/src/meeting/meeting_page.dart
@@ -32,6 +32,7 @@ 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/toasts/hms_recording_error_toast.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_chat_pause_resume_toast.dart';
///[MeetingPage] is the main page of the meeting
///It takes the following parameters:
@@ -87,7 +88,7 @@ class _MeetingPageState extends State {
peer: toast.toastData,
meetingStore: context.read(),
);
- case HMSToastsType.errorToast:
+ case HMSToastsType.recordingErrorToast:
return HMSRecordingErrorToast(
recordingError: toast.toastData,
meetingStore: context.read());
@@ -103,6 +104,13 @@ class _MeetingPageState extends State {
toastColor: Utilities.getToastColor(index, toastsCount),
meetingStore: context.read(),
);
+ case HMSToastsType.chatPauseResumeToast:
+ return HMSChatPauseResumeToast(
+ isChatEnabled: toast.toastData["enabled"],
+ userName: toast.toastData["updatedBy"],
+ meetingStore: context.read());
+ default:
+ return const SizedBox();
}
}
@@ -405,7 +413,7 @@ class _MeetingPageState extends State {
color: HMSThemeColors.backgroundDim,
child: (isVideoOn && previewForRoleTracks.item1 != null)
? Center(
- child: HMSVideoView(
+ child: HMSTextureView(
scaleType: ScaleType.SCALE_ASPECT_FILL,
track: previewForRoleTracks.item1!,
setMirror: true,
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 67964737d..2852ca961 100644
--- a/packages/hms_room_kit/lib/src/meeting/meeting_store.dart
+++ b/packages/hms_room_kit/lib/src/meeting/meeting_store.dart
@@ -179,7 +179,17 @@ class MeetingStore extends ChangeNotifier
bool retryHLS = true;
- String? sessionMetadata;
+ ///[pinnedMessages] is the list of pinned messages
+ List pinnedMessages = [];
+
+ ///[hiddenMessages] is the list of hidden messages
+ List hiddenMessages = [];
+
+ ///[blackListedUserIds] is the list of user ids which are blacklisted from chat
+ List blackListedUserIds = [];
+
+ ///[recipientSelectorValue] is the value of the recipient selector chip
+ dynamic recipientSelectorValue = "Choose a Recipient";
bool isPipActive = false;
@@ -237,6 +247,9 @@ class MeetingStore extends ChangeNotifier
///Video View for screenshare
HMSTextureViewController? screenshareViewController;
+ ///Stores whether Chat State
+ Map chatControls = {"enabled": true, "updatedBy": null};
+
Future join(String userName, String roomCode,
{HMSConfig? roomConfig}) async {
//If roomConfig is null then only we call the methods to get the authToken
@@ -272,6 +285,7 @@ class MeetingStore extends ChangeNotifier
WidgetsBinding.instance.addObserver(this);
setMeetingModeUsingLayoutApi();
_hmsSDKInteractor.join(config: roomConfig);
+ setRecipientSelectorValue();
meetingUrl = roomCode;
return null;
}
@@ -421,9 +435,9 @@ class MeetingStore extends ChangeNotifier
toast.hmsToastType == HMSToastsType.roleChangeToast &&
data.peerId == toast.toastData.peerId);
break;
- case HMSToastsType.errorToast:
+ case HMSToastsType.recordingErrorToast:
toasts.removeWhere(
- (toast) => toast.hmsToastType == HMSToastsType.errorToast);
+ (toast) => toast.hmsToastType == HMSToastsType.recordingErrorToast);
break;
case HMSToastsType.localScreenshareToast:
toasts.removeWhere((toast) =>
@@ -434,6 +448,12 @@ class MeetingStore extends ChangeNotifier
toast.hmsToastType == HMSToastsType.roleChangeDeclineToast &&
data.peerId == toast.toastData.peerId);
break;
+ case HMSToastsType.chatPauseResumeToast:
+ toasts.removeWhere((toast) =>
+ toast.hmsToastType == HMSToastsType.chatPauseResumeToast);
+ case HMSToastsType.errorToast:
+ toasts.removeWhere(
+ (toast) => toast.hmsToastType == HMSToastsType.errorToast);
}
notifyListeners();
}
@@ -470,6 +490,15 @@ class MeetingStore extends ChangeNotifier
hmsActionResultListener: this);
}
+ void setPreviousRole(String oldRole) {
+ _hmsSDKInteractor.changeMetadata(
+ metadata: "{\"isBRBOn\":false,\"prevRole\":\"$oldRole\"}",
+ hmsActionResultListener: this);
+ if (isRaisedHand) {
+ toggleLocalPeerHandRaise();
+ }
+ }
+
Future> getRoles() async {
return await _hmsSDKInteractor.getRoles();
}
@@ -574,14 +603,14 @@ class MeetingStore extends ChangeNotifier
if (indexForVideoTrack != -1) {
previewForRoleVideoTrack =
result[indexForVideoTrack] as HMSLocalVideoTrack;
- isVideoOn = true;
+ isVideoOn = !(previewForRoleVideoTrack?.isMute ?? true);
}
var indexForAudioTrack = result.indexWhere(
(element) => element.kind == HMSTrackKind.kHMSTrackKindAudio);
if (indexForAudioTrack != -1) {
previewForRoleAudioTrack =
result[indexForAudioTrack] as HMSLocalAudioTrack;
- isMicOn = true;
+ isMicOn = !(previewForRoleAudioTrack?.isMute ?? true);
}
notifyListeners();
}
@@ -715,19 +744,31 @@ class MeetingStore extends ChangeNotifier
}
log("Calling refresh PeerList Method $peerListIterators");
peerListIterators.clear();
+
+ ///Here we get off stage roles
List? offStageRoles = HMSRoomLayout.roleLayoutData?.screens
?.conferencing?.defaultConf?.elements?.onStageExp?.offStageRoles;
+
+ ///For each off stage role we get the peer list iterator
offStageRoles?.forEach((role) async {
var peerListIterator = await _hmsSDKInteractor.getPeerListIterator(
peerListIteratorOptions:
PeerListIteratorOptions(limit: 10, byRoleName: role));
+
+ ///If the peerListIterator is not null then we add it to the map
if (peerListIterator != null && peerListIterator is HMSPeerListIterator) {
peerListIterators[role] = peerListIterator;
+
+ ///Here we subtract the number of participants in meeting with the number of participants in the iterator
participantsInMeeting -= participantsInMeetingMap[role]?.length ?? 0;
participantsInMeetingMap[role]?.clear();
+
+ ///Here we get the first set of peers from the iterator
dynamic nonRealTimePeers = await peerListIterator.next();
if (nonRealTimePeers is List) {
- log("Calling refresh PeerList Method $nonRealTimePeers");
+ log("Calling refresh PeerList Method here $nonRealTimePeers");
+
+ ///Here we add the peers to the participantsInMeetingMap
if (nonRealTimePeers.isNotEmpty) {
for (var peer in nonRealTimePeers) {
addPeer(peer);
@@ -1333,6 +1374,12 @@ class MeetingStore extends ChangeNotifier
participantsInMeetingMap["Hand Raised"]
?.removeWhere((oldPeer) => oldPeer.peer.peerId == peer.peerId);
}
+
+ ///If peer is removed from room but selected in the recipient selector
+ ///we reset it to "Choose a Recipient"
+ if (recipientSelectorValue == peer) {
+ recipientSelectorValue = "Choose a Recipient";
+ }
notifyListeners();
}
@@ -1397,6 +1444,10 @@ class MeetingStore extends ChangeNotifier
participantsInMeetingMap[peer.role.name]?[index].updatePeer(peer);
}
notifyListeners();
+ } else if (peerUpdate == HMSPeerUpdate.metadataChanged) {
+ participantsInMeetingMap[peer.role.name]?[index].updatePeer(peer);
+ } else if (peerUpdate == HMSPeerUpdate.metadataChanged) {
+ participantsInMeetingMap[peer.role.name]?[index].updatePeer(peer);
}
} else {
if (peerUpdate == HMSPeerUpdate.roleUpdated) {
@@ -1456,6 +1507,7 @@ class MeetingStore extends ChangeNotifier
case HMSPeerUpdate.roleUpdated:
if (peer.isLocal) {
getSpotlightPeer();
+ setPreviousRole(localPeer?.role.name ?? "");
resetLayout(peer.role.name);
localPeer = peer;
}
@@ -1716,11 +1768,66 @@ class MeetingStore extends ChangeNotifier
SessionStoreKey keyType = SessionStoreKeyValues.getMethodFromName(key);
switch (keyType) {
case SessionStoreKey.pinnedMessageSessionKey:
- sessionMetadata = value;
+ pinnedMessages.clear();
+ if (value != null) {
+ var data = jsonDecode(value);
+ if (data != null && data.isNotEmpty) {
+ data.forEach((element) {
+ pinnedMessages.add({
+ "id": element["id"],
+ "text": element["text"],
+ "pinnedBy": element["pinnedBy"]
+ });
+ });
+ }
+ }
+ notifyListeners();
break;
case SessionStoreKey.spotlight:
setPeerToSpotlight(value);
break;
+ case SessionStoreKey.chatState:
+ if (value != null) {
+ ///Here we set the chat pause/resume state
+ var data = jsonDecode(value);
+
+ ///If current and previous state is same we return
+ if (chatControls["enabled"] == data["enabled"]) break;
+ chatControls["enabled"] = data["enabled"];
+ chatControls["updatedBy"] = data["updatedBy"]["userName"];
+ if ((HMSRoomLayout.chatData?.isPrivateChatEnabled ?? false) ||
+ (HMSRoomLayout.chatData?.isPublicChatEnabled ?? false) ||
+ (HMSRoomLayout.chatData?.rolesWhitelist.isNotEmpty ?? false)) {
+ toasts.add(HMSToastModel(chatControls,
+ hmsToastType: HMSToastsType.chatPauseResumeToast));
+ }
+ notifyListeners();
+ }
+ break;
+ case SessionStoreKey.chatPeerBlacklist:
+ blackListedUserIds.clear();
+ if (value != null) {
+ var data = jsonDecode(value);
+ if (data != null && data.isNotEmpty) {
+ data.forEach((element) {
+ blackListedUserIds.add(element);
+ });
+ }
+ notifyListeners();
+ }
+ break;
+ case SessionStoreKey.chatMessageBlacklist:
+ hiddenMessages.clear();
+ if (value != null) {
+ var data = jsonDecode(value);
+ if (data != null && data.isNotEmpty) {
+ data.forEach((element) {
+ hiddenMessages.add(element);
+ messages.removeWhere((message) => message.messageId == element);
+ });
+ }
+ }
+ break;
case SessionStoreKey.unknown:
break;
}
@@ -1874,11 +1981,79 @@ class MeetingStore extends ChangeNotifier
audioPlayerVolume = volume;
}
- void setSessionMetadataForKey({required String key, String? metadata}) {
+ void setSessionMetadataForKey({required String key, dynamic metadata}) {
_hmsSessionStore?.setSessionMetadataForKey(
key: key, data: metadata, hmsActionResultListener: this);
}
+ ///[togglePeerBlock] method is used to block/unblock a peer from chat
+ void togglePeerBlock({required String userId, bool isBlocked = false}) {
+ if (!isBlocked) {
+ blackListedUserIds.add(userId);
+ } else {
+ blackListedUserIds.remove(userId);
+ }
+ setSessionMetadataForKey(
+ key: SessionStoreKeyValues.getNameFromMethod(
+ SessionStoreKey.chatPeerBlacklist),
+ metadata: blackListedUserIds);
+ }
+
+ ///[unpinMessage] method is used to unpin a message in the session
+ void unpinMessage(String messageId) {
+ pinnedMessages.removeWhere((element) => element["id"] == messageId);
+ setSessionMetadataForKey(
+ key: SessionStoreKeyValues.getNameFromMethod(
+ SessionStoreKey.pinnedMessageSessionKey),
+ metadata: pinnedMessages);
+ }
+
+ ///[pinMessage] method is used to pin a message for the session
+ void pinMessage(HMSMessage message) {
+ if (pinnedMessages.length == 3) {
+ pinnedMessages.removeAt(0);
+ notifyListeners();
+ }
+ var data = List.from(pinnedMessages);
+ data.add({
+ "id": message.messageId,
+ "text": "${message.sender?.name}: ${message.message}",
+ "pinnedBy": localPeer?.name,
+ });
+ setSessionMetadataForKey(
+ key: SessionStoreKeyValues.getNameFromMethod(
+ SessionStoreKey.pinnedMessageSessionKey),
+ metadata: data);
+ }
+
+ void hideMessage(HMSMessage message) {
+ hiddenMessages.add(message.messageId);
+ unpinMessage(message.messageId);
+ setSessionMetadataForKey(
+ key: SessionStoreKeyValues.getNameFromMethod(
+ SessionStoreKey.chatMessageBlacklist),
+ metadata: hiddenMessages);
+ notifyListeners();
+ }
+
+ ///[setReipientSelectorValue] method is used to set the value of recipient selector
+ void setRecipientSelectorValue() {
+ if (HMSRoomLayout.chatData?.isPublicChatEnabled ?? false) {
+ recipientSelectorValue = "Everyone";
+ return;
+ } else if (HMSRoomLayout.chatData?.rolesWhitelist.isNotEmpty ?? false) {
+ recipientSelectorValue = HMSRoomLayout.chatData?.rolesWhitelist
+ .firstWhere(
+ (role) => role != HMSRoomLayout.roleLayoutData?.role) ??
+ "Choose a Recipient";
+ } else if (HMSRoomLayout.chatData?.isPrivateChatEnabled ?? false) {
+ if (peers.length > 1) {
+ recipientSelectorValue = peers[1];
+ }
+ }
+ notifyListeners();
+ }
+
void getSessionMetadata(String key) async {
dynamic result = await _hmsSessionStore?.getSessionMetadataForKey(key: key);
if (result is HMSException) {
@@ -1887,9 +2062,8 @@ class MeetingStore extends ChangeNotifier
time: 5);
return;
}
- if (result != null) {
- sessionMetadata = result as String;
- }
+
+ ///Add pinned message here
notifyListeners();
}
@@ -2189,7 +2363,7 @@ class MeetingStore extends ChangeNotifier
break;
case HMSActionResultListenerMethod.startRtmpOrRecording:
toasts.add(HMSToastModel(hmsException,
- hmsToastType: HMSToastsType.errorToast));
+ hmsToastType: HMSToastsType.recordingErrorToast));
recordingType["browser"] = HMSRecordingState.failed;
notifyListeners();
break;
@@ -2228,7 +2402,9 @@ class MeetingStore extends ChangeNotifier
Utilities.showToast("Change role failed");
break;
case HMSActionResultListenerMethod.setSessionMetadataForKey:
- Utilities.showToast("Set session metadata failed");
+ toasts.add(HMSToastModel(hmsException,
+ hmsToastType: HMSToastsType.errorToast));
+ notifyListeners();
break;
case HMSActionResultListenerMethod.sendHLSTimedMetadata:
// TODO: Handle this case.
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 971273c6e..fdacdf39b 100644
--- a/packages/hms_room_kit/lib/src/preview/preview_store.dart
+++ b/packages/hms_room_kit/lib/src/preview/preview_store.dart
@@ -103,6 +103,8 @@ class PreviewStore extends ChangeNotifier
getRoles();
getCurrentAudioDevice();
getAudioDevicesList();
+ toggleCameraMuteState();
+ toggleMicMuteState();
notifyListeners();
}
diff --git a/packages/hms_room_kit/lib/src/screen_controller.dart b/packages/hms_room_kit/lib/src/screen_controller.dart
index 9b0090649..006576058 100644
--- a/packages/hms_room_kit/lib/src/screen_controller.dart
+++ b/packages/hms_room_kit/lib/src/screen_controller.dart
@@ -104,8 +104,8 @@ class _ScreenControllerState extends State {
}
_hmsSDKInteractor = HMSSDKInteractor(
iOSScreenshareConfig: widget.options?.iOSScreenshareConfig,
- joinWithMutedAudio: AppDebugConfig.joinWithMutedAudio,
- joinWithMutedVideo: AppDebugConfig.joinWithMutedVideo,
+ joinWithMutedAudio: true,
+ joinWithMutedVideo: true,
isSoftwareDecoderDisabled: AppDebugConfig.isSoftwareDecoderDisabled,
isAudioMixerDisabled: AppDebugConfig.isAudioMixerDisabled,
isPrebuilt: true);
@@ -125,9 +125,11 @@ class _ScreenControllerState extends State {
});
} else {
_hmsSDKInteractor.toggleAlwaysScreenOn();
- setState(() {
- isLoading = false;
- });
+ if (mounted) {
+ setState(() {
+ isLoading = false;
+ });
+ }
Constant.debugMode = AppDebugConfig.isDebugMode;
}
}
diff --git a/packages/hms_room_kit/lib/src/service/app_debug_config.dart b/packages/hms_room_kit/lib/src/service/app_debug_config.dart
index 0c6a78d27..39573c59a 100644
--- a/packages/hms_room_kit/lib/src/service/app_debug_config.dart
+++ b/packages/hms_room_kit/lib/src/service/app_debug_config.dart
@@ -6,8 +6,6 @@ class AppDebugConfig {
Setting these values to defaults and can be toggled from the application
This will not be shipped with the ui_kit package and only used for internal testing
*/
- static bool joinWithMutedAudio = false;
- static bool joinWithMutedVideo = false;
static bool skipPreview = false;
static bool mirrorCamera = true;
static bool showStats = false;
@@ -24,8 +22,6 @@ class AppDebugConfig {
/// Resets the debug configuration to default values
static void resetToDefault() {
- joinWithMutedAudio = true;
- joinWithMutedVideo = true;
skipPreview = false;
mirrorCamera = true;
showStats = false;
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 d46fd1935..68712e88c 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
@@ -133,27 +133,31 @@ class _AppUtilitiesBottomSheetState extends State {
optionText: "Participants"),
///This renders the screen share option
- MoreOptionItem(
- onTap: () async {
- Navigator.pop(context);
- if (meetingStore.isScreenShareOn) {
- meetingStore.stopScreenShare();
- } else {
- meetingStore.startScreenShare();
- }
- },
- isActive: meetingStore.isScreenShareOn,
- optionIcon: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/screen_share.svg",
- height: 20,
- width: 20,
- colorFilter: ColorFilter.mode(
- HMSThemeColors.onSurfaceHighEmphasis, BlendMode.srcIn),
+ if (meetingStore.localPeer?.role.publishSettings?.allowed
+ .contains("screen") ??
+ false)
+ MoreOptionItem(
+ onTap: () async {
+ Navigator.pop(context);
+ if (meetingStore.isScreenShareOn) {
+ meetingStore.stopScreenShare();
+ } else {
+ meetingStore.startScreenShare();
+ }
+ },
+ isActive: meetingStore.isScreenShareOn,
+ optionIcon: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/screen_share.svg",
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn),
+ ),
+ optionText: meetingStore.isScreenShareOn
+ ? "Sharing Screen"
+ : "Share Screen",
),
- optionText: meetingStore.isScreenShareOn
- ? "Sharing Screen"
- : "Share Screen",
- ),
///This renders the brb option
if (HMSRoomLayout.isBRBEnabled)
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/chat_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/chat_bottom_sheet.dart
index e0130b270..5da03b874 100644
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/chat_bottom_sheet.dart
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/chat_bottom_sheet.dart
@@ -1,20 +1,24 @@
//Package imports
import 'package:flutter/material.dart';
-import 'package:flutter_linkify/flutter_linkify.dart';
-import 'package:flutter_svg/svg.dart';
+import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import 'package:hmssdk_flutter/hmssdk_flutter.dart';
-import 'package:url_launcher/url_launcher.dart';
//Project imports
-import 'package:hms_room_kit/hms_room_kit.dart';
-import 'package:hms_room_kit/src/enums/session_store_keys.dart';
import 'package:hms_room_kit/src/widgets/chat_widgets/hms_empty_chat_widget.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/message_container.dart';
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
+import 'package:hms_room_kit/src/widgets/chat_widgets/chat_text_field.dart';
+import 'package:hms_room_kit/src/widgets/chat_widgets/pin_chat_widget.dart';
+import 'package:hms_room_kit/hms_room_kit.dart';
+import 'package:hms_room_kit/src/widgets/chat_widgets/recipient_selector_chip.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_error_toast.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_toast_model.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_toasts_type.dart';
+///[ChatBottomSheet] is a bottom sheet that is used to render the bottom sheet for chat
class ChatBottomSheet extends StatefulWidget {
const ChatBottomSheet({super.key});
@@ -24,19 +28,20 @@ class ChatBottomSheet extends StatefulWidget {
class _ChatBottomSheetState extends State {
late double widthOfScreen;
- TextEditingController messageTextController = TextEditingController();
- String valueChoose = "Everyone";
+ String currentlySelectedValue = "Choose a Recipient";
+ String? currentlySelectedpeerId;
+
final ScrollController _scrollController = ScrollController();
final DateFormat formatter = DateFormat('hh:mm a');
+
@override
void dispose() {
- messageTextController.dispose();
_scrollController.dispose();
super.dispose();
}
void _scrollToEnd() {
- if (_scrollController.positions.isNotEmpty) {
+ if (_scrollController.hasClients) {
WidgetsBinding.instance.addPostFrameCallback((_) => _scrollController
.animateTo(_scrollController.position.maxScrollExtent,
duration: const Duration(milliseconds: 200),
@@ -44,18 +49,26 @@ class _ChatBottomSheetState extends State {
}
}
- String sender(HMSMessageRecipient hmsMessageRecipient) {
- if ((hmsMessageRecipient.recipientPeer != null) &&
- (hmsMessageRecipient.recipientRoles == null)) {
- return "PRIVATE";
- } else if ((hmsMessageRecipient.recipientPeer == null) &&
- (hmsMessageRecipient.recipientRoles != null)) {
- return hmsMessageRecipient.recipientRoles![0].name;
+ @override
+ void initState() {
+ super.initState();
+ setRecipientChipValue();
+ }
+
+ ///This function sets the value of the recipient chip
+ void setRecipientChipValue() {
+ dynamic currentValue = context.read().recipientSelectorValue;
+ if (currentValue is HMSPeer) {
+ currentlySelectedValue = currentValue.name;
+ currentlySelectedpeerId = currentValue.peerId;
+ } else if (currentValue is HMSRole) {
+ currentlySelectedValue = currentValue.name;
+ } else if (currentValue is String) {
+ currentlySelectedValue = currentValue;
}
- return "";
}
- void sendMessage() async {
+ void sendMessage(TextEditingController messageTextController) async {
MeetingStore meetingStore = context.read();
List hmsRoles = meetingStore.roles;
String message = messageTextController.text.trim();
@@ -66,18 +79,25 @@ class _ChatBottomSheetState extends State {
rolesName.add(hmsRoles[i].name);
}
- if (valueChoose == "Everyone") {
+ if (currentlySelectedValue == "Everyone") {
meetingStore.sendBroadcastMessage(message);
- } else if (rolesName.contains(valueChoose)) {
+ } else if (rolesName.contains(currentlySelectedValue)) {
List selectedRoles = [];
- selectedRoles
- .add(hmsRoles.firstWhere((role) => role.name == valueChoose));
+ selectedRoles.add(
+ hmsRoles.firstWhere((role) => role.name == currentlySelectedValue));
meetingStore.sendGroupMessage(message, selectedRoles);
- } else if (meetingStore.localPeer!.peerId != valueChoose) {
- var peer = await meetingStore.getPeer(peerId: valueChoose);
- meetingStore.sendDirectMessage(message, peer!);
+ } else if (currentlySelectedpeerId != null &&
+ meetingStore.localPeer!.peerId != currentlySelectedpeerId) {
+ var peer = await meetingStore.getPeer(peerId: currentlySelectedpeerId!);
+ if (peer != null) {
+ meetingStore.sendDirectMessage(message, peer);
+ }
}
- messageTextController.clear();
+ }
+
+ void _updateValueChoose(String newValue, String? peerId) {
+ currentlySelectedValue = newValue;
+ currentlySelectedpeerId = peerId;
}
@override
@@ -90,297 +110,106 @@ class _ChatBottomSheetState extends State {
return true;
},
child: SafeArea(
- child: Padding(
- padding: MediaQuery.of(context).viewInsets,
- child: Column(
- mainAxisSize: MainAxisSize.min,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- const SizedBox(
- height: 15,
- ),
- Selector, int, String?>>(
- selector: (_, meetingStore) => Tuple3(meetingStore.messages,
- meetingStore.messages.length, meetingStore.sessionMetadata),
- builder: (context, data, _) {
- _scrollToEnd();
- return
+ child: Stack(
+ children: [
+ Padding(
+ padding: MediaQuery.of(context).viewInsets,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ const SizedBox(
+ height: 15,
+ ),
+ Selector, int, List, int>>(
+ selector: (_, meetingStore) => Tuple4(
+ meetingStore.messages,
+ meetingStore.messages.length,
+ meetingStore.pinnedMessages,
+ meetingStore.pinnedMessages.length),
+ builder: (context, data, _) {
+ _scrollToEnd();
+ return
- ///If there are no chats and no pinned messages
- (data.item2 == 0 && data.item3 == null)
- ? const Expanded(
- child: Center(child: HMSEmptyChatWidget()))
- : Expanded(
- child: Column(children: [
- ///If there is a pinned chat
- if (data.item3 != null && data.item3 != "")
- Padding(
- padding: const EdgeInsets.only(bottom: 8.0),
- child: Container(
- constraints:
- const BoxConstraints(maxHeight: 150),
- decoration: BoxDecoration(
- borderRadius:
- BorderRadius.circular(8),
- color: HMSThemeColors.surfaceDefault),
- child: SingleChildScrollView(
- child: Padding(
- padding: const EdgeInsets.all(8.0),
- child: Row(
- mainAxisAlignment:
- MainAxisAlignment.spaceBetween,
- children: [
- Row(
- children: [
- SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/pin.svg",
- height: 20,
- width: 20,
- colorFilter: ColorFilter.mode(
- HMSThemeColors
- .onSurfaceMediumEmphasis,
- BlendMode.srcIn),
- ),
- const SizedBox(width: 8),
- SizedBox(
- width:
- MediaQuery.of(context)
- .size
- .width *
- 0.75,
- child: SelectableLinkify(
- text: data.item3!,
- onOpen: (link) async {
- Uri url =
- Uri.parse(link.url);
- if (await canLaunchUrl(
- url)) {
- await launchUrl(url,
- mode: LaunchMode
- .externalApplication);
- }
- },
- options:
- const LinkifyOptions(
- humanize: false),
- style: HMSTextStyle
- .setTextStyle(
- fontSize: 14.0,
- color: HMSThemeColors
- .onSurfaceHighEmphasis,
- letterSpacing: 0.25,
- height: 20 / 14,
- fontWeight:
- FontWeight.w400,
- ),
- linkStyle: HMSTextStyle
- .setTextStyle(
- fontSize: 14.0,
- color: HMSThemeColors
- .primaryDefault,
- letterSpacing:
- 0.25,
- height: 20 / 14,
- fontWeight:
- FontWeight
- .w400),
- ),
- ),
- ],
- ),
- Row(
- children: [
- GestureDetector(
- onTap: () {
- context
- .read<
- MeetingStore>()
- .setSessionMetadataForKey(
- key: SessionStoreKeyValues
- .getNameFromMethod(
- SessionStoreKey
- .pinnedMessageSessionKey),
- metadata: null);
- },
- child: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/close.svg",
- height: 20,
- width: 20,
- colorFilter:
- ColorFilter.mode(
- HMSThemeColors
- .onSurfaceMediumEmphasis,
- BlendMode
- .srcIn),
- )),
- ],
- )
- ],
+ ///If there are no chats and no pinned messages
+ (data.item2 == 0 && data.item3.isEmpty)
+ ? Expanded(
+ child: SingleChildScrollView(
+ physics:
+ const NeverScrollableScrollPhysics(),
+ child: ConstrainedBox(
+ constraints: BoxConstraints(
+ minHeight: MediaQuery.of(context)
+ .size
+ .height *
+ 0.6,
),
+ child: const HMSEmptyChatWidget())))
+ : Expanded(
+ child: Column(children: [
+ const PinChatWidget(),
+
+ /// List containing chats
+ Expanded(
+ child: SingleChildScrollView(
+ reverse: true,
+ child: Column(
+ mainAxisAlignment:
+ MainAxisAlignment.end,
+ children: [
+ ListView.builder(
+ controller: _scrollController,
+ shrinkWrap: true,
+ itemCount: data.item1.length,
+ itemBuilder: (_, index) {
+ return MessageContainer(
+ message: data.item1[index],
+ );
+ }),
+ ],
),
),
- ),
- ),
+ )
+ ]),
+ );
+ },
+ ),
- /// List containing chats
- Expanded(
- child: SingleChildScrollView(
- reverse: true,
- child: Column(
- mainAxisAlignment: MainAxisAlignment.end,
- children: [
- ListView.builder(
- controller: _scrollController,
- shrinkWrap: true,
- itemCount: data.item1.length,
- itemBuilder: (_, index) {
- return MessageContainer(
- message: data
- .item1[index].message
- .trim()
- .toString(),
- senderName: data.item1[index]
- .sender?.name ??
- "Anonymous",
- date: formatter.format(
- data.item1[index].time),
- role: data.item1[index]
- .hmsMessageRecipient ==
- null
- ? ""
- : sender(data.item1[index]
- .hmsMessageRecipient!),
- );
- }),
- ],
- ),
- ),
- )
- ]),
- );
- },
- ),
+ /// This draws the chip to select the roles or peers to send message to
+ if ((HMSRoomLayout.chatData?.isPrivateChatEnabled ?? false) ||
+ (HMSRoomLayout.chatData?.isPublicChatEnabled ?? false) ||
+ (HMSRoomLayout.chatData?.rolesWhitelist.isNotEmpty ??
+ false))
+ ReceipientSelectorChip(
+ currentlySelectedValue: currentlySelectedValue,
+ updateSelectedValue: _updateValueChoose),
- ///Will be added later
- ///
- // Padding(
- // padding: const EdgeInsets.only(bottom: 8.0, left: 16,top: 16),
- // child: Row(
- // children: [
- // HMSTitleText(
- // text: "SEND TO ",
- // textColor: HMSThemeColors.onSurfaceMediumEmphasis,
- // fontSize: 10,
- // lineHeight: 16,
- // letterSpacing: 1.5,
- // ),
- // Container(
- // width: 96,
- // height: 24,
- // decoration: BoxDecoration(
- // border: Border.all(
- // color: HMSThemeColors.borderBright, width: 1),
- // borderRadius:
- // const BorderRadius.all(Radius.circular(4)),
- // color:
- // HMSThemeColors.surfaceDim),
- // child: Row(
- // mainAxisAlignment: MainAxisAlignment.center,
- // children: [
- // HMSTitleText(
- // text: "EVERYONE",
- // fontSize: 10,
- // lineHeight: 16,
- // letterSpacing: 1.5,
- // textColor:
- // HMSThemeColors.onSurfaceHighEmphasis),
- // Icon(Icons.keyboard_arrow_down,color: HMSThemeColors.onSurfaceMediumEmphasis,size: 16,),
- // ],
- // ))
- // ],
- // ),
- // ),
- ///Text Field
- Padding(
- padding: const EdgeInsets.only(top: 8.0),
- child: Container(
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(8),
- color: HMSThemeColors.surfaceDefault),
- child: Row(
- children: [
- Expanded(
- child: TextField(
- textCapitalization: TextCapitalization.sentences,
- textInputAction: TextInputAction.send,
- onTapOutside: (event) =>
- FocusManager.instance.primaryFocus?.unfocus(),
- onSubmitted: (value) {
- sendMessage();
- },
- onChanged: (value) {
- setState(() {});
- },
- style: HMSTextStyle.setTextStyle(
- color: HMSThemeColors.onSurfaceHighEmphasis,
- fontWeight: FontWeight.w400,
- height: 20 / 14,
- fontSize: 14,
- letterSpacing: 0.25),
- controller: messageTextController,
- decoration: InputDecoration(
- suffixIcon: IconButton(
- onPressed: () {
- if (messageTextController.text
- .trim()
- .isEmpty) {
- Utilities.showToast(
- "Message can't be empty");
- }
- sendMessage();
- },
- icon: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/send_message.svg",
- height: 24,
- width: 24,
- colorFilter: ColorFilter.mode(
- messageTextController
- .text
- .trim()
- .isEmpty
- ? HMSThemeColors
- .onSurfaceLowEmphasis
- : HMSThemeColors
- .onSurfaceHighEmphasis,
- BlendMode.srcIn),
- )),
- border: InputBorder.none,
- focusedBorder: OutlineInputBorder(
- borderSide: BorderSide(
- width: 2,
- color: HMSThemeColors.primaryDefault),
- borderRadius: const BorderRadius.all(
- Radius.circular(8))),
- enabledBorder: InputBorder.none,
- errorBorder: InputBorder.none,
- disabledBorder: InputBorder.none,
- hintStyle: HMSTextStyle.setTextStyle(
- color: HMSThemeColors.onSurfaceLowEmphasis,
- fontSize: 14,
- height: 20 / 14,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w400),
- contentPadding: const EdgeInsets.only(
- left: 16, bottom: 8, top: 12, right: 8),
- hintText: "Send a message..."),
- ),
- )
- ],
- ),
- ),
+ ///Text Field
+ if ((HMSRoomLayout.chatData?.isPrivateChatEnabled ?? false) ||
+ (HMSRoomLayout.chatData?.isPublicChatEnabled ?? false) ||
+ (HMSRoomLayout.chatData?.rolesWhitelist.isNotEmpty ??
+ false))
+ ChatTextField(sendMessage: sendMessage)
+ ],
),
- ],
- ),
+ ),
+ Selector, int>>(
+ selector: (_, meetingStore) =>
+ Tuple2(meetingStore.toasts, meetingStore.toasts.length),
+ builder: (_, data, __) {
+ int errorToastIndex = data.item1.indexWhere((element) =>
+ element.hmsToastType == HMSToastsType.errorToast);
+
+ return (errorToastIndex != -1)
+ ? HMSErrorToast(
+ error: data.item1[errorToastIndex].toastData,
+ meetingStore: context.read(),
+ toastColor: HMSThemeColors.surfaceDefault,
+ )
+ : const SizedBox();
+ })
+ ],
),
),
);
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/chat_only_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/chat_only_bottom_sheet.dart
index 4551cce16..3406c8789 100644
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/chat_only_bottom_sheet.dart
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/chat_only_bottom_sheet.dart
@@ -1,11 +1,16 @@
///Package imports
import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
///Project imports
import 'package:hms_room_kit/hms_room_kit.dart';
+import 'package:hms_room_kit/src/enums/session_store_keys.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/widgets/bottom_sheets/chat_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:provider/provider.dart';
///[ChatOnlyBottomSheet] is a bottom sheet that is used to render the bottom sheet to show chat only when participants
///list is disabled from dashboard
@@ -25,10 +30,86 @@ class ChatOnlyBottomSheet extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
HMSSubheadingText(
- text: "Chat",
+ text: HMSRoomLayout.chatData?.chatTitle ?? "Chat",
textColor: HMSThemeColors.onSurfaceHighEmphasis,
fontWeight: FontWeight.w600,
),
+ if (HMSRoomLayout.chatData?.realTimeControls?.canDisableChat ??
+ false)
+ PopupMenuButton(
+ padding: EdgeInsets.zero,
+ position: PopupMenuPosition.under,
+ color: HMSThemeColors.surfaceDefault,
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/settings.svg",
+ width: 24,
+ height: 24,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceLowEmphasis,
+ BlendMode.srcIn)),
+ itemBuilder: (context) => [
+ PopupMenuItem(
+ value: 1,
+ child: Row(children: [
+ SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/${context.read().chatControls["enabled"] ? "recording_paused" : "resume"}.svg",
+ width: 20,
+ height: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn)),
+ const SizedBox(
+ width: 8,
+ ),
+ HMSTitleText(
+ text: context
+ .read()
+ .chatControls["enabled"]
+ ? "Pause Chat"
+ : "Resume Chat",
+ textColor:
+ HMSThemeColors.onSurfaceHighEmphasis,
+ fontSize: 14,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ ),
+ ]))
+ ],
+ onSelected: (value) {
+ switch (value) {
+ case 1:
+ context
+ .read()
+ .setSessionMetadataForKey(
+ key:
+ SessionStoreKeyValues.getNameFromMethod(
+ SessionStoreKey.chatState),
+ metadata: {
+ "enabled": context
+ .read()
+ .chatControls["enabled"]
+ ? false
+ : true,
+ "updatedBy": {
+ "peerID": context
+ .read()
+ .localPeer
+ ?.peerId,
+ "userID": context
+ .read()
+ .localPeer
+ ?.customerUserId,
+ "userName": context
+ .read()
+ .localPeer
+ ?.name
+ },
+ "updatedAt": DateTime.now()
+ .millisecondsSinceEpoch //unix timestamp in miliseconds
+ });
+ break;
+ }
+ }),
const HMSCrossButton(),
],
),
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/chat_utilities_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/chat_utilities_bottom_sheet.dart
new file mode 100644
index 000000000..3cf62ec6a
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/chat_utilities_bottom_sheet.dart
@@ -0,0 +1,213 @@
+///Package imports
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:hmssdk_flutter/hmssdk_flutter.dart';
+import 'package:provider/provider.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/widgets/common_widgets/hms_cross_button.dart';
+import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart';
+
+///[ChatUtilitiesBottomSheet] is a bottom sheet that is used to render the bottom sheet to show the options for a message
+///like pin message, block user etc
+class ChatUtilitiesBottomSheet extends StatefulWidget {
+ final HMSMessage message;
+
+ const ChatUtilitiesBottomSheet({Key? key, required this.message})
+ : super(key: key);
+
+ @override
+ State createState() =>
+ _ChatUtilitiesBottomSheetState();
+}
+
+class _ChatUtilitiesBottomSheetState extends State {
+ bool isPinned = false;
+ bool isBlocked = false;
+
+ @override
+ initState() {
+ super.initState();
+ isPinned = context.read().pinnedMessages.indexWhere(
+ (element) => element["id"] == widget.message.messageId) !=
+ -1;
+
+ isBlocked = context.read().blackListedUserIds.indexWhere(
+ (userId) => userId == widget.message.sender?.customerUserId) !=
+ -1;
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return FractionallySizedBox(
+ heightFactor: 0.5,
+ child: Padding(
+ padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 24),
+ child: SingleChildScrollView(
+ child:
+ Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ HMSTitleText(
+ text: "Message Options",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis),
+ const HMSCrossButton()
+ ],
+ ),
+
+ Padding(
+ padding: const EdgeInsets.only(top: 8, bottom: 8),
+ child: Divider(
+ color: HMSThemeColors.borderDefault,
+ height: 5,
+ ),
+ ),
+
+ ///This renders the option to pin the message
+ ///This is only rendered if the user has the permission to pin messages
+ ///If the message is already pinned it renders the option to unpin the message
+ ///If the message is not pinned it renders the option to pin the message
+ if (HMSRoomLayout.chatData?.allowPinningMessages ?? true)
+ ListTile(
+ horizontalTitleGap: 2,
+ onTap: () async {
+ Navigator.pop(context);
+ if (isPinned) {
+ context
+ .read()
+ .unpinMessage(widget.message.messageId);
+ } else {
+ context.read().pinMessage(widget.message);
+ }
+ },
+ contentPadding: EdgeInsets.zero,
+ leading: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/pin.svg",
+ semanticsLabel: "fl_pin_message_icon",
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis, BlendMode.srcIn),
+ ),
+ title: HMSSubheadingText(
+ text: isPinned ? "Unpin" : "Pin",
+ letterSpacing: 0.1,
+ fontWeight: FontWeight.w600,
+ textColor: HMSThemeColors.onSurfaceHighEmphasis)),
+
+ ListTile(
+ horizontalTitleGap: 2,
+ onTap: () async {
+ Navigator.pop(context);
+ await Clipboard.setData(
+ ClipboardData(text: widget.message.message));
+ },
+ contentPadding: EdgeInsets.zero,
+ leading: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/copy.svg",
+ semanticsLabel: "fl_copy_message_icon",
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis, BlendMode.srcIn),
+ ),
+ title: HMSSubheadingText(
+ text: "Copy Text",
+ letterSpacing: 0.1,
+ fontWeight: FontWeight.w600,
+ textColor: HMSThemeColors.onSurfaceHighEmphasis)),
+
+ if ((HMSRoomLayout.chatData?.realTimeControls?.canHideMessage ??
+ false))
+ ListTile(
+ horizontalTitleGap: 2,
+ onTap: () async {
+ Navigator.pop(context);
+ context.read().hideMessage(widget.message);
+ },
+ contentPadding: EdgeInsets.zero,
+ leading: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/hide.svg",
+ semanticsLabel: "fl_copy_message_icon",
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis, BlendMode.srcIn),
+ ),
+ title: HMSSubheadingText(
+ text: "Hide for Everyone",
+ letterSpacing: 0.1,
+ fontWeight: FontWeight.w600,
+ textColor: HMSThemeColors.onSurfaceHighEmphasis)),
+
+ if ((HMSRoomLayout.chatData?.realTimeControls?.canBlockUser ??
+ false) &&
+ !(widget.message.sender?.isLocal ?? true))
+ ListTile(
+ horizontalTitleGap: 2,
+ onTap: () async {
+ Navigator.pop(context);
+ if (widget.message.sender?.customerUserId != null) {
+ context.read().togglePeerBlock(
+ userId: widget.message.sender!.customerUserId!,
+ isBlocked: isBlocked);
+ }
+ },
+ contentPadding: EdgeInsets.zero,
+ leading: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/block.svg",
+ semanticsLabel: "fl_block_peer_icon",
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.alertErrorDefault, BlendMode.srcIn),
+ ),
+ title: HMSSubheadingText(
+ text: isBlocked ? "Unblock from Chat" : "Block from Chat",
+ letterSpacing: 0.1,
+ fontWeight: FontWeight.w600,
+ textColor: HMSThemeColors.alertErrorDefault)),
+
+ if ((context
+ .read()
+ .localPeer
+ ?.role
+ .permissions
+ .removeOthers ??
+ false) &&
+ !(widget.message.sender?.isLocal ?? true))
+ ListTile(
+ horizontalTitleGap: 2,
+ onTap: () async {
+ Navigator.pop(context);
+ if (widget.message.sender != null) {
+ context
+ .read()
+ .removePeerFromRoom(widget.message.sender!);
+ }
+ },
+ 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",
+ letterSpacing: 0.1,
+ fontWeight: FontWeight.w600,
+ textColor: HMSThemeColors.alertErrorDefault)),
+ ]),
+ ),
+ ),
+ );
+ }
+}
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 858278a11..21a089bd4 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
@@ -33,12 +33,17 @@ class ParticipantsBottomSheet extends StatefulWidget {
class _ParticipantsBottomSheetState extends State {
Timer? timer;
+ bool isLargeRoom = false;
@override
void initState() {
super.initState();
- timer = Timer.periodic(const Duration(seconds: 5),
- (Timer t) => context.read().refreshPeerList());
+
+ isLargeRoom = context.read().hmsRoom?.isLarge ?? false;
+ if (isLargeRoom) {
+ timer = Timer.periodic(const Duration(seconds: 5),
+ (Timer t) => context.read().refreshPeerList());
+ }
}
@override
@@ -138,7 +143,9 @@ class _ParticipantsBottomSheetState extends State {
HMSRole? onStageRole = meetingStore.getOnStageRole();
if (onStageRole != null) {
meetingStore.changeRoleOfPeer(
- peer: peer, roleName: onStageRole, forceChange: false);
+ peer: peer,
+ roleName: onStageRole,
+ forceChange: HMSRoomLayout.skipPreviewForRole);
meetingStore.removeToast(HMSToastsType.roleChangeToast,
data: peer);
}
@@ -335,19 +342,30 @@ class _ParticipantsBottomSheetState extends State {
// child: TextField(),
// ),
// ),
- Selector>, int>>(
- selector: (_, meetingStore) => Tuple2(
- meetingStore.participantsInMeetingMap,
- meetingStore.participantsInMeeting),
- builder: (_, data, __) {
- return ListView.builder(
- physics: const NeverScrollableScrollPhysics(),
- shrinkWrap: true,
- itemCount: data.item1.keys.length,
- itemBuilder: (context, index) {
- String role = data.item1.keys.elementAt(index);
- return (data.item1[role]?.isNotEmpty ?? false)
+ ListView.builder(
+ physics: const NeverScrollableScrollPhysics(),
+ shrinkWrap: true,
+ itemCount: context
+ .read()
+ .participantsInMeetingMap
+ .keys
+ .length,
+ itemBuilder: (context, index) {
+ String role = context
+ .read()
+ .participantsInMeetingMap
+ .keys
+ .elementAt(index);
+ return Selector?>>(
+ selector: (_, meetingStore) => Tuple2(
+ meetingStore
+ .participantsInMeetingMap[role]?.length ??
+ 0,
+ meetingStore.participantsInMeetingMap[role]),
+ builder: (_, participantsPerRole, __) {
+ return (participantsPerRole.item2?.isNotEmpty ??
+ false)
? Column(
children: [
ClipRRect(
@@ -376,30 +394,30 @@ class _ParticipantsBottomSheetState extends State {
.onSurfaceHighEmphasis,
title: HMSSubheadingText(
text:
- "${data.item1.keys.elementAt(index)} (${(HMSRoomLayout.offStageRoles?.contains(role) ?? false) ? context.read().peerListIterators[role]?.totalCount ?? 0 : data.item1[role]?.length}) ",
+ "${context.read().participantsInMeetingMap.keys.elementAt(index)} (${((HMSRoomLayout.offStageRoles?.contains(role) ?? false) && isLargeRoom) ? context.read().peerListIterators[role]?.totalCount ?? 0 : participantsPerRole.item1}) ",
textColor: HMSThemeColors
.onSurfaceMediumEmphasis,
letterSpacing: 0.1,
),
children: [
SizedBox(
- height: data.item1[role] == null
+ height: participantsPerRole.item2 ==
+ null
? 0
- : (data.item1[role]!.length) *
+ : (participantsPerRole.item1) *
54,
child: Center(
child: ListView.builder(
physics:
const NeverScrollableScrollPhysics(),
- itemCount: data.item1[role]
- ?.length ??
- 0,
+ itemCount:
+ participantsPerRole.item1,
itemBuilder:
(context, peerIndex) {
ParticipantsStore
currentPeer =
- data.item1[role]![
- peerIndex];
+ participantsPerRole
+ .item2![peerIndex];
return Padding(
padding:
const EdgeInsets.only(
@@ -445,13 +463,16 @@ class _ParticipantsBottomSheetState extends State {
builder: (_,
peerName,
__) {
- return HMSTitleText(
- text:
- peerName + ((data.item1[role]![peerIndex].peer.isLocal) ? " (You)" : ""),
- fontSize: 14,
- lineHeight: 20,
- letterSpacing: 0.1,
- textColor: HMSThemeColors.onSurfaceHighEmphasis);
+ return Container(
+ constraints:
+ BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.6),
+ child: HMSTitleText(
+ text: peerName + ((participantsPerRole.item2![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
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
index 2a0ecb79e..6a6844f16 100644
--- 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
@@ -131,7 +131,9 @@ class _ParticipantsViewAllBottomSheetState
HMSRole? onStageRole = meetingStore.getOnStageRole();
if (onStageRole != null) {
meetingStore.changeRoleOfPeer(
- peer: peer, roleName: onStageRole, forceChange: false);
+ peer: peer,
+ roleName: onStageRole,
+ forceChange: HMSRoomLayout.skipPreviewForRole);
meetingStore.removeToast(HMSToastsType.roleChangeToast,
data: peer);
}
diff --git a/packages/hms_room_kit/lib/src/widgets/chat_widgets/chat_text_field.dart b/packages/hms_room_kit/lib/src/widgets/chat_widgets/chat_text_field.dart
new file mode 100644
index 000000000..133b4d363
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/widgets/chat_widgets/chat_text_field.dart
@@ -0,0 +1,256 @@
+///Dart imports
+import 'dart:math' as math;
+
+///Package imports
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.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/enums/session_store_keys.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/widgets/common_widgets/hms_subheading_text.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_toast.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_toast_button.dart';
+
+///[ChatTextField] is a component that is used to render the chat text field
+///It renders the text field or relevant UI based on chat State
+class ChatTextField extends StatefulWidget {
+ final Function sendMessage;
+ final Color? toastBackgroundColor;
+ const ChatTextField(
+ {Key? key, required this.sendMessage, this.toastBackgroundColor})
+ : super(key: key);
+
+ @override
+ State createState() => _ChatTextFieldState();
+}
+
+class _ChatTextFieldState extends State {
+ TextEditingController messageTextController = TextEditingController();
+
+ @override
+ void initState() {
+ super.initState();
+ messageTextController = TextEditingController();
+ }
+
+ @override
+ void dispose() {
+ messageTextController.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Selector>>(
+
+ ///item1: whether chat is resumed or not
+ ///item2: number of blacklisted users
+ ///item3: list of blacklisted user ids
+ selector: (_, meetingStore) => Tuple3(
+ meetingStore.chatControls["enabled"],
+ meetingStore.blackListedUserIds.length,
+ meetingStore.blackListedUserIds),
+ builder: (_, chatControls, __) {
+ return chatControls.item1
+ ? Padding(
+ padding: const EdgeInsets.only(top: 8.0),
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: chatControls.item3.contains(context
+ .read()
+ .localPeer
+ ?.customerUserId)
+ ? Row(
+ children: [
+ Expanded(
+ child: Container(
+ color: widget.toastBackgroundColor ??
+ HMSThemeColors.surfaceDefault,
+ height: 36,
+ child: Center(
+ child: HMSSubheadingText(
+ text:
+ "You’ve been blocked from sending messages",
+ textColor: HMSThemeColors
+ .onSurfaceMediumEmphasis),
+ ),
+ ),
+ ),
+ ],
+ )
+ : Row(
+ children: [
+ Expanded(
+ child: Container(
+ color: HMSThemeColors.surfaceDefault,
+ child: Selector(
+ selector: (_, meetingStore) =>
+ meetingStore.recipientSelectorValue,
+ builder: (_, selectedValue, __) {
+ return TextField(
+ enabled: selectedValue !=
+ "Choose a Recipient",
+ textCapitalization:
+ TextCapitalization.sentences,
+ textInputAction:
+ TextInputAction.send,
+ onTapOutside: (event) =>
+ FocusManager
+ .instance.primaryFocus
+ ?.unfocus(),
+ onSubmitted: (value) {
+ widget.sendMessage(
+ messageTextController);
+ messageTextController.clear();
+ },
+ onChanged: (value) {
+ setState(() {});
+ },
+ style: HMSTextStyle.setTextStyle(
+ color: HMSThemeColors
+ .onSurfaceHighEmphasis,
+ fontWeight: FontWeight.w400,
+ height: 20 / 14,
+ fontSize: 14,
+ letterSpacing: 0.25),
+ controller: messageTextController,
+ decoration: InputDecoration(
+ suffixIcon: IconButton(
+ splashRadius: 1,
+ onPressed: () {
+ if (messageTextController
+ .text
+ .trim()
+ .isEmpty) {
+ Utilities.showToast(
+ "Message can't be empty");
+ }
+ widget.sendMessage(
+ messageTextController);
+ messageTextController
+ .clear();
+ },
+ icon: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/send_message.svg",
+ height: 24,
+ width: 24,
+ colorFilter: ColorFilter.mode(
+ messageTextController
+ .text
+ .trim()
+ .isEmpty
+ ? HMSThemeColors
+ .onSurfaceLowEmphasis
+ : HMSThemeColors
+ .onSurfaceHighEmphasis,
+ BlendMode.srcIn),
+ )),
+ border: InputBorder.none,
+ focusedBorder: OutlineInputBorder(
+ borderSide: BorderSide(
+ width: 2,
+ color: HMSThemeColors
+ .primaryDefault),
+ borderRadius:
+ const BorderRadius.all(
+ Radius.circular(
+ 8))),
+ enabledBorder: InputBorder.none,
+ errorBorder: InputBorder.none,
+ disabledBorder:
+ InputBorder.none,
+ hintStyle:
+ HMSTextStyle.setTextStyle(
+ color: HMSThemeColors
+ .onSurfaceLowEmphasis,
+ fontSize: 14,
+ height: 20 / 14,
+ letterSpacing: 0.25,
+ fontWeight:
+ FontWeight.w400),
+ contentPadding:
+ const EdgeInsets.only(
+ left: 16,
+ bottom: 8,
+ top: 12,
+ right: 8),
+ hintText: HMSRoomLayout.chatData
+ ?.messagePlaceholder ??
+ "Send a message..."),
+ );
+ }),
+ ),
+ )
+ ],
+ )))
+ : HMSToast(
+ toastColor: widget.toastBackgroundColor ??
+ HMSThemeColors.surfaceDefault,
+ toastPosition: 0,
+ subtitle: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ HMSSubheadingText(
+ text: "Chat paused",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ fontWeight: FontWeight.w400,
+ ),
+ HMSSubtitleText(
+ text:
+ "Chat has been paused by ${context.read().chatControls["updatedBy"].toString().substring(0, math.min(10, context.read().chatControls["updatedBy"].toString().length))}",
+ textColor: HMSThemeColors.onSurfaceMediumEmphasis,
+ )
+ ],
+ ),
+ action: (HMSRoomLayout
+ .chatData?.realTimeControls?.canDisableChat ??
+ false)
+ ? HMSToastButton(
+ buttonTitle: "Resume",
+ action: () {
+ context
+ .read()
+ .setSessionMetadataForKey(
+ key:
+ SessionStoreKeyValues.getNameFromMethod(
+ SessionStoreKey.chatState),
+ metadata: {
+ "enabled": true,
+ "updatedBy": {
+ "peerID": context
+ .read()
+ .localPeer
+ ?.peerId,
+ "userID": context
+ .read()
+ .localPeer
+ ?.customerUserId,
+ "userName": context
+ .read()
+ .localPeer
+ ?.name
+ },
+ "updatedAt": DateTime.now()
+ .millisecondsSinceEpoch //unix timestamp in miliseconds
+ });
+ },
+ height: 36,
+ width: 88,
+ buttonColor: HMSThemeColors.primaryDefault,
+ textColor: HMSThemeColors.onPrimaryHighEmphasis,
+ )
+ : null,
+ );
+ });
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/widgets/chat_widgets/pin_chat_widget.dart b/packages/hms_room_kit/lib/src/widgets/chat_widgets/pin_chat_widget.dart
new file mode 100644
index 000000000..d51ff8f25
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/widgets/chat_widgets/pin_chat_widget.dart
@@ -0,0 +1,191 @@
+///Package imports
+import 'package:dots_indicator/dots_indicator.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_linkify/flutter_linkify.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:provider/provider.dart';
+import 'package:tuple/tuple.dart';
+import 'package:url_launcher/url_launcher.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';
+
+///[PinChatWidget] renders the pinned message widget
+class PinChatWidget extends StatefulWidget {
+ final Color? backgroundColor;
+
+ const PinChatWidget({Key? key, this.backgroundColor}) : super(key: key);
+
+ @override
+ State createState() => _PinChatWidgetState();
+}
+
+class _PinChatWidgetState extends State {
+ int currentPage = 0;
+ PageController? _pageController;
+ bool isExpanded = false;
+
+ @override
+ void initState() {
+ super.initState();
+ _pageController = PageController();
+ }
+
+ @override
+ void dispose() {
+ _pageController?.dispose();
+ super.dispose();
+ }
+
+ void setCurrentPage(int page) {
+ if (page >= 3) {
+ page = 0;
+ }
+ setState(() {
+ currentPage = page;
+ _pageController?.jumpToPage(currentPage);
+ });
+ }
+
+ void toggleExpand() {
+ setState(() {
+ isExpanded = !isExpanded;
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ ///If there are no pinnedMessage we render an empty SizedBox
+ ///else we render the pinned message widget
+ return Selector, int>>(
+ selector: (_, meetingStore) => Tuple2(
+ meetingStore.pinnedMessages.reversed.toList(),
+ meetingStore.pinnedMessages.length),
+ builder: (_, data, __) {
+ return data.item2 == 0
+ ? const SizedBox()
+ : GestureDetector(
+ onTap: () => toggleExpand(),
+ child: Padding(
+ padding: const EdgeInsets.only(bottom: 8.0),
+ child: Row(
+ children: [
+ AnimatedContainer(
+ height: MediaQuery.of(context).size.height *
+ (isExpanded ? 0.13 : 0.09),
+ width:
+ (HMSRoomLayout.chatData?.allowPinningMessages ??
+ false)
+ ? MediaQuery.of(context).size.width * 0.83
+ : MediaQuery.of(context).size.width * 0.9,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8),
+ color: widget.backgroundColor ??
+ HMSThemeColors.surfaceDefault),
+ duration: const Duration(milliseconds: 0),
+ child: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ if (data.item2 > 1)
+ DotsIndicator(
+ axis: Axis.vertical,
+ mainAxisSize: MainAxisSize.min,
+ dotsCount: data.item2,
+ position: currentPage >= data.item2
+ ? 0
+ : currentPage,
+ decorator: DotsDecorator(
+ spacing: const EdgeInsets.only(
+ bottom: 3.0, right: 8),
+ size: Size(2.0, isExpanded ? 24 : 9.0),
+ activeSize:
+ Size(2.0, isExpanded ? 24 : 9.0),
+ color:
+ HMSThemeColors.onSurfaceLowEmphasis,
+ activeColor:
+ HMSThemeColors.onSurfaceHighEmphasis,
+ activeShape: RoundedRectangleBorder(
+ borderRadius:
+ BorderRadius.circular(16.0)),
+ shape: RoundedRectangleBorder(
+ borderRadius:
+ BorderRadius.circular(16.0)),
+ ),
+ onTap: (position) =>
+ setCurrentPage(position),
+ ),
+ Expanded(
+ child: PageView.builder(
+ scrollDirection: Axis.vertical,
+ controller: _pageController,
+ itemCount: data.item2,
+ physics: const PageScrollPhysics(),
+ onPageChanged: (value) =>
+ setCurrentPage(value),
+ itemBuilder: (context, index) =>
+ SelectableLinkify(
+ maxLines: 3,
+ scrollPhysics: isExpanded
+ ? const BouncingScrollPhysics()
+ : const NeverScrollableScrollPhysics(),
+ text: data.item1[index]["text"],
+ onOpen: (link) async {
+ Uri url = Uri.parse(link.url);
+ if (await canLaunchUrl(url)) {
+ await launchUrl(url,
+ mode: LaunchMode
+ .externalApplication);
+ }
+ },
+ onTap: () => toggleExpand(),
+ options:
+ const LinkifyOptions(humanize: false),
+ style: HMSTextStyle.setTextStyle(
+ fontSize: 14.0,
+ color: HMSThemeColors
+ .onSurfaceHighEmphasis,
+ letterSpacing: 0.25,
+ height: 20 / 14,
+ fontWeight: FontWeight.w400,
+ ),
+ linkStyle: HMSTextStyle.setTextStyle(
+ fontSize: 14.0,
+ color: HMSThemeColors.primaryDefault,
+ letterSpacing: 0.25,
+ height: 20 / 14,
+ fontWeight: FontWeight.w400),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ const SizedBox(width: 8),
+ if (HMSRoomLayout.chatData?.allowPinningMessages ??
+ false)
+ GestureDetector(
+ onTap: () => context
+ .read()
+ .unpinMessage(data.item1[currentPage]["id"]),
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/unpin.svg",
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceMediumEmphasis,
+ BlendMode.srcIn),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ });
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/widgets/chat_widgets/recipient_selector_chip.dart b/packages/hms_room_kit/lib/src/widgets/chat_widgets/recipient_selector_chip.dart
new file mode 100644
index 000000000..c39a78cb1
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/widgets/chat_widgets/recipient_selector_chip.dart
@@ -0,0 +1,153 @@
+///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';
+
+///Project imports
+import 'package:hms_room_kit/hms_room_kit.dart';
+import 'package:hms_room_kit/src/meeting/meeting_store.dart';
+import 'package:hms_room_kit/src/widgets/chat_widgets/recipient_selector_widget.dart';
+import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
+
+///[ReceipientSelectorChip] is a widget that is used to render the receipient selector chip
+class ReceipientSelectorChip extends StatefulWidget {
+ final String currentlySelectedValue;
+ final Function updateSelectedValue;
+ final Color? chipColor;
+
+ const ReceipientSelectorChip(
+ {Key? key,
+ required this.currentlySelectedValue,
+ required this.updateSelectedValue,
+ this.chipColor})
+ : super(key: key);
+ @override
+ State createState() => _ReceipientSelectorChipState();
+}
+
+class _ReceipientSelectorChipState extends State {
+ String currentlySelectedValue = "";
+
+ @override
+ void initState() {
+ super.initState();
+ currentlySelectedValue = widget.currentlySelectedValue;
+ }
+
+ void setSelectedValue() {
+ currentlySelectedValue = "Choose a Recipient";
+ }
+
+ void _updateValueChoose(String newValue, String? peerId) {
+ setState(() {
+ currentlySelectedValue = newValue;
+ });
+ widget.updateSelectedValue(newValue, peerId);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onTap: () => {
+ if (!(HMSRoomLayout.chatData?.isPrivateChatEnabled ?? true) &&
+ (HMSRoomLayout.chatData?.isPublicChatEnabled ?? false) &&
+ (HMSRoomLayout.chatData?.rolesWhitelist.isEmpty ?? false))
+ {() {}}
+ else
+ {
+ showModalBottomSheet(
+ isScrollControlled: true,
+ backgroundColor: Colors.transparent,
+ context: context,
+ builder: (ctx) => ChangeNotifierProvider.value(
+ value: context.read(),
+ child: RecipientSelectorWidget(
+ updateUI: _updateValueChoose,
+ selectedValue: currentlySelectedValue,
+ )))
+ }
+ },
+ child: Padding(
+ padding: const EdgeInsets.only(bottom: 8.0, top: 16),
+ child: Row(
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(right: 8.0),
+ child: HMSTitleText(
+ text: "TO",
+ textColor: HMSThemeColors.onSurfaceMediumEmphasis,
+ fontSize: 12,
+ fontWeight: FontWeight.w400,
+ lineHeight: 16,
+ letterSpacing: 0.4,
+ ),
+ ),
+ Container(
+ height: 24,
+ decoration: BoxDecoration(
+ borderRadius: const BorderRadius.all(Radius.circular(4)),
+ color: widget.chipColor ?? HMSThemeColors.primaryDefault),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 4.0),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Padding(
+ padding: const EdgeInsets.only(right: 4.0),
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/participants.svg",
+ height: 16,
+ width: 16,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceMediumEmphasis,
+ BlendMode.srcIn),
+ ),
+ ),
+ Container(
+ constraints: BoxConstraints(
+ maxWidth: MediaQuery.of(context).size.width * 0.5,
+ ),
+ child: Selector(
+ selector: (_, meetingStore) =>
+ meetingStore.recipientSelectorValue,
+ builder: (_, currentValue, __) {
+ ///Here we set the currentValue based on meetingStore.recipientSelectorValue
+ ///This is to handle a case where a peer is selected but the peer leaves
+ ///So we set the chip selection again to "Choose a Recipient"
+ if (currentValue is HMSPeer) {
+ currentlySelectedValue = currentValue.name;
+ } else if (currentValue is HMSRole) {
+ currentlySelectedValue = currentValue.name;
+ } else if (currentValue is String) {
+ currentlySelectedValue = currentValue;
+ }
+
+ return HMSTitleText(
+ text: currentlySelectedValue,
+ textOverflow: TextOverflow.ellipsis,
+ fontSize: 12,
+ lineHeight: 16,
+ letterSpacing: 0.4,
+ fontWeight: FontWeight.w400,
+ textColor:
+ HMSThemeColors.onPrimaryHighEmphasis);
+ }),
+ ),
+ Padding(
+ padding: const EdgeInsets.only(left: 4.0),
+ child: Icon(
+ Icons.keyboard_arrow_down,
+ color: HMSThemeColors.onPrimaryHighEmphasis,
+ size: 12,
+ ),
+ ),
+ ],
+ ),
+ ))
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/widgets/chat_widgets/recipient_selector_widget.dart b/packages/hms_room_kit/lib/src/widgets/chat_widgets/recipient_selector_widget.dart
new file mode 100644
index 000000000..4446844da
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/widgets/chat_widgets/recipient_selector_widget.dart
@@ -0,0 +1,363 @@
+///Package imports
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/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/widgets/common_widgets/hms_cross_button.dart';
+
+///[ReceipientSelectorChip] is a widget that is used to render the receipient selector chip
+class RecipientSelectorWidget extends StatefulWidget {
+ final Function updateUI;
+ final String selectedValue;
+
+ const RecipientSelectorWidget(
+ {super.key, required this.updateUI, required this.selectedValue});
+
+ @override
+ State createState() =>
+ _RecipientSelectorWidgetState();
+}
+
+class _RecipientSelectorWidgetState extends State {
+ String currentlySelectedValue = "";
+
+ @override
+ void initState() {
+ super.initState();
+ currentlySelectedValue = widget.selectedValue;
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return DraggableScrollableSheet(
+ maxChildSize: 0.7,
+ builder: (context, controller) {
+ return Container(
+ decoration: BoxDecoration(
+ borderRadius: const BorderRadius.only(
+ topLeft: Radius.circular(16), topRight: Radius.circular(16)),
+ color: HMSThemeColors.surfaceDefault,
+ ),
+ child: Column(
+ children: [
+ Column(
+ children: [
+ Padding(
+ padding:
+ const EdgeInsets.only(left: 24.0, right: 24, top: 16),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ HMSTitleText(
+ text: "Send message to",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ letterSpacing: 0.15,
+ ),
+ HMSCrossButton(
+ iconColor: HMSThemeColors.onSecondaryMediumEmphasis,
+ )
+ ],
+ ),
+ ),
+ Padding(
+ padding: const EdgeInsets.symmetric(vertical: 12.0),
+ child: Divider(
+ height: 1,
+ color: HMSThemeColors.borderBright,
+ ),
+ ),
+ ],
+ ),
+
+ ///TODO: Add search bar here
+
+ Expanded(
+ child: SingleChildScrollView(
+ child: Column(
+ children: [
+ if (HMSRoomLayout.chatData?.isPublicChatEnabled ??
+ false)
+ Padding(
+ padding:
+ const EdgeInsets.only(left: 24.0, right: 24),
+ child: ListTile(
+ onTap: () {
+ setState(() {
+ currentlySelectedValue = "Everyone";
+ });
+ widget.updateUI(currentlySelectedValue, null);
+ context
+ .read()
+ .recipientSelectorValue = "Everyone";
+ Navigator.pop(context);
+ },
+ dense: true,
+ horizontalTitleGap: 0,
+ contentPadding: EdgeInsets.zero,
+ titleAlignment: ListTileTitleAlignment.center,
+ leading: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/everyone.svg",
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceMediumEmphasis,
+ BlendMode.srcIn),
+ width: 20,
+ height: 20,
+ ),
+ title: HMSTitleText(
+ text: "Everyone",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ fontSize: 14,
+ letterSpacing: 0.1,
+ lineHeight: 20,
+ ),
+ trailing: currentlySelectedValue == "Everyone"
+ ? SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/tick.svg",
+ fit: BoxFit.scaleDown,
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn),
+ )
+ : const SizedBox(),
+ ),
+ ),
+
+ if (HMSRoomLayout.chatData?.isPublicChatEnabled ??
+ false)
+ Padding(
+ padding: const EdgeInsets.symmetric(vertical: 6.0),
+ child: Divider(
+ height: 1,
+ color: HMSThemeColors.borderBright,
+ ),
+ ),
+
+ ///Group based selection
+ if (HMSRoomLayout.chatData?.rolesWhitelist.isNotEmpty ??
+ false)
+ Padding(
+ padding:
+ const EdgeInsets.only(left: 24.0, right: 24),
+ child: ListTile(
+ dense: true,
+ horizontalTitleGap: 0,
+ contentPadding: EdgeInsets.zero,
+ titleAlignment: ListTileTitleAlignment.center,
+ leading: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/participants.svg",
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceMediumEmphasis,
+ BlendMode.srcIn),
+ width: 20,
+ height: 20,
+ ),
+ title: HMSTitleText(
+ text: "ROLE GROUP",
+ textColor:
+ HMSThemeColors.onSurfaceMediumEmphasis,
+ fontSize: 10,
+ letterSpacing: 1.5,
+ lineHeight: 16,
+ ),
+ ),
+ ),
+
+ if (HMSRoomLayout.chatData?.rolesWhitelist.isNotEmpty ??
+ false)
+ Padding(
+ padding:
+ const EdgeInsets.only(left: 10.0, right: 10),
+ child: Column(
+ children: HMSRoomLayout.chatData!.rolesWhitelist
+ .map((roleName) => ListTile(
+ onTap: () {
+ setState(() {
+ currentlySelectedValue = roleName;
+ });
+ widget.updateUI(
+ currentlySelectedValue, null);
+ context
+ .read()
+ .recipientSelectorValue =
+ context
+ .read()
+ .roles
+ .firstWhere((element) =>
+ element.name == roleName);
+ Navigator.pop(context);
+ },
+ title: HMSTitleText(
+ text: roleName,
+ textColor: HMSThemeColors
+ .onSurfaceHighEmphasis,
+ fontSize: 14,
+ letterSpacing: 0.1,
+ lineHeight: 20,
+ ),
+ trailing:
+ currentlySelectedValue == roleName
+ ? SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/tick.svg",
+ fit: BoxFit.scaleDown,
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors
+ .onSurfaceHighEmphasis,
+ BlendMode.srcIn),
+ )
+ : const SizedBox(),
+ ))
+ .toList(),
+ ),
+ ),
+
+ if (HMSRoomLayout.chatData?.rolesWhitelist.isNotEmpty ??
+ false)
+ Padding(
+ padding: const EdgeInsets.symmetric(vertical: 6.0),
+ child: Divider(
+ height: 1,
+ color: HMSThemeColors.borderBright,
+ ),
+ ),
+
+ ///Participant based selection
+
+ if (HMSRoomLayout.chatData?.isPrivateChatEnabled ??
+ false)
+ Selector, int>>(
+ selector: (_, meetingStore) => Tuple2(
+ meetingStore.peers,
+ meetingStore.peers.length),
+ builder: (_, data, __) {
+ return data.item2 <= 1
+ ? const SizedBox()
+ : Padding(
+ padding: const EdgeInsets.only(
+ left: 24.0, right: 24),
+ child: ListTile(
+ dense: true,
+ horizontalTitleGap: 0,
+ contentPadding: EdgeInsets.zero,
+ titleAlignment:
+ ListTileTitleAlignment.center,
+ leading: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/person.svg",
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors
+ .onSurfaceMediumEmphasis,
+ BlendMode.srcIn),
+ width: 20,
+ height: 20,
+ ),
+ title: HMSTitleText(
+ text: "DIRECT MESSAGE",
+ textColor: HMSThemeColors
+ .onSurfaceMediumEmphasis,
+ fontSize: 10,
+ letterSpacing: 1.5,
+ lineHeight: 16,
+ ),
+ ),
+ );
+ }),
+
+ if (HMSRoomLayout.chatData?.isPrivateChatEnabled ??
+ false)
+ Selector, int>>(
+ selector: (_, meetingStore) => Tuple2(
+ meetingStore.peers,
+ meetingStore.peers.length),
+ builder: (_, data, __) {
+ return data.item2 <= 1
+ ? ((HMSRoomLayout.chatData
+ ?.isPrivateChatEnabled ??
+ false) &&
+ !(HMSRoomLayout.chatData
+ ?.isPublicChatEnabled ??
+ true) &&
+ (HMSRoomLayout.chatData
+ ?.rolesWhitelist.isEmpty ??
+ false))
+ ? HMSTitleText(
+ text: "No recipients yet",
+ textColor: HMSThemeColors
+ .onSurfaceMediumEmphasis,
+ fontSize: 14,
+ letterSpacing: 0.1,
+ lineHeight: 20,
+ )
+ : const SizedBox()
+ : Padding(
+ padding: const EdgeInsets.only(
+ left: 10.0, right: 10),
+ child: Column(
+ children: data.item1
+ .where((peer) =>
+ peer.isLocal == false)
+ .map((peer) => ListTile(
+ onTap: () {
+ setState(() {
+ currentlySelectedValue =
+ peer.name;
+ });
+ widget.updateUI(peer.name,
+ peer.peerId);
+ context
+ .read()
+ .recipientSelectorValue =
+ data.item1.firstWhere(
+ (element) =>
+ element
+ .peerId ==
+ peer.peerId);
+ Navigator.pop(context);
+ },
+ title: HMSTitleText(
+ text: peer.name,
+ textColor: HMSThemeColors
+ .onSurfaceHighEmphasis,
+ fontSize: 14,
+ letterSpacing: 0.1,
+ lineHeight: 20,
+ ),
+ trailing:
+ currentlySelectedValue ==
+ peer.peerId
+ ? SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/tick.svg",
+ fit: BoxFit
+ .scaleDown,
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors
+ .onSurfaceHighEmphasis,
+ BlendMode
+ .srcIn),
+ )
+ : const SizedBox(),
+ ))
+ .toList(),
+ ),
+ );
+ }),
+ ],
+ ),
+ ),
+ )
+ ],
+ ),
+ );
+ });
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_cross_button.dart b/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_cross_button.dart
index d4b1e6b11..065f99743 100644
--- a/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_cross_button.dart
+++ b/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_cross_button.dart
@@ -7,14 +7,15 @@ import 'package:hms_room_kit/src/layout_api/hms_theme_colors.dart';
///This renders the cross button
class HMSCrossButton extends StatelessWidget {
final Function? onPressed;
- const HMSCrossButton({super.key, this.onPressed});
+ final Color? iconColor;
+ const HMSCrossButton({super.key, this.onPressed, this.iconColor});
@override
Widget build(BuildContext context) {
return IconButton(
icon: Icon(
Icons.close,
- color: HMSThemeColors.onSurfaceHighEmphasis,
+ color: iconColor ?? HMSThemeColors.onSurfaceHighEmphasis,
size: 24,
),
onPressed: () {
diff --git a/packages/hms_room_kit/lib/src/widgets/common_widgets/message_container.dart b/packages/hms_room_kit/lib/src/widgets/common_widgets/message_container.dart
index 22204f3b1..77e310f81 100644
--- a/packages/hms_room_kit/lib/src/widgets/common_widgets/message_container.dart
+++ b/packages/hms_room_kit/lib/src/widgets/common_widgets/message_container.dart
@@ -2,110 +2,119 @@
import 'package:flutter/material.dart';
import 'package:flutter_linkify/flutter_linkify.dart';
import 'package:flutter_svg/svg.dart';
+import 'package:hmssdk_flutter/hmssdk_flutter.dart';
+import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
///Project imports
+import 'package:hms_room_kit/src/widgets/bottom_sheets/chat_utilities_bottom_sheet.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_text_style.dart';
-import 'package:hms_room_kit/src/enums/session_store_keys.dart';
-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/widgets/common_widgets/hms_subtitle_text.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_title_text.dart';
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
+///[MessageContainer] is a widget that is used to render the message container
class MessageContainer extends StatelessWidget {
- final String message;
- final String? senderName;
- final String date;
- final String role;
- const MessageContainer({
+ final HMSMessage message;
+ final DateFormat formatter = DateFormat('hh:mm a');
+
+ MessageContainer({
Key? key,
required this.message,
- required this.senderName,
- required this.date,
- required this.role,
}) : super(key: key);
+ String sender(HMSMessageRecipient? hmsMessageRecipient) {
+ if (hmsMessageRecipient == null) return "";
+ if ((hmsMessageRecipient.recipientPeer != null) &&
+ (hmsMessageRecipient.recipientRoles == null)) {
+ if (hmsMessageRecipient.recipientPeer is HMSLocalPeer) {
+ return "to You (DM)";
+ } else {
+ return "to ${hmsMessageRecipient.recipientPeer?.name} (DM)";
+ }
+ } else if ((hmsMessageRecipient.recipientPeer == null) &&
+ (hmsMessageRecipient.recipientRoles != null)) {
+ return "to ${hmsMessageRecipient.recipientRoles?.first.name} (Group)";
+ }
+ return "";
+ }
+
@override
Widget build(BuildContext context) {
double width = MediaQuery.of(context).size.width;
return Padding(
- padding: const EdgeInsets.only(bottom: 16.0),
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisSize: MainAxisSize.min,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ padding: const EdgeInsets.only(bottom: 8.0),
+ child: Container(
+ decoration: BoxDecoration(
+ color: sender(message.hmsMessageRecipient) != ""
+ ? HMSThemeColors.surfaceDefault
+ : HMSThemeColors.surfaceDim,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.all(8),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.min,
children: [
Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
- Container(
- constraints: BoxConstraints(
- maxWidth: role != "" ? width * 0.25 : width * 0.5),
- child: HMSTitleText(
- text: senderName ?? "Anonymous",
- fontSize: 14,
- letterSpacing: 0.1,
- lineHeight: 20,
- textColor: HMSThemeColors.onSurfaceHighEmphasis,
- ),
- ),
- const SizedBox(
- width: 4,
- ),
- HMSSubtitleText(
- text: date,
- textColor: HMSThemeColors.onSurfaceMediumEmphasis,
+ Row(
+ children: [
+ Container(
+ constraints: BoxConstraints(
+ maxWidth: sender(message.hmsMessageRecipient) == ""
+ ? width * 0.25
+ : width * 0.5),
+ child: HMSTitleText(
+ text: message.sender?.name ?? "Anonymous",
+ fontSize: 14,
+ letterSpacing: 0.1,
+ lineHeight: 20,
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ ),
+ ),
+ const SizedBox(
+ width: 4,
+ ),
+ Container(
+ constraints: BoxConstraints(maxWidth: width * 0.5),
+ child: HMSSubtitleText(
+ text: sender(message.hmsMessageRecipient),
+ textColor: HMSThemeColors.onSurfaceMediumEmphasis),
+ ),
+ ],
),
- ],
- ),
- if (HMSRoomLayout.chatData?.allowPinningMessages ?? true)
- Row(
- children: [
- if (role == "")
- PopupMenuButton(
- position: PopupMenuPosition.under,
- color: HMSThemeColors.surfaceDefault,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(8)),
- itemBuilder: (context) {
- return List.generate(1, (index) {
- return PopupMenuItem(
- height: 52,
- child: Row(
- children: [
- SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/pin.svg",
- height: 20,
- width: 20,
- colorFilter: ColorFilter.mode(
- HMSThemeColors.onSurfaceMediumEmphasis,
- BlendMode.srcIn),
- ),
- const SizedBox(
- width: 8,
- ),
- HMSTitleText(
- text: "Pin Message",
- fontSize: 14,
- lineHeight: 20,
- letterSpacing: 0.1,
- textColor:
- HMSThemeColors.onSurfaceHighEmphasis,
- )
- ],
- ),
- onTap: () => context
- .read()
- .setSessionMetadataForKey(
- key: SessionStoreKeyValues
- .getNameFromMethod(SessionStoreKey
- .pinnedMessageSessionKey),
- metadata: "${senderName!}: $message"),
- );
- });
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ HMSSubtitleText(
+ text: formatter.format(message.time),
+ textColor: HMSThemeColors.onSurfaceMediumEmphasis,
+ ),
+ const SizedBox(
+ width: 8,
+ ),
+ GestureDetector(
+ onTap: () {
+ 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: ChatUtilitiesBottomSheet(
+ message: message,
+ )),
+ );
},
child: SvgPicture.asset(
"packages/hms_room_kit/lib/src/assets/icons/more.svg",
@@ -115,37 +124,39 @@ class MessageContainer extends StatelessWidget {
HMSThemeColors.onSurfaceMediumEmphasis,
BlendMode.srcIn),
),
- )
- ],
- )
+ ),
+ ],
+ ),
+ ],
+ ),
+ const SizedBox(
+ height: 8,
+ ),
+ SelectableLinkify(
+ text: message.message.trim().toString(),
+ onOpen: (link) async {
+ Uri url = Uri.parse(link.url);
+ if (await canLaunchUrl(url)) {
+ await launchUrl(url, mode: LaunchMode.externalApplication);
+ }
+ },
+ options: const LinkifyOptions(humanize: false),
+ style: HMSTextStyle.setTextStyle(
+ fontSize: 14.0,
+ color: HMSThemeColors.onSurfaceHighEmphasis,
+ height: 20 / 14,
+ letterSpacing: 0.25,
+ fontWeight: FontWeight.w400),
+ linkStyle: HMSTextStyle.setTextStyle(
+ fontSize: 14.0,
+ color: HMSThemeColors.primaryDefault,
+ letterSpacing: 0.25,
+ height: 20 / 14,
+ fontWeight: FontWeight.w400),
+ ),
],
),
- const SizedBox(
- height: 8,
- ),
- SelectableLinkify(
- text: message,
- onOpen: (link) async {
- Uri url = Uri.parse(link.url);
- if (await canLaunchUrl(url)) {
- await launchUrl(url, mode: LaunchMode.externalApplication);
- }
- },
- options: const LinkifyOptions(humanize: false),
- style: HMSTextStyle.setTextStyle(
- fontSize: 14.0,
- color: HMSThemeColors.onSurfaceHighEmphasis,
- height: 20 / 14,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w400),
- linkStyle: HMSTextStyle.setTextStyle(
- fontSize: 14.0,
- color: HMSThemeColors.primaryDefault,
- letterSpacing: 0.25,
- height: 20 / 14,
- fontWeight: FontWeight.w400),
- ),
- ],
+ ),
),
);
}
diff --git a/packages/hms_room_kit/lib/src/widgets/tab_widgets/chat_participants_tab_bar.dart b/packages/hms_room_kit/lib/src/widgets/tab_widgets/chat_participants_tab_bar.dart
index d41b3275c..f204c2e41 100644
--- a/packages/hms_room_kit/lib/src/widgets/tab_widgets/chat_participants_tab_bar.dart
+++ b/packages/hms_room_kit/lib/src/widgets/tab_widgets/chat_participants_tab_bar.dart
@@ -1,12 +1,20 @@
+///Package imports
import 'package:flutter/material.dart';
-import 'package:hms_room_kit/src/layout_api/hms_theme_colors.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:provider/provider.dart';
+
+///Project imports
+import 'package:hms_room_kit/hms_room_kit.dart';
+import 'package:hms_room_kit/src/enums/session_store_keys.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/widgets/bottom_sheets/chat_bottom_sheet.dart';
import 'package:hms_room_kit/src/widgets/bottom_sheets/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:provider/provider.dart';
+///[ChatParticipantsTabBar] is a tab bar that is used to render the tab bar for chat and participants
+///This is only rendered when both chat and participants list are enabled.
class ChatParticipantsTabBar extends StatefulWidget {
final int tabIndex;
const ChatParticipantsTabBar({super.key, this.tabIndex = 0});
@@ -47,7 +55,12 @@ class _ChatParticipantsTabBarState extends State
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
- width: MediaQuery.of(context).size.width * 0.76,
+ width: MediaQuery.of(context).size.width *
+ ((HMSRoomLayout.chatData?.realTimeControls
+ ?.canDisableChat ??
+ false)
+ ? 0.69
+ : 0.76),
height: 36,
decoration: BoxDecoration(
color: HMSThemeColors.surfaceDefault,
@@ -57,7 +70,8 @@ class _ChatParticipantsTabBarState extends State
tabs: [
Tab(
child: HMSSubheadingText(
- text: "Chat",
+ text: HMSRoomLayout.chatData?.chatTitle ??
+ "Chat",
fontWeight: FontWeight.w600,
textColor: _controller.index == 0
? HMSThemeColors.onSurfaceHighEmphasis
@@ -81,8 +95,86 @@ class _ChatParticipantsTabBarState extends State
],
),
Row(
- mainAxisAlignment: MainAxisAlignment.end,
+ mainAxisAlignment: MainAxisAlignment.start,
children: [
+ if (HMSRoomLayout
+ .chatData?.realTimeControls?.canDisableChat ??
+ false)
+ PopupMenuButton(
+ padding: EdgeInsets.zero,
+ position: PopupMenuPosition.under,
+ color: HMSThemeColors.surfaceDefault,
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/settings.svg",
+ width: 24,
+ height: 24,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceLowEmphasis,
+ BlendMode.srcIn)),
+ itemBuilder: (context) => [
+ PopupMenuItem(
+ value: 1,
+ child: Row(children: [
+ SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/${context.read().chatControls["enabled"] ? "recording_paused" : "resume"}.svg",
+ width: 20,
+ height: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors
+ .onSurfaceHighEmphasis,
+ BlendMode.srcIn)),
+ const SizedBox(
+ width: 8,
+ ),
+ HMSTitleText(
+ text: context
+ .read()
+ .chatControls["enabled"]
+ ? "Pause Chat"
+ : "Resume Chat",
+ textColor: HMSThemeColors
+ .onSurfaceHighEmphasis,
+ fontSize: 14,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ ),
+ ]))
+ ],
+ onSelected: (value) {
+ switch (value) {
+ case 1:
+ context
+ .read()
+ .setSessionMetadataForKey(
+ key: SessionStoreKeyValues
+ .getNameFromMethod(
+ SessionStoreKey.chatState),
+ metadata: {
+ "enabled": context
+ .read()
+ .chatControls["enabled"]
+ ? false
+ : true,
+ "updatedBy": {
+ "peerID": context
+ .read()
+ .localPeer
+ ?.peerId,
+ "userID": context
+ .read()
+ .localPeer
+ ?.customerUserId,
+ "userName": context
+ .read()
+ .localPeer
+ ?.name
+ },
+ "updatedAt": DateTime.now()
+ .millisecondsSinceEpoch //unix timestamp in miliseconds
+ });
+ break;
+ }
+ }),
HMSCrossButton(
onPressed: () =>
context.read().setNewMessageFalse(),
@@ -92,7 +184,7 @@ class _ChatParticipantsTabBarState extends State
],
),
SizedBox(
- height: MediaQuery.of(context).size.height * 0.78,
+ height: MediaQuery.of(context).size.height * 0.76,
child: TabBarView(controller: _controller, children: const [
ChatBottomSheet(),
ParticipantsBottomSheet()
diff --git a/packages/hms_room_kit/lib/src/widgets/toasts/hms_chat_pause_resume_toast.dart b/packages/hms_room_kit/lib/src/widgets/toasts/hms_chat_pause_resume_toast.dart
new file mode 100644
index 000000000..2a2d69a9a
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/widgets/toasts/hms_chat_pause_resume_toast.dart
@@ -0,0 +1,66 @@
+//Dart imports
+import 'dart:math' as math;
+
+//Package imports
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+
+//Project imports
+import 'package:hms_room_kit/src/layout_api/hms_theme_colors.dart';
+import 'package:hms_room_kit/src/meeting/meeting_store.dart';
+import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart';
+import 'package:hms_room_kit/src/widgets/common_widgets/hms_subtitle_text.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_toast.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_toasts_type.dart';
+
+class HMSChatPauseResumeToast extends StatelessWidget {
+ final bool isChatEnabled;
+ final String userName;
+ final MeetingStore meetingStore;
+
+ const HMSChatPauseResumeToast(
+ {Key? key,
+ required this.isChatEnabled,
+ required this.userName,
+ required this.meetingStore})
+ : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return HMSToast(
+ leading: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/${isChatEnabled ? "message_badge_on" : "message_badge_off"}.svg",
+ height: 24,
+ width: 24,
+ ),
+ subtitle: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ HMSSubheadingText(
+ text: "Chat ${isChatEnabled ? "resumed" : "paused"}",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ lineHeight: 20,
+ letterSpacing: 0.1,
+ fontWeight: FontWeight.w400,
+ ),
+ HMSSubtitleText(
+ text:
+ "Chat has been ${isChatEnabled ? "resumed" : "paused"} by ${userName.substring(0, math.min(10, userName.length))}",
+ textColor: HMSThemeColors.onSurfaceMediumEmphasis,
+ )
+ ],
+ ),
+ cancelToastButton: IconButton(
+ icon: Icon(
+ Icons.close,
+ color: HMSThemeColors.onSurfaceHighEmphasis,
+ size: 24,
+ ),
+ onPressed: () {
+ meetingStore.removeToast(HMSToastsType.chatPauseResumeToast);
+ },
+ ),
+ );
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/widgets/toasts/hms_error_toast.dart b/packages/hms_room_kit/lib/src/widgets/toasts/hms_error_toast.dart
new file mode 100644
index 000000000..db37eb076
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/widgets/toasts/hms_error_toast.dart
@@ -0,0 +1,76 @@
+///Dart imports
+import 'dart:math' as math;
+
+///Package imports
+import 'package:flutter/material.dart';
+import 'package:hmssdk_flutter/hmssdk_flutter.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/meeting/meeting_store.dart';
+import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_toast.dart';
+import 'package:hms_room_kit/src/widgets/toasts/hms_toasts_type.dart';
+
+///[HMSRecordingErrorToast] renders the toast when recording fails to start
+class HMSErrorToast extends StatefulWidget {
+ final HMSException error;
+ final MeetingStore meetingStore;
+ final Color? toastColor;
+ final double? toastPosition;
+ const HMSErrorToast(
+ {super.key,
+ required this.error,
+ required this.meetingStore,
+ this.toastColor,
+ this.toastPosition});
+
+ @override
+ State createState() => _HMSErrorToastState();
+}
+
+class _HMSErrorToastState extends State {
+ bool _showWidget = true;
+
+ @override
+ void initState() {
+ super.initState();
+ Future.delayed(const Duration(seconds: 2)).then((value) => {_setTimer()});
+ }
+
+ void _setTimer() {
+ setState(() {
+ _showWidget = false;
+ });
+ context.read().removeToast(HMSToastsType.errorToast);
+ _showWidget = true;
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return _showWidget
+ ? HMSToast(
+ toastColor: widget.toastColor,
+ toastPosition: widget.toastPosition,
+ subtitle: HMSSubheadingText(
+ text: widget.error.description
+ .substring(0, math.min(30, widget.error.description.length)),
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ fontWeight: FontWeight.w600,
+ letterSpacing: 0.1,
+ ),
+ cancelToastButton: IconButton(
+ icon: Icon(
+ Icons.close,
+ color: HMSThemeColors.onSurfaceHighEmphasis,
+ size: 24,
+ ),
+ onPressed: () {
+ widget.meetingStore.removeToast(HMSToastsType.errorToast);
+ },
+ ),
+ )
+ : const SizedBox();
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/widgets/toasts/hms_recording_error_toast.dart b/packages/hms_room_kit/lib/src/widgets/toasts/hms_recording_error_toast.dart
index b7a94f937..ff1ec73be 100644
--- a/packages/hms_room_kit/lib/src/widgets/toasts/hms_recording_error_toast.dart
+++ b/packages/hms_room_kit/lib/src/widgets/toasts/hms_recording_error_toast.dart
@@ -46,7 +46,7 @@ class HMSRecordingErrorToast extends StatelessWidget {
buttonTitle: "Retry",
action: () {
meetingStore.startRtmpOrRecording(toRecord: true);
- meetingStore.removeToast(HMSToastsType.errorToast);
+ meetingStore.removeToast(HMSToastsType.recordingErrorToast);
},
height: 36,
buttonColor: HMSThemeColors.secondaryDefault,
@@ -59,7 +59,7 @@ class HMSRecordingErrorToast extends StatelessWidget {
size: 24,
),
onPressed: () {
- meetingStore.removeToast(HMSToastsType.errorToast);
+ meetingStore.removeToast(HMSToastsType.recordingErrorToast);
},
),
);
diff --git a/packages/hms_room_kit/lib/src/widgets/toasts/hms_toast.dart b/packages/hms_room_kit/lib/src/widgets/toasts/hms_toast.dart
index 814d1cd5e..392fd66bc 100644
--- a/packages/hms_room_kit/lib/src/widgets/toasts/hms_toast.dart
+++ b/packages/hms_room_kit/lib/src/widgets/toasts/hms_toast.dart
@@ -37,6 +37,7 @@ class _HMSToastState extends State {
return Padding(
padding: EdgeInsets.only(bottom: widget.toastPosition ?? 68),
child: AlertDialog(
+ backgroundColor: widget.toastColor,
insetPadding: const EdgeInsets.all(0),
alignment: Alignment.bottomCenter,
contentPadding: const EdgeInsets.all(0),
diff --git a/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart b/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart
index 7b6f011fa..f366d16d0 100644
--- a/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart
+++ b/packages/hms_room_kit/lib/src/widgets/toasts/hms_toasts_type.dart
@@ -1,7 +1,9 @@
///[HMSToastsType] is used to define the type of toast to be shown.
enum HMSToastsType {
roleChangeToast,
- errorToast,
+ recordingErrorToast,
localScreenshareToast,
- roleChangeDeclineToast
+ roleChangeDeclineToast,
+ chatPauseResumeToast,
+ errorToast
}
diff --git a/packages/hms_room_kit/pubspec.lock b/packages/hms_room_kit/pubspec.lock
index c639d8658..dd3607692 100644
--- a/packages/hms_room_kit/pubspec.lock
+++ b/packages/hms_room_kit/pubspec.lock
@@ -204,10 +204,10 @@ packages:
dependency: "direct main"
description:
name: hmssdk_flutter
- sha256: f61fb1ffcaf7296e0e2eeff9bc34d699baf9190136b8570a15cde61819cf3276
+ sha256: "112381755d47a639ef296295ace5b9d73267b89458f33ac767d1b6536a3fc898"
url: "https://pub.dev"
source: hosted
- version: "1.9.5"
+ version: "1.9.6"
http:
dependency: transitive
description:
@@ -228,10 +228,10 @@ packages:
dependency: "direct main"
description:
name: intl
- sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
+ sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
- version: "0.19.0"
+ version: "0.18.1"
js:
dependency: transitive
description:
@@ -332,10 +332,10 @@ packages:
dependency: transitive
description:
name: path_provider_android
- sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
+ sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
url: "https://pub.dev"
source: hosted
- version: "2.2.1"
+ version: "2.2.2"
path_provider_foundation:
dependency: transitive
description:
@@ -625,10 +625,10 @@ packages:
dependency: transitive
description:
name: url_launcher_linux
- sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd"
+ sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811
url: "https://pub.dev"
source: hosted
- version: "3.1.0"
+ version: "3.1.1"
url_launcher_macos:
dependency: transitive
description:
@@ -657,18 +657,18 @@ packages:
dependency: transitive
description:
name: url_launcher_windows
- sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc"
+ sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
url: "https://pub.dev"
source: hosted
- version: "3.1.0"
+ version: "3.1.1"
uuid:
dependency: transitive
description:
name: uuid
- sha256: df5a4d8f22ee4ccd77f8839ac7cb274ebc11ef9adcce8b92be14b797fe889921
+ sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f"
url: "https://pub.dev"
source: hosted
- version: "4.2.1"
+ version: "4.2.2"
vector_graphics:
dependency: transitive
description:
diff --git a/packages/hms_room_kit/pubspec.yaml b/packages/hms_room_kit/pubspec.yaml
index 961253565..52feef84e 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.8
+version: 1.0.9
homepage: https://www.100ms.live/
repository: https://github.com/100mslive/100ms-flutter
issue_tracker: https://github.com/100mslive/100ms-flutter/issues
@@ -14,8 +14,8 @@ dependencies:
flutter:
sdk: flutter
- hmssdk_flutter: ^1.9.5
- intl: ^0.19.0
+ hmssdk_flutter: 1.9.6
+ intl: ^0.18.0
permission_handler: ^11.0.0
provider: ^6.0.5
google_fonts: ^6.1.0
diff --git a/packages/hmssdk_flutter/CHANGELOG.md b/packages/hmssdk_flutter/CHANGELOG.md
index 8c5adf1ae..47ca3c5a5 100644
--- a/packages/hmssdk_flutter/CHANGELOG.md
+++ b/packages/hmssdk_flutter/CHANGELOG.md
@@ -5,6 +5,27 @@
| 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.6 - 2024-01-15
+
+| Package | Version |
+| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
+| hms_room_kit | 1.0.9 |
+| hmssdk_flutter | 1.9.6 |
+
+### ✨ Added
+
+- Added `isLargeRoom` property in `HMSRoom` class to check whether the current room is a large room or not
+
+### 🔄 Changed
+
+- `setSessionMetadataForKey` method now supports `dynamic` type for `data` parameter instead of `String?` type.
+
+ Learn more about Session Store [here](https://www.100ms.live/docs/flutter/v2/how-to-guides/interact-with-room/room/session-store#setting-a-value-for-a-specific-key).
+
+Updated to Android SDK 2.8.5 & iOS SDK 1.4.1
+
+**Full Changelog**: [1.9.5...1.9.6](https://github.com/100mslive/100ms-flutter/compare/1.9.5...1.9.6)
+
# 1.9.5 - 2023-12-15
| Package | Version |
diff --git a/packages/hmssdk_flutter/README.md b/packages/hmssdk_flutter/README.md
index afe2dedff..7eccea214 100644
--- a/packages/hmssdk_flutter/README.md
+++ b/packages/hmssdk_flutter/README.md
@@ -1,4 +1,4 @@
-[![100ms-svg](https://user-images.githubusercontent.com/93931528/205858417-8c0a0d1b-2d46-4710-9316-7418092fd3d6.svg)](https://100ms.live/)
+# 100ms Flutter SDK 🎉
[![Pub Version](https://img.shields.io/pub/v/hmssdk_flutter)](https://pub.dev/packages/hmssdk_flutter)
[![Build](https://github.com/100mslive/100ms-flutter/actions/workflows/build.yml/badge.svg?branch=develop)](https://github.com/100mslive/100ms-flutter/actions/workflows/build.yml)
@@ -10,7 +10,9 @@
[![Activity](https://img.shields.io/github/commit-activity/m/100mslive/100ms-flutter.svg)](https://github.com/100mslive/100ms-flutter/projects?type=classic)
[![Register](https://img.shields.io/badge/Contact-Know%20More-blue)](https://dashboard.100ms.live/register)
-# 100ms Flutter SDK 🎉
+
+
+
Integrate Real Time Audio and Video conferencing, Interactive Live Streaming, and Chat in your apps with 100ms Flutter SDK.
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRoomExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRoomExtension.kt
index d3522c237..bebd5bd78 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRoomExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRoomExtension.kt
@@ -17,6 +17,8 @@ class HMSRoomExtension {
room.peerList.forEach {
args.add(HMSPeerExtension.toDictionary(it)!!)
}
+
+ hashMap["is_large"] = room.isLargeRoom
hashMap["local_peer"] = HMSPeerExtension.toDictionary(room.localPeer)
hashMap["peers"] = args
hashMap["rtmp_streaming_state"] = HMSStreamingState.toDictionary(room.rtmpHMSRtmpStreamingState)
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSSessionStoreAction.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSSessionStoreAction.kt
index 28ea1d2d3..a6bec486b 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSSessionStoreAction.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSSessionStoreAction.kt
@@ -1,6 +1,9 @@
package live.hms.hmssdk_flutter.methods
+import com.google.gson.JsonArray
import com.google.gson.JsonElement
+import com.google.gson.JsonObject
+import com.google.gson.JsonParser
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel.Result
import live.hms.hmssdk_flutter.HMSCommonAction
@@ -101,7 +104,7 @@ class HMSSessionStoreAction {
HMSErrorLogger.returnArgumentsError("key is null")
}
- val data = call.argument("data")
+ val data = call.argument("data")
key?.let {
key as String
diff --git a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt
index 92a1109c2..d41238161 100644
--- a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt
+++ b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt
@@ -1,9 +1,35 @@
Board: https://100ms.atlassian.net/jira/software/projects/FLUT/boards/34/
-- Beam Intermediate State Updates
-https://100ms.atlassian.net/browse/FLUT-135
+- Add app launch animation for Prebuilt
+https://100ms.atlassian.net/browse/FLUT-180
-Room Kit: 1.0.8
-Core SDK: 1.9.5
-Android SDK: 2.8.3
-iOS SDK: 1.4.0
+- Real time chat controls
+https://100ms.atlassian.net/browse/FLUT-153
+
+- Skip Preview for Role Change
+https://100ms.atlassian.net/browse/FLUT-162
+
+- Even if screenshare is disabled, UI still shows screenshare option
+https://100ms.atlassian.net/browse/LIVE-1981
+
+- Block Peer From Chat
+https://100ms.atlassian.net/browse/FLUT-157
+
+- Multi Pin Chat
+https://100ms.atlassian.net/browse/FLUT-154
+
+- can't see pinned chat(by remote peer) on Flutter
+https://100ms.atlassian.net/browse/FLUT-187
+
+- Send to picker based on layout API
+https://100ms.atlassian.net/browse/FLUT-156
+
+- Added hide message functionality
+
+- Add Remove peer option in message context menu
+https://100ms.atlassian.net/browse/FLUT-183
+
+Room Kit: 1.0.9
+Core SDK: 1.9.6
+Android SDK: 2.8.5
+iOS SDK: 1.4.1
diff --git a/packages/hmssdk_flutter/example/android/Gemfile.lock b/packages/hmssdk_flutter/example/android/Gemfile.lock
index 84347bec1..92f3afcf7 100644
--- a/packages/hmssdk_flutter/example/android/Gemfile.lock
+++ b/packages/hmssdk_flutter/example/android/Gemfile.lock
@@ -13,16 +13,16 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.3.0)
- aws-partitions (1.864.0)
- aws-sdk-core (3.190.0)
+ aws-partitions (1.879.0)
+ aws-sdk-core (3.190.2)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1)
- aws-sdk-kms (1.74.0)
+ aws-sdk-kms (1.76.0)
aws-sdk-core (~> 3, >= 3.188.0)
aws-sigv4 (~> 1.1)
- aws-sdk-s3 (1.141.0)
+ aws-sdk-s3 (1.142.0)
aws-sdk-core (~> 3, >= 3.189.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.8)
@@ -38,10 +38,10 @@ GEM
declarative (0.0.20)
digest-crc (0.6.5)
rake (>= 12.0.0, < 14.0.0)
- domain_name (0.6.20231109)
+ domain_name (0.6.20240107)
dotenv (2.8.1)
emoji_regex (3.2.3)
- excon (0.105.0)
+ excon (0.109.0)
faraday (1.10.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -70,8 +70,8 @@ GEM
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday (~> 1.0)
- fastimage (2.2.7)
- fastlane (2.217.0)
+ fastimage (2.3.0)
+ fastlane (2.218.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@@ -98,7 +98,7 @@ GEM
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (>= 2.0.0, < 3.0.0)
naturally (~> 2.2)
- optparse (~> 0.1.1)
+ optparse (>= 0.1.1)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.3)
@@ -114,7 +114,7 @@ GEM
fastlane-plugin-firebase_app_distribution (0.7.4)
google-apis-firebaseappdistribution_v1 (~> 0.3.0)
gh_inspector (1.1.3)
- google-apis-androidpublisher_v3 (0.53.0)
+ google-apis-androidpublisher_v3 (0.54.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-core (0.11.2)
addressable (~> 2.5, >= 2.5.1)
@@ -131,25 +131,25 @@ GEM
google-apis-core (>= 0.11.0, < 2.a)
google-apis-playcustomapp_v1 (0.13.0)
google-apis-core (>= 0.11.0, < 2.a)
- google-apis-storage_v1 (0.29.0)
+ google-apis-storage_v1 (0.31.0)
google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.6.1)
google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0)
- google-cloud-env (2.0.1)
+ google-cloud-env (2.1.0)
faraday (>= 1.0, < 3.a)
google-cloud-errors (1.3.1)
- google-cloud-storage (1.45.0)
+ google-cloud-storage (1.47.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
- google-apis-storage_v1 (~> 0.29.0)
+ google-apis-storage_v1 (~> 0.31.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
- googleauth (1.9.0)
+ googleauth (1.9.1)
faraday (>= 1.0, < 3.a)
- google-cloud-env (~> 2.0, >= 2.0.1)
+ google-cloud-env (~> 2.1)
jwt (>= 1.4, < 3.0)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
@@ -170,9 +170,9 @@ GEM
multipart-post (2.3.0)
nanaimo (0.3.0)
naturally (2.2.1)
- optparse (0.1.1)
+ optparse (0.4.0)
os (1.1.4)
- plist (3.7.0)
+ plist (3.7.1)
public_suffix (5.0.4)
rake (13.1.0)
representable (3.2.0)
@@ -198,7 +198,7 @@ GEM
unicode-display_width (>= 1.1.1, < 3)
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
- tty-screen (0.8.1)
+ tty-screen (0.8.2)
tty-spinner (0.9.3)
tty-cursor (~> 0.7)
tzinfo (2.0.6)
@@ -221,6 +221,7 @@ GEM
PLATFORMS
arm64-darwin-22
+ arm64-darwin-23
DEPENDENCIES
activesupport (= 7.0.8)
diff --git a/packages/hmssdk_flutter/example/android/app/build.gradle b/packages/hmssdk_flutter/example/android/app/build.gradle
index 54a6d0ee7..012d73a03 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 407
- versionName "1.5.107"
+ versionCode 424
+ versionName "1.5.124"
}
signingConfigs {
diff --git a/packages/hmssdk_flutter/example/assets/splash_asset.json b/packages/hmssdk_flutter/example/assets/splash_asset.json
new file mode 100644
index 000000000..1168f5702
--- /dev/null
+++ b/packages/hmssdk_flutter/example/assets/splash_asset.json
@@ -0,0 +1 @@
+{"assets":[{"id":"ziKMqpsDKcUN3Bvdg7UKx","layers":[]},{"id":"MMbJbp671fhpnijWMEBHr","layers":[]},{"id":"8qJUEUPyQOmvqeiL8E33b","layers":[{"ddd":0,"ind":3,"ty":4,"nm":"","ln":"UgEynrgu7noGMchOEpXWn3","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[49700,49700]},"r":{"a":0,"k":0},"s":{"a":0,"k":[159.996,159.996]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","nm":"surface1","it":[{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-0.15,0.22],[-0.15,0.15],[-0.3,-0.6],[0.22,-0.23],[0.15,-0.15],[0.15,0.3],[0.15,0.23]],"o":[[0.15,-0.15],[0.15,-0.23],[0.3,0.6],[-0.15,0.15],[-0.23,0.23],[-0.07,-0.23],[-0.15,-0.45],[0,0]],"v":[[155.18,190.27],[155.63,189.75],[156,189.15],[156.9,190.95],[156.38,191.55],[155.77,192.07],[155.55,191.25],[155.18,190.27]]}}},{"ty":"gf","e":{"a":0,"k":[156.2,190.34]},"g":{"p":2,"k":{"a":0,"k":[0,0,0,0,1,0,0,0,0,0.35,1,0]}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"o":{"a":0,"k":100},"s":{"a":0,"k":[155,191.53]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-2.25,0],[-2.92,0.75],[-0.75,-3.68],[0,-2.25],[2.18,-0.75],[1.43,0]],"o":[[1.5,0],[4.43,0],[0.75,2.18],[0.75,2.93],[-1.5,0.75],[-2.18,0.75],[0,0]],"v":[[255.45,224.25],[260.63,224.25],[271.65,222.75],[274.57,230.85],[275.32,238.95],[269.47,240.45],[263.62,241.2]]}}},{"ty":"gf","e":{"a":0,"k":[265.2,231.82]},"g":{"p":2,"k":{"a":0,"k":[0.14,0,0,0,1,0,0,0,0.14,0.5,1,0]}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"o":{"a":0,"k":100},"s":{"a":0,"k":[284.57,227.73]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.5,2.25],[0.75,2.18],[3,-5.85],[-1.5,-2.18],[-1.43,-1.5],[-1.43,3],[-1.42,2.17]],"o":[[-1.5,-1.5],[-1.5,-2.18],[-2.93,5.85],[1.5,1.5],[2.18,2.18],[0.75,-2.93],[1.58,-2.93],[0,0]],"v":[[89.4,213.98],[84.97,208.8],[81.3,202.2],[72.45,219.82],[76.87,225.68],[82.72,230.85],[84.9,222],[89.4,213.98]]}}},{"ty":"gf","e":{"a":0,"k":[79.62,214.46]},"g":{"p":2,"k":{"a":0,"k":[0,0,0,0,1,0,0,0,0,0.35,1,0]}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"o":{"a":0,"k":100},"s":{"a":0,"k":[91.43,226.15]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[2.25,0],[2.92,1.43],[0.75,-3.68],[0,-3],[-2.18,-0.75],[-1.43,0]],"o":[[-1.5,0],[-4.43,0],[-0.75,2.18],[-0.75,2.93],[1.5,0.75],[2.18,0.75],[0,0]],"v":[[118.8,224.25],[113.63,224.25],[102.6,222.07],[99.68,230.18],[98.93,239.03],[104.78,240.53],[110.63,241.28]]}}},{"ty":"gf","e":{"a":0,"k":[109.36,231.92]},"g":{"p":2,"k":{"a":0,"k":[0.14,0,0,0,1,0,0,0,0.14,0.5,1,0]}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"o":{"a":0,"k":100},"s":{"a":0,"k":[89.99,227.83]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-2.25,0],[-2.92,-1.43],[-0.75,3.68],[0,2.25],[2.18,0.75],[1.43,0]],"o":[[1.5,0],[4.43,0],[0.75,-2.18],[0.75,-2.93],[-1.5,-0.75],[-2.18,-0.75],[0,0]],"v":[[255.45,150.75],[260.63,150.75],[271.65,152.93],[274.57,144.82],[275.32,136.72],[269.47,135.22],[263.62,134.47]]}}},{"ty":"gf","e":{"a":0,"k":[265.26,143.53]},"g":{"p":2,"k":{"a":0,"k":[0.14,0,0,0,1,0,0,0,0.14,0.5,1,0]}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"o":{"a":0,"k":100},"s":{"a":0,"k":[284.95,147.69]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[2.25,-3.67],[0,0],[-4.42,2.92],[-2.92,-5.18]],"o":[[-3.68,2.93],[0,0],[2.93,-3.68],[1.5,5.85],[0,0]],"v":[[89.4,160.35],[81.3,171.38],[72.45,153.75],[83.47,143.48],[89.4,160.35]]}}},{"ty":"gf","e":{"a":0,"k":[79.36,159.83]},"g":{"p":2,"k":{"a":0,"k":[0,0,0,0,1,0,0,0,0,0.35,1,0]}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"o":{"a":0,"k":100},"s":{"a":0,"k":[91.17,148.15]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[2.25,0],[3.67,-0.75],[0,5.93],[-3.67,0]],"o":[[-1.5,0],[-3.68,0],[-2.18,-5.18],[3.68,-1.5],[0,0]],"v":[[119.55,150.75],[114.38,150.75],[103.35,152.25],[99.68,136.05],[111.45,133.88]]}}},{"ty":"gf","e":{"a":0,"k":[109.77,143.15]},"g":{"p":2,"k":{"a":0,"k":[0.14,0,0,0,1,0,0,0,0.14,0.5,1,0]}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"o":{"a":0,"k":100},"s":{"a":0,"k":[90.17,147.29]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[1.43,5.85],[0,-17.62],[-13.2,-9.53],[-2.93,5.1],[0,10.28],[-7.35,7.35]],"o":[[-2.93,-5.18],[-13.2,9.52],[0,17.63],[0.75,-5.85],[-6.6,-6.6],[-0.68,-9.52],[0,0]],"v":[[89.4,160.35],[83.55,143.48],[61.5,186.75],[83.55,230.1],[89.4,213.23],[78.38,186.75],[89.4,160.35]]}}},{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[2.93,-5.1],[0,-10.28],[6.6,-7.35],[-1.43,-5.85],[0,17.63],[13.2,9.53]],"o":[[-0.75,5.85],[6.6,6.6],[0,10.27],[2.93,5.18],[13.2,-9.52],[0,-18.37],[0,0]],"v":[[291.45,144.15],[285.6,161.02],[296.62,187.5],[285.6,214.65],[291.45,231.52],[313.5,188.25],[291.45,144.15]]}}},{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-2.92,-1.43],[0,5.93],[5.18,0],[14.7,-14.7],[2.18,-2.18],[2.18,2.18],[27.97,0],[5.18,-1.43],[-2.18,-5.18],[-3.67,0],[-11.7,-12.52],[-2.18,-2.18],[2.93,-2.93],[3.67,-3.67],[10.35,0],[2.92,1.43],[0,-5.93],[-5.18,0],[-14.7,14.7],[-2.18,2.18],[-2.18,-2.18],[-27.97,0],[-5.18,1.43],[2.18,5.18],[3.67,0],[11.7,12.52],[2.18,2.18],[-2.93,2.93],[-23.55,0]],"o":[[3.68,0],[2.18,-5.18],[-5.18,-1.5],[-27.9,0],[-2.93,2.93],[-2.18,-2.18],[-13.95,-13.95],[-5.18,0],[0,5.85],[3.68,-1.5],[23.48,0],[2.18,2.93],[-1.5,2.18],[-2.93,2.93],[-18.37,15.45],[-3.68,0],[-2.18,5.18],[5.18,1.5],[27.9,0],[2.93,-2.93],[2.18,2.18],[13.95,13.95],[5.18,0],[0,-5.85],[-5.18,2.18],[-23.48,0],[-2.18,-2.93],[1.5,-2.18],[11.02,-10.95],[0,0]],"v":[[260.63,150.75],[271.65,152.93],[275.32,136.73],[259.88,134.55],[193.73,167.63],[186.38,174.98],[179.77,167.63],[113.63,134.55],[98.18,136.73],[101.85,152.93],[112.88,151.43],[168.68,181.57],[175.28,188.93],[168.68,196.28],[159.15,205.8],[114.3,224.18],[103.28,222],[99.6,238.2],[115.05,240.38],[181.2,207.3],[188.55,199.95],[195.15,207.3],[261.3,240.38],[276.75,238.2],[273.07,222],[260.55,224.18],[204.75,194.03],[198.15,186.68],[204.75,179.32],[260.63,150.75]]}}},{"ty":"fl","c":{"a":0,"k":[0.14,0.46,0.96,1]},"r":1,"o":{"a":0,"k":100}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-5.85,-5.85],[20.55,-20.55],[16.13,2.93],[-2.25,5.93],[-7.35,7.35],[14.7,14.02],[13.2,2.18],[5.85,0],[2.92,-0.75],[0,-3.67],[-1.5,-7.35],[-10.27,-10.28],[-3.67,-1.43],[4.43,-3.68],[3.67,3.67],[3.68,7.35],[5.85,-5.85],[20.55,20.55],[-20.55,20.55],[-7.35,2.93],[5.85,5.85],[-20.55,20.55],[-16.12,-2.93],[2.25,-5.93],[7.35,-7.35],[-14.7,-14.02],[-20.55,-2.93],[-2.93,0],[-3.68,0],[-2.92,0.75],[1.5,12.45],[10.27,11.03],[3.67,1.43],[-4.43,3.68],[-3.67,-3.67],[-3.68,-7.35],[-5.85,5.85],[-20.55,-20.55],[20.55,-20.55],[7.35,-2.93]],"o":[[7.35,3.68],[20.55,21.3],[-12.52,12.52],[3.68,-5.18],[9.52,0],[13.95,-14.7],[-10.27,-11.02],[-8.85,0],[-3.68,0],[0,2.18],[0,5.85],[2.18,13.95],[2.93,2.93],[-1.5,5.18],[-4.43,-2.18],[-5.85,-5.85],[-3.68,7.35],[-20.55,20.55],[-20.55,-21.3],[5.85,-5.85],[-7.35,-3.68],[-20.55,-21.3],[12.52,-12.52],[-3.68,5.18],[-9.52,0],[-13.95,14.7],[6.6,6.6],[2.18,0.75],[5.18,0.75],[3.68,0],[0.75,-6.6],[-2.18,-13.95],[-2.93,-2.93],[1.5,-5.18],[4.43,2.18],[5.85,5.85],[3.68,-7.35],[20.55,-20.55],[20.55,21.3],[-5.85,4.35],[0,0]],"v":[[256.2,187.5],[276.75,201.45],[276.75,277.13],[231.23,291.82],[239.33,275.63],[265.8,264.6],[265.8,212.4],[226.88,194.78],[204.83,194.78],[195.3,195.53],[194.55,205.05],[196.05,226.35],[212.93,266.03],[222.45,272.63],[213.6,286.58],[201.08,277.05],[187.13,256.5],[173.18,277.05],[98.25,277.05],[98.25,201.38],[118.8,187.43],[98.25,173.48],[98.25,97.8],[143.78,83.11],[135.68,99.3],[109.2,110.33],[109.2,162.53],[148.13,180.15],[156.23,180.9],[169.43,181.65],[178.95,180.9],[178.2,150.08],[161.32,110.4],[151.8,103.8],[160.65,89.85],[173.18,99.38],[187.13,119.93],[201.07,99.38],[276,99.38],[276,175.05],[256.2,187.5]]}}},{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-10.28,11.02],[14.7,14.02],[13.95,-14.7],[3.68,-20.55],[0,-0.75],[0,-2.93],[0,-3.68],[-0.75,-2.17],[-1.5,0],[-1.43,0],[-1.5,0],[-8.03,0.75]],"o":[[13.95,-2.18],[13.95,-14.7],[-13.95,-14.7],[-6.6,6.6],[0,0],[-0.75,2.18],[-0.75,5.18],[0,3.68],[0.75,0],[0.75,0],[0.75,0],[5.25,0.82],[0,0]],"v":[[226.05,179.4],[264.98,161.77],[264.98,109.57],[213.53,109.57],[195.9,148.5],[195.9,149.25],[195.15,157.35],[194.4,170.55],[195.15,180.07],[198.83,180.07],[201.75,180.07],[205.43,180.07],[226.05,179.4]]}}},{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-13.95,14.7],[-2.18,13.95],[0.75,6.6],[12.45,-1.5],[10.28,-11.02],[-14.7,-13.95]],"o":[[13.95,14.7],[10.27,-10.27],[2.18,-12.52],[-6.6,-0.75],[-13.95,2.18],[-14.1,14.7],[0,0]],"v":[[110.02,265.35],[161.47,265.35],[179.1,225.68],[179.85,194.85],[149.02,195.6],[110.1,213.23],[110.02,265.35]]}}},{"ty":"gf","e":{"a":0,"k":[94.21,267.89]},"g":{"p":2,"k":{"a":0,"k":[0,0.14,0.46,0.96,0.61,0.14,0.46,0.96,0,0.3,0.61,0.45]}},"t":2,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"o":{"a":0,"k":100},"s":{"a":0,"k":[184.22,182.05]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-6.68,-4.43],[-3.68,-10.27],[0,-8.78],[29.4,0],[9.53,13.2],[-5.85,2.93],[-10.28,0],[0,19.88],[12.52,16.95],[2.25,2.18],[2.92,2.17],[-0.75,2.92],[-3.68,0]],"o":[[4.43,4.43],[5.85,8.1],[2.93,8.1],[0,29.4],[-17.62,0],[5.85,-0.75],[6.6,7.35],[20.55,0],[0,-8.85],[-1.5,-2.18],[-2.93,-3.68],[0,-3.68],[2.85,-1.5],[0,0]],"v":[[204,194.85],[220.2,208.8],[235.65,236.7],[240.07,261.68],[187.2,315.3],[143.85,293.25],[160.72,287.4],[187.2,299.17],[223.95,262.42],[208.5,222],[203.32,215.39],[193.8,205.87],[194.55,196.35],[204,194.85]]}}},{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,-5.18],[2.93,-8.1],[5.93,-8.1],[4.43,-4.43],[2.92,0.75],[0,3.67],[-4.43,6.68],[0,14.7],[0.75,3.67],[-5.93,0]],"o":[[1.5,5.18],[0,8.85],[-3.68,10.27],[-6.6,4.43],[-3.68,0],[0,-2.93],[4.43,-4.43],[8.1,-11.02],[0,-3.68],[5.25,-3.68],[0,0]],"v":[[238.57,98.63],[240.75,114.07],[236.32,139.05],[220.88,166.95],[204.68,181.65],[195.15,180.9],[194.4,171.38],[208.35,155.18],[223.8,114.75],[222.3,103.73],[238.57,98.63]]}}},{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[17.63,0],[0,-29.4],[-2.93,-8.1],[-5.93,-8.1],[-4.43,-5.18],[-2.92,0.75],[0,3.67],[4.43,6.68],[0,14.7],[-20.55,0],[-6.68,-7.35],[-5.85,0.75]],"o":[[-9.52,-13.95],[-29.4,0],[0,8.85],[3.68,10.27],[6.6,4.43],[3.68,0],[0,-2.93],[-4.43,-4.43],[-8.1,-11.02],[0,-20.55],[10.27,0],[5.02,-3.6],[0,0]],"v":[[230.48,82.43],[187.13,59.63],[134.25,113.25],[138.68,138.23],[154.13,166.13],[170.32,180.82],[179.85,180.07],[180.6,170.55],[166.65,154.35],[151.2,113.93],[187.95,77.18],[214.43,88.95],[230.48,82.43]]}}},{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[0,5.18],[-2.93,8.1],[-5.93,8.1],[-2.18,2.25],[-2.92,2.92],[-2.92,-0.75],[0,-3.67],[4.43,-6.68],[0,-14.7],[-0.75,-3.67],[5.93,0]],"o":[[-1.5,-5.18],[0,-8.85],[3.68,-10.27],[2.18,-1.5],[3.68,-2.93],[3.68,0],[0,2.93],[-4.43,4.43],[-8.1,11.02],[0,3.68],[-5.18,3.68],[0,0]],"v":[[136.43,276.38],[134.25,260.93],[138.68,235.95],[154.13,208.05],[160.73,202.88],[170.25,193.35],[179.77,194.1],[180.52,203.63],[166.57,219.82],[151.13,260.25],[152.63,271.27],[136.43,276.38]]}}},{"ty":"gf","e":{"a":0,"k":[187.5,314.93]},"g":{"p":3,"k":{"a":0,"k":[0,0.14,0.46,0.96,0.5,0.14,0.46,0.96,1,0.14,0.46,0.96,0,0.25,0.5,0.2,1,0.25]}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"o":{"a":0,"k":100},"s":{"a":0,"k":[187.5,60.03]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"a":0,"k":{"c":true,"i":[[0,0],[-0.15,-0.22],[-0.07,-0.15],[-0.3,0.6],[0.22,0.23],[0.15,0.15],[0.15,-0.37],[0.15,-0.23]],"o":[[0.15,0.15],[0.15,0.23],[0.3,-0.6],[-0.15,-0.15],[-0.23,-0.23],[-0.07,0.23],[-0.07,0.38],[0,0]],"v":[[155.18,184.8],[155.63,185.32],[156,185.93],[156.9,184.13],[156.38,183.52],[155.77,183],[155.55,183.9],[155.18,184.8]]}}},{"ty":"gf","e":{"a":0,"k":[156.17,184.71]},"g":{"p":2,"k":{"a":0,"k":[0,0,0,0,1,0,0,0,0,0.35,1,0]}},"t":1,"a":{"a":0,"k":0},"h":{"a":0,"k":0},"o":{"a":0,"k":100},"s":{"a":0,"k":[154.98,183.53]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}]}]},{"ddd":0,"ind":4,"ty":0,"nm":"","ln":"precomp_zYkOCouISjVu5d5nn5HrS4","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"ziKMqpsDKcUN3Bvdg7UKx"},{"ddd":0,"ind":5,"ty":0,"nm":"","ln":"precomp_Fnqs1QdqqnXn0KX5vfOUk5","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"MMbJbp671fhpnijWMEBHr"}]},{"id":"RBIN7Z735nugzQacxcYC2","layers":[{"ddd":0,"ind":2,"ty":0,"nm":"","ln":"precomp_R_IXdwwN3vNlbMEF5Ihvg2","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":1,"k":[{"t":0,"s":[0],"h":1},{"t":0,"s":[-45],"i":{"x":0,"y":1},"o":{"x":0.5,"y":0}},{"t":0,"s":[-45],"h":1},{"t":63,"s":[-45],"i":{"x":0,"y":1},"o":{"x":0.5,"y":0}},{"t":124,"s":[0],"h":1}]},"s":{"a":1,"k":[{"t":0,"s":[100,100],"h":1},{"t":0,"s":[0,0],"i":{"x":0,"y":1},"o":{"x":0.5,"y":0}},{"t":0,"s":[0,0],"h":1},{"t":63,"s":[0,0],"i":{"x":0,"y":1},"o":{"x":0.5,"y":0}},{"t":124,"s":[100,100],"h":1}]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"8qJUEUPyQOmvqeiL8E33b"}]},{"id":"p__9MXcIRLhF15ixTF4mm","layers":[{"ddd":0,"ind":9,"ty":4,"nm":"","ln":"67-IEEmLj_jVXOXLSjv009","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[100,0],[0,100],[-100,0],[0,-100],[100,0]],"i":[[0,0],[55.23,0],[0,55.23],[-55.23,0],[0,-55.23]],"o":[[0,55.23],[-55.23,0],[0,-55.23],[55.23,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[100,0],[100,0],[100,0],[100,0],[100,0]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"fl","hd":false,"bm":0,"c":{"a":0,"k":[0,0,0]},"r":1,"o":{"a":0,"k":100}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]}]},{"id":"pXhzWvmkrPhE4mevlVqKs","layers":[]},{"id":"4mDDqwEnQDYdAWIVergxl","layers":[]},{"id":"NWtvgbPMwtcH_vk8xQd0k","layers":[{"ddd":0,"ind":8,"ty":0,"nm":"","ln":"precomp_GRQqqplbImYEcvwh6SJYE8","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"p__9MXcIRLhF15ixTF4mm"},{"ddd":0,"ind":10,"ty":0,"nm":"","ln":"precomp_IS0z3o7MEqhjimI9gArbo10","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"pXhzWvmkrPhE4mevlVqKs"},{"ddd":0,"ind":11,"ty":0,"nm":"","ln":"precomp_3TVhnVJ-0HEUm8MCSflL011","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"4mDDqwEnQDYdAWIVergxl"}]},{"id":"bBKV-rsOatp43kXq_ubAP","layers":[{"ddd":0,"ind":13,"ty":4,"nm":"","ln":"Xs4w8u6CAb1pGTt1ozCrm13","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[150,0],[0,150],[-150,0],[0,-150],[150,0]],"i":[[0,0],[82.84,0],[0,82.84],[-82.84,0],[0,-82.84]],"o":[[0,82.84],[-82.84,0],[0,-82.84],[82.84,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[150,0],[150,0],[150,0],[150,0],[150,0]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"st","hd":false,"bm":0,"c":{"a":1,"k":[{"t":0,"s":[0,0,0],"h":1},{"t":0,"s":[0,0,0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0,0,0],"h":1},{"t":51,"s":[0,0,0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":87,"s":[0,0,0],"h":1}]},"lc":1,"lj":1,"o":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":0,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[100],"h":1},{"t":51,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":87,"s":[100],"h":1}]},"w":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":0,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0],"h":1},{"t":51,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":87,"s":[100],"h":1}]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]},{"ddd":0,"ind":14,"ty":4,"nm":"","ln":"fMK8gsuyLfv8kjs0GhEVV14","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[150,0],[0,150],[-150,0],[0,-150],[150,0]],"i":[[0,0],[82.84,0],[0,82.84],[-82.84,0],[0,-82.84]],"o":[[0,82.84],[-82.84,0],[0,-82.84],[82.84,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[150,0],[150,0],[150,0],[150,0],[150,0]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"fl","hd":false,"bm":0,"c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":0}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]}]},{"id":"fR_HHhg4r9Z3jHrrmBOF_","layers":[{"ddd":0,"ind":16,"ty":4,"nm":"","ln":"pD5_CNKeCPUzssCl_oqQk16","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[300,0],[0,300],[-300,0],[0,-300],[300,-0.01]],"i":[[0,0],[165.68,0],[0,165.68],[-165.68,0],[0,-165.68]],"o":[[0,165.68],[-165.68,0],[0,-165.68],[165.68,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[300,-0.01],[300,-0.01],[300,-0.01],[300,-0.01],[300,-0.01]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"st","hd":false,"bm":0,"c":{"a":1,"k":[{"t":0,"s":[0,0,0],"h":1},{"t":0,"s":[0,0,0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0,0,0],"h":1},{"t":54,"s":[0,0,0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":90,"s":[0,0,0],"h":1}]},"lc":1,"lj":1,"o":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":0,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[100],"h":1},{"t":54,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":90,"s":[100],"h":1}]},"w":{"a":1,"k":[{"t":0,"s":[200],"h":1},{"t":0,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0],"h":1},{"t":54,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":90,"s":[200],"h":1}]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]},{"ddd":0,"ind":17,"ty":4,"nm":"","ln":"31U0no9YbIRV7RBcqXMLq17","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[300,0],[0,300],[-300,0],[0,-300],[300,-0.01]],"i":[[0,0],[165.68,0],[0,165.68],[-165.68,0],[0,-165.68]],"o":[[0,165.68],[-165.68,0],[0,-165.68],[165.68,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[300,-0.01],[300,-0.01],[300,-0.01],[300,-0.01],[300,-0.01]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"fl","hd":false,"bm":0,"c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":0}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]}]},{"id":"GxE232NK7SuoNwPkgRhjz","layers":[{"ddd":0,"ind":19,"ty":4,"nm":"","ln":"sDqi4dzaShBYAe6msE3-s19","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[600,0],[0,600],[-600,0.01],[-0.01,-600],[600,-0.01]],"i":[[0,0],[331.37,0],[0,331.37],[-331.37,0],[-0.01,-331.37]],"o":[[0,331.37],[-331.37,0],[0,-331.37],[331.37,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[600,-0.01],[600,-0.01],[600,-0.01],[600,-0.01],[600,-0.01]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"st","hd":false,"bm":0,"c":{"a":1,"k":[{"t":0,"s":[0,0,0],"h":1},{"t":0,"s":[0,0,0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0,0,0],"h":1},{"t":57,"s":[0,0,0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":93,"s":[0,0,0],"h":1}]},"lc":1,"lj":1,"o":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":0,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[100],"h":1},{"t":57,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":93,"s":[100],"h":1}]},"w":{"a":1,"k":[{"t":0,"s":[400],"h":1},{"t":0,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0],"h":1},{"t":57,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":93,"s":[400],"h":1}]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]},{"ddd":0,"ind":20,"ty":4,"nm":"","ln":"RQtU21AHPj19Md2kWKZwb20","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[600,0],[0,600],[-600,0.01],[-0.01,-600],[600,-0.01]],"i":[[0,0],[331.37,0],[0,331.37],[-331.37,0],[-0.01,-331.37]],"o":[[0,331.37],[-331.37,0],[0,-331.37],[331.37,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[600,-0.01],[600,-0.01],[600,-0.01],[600,-0.01],[600,-0.01]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"fl","hd":false,"bm":0,"c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":0}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]}]},{"id":"wFIhVHqyGhh2gFNgFXn5u","layers":[{"ddd":0,"ind":22,"ty":4,"nm":"","ln":"7wH1-Es39SGT2VbAUhcWV22","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[1200,0],[0.01,1200],[-1200,0.01],[-0.02,-1200],[1200,-0.02]],"i":[[0,0],[662.74,0],[0.01,662.74],[-662.74,0.01],[-0.01,-662.74]],"o":[[0,662.74],[-662.74,0],[-0.01,-662.74],[662.74,-0.01],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[1200,-0.02],[1200,-0.02],[1200,-0.02],[1200,-0.02],[1200,-0.02]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"st","hd":false,"bm":0,"c":{"a":1,"k":[{"t":0,"s":[0,0,0],"h":1},{"t":0,"s":[0,0,0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0,0,0],"h":1},{"t":60,"s":[0,0,0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":96,"s":[0,0,0],"h":1}]},"lc":1,"lj":1,"o":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":0,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[100],"h":1},{"t":60,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":96,"s":[100],"h":1}]},"w":{"a":1,"k":[{"t":0,"s":[800],"h":1},{"t":0,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0],"h":1},{"t":60,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":96,"s":[800],"h":1}]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]},{"ddd":0,"ind":23,"ty":4,"nm":"","ln":"5q-c2--_O_U2Mqa3zAlgx23","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[1200,0],[0.01,1200],[-1200,0.01],[-0.02,-1200],[1200,-0.02]],"i":[[0,0],[662.74,0],[0.01,662.74],[-662.74,0.01],[-0.01,-662.74]],"o":[[0,662.74],[-662.74,0],[-0.01,-662.74],[662.74,-0.01],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[1200,-0.02],[1200,-0.02],[1200,-0.02],[1200,-0.02],[1200,-0.02]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"fl","hd":false,"bm":0,"c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":0}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]}]},{"id":"xVgDJCd6Add0pw30WUKT0","layers":[]},{"id":"vpYGssmo2d4QEkeCJMX8b","layers":[]},{"id":"Tl00GHzD2aACKdJYC113w","layers":[{"ddd":0,"ind":7,"ty":0,"nm":"","ln":"precomp_CsMnQClD7","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":1,"k":[{"t":0,"s":[100,100],"h":1},{"t":0,"s":[0,0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0,0],"h":1},{"t":48,"s":[0,0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":84,"s":[100,100],"h":1}]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"NWtvgbPMwtcH_vk8xQd0k"},{"ddd":0,"ind":12,"ty":0,"nm":"","ln":"precomp_fl1A06cl12","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"bBKV-rsOatp43kXq_ubAP"},{"ddd":0,"ind":15,"ty":0,"nm":"","ln":"precomp_aX4MlTBA15","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"fR_HHhg4r9Z3jHrrmBOF_"},{"ddd":0,"ind":18,"ty":0,"nm":"","ln":"precomp_pPZPEB3l18","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"GxE232NK7SuoNwPkgRhjz"},{"ddd":0,"ind":21,"ty":0,"nm":"","ln":"precomp_P1E2mmnI21","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"wFIhVHqyGhh2gFNgFXn5u"},{"ddd":0,"ind":24,"ty":0,"nm":"","ln":"precomp_SKy1n0fZxgQ7ho13OiO2r24","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"xVgDJCd6Add0pw30WUKT0"},{"ddd":0,"ind":25,"ty":0,"nm":"","ln":"precomp_1KhDhZ_oDlEkM9NOOx25s25","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"vpYGssmo2d4QEkeCJMX8b"}]},{"id":"T_z3LRt2_itFo7GvsrBlM","layers":[{"ddd":0,"ind":29,"ty":4,"nm":"","ln":"GwyKD3IsVmKHvgTSXWxBg29","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[100,0],[0,100],[-100,0],[0,-100],[100,0]],"i":[[0,0],[55.23,0],[0,55.23],[-55.23,0],[0,-55.23]],"o":[[0,55.23],[-55.23,0],[0,-55.23],[55.23,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[100,0],[100,0],[100,0],[100,0],[100,0]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"fl","hd":false,"bm":0,"c":{"a":0,"k":[0.15,0.45,0.93]},"r":1,"o":{"a":0,"k":100}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]}]},{"id":"caklUhVCvaHNe3rWApFYj","layers":[]},{"id":"8QOW4ToZAdUBM_-mK5Rd8","layers":[]},{"id":"upDZqBPMLPBNNzjz6EsZC","layers":[{"ddd":0,"ind":28,"ty":0,"nm":"","ln":"precomp_mR8L_8aL8OpMkuXvyavdl28","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"T_z3LRt2_itFo7GvsrBlM"},{"ddd":0,"ind":30,"ty":0,"nm":"","ln":"precomp_C77KXaxK8wZB_LpxbwZem30","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"caklUhVCvaHNe3rWApFYj"},{"ddd":0,"ind":31,"ty":0,"nm":"","ln":"precomp_MVxInYF7-3u5twFbBUqQE31","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"8QOW4ToZAdUBM_-mK5Rd8"}]},{"id":"ToJ0jO5FL_qKcrAAlA0HC","layers":[{"ddd":0,"ind":33,"ty":4,"nm":"","ln":"VR45nawy7HKF_2ENBMMMj33","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[150,0],[0,150],[-150,0],[0,-150],[150,0]],"i":[[0,0],[82.84,0],[0,82.84],[-82.84,0],[0,-82.84]],"o":[[0,82.84],[-82.84,0],[0,-82.84],[82.84,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[150,0],[150,0],[150,0],[150,0],[150,0]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"st","hd":false,"bm":0,"c":{"a":1,"k":[{"t":0,"s":[0.15,0.45,0.93],"h":1},{"t":0,"s":[0.15,0.45,0.93],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0.15,0.45,0.93],"h":1},{"t":3,"s":[0.15,0.45,0.93],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":39,"s":[0.15,0.45,0.93],"h":1}]},"lc":1,"lj":1,"o":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":0,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[100],"h":1},{"t":3,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":39,"s":[100],"h":1}]},"w":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":0,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0],"h":1},{"t":3,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":39,"s":[100],"h":1}]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]},{"ddd":0,"ind":34,"ty":4,"nm":"","ln":"fh9SQL1vtEKSiP55gYwIM34","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[150,0],[0,150],[-150,0],[0,-150],[150,0]],"i":[[0,0],[82.84,0],[0,82.84],[-82.84,0],[0,-82.84]],"o":[[0,82.84],[-82.84,0],[0,-82.84],[82.84,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[150,0],[150,0],[150,0],[150,0],[150,0]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"fl","hd":false,"bm":0,"c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":0}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]}]},{"id":"1S7rN3dcGZbIUW63l-saM","layers":[{"ddd":0,"ind":36,"ty":4,"nm":"","ln":"se3ZC3UOUevXVHcey4Z2036","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[300,0],[0,300],[-300,0],[0,-300],[300,-0.01]],"i":[[0,0],[165.68,0],[0,165.68],[-165.68,0],[0,-165.68]],"o":[[0,165.68],[-165.68,0],[0,-165.68],[165.68,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[300,-0.01],[300,-0.01],[300,-0.01],[300,-0.01],[300,-0.01]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"st","hd":false,"bm":0,"c":{"a":1,"k":[{"t":0,"s":[0.15,0.45,0.93],"h":1},{"t":0,"s":[0.15,0.45,0.93],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0.15,0.45,0.93],"h":1},{"t":6,"s":[0.15,0.45,0.93],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":42,"s":[0.15,0.45,0.93],"h":1}]},"lc":1,"lj":1,"o":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":0,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[100],"h":1},{"t":6,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":42,"s":[100],"h":1}]},"w":{"a":1,"k":[{"t":0,"s":[200],"h":1},{"t":0,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0],"h":1},{"t":6,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":42,"s":[200],"h":1}]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]},{"ddd":0,"ind":37,"ty":4,"nm":"","ln":"gHAQhtZDjL1K7r_tjywuh37","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[300,0],[0,300],[-300,0],[0,-300],[300,-0.01]],"i":[[0,0],[165.68,0],[0,165.68],[-165.68,0],[0,-165.68]],"o":[[0,165.68],[-165.68,0],[0,-165.68],[165.68,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[300,-0.01],[300,-0.01],[300,-0.01],[300,-0.01],[300,-0.01]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"fl","hd":false,"bm":0,"c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":0}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]}]},{"id":"VTvqmBm84OwBufWhds1ay","layers":[{"ddd":0,"ind":39,"ty":4,"nm":"","ln":"bDEhEDMWbXVWJi7TZDSEY39","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[600,0],[0,600],[-600,0.01],[-0.01,-600],[600,-0.01]],"i":[[0,0],[331.37,0],[0,331.37],[-331.37,0],[-0.01,-331.37]],"o":[[0,331.37],[-331.37,0],[0,-331.37],[331.37,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[600,-0.01],[600,-0.01],[600,-0.01],[600,-0.01],[600,-0.01]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"st","hd":false,"bm":0,"c":{"a":1,"k":[{"t":0,"s":[0.15,0.45,0.93],"h":1},{"t":0,"s":[0.15,0.45,0.93],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0.15,0.45,0.93],"h":1},{"t":9,"s":[0.15,0.45,0.93],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":45,"s":[0.15,0.45,0.93],"h":1}]},"lc":1,"lj":1,"o":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":0,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[100],"h":1},{"t":9,"s":[100],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":45,"s":[100],"h":1}]},"w":{"a":1,"k":[{"t":0,"s":[400],"h":1},{"t":0,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":0,"s":[0],"h":1},{"t":9,"s":[0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":45,"s":[400],"h":1}]}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]},{"ddd":0,"ind":40,"ty":4,"nm":"","ln":"XVix6HapBVkT0xm_E5BPn40","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"sh","hd":false,"ix":0,"ks":{"a":0,"k":{"v":[[600,0],[0,600],[-600,0.01],[-0.01,-600],[600,-0.01]],"i":[[0,0],[331.37,0],[0,331.37],[-331.37,0],[-0.01,-331.37]],"o":[[0,331.37],[-331.37,0],[0,-331.37],[331.37,0],[0,0]]}}},{"ty":"sh","hd":false,"ix":1,"ks":{"a":0,"k":{"v":[[600,-0.01],[600,-0.01],[600,-0.01],[600,-0.01],[600,-0.01]],"i":[[0,0],[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0],[0,0]]}}},{"ty":"fl","hd":false,"bm":0,"c":{"a":0,"k":[1,1,1]},"r":1,"o":{"a":0,"k":0}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]}]},{"id":"HugSlUmQYQP5pA04RLXjk","layers":[]},{"id":"IpiyNtnh13wI4m9qGyH3T","layers":[]},{"id":"YEKe0SQfzl-4vrGH97B38","layers":[{"ddd":0,"ind":27,"ty":0,"nm":"","ln":"precomp_D63i1HEg27","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":1,"k":[{"t":0,"s":[100,100],"h":1},{"t":0,"s":[0,0],"i":{"x":0.25,"y":1},"o":{"x":0.25,"y":0.1}},{"t":36,"s":[100,100],"h":1}]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"upDZqBPMLPBNNzjz6EsZC"},{"ddd":0,"ind":32,"ty":0,"nm":"","ln":"precomp_1O5Vc2rS32","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"ToJ0jO5FL_qKcrAAlA0HC"},{"ddd":0,"ind":35,"ty":0,"nm":"","ln":"precomp_DNQQhrwD35","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"1S7rN3dcGZbIUW63l-saM"},{"ddd":0,"ind":38,"ty":0,"nm":"","ln":"precomp_PTVsgqc538","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"VTvqmBm84OwBufWhds1ay"},{"ddd":0,"ind":41,"ty":0,"nm":"","ln":"precomp_BNJz3Ruo-oxZg3j1qXC4-41","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"HugSlUmQYQP5pA04RLXjk"},{"ddd":0,"ind":42,"ty":0,"nm":"","ln":"precomp_-2mA_xgK9yhxzHGNQ1q3w42","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"IpiyNtnh13wI4m9qGyH3T"}]},{"id":"wO5ruENsgr95sZvoxf2bz","layers":[]},{"id":"WglsG8FIjfP-BcjIdQnCM","layers":[{"ddd":0,"ind":45,"ty":4,"nm":"","ln":"J6F5EUVkkPOKMZaA-XqQt45","sr":1,"ks":{"a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"ip":0,"op":123,"st":0,"bm":0,"shapes":[{"ty":"gr","hd":false,"bm":0,"it":[{"ty":"rc","hd":false,"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[1080,1920]}},{"ty":"fl","hd":false,"bm":0,"c":{"a":0,"k":[0,0,0]},"r":1,"o":{"a":0,"k":100}},{"ty":"tr","nm":"Transform","a":{"a":0,"k":[0,0]},"o":{"a":0,"k":100},"p":{"a":0,"k":[0,0]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}}],"np":0}]}]},{"id":"H86kji1shNbIr1iih2Dz2","layers":[{"ddd":0,"ind":1,"ty":0,"nm":"","ln":"precomp_6FW-apZ1cvo38581b1SQY1","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":1,"k":[{"t":0,"s":[100],"h":1},{"t":0,"s":[0],"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"t":0,"s":[0],"h":1},{"t":63,"s":[100],"i":{"x":1,"y":1},"o":{"x":0,"y":0}},{"t":63,"s":[100],"h":1}]},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"RBIN7Z735nugzQacxcYC2"},{"ddd":0,"ind":6,"ty":0,"nm":"","ln":"precomp_JG7CTZ316","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"Tl00GHzD2aACKdJYC113w"},{"ddd":0,"ind":26,"ty":0,"nm":"","ln":"precomp_V2xAiafH26","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"YEKe0SQfzl-4vrGH97B38"},{"ddd":0,"ind":43,"ty":0,"nm":"","ln":"precomp_uzhIE6hz3nT4z3VN-5BZr43","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"wO5ruENsgr95sZvoxf2bz"},{"ddd":0,"ind":44,"ty":0,"nm":"","ln":"precomp_Jy6yFoeT9DRF9O-Dg1V_444","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[50000,50000]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"WglsG8FIjfP-BcjIdQnCM"}]}],"ddd":0,"fr":60,"h":1920,"ip":0,"layers":[{"ddd":0,"ind":0,"ty":0,"nm":"","ln":"precomp_WGhsPayw0","sr":1,"ks":{"a":{"a":0,"k":[50000,50000]},"o":{"a":0,"k":100},"p":{"a":0,"k":[540,960]},"r":{"a":0,"k":0},"s":{"a":0,"k":[100,100]},"sk":{"a":0,"k":0},"sa":{"a":0,"k":0}},"ao":0,"w":100000,"h":100000,"ip":0,"op":123,"st":0,"bm":0,"refId":"H86kji1shNbIr1iih2Dz2"}],"meta":{"g":"https://jitter.video"},"nm":"Donuts-[remix]-[copy]","op":123,"v":"5.7.4","w":1080}
\ No newline at end of file
diff --git a/packages/hmssdk_flutter/example/ios/Gemfile.lock b/packages/hmssdk_flutter/example/ios/Gemfile.lock
index 3973c327d..2c203ea22 100644
--- a/packages/hmssdk_flutter/example/ios/Gemfile.lock
+++ b/packages/hmssdk_flutter/example/ios/Gemfile.lock
@@ -13,16 +13,16 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.3.0)
- aws-partitions (1.864.0)
- aws-sdk-core (3.190.0)
+ aws-partitions (1.878.0)
+ aws-sdk-core (3.190.2)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.8)
jmespath (~> 1, >= 1.6.1)
- aws-sdk-kms (1.74.0)
+ aws-sdk-kms (1.76.0)
aws-sdk-core (~> 3, >= 3.188.0)
aws-sigv4 (~> 1.1)
- aws-sdk-s3 (1.141.0)
+ aws-sdk-s3 (1.142.0)
aws-sdk-core (~> 3, >= 3.189.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.8)
@@ -38,10 +38,10 @@ GEM
declarative (0.0.20)
digest-crc (0.6.5)
rake (>= 12.0.0, < 14.0.0)
- domain_name (0.6.20231109)
+ domain_name (0.6.20240107)
dotenv (2.8.1)
emoji_regex (3.2.3)
- excon (0.105.0)
+ excon (0.109.0)
faraday (1.10.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
@@ -70,8 +70,8 @@ GEM
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday (~> 1.0)
- fastimage (2.2.7)
- fastlane (2.217.0)
+ fastimage (2.3.0)
+ fastlane (2.218.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@@ -98,7 +98,7 @@ GEM
mini_magick (>= 4.9.4, < 5.0.0)
multipart-post (>= 2.0.0, < 3.0.0)
naturally (~> 2.2)
- optparse (~> 0.1.1)
+ optparse (>= 0.1.1)
plist (>= 3.1.0, < 4.0.0)
rubyzip (>= 2.0.0, < 3.0.0)
security (= 0.1.3)
@@ -115,7 +115,7 @@ GEM
google-apis-firebaseappdistribution_v1 (~> 0.3.0)
fastlane-plugin-versioning (0.5.2)
gh_inspector (1.1.3)
- google-apis-androidpublisher_v3 (0.53.0)
+ google-apis-androidpublisher_v3 (0.54.0)
google-apis-core (>= 0.11.0, < 2.a)
google-apis-core (0.11.2)
addressable (~> 2.5, >= 2.5.1)
@@ -132,25 +132,25 @@ GEM
google-apis-core (>= 0.11.0, < 2.a)
google-apis-playcustomapp_v1 (0.13.0)
google-apis-core (>= 0.11.0, < 2.a)
- google-apis-storage_v1 (0.29.0)
+ google-apis-storage_v1 (0.31.0)
google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.6.1)
google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0)
- google-cloud-env (2.0.1)
+ google-cloud-env (2.1.0)
faraday (>= 1.0, < 3.a)
google-cloud-errors (1.3.1)
- google-cloud-storage (1.45.0)
+ google-cloud-storage (1.47.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
google-apis-iamcredentials_v1 (~> 0.1)
- google-apis-storage_v1 (~> 0.29.0)
+ google-apis-storage_v1 (~> 0.31.0)
google-cloud-core (~> 1.6)
googleauth (>= 0.16.2, < 2.a)
mini_mime (~> 1.0)
- googleauth (1.9.0)
+ googleauth (1.9.1)
faraday (>= 1.0, < 3.a)
- google-cloud-env (~> 2.0, >= 2.0.1)
+ google-cloud-env (~> 2.1)
jwt (>= 1.4, < 3.0)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
@@ -171,9 +171,9 @@ GEM
multipart-post (2.3.0)
nanaimo (0.3.0)
naturally (2.2.1)
- optparse (0.1.1)
+ optparse (0.4.0)
os (1.1.4)
- plist (3.7.0)
+ plist (3.7.1)
public_suffix (5.0.4)
rake (13.1.0)
representable (3.2.0)
@@ -199,7 +199,7 @@ GEM
unicode-display_width (>= 1.1.1, < 3)
trailblazer-option (0.1.2)
tty-cursor (0.7.1)
- tty-screen (0.8.1)
+ tty-screen (0.8.2)
tty-spinner (0.9.3)
tty-cursor (~> 0.7)
tzinfo (2.0.6)
diff --git a/packages/hmssdk_flutter/example/ios/Podfile.lock b/packages/hmssdk_flutter/example/ios/Podfile.lock
index f8bb6db68..928741223 100644
--- a/packages/hmssdk_flutter/example/ios/Podfile.lock
+++ b/packages/hmssdk_flutter/example/ios/Podfile.lock
@@ -97,14 +97,14 @@ PODS:
- HMSBroadcastExtensionSDK (0.0.9)
- HMSHLSPlayerSDK (0.0.2):
- HMSAnalyticsSDK (= 0.0.2)
- - HMSSDK (1.4.0):
+ - HMSSDK (1.4.1):
- HMSAnalyticsSDK (= 0.0.2)
- HMSWebRTC (= 1.0.5116)
- - hmssdk_flutter (1.9.5):
+ - hmssdk_flutter (1.9.6):
- Flutter
- HMSBroadcastExtensionSDK (= 0.0.9)
- HMSHLSPlayerSDK (= 0.0.2)
- - HMSSDK (= 1.4.0)
+ - HMSSDK (= 1.4.1)
- HMSWebRTC (1.0.5116)
- MTBBarcodeScanner (5.0.11)
- nanopb (2.30909.1):
@@ -235,8 +235,8 @@ SPEC CHECKSUMS:
HMSAnalyticsSDK: 4d2a88a729b1eb42f3d25f217c28937ec318a5b7
HMSBroadcastExtensionSDK: d80fe325f6c928bd8e5176290b5a4b7ae15d6fbb
HMSHLSPlayerSDK: 6a54ad4d12f3dc2270d1ecd24019d71282a4f6a3
- HMSSDK: 1bfd81ce70d61864cf2496018892d95335164b53
- hmssdk_flutter: b8e4641f6839d0492c447b338169a813cb443816
+ HMSSDK: 6a579cb806d4760cda149002150ff0beab03749b
+ hmssdk_flutter: 0b12e79b2f184fa3308fb65dade6e3b022d805c9
HMSWebRTC: ae54e9dd91b869051b283b43b14f57d43b7bf8e1
MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb
nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5
diff --git a/packages/hmssdk_flutter/example/ios/Runner/Info.plist b/packages/hmssdk_flutter/example/ios/Runner/Info.plist
index 7cec9b70f..0c03a60e5 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.107
+ 1.5.124
CFBundleSignature
????
CFBundleURLTypes
@@ -48,7 +48,7 @@
CFBundleVersion
- 407
+ 424
ITSAppUsesNonExemptEncryption
LSApplicationCategoryType
diff --git a/packages/hmssdk_flutter/example/lib/app_settings_bottom_sheet.dart b/packages/hmssdk_flutter/example/lib/app_settings_bottom_sheet.dart
index 978aeb86c..7186aecb3 100644
--- a/packages/hmssdk_flutter/example/lib/app_settings_bottom_sheet.dart
+++ b/packages/hmssdk_flutter/example/lib/app_settings_bottom_sheet.dart
@@ -17,8 +17,6 @@ class AppSettingsBottomSheet extends StatefulWidget {
}
class _AppSettingsBottomSheetState extends State {
- bool joinWithMutedAudio = false;
- bool joinWithMutedVideo = false;
bool skipPreview = false;
bool mirrorCamera = true;
bool showStats = false;
@@ -51,10 +49,6 @@ class _AppSettingsBottomSheetState extends State {
if (Platform.isAndroid && versions['android'] == null) {
throw const FormatException("android version not found");
}
- joinWithMutedAudio =
- await Utilities.getBoolData(key: 'join-with-muted-audio') ?? false;
- joinWithMutedVideo =
- await Utilities.getBoolData(key: 'join-with-muted-video') ?? false;
skipPreview = await Utilities.getBoolData(key: 'skip-preview') ?? false;
mirrorCamera = await Utilities.getBoolData(key: 'mirror-camera') ?? true;
showStats = await Utilities.getBoolData(key: 'show-stats') ?? false;
@@ -87,8 +81,6 @@ class _AppSettingsBottomSheetState extends State {
AppDebugConfig.isAudioMixerDisabled = isAudioMixerDisabled;
AppDebugConfig.isAutoSimulcast = isAutoSimulcast;
AppDebugConfig.isSoftwareDecoderDisabled = isSoftwareDecoderDisabled;
- AppDebugConfig.joinWithMutedAudio = joinWithMutedAudio;
- AppDebugConfig.joinWithMutedVideo = joinWithMutedVideo;
AppDebugConfig.mirrorCamera = mirrorCamera;
AppDebugConfig.showStats = showStats;
AppDebugConfig.skipPreview = skipPreview;
@@ -225,66 +217,6 @@ class _AppSettingsBottomSheetState extends State {
setState(() {})
}),
),
- ListTile(
- horizontalTitleGap: 2,
- enabled: false,
- contentPadding: EdgeInsets.zero,
- leading: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/mic_state_off.svg",
- fit: BoxFit.scaleDown,
- colorFilter:
- ColorFilter.mode(themeDefaultColor, BlendMode.srcIn),
- ),
- title: Text(
- "Join with muted audio",
- semanticsLabel: "fl_join_with_muted_audio",
- style: HMSTextStyle.setTextStyle(
- fontSize: 14,
- color: themeDefaultColor,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w600),
- ),
- trailing: CupertinoSwitch(
- activeColor: hmsdefaultColor,
- value: joinWithMutedAudio,
- onChanged: (value) => {
- joinWithMutedAudio = value,
- Utilities.saveBoolData(
- key: 'join-with-muted-audio', value: value),
- AppDebugConfig.joinWithMutedAudio = value,
- setState(() {})
- }),
- ),
- ListTile(
- horizontalTitleGap: 2,
- enabled: false,
- contentPadding: EdgeInsets.zero,
- leading: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/cam_state_off.svg",
- fit: BoxFit.scaleDown,
- colorFilter:
- ColorFilter.mode(themeDefaultColor, BlendMode.srcIn),
- ),
- title: Text(
- "Join with muted video",
- semanticsLabel: "fl_join_with_muted_video",
- style: HMSTextStyle.setTextStyle(
- fontSize: 14,
- color: themeDefaultColor,
- letterSpacing: 0.25,
- fontWeight: FontWeight.w600),
- ),
- trailing: CupertinoSwitch(
- activeColor: hmsdefaultColor,
- value: joinWithMutedVideo,
- onChanged: (value) => {
- joinWithMutedVideo = value,
- Utilities.saveBoolData(
- key: 'join-with-muted-video', value: value),
- AppDebugConfig.joinWithMutedVideo = value,
- setState(() {})
- }),
- ),
// ListTile(
// horizontalTitleGap: 2,
// enabled: false,
diff --git a/packages/hmssdk_flutter/example/lib/main.dart b/packages/hmssdk_flutter/example/lib/main.dart
index e8b1509ef..cf391ed08 100644
--- a/packages/hmssdk_flutter/example/lib/main.dart
+++ b/packages/hmssdk_flutter/example/lib/main.dart
@@ -13,9 +13,11 @@ import 'package:hms_room_kit/hms_room_kit.dart';
import 'package:hmssdk_flutter_example/app_settings_bottom_sheet.dart';
import 'package:hmssdk_flutter_example/qr_code_screen.dart';
import 'package:hmssdk_flutter_example/room_service.dart';
+import 'package:lottie/lottie.dart';
import 'package:provider/provider.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:uni_links/uni_links.dart';
+import 'package:uuid/uuid.dart';
bool _initialURILinkHandled = false;
StreamSubscription? _streamSubscription;
@@ -57,9 +59,11 @@ class HMSExampleApp extends StatefulWidget {
context.findAncestorStateOfType<_HMSExampleAppState>()!;
}
-class _HMSExampleAppState extends State {
+class _HMSExampleAppState extends State
+ with TickerProviderStateMixin {
ThemeMode _themeMode = ThemeMode.dark;
Uri? _currentURI;
+ late AnimationController _controller;
ThemeData _darkTheme = ThemeData(
bottomSheetTheme: BottomSheetThemeData(
@@ -88,6 +92,10 @@ class _HMSExampleAppState extends State {
_initURIHandler();
_incomingLinkHandler();
initDynamicLinks();
+ _controller = AnimationController(
+ duration: Duration(seconds: (5)),
+ vsync: this,
+ );
}
Future _initURIHandler() async {
@@ -173,9 +181,26 @@ class _HMSExampleAppState extends State {
@override
Widget build(BuildContext context) {
return MaterialApp(
- home: HomePage(
- deepLinkURL: _currentURI == null ? null : _currentURI.toString(),
- ),
+ home: Builder(builder: (context) {
+ return Lottie.asset(
+ 'assets/splash_asset.json',
+ controller: _controller,
+ animate: true,
+ onLoaded: (composition) {
+ _controller
+ ..duration = composition.duration
+ ..forward().whenComplete(() => Navigator.pushReplacement(
+ context,
+ MaterialPageRoute(
+ builder: (context) => HomePage(
+ deepLinkURL: _currentURI == null
+ ? null
+ : _currentURI.toString(),
+ )),
+ ));
+ },
+ );
+ }),
theme: _lightTheme,
darkTheme: _darkTheme,
themeMode: _themeMode,
@@ -196,6 +221,8 @@ class HomePage extends StatefulWidget {
class _HomePageState extends State {
TextEditingController meetingLinkController = TextEditingController();
+ Uuid? uuid;
+ String uuidString = "";
PackageInfo _packageInfo = PackageInfo(
appName: 'Unknown',
@@ -214,6 +241,12 @@ class _HomePageState extends State {
void getData() async {
String savedMeetingUrl = await Utilities.getStringData(key: 'meetingLink');
+ uuidString = await Utilities.getStringData(key: "uuid");
+ if (uuidString.isEmpty) {
+ uuid = Uuid();
+ uuidString = uuid!.v4();
+ Utilities.saveStringData(key: "uuid", value: uuidString);
+ }
if (widget.deepLinkURL == null && savedMeetingUrl.isNotEmpty) {
meetingLinkController.text = savedMeetingUrl;
} else {
@@ -295,7 +328,7 @@ class _HomePageState extends State {
: "Flutter User",
endPoints: endPoints,
userId:
- "user_flutter", // pass your custom unique user identifier here
+ uuidString, // pass your custom unique user identifier here
iOSScreenshareConfig: HMSIOSScreenshareConfig(
appGroup: "group.flutterhms",
preferredExtension:
@@ -529,8 +562,12 @@ class _HomePageState extends State {
onPressed: () async {
bool res = await Utilities.getCameraPermissions();
if (res) {
- Navigator.push(context,
- MaterialPageRoute(builder: (_) => QRCodeScreen()));
+ Navigator.push(
+ context,
+ MaterialPageRoute(
+ builder: (_) => QRCodeScreen(
+ uuidString: uuidString,
+ )));
}
},
child: Container(
diff --git a/packages/hmssdk_flutter/example/lib/qr_code_screen.dart b/packages/hmssdk_flutter/example/lib/qr_code_screen.dart
index 54a78eddc..9560d9853 100644
--- a/packages/hmssdk_flutter/example/lib/qr_code_screen.dart
+++ b/packages/hmssdk_flutter/example/lib/qr_code_screen.dart
@@ -6,7 +6,8 @@ import 'package:hmssdk_flutter_example/room_service.dart';
import 'package:qr_code_scanner/qr_code_scanner.dart';
class QRCodeScreen extends StatefulWidget {
- QRCodeScreen({Key? key}) : super(key: key);
+ final String uuidString;
+ QRCodeScreen({Key? key, required this.uuidString}) : super(key: key);
@override
State createState() => _QRCodeScreenState();
@@ -74,6 +75,8 @@ class _QRCodeScreenState extends State {
} else {
Constant.roomCode = scanData.code!.trim();
}
+ Utilities.saveStringData(
+ key: "meetingLink", value: scanData.code!.trim());
Navigator.of(context).pushReplacement(MaterialPageRoute(
builder: (_) => HMSPrebuilt(
roomCode: Constant.roomCode,
@@ -81,6 +84,7 @@ class _QRCodeScreenState extends State {
userName: AppDebugConfig.nameChangeOnPreview
? null
: "Flutter User",
+ userId: widget.uuidString,
endPoints: endPoints,
iOSScreenshareConfig: HMSIOSScreenshareConfig(
appGroup: "group.flutterhms",
diff --git a/packages/hmssdk_flutter/example/pubspec.lock b/packages/hmssdk_flutter/example/pubspec.lock
index 1f981838a..08aa8aaa8 100644
--- a/packages/hmssdk_flutter/example/pubspec.lock
+++ b/packages/hmssdk_flutter/example/pubspec.lock
@@ -286,15 +286,15 @@ packages:
path: "../../hms_room_kit"
relative: true
source: path
- version: "1.0.8"
+ version: "1.0.9"
hmssdk_flutter:
dependency: transitive
description:
name: hmssdk_flutter
- sha256: f61fb1ffcaf7296e0e2eeff9bc34d699baf9190136b8570a15cde61819cf3276
+ sha256: "112381755d47a639ef296295ace5b9d73267b89458f33ac767d1b6536a3fc898"
url: "https://pub.dev"
source: hosted
- version: "1.9.5"
+ version: "1.9.6"
http:
dependency: transitive
description:
@@ -315,10 +315,10 @@ packages:
dependency: transitive
description:
name: intl
- sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
+ sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
url: "https://pub.dev"
source: hosted
- version: "0.19.0"
+ version: "0.18.1"
js:
dependency: transitive
description:
@@ -336,7 +336,7 @@ packages:
source: hosted
version: "5.0.0"
lottie:
- dependency: transitive
+ dependency: "direct main"
description:
name: lottie
sha256: a93542cc2d60a7057255405f62252533f8e8956e7e06754955669fd32fb4b216
@@ -427,10 +427,10 @@ packages:
dependency: transitive
description:
name: path_provider_android
- sha256: e595b98692943b4881b219f0a9e3945118d3c16bd7e2813f98ec6e532d905f72
+ sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
url: "https://pub.dev"
source: hosted
- version: "2.2.1"
+ version: "2.2.2"
path_provider_foundation:
dependency: transitive
description:
@@ -752,10 +752,10 @@ packages:
dependency: transitive
description:
name: url_launcher_linux
- sha256: "9f2d390e096fdbe1e6e6256f97851e51afc2d9c423d3432f1d6a02a8a9a8b9fd"
+ sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811
url: "https://pub.dev"
source: hosted
- version: "3.1.0"
+ version: "3.1.1"
url_launcher_macos:
dependency: transitive
description:
@@ -784,18 +784,18 @@ packages:
dependency: transitive
description:
name: url_launcher_windows
- sha256: "7754a1ad30ee896b265f8d14078b0513a4dba28d358eabb9d5f339886f4a1adc"
+ sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
url: "https://pub.dev"
source: hosted
- version: "3.1.0"
+ version: "3.1.1"
uuid:
- dependency: transitive
+ dependency: "direct main"
description:
name: uuid
- sha256: df5a4d8f22ee4ccd77f8839ac7cb274ebc11ef9adcce8b92be14b797fe889921
+ sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f"
url: "https://pub.dev"
source: hosted
- version: "4.2.1"
+ version: "4.2.2"
vector_graphics:
dependency: transitive
description:
diff --git a/packages/hmssdk_flutter/example/pubspec.yaml b/packages/hmssdk_flutter/example/pubspec.yaml
index b152fd524..bf2a0a711 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.9.5
+version: 1.9.6
environment:
sdk: ">=2.16.0 <4.0.0"
@@ -15,6 +15,7 @@ dependencies:
hms_room_kit:
path: ../../hms_room_kit
+ lottie: ^2.7.0
firebase_crashlytics: 3.3.2
firebase_core: 2.13.1
firebase_performance: 0.9.2+2
@@ -24,6 +25,7 @@ dependencies:
url_launcher:
qr_code_scanner:
uni_links:
+ uuid:
dev_dependencies:
flutter_test:
diff --git a/packages/hmssdk_flutter/ios/Classes/Actions/HMSSessionStoreAction.swift b/packages/hmssdk_flutter/ios/Classes/Actions/HMSSessionStoreAction.swift
index 931d26c38..f400ede98 100644
--- a/packages/hmssdk_flutter/ios/Classes/Actions/HMSSessionStoreAction.swift
+++ b/packages/hmssdk_flutter/ios/Classes/Actions/HMSSessionStoreAction.swift
@@ -47,11 +47,43 @@ class HMSSessionStoreAction {
return
}
- if value is String? || value is NSNull {
- result(HMSResultExtension.toDictionary(true, value))
- } else {
- HMSErrorLogger.returnHMSException(#function, "Session metadata type is not compatible, Please use String? type while setting metadata", "Type Incompatibility Error", result)
- }
+ do{
+ let isValid = try JSONSerialization.isValidJSONObject(value)
+
+ if(isValid){
+ let jsonData = try JSONSerialization.data(withJSONObject: value, options: [])
+ if let jsonString = String(data: jsonData, encoding: .utf8){
+ result(HMSResultExtension.toDictionary(true, jsonString))
+ }else{
+ HMSErrorLogger.logError(#function, "Session metadata type is not compatible, Please use String? type while setting metadata", "Type Incompatibility Error")
+ result(HMSResultExtension.toDictionary(true, nil))
+ }
+ }
+ else{
+ if let intValue = value as? Int{
+ let stringValue = String(intValue)
+ result(HMSResultExtension.toDictionary(true, stringValue))
+ } else if let doubleValue = value as? Double{
+ let stringValue = String(doubleValue)
+ result(HMSResultExtension.toDictionary(true, stringValue))
+ } else if let stringValue = value as? String{
+ result(HMSResultExtension.toDictionary(true, stringValue))
+ } else if let boolValue = value as? Bool{
+ let stringValue = String(boolValue)
+ result(HMSResultExtension.toDictionary(true, stringValue))
+ } else if (value == nil || value is NSNull){
+ result(HMSResultExtension.toDictionary(true, nil))
+ }
+ else{
+ HMSErrorLogger.logError(#function, "Session metadata type is not compatible, Please use compatible type while setting metadata", "Type Incompatibility Error")
+ result(HMSResultExtension.toDictionary(true, nil))
+ }
+ }
+ }
+ catch{
+ HMSErrorLogger.logError(#function, "Session metadata type is not compatible, JSON parsing failed", "Type Incompatibility Error")
+ result(HMSResultExtension.toDictionary(true, nil))
+ }
}
@@ -80,7 +112,7 @@ class HMSSessionStoreAction {
if let error = error {
HMSErrorLogger.logError(#function, "Error in setting data: \(data ?? "null") for key: \(key) to the Session Store. Error: \(error.localizedDescription)", "Key Error")
- result(HMSErrorExtension.getError("Error in setting data: \(data ?? "null") for key: \(key) to the Session Store. Error: \(error.localizedDescription)"))
+ result(HMSErrorExtension.toDictionary(error))
return
}
result(nil)
diff --git a/packages/hmssdk_flutter/ios/Classes/Models/HMSRoomExtension.swift b/packages/hmssdk_flutter/ios/Classes/Models/HMSRoomExtension.swift
index 183c18650..cad828eb2 100644
--- a/packages/hmssdk_flutter/ios/Classes/Models/HMSRoomExtension.swift
+++ b/packages/hmssdk_flutter/ios/Classes/Models/HMSRoomExtension.swift
@@ -17,7 +17,7 @@ class HMSRoomExtension {
if let roomID = room.roomID {
dict["id"] = roomID
}
-
+
if let name = room.name {
dict["name"] = name
}
@@ -34,6 +34,7 @@ class HMSRoomExtension {
dict["peer_count"] = peerCount
}
+ dict["is_large"] = room.isLarge
var peers = [[String: Any]]()
room.peers.forEach { peers.append(HMSPeerExtension.toDictionary($0)) }
dict["peers"] = peers
diff --git a/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift b/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift
index 158e8d361..ef9e71cb5 100644
--- a/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift
+++ b/packages/hmssdk_flutter/ios/Classes/SwiftHmssdkFlutterPlugin.swift
@@ -544,10 +544,39 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene
var dict: [String: Any] = ["key": key]
- if value is String? || value is NSNull {
- dict["value"] = value
- } else {
- HMSErrorLogger.logError(#function, "Session metadata type is not compatible, Please use String? type while setting metadata", "Type Incompatibility Error")
+ do{
+ let isValid = try JSONSerialization.isValidJSONObject(value)
+ if(isValid){
+ let jsonData = try JSONSerialization.data(withJSONObject: value, options: [])
+ if let jsonString = String(data: jsonData, encoding: .utf8){
+ dict["value"] = jsonString
+ }else{
+ HMSErrorLogger.logError(#function, "Session metadata type is not compatible, Please use String? type while setting metadata", "Type Incompatibility Error")
+ dict["value"] = nil
+ }
+ }
+ else{
+ if let intValue = value as? Int{
+ let stringValue = String(intValue)
+ dict["value"] = stringValue
+ } else if let doubleValue = value as? Double{
+ let doubleValue = String(doubleValue)
+ dict["value"] = doubleValue
+ } else if let stringValue = value as? String{
+ dict["value"] = stringValue
+ } else if let boolValue = value as? Bool{
+ dict["value"] = String(boolValue)
+ } else if (value == nil || value is NSNull) {
+ dict["value"] = nil
+ }
+ else{
+ HMSErrorLogger.logError(#function, "Session metadata type is not compatible, Please use compatible type while setting metadata", "Type Incompatibility Error")
+ dict["value"] = nil
+ }
+ }
+ }
+ catch{
+ HMSErrorLogger.logError(#function, "Session metadata type is not compatible, JSON parsing failed", "Type Incompatibility Error")
dict["value"] = nil
}
@@ -806,8 +835,7 @@ public class SwiftHmssdkFlutterPlugin: NSObject, FlutterPlugin, HMSUpdateListene
}
/**
- [toggleAlwaysScreenOn] provides a way to keep the screen always ON
- when enabled.
+ [toggleAlwaysScreenOn] provides a way to keep the screen always ON when enabled.
*/
private func toggleAlwaysScreenOn(_ result: @escaping FlutterResult) {
UIApplication.shared.isIdleTimerDisabled = !UIApplication.shared.isIdleTimerDisabled
diff --git a/packages/hmssdk_flutter/lib/assets/sdk-versions.json b/packages/hmssdk_flutter/lib/assets/sdk-versions.json
index 17d0668de..3a03d19de 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.9.5",
- "ios": "1.4.0",
+ "flutter": "1.9.6",
+ "ios": "1.4.1",
"iOSBroadcastExtension": "0.0.9",
"iOSHLSPlayerSDK": "0.0.2",
- "android": "2.8.3"
+ "android": "2.8.5"
}
diff --git a/packages/hmssdk_flutter/lib/src/model/hms_room.dart b/packages/hmssdk_flutter/lib/src/model/hms_room.dart
index 38132cc6e..3671372d0 100644
--- a/packages/hmssdk_flutter/lib/src/model/hms_room.dart
+++ b/packages/hmssdk_flutter/lib/src/model/hms_room.dart
@@ -21,6 +21,7 @@ class HMSRoom {
String id;
String? name;
String? metaData;
+ bool isLarge;
HMSBrowserRecordingState? hmsBrowserRecordingState;
HMSRtmpStreamingState? hmsRtmpStreamingState;
HMSServerRecordingState? hmsServerRecordingState;
@@ -37,6 +38,7 @@ class HMSRoom {
{required this.id,
this.name,
required this.peers,
+ required this.isLarge,
this.metaData,
this.hmsServerRecordingState,
this.hmsRtmpStreamingState,
@@ -76,6 +78,7 @@ class HMSRoom {
hmshlsRecordingState: map["hls_recording_state"] != null
? HMSHLSRecordingState.fromMap(map["hls_recording_state"] as Map)
: null,
+ isLarge: map["is_large"],
id: map['id'],
name: map['name'],
peers: peers,
diff --git a/packages/hmssdk_flutter/lib/src/model/hms_session_store.dart b/packages/hmssdk_flutter/lib/src/model/hms_session_store.dart
index 0c8f2f380..ad11f709a 100644
--- a/packages/hmssdk_flutter/lib/src/model/hms_session_store.dart
+++ b/packages/hmssdk_flutter/lib/src/model/hms_session_store.dart
@@ -77,9 +77,9 @@ class HMSSessionStore {
///Refer: Read more about setSessionMetadataForKey [here](https://www.100ms.live/docs/flutter/v2/how-to-guides/interact-with-room/room/session-store#setting-a-value-for-a-specific-key)
Future setSessionMetadataForKey(
{required String key,
- required String? data,
+ required dynamic data,
HMSActionResultListener? hmsActionResultListener}) async {
- Map arguments = {
+ Map arguments = {
"key": key,
"data": data,
};
diff --git a/packages/hmssdk_flutter/pubspec.yaml b/packages/hmssdk_flutter/pubspec.yaml
index 5208094b9..e17f3f23c 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.9.5
+version: 1.9.6
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/hms-callkit-app/functions/package-lock.json b/sample apps/hms-callkit-app/functions/package-lock.json
index 470efca98..b94edf571 100644
--- a/sample apps/hms-callkit-app/functions/package-lock.json
+++ b/sample apps/hms-callkit-app/functions/package-lock.json
@@ -6,7 +6,7 @@
"": {
"name": "functions",
"dependencies": {
- "firebase-admin": "^10.0.2",
+ "firebase-admin": "^12.0.0",
"firebase-functions": "^3.18.0"
},
"devDependencies": {
@@ -52,239 +52,188 @@
"node": ">=14"
}
},
+ "node_modules/@firebase/app-check-interop-types": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@firebase/app-check-interop-types/-/app-check-interop-types-0.3.0.tgz",
+ "integrity": "sha512-xAxHPZPIgFXnI+vb4sbBjZcde7ZluzPPaSK7Lx3/nmuVk4TjZvnL8ONnkd4ERQKL8WePQySU+pRcWkh8rDf5Sg=="
+ },
"node_modules/@firebase/app-types": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz",
- "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==",
- "peer": true
+ "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q=="
},
"node_modules/@firebase/auth-interop-types": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.1.7.tgz",
- "integrity": "sha512-yA/dTveGGPcc85JP8ZE/KZqfGQyQTBCV10THdI8HTlP1GDvNrhr//J5jAt58MlsCOaO3XmC4DqScPBbtIsR/EA==",
- "peerDependencies": {
- "@firebase/app-types": "0.x",
- "@firebase/util": "1.x"
- }
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@firebase/auth-interop-types/-/auth-interop-types-0.2.1.tgz",
+ "integrity": "sha512-VOaGzKp65MY6P5FI84TfYKBXEPi6LmOCSMMzys6o2BN2LOsqy7pCuZCup7NYnfbk5OkkQKzvIfHOzTm0UDpkyg=="
},
"node_modules/@firebase/component": {
- "version": "0.5.21",
- "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.5.21.tgz",
- "integrity": "sha512-12MMQ/ulfygKpEJpseYMR0HunJdlsLrwx2XcEs40M18jocy2+spyzHHEwegN3x/2/BLFBjR5247Etmz0G97Qpg==",
+ "version": "0.6.4",
+ "resolved": "https://registry.npmjs.org/@firebase/component/-/component-0.6.4.tgz",
+ "integrity": "sha512-rLMyrXuO9jcAUCaQXCMjCMUsWrba5fzHlNK24xz5j2W6A/SRmK8mZJ/hn7V0fViLbxC0lPMtrK1eYzk6Fg03jA==",
"dependencies": {
- "@firebase/util": "1.7.3",
+ "@firebase/util": "1.9.3",
"tslib": "^2.1.0"
}
},
"node_modules/@firebase/database": {
- "version": "0.13.10",
- "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.13.10.tgz",
- "integrity": "sha512-KRucuzZ7ZHQsRdGEmhxId5jyM2yKsjsQWF9yv0dIhlxYg0D8rCVDZc/waoPKA5oV3/SEIoptF8F7R1Vfe7BCQA==",
- "dependencies": {
- "@firebase/auth-interop-types": "0.1.7",
- "@firebase/component": "0.5.21",
- "@firebase/logger": "0.3.4",
- "@firebase/util": "1.7.3",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@firebase/database/-/database-1.0.2.tgz",
+ "integrity": "sha512-8X6NBJgUQzDz0xQVaCISoOLINKat594N2eBbMR3Mu/MH/ei4WM+aAMlsNzngF22eljXu1SILP5G3evkyvsG3Ng==",
+ "dependencies": {
+ "@firebase/app-check-interop-types": "0.3.0",
+ "@firebase/auth-interop-types": "0.2.1",
+ "@firebase/component": "0.6.4",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
"faye-websocket": "0.11.4",
"tslib": "^2.1.0"
}
},
"node_modules/@firebase/database-compat": {
- "version": "0.2.10",
- "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.2.10.tgz",
- "integrity": "sha512-fK+IgUUqVKcWK/gltzDU+B1xauCOfY6vulO8lxoNTkcCGlSxuTtwsdqjGkFmgFRMYjXFWWJ6iFcJ/vXahzwCtA==",
- "dependencies": {
- "@firebase/component": "0.5.21",
- "@firebase/database": "0.13.10",
- "@firebase/database-types": "0.9.17",
- "@firebase/logger": "0.3.4",
- "@firebase/util": "1.7.3",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-1.0.2.tgz",
+ "integrity": "sha512-09ryJnXDvuycsxn8aXBzLhBTuCos3HEnCOBWY6hosxfYlNCGnLvG8YMlbSAt5eNhf7/00B095AEfDsdrrLjxqA==",
+ "dependencies": {
+ "@firebase/component": "0.6.4",
+ "@firebase/database": "1.0.2",
+ "@firebase/database-types": "1.0.0",
+ "@firebase/logger": "0.4.0",
+ "@firebase/util": "1.9.3",
"tslib": "^2.1.0"
}
},
"node_modules/@firebase/database-types": {
- "version": "0.9.17",
- "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-0.9.17.tgz",
- "integrity": "sha512-YQm2tCZyxNtEnlS5qo5gd2PAYgKCy69tUKwioGhApCFThW+mIgZs7IeYeJo2M51i4LCixYUl+CvnOyAnb/c3XA==",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@firebase/database-types/-/database-types-1.0.0.tgz",
+ "integrity": "sha512-SjnXStoE0Q56HcFgNQ+9SsmJc0c8TqGARdI/T44KXy+Ets3r6x/ivhQozT66bMnCEjJRywYoxNurRTMlZF8VNg==",
"dependencies": {
- "@firebase/app-types": "0.8.1",
- "@firebase/util": "1.7.3"
+ "@firebase/app-types": "0.9.0",
+ "@firebase/util": "1.9.3"
}
},
- "node_modules/@firebase/database-types/node_modules/@firebase/app-types": {
- "version": "0.8.1",
- "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.8.1.tgz",
- "integrity": "sha512-p75Ow3QhB82kpMzmOntv866wH9eZ3b4+QbUY+8/DA5Zzdf1c8Nsk8B7kbFpzJt4wwHMdy5LTF5YUnoTc1JiWkw=="
- },
"node_modules/@firebase/logger": {
- "version": "0.3.4",
- "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.3.4.tgz",
- "integrity": "sha512-hlFglGRgZEwoyClZcGLx/Wd+zoLfGmbDkFx56mQt/jJ0XMbfPqwId1kiPl0zgdWZX+D8iH+gT6GuLPFsJWgiGw==",
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/@firebase/logger/-/logger-0.4.0.tgz",
+ "integrity": "sha512-eRKSeykumZ5+cJPdxxJRgAC3G5NknY2GwEbKfymdnXtnT0Ucm4pspfR6GT4MUQEDuJwRVbVcSx85kgJulMoFFA==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/@firebase/util": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.7.3.tgz",
- "integrity": "sha512-wxNqWbqokF551WrJ9BIFouU/V5SL1oYCGx1oudcirdhadnQRFH5v1sjgGL7cUV/UsekSycygphdrF2lxBxOYKg==",
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz",
+ "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==",
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/@google-cloud/firestore": {
- "version": "4.15.1",
- "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-4.15.1.tgz",
- "integrity": "sha512-2PWsCkEF1W02QbghSeRsNdYKN1qavrHBP3m72gPDMHQSYrGULOaTi7fSJquQmAtc4iPVB2/x6h80rdLHTATQtA==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/@google-cloud/firestore/-/firestore-7.1.0.tgz",
+ "integrity": "sha512-kkTC0Sb9r2lONuFF8Tr2wFfBfk0DT1/EKcTKOhsuoXUVClv3jCqGYVPtHgQsHFjdOsubS+tx9G5D5WG+obB2DA==",
"optional": true,
"dependencies": {
"fast-deep-equal": "^3.1.1",
"functional-red-black-tree": "^1.0.1",
- "google-gax": "^2.24.1",
- "protobufjs": "^6.8.6"
+ "google-gax": "^4.0.4",
+ "protobufjs": "^7.2.5"
},
"engines": {
- "node": ">=10.10.0"
+ "node": ">=14.0.0"
}
},
"node_modules/@google-cloud/paginator": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-3.0.7.tgz",
- "integrity": "sha512-jJNutk0arIQhmpUUQJPJErsojqo834KcyB6X7a1mxuic8i1tKXxde8E69IZxNZawRIlZdIK2QY4WALvlK5MzYQ==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.0.tgz",
+ "integrity": "sha512-87aeg6QQcEPxGCOthnpUjvw4xAZ57G7pL8FS0C4e/81fr3FjkpUpibf1s2v5XGyGhUVGF4Jfg7yEcxqn2iUw1w==",
"optional": true,
"dependencies": {
"arrify": "^2.0.0",
"extend": "^3.0.2"
},
"engines": {
- "node": ">=10"
+ "node": ">=14.0.0"
}
},
"node_modules/@google-cloud/projectify": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-2.1.1.tgz",
- "integrity": "sha512-+rssMZHnlh0twl122gXY4/aCrk0G1acBqkHFfYddtsqpYXGxA29nj9V5V9SfC+GyOG00l650f6lG9KL+EpFEWQ==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz",
+ "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==",
"optional": true,
"engines": {
- "node": ">=10"
+ "node": ">=14.0.0"
}
},
"node_modules/@google-cloud/promisify": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-2.0.4.tgz",
- "integrity": "sha512-j8yRSSqswWi1QqUGKVEKOG03Q7qOoZP6/h2zN2YO+F5h2+DHU0bSrHCK9Y7lo2DI9fBd8qGAw795sf+3Jva4yA==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz",
+ "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==",
"optional": true,
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/@google-cloud/storage": {
- "version": "5.20.5",
- "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.20.5.tgz",
- "integrity": "sha512-lOs/dCyveVF8TkVFnFSF7IGd0CJrTm91qiK6JLu+Z8qiT+7Ag0RyVhxZIWkhiACqwABo7kSHDm8FdH8p2wxSSw==",
+ "version": "7.7.0",
+ "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-7.7.0.tgz",
+ "integrity": "sha512-EMCEY+6JiIkx7Dt8NXVGGjy1vRdSGdHkoqZoqjJw7cEBkT7ZkX0c7puedfn1MamnzW5SX4xoa2jVq5u7OWBmkQ==",
"optional": true,
"dependencies": {
- "@google-cloud/paginator": "^3.0.7",
- "@google-cloud/projectify": "^2.0.0",
- "@google-cloud/promisify": "^2.0.0",
+ "@google-cloud/paginator": "^5.0.0",
+ "@google-cloud/projectify": "^4.0.0",
+ "@google-cloud/promisify": "^4.0.0",
"abort-controller": "^3.0.0",
- "arrify": "^2.0.0",
"async-retry": "^1.3.3",
"compressible": "^2.0.12",
- "configstore": "^5.0.0",
"duplexify": "^4.0.0",
"ent": "^2.2.0",
- "extend": "^3.0.2",
- "gaxios": "^4.0.0",
- "google-auth-library": "^7.14.1",
- "hash-stream-validation": "^0.2.2",
+ "fast-xml-parser": "^4.3.0",
+ "gaxios": "^6.0.2",
+ "google-auth-library": "^9.0.0",
"mime": "^3.0.0",
"mime-types": "^2.0.8",
"p-limit": "^3.0.1",
- "pumpify": "^2.0.0",
- "retry-request": "^4.2.2",
- "stream-events": "^1.0.4",
- "teeny-request": "^7.1.3",
- "uuid": "^8.0.0",
- "xdg-basedir": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/@grpc/grpc-js": {
- "version": "1.6.12",
- "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.6.12.tgz",
- "integrity": "sha512-JmvQ03OTSpVd9JTlj/K3IWHSz4Gk/JMLUTtW7Zb0KvO1LcOYGATh5cNuRYzCAeDR3O8wq+q8FZe97eO9MBrkUw==",
- "optional": true,
- "dependencies": {
- "@grpc/proto-loader": "^0.7.0",
- "@types/node": ">=12.12.47"
+ "retry-request": "^7.0.0",
+ "teeny-request": "^9.0.0",
+ "uuid": "^8.0.0"
},
"engines": {
- "node": "^8.13.0 || >=10.10.0"
+ "node": ">=14"
}
},
- "node_modules/@grpc/grpc-js/node_modules/@grpc/proto-loader": {
- "version": "0.7.4",
- "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.4.tgz",
- "integrity": "sha512-MnWjkGwqQ3W8fx94/c1CwqLsNmHHv2t0CFn+9++6+cDphC1lolpg9M2OU0iebIjK//pBNX9e94ho+gjx6vz39w==",
+ "node_modules/@google-cloud/storage/node_modules/uuid": {
+ "version": "8.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
+ "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
"optional": true,
- "dependencies": {
- "@types/long": "^4.0.1",
- "lodash.camelcase": "^4.3.0",
- "long": "^4.0.0",
- "protobufjs": "^7.0.0",
- "yargs": "^16.2.0"
- },
"bin": {
- "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
- },
- "engines": {
- "node": ">=6"
+ "uuid": "dist/bin/uuid"
}
},
- "node_modules/@grpc/grpc-js/node_modules/protobufjs": {
- "version": "7.2.2",
- "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.2.tgz",
- "integrity": "sha512-++PrQIjrom+bFDPpfmqXfAGSQs40116JRrqqyf53dymUMvvb5d/LMRyicRoF1AUKoXVS1/IgJXlEgcpr4gTF3Q==",
- "hasInstallScript": true,
+ "node_modules/@grpc/grpc-js": {
+ "version": "1.9.13",
+ "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.9.13.tgz",
+ "integrity": "sha512-OEZZu9v9AA+7/tghMDE8o5DAMD5THVnwSqDWuh7PPYO5287rTyqy0xEHT6/e4pbqSrhyLPdQFsam4TwFQVVIIw==",
"optional": true,
"dependencies": {
- "@protobufjs/aspromise": "^1.1.2",
- "@protobufjs/base64": "^1.1.2",
- "@protobufjs/codegen": "^2.0.4",
- "@protobufjs/eventemitter": "^1.1.0",
- "@protobufjs/fetch": "^1.1.0",
- "@protobufjs/float": "^1.0.2",
- "@protobufjs/inquire": "^1.1.0",
- "@protobufjs/path": "^1.1.2",
- "@protobufjs/pool": "^1.1.0",
- "@protobufjs/utf8": "^1.1.0",
- "@types/node": ">=13.7.0",
- "long": "^5.0.0"
+ "@grpc/proto-loader": "^0.7.8",
+ "@types/node": ">=12.12.47"
},
"engines": {
- "node": ">=12.0.0"
+ "node": "^8.13.0 || >=10.10.0"
}
},
- "node_modules/@grpc/grpc-js/node_modules/protobufjs/node_modules/long": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/long/-/long-5.2.1.tgz",
- "integrity": "sha512-GKSNGeNAtw8IryjjkhZxuKB3JzlcLTwjtiQCHKvqQet81I93kXslhDQruGI/QsddO83mcDToBVy7GqGS/zYf/A==",
- "optional": true
- },
"node_modules/@grpc/proto-loader": {
- "version": "0.6.13",
- "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz",
- "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==",
+ "version": "0.7.10",
+ "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.10.tgz",
+ "integrity": "sha512-CAqDfoaQ8ykFd9zqBDn4k6iWT9loLAlc2ETmDFS9JCD70gDcnA4L3AFEo2iV7KyAtAAHFW9ftq1Fz+Vsgq80RQ==",
"optional": true,
"dependencies": {
- "@types/long": "^4.0.1",
"lodash.camelcase": "^4.3.0",
- "long": "^4.0.0",
- "protobufjs": "^6.11.3",
- "yargs": "^16.2.0"
+ "long": "^5.0.0",
+ "protobufjs": "^7.2.4",
+ "yargs": "^17.7.2"
},
"bin": {
"proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
@@ -361,14 +310,6 @@
"node": ">= 8"
}
},
- "node_modules/@panva/asn1.js": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/@panva/asn1.js/-/asn1.js-1.0.0.tgz",
- "integrity": "sha512-UdkG3mLEqXgnlKsWanWcgb6dOjUzJ+XC5f+aWw30qrtjxeNUSfKX1cd5FBzOaXQumoe9nIqeZUvrRJS03HCCtw==",
- "engines": {
- "node": ">=10.13.0"
- }
- },
"node_modules/@protobufjs/aspromise": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
@@ -451,6 +392,12 @@
"@types/node": "*"
}
},
+ "node_modules/@types/caseless": {
+ "version": "0.12.5",
+ "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz",
+ "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==",
+ "optional": true
+ },
"node_modules/@types/connect": {
"version": "3.4.35",
"resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz",
@@ -488,9 +435,9 @@
}
},
"node_modules/@types/jsonwebtoken": {
- "version": "8.5.9",
- "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.9.tgz",
- "integrity": "sha512-272FMnFGzAVMGtu9tkr29hRL6bZj4Zs1KZNeHLnKqAvp06tAIcarTMwOh8/8bz4FmKRcMxZhZNeUAQsNLoiPhg==",
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.5.tgz",
+ "integrity": "sha512-VRLSGzik+Unrup6BsouBeHsf4d1hOEgYWTm/7Nmw1sXoN1+tRly/Gy/po3yeahnP4jfnQWWAhQAqcNfH7ngOkA==",
"dependencies": {
"@types/node": "*"
}
@@ -513,9 +460,12 @@
"integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
},
"node_modules/@types/node": {
- "version": "18.13.0",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.13.0.tgz",
- "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg=="
+ "version": "20.10.5",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.5.tgz",
+ "integrity": "sha512-nNPsNE65wjMxEKI93yOP+NPGGBJz/PoN3kZsVLee0XMiJolxSekEVD8wRwBUBqkwc7UWop0edW50yrCQW4CyRw==",
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
},
"node_modules/@types/qs": {
"version": "6.9.7",
@@ -527,6 +477,18 @@
"resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz",
"integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw=="
},
+ "node_modules/@types/request": {
+ "version": "2.48.12",
+ "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz",
+ "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==",
+ "optional": true,
+ "dependencies": {
+ "@types/caseless": "*",
+ "@types/node": "*",
+ "@types/tough-cookie": "*",
+ "form-data": "^2.5.0"
+ }
+ },
"node_modules/@types/serve-static": {
"version": "1.15.0",
"resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.0.tgz",
@@ -536,6 +498,12 @@
"@types/node": "*"
}
},
+ "node_modules/@types/tough-cookie": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
+ "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
+ "optional": true
+ },
"node_modules/abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
@@ -582,15 +550,15 @@
}
},
"node_modules/agent-base": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
- "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
+ "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
"optional": true,
"dependencies": {
- "debug": "4"
+ "debug": "^4.3.4"
},
"engines": {
- "node": ">= 6.0.0"
+ "node": ">= 14"
}
},
"node_modules/ajv": {
@@ -662,6 +630,12 @@
"retry": "0.13.1"
}
},
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "optional": true
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -689,9 +663,9 @@
"optional": true
},
"node_modules/bignumber.js": {
- "version": "9.1.1",
- "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.1.tgz",
- "integrity": "sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig==",
+ "version": "9.1.2",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz",
+ "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==",
"optional": true,
"engines": {
"node": "*"
@@ -794,14 +768,17 @@
}
},
"node_modules/cliui": {
- "version": "7.0.4",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
- "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"optional": true,
"dependencies": {
"string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
+ "strip-ansi": "^6.0.1",
"wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
}
},
"node_modules/color-convert": {
@@ -822,6 +799,18 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"devOptional": true
},
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "optional": true,
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
"node_modules/compressible": {
"version": "2.0.18",
"resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz",
@@ -840,23 +829,6 @@
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
"dev": true
},
- "node_modules/configstore": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz",
- "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==",
- "optional": true,
- "dependencies": {
- "dot-prop": "^5.2.0",
- "graceful-fs": "^4.1.2",
- "make-dir": "^3.0.0",
- "unique-string": "^2.0.0",
- "write-file-atomic": "^3.0.0",
- "xdg-basedir": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/content-disposition": {
"version": "0.5.4",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@@ -915,15 +887,6 @@
"node": ">= 8"
}
},
- "node_modules/crypto-random-string": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz",
- "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
- "optional": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -946,6 +909,15 @@
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
"dev": true
},
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "optional": true,
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
"node_modules/depd": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
@@ -975,18 +947,6 @@
"node": ">=6.0.0"
}
},
- "node_modules/dot-prop": {
- "version": "5.3.0",
- "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
- "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
- "optional": true,
- "dependencies": {
- "is-obj": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/duplexify": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz",
@@ -1338,11 +1298,27 @@
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
"dev": true
},
- "node_modules/fast-text-encoding": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.6.tgz",
- "integrity": "sha512-VhXlQgj9ioXCqGstD37E/HBeqEGV/qOD/kmbVG8h5xKBYvM1L3lR1Zn4555cQ8GkYbJa8aJSipLPndE1k6zK2w==",
- "optional": true
+ "node_modules/fast-xml-parser": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.3.2.tgz",
+ "integrity": "sha512-rmrXUXwbJedoXkStenj1kkljNF7ugn5ZjR9FJcwmCfcCbtOMDghPajbc+Tck6vE6F5XsDmx+Pr2le9fw8+pXBg==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/NaturalIntelligence"
+ },
+ {
+ "type": "paypal",
+ "url": "https://paypal.me/naturalintelligence"
+ }
+ ],
+ "optional": true,
+ "dependencies": {
+ "strnum": "^1.0.5"
+ },
+ "bin": {
+ "fxparser": "src/cli/cli.js"
+ }
},
"node_modules/fastq": {
"version": "1.15.0",
@@ -1423,25 +1399,25 @@
}
},
"node_modules/firebase-admin": {
- "version": "10.3.0",
- "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-10.3.0.tgz",
- "integrity": "sha512-A0wgMLEjyVyUE+heyMJYqHRkPVjpebhOYsa47RHdrTM4ltApcx8Tn86sUmjqxlfh09gNnILAm7a8q5+FmgBYpg==",
- "dependencies": {
- "@fastify/busboy": "^1.1.0",
- "@firebase/database-compat": "^0.2.0",
- "@firebase/database-types": "^0.9.7",
- "@types/node": ">=12.12.47",
- "jsonwebtoken": "^8.5.1",
- "jwks-rsa": "^2.0.2",
+ "version": "12.0.0",
+ "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-12.0.0.tgz",
+ "integrity": "sha512-wBrrSSsKV++/+O8E7O/C7/wL0nbG/x4Xv4yatz/+sohaZ+LsnWtYUcrd3gZutO86hLpDex7xgyrkKbgulmtVyQ==",
+ "dependencies": {
+ "@fastify/busboy": "^1.2.1",
+ "@firebase/database-compat": "^1.0.2",
+ "@firebase/database-types": "^1.0.0",
+ "@types/node": "^20.10.3",
+ "jsonwebtoken": "^9.0.0",
+ "jwks-rsa": "^3.0.1",
"node-forge": "^1.3.1",
- "uuid": "^8.3.2"
+ "uuid": "^9.0.0"
},
"engines": {
- "node": ">=12.7.0"
+ "node": ">=14"
},
"optionalDependencies": {
- "@google-cloud/firestore": "^4.15.1",
- "@google-cloud/storage": "^5.18.3"
+ "@google-cloud/firestore": "^7.1.0",
+ "@google-cloud/storage": "^7.7.0"
}
},
"node_modules/firebase-functions": {
@@ -1502,6 +1478,20 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
"dev": true
},
+ "node_modules/form-data": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz",
+ "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==",
+ "optional": true,
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 0.12"
+ }
+ },
"node_modules/forwarded": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -1536,32 +1526,31 @@
"optional": true
},
"node_modules/gaxios": {
- "version": "4.3.3",
- "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-4.3.3.tgz",
- "integrity": "sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA==",
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.1.1.tgz",
+ "integrity": "sha512-bw8smrX+XlAoo9o1JAksBwX+hi/RG15J+NTSxmNPIclKC3ZVK6C2afwY8OSdRvOK0+ZLecUJYtj2MmjOt3Dm0w==",
"optional": true,
"dependencies": {
- "abort-controller": "^3.0.0",
"extend": "^3.0.2",
- "https-proxy-agent": "^5.0.0",
+ "https-proxy-agent": "^7.0.1",
"is-stream": "^2.0.0",
- "node-fetch": "^2.6.7"
+ "node-fetch": "^2.6.9"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/gcp-metadata": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-4.3.1.tgz",
- "integrity": "sha512-x850LS5N7V1F3UcV7PoupzGsyD6iVwTVvsh3tbXfkctZnBnjW5yu5z1/3k3SehF7TyoTIe78rJs02GMMy+LF+A==",
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz",
+ "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==",
"optional": true,
"dependencies": {
- "gaxios": "^4.0.0",
+ "gaxios": "^6.0.0",
"json-bigint": "^1.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/get-caller-file": {
@@ -1634,73 +1623,44 @@
}
},
"node_modules/google-auth-library": {
- "version": "7.14.1",
- "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.14.1.tgz",
- "integrity": "sha512-5Rk7iLNDFhFeBYc3s8l1CqzbEBcdhwR193RlD4vSNFajIcINKI8W8P0JLmBpwymHqqWbX34pJDQu39cSy/6RsA==",
+ "version": "9.4.1",
+ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.4.1.tgz",
+ "integrity": "sha512-Chs7cuzDuav8W/BXOoRgSXw4u0zxYtuqAHETDR5Q6dG1RwNwz7NUKjsDDHAsBV3KkiiJBtJqjbzy1XU1L41w1g==",
"optional": true,
"dependencies": {
- "arrify": "^2.0.0",
"base64-js": "^1.3.0",
"ecdsa-sig-formatter": "^1.0.11",
- "fast-text-encoding": "^1.0.0",
- "gaxios": "^4.0.0",
- "gcp-metadata": "^4.2.0",
- "gtoken": "^5.0.4",
- "jws": "^4.0.0",
- "lru-cache": "^6.0.0"
+ "gaxios": "^6.1.1",
+ "gcp-metadata": "^6.1.0",
+ "gtoken": "^7.0.0",
+ "jws": "^4.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
"node_modules/google-gax": {
- "version": "2.30.5",
- "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.30.5.tgz",
- "integrity": "sha512-Jey13YrAN2hfpozHzbtrwEfEHdStJh1GwaQ2+Akh1k0Tv/EuNVSuBtHZoKSBm5wBMvNsxTsEIZ/152NrYyZgxQ==",
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.0.5.tgz",
+ "integrity": "sha512-yLoYtp4zE+8OQA74oBEbNkbzI6c95W01JSL7RqC8XERKpRvj3ytZp1dgnbA6G9aRsc8pZB25xWYBcCmrbYOEhA==",
"optional": true,
"dependencies": {
- "@grpc/grpc-js": "~1.6.0",
- "@grpc/proto-loader": "^0.6.12",
+ "@grpc/grpc-js": "~1.9.6",
+ "@grpc/proto-loader": "^0.7.0",
"@types/long": "^4.0.0",
"abort-controller": "^3.0.0",
"duplexify": "^4.0.0",
- "fast-text-encoding": "^1.0.3",
- "google-auth-library": "^7.14.0",
- "is-stream-ended": "^0.1.4",
+ "google-auth-library": "^9.0.0",
"node-fetch": "^2.6.1",
"object-hash": "^3.0.0",
- "proto3-json-serializer": "^0.1.8",
- "protobufjs": "6.11.3",
- "retry-request": "^4.0.0"
- },
- "bin": {
- "compileProtos": "build/tools/compileProtos.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/google-p12-pem": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/google-p12-pem/-/google-p12-pem-3.1.4.tgz",
- "integrity": "sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg==",
- "optional": true,
- "dependencies": {
- "node-forge": "^1.3.1"
- },
- "bin": {
- "gp12-pem": "build/src/bin/gp12-pem.js"
+ "proto3-json-serializer": "^2.0.0",
+ "protobufjs": "7.2.5",
+ "retry-request": "^7.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
}
},
- "node_modules/graceful-fs": {
- "version": "4.2.10",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
- "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
- "optional": true
- },
"node_modules/grapheme-splitter": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
@@ -1708,17 +1668,16 @@
"dev": true
},
"node_modules/gtoken": {
- "version": "5.3.2",
- "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-5.3.2.tgz",
- "integrity": "sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.0.1.tgz",
+ "integrity": "sha512-KcFVtoP1CVFtQu0aSk3AyAt2og66PFhZAlkUOuWKwzMLoulHXG5W5wE5xAnHb+yl3/wEFoqGW7/cDGMU8igDZQ==",
"optional": true,
"dependencies": {
- "gaxios": "^4.0.0",
- "google-p12-pem": "^3.1.3",
+ "gaxios": "^6.0.0",
"jws": "^4.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=14.0.0"
}
},
"node_modules/has": {
@@ -1752,12 +1711,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/hash-stream-validation": {
- "version": "0.2.4",
- "resolved": "https://registry.npmjs.org/hash-stream-validation/-/hash-stream-validation-0.2.4.tgz",
- "integrity": "sha512-Gjzu0Xn7IagXVkSu9cSFuK1fqzwtLwFhNhVL8IFJijRNMgUttFbBSIAzKuSIrsFMO1+g1RlsoN49zPIbwPDMGQ==",
- "optional": true
- },
"node_modules/http-errors": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz",
@@ -1792,17 +1745,29 @@
"node": ">= 6"
}
},
+ "node_modules/http-proxy-agent/node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "optional": true,
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
"node_modules/https-proxy-agent": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
- "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==",
"optional": true,
"dependencies": {
- "agent-base": "6",
+ "agent-base": "^7.0.2",
"debug": "4"
},
"engines": {
- "node": ">= 6"
+ "node": ">= 14"
}
},
"node_modules/iconv-lite": {
@@ -1845,7 +1810,7 @@
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
- "devOptional": true,
+ "dev": true,
"engines": {
"node": ">=0.8.19"
}
@@ -1903,15 +1868,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/is-obj": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
- "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
- "optional": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/is-path-inside": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
@@ -1933,18 +1889,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/is-stream-ended": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/is-stream-ended/-/is-stream-ended-0.1.4.tgz",
- "integrity": "sha512-xj0XPvmr7bQFTvirqnFr50o0hQIh6ZItDqloxt5aJrR4NQsYeSsyFQERYGCAzfindAcnKjINnwEEgLx4IqVzQw==",
- "optional": true
- },
- "node_modules/is-typedarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
- "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==",
- "optional": true
- },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -1952,15 +1896,9 @@
"dev": true
},
"node_modules/jose": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.6.tgz",
- "integrity": "sha512-FVoPY7SflDodE4lknJmbAHSUjLCzE2H1F6MS0RYKMQ8SR+lNccpMf8R4eqkNYyyUjR5qZReOzZo5C5YiHOCjjg==",
- "dependencies": {
- "@panva/asn1.js": "^1.0.0"
- },
- "engines": {
- "node": ">=10.13.0 < 13 || >=13.7.0"
- },
+ "version": "4.15.4",
+ "resolved": "https://registry.npmjs.org/jose/-/jose-4.15.4.tgz",
+ "integrity": "sha512-W+oqK4H+r5sITxfxpSU+MMdr/YSWGvgZMQDIsNoBDGGy4i7GBPTtvFKibQzW06n3U3TqHjhvBJsirShsEJ6eeQ==",
"funding": {
"url": "https://github.com/sponsors/panva"
}
@@ -2009,9 +1947,9 @@
"dev": true
},
"node_modules/jsonwebtoken": {
- "version": "8.5.1",
- "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
- "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.2.tgz",
+ "integrity": "sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==",
"dependencies": {
"jws": "^3.2.2",
"lodash.includes": "^4.3.0",
@@ -2022,11 +1960,11 @@
"lodash.isstring": "^4.0.1",
"lodash.once": "^4.0.0",
"ms": "^2.1.1",
- "semver": "^5.6.0"
+ "semver": "^7.5.4"
},
"engines": {
- "node": ">=4",
- "npm": ">=1.4.28"
+ "node": ">=12",
+ "npm": ">=6"
}
},
"node_modules/jsonwebtoken/node_modules/jwa": {
@@ -2060,25 +1998,25 @@
}
},
"node_modules/jwks-rsa": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.1.5.tgz",
- "integrity": "sha512-IODtn1SwEm7n6GQZnQLY0oxKDrMh7n/jRH1MzE8mlxWMrh2NnMyOsXTebu8vJ1qCpmuTJcL4DdiE0E4h8jnwsA==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-3.1.0.tgz",
+ "integrity": "sha512-v7nqlfezb9YfHHzYII3ef2a2j1XnGeSE/bK3WfumaYCqONAIstJbrEGapz4kadScZzEt7zYCN7bucj8C0Mv/Rg==",
"dependencies": {
- "@types/express": "^4.17.14",
- "@types/jsonwebtoken": "^8.5.9",
+ "@types/express": "^4.17.17",
+ "@types/jsonwebtoken": "^9.0.2",
"debug": "^4.3.4",
- "jose": "^2.0.6",
+ "jose": "^4.14.6",
"limiter": "^1.1.5",
- "lru-memoizer": "^2.1.4"
+ "lru-memoizer": "^2.2.0"
},
"engines": {
- "node": ">=10 < 13 || >=14"
+ "node": ">=14"
}
},
"node_modules/jwks-rsa/node_modules/@types/express": {
- "version": "4.17.17",
- "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.17.tgz",
- "integrity": "sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==",
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz",
+ "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==",
"dependencies": {
"@types/body-parser": "*",
"@types/express-serve-static-core": "^4.17.33",
@@ -2187,21 +2125,18 @@
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg=="
},
"node_modules/long": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz",
- "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==",
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
+ "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==",
"optional": true
},
"node_modules/lru-cache": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
- "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
- "optional": true,
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz",
+ "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==",
"dependencies": {
- "yallist": "^4.0.0"
- },
- "engines": {
- "node": ">=10"
+ "pseudomap": "^1.0.1",
+ "yallist": "^2.0.0"
}
},
"node_modules/lru-memoizer": {
@@ -2213,44 +2148,6 @@
"lru-cache": "~4.0.0"
}
},
- "node_modules/lru-memoizer/node_modules/lru-cache": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.0.2.tgz",
- "integrity": "sha512-uQw9OqphAGiZhkuPlpFGmdTU2tEuhxTourM/19qGJrxBPHAr/f8BT1a0i/lOclESnGatdJG/UCkP9kZB/Lh1iw==",
- "dependencies": {
- "pseudomap": "^1.0.1",
- "yallist": "^2.0.0"
- }
- },
- "node_modules/lru-memoizer/node_modules/yallist": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
- "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
- },
- "node_modules/make-dir": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
- "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
- "optional": true,
- "dependencies": {
- "semver": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/make-dir/node_modules/semver": {
- "version": "6.3.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
- "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
- "optional": true,
- "bin": {
- "semver": "bin/semver.js"
- }
- },
"node_modules/media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
@@ -2515,18 +2412,21 @@
}
},
"node_modules/proto3-json-serializer": {
- "version": "0.1.9",
- "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.9.tgz",
- "integrity": "sha512-A60IisqvnuI45qNRygJjrnNjX2TMdQGMY+57tR3nul3ZgO2zXkR9OGR8AXxJhkqx84g0FTnrfi3D5fWMSdANdQ==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.0.tgz",
+ "integrity": "sha512-FB/YaNrpiPkyQNSNPilpn8qn0KdEfkgmJ9JP93PQyF/U4bAiXY5BiUdDhiDO4S48uSQ6AesklgVlrKiqZPzegw==",
"optional": true,
"dependencies": {
- "protobufjs": "^6.11.2"
+ "protobufjs": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=14.0.0"
}
},
"node_modules/protobufjs": {
- "version": "6.11.3",
- "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz",
- "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==",
+ "version": "7.2.5",
+ "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.2.5.tgz",
+ "integrity": "sha512-gGXRSXvxQ7UiPgfw8gevrfRWcTlSbOFg+p/N+JVJEK5VhueL2miT6qTymqAmjr1Q5WbOCyJbyrk6JfWKwlFn6A==",
"hasInstallScript": true,
"optional": true,
"dependencies": {
@@ -2540,13 +2440,11 @@
"@protobufjs/path": "^1.1.2",
"@protobufjs/pool": "^1.1.0",
"@protobufjs/utf8": "^1.1.0",
- "@types/long": "^4.0.1",
"@types/node": ">=13.7.0",
- "long": "^4.0.0"
+ "long": "^5.0.0"
},
- "bin": {
- "pbjs": "bin/pbjs",
- "pbts": "bin/pbts"
+ "engines": {
+ "node": ">=12.0.0"
}
},
"node_modules/proxy-addr": {
@@ -2566,27 +2464,6 @@
"resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
"integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ=="
},
- "node_modules/pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "optional": true,
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
- "node_modules/pumpify": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz",
- "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==",
- "optional": true,
- "dependencies": {
- "duplexify": "^4.1.1",
- "inherits": "^2.0.3",
- "pump": "^3.0.0"
- }
- },
"node_modules/punycode": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
@@ -2653,9 +2530,9 @@
}
},
"node_modules/readable-stream": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
- "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+ "version": "3.6.2",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+ "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"optional": true,
"dependencies": {
"inherits": "^2.0.3",
@@ -2706,16 +2583,18 @@
}
},
"node_modules/retry-request": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.2.2.tgz",
- "integrity": "sha512-xA93uxUD/rogV7BV59agW/JHPGXeREMWiZc9jhcwY4YdZ7QOtC7qbomYg0n4wyk2lJhggjvKvhNX8wln/Aldhg==",
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.1.tgz",
+ "integrity": "sha512-ZI6vJp9rfB71mrZpw+n9p/B6HCsd7QJlSEQftZ+xfJzr3cQ9EPGKw1FF0BnViJ0fYREX6FhymBD2CARpmsFciQ==",
"optional": true,
"dependencies": {
+ "@types/request": "^2.48.8",
"debug": "^4.1.1",
- "extend": "^3.0.2"
+ "extend": "^3.0.2",
+ "teeny-request": "^9.0.0"
},
"engines": {
- "node": ">=8.10.0"
+ "node": ">=14"
}
},
"node_modules/reusify": {
@@ -2791,13 +2670,35 @@
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
"node_modules/semver": {
- "version": "5.7.2",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
- "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
"bin": {
- "semver": "bin/semver"
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
}
},
+ "node_modules/semver/node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+ },
"node_modules/send": {
"version": "0.18.0",
"resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz",
@@ -2903,12 +2804,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/signal-exit": {
- "version": "3.0.7",
- "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
- "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
- "optional": true
- },
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -2979,6 +2874,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/strnum": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
+ "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
+ "optional": true
+ },
"node_modules/stubs": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
@@ -2998,19 +2899,44 @@
}
},
"node_modules/teeny-request": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-7.2.0.tgz",
- "integrity": "sha512-SyY0pek1zWsi0LRVAALem+avzMLc33MKW/JLLakdP4s9+D7+jHcy5x6P+h94g2QNZsAqQNfX5lsbd3WSeJXrrw==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz",
+ "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==",
"optional": true,
"dependencies": {
"http-proxy-agent": "^5.0.0",
"https-proxy-agent": "^5.0.0",
- "node-fetch": "^2.6.1",
+ "node-fetch": "^2.6.9",
"stream-events": "^1.0.5",
- "uuid": "^8.0.0"
+ "uuid": "^9.0.0"
},
"engines": {
- "node": ">=10"
+ "node": ">=14"
+ }
+ },
+ "node_modules/teeny-request/node_modules/agent-base": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
+ "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+ "optional": true,
+ "dependencies": {
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6.0.0"
+ }
+ },
+ "node_modules/teeny-request/node_modules/https-proxy-agent": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
+ "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+ "optional": true,
+ "dependencies": {
+ "agent-base": "6",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 6"
}
},
"node_modules/text-decoding": {
@@ -3038,9 +2964,9 @@
"integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="
},
"node_modules/tslib": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.0.tgz",
- "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg=="
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
+ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/type-check": {
"version": "0.4.0",
@@ -3078,26 +3004,10 @@
"node": ">= 0.6"
}
},
- "node_modules/typedarray-to-buffer": {
- "version": "3.1.5",
- "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
- "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
- "optional": true,
- "dependencies": {
- "is-typedarray": "^1.0.0"
- }
- },
- "node_modules/unique-string": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz",
- "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==",
- "optional": true,
- "dependencies": {
- "crypto-random-string": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
+ "node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
},
"node_modules/unpipe": {
"version": "1.0.0",
@@ -3131,9 +3041,13 @@
}
},
"node_modules/uuid": {
- "version": "8.3.2",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",
- "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==",
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
+ "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
+ "funding": [
+ "https://github.com/sponsors/broofa",
+ "https://github.com/sponsors/ctavan"
+ ],
"bin": {
"uuid": "dist/bin/uuid"
}
@@ -3228,27 +3142,6 @@
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"devOptional": true
},
- "node_modules/write-file-atomic": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
- "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==",
- "optional": true,
- "dependencies": {
- "imurmurhash": "^0.1.4",
- "is-typedarray": "^1.0.0",
- "signal-exit": "^3.0.2",
- "typedarray-to-buffer": "^3.1.5"
- }
- },
- "node_modules/xdg-basedir": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz",
- "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==",
- "optional": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
@@ -3259,36 +3152,35 @@
}
},
"node_modules/yallist": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
- "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "optional": true
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A=="
},
"node_modules/yargs": {
- "version": "16.2.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
- "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
"optional": true,
"dependencies": {
- "cliui": "^7.0.2",
+ "cliui": "^8.0.1",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
- "string-width": "^4.2.0",
+ "string-width": "^4.2.3",
"y18n": "^5.0.5",
- "yargs-parser": "^20.2.2"
+ "yargs-parser": "^21.1.1"
},
"engines": {
- "node": ">=10"
+ "node": ">=12"
}
},
"node_modules/yargs-parser": {
- "version": "20.2.9",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
- "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"optional": true,
"engines": {
- "node": ">=10"
+ "node": ">=12"
}
},
"node_modules/yocto-queue": {
diff --git a/sample apps/hms-callkit-app/functions/package.json b/sample apps/hms-callkit-app/functions/package.json
index 70089faf0..dd31b2df0 100644
--- a/sample apps/hms-callkit-app/functions/package.json
+++ b/sample apps/hms-callkit-app/functions/package.json
@@ -14,7 +14,7 @@
},
"main": "index.js",
"dependencies": {
- "firebase-admin": "^10.0.2",
+ "firebase-admin": "^12.0.0",
"firebase-functions": "^3.18.0"
},
"devDependencies": {