diff --git a/.trunk/.gitignore b/.trunk/.gitignore
index 1e2465290..15966d087 100644
--- a/.trunk/.gitignore
+++ b/.trunk/.gitignore
@@ -6,3 +6,4 @@
plugins
user_trunk.yaml
user.yaml
+tmp
diff --git a/.trunk/trunk.yaml b/.trunk/trunk.yaml
index 3d660863f..bb53f1c98 100644
--- a/.trunk/trunk.yaml
+++ b/.trunk/trunk.yaml
@@ -1,28 +1,28 @@
version: 0.1
cli:
- version: 1.18.0
+ version: 1.21.0
plugins:
sources:
- id: trunk
- ref: v1.3.0
+ ref: v1.4.5
uri: https://github.com/trunk-io/plugins
lint:
enabled:
- - actionlint@1.6.26
- - checkov@3.1.9
- - osv-scanner@1.5.0
- - trivy@0.48.0
- - trufflehog@3.63.2
+ - actionlint@1.6.27
+ - checkov@3.2.60
+ - osv-scanner@1.7.0
+ - trivy@0.50.1
+ - trufflehog@3.71.0
- oxipng@9.0.0
- - yamllint@1.33.0
- - markdownlint@0.37.0
- - prettier@3.1.0
+ - yamllint@1.35.1
+ - markdownlint@0.39.0
+ - prettier@3.2.5
- git-diff-check
- shfmt@3.6.0
- - shellcheck@0.9.0
- - gitleaks@8.18.1
- - svgo@3.0.5
- - ktlint@1.0.1
+ - shellcheck@0.10.0
+ - gitleaks@8.18.2
+ - svgo@3.2.0
+ - ktlint@1.2.1
runtimes:
enabled:
- python@3.10.8
diff --git a/packages/hms_room_kit/example/ios/Podfile.lock b/packages/hms_room_kit/example/ios/Podfile.lock
index c2f593f29..1d21584f3 100644
--- a/packages/hms_room_kit/example/ios/Podfile.lock
+++ b/packages/hms_room_kit/example/ios/Podfile.lock
@@ -4,14 +4,16 @@ PODS:
- HMSBroadcastExtensionSDK (0.0.9)
- HMSHLSPlayerSDK (0.0.2):
- HMSAnalyticsSDK (= 0.0.2)
- - HMSSDK (1.7.0):
+ - HMSNoiseCancellationModels (1.0.0)
+ - HMSSDK (1.8.0):
- HMSAnalyticsSDK (= 0.0.2)
- HMSWebRTC (= 1.0.5118)
- hmssdk_flutter (1.10.0):
- Flutter
- HMSBroadcastExtensionSDK (= 0.0.9)
- HMSHLSPlayerSDK (= 0.0.2)
- - HMSSDK (= 1.7.0)
+ - HMSNoiseCancellationModels (= 1.0.0)
+ - HMSSDK (= 1.8.0)
- HMSWebRTC (1.0.5118)
- path_provider_foundation (0.0.1):
- Flutter
@@ -40,6 +42,7 @@ SPEC REPOS:
- HMSAnalyticsSDK
- HMSBroadcastExtensionSDK
- HMSHLSPlayerSDK
+ - HMSNoiseCancellationModels
- HMSSDK
- HMSWebRTC
@@ -64,8 +67,9 @@ SPEC CHECKSUMS:
HMSAnalyticsSDK: 4d2a88a729b1eb42f3d25f217c28937ec318a5b7
HMSBroadcastExtensionSDK: d80fe325f6c928bd8e5176290b5a4b7ae15d6fbb
HMSHLSPlayerSDK: 6a54ad4d12f3dc2270d1ecd24019d71282a4f6a3
- HMSSDK: 421b4ce83a601bbda283b3b9fbcd1da6898d2a84
- hmssdk_flutter: dd0d9bcb8fb90c54319d0114e917c4607c0bc382
+ HMSNoiseCancellationModels: a3bda1405a16015632f4bcabd46ce48f35103b02
+ HMSSDK: c893d1381a47ed02760ef6d06625b9aa5251f998
+ hmssdk_flutter: 997715f0bedfcb22750fb95549672bf3fea380ff
HMSWebRTC: 4487c7200f1e9358412c1d8cd974edd2766467dc
path_provider_foundation: 3784922295ac71e43754bd15e0653ccfd36a147c
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
diff --git a/packages/hms_room_kit/example/pubspec.lock b/packages/hms_room_kit/example/pubspec.lock
index 8cca87c8d..a43e05a3d 100644
--- a/packages/hms_room_kit/example/pubspec.lock
+++ b/packages/hms_room_kit/example/pubspec.lock
@@ -13,10 +13,10 @@ packages:
dependency: transitive
description:
name: args
- sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
+ sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
url: "https://pub.dev"
source: hosted
- version: "2.4.2"
+ version: "2.5.0"
async:
dependency: transitive
description:
@@ -61,10 +61,10 @@ packages:
dependency: transitive
description:
name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
- version: "1.18.0"
+ version: "1.17.2"
convert:
dependency: transitive
description:
@@ -77,10 +77,10 @@ packages:
dependency: transitive
description:
name: cross_file
- sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
+ sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5"
url: "https://pub.dev"
source: hosted
- version: "0.3.4+1"
+ version: "0.3.3+7"
crypto:
dependency: transitive
description:
@@ -133,10 +133,10 @@ packages:
dependency: transitive
description:
name: ffi
- sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
+ sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.0"
file:
dependency: transitive
description:
@@ -145,14 +145,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.0.0"
- fixnum:
- dependency: transitive
- description:
- name: fixnum
- sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
- url: "https://pub.dev"
- source: hosted
- version: "1.1.0"
flutter:
dependency: "direct main"
description: flutter
@@ -218,20 +210,18 @@ packages:
hmssdk_flutter:
dependency: transitive
description:
- path: "packages/hmssdk_flutter"
- ref: develop
- resolved-ref: f23908cdd1254aab1ebe01df6dfc75bdbbd44ae8
- url: "https://github.com/100mslive/100ms-flutter.git"
- source: git
+ path: "../../hmssdk_flutter"
+ relative: true
+ source: path
version: "1.10.0"
http:
dependency: transitive
description:
name: http
- sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
+ sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
url: "https://pub.dev"
source: hosted
- version: "1.2.1"
+ version: "1.1.0"
http_parser:
dependency: transitive
description:
@@ -252,34 +242,10 @@ packages:
dependency: transitive
description:
name: js
- sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
- url: "https://pub.dev"
- source: hosted
- version: "0.7.1"
- leak_tracker:
- dependency: transitive
- description:
- name: leak_tracker
- sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
- url: "https://pub.dev"
- source: hosted
- version: "10.0.0"
- leak_tracker_flutter_testing:
- dependency: transitive
- description:
- name: leak_tracker_flutter_testing
- sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
- url: "https://pub.dev"
- source: hosted
- version: "2.0.1"
- leak_tracker_testing:
- dependency: transitive
- description:
- name: leak_tracker_testing
- sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
+ sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
- version: "2.0.1"
+ version: "0.6.7"
linkify:
dependency: transitive
description:
@@ -308,34 +274,34 @@ packages:
dependency: transitive
description:
name: matcher
- sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
+ sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
- version: "0.12.16+1"
+ version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
- sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
+ sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
- version: "0.8.0"
+ version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
- sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
+ sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
source: hosted
- version: "1.11.0"
+ version: "1.9.1"
mime:
dependency: transitive
description:
name: mime
- sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
+ sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
url: "https://pub.dev"
source: hosted
- version: "1.0.5"
+ version: "1.0.4"
nested:
dependency: transitive
description:
@@ -348,10 +314,10 @@ packages:
dependency: transitive
description:
name: path
- sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
+ sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
- version: "1.9.0"
+ version: "1.8.3"
path_parsing:
dependency: transitive
description:
@@ -364,18 +330,18 @@ packages:
dependency: transitive
description:
name: path_provider
- sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
+ sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.3"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
- sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
+ sha256: "51f0d2c554cfbc9d6a312ab35152fc77e2f0b758ce9f1a444a3a1e5b8f3c6b7f"
url: "https://pub.dev"
source: hosted
- version: "2.2.2"
+ version: "2.2.3"
path_provider_foundation:
dependency: transitive
description:
@@ -412,58 +378,50 @@ packages:
dependency: transitive
description:
name: permission_handler
- sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb"
+ sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8"
url: "https://pub.dev"
source: hosted
- version: "11.3.1"
+ version: "11.0.1"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
- sha256: "1acac6bae58144b442f11e66621c062aead9c99841093c38f5bcdcc24c1c3474"
+ sha256: f9fddd3b46109bd69ff3f9efa5006d2d309b7aec0f3c1c5637a60a2d5659e76e
url: "https://pub.dev"
source: hosted
- version: "12.0.5"
+ version: "11.1.0"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
- sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662
+ sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
url: "https://pub.dev"
source: hosted
- version: "9.4.4"
- permission_handler_html:
- dependency: transitive
- description:
- name: permission_handler_html
- sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d"
- url: "https://pub.dev"
- source: hosted
- version: "0.1.1"
+ version: "9.1.4"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
- sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20"
+ sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4"
url: "https://pub.dev"
source: hosted
- version: "4.2.1"
+ version: "3.12.0"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
- sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
+ sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
url: "https://pub.dev"
source: hosted
- version: "0.2.1"
+ version: "0.1.3"
petitparser:
dependency: transitive
description:
name: petitparser
- sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
+ sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
url: "https://pub.dev"
source: hosted
- version: "6.0.2"
+ version: "5.4.0"
platform:
dependency: transitive
description:
@@ -484,10 +442,10 @@ packages:
dependency: transitive
description:
name: pointycastle
- sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
+ sha256: "70fe966348fe08c34bf929582f1d8247d9d9408130723206472b4687227e4333"
url: "https://pub.dev"
source: hosted
- version: "3.7.4"
+ version: "3.8.0"
provider:
dependency: transitive
description:
@@ -516,10 +474,10 @@ packages:
dependency: transitive
description:
name: shared_preferences
- sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
+ sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
url: "https://pub.dev"
source: hosted
- version: "2.2.2"
+ version: "2.2.3"
shared_preferences_android:
dependency: transitive
description:
@@ -556,10 +514,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_web
- sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
+ sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
url: "https://pub.dev"
source: hosted
- version: "2.3.0"
+ version: "2.2.1"
shared_preferences_windows:
dependency: transitive
description:
@@ -593,18 +551,18 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
@@ -625,10 +583,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
- version: "0.6.1"
+ version: "0.6.0"
tuple:
dependency: transitive
description:
@@ -649,10 +607,10 @@ packages:
dependency: transitive
description:
name: url_launcher
- sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e"
+ sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c
url: "https://pub.dev"
source: hosted
- version: "6.2.5"
+ version: "6.2.4"
url_launcher_android:
dependency: transitive
description:
@@ -665,10 +623,10 @@ packages:
dependency: transitive
description:
name: url_launcher_ios
- sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5"
+ sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03"
url: "https://pub.dev"
source: hosted
- version: "6.2.5"
+ version: "6.2.4"
url_launcher_linux:
dependency: transitive
description:
@@ -697,10 +655,10 @@ packages:
dependency: transitive
description:
name: url_launcher_web
- sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d"
+ sha256: "7fd2f55fe86cea2897b963e864dc01a7eb0719ecc65fcef4c1cc3d686d718bb2"
url: "https://pub.dev"
source: hosted
- version: "2.3.0"
+ version: "2.2.0"
url_launcher_windows:
dependency: transitive
description:
@@ -713,10 +671,10 @@ packages:
dependency: transitive
description:
name: uuid
- sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8
+ sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f"
url: "https://pub.dev"
source: hosted
- version: "4.3.3"
+ version: "4.2.2"
vector_graphics:
dependency: transitive
description:
@@ -757,30 +715,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.4.0+2"
- vm_service:
- dependency: transitive
- description:
- name: vm_service
- sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
- url: "https://pub.dev"
- source: hosted
- version: "13.0.0"
web:
dependency: transitive
description:
name: web
- sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
+ sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
url: "https://pub.dev"
source: hosted
- version: "0.5.1"
+ version: "0.1.4-beta"
win32:
dependency: transitive
description:
name: win32
- sha256: "0a989dc7ca2bb51eac91e8fd00851297cfffd641aa7538b165c62637ca0eaa4a"
+ sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574
url: "https://pub.dev"
source: hosted
- version: "5.4.0"
+ version: "5.1.1"
xdg_directories:
dependency: transitive
description:
@@ -793,10 +743,10 @@ packages:
dependency: transitive
description:
name: xml
- sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
+ sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
url: "https://pub.dev"
source: hosted
- version: "6.5.0"
+ version: "6.3.0"
sdks:
- dart: ">=3.3.0 <4.0.0"
- flutter: ">=3.19.0"
+ dart: ">=3.1.0 <4.0.0"
+ flutter: ">=3.13.0"
diff --git a/packages/hms_room_kit/lib/src/assets/icons/caption_off.svg b/packages/hms_room_kit/lib/src/assets/icons/caption_off.svg
new file mode 100644
index 000000000..9532a1d0c
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/caption_off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/hms_room_kit/lib/src/assets/icons/caption_on.svg b/packages/hms_room_kit/lib/src/assets/icons/caption_on.svg
new file mode 100644
index 000000000..0716c0d8b
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/caption_on.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/hms_room_kit/lib/src/assets/icons/hand_off.svg b/packages/hms_room_kit/lib/src/assets/icons/hand_off.svg
new file mode 100644
index 000000000..88e183ecd
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/assets/icons/hand_off.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/hms_room_kit/lib/src/assets/icons/music_wave.svg b/packages/hms_room_kit/lib/src/assets/icons/music_wave.svg
index 863ee3614..0e56ef9fa 100644
--- a/packages/hms_room_kit/lib/src/assets/icons/music_wave.svg
+++ b/packages/hms_room_kit/lib/src/assets/icons/music_wave.svg
@@ -1,9 +1 @@
-
+
\ No newline at end of file
diff --git a/packages/hms_room_kit/lib/src/assets/icons/sip_call.svg b/packages/hms_room_kit/lib/src/assets/icons/sip_call.svg
index 635ee3b49..500fe670f 100644
--- a/packages/hms_room_kit/lib/src/assets/icons/sip_call.svg
+++ b/packages/hms_room_kit/lib/src/assets/icons/sip_call.svg
@@ -1,7 +1 @@
-
+
\ No newline at end of file
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_hand_raise_menu.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_hand_raise_menu.dart
new file mode 100644
index 000000000..20aafc5af
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_hand_raise_menu.dart
@@ -0,0 +1,79 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:hms_room_kit/hms_room_kit.dart';
+import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
+import 'package:hms_room_kit/src/meeting/meeting_store.dart';
+import 'package:hms_room_kit/src/widgets/bottom_sheets/hls_app_utilities_bottom_sheet.dart';
+import 'package:hms_room_kit/src/widgets/common_widgets/hms_embedded_button.dart';
+import 'package:provider/provider.dart';
+
+class HLSHandRaiseMenu extends StatelessWidget {
+ const HLSHandRaiseMenu({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ Selector(
+ selector: (_, meetingStore) => meetingStore.isRaisedHand,
+ builder: (_, isRaisedHand, __) {
+ return HMSEmbeddedButton(
+ onTap: () => {
+ context.read().toggleLocalPeerHandRaise(),
+ },
+ enabledBorderColor: HMSThemeColors.surfaceBrighter,
+ offColor: HMSThemeColors.surfaceDefault,
+ disabledBorderColor: HMSThemeColors.surfaceDefault,
+ onColor: HMSThemeColors.surfaceBrighter,
+ isActive: isRaisedHand,
+ child: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: SvgPicture.asset(
+ isRaisedHand
+ ? "packages/hms_room_kit/lib/src/assets/icons/hand_off.svg"
+ : "packages/hms_room_kit/lib/src/assets/icons/hand_outline.svg",
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis, BlendMode.srcIn),
+ semanticsLabel: "hand_raise_button",
+ ),
+ ),
+ );
+ }),
+ const SizedBox(
+ width: 8,
+ ),
+ if (HMSRoomLayout.isParticipantsListEnabled ||
+ Constant.prebuiltOptions?.userName == null)
+ HMSEmbeddedButton(
+ onTap: () async => {
+ 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: const HLSAppUtilitiesBottomSheet()),
+ )
+ },
+ enabledBorderColor: HMSThemeColors.surfaceDefault,
+ onColor: HMSThemeColors.surfaceDefault,
+ isActive: true,
+ child: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/menu.svg",
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis, BlendMode.srcIn),
+ semanticsLabel: "more_button"),
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_player.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_player.dart
index f9a90edfe..86d690dcc 100644
--- a/packages/hms_room_kit/lib/src/hls_viewer/hls_player.dart
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_player.dart
@@ -3,41 +3,97 @@ library;
///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/hls_viewer/hls_player_store.dart';
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
-import 'package:provider/provider.dart';
+import 'package:hms_room_kit/src/hls_viewer/hls_player_overlay_options.dart';
+import 'package:hms_room_kit/src/hls_viewer/hls_waiting_ui.dart';
+import 'package:hms_room_kit/src/layout_api/hms_theme_colors.dart';
///[HLSPlayer] is a component that is used to show the HLS Player
class HLSPlayer extends StatelessWidget {
- final double? ratio;
- const HLSPlayer({Key? key, this.ratio}) : super(key: key);
+ const HLSPlayer({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
///We use the hlsAspectRatio from the [MeetingStore] to set the aspect ratio of the player
///By default the aspect ratio is 9:16
- return Selector(
- selector: (_, meetingStore) => meetingStore.hlsAspectRatio,
- builder: (_, ratio, __) {
- return GestureDetector(
- child: AspectRatio(
- aspectRatio: ratio,
- child: InkWell(
- onTap: () =>
- context.read().toggleButtonsVisibility(),
- splashFactory: NoSplash.splashFactory,
- child: IgnorePointer(
- child: HMSHLSPlayer(
- key: key,
- showPlayerControls: false,
- isHLSStatsRequired:
- context.read().isHLSStatsEnabled,
- ),
- ),
+ return Selector(
+ selector: (_, meetingStore) => meetingStore.hasHlsStarted,
+ builder: (_, hasHLSStarted, __) {
+ return Stack(
+ children: [
+ ///Renders the HLS Player if the HLS has started
+ ///Otherwise renders the waiting UI
+ hasHLSStarted
+ ? Align(
+ alignment: Alignment.center,
+ child: Selector(
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.hlsPlayerSize,
+ builder: (_, hlsPlayerSize, __) {
+ return AspectRatio(
+ aspectRatio:
+ hlsPlayerSize.width / hlsPlayerSize.height,
+ child: InkWell(
+ onTap: () => context
+ .read()
+ .toggleButtonsVisibility(),
+ splashFactory: NoSplash.splashFactory,
+ splashColor: HMSThemeColors.backgroundDim,
+ child: IgnorePointer(
+ child: const HMSHLSPlayer(
+ showPlayerControls: false,
+ ),
+ ),
+ ),
+ );
+ }),
+ )
+ : Center(child: const HLSWaitingUI()),
+
+ ///This renders the overlay controls for HLS Player
+ Align(
+ alignment: Alignment.center,
+ child: Selector(
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.isFullScreen,
+ builder: (_, isFullScreen, __) {
+ return isFullScreen
+ ? Selector(
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.hlsPlayerSize,
+ builder: (_, hlsPlayerSize, __) {
+ return AspectRatio(
+ aspectRatio: hlsPlayerSize.width /
+ hlsPlayerSize.height,
+ child: HLSPlayerOverlayOptions(
+ hasHLSStarted: hasHLSStarted,
+ ),
+ );
+ })
+ : HLSPlayerOverlayOptions(
+ hasHLSStarted: hasHLSStarted);
+ }),
),
- ),
+ Selector(
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.playerPlaybackState,
+ builder: (_, state, __) {
+ return state == HMSHLSPlaybackState.BUFFERING || state == HMSHLSPlaybackState.FAILED
+ ? Align(
+ alignment: Alignment.center,
+ child: CircularProgressIndicator(
+ color: HMSThemeColors.primaryDefault,
+ strokeWidth: 2,
+ ),
+ )
+ : const SizedBox();
+ },
+ )
+ ],
);
});
}
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_player_desktop_controls.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_player_desktop_controls.dart
new file mode 100644
index 000000000..9ebba4811
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_player_desktop_controls.dart
@@ -0,0 +1,50 @@
+library;
+
+///Package imports
+import 'package:flutter/material.dart';
+
+///Project imports
+import 'package:hms_room_kit/src/hls_viewer/hls_stream_description.dart';
+import 'package:hms_room_kit/src/widgets/bottom_sheets/chat_bottom_sheet.dart';
+
+///[HLSPlayerDesktopControls] is the desktop controls for the HLS Player
+class HLSPlayerDesktopControls extends StatefulWidget {
+ @override
+ State createState() =>
+ _HLSPlayerDesktopControlsState();
+}
+
+class _HLSPlayerDesktopControlsState extends State {
+ bool showDescription = false;
+
+ ///[toggleDescription] toggles the visibility of description
+ void toggleDescription() {
+ setState(() {
+ showDescription = !showDescription;
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Expanded(
+ child: Column(
+ children: [
+ ///Renders HLS Stream Description and Chat Bottom Sheet
+ HLSStreamDescription(
+ showDescription: showDescription,
+ toggleDescription: toggleDescription),
+
+ ///Renders Chat Bottom Sheet only is the description is not visible
+ if (!showDescription)
+ Expanded(
+ child: Padding(
+ padding: const EdgeInsets.only(bottom: 8.0),
+ child: ChatBottomSheet(
+ isHLSChat: true,
+ ),
+ ))
+ ],
+ ),
+ );
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_player_overlay_options.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_player_overlay_options.dart
new file mode 100644
index 000000000..58dec346e
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_player_overlay_options.dart
@@ -0,0 +1,30 @@
+library;
+
+///Package imports
+import 'package:flutter/material.dart';
+
+///Project imports
+import 'package:hms_room_kit/src/hls_viewer/hls_viewer_bottom_navigation_bar.dart';
+import 'package:hms_room_kit/src/hls_viewer/hls_viewer_header.dart';
+
+///[HLSPlayerOverlayOptions] renders the overlay options for the HLS Player
+class HLSPlayerOverlayOptions extends StatelessWidget {
+ final bool hasHLSStarted;
+
+ const HLSPlayerOverlayOptions({super.key, required this.hasHLSStarted});
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ HLSViewerHeader(
+ hasHLSStarted: hasHLSStarted,
+ ),
+
+ ///Renders the bottom navigation bar if the HLS has started
+ ///Otherwise does not render the bottom navigation bar
+ hasHLSStarted ? HLSViewerBottomNavigationBar() : const SizedBox()
+ ],
+ );
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_player_store.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_player_store.dart
index 8651d49b7..f48fab29b 100644
--- a/packages/hms_room_kit/lib/src/hls_viewer/hls_player_store.dart
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_player_store.dart
@@ -1,8 +1,19 @@
+library;
+
+///Dart imports
import 'dart:async';
+import 'dart:developer';
+
+///Package imports
import 'package:flutter/material.dart';
+import 'package:hmssdk_flutter/hmssdk_flutter.dart';
+
+///Project imports
import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
-class HLSPlayerStore extends ChangeNotifier {
+///[HLSPlayerStore] is a store that stores the state of the HLS Player
+class HLSPlayerStore extends ChangeNotifier
+ implements HMSHLSPlaybackEventsListener {
///This variable stores whether the application is in full screen or not
bool isFullScreen = false;
@@ -12,6 +23,12 @@ class HLSPlayerStore extends ChangeNotifier {
///This variable stores whether the buttons are visible or not
bool areStreamControlsVisible = true;
+ ///This variable stores whether the captions are enabled or not
+ bool isCaptionEnabled = false;
+
+ ///This variable stores whether the captions are supported or not
+ bool areCaptionsSupported = false;
+
///This variable stores whether the chat is opened or not
///The initial value is taken from the [HMSRoomLayout.chatData]
bool isChatOpened = (HMSRoomLayout.chatData?.isOpenInitially ?? false) &&
@@ -22,6 +39,20 @@ class HLSPlayerStore extends ChangeNotifier {
///This is done to avoid multiple timers running at the same time
bool _isTimerActive = false;
+ ///This variable stores whether there is some error in playing stream
+ bool isPlayerFailed = false;
+
+ ///HLS Player Stats
+
+ HMSHLSPlayerStats? hlsPlayerStats;
+
+ ///[hlsPlayerSize] stores the resolution of HLS Stream
+ Size hlsPlayerSize = Size(1, 1);
+
+ bool isHLSStatsEnabled = false;
+
+ HMSHLSPlaybackState playerPlaybackState = HMSHLSPlaybackState.PLAYING;
+
///This method starts a timer for 5 seconds and then hides the buttons
///
///[isStreamPlaying] is used to check if the video is playing or not
@@ -38,6 +69,13 @@ class HLSPlayerStore extends ChangeNotifier {
});
}
+ ///[toggleFullScreen] toggles the full screen mode
+ void toggleFullScreen() {
+ isFullScreen = !isFullScreen;
+ notifyListeners();
+ }
+
+ ///This method sets the [isStreamPlaying] to true or false
void setStreamPlaying(bool isStreamPlaying) {
this.isStreamPlaying = isStreamPlaying;
if (isStreamPlaying) {
@@ -47,15 +85,23 @@ class HLSPlayerStore extends ChangeNotifier {
return;
} else {
areStreamControlsVisible = true;
+ isFullScreen = false;
}
notifyListeners();
}
+ ///This method toggles the visibility of the chat
void toggleIsChatOpened() {
isChatOpened = !isChatOpened;
notifyListeners();
}
+ ///This method toggles the visibility of the captions
+ void toggleCaptions() {
+ isCaptionEnabled = !isCaptionEnabled;
+ notifyListeners();
+ }
+
///This method toggles the visibility of the buttons
///
///If the buttons are not visible we set the [areStreamControlsVisible] to true
@@ -77,4 +123,60 @@ class HLSPlayerStore extends ChangeNotifier {
}
}
}
+
+ ///[areClosedCaptionsSupported] checks if the closed captions are supported or not
+ void areClosedCaptionsSupported() async {
+ areCaptionsSupported =
+ await HMSHLSPlayerController.areClosedCaptionsSupported();
+ notifyListeners();
+ }
+
+ void setHLSPlayerStats(bool value) {
+ isHLSStatsEnabled = value;
+ if (!value) {
+ HMSHLSPlayerController.removeHLSStatsListener();
+ } else {
+ HMSHLSPlayerController.addHLSStatsListener();
+ }
+ notifyListeners();
+ }
+
+ @override
+ void onCue({required HMSHLSCue hlsCue}) {}
+
+ @override
+ void onHLSError({required HMSException hlsException}) {}
+
+ @override
+ void onHLSEventUpdate({required HMSHLSPlayerStats playerStats}) {
+ log("onHLSEventUpdate-> bitrate:${playerStats.averageBitrate} buffered duration: ${playerStats.bufferedDuration}");
+ hlsPlayerStats = playerStats;
+ notifyListeners();
+ }
+
+ @override
+ void onPlaybackFailure({required String? error}) {
+ log("Playback failure $error");
+ }
+
+ @override
+ void onPlaybackStateChanged({required HMSHLSPlaybackState playbackState}) {
+ log("Playback state changed to ${playbackState.name}");
+ playerPlaybackState = playbackState;
+ if (playerPlaybackState == HMSHLSPlaybackState.PLAYING) {
+ isPlayerFailed = false;
+ areClosedCaptionsSupported();
+ }
+ if (playerPlaybackState == HMSHLSPlaybackState.FAILED) {
+ isPlayerFailed = true;
+ }
+ notifyListeners();
+ }
+
+ @override
+ void onVideoSizeChanged({required Size size}) {
+ log("onVideoSizeChanged -> height:${size.height} width:${size.width}");
+ hlsPlayerSize = size;
+ notifyListeners();
+ }
}
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_stats_view.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_stats_view.dart
index 3b4f686df..1b411e895 100644
--- a/packages/hms_room_kit/lib/src/hls_viewer/hls_stats_view.dart
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_stats_view.dart
@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:hms_room_kit/src/common/app_color.dart';
-import 'package:hms_room_kit/src/meeting/meeting_store.dart';
+import 'package:hms_room_kit/src/hls_viewer/hls_player_store.dart';
import 'package:provider/provider.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_text_style.dart';
@@ -18,72 +18,72 @@ class HLSStatsView extends StatelessWidget {
child: ListView(
shrinkWrap: true,
children: [
- Selector(
+ Selector(
builder: (_, bitrate, __) {
return Text(
"Bitrate : ${bitrate == null ? "-" : (bitrate / 8000)} KBps",
style: HMSTextStyle.setTextStyle(
color: iconColor, fontSize: 12));
},
- selector: (_, meetingStore) =>
- meetingStore.hlsPlayerStats?.averageBitrate),
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.hlsPlayerStats?.averageBitrate),
const SizedBox(
height: 10,
),
- Selector(
+ Selector(
builder: (_, bufferedDuration, __) {
return Text(
"Buffered Duration : ${bufferedDuration == null ? "-" : bufferedDuration / 1000}",
style: HMSTextStyle.setTextStyle(
color: iconColor, fontSize: 12));
},
- selector: (_, meetingStore) =>
- meetingStore.hlsPlayerStats?.bufferedDuration),
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.hlsPlayerStats?.bufferedDuration),
const SizedBox(
height: 10,
),
- Selector(
+ Selector(
builder: (_, videoWidth, __) {
return Text("Video Width : ${videoWidth ?? "-"} px",
style: HMSTextStyle.setTextStyle(
color: iconColor, fontSize: 12));
},
- selector: (_, meetingStore) =>
- meetingStore.hlsPlayerStats?.videoWidth),
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.hlsPlayerStats?.videoWidth),
const SizedBox(
height: 10,
),
- Selector(
+ Selector(
builder: (_, videoHeight, __) {
return Text("Video Height : ${videoHeight ?? "-"} px",
style: HMSTextStyle.setTextStyle(
color: iconColor, fontSize: 12));
},
- selector: (_, meetingStore) =>
- meetingStore.hlsPlayerStats?.videoHeight),
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.hlsPlayerStats?.videoHeight),
const SizedBox(
height: 10,
),
- Selector(
+ Selector(
builder: (_, droppedFrameCount, __) {
return Text("Dropped Frames : ${droppedFrameCount ?? "-"} ",
style: HMSTextStyle.setTextStyle(
color: iconColor, fontSize: 12));
},
- selector: (_, meetingStore) =>
- meetingStore.hlsPlayerStats?.droppedFrameCount),
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.hlsPlayerStats?.droppedFrameCount),
const SizedBox(
height: 10,
),
- Selector(
+ Selector(
builder: (_, distanceFromLive, __) {
return Text(
"Distance from live edge : ${distanceFromLive == null ? "-" : distanceFromLive / 1000}s",
style: HMSTextStyle.setTextStyle(
color: iconColor, fontSize: 12));
},
- selector: (_, meetingStore) =>
- meetingStore.hlsPlayerStats?.distanceFromLive),
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.hlsPlayerStats?.distanceFromLive),
],
),
);
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_stream_description.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_stream_description.dart
new file mode 100644
index 000000000..fc752d663
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_stream_description.dart
@@ -0,0 +1,319 @@
+library;
+
+///Dart imports
+import 'dart:developer';
+
+///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/hls_viewer/hls_stream_timer.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';
+
+///[HLSStreamDescription] is a widget that is used to render the description of the HLS Stream
+class HLSStreamDescription extends StatelessWidget {
+ final bool showDescription;
+ final Function toggleDescription;
+
+ HLSStreamDescription(
+ {Key? key, this.showDescription = false, required this.toggleDescription})
+ : super(key: key);
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ child: Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: Column(
+ children: [
+ ///If [showDescription] is true, we render the description of the HLS Stream
+ ///This widget is only rendered if description is present and it's visibility is true
+ if (showDescription)
+ GestureDetector(
+ onTap: () => toggleDescription(),
+ child: Padding(
+ padding: const EdgeInsets.symmetric(vertical: 12.0),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(
+ child: HMSTitleText(
+ text: "About Session",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ letterSpacing: 0 / 15,
+ ),
+ ),
+ Icon(Icons.keyboard_arrow_down_rounded),
+ ],
+ ),
+ ),
+ ),
+ if (showDescription)
+ Padding(
+ padding: const EdgeInsets.only(bottom: 16.0),
+ child: Divider(
+ color: HMSThemeColors.borderBright,
+ height: 2,
+ ),
+ ),
+ Row(
+ children: [
+ ///This renders the logo
+ ///If the logo is null, we render an empty SizedBox
+ ///If the logo is an svg, we render the svg
+ ///If the logo is an image, we render the image
+ HMSRoomLayout.roleLayoutData?.logo?.url == null
+ ? Container()
+ : HMSRoomLayout.roleLayoutData!.logo!.url!.contains("svg")
+ ? SvgPicture.network(
+ HMSRoomLayout.roleLayoutData!.logo!.url!,
+ height: 32,
+ width: 32,
+ )
+ : Image.network(
+ HMSRoomLayout.roleLayoutData!.logo!.url!,
+ errorBuilder: (context, exception, _) {
+ log('Error is $exception');
+ return const SizedBox(
+ width: 32,
+ height: 32,
+ );
+ },
+ height: 32,
+ width: 32,
+ ),
+ SizedBox(
+ width: 12,
+ ),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ ///This renders the title
+ ///Only renders this if the title is non null and not empty
+ if (HMSRoomLayout
+ .roleLayoutData
+ ?.screens
+ ?.conferencing
+ ?.hlsLiveStreaming
+ ?.elements
+ ?.header
+ ?.title
+ ?.isNotEmpty ??
+ false)
+ Container(
+ child: HMSSubheadingText(
+ text: HMSRoomLayout
+ .roleLayoutData
+ ?.screens
+ ?.conferencing
+ ?.hlsLiveStreaming
+ ?.elements
+ ?.header
+ ?.title ??
+ "",
+ maxLines: showDescription ? 5 : 2,
+ textColor: HMSThemeColors.onSecondaryHighEmphasis,
+ textOverflow: TextOverflow.ellipsis,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ Row(
+ children: [
+ ///This renders the number of peers watching the stream
+ Selector(
+ selector: (_, meetingStore) =>
+ meetingStore.peersInRoom,
+ builder: (_, data, __) {
+ return HMSSubtitleText(
+ text: Utilities.formatNumber(data) +
+ " watching",
+ letterSpacing: 0.4,
+ textColor:
+ HMSThemeColors.onSurfaceMediumEmphasis);
+ }),
+
+ if (context.read().hasHlsStarted)
+ Padding(
+ padding:
+ const EdgeInsets.symmetric(horizontal: 8.0),
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/red_dot.svg",
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis,
+ BlendMode.srcIn),
+ ),
+ ),
+
+ ///This renders the timer for the HLS Stream
+ ///This is only rendered if the HLS Stream has started
+ ///This shows for how much time you have been watching stream
+ if (context.read().hasHlsStarted)
+ HLSStreamTimer(),
+
+ ///This renders the recording status
+ ///If the recording is started, we render the recording indicator
+ ///else we render an empty Container
+ ///
+ ///For recording status we use the recordingType map from the [MeetingStore]
+ (HMSRoomLayout
+ .roleLayoutData
+ ?.screens
+ ?.conferencing
+ ?.hlsLiveStreaming
+ ?.elements
+ ?.header
+ ?.description !=
+ null &&
+ !showDescription)
+ ? GestureDetector(
+ onTap: () {
+ if ((HMSRoomLayout
+ .roleLayoutData
+ ?.screens
+ ?.conferencing
+ ?.hlsLiveStreaming
+ ?.elements
+ ?.header
+ ?.description !=
+ null)) {
+ toggleDescription();
+ }
+ },
+ child: HMSSubtitleText(
+ text: " ...more",
+ fontWeight: FontWeight.w600,
+ textColor:
+ HMSThemeColors.onSurfaceHighEmphasis,
+ letterSpacing: 0.4,
+ ),
+ )
+ : Selector<
+ MeetingStore,
+ Tuple3<
+ HMSRecordingState,
+ HMSRecordingState,
+ HMSRecordingState>>(
+ selector: (_, meetingStore) => Tuple3(
+ meetingStore.recordingType["browser"] ??
+ HMSRecordingState.none,
+ meetingStore.recordingType["server"] ??
+ HMSRecordingState.none,
+ meetingStore.recordingType["hls"] ??
+ HMSRecordingState.none),
+ builder: (_, data, __) {
+ return (data.item1 ==
+ HMSRecordingState.started ||
+ data.item1 ==
+ HMSRecordingState.resumed ||
+ data.item2 ==
+ HMSRecordingState.started ||
+ data.item2 ==
+ HMSRecordingState.resumed ||
+ data.item3 ==
+ HMSRecordingState.started ||
+ data.item3 ==
+ HMSRecordingState.resumed)
+ ? Row(
+ children: [
+ Padding(
+ padding:
+ const EdgeInsets.symmetric(
+ horizontal: 8.0),
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/red_dot.svg",
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors
+ .onSurfaceHighEmphasis,
+ BlendMode.srcIn),
+ ),
+ ),
+ HMSSubtitleText(
+ text: "Recording",
+ letterSpacing: 0.4,
+ textColor: HMSThemeColors
+ .onSurfaceMediumEmphasis,
+ ),
+ ],
+ )
+ : const SizedBox();
+ }),
+ ],
+ )
+ ],
+ ),
+ )
+ ],
+ ),
+
+ ///This renders the description of the HLS Stream
+ ///This is only rendered if the description is present and the visibility is true
+ if (!showDescription)
+ Padding(
+ padding: const EdgeInsets.only(top: 16.0),
+ child: Divider(
+ color: HMSThemeColors.borderBright,
+ height: 2,
+ ),
+ ),
+ if (showDescription &&
+ (HMSRoomLayout.roleLayoutData?.screens?.conferencing
+ ?.hlsLiveStreaming?.elements?.header?.description !=
+ null))
+ Padding(
+ padding: const EdgeInsets.only(top: 16.0),
+
+ ///Here we use SelectableLinkify to render the description
+ ///so that if there is any link in the description, it can be clicked
+ child: SingleChildScrollView(
+ child: Container(
+ constraints: BoxConstraints(
+ maxHeight: MediaQuery.of(context).size.height * 0.38),
+ child: SelectableLinkify(
+ text: HMSRoomLayout
+ .roleLayoutData
+ ?.screens
+ ?.conferencing
+ ?.hlsLiveStreaming
+ ?.elements
+ ?.header
+ ?.description ??
+ "",
+ style: HMSTextStyle.setTextStyle(
+ fontSize: 14.0,
+ color: HMSThemeColors.onSurfaceMediumEmphasis,
+ letterSpacing: 0.25,
+ height: 20 / 14,
+ fontWeight: FontWeight.w400,
+ ),
+ linkStyle: HMSTextStyle.setTextStyle(
+ fontSize: 14.0,
+ color: HMSThemeColors.primaryBright,
+ letterSpacing: 0.25,
+ height: 20 / 14,
+ fontWeight: FontWeight.w400),
+ onOpen: (link) async {
+ Uri url = Uri.parse(link.url);
+ if (await canLaunchUrl(url)) {
+ await launchUrl(url,
+ mode: LaunchMode.externalApplication);
+ }
+ },
+ ),
+ ),
+ ),
+ )
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_stream_timer.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_stream_timer.dart
new file mode 100644
index 000000000..10ee84c08
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_stream_timer.dart
@@ -0,0 +1,75 @@
+import 'dart:async';
+
+import 'package:flutter/material.dart';
+import 'package:hms_room_kit/hms_room_kit.dart';
+import 'package:hms_room_kit/src/meeting/meeting_store.dart';
+import 'package:provider/provider.dart';
+
+class HLSStreamTimer extends StatefulWidget {
+ @override
+ State createState() => _HLSStreamTimerState();
+}
+
+class _HLSStreamTimerState extends State {
+ int _secondsElapsed = 0;
+ Timer? _timer;
+
+ @override
+ void initState() {
+ super.initState();
+ DateTime? startedAt = context
+ .read()
+ .hmsRoom
+ ?.hmshlsStreamingState
+ ?.variants
+ .first
+ ?.startedAt;
+
+ if (startedAt != null) {
+ _secondsElapsed = DateTime.now()
+ .difference(DateTime.fromMillisecondsSinceEpoch(
+ startedAt.millisecondsSinceEpoch))
+ .inSeconds;
+ }
+ _startTimer();
+ }
+
+ @override
+ void dispose() {
+ _timer?.cancel();
+ super.dispose();
+ }
+
+ void _startTimer() {
+ _timer = Timer.periodic(Duration(seconds: 1), (timer) {
+ setState(() {
+ _secondsElapsed++;
+ });
+ });
+ }
+
+ ///[_getFormattedTime] returns the formatted time in hh:mm:ss format
+ String _getFormattedTime() {
+ int _minutes = _secondsElapsed ~/ 60;
+ int _seconds = _secondsElapsed % 60;
+
+ int _hours = 0;
+ if (_minutes > 59) {
+ _hours = _minutes ~/ 60;
+ _minutes %= 60;
+ }
+
+ ///We only show seconds if hours and minutes are 0
+ ///only minutes if hours are 0
+ ///only hours if hours are greater than 0
+ return "Started${_hours > 0 ? " ${_hours.toString()}h" : ""} ${_hours < 1 && _minutes > 0 ? "${_minutes.toString()}m" : ""} ${_hours < 1 && _minutes < 1 ? "${_seconds.toString()}s " : ""}ago";
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return HMSSubtitleText(
+ text: _getFormattedTime(),
+ letterSpacing: 0.4,
+ textColor: HMSThemeColors.onSurfaceMediumEmphasis);
+ }
+}
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 4defbf420..76584868a 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
@@ -1,24 +1,13 @@
library;
-///Dart imports
-import 'dart:io';
-
///Package imports
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
///Project imports
-import 'package:hms_room_kit/src/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/overlay_chat_component.dart';
-import 'package:hms_room_kit/src/widgets/bottom_sheets/hls_app_utilities_bottom_sheet.dart';
import 'package:hms_room_kit/src/hls_viewer/hls_player_store.dart';
-import 'package:hms_room_kit/src/meeting/meeting_store.dart';
-import 'package:hms_room_kit/src/widgets/common_widgets/hms_embedded_button.dart';
///[HLSViewerBottomNavigationBar] is the bottom navigation bar for the HLS Viewer
class HLSViewerBottomNavigationBar extends StatelessWidget {
@@ -33,25 +22,25 @@ class HLSViewerBottomNavigationBar extends StatelessWidget {
end: Alignment.bottomCenter,
colors: [Colors.black.withAlpha(0), Colors.black.withAlpha(64)])),
child: Padding(
- padding: EdgeInsets.only(bottom: Platform.isIOS ? 32.0 : 8),
+ padding: EdgeInsets.only(left: 12, right: 12),
///Here we render the chat component if the chat is opened
///We also render the leave button, hand raise button, chat button and the menu button
child: Column(
children: [
///Chat Component only visible when the chat is opened
- if (HMSRoomLayout.chatData != null)
- Selector(
- selector: (_, hlsPlayerStore) => hlsPlayerStore.isChatOpened,
- builder: (_, isChatOpened, __) {
- if (isChatOpened) {
- Provider.of(context, listen: true)
- .isNewMessageReceived = false;
- }
- return isChatOpened
- ? const OverlayChatComponent()
- : Container();
- }),
+ // if (HMSRoomLayout.chatData != null)
+ // Selector(
+ // selector: (_, hlsPlayerStore) => hlsPlayerStore.isChatOpened,
+ // builder: (_, isChatOpened, __) {
+ // if (isChatOpened) {
+ // Provider.of(context, listen: true)
+ // .isNewMessageReceived = false;
+ // }
+ // return isChatOpened
+ // ? const OverlayChatComponent()
+ // : Container();
+ // }),
///Bottom Navigation Bar
///We render the leave button, hand raise button, chat button and the menu button
@@ -60,214 +49,54 @@ class HLSViewerBottomNavigationBar extends StatelessWidget {
selector: (_, hlsPlayerStore) =>
hlsPlayerStore.areStreamControlsVisible,
builder: (_, areStreamControlsVisible, __) {
- return AnimatedContainer(
- duration: const Duration(milliseconds: 200),
- height: areStreamControlsVisible ? 40 : 0,
- child: areStreamControlsVisible
- ? Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- ///Leave Button
- HMSEmbeddedButton(
- onTap: () async => {
- await UtilityComponents.onBackPressed(context)
- },
- offColor: HMSThemeColors.alertErrorDefault,
- disabledBorderColor:
- HMSThemeColors.alertErrorDefault,
- isActive: false,
- child: Padding(
- padding: const EdgeInsets.all(8.0),
- child: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/exit_room.svg",
- colorFilter: ColorFilter.mode(
- HMSThemeColors.alertErrorBrighter,
- BlendMode.srcIn),
- semanticsLabel: "leave_room_button",
- ),
- ),
- ),
- const SizedBox(
- width: 24,
- ),
-
- ///Hand Raise Button
- Selector(
- selector: (_, meetingStore) =>
- meetingStore.isRaisedHand,
- builder: (_, isRaisedHand, __) {
- return HMSEmbeddedButton(
- onTap: () => {
- context
- .read()
- .toggleLocalPeerHandRaise(),
- },
- enabledBorderColor: HMSThemeColors
- .backgroundDim
- .withAlpha(64),
- onColor: HMSThemeColors.backgroundDim
- .withAlpha(64),
- isActive: !isRaisedHand,
- child: Padding(
- padding: const EdgeInsets.all(8.0),
+ return areStreamControlsVisible
+ ? Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ ///This renders the go live button
+ Row(
+ children: [
+ GestureDetector(
+ onTap: () => {},
+ child: Row(
+ children: [
+ Padding(
+ padding:
+ const EdgeInsets.only(right: 8.0),
child: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/hand_outline.svg",
- colorFilter: ColorFilter.mode(
- HMSThemeColors
- .onSurfaceHighEmphasis,
- BlendMode.srcIn),
- semanticsLabel: "hand_raise_button",
- ),
- ),
- );
- }),
- const SizedBox(
- width: 24,
- ),
-
- ///Chat Button
- if (HMSRoomLayout.chatData != null)
- Selector(
- selector: (_, hlsPlayerStore) =>
- hlsPlayerStore.isChatOpened,
- builder: (_, isChatOpened, __) {
- return HMSEmbeddedButton(
- onTap: () => {
- if (HMSRoomLayout
- .chatData?.isOverlay ??
- false)
- {
- context
- .read()
- .toggleIsChatOpened()
- }
- else
- {
- 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<
- MeetingStore>(),
- child: HMSRoomLayout
- .isParticipantsListEnabled
- ? const ChatParticipantsTabBar(
- tabIndex: 0,
- )
- : const ChatOnlyBottomSheet()),
- )
- }
- },
- enabledBorderColor: HMSThemeColors
- .backgroundDim
- .withAlpha(64),
- onColor: HMSThemeColors.backgroundDim
- .withAlpha(64),
- isActive: !isChatOpened,
- child: Padding(
- padding: const EdgeInsets.all(8.0),
- child: Selector(
- selector: (_, meetingStore) =>
- meetingStore
- .isNewMessageReceived,
- builder: (_,
- isNewMessageReceived, __) {
- return isNewMessageReceived
- ? Badge(
- backgroundColor:
- HMSThemeColors
- .primaryDefault,
- child:
- SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/message_badge_off.svg",
- semanticsLabel:
- "chat_button",
- colorFilter:
- ColorFilter.mode(
- HMSThemeColors
- .onSurfaceHighEmphasis,
- BlendMode
- .srcIn),
- ),
- )
- : SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/message_badge_off.svg",
- colorFilter:
- ColorFilter.mode(
- HMSThemeColors
- .onSurfaceHighEmphasis,
- BlendMode
- .srcIn),
- semanticsLabel:
- "chat_button",
- );
- })),
- );
- }),
-
- if (HMSRoomLayout.chatData != null)
- const SizedBox(
- width: 24,
- ),
-
- ///Menu Button
- if (HMSRoomLayout.isParticipantsListEnabled ||
- Constant.prebuiltOptions?.userName == null)
- HMSEmbeddedButton(
- onTap: () async => {
- showModalBottomSheet(
- isScrollControlled: true,
- backgroundColor:
- HMSThemeColors.surfaceDim,
- shape: const RoundedRectangleBorder(
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(16),
- topRight: Radius.circular(16)),
+ "packages/hms_room_kit/lib/src/assets/icons/red_dot.svg"),
),
- context: context,
- builder: (ctx) =>
- ChangeNotifierProvider.value(
- value:
- context.read(),
- child:
- const HLSAppUtilitiesBottomSheet()),
- )
- },
- enabledBorderColor: HMSThemeColors
- .backgroundDim
- .withAlpha(64),
- onColor: HMSThemeColors.backgroundDim
- .withAlpha(64),
- isActive: true,
- child: Padding(
- padding: const EdgeInsets.all(8.0),
- child: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/menu.svg",
- colorFilter: ColorFilter.mode(
- HMSThemeColors
- .onSurfaceHighEmphasis,
- BlendMode.srcIn),
- semanticsLabel: "more_button"),
+ HMSTitleText(
+ text: "LIVE",
+ textColor: HMSThemeColors
+ .onSurfaceHighEmphasis)
+ ],
),
- ),
- ],
- )
- : Container(),
- );
+ )
+ ],
+ ),
+
+ ///This renders the minimize/maximize button
+ ///to toggle the full screen mode
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ Selector(
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.isFullScreen,
+ builder: (_, isFullScreen, __) {
+ return InkWell(
+ onTap: () => context
+ .read()
+ .toggleFullScreen(),
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/${isFullScreen ? "minimize" : "maximize"}.svg"),
+ );
+ })
+ ])
+ ],
+ )
+ : const SizedBox();
}),
],
),
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_header.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_header.dart
index b38c21f69..121f4dcd3 100644
--- a/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_header.dart
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_header.dart
@@ -1,27 +1,18 @@
library;
-///Dart imports
-import 'dart:developer';
-import 'dart:io';
-
///Package imports
import 'package:flutter/material.dart';
-import 'package:flutter_svg/flutter_svg.dart';
-import 'package:hmssdk_flutter/hmssdk_flutter.dart';
import 'package:provider/provider.dart';
-import 'package:tuple/tuple.dart';
///Project imports
-import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
+import 'package:hms_room_kit/src/common/utility_components.dart';
+import 'package:hms_room_kit/src/hls_viewer/hls_player_store.dart';
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_title_text.dart';
-import 'package:hms_room_kit/src/common/utility_functions.dart';
-import 'package:hms_room_kit/src/widgets/common_widgets/live_badge.dart';
///[HLSViewerHeader] is the header of the HLS Viewer screen
class HLSViewerHeader extends StatelessWidget {
- const HLSViewerHeader({super.key});
+ final bool hasHLSStarted;
+ const HLSViewerHeader({super.key, required this.hasHLSStarted});
@override
Widget build(BuildContext context) {
@@ -35,165 +26,81 @@ class HLSViewerHeader extends StatelessWidget {
HMSThemeColors.backgroundDim.withAlpha(0)
])),
child: Padding(
- padding:
- EdgeInsets.only(left: 15, right: 15, top: Platform.isIOS ? 55 : 45),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Row(
- children: [
- ///We render the logo as set in the dashboard
- HMSRoomLayout.roleLayoutData?.logo?.url == null
- ? Container()
- : HMSRoomLayout.roleLayoutData!.logo!.url!.contains("svg")
- ? SvgPicture.network(
- HMSRoomLayout.roleLayoutData!.logo!.url!,
- height: 30,
- width: 30,
- )
- : Image.network(
- HMSRoomLayout.roleLayoutData!.logo!.url!,
- errorBuilder: (context, exception, _) {
- log('Error is $exception');
- return const SizedBox(
- width: 30,
- height: 30,
- );
- },
- height: 30,
- width: 30,
- ),
- const SizedBox(
- width: 12,
- ),
-
- ///We render the LIVE icon based on the HLS streaming status
- ///If the HLS streaming is started we show the LIVE icon
- ///If the HLS streaming is not started we show nothing
- Selector(
- selector: (_, meetingStore) =>
- (meetingStore.streamingType['hls'] ==
- HMSStreamingState.started ||
- meetingStore.streamingType['rtmp'] ==
- HMSStreamingState.started),
- builder: (_, isHLSStarted, __) {
- return isHLSStarted ? const LiveBadge() : Container();
- }),
- const SizedBox(
- width: 8,
- ),
-
- ///We render the recording icon based on the recording status
- ///If the recording is started we show the recording icon
- ///If the recording is not started we show nothing
- ///
- ///If recording initialising state is true we show the loader
- Selector<
- MeetingStore,
- Tuple3>(
- selector: (_, meetingStore) => Tuple3(
- meetingStore.recordingType["browser"] ??
- HMSRecordingState.none,
- meetingStore.recordingType["server"] ??
- HMSRecordingState.none,
- meetingStore.recordingType["hls"] ??
- HMSRecordingState.none),
- builder: (_, data, __) {
- return (data.item1 == HMSRecordingState.started ||
- data.item1 == HMSRecordingState.resumed ||
- data.item2 == HMSRecordingState.started ||
- data.item2 == HMSRecordingState.resumed ||
- data.item3 == HMSRecordingState.started ||
- data.item3 == HMSRecordingState.resumed)
- ? SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/record.svg",
- height: 24,
- width: 24,
- colorFilter: ColorFilter.mode(
- HMSThemeColors.alertErrorDefault,
- BlendMode.srcIn),
+ padding: EdgeInsets.only(left: 12, right: 12),
+ child: Selector(
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.areStreamControlsVisible,
+ builder: (_, areStreamControlsVisible, __) {
+ return areStreamControlsVisible
+ ? Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ children: [
+ ///This renders the [Close Button] and is always visible iff the controls are visible
+ IconButton(
+ icon: Icon(
+ Icons.close,
+ color: HMSThemeColors.onSurfaceHighEmphasis,
+ size: 24,
+ ),
+ onPressed: () {
+ UtilityComponents.onBackPressed(context);
+ },
)
- : (data.item1 == HMSRecordingState.starting ||
- data.item2 == HMSRecordingState.starting ||
- data.item3 == HMSRecordingState.starting)
- ? SizedBox(
- height: 24,
- width: 24,
- child: CircularProgressIndicator(
- strokeWidth: 1,
- color: HMSThemeColors.onSurfaceHighEmphasis,
- ))
- : (data.item1 == HMSRecordingState.paused ||
- data.item2 == HMSRecordingState.paused ||
- data.item3 == HMSRecordingState.paused)
- ? SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/recording_paused.svg",
- height: 24,
- width: 24,
- colorFilter: ColorFilter.mode(
- HMSThemeColors.onSurfaceHighEmphasis,
- BlendMode.srcIn),
- )
- : Container();
- }),
- const SizedBox(
- width: 8,
- ),
+ ],
+ ),
+
+ ///This renders the [Caption Button] and [Settings Button] only if the controls are visible
+ ///and the HLS has started
+ // if (hasHLSStarted)
+ // Row(
+ // mainAxisAlignment: MainAxisAlignment.end,
+ // children: [
+ // ///The caption button is only rendered when closed captions are supported
+ // ///and the HLS has started
+ // Selector>(
+ // selector: (_, hlsPlayerStore) => Tuple2(
+ // hlsPlayerStore.isCaptionEnabled,
+ // hlsPlayerStore.areCaptionsSupported),
+ // builder: (_, captionsData, __) {
+ // return captionsData.item2
+ // ? InkWell(
+ // onTap: () {
+ // context
+ // .read()
+ // .toggleCaptions();
+ // },
+ // child: SvgPicture.asset(
+ // "packages/hms_room_kit/lib/src/assets/icons/caption_${captionsData.item1 ? "on" : "off"}.svg",
+ // colorFilter: ColorFilter.mode(
+ // HMSThemeColors
+ // .onSurfaceHighEmphasis,
+ // BlendMode.srcIn),
+ // semanticsLabel:
+ // "caption_toggle_button",
+ // ),
+ // )
+ // : const SizedBox();
+ // }),
+ // const SizedBox(
+ // width: 16,
+ // ),
- ///This renders the number of peers
- ///If the HLS or RTMP streaming is started, we render the number of peers
- ///else we render an empty Container
- Selector>(
- selector: (_, meetingStore) => Tuple2(
- meetingStore.streamingType['hls'] ==
- HMSStreamingState.started ||
- meetingStore.streamingType['rtmp'] ==
- HMSStreamingState.started,
- meetingStore.peersInRoom),
- builder: (_, data, __) {
- return data.item1
- ? Container(
- width: 59,
- height: 24,
- decoration: BoxDecoration(
- border: Border.all(
- color: HMSThemeColors.borderBright,
- width: 1),
- borderRadius: const BorderRadius.all(
- Radius.circular(4)),
- color: HMSThemeColors.backgroundDim
- .withOpacity(0.64)),
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/watching.svg",
- width: 16,
- height: 16,
- colorFilter: ColorFilter.mode(
- HMSThemeColors.onSurfaceHighEmphasis,
- BlendMode.srcIn),
- semanticsLabel: "fl_watching",
- ),
- const SizedBox(
- width: 4,
- ),
- HMSTitleText(
- text: Utilities.formatNumber(data.item2),
- fontSize: 10,
- lineHeight: 10,
- letterSpacing: 1.5,
- textColor:
- HMSThemeColors.onSurfaceHighEmphasis)
- ],
- ))
- : Container();
- })
- ],
- ),
- ],
- ),
+ // ///This renders the settings button
+ // SvgPicture.asset(
+ // "packages/hms_room_kit/lib/src/assets/icons/settings.svg",
+ // colorFilter: ColorFilter.mode(
+ // HMSThemeColors.onSurfaceHighEmphasis,
+ // BlendMode.srcIn),
+ // semanticsLabel: "caption_toggle_button",
+ // )
+ // ],
+ // )
+ ],
+ )
+ : const SizedBox();
+ }),
),
);
}
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_page.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_page.dart
index 75ad91091..73bfda9fe 100644
--- a/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_page.dart
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_viewer_page.dart
@@ -5,26 +5,24 @@ import 'dart:math';
///Package imports
import 'package:flutter/material.dart';
-import 'package:hms_room_kit/src/widgets/toasts/toast_widget.dart';
import 'package:provider/provider.dart';
import 'package:tuple/tuple.dart';
import 'package:hmssdk_flutter/hmssdk_flutter.dart';
///Project imports
+import 'package:hms_room_kit/src/widgets/bottom_sheets/refresh_stream_bottom_sheet.dart';
+import 'package:hms_room_kit/src/hls_viewer/hls_player_desktop_controls.dart';
+import 'package:hms_room_kit/src/widgets/toasts/toast_widget.dart';
import 'package:hms_room_kit/src/widgets/app_dialogs/audio_device_change_dialog.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_left_room_screen.dart';
import 'package:hms_room_kit/src/widgets/toasts/hms_toast_model.dart';
-import 'package:hms_room_kit/src/hls_viewer/hls_viewer_bottom_navigation_bar.dart';
-import 'package:hms_room_kit/src/hls_viewer/hls_viewer_header.dart';
import 'package:hms_room_kit/src/layout_api/hms_theme_colors.dart';
import 'package:hms_room_kit/src/preview_for_role/preview_for_role_bottom_sheet.dart';
import 'package:hms_room_kit/src/preview_for_role/preview_for_role_header.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_circular_avatar.dart';
import 'package:hms_room_kit/src/common/utility_components.dart';
-import 'package:hms_room_kit/src/common/utility_functions.dart';
import 'package:hms_room_kit/src/hls_viewer/hls_player.dart';
import 'package:hms_room_kit/src/hls_viewer/hls_player_store.dart';
-import 'package:hms_room_kit/src/hls_viewer/hls_waiting_ui.dart';
import 'package:hms_room_kit/src/meeting/meeting_store.dart';
///[HLSViewerPage] is the page that is used to render the HLS Viewer
@@ -37,6 +35,10 @@ class HLSViewerPage extends StatefulWidget {
}
class _HLSViewerPageState extends State {
+ ///These variables keep track of height and width of the screen
+ double height = 0.0;
+ double width = 0.0;
+
@override
void initState() {
super.initState();
@@ -44,10 +46,19 @@ class _HLSViewerPageState extends State {
///We start the timer to hide the controls
WidgetsBinding.instance.addPostFrameCallback((_) {
context.read().startTimerToHideButtons();
+ HMSHLSPlayerController.addHMSHLSPlaybackEventsListener(
+ context.read());
});
}
}
+ @override
+ void didChangeDependencies() {
+ super.didChangeDependencies();
+ height = MediaQuery.of(context).size.height;
+ width = MediaQuery.of(context).size.width;
+ }
+
///This function is used to set the stream status
void _setStreamStatus(bool hasHlsStarted) {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
@@ -55,6 +66,13 @@ class _HLSViewerPageState extends State {
});
}
+ @override
+ void deactivate() {
+ HMSHLSPlayerController.removeHMSHLSPlaybackEventsListener(
+ context.read());
+ super.deactivate();
+ }
+
@override
Widget build(BuildContext context) {
return WillPopScope(
@@ -83,18 +101,18 @@ class _HLSViewerPageState extends State {
builder: (_, isPipActive, __) {
return isPipActive
? HMSHLSPlayer()
- : Scaffold(
- backgroundColor: HMSThemeColors.backgroundDim,
- body: Theme(
- data: ThemeData(
- brightness: Brightness.dark,
- primaryColor: HMSThemeColors.primaryDefault,
- scaffoldBackgroundColor:
- HMSThemeColors.backgroundDim),
- child: SingleChildScrollView(
+ : SafeArea(
+ child: Scaffold(
+ backgroundColor: HMSThemeColors.backgroundDim,
+ body: Theme(
+ data: ThemeData(
+ brightness: Brightness.dark,
+ primaryColor: HMSThemeColors.primaryDefault,
+ scaffoldBackgroundColor:
+ HMSThemeColors.backgroundDim),
child: SizedBox(
- width: MediaQuery.of(context).size.width,
- height: MediaQuery.of(context).size.height,
+ width: width,
+ height: height,
child: Stack(
children: [
Selector(
@@ -102,69 +120,40 @@ class _HLSViewerPageState extends State {
meetingStore.hasHlsStarted,
builder: (_, hasHlsStarted, __) {
_setStreamStatus(hasHlsStarted);
- return (hasHlsStarted)
- ? SizedBox(
- width: MediaQuery.of(context)
- .size
- .width,
- height: MediaQuery.of(context)
- .size
- .height,
- child: HLSPlayer(
- key: Key(context
- .read<
- MeetingStore>()
- .localPeer
- ?.peerId ??
- "HLS_PLAYER"),
- ratio: Utilities
- .getHLSPlayerDefaultRatio(
- MediaQuery.of(
- context)
- .size),
- ),
- )
- : SizedBox(
- width: MediaQuery.of(context)
- .size
- .width,
- height: MediaQuery.of(context)
- .size
- .height,
- child: const HLSWaitingUI());
- }),
- ///Will only be displayed when the controls are visible
- SizedBox(
- height:
- MediaQuery.of(context).size.height,
- child: Column(
- mainAxisAlignment:
- MainAxisAlignment.spaceBetween,
- children: [
- Selector(
+ return Selector(
selector: (_, hlsPlayerStore) =>
- hlsPlayerStore
- .areStreamControlsVisible,
- builder: (_,
- areStreamControlsVisible,
- __) {
- return AnimatedContainer(
- duration: const Duration(
- milliseconds: 200),
- height:
- areStreamControlsVisible
- ? 100
- : 0,
- child: areStreamControlsVisible
- ? const HLSViewerHeader()
- : Container(),
+ hlsPlayerStore.isFullScreen,
+ builder: (_, isFullScreen, __) {
+ double widgetHeight = height -
+ MediaQuery.of(context)
+ .viewPadding
+ .top -
+ MediaQuery.of(context)
+ .viewPadding
+ .bottom;
+ return Column(
+ mainAxisAlignment:
+ isFullScreen
+ ? MainAxisAlignment
+ .center
+ : MainAxisAlignment
+ .start,
+ children: [
+ ///Renders HLS Player
+ SizedBox(
+ width: width,
+ height: isFullScreen
+ ? widgetHeight
+ : widgetHeight * 0.27,
+ child: const HLSPlayer(),
+ ),
+ if (!isFullScreen)
+ HLSPlayerDesktopControls()
+ ],
);
- }),
- const HLSViewerBottomNavigationBar()
- ],
- ),
- ),
+ });
+ }),
///This renders the preview for role component
Selector<
@@ -282,6 +271,7 @@ class _HLSViewerPageState extends State {
return Container();
}),
+ ///This renders toasts
Selector(
selector: (_, meetingStore) =>
@@ -390,6 +380,7 @@ class _HLSViewerPageState extends State {
}).toList());
}),
+ ///This renders the reconnection dialog
Selector(
selector: (_, meetingStore) =>
meetingStore.reconnecting,
@@ -401,6 +392,21 @@ class _HLSViewerPageState extends State {
}
return const SizedBox();
}),
+
+ ///This renders the bottom sheet for the stream error
+ ///with a button refresh the stream
+ Selector(
+ selector: (_, hlsPlayerStore) =>
+ hlsPlayerStore.isPlayerFailed,
+ builder: (_, isPlayerFailed, __) {
+ return Positioned(
+ bottom: 0,
+ child: isPlayerFailed?RefreshStreamBottomSheet():const SizedBox());
+ },
+ ),
+
+ ///Renders the error toast with a leave button since the
+ ///error is irrecoverable
if (failureData.item2 != null &&
(failureData.item2?.code?.errorCode ==
1003 ||
diff --git a/packages/hms_room_kit/lib/src/hls_viewer/hls_waiting_ui.dart b/packages/hms_room_kit/lib/src/hls_viewer/hls_waiting_ui.dart
index dd12f6881..15a0a4311 100644
--- a/packages/hms_room_kit/lib/src/hls_viewer/hls_waiting_ui.dart
+++ b/packages/hms_room_kit/lib/src/hls_viewer/hls_waiting_ui.dart
@@ -15,40 +15,43 @@ class HLSWaitingUI extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- CircleAvatar(
- radius: 50,
- backgroundColor: HMSThemeColors.surfaceDefault,
- child: SvgPicture.asset(
- "packages/hms_room_kit/lib/src/assets/icons/live.svg",
- height: 56,
- width: 56,
- colorFilter: ColorFilter.mode(
- HMSThemeColors.onSurfaceHighEmphasis, BlendMode.srcIn),
+ return SingleChildScrollView(
+ physics: NeverScrollableScrollPhysics(),
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ CircleAvatar(
+ radius: 50,
+ backgroundColor: HMSThemeColors.surfaceDefault,
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/live.svg",
+ height: 56,
+ width: 56,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.onSurfaceHighEmphasis, BlendMode.srcIn),
+ ),
),
- ),
- const SizedBox(
- height: 24,
- ),
- HMSTitleText(
- text: "Stream yet to start",
- textColor: HMSThemeColors.onSurfaceHighEmphasis,
- fontSize: 24,
- lineHeight: 32,
- letterSpacing: 0.25,
- ),
- const SizedBox(
- height: 8,
- ),
- HMSSubheadingText(
- text: "Sit back and relax",
- fontSize: 16,
- lineHeight: 24,
- letterSpacing: 0.5,
- textColor: HMSThemeColors.onSurfaceMediumEmphasis)
- ],
+ const SizedBox(
+ height: 24,
+ ),
+ HMSTitleText(
+ text: "Stream yet to start",
+ textColor: HMSThemeColors.onSurfaceHighEmphasis,
+ fontSize: 24,
+ lineHeight: 32,
+ letterSpacing: 0.25,
+ ),
+ const SizedBox(
+ height: 8,
+ ),
+ HMSSubheadingText(
+ text: "Sit back and relax",
+ fontSize: 16,
+ lineHeight: 24,
+ letterSpacing: 0.5,
+ textColor: HMSThemeColors.onSurfaceMediumEmphasis)
+ ],
+ ),
);
}
}
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 9c630c695..6ae2eefe4 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
@@ -77,7 +77,32 @@ class HlsLiveStreaming {
}
}
+class Header {
+ String? title;
+ String? description;
+
+ Header({this.title, this.description});
+
+ Header.fromJson(Map? json) {
+ if (json == null) {
+ title = null;
+ description = null;
+ return;
+ }
+ title = json['title'];
+ description = json['description'];
+ }
+
+ Map toJson() {
+ final Map data = {};
+ data['title'] = title;
+ data['description'] = description;
+ return data;
+ }
+}
+
class Elements {
+ Header? header;
Chat? chat;
Map? participantList;
VideoTileLayout? videoTileLayout;
@@ -86,7 +111,8 @@ class Elements {
Map? brb;
Elements(
- {this.chat,
+ {this.header,
+ this.chat,
this.participantList,
this.videoTileLayout,
this.emojiReactions,
@@ -95,6 +121,7 @@ class Elements {
Elements.fromJson(Map? json) {
if (json == null) {
+ header = null;
chat = null;
participantList = null;
videoTileLayout = null;
@@ -103,6 +130,10 @@ class Elements {
brb = null;
return;
}
+
+ header = (json.containsKey('header') && json['header'] != null)
+ ? Header.fromJson(json['header'])
+ : null;
chat = (json.containsKey('chat') && json['chat'] != null)
? Chat.fromJson(json['chat'])
: null;
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 f291cf09c..af3ed5d78 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
@@ -1,6 +1,6 @@
-///Package imports
library;
+///Package imports
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:provider/provider.dart';
@@ -8,7 +8,7 @@ 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/overlay_chat_component.dart';
+import 'package:hms_room_kit/src/widgets/chat_widgets/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';
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 caecb2613..c205caf92 100644
--- a/packages/hms_room_kit/lib/src/meeting/meeting_store.dart
+++ b/packages/hms_room_kit/lib/src/meeting/meeting_store.dart
@@ -218,12 +218,6 @@ class MeetingStore extends ChangeNotifier
String? spotlightMetadata;
- ///HLS Player Stats
-
- HMSHLSPlayerStats? hlsPlayerStats;
-
- bool isHLSStatsEnabled = false;
-
bool isDefaultAspectRatioSelected = true;
int currentPage = 0;
@@ -2704,6 +2698,9 @@ class MeetingStore extends ChangeNotifier
notifyListeners();
}
+ @override
+ void onVideoSizeChanged({required Size size}) {}
+
@override
void onCue({required HMSHLSCue hlsCue}) {
log("onCue -> payload:${hlsCue.startDate}");
@@ -2758,36 +2755,16 @@ class MeetingStore extends ChangeNotifier
}
@override
- void onPlaybackFailure({required String? error}) {
- Utilities.showToast("Playback failure $error");
- }
+ void onPlaybackFailure({required String? error}) {}
@override
- void onPlaybackStateChanged({required HMSHLSPlaybackState playbackState}) {
- Utilities.showToast("Playback state changed to ${playbackState.name}");
- }
+ void onPlaybackStateChanged({required HMSHLSPlaybackState playbackState}) {}
@override
- void onHLSError({required HMSException hlsException}) {
- // TODO: implement onHLSError
- }
+ void onHLSError({required HMSException hlsException}) {}
@override
- void onHLSEventUpdate({required HMSHLSPlayerStats playerStats}) {
- log("onHLSEventUpdate-> bitrate:${playerStats.averageBitrate} buffered duration: ${playerStats.bufferedDuration}");
- hlsPlayerStats = playerStats;
- notifyListeners();
- }
-
- void setHLSPlayerStats(bool value) {
- isHLSStatsEnabled = value;
- if (!value) {
- HMSHLSPlayerController.removeHLSStatsListener();
- } else {
- HMSHLSPlayerController.addHLSStatsListener();
- }
- notifyListeners();
- }
+ void onHLSEventUpdate({required HMSHLSPlayerStats playerStats}) {}
///Insert poll question
void insertPollQuestion(HMSPollStore store) {
diff --git a/packages/hms_room_kit/lib/src/preview/preview_bottom_button_section.dart b/packages/hms_room_kit/lib/src/preview/preview_bottom_button_section.dart
index 4dae03d6b..7ade631bf 100644
--- a/packages/hms_room_kit/lib/src/preview/preview_bottom_button_section.dart
+++ b/packages/hms_room_kit/lib/src/preview/preview_bottom_button_section.dart
@@ -102,7 +102,15 @@ class PreviewBottomButtonSection extends StatelessWidget {
),
Row(
children: [
- if (previewStore.isNoiseCancellationAvailable &&
+ ///This renders the [Noise Cancellation Button] only if the
+ ///Peer role has the permission to publish audio
+ ///and the Peer is not null
+ ///and the noise cancellation is available
+ ///and mic is unmuted
+ if ((previewStore.peer?.role.publishSettings?.allowed
+ .contains("audio") ??
+ false) &&
+ previewStore.isNoiseCancellationAvailable &&
previewStore.isAudioOn)
Padding(
padding: const EdgeInsets.only(right: 8.0),
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 8286a0368..d7d66bf06 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,5 +1,6 @@
//Package imports
import 'package:flutter/material.dart';
+import 'package:hms_room_kit/src/hls_viewer/hls_hand_raise_menu.dart';
import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
import 'package:intl/intl.dart';
import 'package:provider/provider.dart';
@@ -20,7 +21,8 @@ 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});
+ final bool isHLSChat;
+ const ChatBottomSheet({super.key, this.isHLSChat = false});
@override
State createState() => _ChatBottomSheetState();
@@ -110,106 +112,133 @@ class _ChatBottomSheetState extends State {
return true;
},
child: SafeArea(
- 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.isEmpty)
- ? Expanded(
- child: SingleChildScrollView(
- physics:
- const NeverScrollableScrollPhysics(),
- child: ConstrainedBox(
- constraints: BoxConstraints(
- minHeight: MediaQuery.of(context)
- .size
- .height *
- 0.6,
+ child: Padding(
+ padding: EdgeInsets.symmetric(horizontal: widget.isHLSChat ? 16 : 0),
+ 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.isEmpty)
+ ? Expanded(
+ child: SingleChildScrollView(
+ physics:
+ const NeverScrollableScrollPhysics(),
+ child: ConstrainedBox(
+ constraints: BoxConstraints(
+ minHeight: MediaQuery.of(context)
+ .size
+ .height *
+ 0.5,
+ ),
+ 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(
+ isHLSChat:
+ widget.isHLSChat,
+ message:
+ data.item1[index],
+ );
+ }),
+ ],
),
- 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],
- );
- }),
- ],
),
- ),
- )
- ]),
- );
- },
- ),
-
- /// 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),
-
- ///Text Field
- if ((HMSRoomLayout.chatData?.isPrivateChatEnabled ?? false) ||
- (HMSRoomLayout.chatData?.isPublicChatEnabled ?? false) ||
- (HMSRoomLayout.chatData?.rolesWhitelist.isNotEmpty ??
- false))
- ChatTextField(sendMessage: sendMessage)
- ],
+ )
+ ]),
+ );
+ },
+ ),
+
+ /// 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),
+
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.end,
+ children: [
+ ///Text Field
+ if ((HMSRoomLayout.chatData?.isPrivateChatEnabled ??
+ false) ||
+ (HMSRoomLayout.chatData?.isPublicChatEnabled ??
+ false) ||
+ (HMSRoomLayout
+ .chatData?.rolesWhitelist.isNotEmpty ??
+ false))
+ Expanded(
+ child: Row(
+ children: [
+ ChatTextField(
+ sendMessage: sendMessage,
+ isHLSChat: widget.isHLSChat,
+ ),
+ ],
+ ),
+ ),
+ if (widget.isHLSChat) HLSHandRaiseMenu()
+ ],
+ )
+ ],
+ ),
),
- ),
- 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();
- })
- ],
+ 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/hls_app_utilities_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/hls_app_utilities_bottom_sheet.dart
index 8d8c42d20..e1eef8af9 100644
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/hls_app_utilities_bottom_sheet.dart
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/hls_app_utilities_bottom_sheet.dart
@@ -15,7 +15,6 @@ import 'package:hms_room_kit/src/widgets/common_widgets/hms_cross_button.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/more_option_item.dart';
import 'package:hms_room_kit/src/layout_api/hms_room_layout.dart';
import 'package:hms_room_kit/src/widgets/bottom_sheets/overlay_participants_bottom_sheet.dart';
-import 'package:hms_room_kit/src/widgets/tab_widgets/chat_participants_tab_bar.dart';
///[HLSAppUtilitiesBottomSheet] is a bottom sheet that is used to show more options in the meeting
class HLSAppUtilitiesBottomSheet extends StatefulWidget {
@@ -100,13 +99,7 @@ class _HLSMoreOptionsBottomSheetBottomSheetState
context: context,
builder: (ctx) => ChangeNotifierProvider.value(
value: meetingStore,
- child: (HMSRoomLayout.chatData == null ||
- (HMSRoomLayout.chatData?.isOverlay ??
- true))
- ? const OverlayParticipantsBottomSheet()
- : const ChatParticipantsTabBar(
- tabIndex: 1,
- )),
+ child: const OverlayParticipantsBottomSheet()),
);
},
optionIcon: badge.Badge(
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/leave_session_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/leave_session_bottom_sheet.dart
index b85347fb4..11cb839a6 100644
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/leave_session_bottom_sheet.dart
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/leave_session_bottom_sheet.dart
@@ -1,11 +1,17 @@
+library;
+
+///Package imports
import 'package:flutter/material.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/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/end_service_bottom_sheet.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart';
import 'package:hms_room_kit/src/widgets/common_widgets/leave_session_tile.dart';
-import 'package:provider/provider.dart';
class LeaveSessionBottomSheet extends StatefulWidget {
final MeetingStore meetingStore;
@@ -29,6 +35,8 @@ class _LeaveSessionBottomSheetState extends State {
super.deactivate();
}
+ ///Here we render bottom sheet with leave and end options
+
@override
Widget build(BuildContext context) {
return ((widget.meetingStore.localPeer?.role.permissions.endRoom ??
@@ -74,7 +82,8 @@ class _LeaveSessionBottomSheetState extends State {
widget.meetingStore.leave(),
},
title: HMSTitleText(
- text: "Leave Session",
+ text:
+ "Leave ${HMSRoomLayout.peerType == PeerRoleType.conferencing ? "Session" : "Stream"}",
textColor: HMSThemeColors.alertErrorDefault,
letterSpacing: 0.15,
fontSize: 20,
@@ -89,11 +98,12 @@ class _LeaveSessionBottomSheetState extends State {
),
subTitle: HMSSubheadingText(
text:
- "Others will continue after you leave. You can join\n the session again.",
+ "Others will continue after you leave. You can join the session again.",
maxLines: 2,
textColor: HMSThemeColors.onSurfaceMediumEmphasis,
),
- buttonText: "Leave Session",
+ buttonText:
+ "Leave ${HMSRoomLayout.peerType == PeerRoleType.conferencing ? "Session" : "Stream"}",
),
),
)
@@ -200,7 +210,8 @@ class _LeaveSessionBottomSheetState extends State {
widget.meetingStore.leave(),
},
title: HMSTitleText(
- text: "Leave Session",
+ text:
+ "Leave ${HMSRoomLayout.peerType == PeerRoleType.conferencing ? "Session" : "Stream"}",
textColor: HMSThemeColors.alertErrorDefault,
letterSpacing: 0.15,
fontSize: 20,
@@ -214,11 +225,12 @@ class _LeaveSessionBottomSheetState extends State {
),
subTitle: HMSSubheadingText(
text:
- "Others will continue after you leave. You can join\n the session again.",
+ "Others will continue after you leave. You can join the session again.",
maxLines: 2,
textColor: HMSThemeColors.onSurfaceMediumEmphasis,
),
- buttonText: "Leave Session",
+ buttonText:
+ "Leave ${HMSRoomLayout.peerType == PeerRoleType.conferencing ? "Session" : "Stream"}",
),
);
}
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 08879449e..6709937d8 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
@@ -242,7 +242,7 @@ class _ParticipantsBottomSheetState extends State {
),
if (mutePermission &&
peerTrackNode != null &&
- !peerTrackNode.peer.isLocal)
+ !peerTrackNode.peer.isLocal && peerTrackNode.peer.type == HMSPeerType.regular)
PopupMenuItem(
value: 3,
child: Row(children: [
@@ -271,7 +271,7 @@ class _ParticipantsBottomSheetState extends State {
),
if (mutePermission &&
peerTrackNode != null &&
- !peerTrackNode.peer.isLocal)
+ !peerTrackNode.peer.isLocal && peerTrackNode.peer.type == HMSPeerType.regular)
PopupMenuItem(
value: 4,
child: Row(children: [
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/refresh_stream_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/refresh_stream_bottom_sheet.dart
new file mode 100644
index 000000000..f09159132
--- /dev/null
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/refresh_stream_bottom_sheet.dart
@@ -0,0 +1,118 @@
+library;
+
+///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/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_title_text.dart';
+
+
+///[RefreshStreamBottomSheet] is a bottom sheet that is used to render the bottom sheet to refresh the stream
+class RefreshStreamBottomSheet extends StatefulWidget {
+ const RefreshStreamBottomSheet({super.key});
+
+ @override
+ State createState() =>
+ _RefreshStreamBottomSheetState();
+}
+
+class _RefreshStreamBottomSheetState extends State {
+ @override
+ void initState() {
+ super.initState();
+ context.read().addBottomSheet(context);
+ }
+
+ @override
+ void deactivate() {
+ context.read().removeBottomSheet(context);
+ super.deactivate();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ height: 192,
+ decoration: BoxDecoration(
+ color: HMSThemeColors.surfaceDim,
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(16), topRight: Radius.circular(16)),
+ ),
+ child: Padding(
+ padding: const EdgeInsets.only(top: 16.0, left: 20, right: 20),
+ child: Container(
+ width: MediaQuery.of(context).size.width - 40,
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Row(
+ children: [
+ SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/end_warning.svg",
+ height: 20,
+ width: 20,
+ colorFilter: ColorFilter.mode(
+ HMSThemeColors.alertErrorDefault, BlendMode.srcIn),
+ ),
+ const SizedBox(
+ width: 8,
+ ),
+ HMSTitleText(
+ text: "Playback Error",
+ textColor: HMSThemeColors.alertErrorDefault,
+ letterSpacing: 0.15,
+ fontSize: 20,
+ )
+ ],
+ ),
+ ],
+ ),
+ const SizedBox(
+ height: 8,
+ ),
+ HMSSubheadingText(
+ text:
+ "Something went wrong with the stream. Please tap on ‘Refresh Stream’ to retry.",
+ maxLines: 3,
+ textColor: HMSThemeColors.onSurfaceMediumEmphasis,
+ ),
+ const SizedBox(
+ height: 16,
+ ),
+ ElevatedButton(
+ style: ButtonStyle(
+ shadowColor:
+ MaterialStateProperty.all(HMSThemeColors.surfaceDim),
+ backgroundColor: MaterialStateProperty.all(
+ HMSThemeColors.primaryDefault),
+ shape: MaterialStateProperty.all(
+ RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(8.0),
+ ))),
+ onPressed: () {
+ HMSHLSPlayerController.start();
+ },
+ child: SizedBox(
+ height: 48,
+ child: Center(
+ child: HMSTitleText(
+ text: "Refresh Stream",
+ textColor: HMSThemeColors.baseWhite),
+ ),
+ ))
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/remote_peer_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/remote_peer_bottom_sheet.dart
index 8ed1fec2e..3a10f7678 100644
--- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/remote_peer_bottom_sheet.dart
+++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/remote_peer_bottom_sheet.dart
@@ -158,8 +158,8 @@ class _RemotePeerBottomSheetState extends State {
// text: "Spotlight Tile for Everyone",
// textColor: HMSThemeColors.onSurfaceHighEmphasis)),
- if (widget.meetingStore.localPeer?.role.permissions.mute ??
- false)
+ if ((widget.meetingStore.localPeer?.role.permissions.mute ??
+ false) && widget.peerTrackNode.peer.type == HMSPeerType.regular)
ListTile(
horizontalTitleGap: 2,
onTap: () async {
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
index cf25706c5..30fbdc3c8 100644
--- 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
@@ -23,8 +23,12 @@ import 'package:hms_room_kit/src/widgets/toasts/hms_toast_button.dart';
class ChatTextField extends StatefulWidget {
final Function sendMessage;
final Color? toastBackgroundColor;
+ final bool isHLSChat;
const ChatTextField(
- {Key? key, required this.sendMessage, this.toastBackgroundColor})
+ {Key? key,
+ required this.sendMessage,
+ this.toastBackgroundColor,
+ this.isHLSChat = false})
: super(key: key);
@override
@@ -48,211 +52,212 @@ class _ChatTextFieldState extends State {
@override
Widget build(BuildContext context) {
- return Selector>>(
+ double width = MediaQuery.of(context).size.width - 32;
+ return SizedBox(
+ height: 40,
+ width: widget.isHLSChat ? width * 0.7 : width,
+ child: 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),
- ),
+ ///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
+
+ ///If chat is not paused we render the text field
+ ///else we render the paused chat toast
+ ? Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: chatControls.item3.contains(context
+ .read()
+ .localPeer
+ ?.customerUserId)
+
+ ///If the user is blocked from sending messages
+ ? 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,
+ ),
+ ],
+ )
+ : Row(
+ children: [
+ Expanded(
+ child: Container(
+ color: HMSThemeColors.surfaceDefault,
+ child: Selector(
+ selector: (_, meetingStore) =>
+ meetingStore.recipientSelectorValue,
+ builder: (_, selectedValue, __) {
+ return TextField(
+ ///Here if the selected value is empty or equal to "Choose a Recipient" we disable the text field
+ 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(
+ isDense: true,
+ suffixIcon: GestureDetector(
+ onTap: () {
+ if (messageTextController
+ .text
+ .trim()
+ .isEmpty) {
+ Utilities.showToast(
+ "Message can't be empty");
+ }
+ widget.sendMessage(
+ messageTextController);
+ messageTextController
+ .clear();
+ },
+ child: SvgPicture.asset(
+ "packages/hms_room_kit/lib/src/assets/icons/send_message.svg",
+ fit: BoxFit.scaleDown,
+ colorFilter: ColorFilter.mode(
+ messageTextController
+ .text
+ .trim()
+ .isEmpty
+ ? HMSThemeColors
+ .onSurfaceLowEmphasis
+ : HMSThemeColors
+ .onSurfaceHighEmphasis,
+ BlendMode.srcIn),
+ )),
+ 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.symmetric(
+ vertical: 8,
+ horizontal: 12),
+ 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,
)
- : null,
- );
- });
+ ],
+ ),
+ 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/hls_viewer/overlay_chat_component.dart b/packages/hms_room_kit/lib/src/widgets/chat_widgets/overlay_chat_component.dart
similarity index 100%
rename from packages/hms_room_kit/lib/src/hls_viewer/overlay_chat_component.dart
rename to packages/hms_room_kit/lib/src/widgets/chat_widgets/overlay_chat_component.dart
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
index 7920e612e..9c2c962e0 100644
--- 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
@@ -71,7 +71,7 @@ class _ReceipientSelectorChipState extends State {
}
},
child: Padding(
- padding: const EdgeInsets.only(bottom: 8.0, top: 16),
+ padding: const EdgeInsets.only(bottom: 8.0),
child: Row(
children: [
Padding(
diff --git a/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_subheading_text.dart b/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_subheading_text.dart
index 8f511bb9c..f1f8fbf57 100644
--- a/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_subheading_text.dart
+++ b/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_subheading_text.dart
@@ -28,7 +28,7 @@ class HMSSubheadingText extends StatelessWidget {
final FontWeight? fontWeight;
final TextOverflow? textOverflow;
final TextAlign? textAlign;
- final int maxLines;
+ final int? maxLines;
const HMSSubheadingText(
{Key? key,
required this.text,
@@ -36,7 +36,7 @@ class HMSSubheadingText extends StatelessWidget {
this.letterSpacing = 0.25,
this.lineHeight = 20,
this.fontSize = 14,
- this.maxLines = 1,
+ this.maxLines,
this.fontWeight = FontWeight.w400,
this.textOverflow = TextOverflow.ellipsis,
this.textAlign = TextAlign.start})
diff --git a/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_subtitle_text.dart b/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_subtitle_text.dart
index 6cd6e9bda..248eacedd 100644
--- a/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_subtitle_text.dart
+++ b/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_subtitle_text.dart
@@ -37,7 +37,7 @@ class HMSSubtitleText extends StatelessWidget {
this.fontWeight = FontWeight.w400,
this.textOverflow = TextOverflow.ellipsis,
this.textAlign,
- this.maxLines = 1})
+ this.maxLines})
: super(key: key);
@override
diff --git a/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_title_text.dart b/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_title_text.dart
index 945a21979..fd10fa9e4 100644
--- a/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_title_text.dart
+++ b/packages/hms_room_kit/lib/src/widgets/common_widgets/hms_title_text.dart
@@ -24,7 +24,7 @@ class HMSTitleText extends StatelessWidget {
final double? fontSize;
final FontWeight? fontWeight;
final TextOverflow? textOverflow;
- final int maxLines;
+ final int? maxLines;
const HMSTitleText(
{Key? key,
@@ -35,7 +35,7 @@ class HMSTitleText extends StatelessWidget {
this.fontSize = 16,
this.fontWeight = FontWeight.w600,
this.textOverflow = TextOverflow.ellipsis,
- this.maxLines = 1})
+ this.maxLines})
: super(key: key);
@override
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 5b042ac56..d3753bba5 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
@@ -20,12 +20,11 @@ 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 HMSMessage message;
+ final bool isHLSChat;
final DateFormat formatter = DateFormat('hh:mm a');
- MessageContainer({
- Key? key,
- required this.message,
- }) : super(key: key);
+ MessageContainer({Key? key, required this.message, this.isHLSChat = false})
+ : super(key: key);
String sender(HMSMessageRecipient? hmsMessageRecipient) {
if (hmsMessageRecipient == null) return "";
@@ -50,9 +49,13 @@ class MessageContainer extends StatelessWidget {
padding: const EdgeInsets.only(bottom: 8.0),
child: Container(
decoration: BoxDecoration(
- color: sender(message.hmsMessageRecipient) != ""
- ? HMSThemeColors.surfaceDefault
- : HMSThemeColors.surfaceDim,
+ color: isHLSChat
+ ? sender(message.hmsMessageRecipient) != ""
+ ? HMSThemeColors.backgroundDefault
+ : HMSThemeColors.backgroundDim
+ : sender(message.hmsMessageRecipient) != ""
+ ? HMSThemeColors.surfaceDefault
+ : HMSThemeColors.surfaceDim,
borderRadius: BorderRadius.circular(8),
),
child: Padding(
diff --git a/packages/hms_room_kit/pubspec.lock b/packages/hms_room_kit/pubspec.lock
index 652504aca..4b623d248 100644
--- a/packages/hms_room_kit/pubspec.lock
+++ b/packages/hms_room_kit/pubspec.lock
@@ -13,10 +13,10 @@ packages:
dependency: transitive
description:
name: args
- sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596
+ sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
url: "https://pub.dev"
source: hosted
- version: "2.4.2"
+ version: "2.5.0"
async:
dependency: transitive
description:
@@ -61,10 +61,10 @@ packages:
dependency: "direct main"
description:
name: collection
- sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
+ sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
url: "https://pub.dev"
source: hosted
- version: "1.18.0"
+ version: "1.17.2"
convert:
dependency: transitive
description:
@@ -77,10 +77,10 @@ packages:
dependency: transitive
description:
name: cross_file
- sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32"
+ sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5"
url: "https://pub.dev"
source: hosted
- version: "0.3.4+1"
+ version: "0.3.3+7"
crypto:
dependency: transitive
description:
@@ -125,10 +125,10 @@ packages:
dependency: transitive
description:
name: ffi
- sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
+ sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.0"
file:
dependency: transitive
description:
@@ -137,14 +137,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "7.0.0"
- fixnum:
- dependency: transitive
- description:
- name: fixnum
- sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
- url: "https://pub.dev"
- source: hosted
- version: "1.1.0"
flutter:
dependency: "direct main"
description: flutter
@@ -195,20 +187,18 @@ packages:
hmssdk_flutter:
dependency: "direct main"
description:
- path: "packages/hmssdk_flutter"
- ref: develop
- resolved-ref: f23908cdd1254aab1ebe01df6dfc75bdbbd44ae8
- url: "https://github.com/100mslive/100ms-flutter.git"
- source: git
+ path: "../hmssdk_flutter"
+ relative: true
+ source: path
version: "1.10.0"
http:
dependency: transitive
description:
name: http
- sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938"
+ sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525"
url: "https://pub.dev"
source: hosted
- version: "1.2.1"
+ version: "1.1.0"
http_parser:
dependency: transitive
description:
@@ -229,34 +219,10 @@ packages:
dependency: transitive
description:
name: js
- sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf
- url: "https://pub.dev"
- source: hosted
- version: "0.7.1"
- leak_tracker:
- dependency: transitive
- description:
- name: leak_tracker
- sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa"
- url: "https://pub.dev"
- source: hosted
- version: "10.0.0"
- leak_tracker_flutter_testing:
- dependency: transitive
- description:
- name: leak_tracker_flutter_testing
- sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0
- url: "https://pub.dev"
- source: hosted
- version: "2.0.1"
- leak_tracker_testing:
- dependency: transitive
- description:
- name: leak_tracker_testing
- sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47
+ sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3
url: "https://pub.dev"
source: hosted
- version: "2.0.1"
+ version: "0.6.7"
linkify:
dependency: transitive
description:
@@ -285,34 +251,34 @@ packages:
dependency: transitive
description:
name: matcher
- sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
+ sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
url: "https://pub.dev"
source: hosted
- version: "0.12.16+1"
+ version: "0.12.16"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
- sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
+ sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
url: "https://pub.dev"
source: hosted
- version: "0.8.0"
+ version: "0.5.0"
meta:
dependency: transitive
description:
name: meta
- sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
+ sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
url: "https://pub.dev"
source: hosted
- version: "1.11.0"
+ version: "1.9.1"
mime:
dependency: transitive
description:
name: mime
- sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
+ sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e
url: "https://pub.dev"
source: hosted
- version: "1.0.5"
+ version: "1.0.4"
nested:
dependency: transitive
description:
@@ -325,10 +291,10 @@ packages:
dependency: transitive
description:
name: path
- sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
+ sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917"
url: "https://pub.dev"
source: hosted
- version: "1.9.0"
+ version: "1.8.3"
path_parsing:
dependency: transitive
description:
@@ -341,18 +307,18 @@ packages:
dependency: "direct main"
description:
name: path_provider
- sha256: b27217933eeeba8ff24845c34003b003b2b22151de3c908d0e679e8fe1aa078b
+ sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.3"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
- sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668"
+ sha256: "51f0d2c554cfbc9d6a312ab35152fc77e2f0b758ce9f1a444a3a1e5b8f3c6b7f"
url: "https://pub.dev"
source: hosted
- version: "2.2.2"
+ version: "2.2.3"
path_provider_foundation:
dependency: transitive
description:
@@ -389,58 +355,50 @@ packages:
dependency: "direct main"
description:
name: permission_handler
- sha256: "18bf33f7fefbd812f37e72091a15575e72d5318854877e0e4035a24ac1113ecb"
+ sha256: "284a66179cabdf942f838543e10413246f06424d960c92ba95c84439154fcac8"
url: "https://pub.dev"
source: hosted
- version: "11.3.1"
+ version: "11.0.1"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
- sha256: "1acac6bae58144b442f11e66621c062aead9c99841093c38f5bcdcc24c1c3474"
+ sha256: f9fddd3b46109bd69ff3f9efa5006d2d309b7aec0f3c1c5637a60a2d5659e76e
url: "https://pub.dev"
source: hosted
- version: "12.0.5"
+ version: "11.1.0"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
- sha256: e9ad66020b89ff1b63908f247c2c6f931c6e62699b756ef8b3c4569350cd8662
- url: "https://pub.dev"
- source: hosted
- version: "9.4.4"
- permission_handler_html:
- dependency: transitive
- description:
- name: permission_handler_html
- sha256: "54bf176b90f6eddd4ece307e2c06cf977fb3973719c35a93b85cc7093eb6070d"
+ sha256: "99e220bce3f8877c78e4ace901082fb29fa1b4ebde529ad0932d8d664b34f3f5"
url: "https://pub.dev"
source: hosted
- version: "0.1.1"
+ version: "9.1.4"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
- sha256: "48d4fcf201a1dad93ee869ab0d4101d084f49136ec82a8a06ed9cfeacab9fd20"
+ sha256: "6760eb5ef34589224771010805bea6054ad28453906936f843a8cc4d3a55c4a4"
url: "https://pub.dev"
source: hosted
- version: "4.2.1"
+ version: "3.12.0"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
- sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
+ sha256: cc074aace208760f1eee6aa4fae766b45d947df85bc831cde77009cdb4720098
url: "https://pub.dev"
source: hosted
- version: "0.2.1"
+ version: "0.1.3"
petitparser:
dependency: transitive
description:
name: petitparser
- sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
+ sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750
url: "https://pub.dev"
source: hosted
- version: "6.0.2"
+ version: "5.4.0"
platform:
dependency: transitive
description:
@@ -461,10 +419,10 @@ packages:
dependency: transitive
description:
name: pointycastle
- sha256: "43ac87de6e10afabc85c445745a7b799e04de84cebaa4fd7bf55a5e1e9604d29"
+ sha256: "70fe966348fe08c34bf929582f1d8247d9d9408130723206472b4687227e4333"
url: "https://pub.dev"
source: hosted
- version: "3.7.4"
+ version: "3.8.0"
provider:
dependency: "direct main"
description:
@@ -493,10 +451,10 @@ packages:
dependency: "direct main"
description:
name: shared_preferences
- sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02"
+ sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180
url: "https://pub.dev"
source: hosted
- version: "2.2.2"
+ version: "2.2.3"
shared_preferences_android:
dependency: transitive
description:
@@ -533,10 +491,10 @@ packages:
dependency: transitive
description:
name: shared_preferences_web
- sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a"
+ sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf
url: "https://pub.dev"
source: hosted
- version: "2.3.0"
+ version: "2.2.1"
shared_preferences_windows:
dependency: transitive
description:
@@ -570,18 +528,18 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
+ sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
url: "https://pub.dev"
source: hosted
- version: "1.11.1"
+ version: "1.11.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
- sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
+ sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
url: "https://pub.dev"
source: hosted
- version: "2.1.2"
+ version: "2.1.1"
string_scanner:
dependency: transitive
description:
@@ -602,10 +560,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
+ sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
url: "https://pub.dev"
source: hosted
- version: "0.6.1"
+ version: "0.6.0"
tuple:
dependency: "direct main"
description:
@@ -626,10 +584,10 @@ packages:
dependency: "direct main"
description:
name: url_launcher
- sha256: "0ecc004c62fd3ed36a2ffcbe0dd9700aee63bd7532d0b642a488b1ec310f492e"
+ sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c
url: "https://pub.dev"
source: hosted
- version: "6.2.5"
+ version: "6.2.4"
url_launcher_android:
dependency: transitive
description:
@@ -642,10 +600,10 @@ packages:
dependency: transitive
description:
name: url_launcher_ios
- sha256: "9149d493b075ed740901f3ee844a38a00b33116c7c5c10d7fb27df8987fb51d5"
+ sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03"
url: "https://pub.dev"
source: hosted
- version: "6.2.5"
+ version: "6.2.4"
url_launcher_linux:
dependency: transitive
description:
@@ -674,10 +632,10 @@ packages:
dependency: transitive
description:
name: url_launcher_web
- sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d"
+ sha256: "7fd2f55fe86cea2897b963e864dc01a7eb0719ecc65fcef4c1cc3d686d718bb2"
url: "https://pub.dev"
source: hosted
- version: "2.3.0"
+ version: "2.2.0"
url_launcher_windows:
dependency: transitive
description:
@@ -690,10 +648,10 @@ packages:
dependency: transitive
description:
name: uuid
- sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8
+ sha256: "22c94e5ad1e75f9934b766b53c742572ee2677c56bc871d850a57dad0f82127f"
url: "https://pub.dev"
source: hosted
- version: "4.3.3"
+ version: "4.2.2"
vector_graphics:
dependency: transitive
description:
@@ -734,30 +692,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.4.0+2"
- vm_service:
- dependency: transitive
- description:
- name: vm_service
- sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
- url: "https://pub.dev"
- source: hosted
- version: "13.0.0"
web:
dependency: transitive
description:
name: web
- sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27"
+ sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
url: "https://pub.dev"
source: hosted
- version: "0.5.1"
+ version: "0.1.4-beta"
win32:
dependency: transitive
description:
name: win32
- sha256: "0a989dc7ca2bb51eac91e8fd00851297cfffd641aa7538b165c62637ca0eaa4a"
+ sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574
url: "https://pub.dev"
source: hosted
- version: "5.4.0"
+ version: "5.1.1"
xdg_directories:
dependency: transitive
description:
@@ -770,10 +720,10 @@ packages:
dependency: transitive
description:
name: xml
- sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
+ sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84"
url: "https://pub.dev"
source: hosted
- version: "6.5.0"
+ version: "6.3.0"
sdks:
- dart: ">=3.3.0 <4.0.0"
- flutter: ">=3.19.0"
+ dart: ">=3.1.0 <4.0.0"
+ flutter: ">=3.13.0"
diff --git a/packages/hms_room_kit/pubspec.yaml b/packages/hms_room_kit/pubspec.yaml
index cc9d7d6f0..e051445d5 100644
--- a/packages/hms_room_kit/pubspec.yaml
+++ b/packages/hms_room_kit/pubspec.yaml
@@ -15,7 +15,7 @@ dependencies:
sdk: flutter
hmssdk_flutter:
- path: ../hmssdk_flutter
+ path: ../hmssdk_flutter
intl: ^0.18.0
permission_handler: ^11.0.0
provider: ^6.0.5
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSHLSVariantExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSHLSVariantExtension.kt
index bebd5530e..7b8ff793d 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSHLSVariantExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSHLSVariantExtension.kt
@@ -1,7 +1,6 @@
package live.hms.hmssdk_flutter
import live.hms.video.sdk.models.HMSHLSVariant
-import java.text.SimpleDateFormat
class HMSHLSVariantExtension {
companion object {
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSPeerExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSPeerExtension.kt
index 8f57848fb..31222fbfb 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSPeerExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSPeerExtension.kt
@@ -49,7 +49,7 @@ class HMSPeerExtension {
}
private fun getValueFromPeerType(peerType: HMSPeerType): String {
- return when(peerType){
+ return when (peerType) {
HMSPeerType.SIP -> "sip"
HMSPeerType.REGULAR -> "regular"
else -> "regular"
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRtmpStreamingState.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRtmpStreamingState.kt
index 04e62b4b2..6cd49555c 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRtmpStreamingState.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSRtmpStreamingState.kt
@@ -2,7 +2,6 @@
import live.hms.hmssdk_flutter.HMSExceptionExtension
import live.hms.hmssdk_flutter.HMSHLSVariantExtension
import live.hms.video.sdk.models.*
-import java.text.SimpleDateFormat
class HMSStreamingState {
companion object {
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSTrackSettingsExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSTrackSettingsExtension.kt
index c810d7893..2a742e6a0 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSTrackSettingsExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HMSTrackSettingsExtension.kt
@@ -54,7 +54,7 @@ class HMSTrackSettingsExtension {
val enableNoiseCancellation = audioHashMap["enable_noise_cancellation"] as? Boolean
enableNoiseCancellation?.let {
- if(it){
+ if (it) {
hmsAudioTrackSettings.enableNoiseCancellation(true)
}
}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt
index a177ab114..6c7ff934b 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/HmssdkFlutterPlugin.kt
@@ -38,7 +38,6 @@ import live.hms.video.error.HMSException
import live.hms.video.events.AgentType
import live.hms.video.interactivity.HmsPollUpdateListener
import live.hms.video.media.tracks.*
-import live.hms.video.polls.HMSPollBuilder
import live.hms.video.polls.models.HMSPollUpdateType
import live.hms.video.polls.models.HmsPoll
import live.hms.video.sdk.*
@@ -65,7 +64,7 @@ class HmssdkFlutterPlugin :
private var rtcStatsChannel: EventChannel? = null
private var sessionStoreChannel: EventChannel? = null
var hlsPlayerChannel: EventChannel? = null
- private var pollsEventChannel : EventChannel? = null
+ private var pollsEventChannel: EventChannel? = null
private var eventSink: EventChannel.EventSink? = null
private var previewSink: EventChannel.EventSink? = null
private var logsSink: EventChannel.EventSink? = null
@@ -122,7 +121,7 @@ class HmssdkFlutterPlugin :
this.rtcStatsChannel?.setStreamHandler(this) ?: Log.e("Channel Error", "RTC Stats channel not found")
this.sessionStoreChannel?.setStreamHandler(this) ?: Log.e("Channel Error", "Session Store channel not found")
this.hlsPlayerChannel?.setStreamHandler(this) ?: Log.e("Channel Error", "HLS Player channel not found")
- this.pollsEventChannel?.setStreamHandler(this) ?: Log.e("Channel Error","polls events channel not found")
+ this.pollsEventChannel?.setStreamHandler(this) ?: Log.e("Channel Error", "polls events channel not found")
this.hmsVideoFactory = HMSVideoViewFactory(this)
this.hmsHLSPlayerFactory = HMSHLSPlayerFactory(this)
@@ -253,8 +252,8 @@ class HmssdkFlutterPlugin :
"remove_key_change_listener" -> {
removeKeyChangeListener(call, result)
}
- "start_hls_player", "stop_hls_player", "pause_hls_player", "resume_hls_player", "seek_to_live_position", "seek_forward", "seek_backward", "set_hls_player_volume", "add_hls_stats_listener", "remove_hls_stats_listener" -> {
- HMSHLSPlayerAction.hlsPlayerAction(call, result, activity)
+ "start_hls_player", "stop_hls_player", "pause_hls_player", "resume_hls_player", "seek_to_live_position", "seek_forward", "seek_backward", "set_hls_player_volume", "add_hls_stats_listener", "remove_hls_stats_listener", "are_closed_captions_supported", "enable_closed_captions", "disable_closed_captions" -> {
+ HMSHLSPlayerAction.hlsPlayerAction(call, result)
}
"toggle_always_screen_on" -> {
toggleAlwaysScreenOn(result)
@@ -286,8 +285,8 @@ class HmssdkFlutterPlugin :
HMSPeerListIteratorAction.peerListIteratorAction(call, result, hmssdk!!)
}
- "add_poll_update_listener", "remove_poll_update_listener", "quick_start_poll", "add_single_choice_poll_response", "add_multi_choice_poll_response", "stop_poll", "fetch_leaderboard","fetch_poll_list", "fetch_poll_questions", "get_poll_results" -> {
- pollActions(call,result)
+ "add_poll_update_listener", "remove_poll_update_listener", "quick_start_poll", "add_single_choice_poll_response", "add_multi_choice_poll_response", "stop_poll", "fetch_leaderboard", "fetch_poll_list", "fetch_poll_questions", "get_poll_results" -> {
+ pollActions(call, result)
}
"enable_noise_cancellation", "disable_noise_cancellation", "is_noise_cancellation_enabled", "is_noise_cancellation_available" -> {
@@ -472,17 +471,22 @@ class HmssdkFlutterPlugin :
}
private var currentPolls = ArrayList()
- private fun pollActions(call: MethodCall, result: Result){
- when(call.method){
+
+ private fun pollActions(
+ call: MethodCall,
+ result: Result,
+ ) {
+ when (call.method) {
"add_poll_update_listener" -> {
hmssdk?.getHmsInteractivityCenter()?.pollUpdateListener = hmsPollListener
}
"remove_poll_update_listener" -> {
hmssdk?.getHmsInteractivityCenter()?.pollUpdateListener = null
}
- else -> hmssdk?.let {
- HMSPollAction.pollActions(call,result, it,currentPolls)
- }
+ else ->
+ hmssdk?.let {
+ HMSPollAction.pollActions(call, result, it, currentPolls)
+ }
}
}
@@ -497,7 +501,7 @@ class HmssdkFlutterPlugin :
rtcStatsChannel?.setStreamHandler(null) ?: Log.e("Channel Error", "RTC Stats channel not found")
sessionStoreChannel?.setStreamHandler(null) ?: Log.e("Channel Error", "Session Store channel not found")
hlsPlayerChannel?.setStreamHandler(null) ?: Log.e("Channel Error", "HLS Player channel not found")
- pollsEventChannel?.setStreamHandler(null)?: Log.e("Channel Error", "polls event channel not found")
+ pollsEventChannel?.setStreamHandler(null) ?: Log.e("Channel Error", "polls event channel not found")
eventSink = null
previewSink = null
rtcSink = null
@@ -635,7 +639,7 @@ class HmssdkFlutterPlugin :
this.sessionStoreSink = events
} else if (nameOfEventSink == "hls_player") {
this.hlsPlayerSink = events
- } else if(nameOfEventSink == "polls") {
+ } else if (nameOfEventSink == "polls") {
this.pollsSink = events
}
}
@@ -673,7 +677,12 @@ class HmssdkFlutterPlugin :
Log.i("HMSTextureView", "Init Add Track called for track: ${track.trackId}")
renderer.addTrack(videoTrack, disableAutoSimulcastLayerSelect)
} ?: run {
- HMSErrorLogger.returnHMSException("createTextureView", "No track with $trackId found", "Track not found error", result)
+ HMSErrorLogger.returnHMSException(
+ "createTextureView",
+ "No track with $trackId found",
+ "Track not found error",
+ result,
+ )
return
}
} ?: run {
@@ -876,7 +885,8 @@ class HmssdkFlutterPlugin :
authToken?.let {
hmssdk!!.getRoomLayout(
- authToken, layoutRequestOptions,
+ authToken,
+ layoutRequestOptions,
object : HMSLayoutListener {
override fun onError(error: HMSException) {
result.success(HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)))
@@ -1582,8 +1592,12 @@ class HmssdkFlutterPlugin :
private fun startScreenShare(result: Result) {
androidScreenshareResult = result
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- activity.applicationContext?.registerReceiver(activityBroadcastReceiver, IntentFilter("ACTIVITY_RECEIVER"), Context.RECEIVER_EXPORTED)
- }else {
+ activity.applicationContext?.registerReceiver(
+ activityBroadcastReceiver,
+ IntentFilter("ACTIVITY_RECEIVER"),
+ Context.RECEIVER_EXPORTED,
+ )
+ } else {
activity.applicationContext?.registerReceiver(activityBroadcastReceiver, IntentFilter("ACTIVITY_RECEIVER"))
}
val mediaProjectionManager: MediaProjectionManager =
@@ -1651,9 +1665,13 @@ class HmssdkFlutterPlugin :
androidAudioShareResult = result
mode = call.argument("audio_mixing_mode")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
- activity.applicationContext?.registerReceiver(activityBroadcastReceiver, IntentFilter("ACTIVITY_RECEIVER"), Context.RECEIVER_EXPORTED)
- }else {
- activity.applicationContext?.registerReceiver(activityBroadcastReceiver, IntentFilter("ACTIVITY_RECEIVER"),)
+ activity.applicationContext?.registerReceiver(
+ activityBroadcastReceiver,
+ IntentFilter("ACTIVITY_RECEIVER"),
+ Context.RECEIVER_EXPORTED,
+ )
+ } else {
+ activity.applicationContext?.registerReceiver(activityBroadcastReceiver, IntentFilter("ACTIVITY_RECEIVER"))
}
val mediaProjectionManager: MediaProjectionManager? =
activity.getSystemService(
@@ -2042,7 +2060,6 @@ class HmssdkFlutterPlugin :
private val audioPreviewDeviceChangeListener =
object : AudioManagerDeviceChangeListener {
-
override fun onAudioDeviceChanged(
selectedAudioDevice: AudioDevice,
availableAudioDevices: Set,
@@ -2075,7 +2092,6 @@ class HmssdkFlutterPlugin :
}
}
}
-
}
private val audioDeviceChangeListener =
@@ -2087,12 +2103,12 @@ class HmssdkFlutterPlugin :
val args = HashMap()
args["event_name"] = "on_audio_device_changed"
val dict = HashMap()
- dict["current_audio_device"] = selectedAudioDevice.name
- val audioDevicesList = ArrayList()
- availableAudioDevices.forEach { device ->
- audioDevicesList.add(device.name)
- }
- dict["available_audio_device"] = audioDevicesList
+ dict["current_audio_device"] = selectedAudioDevice.name
+ val audioDevicesList = ArrayList()
+ availableAudioDevices.forEach { device ->
+ audioDevicesList.add(device.name)
+ }
+ dict["available_audio_device"] = audioDevicesList
args["data"] = dict
if (args["data"] != null) {
CoroutineScope(Dispatchers.Main).launch {
@@ -2114,36 +2130,37 @@ class HmssdkFlutterPlugin :
}
}
- private val hmsPollListener = object : HmsPollUpdateListener{
- override fun onPollUpdate(hmsPoll: HmsPoll, hmsPollUpdateType: HMSPollUpdateType) {
-
- if(hmsPollUpdateType == HMSPollUpdateType.started){
- currentPolls.add(hmsPoll)
- } else if(hmsPollUpdateType == HMSPollUpdateType.resultsupdated){
- val index = currentPolls.indexOfFirst { it.pollId == hmsPoll.pollId }
- if(index != -1){
- currentPolls[index] = hmsPoll
- }
- } else if(hmsPollUpdateType == HMSPollUpdateType.stopped){
- val index = currentPolls.indexOfFirst { it.pollId == hmsPoll.pollId }
- if(index != -1){
- currentPolls.removeAt(index)
+ private val hmsPollListener =
+ object : HmsPollUpdateListener {
+ override fun onPollUpdate(
+ hmsPoll: HmsPoll,
+ hmsPollUpdateType: HMSPollUpdateType,
+ ) {
+ if (hmsPollUpdateType == HMSPollUpdateType.started) {
+ currentPolls.add(hmsPoll)
+ } else if (hmsPollUpdateType == HMSPollUpdateType.resultsupdated) {
+ val index = currentPolls.indexOfFirst { it.pollId == hmsPoll.pollId }
+ if (index != -1) {
+ currentPolls[index] = hmsPoll
+ }
+ } else if (hmsPollUpdateType == HMSPollUpdateType.stopped) {
+ val index = currentPolls.indexOfFirst { it.pollId == hmsPoll.pollId }
+ if (index != -1) {
+ currentPolls.removeAt(index)
+ }
}
- }
- val args = HashMap()
- args["event_name"] = "on_poll_update"
+ val args = HashMap()
+ args["event_name"] = "on_poll_update"
- val pollHashMap = HashMap()
- pollHashMap["poll"] = HMSPollExtension.toDictionary(hmsPoll)
- pollHashMap["poll_update_type"] = HMSPollExtension.getPollUpdateType(hmsPollUpdateType)
- args["data"] = pollHashMap
+ val pollHashMap = HashMap()
+ pollHashMap["poll"] = HMSPollExtension.toDictionary(hmsPoll)
+ pollHashMap["poll_update_type"] = HMSPollExtension.getPollUpdateType(hmsPollUpdateType)
+ args["data"] = pollHashMap
- CoroutineScope(Dispatchers.Main).launch {
- pollsSink?.success(args)
+ CoroutineScope(Dispatchers.Main).launch {
+ pollsSink?.success(args)
+ }
}
}
- }
-
-
}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hls_player/HLSStatsHandler.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hls_player/HLSStatsHandler.kt
index 208a7630c..e0e11fada 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hls_player/HLSStatsHandler.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hls_player/HLSStatsHandler.kt
@@ -66,7 +66,11 @@ class HLSStatsHandler {
}
},
) ?: run {
- HMSErrorLogger.logError("addHLSStatsListener", "hlsPlayer is null, Consider calling this method after attaching the HMSHLSPlayer or sending isHLSStatsRequired as true to get the stats", "NULL_ERROR")
+ HMSErrorLogger.logError(
+ "addHLSStatsListener",
+ "hlsPlayer is null, Consider calling this method after attaching the HMSHLSPlayer or sending isHLSStatsRequired as true to get the stats",
+ "NULL_ERROR",
+ )
}
}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hls_player/HMSHLSPlayerAction.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hls_player/HMSHLSPlayerAction.kt
index 5da7aff21..5cac07bb0 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hls_player/HMSHLSPlayerAction.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hls_player/HMSHLSPlayerAction.kt
@@ -1,12 +1,9 @@
package live.hms.hmssdk_flutter.hls_player
-import android.app.Activity
-import android.content.Intent
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel.Result
-import live.hms.hmssdk_flutter.Constants.Companion.HLS_PLAYER_INTENT
-import live.hms.hmssdk_flutter.Constants.Companion.METHOD_CALL
import live.hms.hmssdk_flutter.HMSErrorLogger
+import java.lang.ref.WeakReference
/**
* This class is used to send actions from flutter plugin to HLS Player
@@ -14,99 +11,104 @@ import live.hms.hmssdk_flutter.HMSErrorLogger
*/
class HMSHLSPlayerAction {
companion object {
+ private var hlsActions: WeakReference? = null
+
fun hlsPlayerAction(
call: MethodCall,
result: Result,
- activity: Activity,
) {
when (call.method) {
- "start_hls_player" -> start(call, result, activity)
- "stop_hls_player" -> stop(result, activity)
- "pause_hls_player" -> pause(result, activity)
- "resume_hls_player" -> resume(result, activity)
- "seek_to_live_position" -> seekToLivePosition(result, activity)
- "seek_forward" -> seekForward(call, result, activity)
- "seek_backward" -> seekBackward(call, result, activity)
- "set_hls_player_volume" -> setVolume(call, result, activity)
- "add_hls_stats_listener" -> addHLSStatsListener(result, activity)
- "remove_hls_stats_listener" -> removeHLSStatsListener(result, activity)
+ "start_hls_player" -> start(call, result)
+ "stop_hls_player" -> stop(result)
+ "pause_hls_player" -> pause(result)
+ "resume_hls_player" -> resume(result)
+ "seek_to_live_position" -> seekToLivePosition(result)
+ "seek_forward" -> seekForward(call, result)
+ "seek_backward" -> seekBackward(call, result)
+ "set_hls_player_volume" -> setVolume(call, result)
+ "add_hls_stats_listener" -> addHLSStatsListener(result)
+ "remove_hls_stats_listener" -> removeHLSStatsListener(result)
+ "are_closed_captions_supported" -> areClosedCaptionsSupported(result)
+ "enable_closed_captions" -> enableClosedCaptions(result)
+ "disable_closed_captions" -> disableClosedCaptions(result)
else -> {
result.notImplemented()
}
}
}
+ fun assignInterfaceObject(actionObject: WeakReference) {
+ hlsActions = actionObject
+ }
+
/**
* Starts the HLS player by sending a broadcast intent with the specified method call and HLS URL.
*
* @param call The method call object containing the HLS URL as an argument.
* @param result The result object to be returned after starting the player.
- * @param activity The current activity from which the method is called.
*/
private fun start(
call: MethodCall,
result: Result,
- activity: Activity,
) {
val hlsUrl = call.argument("hls_url")
- activity.sendBroadcast(Intent(HLS_PLAYER_INTENT).putExtra(METHOD_CALL, "start_hls_player").putExtra("hls_url", hlsUrl))
- result.success(null)
+ hlsActions?.let {
+ it.get()?.start(hlsUrl, result)
+ }?:run{
+ HMSErrorLogger.logError("start", "hlsActions is NULL", "NULL Error")
+ }
}
/**
* Stops the HLS player by sending a broadcast intent with the specified method call.
*
* @param result The result object to be returned after stopping the player.
- * @param activity The current activity from which the method is called.
*/
- private fun stop(
- result: Result,
- activity: Activity,
- ) {
- activity.sendBroadcast(Intent(HLS_PLAYER_INTENT).putExtra(METHOD_CALL, "stop_hls_player"))
- result.success(null)
+ private fun stop(result: Result) {
+ hlsActions?.let {
+ it.get()?.stop(result)
+ }?:run{
+ HMSErrorLogger.logError("stop", "hlsActions is NULL", "NULL Error")
+ }
}
/**
* Pauses the HLS player by sending a broadcast intent with the specified method call.
*
* @param result The result object to be returned after pausing the player.
- * @param activity The current activity from which the method is called.
*/
- private fun pause(
- result: Result,
- activity: Activity,
- ) {
- activity.sendBroadcast(Intent(HLS_PLAYER_INTENT).putExtra(METHOD_CALL, "pause_hls_player"))
- result.success(null)
+ private fun pause(result: Result) {
+ hlsActions?.let {
+ it.get()?.pause(result)
+ }?:run{
+ HMSErrorLogger.logError("pause", "hlsActions is NULL", "NULL Error")
+ }
}
/**
* Resumes the HLS player by sending a broadcast intent with the specified method call.
*
* @param result The result object to be returned after resuming the player.
- * @param activity The current activity from which the method is called.
*/
- private fun resume(
- result: Result,
- activity: Activity,
- ) {
- activity.sendBroadcast(Intent(HLS_PLAYER_INTENT).putExtra(METHOD_CALL, "resume_hls_player"))
- result.success(null)
+ private fun resume(result: Result) {
+ hlsActions?.let {
+ it.get()?.resume(result)
+ }?:run{
+ HMSErrorLogger.logError("resume", "hlsActions is NULL", "NULL Error")
+ }
}
/**
* Seeks to the live position in the HLS player by sending a broadcast intent with the specified method call.
*
* @param result The result object to be returned after seeking to the live position.
- * @param activity The current activity from which the method is called.
*/
- private fun seekToLivePosition(
- result: Result,
- activity: Activity,
- ) {
- activity.sendBroadcast(Intent(HLS_PLAYER_INTENT).putExtra(METHOD_CALL, "seek_to_live_position"))
- result.success(null)
+ private fun seekToLivePosition(result: Result) {
+ hlsActions?.let {
+ it.get()?.seekToLivePosition(result)
+ }?:run{
+ HMSErrorLogger.logError("seekToLivePosition", "hlsActions is NULL", "NULL Error")
+ }
}
/**
@@ -114,12 +116,10 @@ class HMSHLSPlayerAction {
*
* @param call The method call object containing the number of seconds to seek forward as an argument.
* @param result The result object to be returned after seeking forward.
- * @param activity The current activity from which the method is called.
*/
private fun seekForward(
call: MethodCall,
result: Result,
- activity: Activity,
) {
val seconds: Int? =
call.argument("seconds") ?: run {
@@ -128,9 +128,12 @@ class HMSHLSPlayerAction {
}
seconds?.let {
- activity.sendBroadcast(Intent(HLS_PLAYER_INTENT).putExtra(METHOD_CALL, "seek_forward").putExtra("seconds", seconds))
+ hlsActions?.let {_hlsActions ->
+ _hlsActions.get()?.seekForward(it, result)
+ }?:run{
+ HMSErrorLogger.logError("seekForward", "hlsActions is NULL", "NULL Error")
+ }
}
- result.success(null)
}
/**
@@ -138,12 +141,10 @@ class HMSHLSPlayerAction {
*
* @param call The method call object containing the number of seconds to seek backward as an argument.
* @param result The result object to be returned after seeking backward.
- * @param activity The current activity from which the method is called.
*/
private fun seekBackward(
call: MethodCall,
result: Result,
- activity: Activity,
) {
val seconds: Int? =
call.argument("seconds") ?: run {
@@ -152,9 +153,12 @@ class HMSHLSPlayerAction {
}
seconds?.let {
- activity.sendBroadcast(Intent(HLS_PLAYER_INTENT).putExtra(METHOD_CALL, "seek_backward").putExtra("seconds", seconds))
+ hlsActions?.let { _hlsActions ->
+ _hlsActions.get()?.seekBackward(it, result)
+ }?:run{
+ HMSErrorLogger.logError("seekBackward", "hlsActions is NULL", "NULL Error")
+ }
}
- result.success(null)
}
/**
@@ -162,12 +166,10 @@ class HMSHLSPlayerAction {
*
* @param call The method call object containing the volume level as an argument.
* @param result The result object to be returned after setting the volume.
- * @param activity The current activity from which the method is called.
*/
private fun setVolume(
call: MethodCall,
result: Result,
- activity: Activity,
) {
val volume: Int? =
call.argument("volume") ?: run {
@@ -176,37 +178,79 @@ class HMSHLSPlayerAction {
}
volume?.let {
- activity.sendBroadcast(Intent(HLS_PLAYER_INTENT).putExtra(METHOD_CALL, "set_volume").putExtra("volume", volume))
+ hlsActions?.let {_hlsActions ->
+ _hlsActions.get()?.setVolume(it,result)
+ }?:run{
+ HMSErrorLogger.logError("setVolume", "hlsActions is NULL", "NULL Error")
+ }
}
- result.success(null)
}
/**
* Adds a listener to receive HLS player statistics by sending a broadcast intent with the corresponding method call.
*
* @param result The result object to be returned after adding the HLS stats listener.
- * @param activity The current activity from which the method is called.
*/
- private fun addHLSStatsListener(
- result: Result,
- activity: Activity,
- ) {
- activity.sendBroadcast(Intent(HLS_PLAYER_INTENT).putExtra(METHOD_CALL, "add_hls_stats_listener"))
- result.success(null)
+ private fun addHLSStatsListener(result: Result) {
+
+ hlsActions?.let {
+ it.get()?.addHLSStatsListener(result)
+ }?:run{
+ HMSErrorLogger.logError("addHLSStatsListener", "hlsActions is NULL", "NULL Error")
+ }
}
/**
* Removes the listener for HLS player statistics by sending a broadcast intent with the corresponding method call.
*
* @param result The result object to be returned after removing the HLS stats listener.
- * @param activity The current activity from which the method is called.
*/
- private fun removeHLSStatsListener(
- result: Result,
- activity: Activity,
- ) {
- activity.sendBroadcast(Intent(HLS_PLAYER_INTENT).putExtra(METHOD_CALL, "remove_hls_stats_listener"))
- result.success(null)
+ private fun removeHLSStatsListener(result: Result) {
+ hlsActions?.let {
+ it.get()?.removeHLSStatsListener(result)
+ }?:run{
+ HMSErrorLogger.logError("removeHLSStatsListener", "hlsActions is NULL", "NULL Error")
+ }
+ }
+
+ /**
+ * Checks whether closed captions are supported or not
+ * This can be enabled/disabled from 100ms dashboard
+ *
+ * @param result The result object used to send response regarding closed captions
+ */
+ private fun areClosedCaptionsSupported(result: Result) {
+ hlsActions?.let {
+ it.get()?.areClosedCaptionsSupported(result)
+ }?:run{
+ HMSErrorLogger.logError("areClosedCaptionsSupported", "hlsActions is NULL", "NULL Error")
+ }
+ }
+
+ /**
+ * Enable closed captions in the player
+ *
+ * @param result is the object to be returned after enabling closed captions
+ */
+ private fun enableClosedCaptions(result: Result) {
+ hlsActions?.let {
+ it.get()?.enableClosedCaptions(result)
+ }?:run{
+ HMSErrorLogger.logError("enableClosedCaptions", "hlsActions is NULL", "NULL Error")
+ }
+ }
+
+ /**
+ * Disable closed captions in the player
+ *
+ * @param result is the object to be returned after disabling closed captions
+ */
+ private fun disableClosedCaptions(result: Result) {
+ hlsActions?.let {
+ it.get()?.disableClosedCaptions(result)
+ }?:run{
+ HMSErrorLogger.logError("disableClosedCaptions", "hlsActions is NULL", "NULL Error")
+ }
}
}
}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hls_player/IHLSPlayerActionInterface.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hls_player/IHLSPlayerActionInterface.kt
new file mode 100644
index 000000000..4a3b20ef1
--- /dev/null
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/hls_player/IHLSPlayerActionInterface.kt
@@ -0,0 +1,48 @@
+package live.hms.hmssdk_flutter.hls_player
+
+import io.flutter.plugin.common.MethodChannel.Result
+
+/**
+ * [IHLSPlayerActionInterface] contains HLS Player methods
+ * This is implemented in HMSHLSPlayer view to execute the method calls
+ * from flutter
+ */
+interface IHLSPlayerActionInterface {
+ fun start(
+ hlsUrl: String?,
+ result: Result,
+ )
+
+ fun stop(result: Result)
+
+ fun pause(result: Result)
+
+ fun resume(result: Result)
+
+ fun seekToLivePosition(result: Result)
+
+ fun seekForward(
+ seconds: Int,
+ result: Result,
+ )
+
+ fun seekBackward(
+ seconds: Int,
+ result: Result,
+ )
+
+ fun setVolume(
+ volume: Int,
+ result: Result,
+ )
+
+ fun addHLSStatsListener(result: Result)
+
+ fun removeHLSStatsListener(result: Result)
+
+ fun areClosedCaptionsSupported(result: Result)
+
+ fun enableClosedCaptions(result: Result)
+
+ fun disableClosedCaptions(result: Result)
+}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSCameraControlsAction.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSCameraControlsAction.kt
index e39727c85..7a1040118 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSCameraControlsAction.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSCameraControlsAction.kt
@@ -98,7 +98,11 @@ class HMSCameraControlsAction {
if (cameraControl.isFlashSupported()) {
cameraControl.setFlash(true)
} else {
- HMSErrorLogger.logError("captureImageAtMaxSupportedResolution", "Flash is not supported for current facing camera", "Compatibility error")
+ HMSErrorLogger.logError(
+ "captureImageAtMaxSupportedResolution",
+ "Flash is not supported for current facing camera",
+ "Compatibility error",
+ )
}
}
cameraControl.captureImageAtMaxSupportedResolution(imageFile) { isSuccess ->
@@ -107,7 +111,9 @@ class HMSCameraControlsAction {
if (isSuccess) {
result.success(HMSResultExtension.toDictionary(true, filePath))
} else {
- result.success(HMSResultExtension.toDictionary(false, HMSExceptionExtension.getError("Error in capturing image")))
+ result.success(
+ HMSResultExtension.toDictionary(false, HMSExceptionExtension.getError("Error in capturing image")),
+ )
}
if (withFlash) {
cameraControl.setFlash(false)
@@ -177,7 +183,14 @@ class HMSCameraControlsAction {
result.success(HMSResultExtension.toDictionary(true, null))
return
} else {
- result.success(HMSResultExtension.toDictionary(false, HMSExceptionExtension.getError("Flash is not supported for current facing camera, Also please ensure camera is turned ON")))
+ result.success(
+ HMSResultExtension.toDictionary(
+ false,
+ HMSExceptionExtension.getError(
+ "Flash is not supported for current facing camera, Also please ensure camera is turned ON",
+ ),
+ ),
+ )
return
}
} ?: run {
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSNoiseCancellationControllerAction.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSNoiseCancellationControllerAction.kt
index 6cea949ba..90a267057 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSNoiseCancellationControllerAction.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSNoiseCancellationControllerAction.kt
@@ -8,24 +8,24 @@ import live.hms.video.factories.noisecancellation.AvailabilityStatus
import live.hms.video.sdk.HMSSDK
class HMSNoiseCancellationControllerAction {
-
companion object {
-
- fun noiseCancellationActions(call: MethodCall,
- result: MethodChannel.Result,
- hmssdk: HMSSDK,){
- when(call.method){
+ fun noiseCancellationActions(
+ call: MethodCall,
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
+ when (call.method) {
"enable_noise_cancellation" -> {
- enable(result,hmssdk)
+ enable(result, hmssdk)
}
"disable_noise_cancellation" -> {
- disable(result,hmssdk)
+ disable(result, hmssdk)
}
"is_noise_cancellation_enabled" -> {
- isEnabled(result,hmssdk)
+ isEnabled(result, hmssdk)
}
"is_noise_cancellation_available" -> {
- isAvailable(result,hmssdk)
+ isAvailable(result, hmssdk)
}
else -> {
result.notImplemented()
@@ -36,7 +36,10 @@ class HMSNoiseCancellationControllerAction {
/**
* [enable] method enables noise cancellation for the user
*/
- private fun enable(result: MethodChannel.Result, hmssdk: HMSSDK){
+ private fun enable(
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
hmssdk.setNoiseCancellationEnabled(true)
result.success(null)
}
@@ -44,7 +47,10 @@ class HMSNoiseCancellationControllerAction {
/**
* [disable] method disables noise cancellation for the user
*/
- private fun disable(result: MethodChannel.Result, hmssdk: HMSSDK){
+ private fun disable(
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
hmssdk.setNoiseCancellationEnabled(false)
result.success(null)
}
@@ -52,7 +58,10 @@ class HMSNoiseCancellationControllerAction {
/**
* [isEnabled] method returns whether noise cancellation is enabled or not
*/
- private fun isEnabled(result: MethodChannel.Result, hmssdk: HMSSDK){
+ private fun isEnabled(
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
val isEnabled = hmssdk.getNoiseCancellationEnabled()
result.success(HMSResultExtension.toDictionary(true, isEnabled))
}
@@ -60,17 +69,18 @@ class HMSNoiseCancellationControllerAction {
/**
* [isAvailable] method returns whether noise cancellation is available in the room
*/
- private fun isAvailable(result: MethodChannel.Result, hmssdk: HMSSDK){
+ private fun isAvailable(
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
val availabilityStatus = hmssdk.isNoiseCancellationAvailable()
- if(availabilityStatus == AvailabilityStatus.Available){
+ if (availabilityStatus == AvailabilityStatus.Available) {
result.success(HMSResultExtension.toDictionary(true, data = true))
- }else{
+ } else {
val reason = (availabilityStatus as AvailabilityStatus.NotAvailable).reason
- HMSErrorLogger.logError("isAvailable",reason,"NoiseCancellation Error")
+ HMSErrorLogger.logError("isAvailable", reason, "NoiseCancellation Error")
result.success(HMSResultExtension.toDictionary(true, data = false))
}
}
-
}
-
-}
\ No newline at end of file
+}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPeerListIteratorAction.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPeerListIteratorAction.kt
index 8bc585269..c28a7b9c1 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPeerListIteratorAction.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPeerListIteratorAction.kt
@@ -60,10 +60,16 @@ class HMSPeerListIteratorAction {
peerListIteratorOptions =
PeerListIteratorOptions(
byRoleName = it["by_role_name"] as String?,
- byPeerIds = it["by_peer_ids"] as ArrayList?, limit = limitValue,
+ byPeerIds = it["by_peer_ids"] as ArrayList?,
+ limit = limitValue,
)
} ?: run {
- HMSErrorLogger.returnHMSException("getPeerListIterator", "limit parameter is null while peerListIteratorOptions is non-null", "NULL Error", result)
+ HMSErrorLogger.returnHMSException(
+ "getPeerListIterator",
+ "limit parameter is null while peerListIteratorOptions is non-null",
+ "NULL Error",
+ result,
+ )
}
}
@@ -100,7 +106,12 @@ class HMSPeerListIteratorAction {
peerListIterator?.let { iterator ->
result.success(HMSResultExtension.toDictionary(true, iterator.hasNext()))
} ?: run {
- HMSErrorLogger.returnHMSException("peerListIteratorHasNext", "No peerListIterator with given uid found", "NULL Error", result)
+ HMSErrorLogger.returnHMSException(
+ "peerListIteratorHasNext",
+ "No peerListIterator with given uid found",
+ "NULL Error",
+ result,
+ )
}
} ?: run {
HMSErrorLogger.returnHMSException("peerListIteratorHasNext", "uid is null", "NULL Error", result)
@@ -128,7 +139,9 @@ class HMSPeerListIteratorAction {
iterator.next(
object : PeerListResultListener {
override fun onError(error: HMSException) {
- methodChannelResult.success(HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)))
+ methodChannelResult.success(
+ HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)),
+ )
}
override fun onSuccess(result: ArrayList) {
@@ -144,7 +157,12 @@ class HMSPeerListIteratorAction {
},
)
} ?: run {
- HMSErrorLogger.returnHMSException("peerListIteratorNext", "No peerListIterator with given uid found", "NULL Error", methodChannelResult)
+ HMSErrorLogger.returnHMSException(
+ "peerListIteratorNext",
+ "No peerListIterator with given uid found",
+ "NULL Error",
+ methodChannelResult,
+ )
}
} ?: run {
HMSErrorLogger.returnHMSException("peerListIteratorNext", "uid is null", "NULL Error", methodChannelResult)
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPollAction.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPollAction.kt
index a18054604..712493445 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPollAction.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/methods/HMSPollAction.kt
@@ -6,8 +6,8 @@ import live.hms.hmssdk_flutter.HMSCommonAction
import live.hms.hmssdk_flutter.HMSErrorLogger
import live.hms.hmssdk_flutter.HMSExceptionExtension
import live.hms.hmssdk_flutter.HMSResultExtension
-import live.hms.hmssdk_flutter.poll_extension.HMSPollBuilderExtension
import live.hms.hmssdk_flutter.poll_extension.HMSPollAnswerResponseExtension
+import live.hms.hmssdk_flutter.poll_extension.HMSPollBuilderExtension
import live.hms.hmssdk_flutter.poll_extension.HMSPollExtension
import live.hms.hmssdk_flutter.poll_extension.HMSPollLeaderboardResponseExtension
import live.hms.hmssdk_flutter.poll_extension.HMSPollQuestionExtension
@@ -23,53 +23,64 @@ import live.hms.video.sdk.HMSSDK
import live.hms.video.sdk.HmsTypedActionResultListener
class HMSPollAction {
-
- companion object{
- fun pollActions(call: MethodCall, result: MethodChannel.Result, hmssdk: HMSSDK, polls: ArrayList?){
- when(call.method){
- "quick_start_poll" -> quickStartPoll(call,result,hmssdk)
- "add_single_choice_poll_response" -> addSingleChoicePollResponse(call,result,hmssdk,polls)
- "add_multi_choice_poll_response" -> addMultiChoicePollResponse(call,result,hmssdk,polls)
- "stop_poll" -> stopPoll(call,result,hmssdk,polls)
- "fetch_leaderboard" -> fetchLeaderboard(call,result,hmssdk)
- "fetch_poll_list" -> fetchPollList(call,result,hmssdk)
- "fetch_poll_questions" -> fetchPollQuestions(call,result,hmssdk)
- "get_poll_results" -> getPollResults(call,result,hmssdk)
+ companion object {
+ fun pollActions(
+ call: MethodCall,
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ polls: ArrayList?,
+ ) {
+ when (call.method) {
+ "quick_start_poll" -> quickStartPoll(call, result, hmssdk)
+ "add_single_choice_poll_response" -> addSingleChoicePollResponse(call, result, hmssdk, polls)
+ "add_multi_choice_poll_response" -> addMultiChoicePollResponse(call, result, hmssdk, polls)
+ "stop_poll" -> stopPoll(call, result, hmssdk, polls)
+ "fetch_leaderboard" -> fetchLeaderboard(call, result, hmssdk)
+ "fetch_poll_list" -> fetchPollList(call, result, hmssdk)
+ "fetch_poll_questions" -> fetchPollQuestions(call, result, hmssdk)
+ "get_poll_results" -> getPollResults(call, result, hmssdk)
}
}
- private fun quickStartPoll(call: MethodCall, result: MethodChannel.Result, hmssdk: HMSSDK){
+ private fun quickStartPoll(
+ call: MethodCall,
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
+ val pollBuilderMap = call.argument?>("poll_builder")
- val pollBuilderMap = call.argument?>("poll_builder")
-
- val pollBuilder = HMSPollBuilderExtension.toHMSPollBuilder(pollBuilderMap,hmssdk)
+ val pollBuilder = HMSPollBuilderExtension.toHMSPollBuilder(pollBuilderMap, hmssdk)
pollBuilder?.let {
- hmssdk.getHmsInteractivityCenter().quickStartPoll( pollBuilder, HMSCommonAction.getActionListener(result))
- }?:run{
+ hmssdk.getHmsInteractivityCenter().quickStartPoll(pollBuilder, HMSCommonAction.getActionListener(result))
+ } ?: run {
HMSErrorLogger.returnArgumentsError("pollBuilder parsing failed")
}
-
}
- private fun addSingleChoicePollResponse(call: MethodCall, methodChannelResult: MethodChannel.Result, hmssdk: HMSSDK, currentPolls: ArrayList?){
-
+ private fun addSingleChoicePollResponse(
+ call: MethodCall,
+ methodChannelResult: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ currentPolls: ArrayList?,
+ ) {
val pollId = call.argument("poll_id")
val index = call.argument("question_index")
val userId = call.argument("user_id")
- val answer = call.argument>("answer")
+ val answer = call.argument>("answer")
val timeTakenToAnswer = call.argument("time_taken_to_answer")
/*
* Here we get index for the option selected by the user
* if the option doesn't exist we return the arguments error
*/
- val optionIndex = answer?.let {
- it["index"] as Int
- }?:run {
- HMSErrorLogger.returnArgumentsError("Invalid option index")
- return
- }
+ val optionIndex =
+ answer?.let {
+ it["index"] as Int
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("Invalid option index")
+ return
+ }
/*
* We fetch the polls which are currently active and find the poll matching the pollId
@@ -82,54 +93,67 @@ class HMSPollAction {
*
* If anywhere the sdk is unable to find the property we return the error
*/
- currentPolls?.find { it.pollId == pollId }?.let {poll ->
- index?.let {questionIndex ->
+ currentPolls?.find { it.pollId == pollId }?.let { poll ->
+ index?.let { questionIndex ->
- poll.questions?.get(questionIndex)?.let { currentQuestion ->
+ poll.questions?.get(questionIndex)?.let { currentQuestion ->
/*
* Here the index needs to be subtracted by 1
* since the HMSPollQuestionOption object has indexing with 1
*/
- val questionOption = currentQuestion.options?.get(optionIndex - 1)
- questionOption?.let {selectedOption ->
- val response =
- timeTakenToAnswer?.let {_timeTakenToAnswer ->
- HMSPollResponseBuilder(poll, userId).addResponse(currentQuestion,selectedOption,
- _timeTakenToAnswer.toLong()
- )
- }?: run {
- HMSPollResponseBuilder(poll, userId).addResponse(currentQuestion,selectedOption)
- }
- hmssdk.getHmsInteractivityCenter().add(response, object : HmsTypedActionResultListener{
+ val questionOption = currentQuestion.options?.get(optionIndex - 1)
+ questionOption?.let { selectedOption ->
+ val response =
+ timeTakenToAnswer?.let { _timeTakenToAnswer ->
+ HMSPollResponseBuilder(poll, userId).addResponse(
+ currentQuestion,
+ selectedOption,
+ _timeTakenToAnswer.toLong(),
+ )
+ } ?: run {
+ HMSPollResponseBuilder(poll, userId).addResponse(currentQuestion, selectedOption)
+ }
+ hmssdk.getHmsInteractivityCenter().add(
+ response,
+ object : HmsTypedActionResultListener {
override fun onSuccess(result: PollAnswerResponse) {
- methodChannelResult.success(HMSResultExtension.toDictionary(true,HMSPollAnswerResponseExtension.toDictionary(result)))
+ methodChannelResult.success(
+ HMSResultExtension.toDictionary(true, HMSPollAnswerResponseExtension.toDictionary(result)),
+ )
}
+
override fun onError(error: HMSException) {
- methodChannelResult.success(HMSResultExtension.toDictionary(false,HMSExceptionExtension.toDictionary(error)))
+ methodChannelResult.success(
+ HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)),
+ )
}
- })
- }
-
- }?:run {
- HMSErrorLogger.returnArgumentsError("Question not found")
- return
+ },
+ )
}
- }?: run {
- HMSErrorLogger.returnArgumentsError("Incorrect question index")
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("Question not found")
return
}
- }?:run {
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("Incorrect question index")
+ return
+ }
+ } ?: run {
HMSErrorLogger.returnArgumentsError("No poll with given pollId found")
return
}
}
- private fun addMultiChoicePollResponse(call: MethodCall, methodChannelResult: MethodChannel.Result, hmssdk: HMSSDK, currentPolls: ArrayList?){
-
+ private fun addMultiChoicePollResponse(
+ call: MethodCall,
+ methodChannelResult: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ currentPolls: ArrayList?,
+ ) {
val pollId = call.argument("poll_id")
val index = call.argument("question_index")
val userId = call.argument("user_id")
- val answer = call.argument?>>("answer")
+ val answer = call.argument?>>("answer")
val timeTakenToAnswer = call.argument("time_taken_to_answer")
/*
@@ -144,121 +168,154 @@ class HMSPollAction {
* If anywhere the sdk is unable to find the property we return the error
*/
currentPolls?.find { it.pollId == pollId }?.let { poll ->
- index?.let {questionIndex ->
+ index?.let { questionIndex ->
poll.questions?.get(questionIndex)?.let { currentQuestion ->
val questionOptions = ArrayList()
answer?.forEach { selectedOptions ->
- selectedOptions as HashMap
+ selectedOptions as HashMap
/*
* Here the index needs to be subtracted by 1
* since the HMSPollQuestionOption object has indexing with 1
*/
selectedOptions["index"]?.let {
- index -> index as Int
+ index ->
+ index as Int
val questionOption = currentQuestion.options?.get(index - 1)
- questionOption?.let {option ->
+ questionOption?.let { option ->
questionOptions.add(option)
}
}
}
val response =
- timeTakenToAnswer?.let {_timeTakenToAnswer ->
- HMSPollResponseBuilder(poll, userId).addResponse(currentQuestion,questionOptions,
- _timeTakenToAnswer.toLong()
+ timeTakenToAnswer?.let { _timeTakenToAnswer ->
+ HMSPollResponseBuilder(poll, userId).addResponse(
+ currentQuestion,
+ questionOptions,
+ _timeTakenToAnswer.toLong(),
)
- }?: run {
- HMSPollResponseBuilder(poll, userId).addResponse(currentQuestion,questionOptions)
- }
- hmssdk.getHmsInteractivityCenter().add(response, object : HmsTypedActionResultListener{
- override fun onSuccess(result: PollAnswerResponse) {
- methodChannelResult.success(HMSResultExtension.toDictionary(true,HMSPollAnswerResponseExtension.toDictionary(result)))
- }
- override fun onError(error: HMSException) {
- methodChannelResult.success(HMSResultExtension.toDictionary(false,HMSExceptionExtension.toDictionary(error)))
+ } ?: run {
+ HMSPollResponseBuilder(poll, userId).addResponse(currentQuestion, questionOptions)
}
- })
+ hmssdk.getHmsInteractivityCenter().add(
+ response,
+ object : HmsTypedActionResultListener {
+ override fun onSuccess(result: PollAnswerResponse) {
+ methodChannelResult.success(
+ HMSResultExtension.toDictionary(true, HMSPollAnswerResponseExtension.toDictionary(result)),
+ )
+ }
- }?: run {
+ override fun onError(error: HMSException) {
+ methodChannelResult.success(
+ HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)),
+ )
+ }
+ },
+ )
+ } ?: run {
HMSErrorLogger.returnArgumentsError("Question not found")
return
}
- }?:run{
+ } ?: run {
HMSErrorLogger.returnArgumentsError("Incorrect question index")
return
}
-
- }?:run {
- HMSErrorLogger.returnArgumentsError("No poll with given pollId found")
- return
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("No poll with given pollId found")
+ return
}
}
- private fun stopPoll(call: MethodCall, result: MethodChannel.Result, hmssdk: HMSSDK, currentPolls: ArrayList?){
+ private fun stopPoll(
+ call: MethodCall,
+ result: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ currentPolls: ArrayList?,
+ ) {
val pollId = call.argument("poll_id")
- val poll = currentPolls?.first{
- it.pollId == pollId
- }?:run {
- HMSErrorLogger.returnArgumentsError("No Poll with given pollId found")
- return
- }
- hmssdk.getHmsInteractivityCenter().stop(poll,HMSCommonAction.getActionListener(result))
-
+ val poll =
+ currentPolls?.first {
+ it.pollId == pollId
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("No Poll with given pollId found")
+ return
+ }
+ hmssdk.getHmsInteractivityCenter().stop(poll, HMSCommonAction.getActionListener(result))
}
- private fun fetchLeaderboard(call: MethodCall, methodChannelResult: MethodChannel.Result, hmssdk: HMSSDK){
+ private fun fetchLeaderboard(
+ call: MethodCall,
+ methodChannelResult: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
val pollId = call.argument("poll_id")
val count = call.argument("count")
val startIndex = call.argument("start_index")
val includeCurrentPeer = call.argument("include_current_peer")
- if(pollId == null || count == null || startIndex == null || includeCurrentPeer == null){
+ if (pollId == null || count == null || startIndex == null || includeCurrentPeer == null) {
HMSErrorLogger.returnArgumentsError("Either pollId, count, startIndex or includeCurrentPeer is null")
return
}
- hmssdk.getHmsInteractivityCenter().fetchLeaderboard(pollId,count.toLong(),startIndex.toLong(),includeCurrentPeer, object : HmsTypedActionResultListener {
- override fun onSuccess(result: PollLeaderboardResponse) {
- methodChannelResult.success(HMSResultExtension.toDictionary(true,HMSPollLeaderboardResponseExtension.toDictionary(result)))
- }
+ hmssdk.getHmsInteractivityCenter().fetchLeaderboard(
+ pollId,
+ count.toLong(),
+ startIndex.toLong(),
+ includeCurrentPeer,
+ object : HmsTypedActionResultListener {
+ override fun onSuccess(result: PollLeaderboardResponse) {
+ methodChannelResult.success(
+ HMSResultExtension.toDictionary(true, HMSPollLeaderboardResponseExtension.toDictionary(result)),
+ )
+ }
- override fun onError(error: HMSException) {
- methodChannelResult.success(HMSResultExtension.toDictionary(false,HMSExceptionExtension.toDictionary(error)))
- }
- })
+ override fun onError(error: HMSException) {
+ methodChannelResult.success(HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)))
+ }
+ },
+ )
}
- private fun fetchPollList(call: MethodCall, methodChannelResult: MethodChannel.Result, hmssdk: HMSSDK){
+ private fun fetchPollList(
+ call: MethodCall,
+ methodChannelResult: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
val state = call.argument("poll_state")
val pollState = getPollState(state)
pollState?.let {
- hmssdk.getHmsInteractivityCenter().fetchPollList(it,object : HmsTypedActionResultListener>{
- override fun onSuccess(result: List) {
-
- val map = ArrayList>()
+ hmssdk.getHmsInteractivityCenter().fetchPollList(
+ it,
+ object : HmsTypedActionResultListener> {
+ override fun onSuccess(result: List) {
+ val map = ArrayList>()
- result.forEach { poll ->
- map.add(HMSPollExtension.toDictionary(poll))
+ result.forEach { poll ->
+ map.add(HMSPollExtension.toDictionary(poll))
+ }
+ methodChannelResult.success(HMSResultExtension.toDictionary(true, map))
}
- methodChannelResult.success(HMSResultExtension.toDictionary(true, map))
- }
-
- override fun onError(error: HMSException) {
- methodChannelResult.success(HMSResultExtension.toDictionary(false,HMSExceptionExtension.toDictionary(error)))
- }
- })
-
- }?: run {
- HMSErrorLogger.returnHMSException("fetchPollList","No poll state matched", "ARGUMENTS_ERROR",methodChannelResult)
+ override fun onError(error: HMSException) {
+ methodChannelResult.success(HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)))
+ }
+ },
+ )
+ } ?: run {
+ HMSErrorLogger.returnHMSException("fetchPollList", "No poll state matched", "ARGUMENTS_ERROR", methodChannelResult)
}
-
}
- private fun fetchPollQuestions(call: MethodCall, methodChannelResult: MethodChannel.Result, hmssdk: HMSSDK){
+ private fun fetchPollQuestions(
+ call: MethodCall,
+ methodChannelResult: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
val pollId = call.argument("poll_id")
val state = call.argument("poll_state")
@@ -266,51 +323,63 @@ class HMSPollAction {
val pollState = getPollState(state)
pollState?.let {
- hmssdk.getHmsInteractivityCenter().fetchPollList(it,object : HmsTypedActionResultListener>{
- override fun onSuccess(result: List) {
-
- val poll = result.find {
- _poll ->
- _poll.pollId == pollId
- }
- poll?.let { _poll ->
- hmssdk.getHmsInteractivityCenter().fetchPollQuestions(_poll, object : HmsTypedActionResultListener>{
- override fun onSuccess(result: List) {
- val map = ArrayList>()
-
- result.forEach { pollQuestion ->
- val pollQuestionMap = HMSPollQuestionExtension.toDictionary(pollQuestion)
- pollQuestionMap?.let { _pollQuestionMap ->
- map.add(_pollQuestionMap)
- }
- }
- methodChannelResult.success(HMSResultExtension.toDictionary(true, map))
- }
-
- override fun onError(error: HMSException) {
- methodChannelResult.success(HMSResultExtension.toDictionary(false,HMSExceptionExtension.toDictionary(error)))
+ hmssdk.getHmsInteractivityCenter().fetchPollList(
+ it,
+ object : HmsTypedActionResultListener> {
+ override fun onSuccess(result: List) {
+ val poll =
+ result.find {
+ _poll ->
+ _poll.pollId == pollId
}
+ poll?.let { _poll ->
+ hmssdk.getHmsInteractivityCenter().fetchPollQuestions(
+ _poll,
+ object : HmsTypedActionResultListener> {
+ override fun onSuccess(result: List) {
+ val map = ArrayList>()
+
+ result.forEach { pollQuestion ->
+ val pollQuestionMap = HMSPollQuestionExtension.toDictionary(pollQuestion)
+ pollQuestionMap?.let { _pollQuestionMap ->
+ map.add(_pollQuestionMap)
+ }
+ }
+ methodChannelResult.success(HMSResultExtension.toDictionary(true, map))
+ }
- })
- }?:run{
- HMSErrorLogger.logError("fetchPollQuestions","No poll with given pollId found","NULL_ERROR")
+ override fun onError(error: HMSException) {
+ methodChannelResult.success(
+ HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)),
+ )
+ }
+ },
+ )
+ } ?: run {
+ HMSErrorLogger.logError("fetchPollQuestions", "No poll with given pollId found", "NULL_ERROR")
+ }
}
- }
- override fun onError(error: HMSException) {
- methodChannelResult.success(HMSResultExtension.toDictionary(false,HMSExceptionExtension.toDictionary(error)))
- }
- })
- }?:run{
+ override fun onError(error: HMSException) {
+ methodChannelResult.success(
+ HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)),
+ )
+ }
+ },
+ )
+ } ?: run {
HMSErrorLogger.returnArgumentsError("No state matched with given state")
}
- }?:run{
+ } ?: run {
HMSErrorLogger.returnArgumentsError("pollId is null")
}
}
- private fun getPollResults(call: MethodCall, methodChannelResult: MethodChannel.Result, hmssdk: HMSSDK){
-
+ private fun getPollResults(
+ call: MethodCall,
+ methodChannelResult: MethodChannel.Result,
+ hmssdk: HMSSDK,
+ ) {
val pollId = call.argument("poll_id")
val state = call.argument("poll_state")
@@ -318,48 +387,61 @@ class HMSPollAction {
val pollState = getPollState(state)
pollState?.let {
- hmssdk.getHmsInteractivityCenter().fetchPollList(it,object : HmsTypedActionResultListener>{
- override fun onSuccess(result: List) {
-
- val poll = result.find {
- _poll ->
- _poll.pollId == pollId
- }
- poll?.let { _poll ->
- hmssdk.getHmsInteractivityCenter().getPollResults(_poll, object : HmsTypedActionResultListener{
- override fun onSuccess(result: HmsPoll) {
- methodChannelResult.success(HMSResultExtension.toDictionary(true, HMSPollExtension.toDictionary(result)))
- }
-
- override fun onError(error: HMSException) {
- methodChannelResult.success(HMSResultExtension.toDictionary(false,HMSExceptionExtension.toDictionary(error)))
+ hmssdk.getHmsInteractivityCenter().fetchPollList(
+ it,
+ object : HmsTypedActionResultListener> {
+ override fun onSuccess(result: List) {
+ val poll =
+ result.find {
+ _poll ->
+ _poll.pollId == pollId
}
+ poll?.let { _poll ->
+ hmssdk.getHmsInteractivityCenter().getPollResults(
+ _poll,
+ object : HmsTypedActionResultListener {
+ override fun onSuccess(result: HmsPoll) {
+ methodChannelResult.success(
+ HMSResultExtension.toDictionary(true, HMSPollExtension.toDictionary(result)),
+ )
+ }
- })
- }?:run{
- HMSErrorLogger.logError("getPollResults","No poll with given pollId found","NULL_ERROR")
+ override fun onError(error: HMSException) {
+ methodChannelResult.success(
+ HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)),
+ )
+ }
+ },
+ )
+ } ?: run {
+ HMSErrorLogger.logError("getPollResults", "No poll with given pollId found", "NULL_ERROR")
+ }
}
- }
- override fun onError(error: HMSException) {
- methodChannelResult.success(HMSResultExtension.toDictionary(false,HMSExceptionExtension.toDictionary(error)))
- }
- })
- }?:run{
+ override fun onError(error: HMSException) {
+ methodChannelResult.success(
+ HMSResultExtension.toDictionary(false, HMSExceptionExtension.toDictionary(error)),
+ )
+ }
+ },
+ )
+ } ?: run {
HMSErrorLogger.returnArgumentsError("No state matched with given state")
}
- }?:run{
+ } ?: run {
HMSErrorLogger.returnArgumentsError("pollId is null")
}
}
- private fun getPollState(pollState: String?):HmsPollState?{
- return when(pollState){
- "created"-> HmsPollState.CREATED
- "started" -> HmsPollState.STARTED
+ private fun getPollState(pollState: String?): HmsPollState? {
+ return when (pollState) {
+ "created" -> HmsPollState.CREATED
+ "started" -> HmsPollState.STARTED
"stopped" -> HmsPollState.STOPPED
- else -> {null}
+ else -> {
+ null
+ }
}
}
}
-}
\ No newline at end of file
+}
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 a6bec486b..6eecc5f13 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,9 +1,6 @@
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
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollAnswerExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollAnswerExtension.kt
index d623f20ad..b02ac910c 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollAnswerExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollAnswerExtension.kt
@@ -3,12 +3,9 @@ package live.hms.hmssdk_flutter.poll_extension
import live.hms.hmssdk_flutter.HMSErrorLogger
import live.hms.hmssdk_flutter.poll_extension.HMSPollQuestionExtension.Companion.getStringFromPollQuestionType
import live.hms.video.polls.models.answer.HmsPollAnswer
-import live.hms.video.polls.models.network.HMSPollQuestionResponse
class HMSPollAnswerExtension {
-
companion object {
-
fun toDictionary(answer: HmsPollAnswer?): HashMap? {
answer?.let {
val map = HashMap()
@@ -26,72 +23,76 @@ class HMSPollAnswerExtension {
}
}
- fun toHMSPollAnswer(answerMap: HashMap?): HmsPollAnswer?{
-
+ fun toHMSPollAnswer(answerMap: HashMap?): HmsPollAnswer? {
answerMap?.let {
-
- val answer = answerMap["answer"]?.let {
- it as String
- }?:run {
- HMSErrorLogger.returnArgumentsError("answer should not be null")
- return null
- }
-
- val duration = answerMap["duration"]?.let {
- (it as Int).toLong()
- }?:run {
- HMSErrorLogger.returnArgumentsError("duration should not be null")
- return null
- }
-
- val questionId = answerMap["question_id"]?.let {
- it as Int
- }?:run {
- HMSErrorLogger.returnArgumentsError("questionId should not be null")
- return null
- }
-
- val questionType = answerMap["question_type"]?.let {
- HMSPollQuestionExtension.getPollQuestionTypeFromString(it as String)
- }?:run {
- HMSErrorLogger.returnArgumentsError("questionType should not be null")
- return null
- }
-
- val selectedOption = answerMap["selected_option"]?.let {
- it as Int
- }?:run {
- HMSErrorLogger.returnArgumentsError("selectedOption should not be null")
- return null
- }
-
- val selectedOptions = answerMap["selected_options"]?.let {
- it as ArrayList
- }?:run {
- HMSErrorLogger.returnArgumentsError("selectedOptions should not be null")
- return null
- }
-
- val skipped = answerMap["skipped"]?.let {
- it as Boolean
- }?:run {
- HMSErrorLogger.returnArgumentsError("skipped should not be null")
- return null
- }
-
- val update = answerMap["update"]?.let {
- it as Boolean
- }?:run {
- HMSErrorLogger.returnArgumentsError("update should not be null")
- return null
- }
-
- return HmsPollAnswer(questionId,questionType,skipped,selectedOption,selectedOptions,answer,update,duration)
-
-
- }?:run {
+ val answer =
+ answerMap["answer"]?.let {
+ it as String
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("answer should not be null")
+ return null
+ }
+
+ val duration =
+ answerMap["duration"]?.let {
+ (it as Int).toLong()
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("duration should not be null")
+ return null
+ }
+
+ val questionId =
+ answerMap["question_id"]?.let {
+ it as Int
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("questionId should not be null")
+ return null
+ }
+
+ val questionType =
+ answerMap["question_type"]?.let {
+ HMSPollQuestionExtension.getPollQuestionTypeFromString(it as String)
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("questionType should not be null")
+ return null
+ }
+
+ val selectedOption =
+ answerMap["selected_option"]?.let {
+ it as Int
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("selectedOption should not be null")
+ return null
+ }
+
+ val selectedOptions =
+ answerMap["selected_options"]?.let {
+ it as ArrayList
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("selectedOptions should not be null")
+ return null
+ }
+
+ val skipped =
+ answerMap["skipped"]?.let {
+ it as Boolean
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("skipped should not be null")
+ return null
+ }
+
+ val update =
+ answerMap["update"]?.let {
+ it as Boolean
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("update should not be null")
+ return null
+ }
+
+ return HmsPollAnswer(questionId, questionType, skipped, selectedOption, selectedOptions, answer, update, duration)
+ } ?: run {
return null
}
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollAnswerResponseExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollAnswerResponseExtension.kt
index cf0c2e38e..852d72f3b 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollAnswerResponseExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollAnswerResponseExtension.kt
@@ -4,14 +4,12 @@ import live.hms.hmssdk_flutter.HMSExceptionExtension
import live.hms.video.polls.models.answer.PollAnswerResponse
class HMSPollAnswerResponseExtension {
-
- companion object{
- fun toDictionary(pollAnswerResponse: PollAnswerResponse):HashMap?{
-
- val map = HashMap()
- val resultMapList = ArrayList>()
- pollAnswerResponse.result.forEach{
- val resultMap = HashMap()
+ companion object {
+ fun toDictionary(pollAnswerResponse: PollAnswerResponse): HashMap? {
+ val map = HashMap()
+ val resultMapList = ArrayList>()
+ pollAnswerResponse.result.forEach {
+ val resultMap = HashMap()
resultMap["correct"] = it.correct
resultMap["error"] = HMSExceptionExtension.toDictionary(it.error)
resultMap["question_index"] = it.questionIndex
@@ -24,4 +22,4 @@ class HMSPollAnswerResponseExtension {
return map
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollBuilderExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollBuilderExtension.kt
index e53f9765a..d62a8fe98 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollBuilderExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollBuilderExtension.kt
@@ -1,26 +1,23 @@
package live.hms.hmssdk_flutter.poll_extension
import live.hms.hmssdk_flutter.HMSErrorLogger
-import live.hms.hmssdk_flutter.HMSRoleExtension
import live.hms.video.polls.HMSPollBuilder
import live.hms.video.polls.HMSPollQuestionBuilder
import live.hms.video.polls.models.HmsPollCategory
import live.hms.video.polls.models.HmsPollUserTrackingMode
-import live.hms.video.polls.models.question.HMSPollQuestion
import live.hms.video.polls.models.question.HMSPollQuestionType
import live.hms.video.sdk.HMSSDK
import live.hms.video.sdk.models.role.HMSRole
-import okhttp3.internal.notify
class HMSPollBuilderExtension {
-
- companion object{
-
- fun toHMSPollBuilder(pollBuilderMap: HashMap?,hmssdk: HMSSDK):HMSPollBuilder?{
-
+ companion object {
+ fun toHMSPollBuilder(
+ pollBuilderMap: HashMap?,
+ hmssdk: HMSSDK,
+ ): HMSPollBuilder? {
pollBuilderMap?.let {
val pollBuilder = HMSPollBuilder.Builder()
- pollBuilderMap["anonymous"]?.let{
+ pollBuilderMap["anonymous"]?.let {
pollBuilder.withAnonymous(it as Boolean)
}
pollBuilderMap["duration"]?.let {
@@ -41,13 +38,12 @@ class HMSPollBuilderExtension {
val questions = it as ArrayList<*>
val pollQuestions = ArrayList()
questions.forEach { pollQuestion ->
- pollQuestion as HashMap?
+ pollQuestion as HashMap?
val pollQuestionBuilder = getPollQuestionBuilder(pollQuestion)
- pollQuestionBuilder?.let {questionBuilder ->
+ pollQuestionBuilder?.let { questionBuilder ->
pollBuilder.addQuestion(questionBuilder)
}
}
-
}
val availableRoles = hmssdk.getRoles()
@@ -66,9 +62,9 @@ class HMSPollBuilderExtension {
pollBuilderMap["roles_that_can_vote"]?.let {
val roles = it as ArrayList<*>
val rolesThatCanVote = ArrayList()
- roles.forEach{ forEveryRole ->
+ roles.forEach { forEveryRole ->
val role = availableRoles.find { role -> role.name == forEveryRole }
- role?.let {currentRole ->
+ role?.let { currentRole ->
rolesThatCanVote.add(currentRole)
}
}
@@ -80,122 +76,123 @@ class HMSPollBuilderExtension {
}
return pollBuilder.build()
-
- }?: run {
+ } ?: run {
return null
}
-
-
}
private fun getPollCategoryFromString(category: String): HmsPollCategory {
- return when(category) {
+ return when (category) {
"poll" -> HmsPollCategory.POLL
"quiz" -> HmsPollCategory.QUIZ
else -> HmsPollCategory.POLL
}
}
-
- private fun getPollUserTrackingModeFromString(pollUserTrackingMode: String):HmsPollUserTrackingMode{
- return when(pollUserTrackingMode){
+ private fun getPollUserTrackingModeFromString(pollUserTrackingMode: String): HmsPollUserTrackingMode {
+ return when (pollUserTrackingMode) {
"user_id" -> HmsPollUserTrackingMode.USER_ID
"peer_id" -> HmsPollUserTrackingMode.PEER_ID
- "username"-> HmsPollUserTrackingMode.USERNAME
+ "username" -> HmsPollUserTrackingMode.USERNAME
else -> HmsPollUserTrackingMode.USER_ID
-
}
}
- private fun getPollQuestionTypeFromString(pollQuestionType: String): HMSPollQuestionType{
- return when(pollQuestionType){
+ private fun getPollQuestionTypeFromString(pollQuestionType: String): HMSPollQuestionType {
+ return when (pollQuestionType) {
"multi_choice" -> HMSPollQuestionType.multiChoice
"short_answer" -> HMSPollQuestionType.shortAnswer
- "long_answer" -> HMSPollQuestionType.longAnswer
+ "long_answer" -> HMSPollQuestionType.longAnswer
"single_choice" -> HMSPollQuestionType.singleChoice
else -> HMSPollQuestionType.singleChoice
}
}
- private fun getPollQuestionBuilder(pollQuestion: HashMap?):HMSPollQuestionBuilder?{
-
- val pollQuestionBuilder : HMSPollQuestionBuilder.Builder
+ private fun getPollQuestionBuilder(pollQuestion: HashMap?): HMSPollQuestionBuilder? {
+ val pollQuestionBuilder: HMSPollQuestionBuilder.Builder
pollQuestion?.let {
+ val type =
+ pollQuestion["type"]?.let { type ->
+ getPollQuestionTypeFromString(type as String)
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("type should not be null")
+ return null
+ }
- val type = pollQuestion["type"]?.let {type ->
- getPollQuestionTypeFromString(type as String)
- }?:run{
- HMSErrorLogger.returnArgumentsError("type should not be null")
- return null
- }
-
- type.let {questionType ->
+ type.let { questionType ->
pollQuestionBuilder = HMSPollQuestionBuilder.Builder(questionType)
}
- val canSkip = pollQuestion["can_skip"]?.let {canSkipQuestion ->
- canSkipQuestion as Boolean
- }
+ val canSkip =
+ pollQuestion["can_skip"]?.let { canSkipQuestion ->
+ canSkipQuestion as Boolean
+ }
canSkip?.let { canSkipQuestion ->
pollQuestionBuilder.withCanBeSkipped(canSkipQuestion)
}
- val text = pollQuestion["text"]?.let { text ->
- text as String
- }
+ val text =
+ pollQuestion["text"]?.let { text ->
+ text as String
+ }
text?.let {
pollQuestionBuilder.withTitle(text)
}
- val duration = pollQuestion["duration"]?.let { duration ->
- (duration as Int).toLong()
- }
+ val duration =
+ pollQuestion["duration"]?.let { duration ->
+ (duration as Int).toLong()
+ }
duration?.let { duration ->
pollQuestionBuilder.withDuration(duration)
}
- val weight = pollQuestion["weight"]?.let {weight ->
- weight as Int
- }
+ val weight =
+ pollQuestion["weight"]?.let { weight ->
+ weight as Int
+ }
weight?.let {
pollQuestionBuilder.withWeight(weight)
}
- val answerHidden = pollQuestion["answer_hidden"]?.let {answerHidden ->
- answerHidden as Boolean
- }
+ val answerHidden =
+ pollQuestion["answer_hidden"]?.let { answerHidden ->
+ answerHidden as Boolean
+ }
answerHidden?.let {
pollQuestionBuilder.withAnswerHidden(answerHidden)
}
- val maxLength = pollQuestion["max_length"]?.let { maxLength ->
- (maxLength as Int).toLong()
- }
+ val maxLength =
+ pollQuestion["max_length"]?.let { maxLength ->
+ (maxLength as Int).toLong()
+ }
maxLength?.let {
pollQuestionBuilder.withMaxLength(maxLength)
}
-
- val minLength = pollQuestion["min_length"]?.let { minLength ->
- (minLength as Int).toLong()
- }
+ val minLength =
+ pollQuestion["min_length"]?.let { minLength ->
+ (minLength as Int).toLong()
+ }
minLength?.let {
pollQuestionBuilder.withMinLength(minLength)
}
- val pollOptions = pollQuestion["poll_options"]?.let { options ->
- options as ArrayList
- }?:run {
- HMSErrorLogger.returnArgumentsError("pollOptions should not be null")
- null
- }
+ val pollOptions =
+ pollQuestion["poll_options"]?.let { options ->
+ options as ArrayList
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("pollOptions should not be null")
+ null
+ }
pollOptions?.let {
pollOptions.forEach {
@@ -203,45 +200,46 @@ class HMSPollBuilderExtension {
}
}
- val option = pollQuestion["options"]?.let { options ->
+ val option =
+ pollQuestion["options"]?.let { options ->
- options as ArrayList>
- val optionMap = ArrayList>()
+ options as ArrayList>
+ val optionMap = ArrayList>()
- options.forEach {
- val text = it["text"] as String?
- text?.let { optionText ->
- val isCorrect = it["is_correct"]
- isCorrect?.let { isCorrectOption ->
- optionMap.add(Pair(optionText,isCorrectOption))
+ options.forEach {
+ val text = it["text"] as String?
+ text?.let { optionText ->
+ val isCorrect = it["is_correct"]
+ isCorrect?.let { isCorrectOption ->
+ optionMap.add(Pair(optionText, isCorrectOption))
+ }
}
}
+ optionMap
+ } ?: run {
+ HMSErrorLogger.returnArgumentsError("options should not be null")
+ null
}
- optionMap
- }?:run {
- HMSErrorLogger.returnArgumentsError("options should not be null")
- null
- }
option?.let {
option.forEach {
- pollQuestionBuilder.addQuizOption(it.first,it.second)
+ pollQuestionBuilder.addQuizOption(it.first, it.second)
}
}
- val canChangeResponse = pollQuestion["can_change_response"]?.let { canChangeResponse ->
- canChangeResponse as Boolean
- }
+ val canChangeResponse =
+ pollQuestion["can_change_response"]?.let { canChangeResponse ->
+ canChangeResponse as Boolean
+ }
canChangeResponse?.let {
pollQuestionBuilder.withCanChangeResponse(it)
}
return pollQuestionBuilder.build()
-
- }?:run{
+ } ?: run {
return null
}
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollExtension.kt
index e70358047..7852b20fb 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollExtension.kt
@@ -5,11 +5,9 @@ import live.hms.hmssdk_flutter.HMSRoleExtension
import live.hms.video.polls.models.*
class HMSPollExtension {
-
companion object {
fun toDictionary(poll: HmsPoll): HashMap {
-
- val map = HashMap()
+ val map = HashMap()
map["anonymous"] = poll.anonymous
map["category"] = getPollCategory(poll.category)
@@ -19,22 +17,22 @@ class HMSPollExtension {
map["poll_id"] = poll.pollId
map["question_count"] = poll.questionCount
- val questions = ArrayList?>()
- poll.questions?.forEach{
+ val questions = ArrayList?>()
+ poll.questions?.forEach {
questions.add(HMSPollQuestionExtension.toDictionary(it))
}
map["questions"] = questions
map["result"] = HMSPollResultDisplayExtension.toDictionary(poll.result)
- val rolesThatCanViewResponses = ArrayList?>()
- poll.rolesThatCanViewResponses.forEach{
+ val rolesThatCanViewResponses = ArrayList?>()
+ poll.rolesThatCanViewResponses.forEach {
rolesThatCanViewResponses.add(HMSRoleExtension.toDictionary(it))
}
map["roles_that_can_view_responses"] = rolesThatCanViewResponses
- val rolesThatCanVote = ArrayList?>()
- poll.rolesThatCanVote.forEach{
+ val rolesThatCanVote = ArrayList?>()
+ poll.rolesThatCanVote.forEach {
rolesThatCanVote.add(HMSRoleExtension.toDictionary(it))
}
map["roles_that_can_vote"] = rolesThatCanVote
@@ -44,7 +42,7 @@ class HMSPollExtension {
map["state"] = getPollState(poll.state)
map["stopped_at"] = poll.stoppedAt?.let {
it * 1000
- }?:run {
+ } ?: run {
null
}
map["title"] = poll.title
@@ -52,16 +50,16 @@ class HMSPollExtension {
return map
}
- private fun getPollCategory(pollCategory: HmsPollCategory):String?{
- return when(pollCategory){
+ private fun getPollCategory(pollCategory: HmsPollCategory): String? {
+ return when (pollCategory) {
HmsPollCategory.POLL -> "poll"
HmsPollCategory.QUIZ -> "quiz"
else -> null
}
}
- private fun getPollUserTrackingMode(pollUserTrackingMode: HmsPollUserTrackingMode?):String?{
- return when(pollUserTrackingMode){
+ private fun getPollUserTrackingMode(pollUserTrackingMode: HmsPollUserTrackingMode?): String? {
+ return when (pollUserTrackingMode) {
HmsPollUserTrackingMode.USER_ID -> "user_id"
HmsPollUserTrackingMode.PEER_ID -> "peer_id"
HmsPollUserTrackingMode.USERNAME -> "username"
@@ -69,8 +67,8 @@ class HMSPollExtension {
}
}
- private fun getPollState(pollState: HmsPollState):String?{
- return when(pollState){
+ private fun getPollState(pollState: HmsPollState): String? {
+ return when (pollState) {
HmsPollState.CREATED -> "created"
HmsPollState.STARTED -> "started"
HmsPollState.STOPPED -> "stopped"
@@ -78,8 +76,8 @@ class HMSPollExtension {
}
}
- fun getPollUpdateType(hmsPollUpdateType: HMSPollUpdateType):String?{
- return when(hmsPollUpdateType){
+ fun getPollUpdateType(hmsPollUpdateType: HMSPollUpdateType): String? {
+ return when (hmsPollUpdateType) {
HMSPollUpdateType.started -> "started"
HMSPollUpdateType.stopped -> "stopped"
HMSPollUpdateType.resultsupdated -> "results_updated"
@@ -88,4 +86,3 @@ class HMSPollExtension {
}
}
}
-
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardEntryExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardEntryExtension.kt
index 335542faa..39d73eae0 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardEntryExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardEntryExtension.kt
@@ -3,12 +3,9 @@ package live.hms.hmssdk_flutter.poll_extension
import live.hms.video.polls.network.HMSPollLeaderboardEntry
class HMSPollLeaderboardEntryExtension {
-
- companion object{
-
- fun toDictionary(hmsPollLeaderboardEntry: HMSPollLeaderboardEntry):HashMap{
-
- val map = HashMap()
+ companion object {
+ fun toDictionary(hmsPollLeaderboardEntry: HMSPollLeaderboardEntry): HashMap {
+ val map = HashMap()
map["correct_responses"] = hmsPollLeaderboardEntry.correctResponses
map["duration"] = hmsPollLeaderboardEntry.duration
@@ -19,4 +16,4 @@ class HMSPollLeaderboardEntryExtension {
return map
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardResponseExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardResponseExtension.kt
index a87ca438c..47fafbbf4 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardResponseExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardResponseExtension.kt
@@ -3,14 +3,11 @@ package live.hms.hmssdk_flutter.poll_extension
import live.hms.video.polls.network.PollLeaderboardResponse
class HMSPollLeaderboardResponseExtension {
+ companion object {
+ fun toDictionary(pollLeaderboardResponse: PollLeaderboardResponse): HashMap {
+ val map = HashMap()
- companion object{
-
- fun toDictionary(pollLeaderboardResponse: PollLeaderboardResponse):HashMap{
-
- val map = HashMap()
-
- val entryMap = ArrayList>()
+ val entryMap = ArrayList>()
pollLeaderboardResponse.entries?.forEach { pollLeaderboardResponse ->
entryMap.add(HMSPollLeaderboardEntryExtension.toDictionary(pollLeaderboardResponse))
@@ -22,4 +19,4 @@ class HMSPollLeaderboardResponseExtension {
return map
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardSummaryExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardSummaryExtension.kt
index b5eee64d7..22b3692a2 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardSummaryExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollLeaderboardSummaryExtension.kt
@@ -3,16 +3,13 @@ package live.hms.hmssdk_flutter.poll_extension
import live.hms.video.polls.network.HMSPollLeaderboardSummary
class HMSPollLeaderboardSummaryExtension {
-
- companion object{
-
- fun toDictionary(pollLeaderboardSummary: HMSPollLeaderboardSummary?):HashMap?{
-
- if(pollLeaderboardSummary == null){
+ companion object {
+ fun toDictionary(pollLeaderboardSummary: HMSPollLeaderboardSummary?): HashMap? {
+ if (pollLeaderboardSummary == null) {
return null
}
- val map = HashMap()
+ val map = HashMap()
map["average_score"] = pollLeaderboardSummary.averageScore
map["average_time"] = pollLeaderboardSummary.averageTime
@@ -23,4 +20,4 @@ class HMSPollLeaderboardSummaryExtension {
return map
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollQuestionAnswerExtension.kt b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollQuestionAnswerExtension.kt
index e46e44a35..bcff675d3 100644
--- a/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollQuestionAnswerExtension.kt
+++ b/packages/hmssdk_flutter/android/src/main/kotlin/live/hms/hmssdk_flutter/poll_extension/HMSPollQuestionAnswerExtension.kt
@@ -4,47 +4,47 @@ import live.hms.hmssdk_flutter.HMSErrorLogger
import live.hms.video.polls.models.answer.HMSPollQuestionAnswer
class HMSPollQuestionAnswerExtension {
-
companion object {
- fun toDictionary(answer: HMSPollQuestionAnswer?):HashMap?{
+ fun toDictionary(answer: HMSPollQuestionAnswer?): HashMap? {
answer?.let {
- val map = HashMap()
+ val map = HashMap