From 3f8e00a8069cd292e249765a7af56991f590ff8e Mon Sep 17 00:00:00 2001 From: Pushpam <93931528+Decoder07@users.noreply.github.com> Date: Fri, 16 Feb 2024 19:04:30 +0530 Subject: [PATCH] Flut 210 (#1713) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Created extension for polls * Added poll callbacks * Added files for poll callbacks * Updated release notes (#1694) * Updated release notes * Updated tag position * Added image * Update readme * Updated links for sdk and prebuilt * Updated links for sdk and prebuilt * Fixed bugs * 🤖 Automated Format and Fix * released sample app version 1.5.124 (424) 🍀 * 🤖 Automated Format and Fix * Updated changelog * Updated pubspec * 🤖 Automated Format and Fix * Updated sdk version in room kit * 🤖 Automated Format and Fix * Updated changes * updated changelog * Completed poll parsing * Added iOS implementation * Added parsing in iOS * Added create poll ui * Added options ui * Added launch poll flow * Added launch poll flow * Added option to view previous polls * released sample app version 1.5.132 (432) 🍀 * Added voting flow * Refactored code * Completed voting flow * Added polls voted flow * released sample app version 1.5.133 (433) 🍀 * updated gems * updated supported version in app framework info.plist * Added changes * Fixed poll results issue * Updated changelog * Added option to start quiz * resolved errors * Added quiz option * Updated gemfile * 🤖 Automated Format and Fix * Updated sdk versions (#1714) * Updated sdk versions * Fixed build errors * 🤖 Automated Format and Fix --------- Co-authored-by: Decoder07 * 🤖 Automated Format and Fix * released sample app version 1.5.140 (440) 🍀 * updated packages * 🤖 Automated Format and Fix * Fixed bugs * 🤖 Automated Format and Fix * Added sorting for polls and quizzes * 🤖 Automated Format and Fix * release sample app version 1.5.141 (441) 🍀 * Added changelog --------- Co-authored-by: Decoder07 Co-authored-by: Yogesh Singh Co-authored-by: ygit --- packages/hms_room_kit/CHANGELOG.md | 15 + packages/hms_room_kit/example/pubspec.lock | 39 +- packages/hms_room_kit/example/pubspec.yaml | 2 +- .../lib/src/common/utility_functions.dart | 10 + .../lib/src/hmssdk_interactor.dart | 8 +- .../lib/src/meeting/meeting_page.dart | 2 +- .../lib/src/meeting/meeting_store.dart | 33 +- .../app_utilities_bottom_sheet.dart | 43 +- .../hls_app_utilities_bottom_sheet.dart | 26 +- .../poll_and_quiz_bottom_sheet.dart | 41 +- .../bottom_sheets/poll_vote_bottom_sheet.dart | 17 +- .../create_poll_form.dart | 29 +- .../poll_question_bottom_sheet.dart | 153 ++++-- .../poll_question_card.dart | 4 +- .../{poll_form.dart => poll_quiz_form.dart} | 33 +- .../saved_question_widget.dart | 44 +- .../poll_quiz_selection_widget.dart | 7 +- .../create_quiz_form.dart | 500 ++++++++++++++++++ .../voting_flow_widgets/poll_result_card.dart | 107 +++- .../voting_flow_widgets/poll_vote_card.dart | 11 +- .../widgets/toasts/hms_poll_start_toast.dart | 11 +- packages/hms_room_kit/pubspec.lock | 37 +- packages/hms_room_kit/pubspec.yaml | 5 +- packages/hmssdk_flutter/CHANGELOG.md | 15 + .../poll_extension/HMSPollBuilderExtension.kt | 8 +- .../example/ExampleAppChangelog.txt | 34 +- .../example/android/Gemfile.lock | 15 +- .../example/android/app/build.gradle | 8 +- .../hmssdk_flutter/example/ios/Gemfile.lock | 15 +- .../hmssdk_flutter/example/ios/Podfile.lock | 32 +- .../example/ios/Runner/Info.plist | 4 +- packages/hmssdk_flutter/example/pubspec.lock | 89 ++-- packages/hmssdk_flutter/example/pubspec.yaml | 2 +- .../polls/HMSPollBuilderExtension.swift | 4 +- .../lib/assets/sdk-versions.json | 2 +- .../lib/src/enum/hms_audio_codec.dart | 5 +- packages/hmssdk_flutter/lib/src/hmssdk.dart | 5 +- .../polls/hms_poll_interactivity_center.dart | 8 +- .../polls/hms_poll_question_builder.dart | 18 +- packages/hmssdk_flutter/pubspec.lock | 50 +- packages/hmssdk_flutter/pubspec.yaml | 2 +- 41 files changed, 1126 insertions(+), 367 deletions(-) rename packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/{poll_form.dart => poll_quiz_form.dart} (88%) create mode 100644 packages/hms_room_kit/lib/src/widgets/poll_widgets/quiz_creation_widgets/create_quiz_form.dart diff --git a/packages/hms_room_kit/CHANGELOG.md b/packages/hms_room_kit/CHANGELOG.md index e66819d5f..99086ca21 100644 --- a/packages/hms_room_kit/CHANGELOG.md +++ b/packages/hms_room_kit/CHANGELOG.md @@ -5,6 +5,21 @@ | hms_room_kit | [![Pub Version](https://img.shields.io/pub/v/hms_room_kit)](https://pub.dev/packages/hms_room_kit) | | hmssdk_flutter | [![Pub Version](https://img.shields.io/pub/v/hmssdk_flutter)](https://pub.dev/packages/hmssdk_flutter) | +## 1.0.13 - 2024-02-16 + +| Package | Version | +| -------------- | ------------------------------------------------------------------------------------------------------ | +| hms_room_kit | 1.0.13 | +| hmssdk_flutter | 1.9.10 | + +### 🚀 Added + +- Introducing quizzes on prebuilt + + Users can now create, manage, and stop quizzes directly from the prebuilt interface. + +Updated `hmssdk_flutter` package version to 1.9.10 + ## 1.0.12 - 2024-02-12 | Package | Version | diff --git a/packages/hms_room_kit/example/pubspec.lock b/packages/hms_room_kit/example/pubspec.lock index 7f0a5092c..4c3bd3349 100644 --- a/packages/hms_room_kit/example/pubspec.lock +++ b/packages/hms_room_kit/example/pubspec.lock @@ -154,10 +154,10 @@ packages: dependency: transitive description: name: flutter_foreground_task - sha256: e48d2d810a2d643362e64de41146ed8e95d4dd282bae6abbb32309d9f0bf5d67 + sha256: "9bcfcb43bba4a5446a056e723d21118ff6e184926b5557365c32c13caca157c2" url: "https://pub.dev" source: hosted - version: "6.1.2" + version: "6.1.3" flutter_linkify: dependency: transitive description: @@ -214,15 +214,14 @@ packages: path: ".." relative: true source: path - version: "1.0.12" + version: "1.0.13" hmssdk_flutter: dependency: transitive description: - name: hmssdk_flutter - sha256: bad4ff87c677970f0c9acfcd4e84b60089461e1c1eef23e3a3ae6ab191484b95 - url: "https://pub.dev" - source: hosted - version: "1.9.9" + path: "../../hmssdk_flutter" + relative: true + source: path + version: "1.9.10" http: dependency: transitive description: @@ -467,10 +466,10 @@ packages: dependency: transitive description: name: share_plus - sha256: f74fc3f1cbd99f39760182e176802f693fa0ec9625c045561cfad54681ea93dd + sha256: "3ef39599b00059db0990ca2e30fca0a29d8b37aae924d60063f8e0184cf20900" url: "https://pub.dev" source: hosted - version: "7.2.1" + version: "7.2.2" share_plus_platform_interface: dependency: transitive description: @@ -624,10 +623,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f" + sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745 url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.3.0" url_launcher_ios: dependency: transitive description: @@ -656,10 +655,10 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" url_launcher_web: dependency: transitive description: @@ -688,26 +687,26 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "18f6690295af52d081f6808f2f7c69f0eed6d7e23a71539d75f4aeb8f0062172" + sha256: "4ac59808bbfca6da38c99f415ff2d3a5d7ca0a6b4809c71d9cf30fba5daf9752" url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.10+1" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "531d20465c10dfac7f5cd90b60bbe4dd9921f1ec4ca54c83ebb176dbacb7bb2d" + sha256: f3247e7ab0ec77dc759263e68394990edc608fb2b480b80db8aa86ed09279e33 url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.10+1" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad" + sha256: "18489bdd8850de3dd7ca8a34e0c446f719ec63e2bab2e7a8cc66a9028dd76c5a" url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.10+1" vector_math: dependency: transitive description: diff --git a/packages/hms_room_kit/example/pubspec.yaml b/packages/hms_room_kit/example/pubspec.yaml index 34b4c4d6c..eb2e67f1f 100644 --- a/packages/hms_room_kit/example/pubspec.yaml +++ b/packages/hms_room_kit/example/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.0.12 +version: 1.0.13 environment: sdk: ">=2.19.6 <3.0.0" diff --git a/packages/hms_room_kit/lib/src/common/utility_functions.dart b/packages/hms_room_kit/lib/src/common/utility_functions.dart index b7a2d8512..687e0c8ed 100644 --- a/packages/hms_room_kit/lib/src/common/utility_functions.dart +++ b/packages/hms_room_kit/lib/src/common/utility_functions.dart @@ -11,6 +11,7 @@ import 'package:shared_preferences/shared_preferences.dart'; ///Project imports import 'package:hms_room_kit/hms_room_kit.dart'; +import 'package:tuple/tuple.dart'; ///This class contains the utility functions used in the app class Utilities { @@ -121,6 +122,15 @@ class Utilities { } } + ///This function returns the question type for poll/quiz + static List> + getQuestionTypeForPollQuiz() { + return const [ + Tuple2("Single Choice", HMSPollQuestionType.singleChoice), + Tuple2("Multiple Choice", HMSPollQuestionType.multiChoice) + ]; + } + ///This method returns the scale of the toast according to the index and the total number of toasts static double getToastScale(int index, int toastsCount) { if (toastsCount == 1) { diff --git a/packages/hms_room_kit/lib/src/hmssdk_interactor.dart b/packages/hms_room_kit/lib/src/hmssdk_interactor.dart index 8e22d78d4..f1b935ee4 100644 --- a/packages/hms_room_kit/lib/src/hmssdk_interactor.dart +++ b/packages/hms_room_kit/lib/src/hmssdk_interactor.dart @@ -414,12 +414,10 @@ class HMSSDKInteractor { forPeer: forPeer, hmsActionResultListener: hmsActionResultListener); } - void quickStartPoll( - {required HMSPollBuilder pollBuilder, - HMSActionResultListener? hmsActionResultListener}) { + void quickStartPoll({required HMSPollBuilder pollBuilder}) { HMSPollInteractivityCenter.quickStartPoll( - pollBuilder: pollBuilder, - hmsActionResultListener: hmsActionResultListener); + pollBuilder: pollBuilder, + ); } Future addSingleChoicePollResponse( diff --git a/packages/hms_room_kit/lib/src/meeting/meeting_page.dart b/packages/hms_room_kit/lib/src/meeting/meeting_page.dart index fd27b8d46..0f62f54d1 100644 --- a/packages/hms_room_kit/lib/src/meeting/meeting_page.dart +++ b/packages/hms_room_kit/lib/src/meeting/meeting_page.dart @@ -5,12 +5,12 @@ import 'dart:math'; ///Package imports import 'package:flutter/material.dart'; import 'package:flutter_foreground_task/flutter_foreground_task.dart'; -import 'package:hms_room_kit/src/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/toasts/toast_widget.dart'; import 'package:hms_room_kit/hms_room_kit.dart'; import 'package:hms_room_kit/src/meeting/meeting_grid_component.dart'; import 'package:hms_room_kit/src/meeting/meeting_navigation_visibility_controller.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 ccd9c7ddc..3d2e8c325 100644 --- a/packages/hms_room_kit/lib/src/meeting/meeting_store.dart +++ b/packages/hms_room_kit/lib/src/meeting/meeting_store.dart @@ -2236,10 +2236,9 @@ class MeetingStore extends ChangeNotifier ///Polls and Quiz - ///Method to start poll + ///Method to start poll and quiz void quickStartPoll(HMSPollBuilder pollBuilder) { - _hmsSDKInteractor.quickStartPoll( - pollBuilder: pollBuilder, hmsActionResultListener: this); + _hmsSDKInteractor.quickStartPoll(pollBuilder: pollBuilder); } ///Method to add Poll Response @@ -2660,6 +2659,27 @@ class MeetingStore extends ChangeNotifier notifyListeners(); } + ///Insert poll question + void insertPollQuestion(HMSPollStore store) { + pollQuestions.add(store); + sortPollQuestions(); + } + + ///Function to sort poll questions based on state and startedAt time + void sortPollQuestions() { + pollQuestions.sort((a, b) { + if (a.poll.state != b.poll.state) { + return a.poll.state == HMSPollState.started ? 1 : -1; + } else { + if (a.poll.startedAt != null && b.poll.startedAt != null) { + return a.poll.startedAt!.compareTo(b.poll.startedAt!); + } + } + return 1; + }); + notifyListeners(); + } + @override void onPeerListUpdate( {required List addedPeers, @@ -2673,7 +2693,7 @@ class MeetingStore extends ChangeNotifier @override void onPollUpdate( {required HMSPoll poll, required HMSPollUpdateType pollUpdateType}) { - log("onPollUpdate -> poll $poll updateType: $pollUpdateType startedAt: ${poll.startedAt}"); + log("onPollUpdate -> poll $poll updateType: $pollUpdateType}"); switch (pollUpdateType) { ///If the poll is started we add the poll in questions list case HMSPollUpdateType.started: @@ -2691,7 +2711,7 @@ class MeetingStore extends ChangeNotifier if (index == -1) { HMSPollStore store = HMSPollStore(poll: poll); if (HMSRoomLayout.peerType == PeerRoleType.conferencing) { - pollQuestions.add(store); + insertPollQuestion(store); toasts.add(HMSToastModel(store, hmsToastType: HMSToastsType.pollStartedToast)); notifyListeners(); @@ -2707,7 +2727,7 @@ class MeetingStore extends ChangeNotifier if (poll.startedAt != null && (DateTime.now().difference(poll.startedAt!) > const Duration(seconds: 20))) { - pollQuestions.add(store); + insertPollQuestion(store); toasts.add(HMSToastModel(store, hmsToastType: HMSToastsType.pollStartedToast)); } else { @@ -2734,6 +2754,7 @@ class MeetingStore extends ChangeNotifier .indexWhere((element) => element.poll.pollId == poll.pollId); if (index != -1) { pollQuestions[index].updateState(poll); + sortPollQuestions(); } notifyListeners(); break; diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart index 3528d5be7..dfccf78d4 100644 --- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart +++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/app_utilities_bottom_sheet.dart @@ -51,29 +51,30 @@ class _AppUtilitiesBottomSheetState extends State { bottom: 24), child: SingleChildScrollView( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, children: [ ///This renders the title and close button - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Row( - children: [ - HMSTitleText( - text: "Options", - textColor: HMSThemeColors.onSurfaceHighEmphasis, - letterSpacing: 0.15, - ) - ], - ), - const Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - HMSCrossButton(), - ], - ) - ], - ), + Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + HMSTitleText( + text: "Options", + textColor: HMSThemeColors.onSurfaceHighEmphasis, + letterSpacing: 0.15, + ) + ], + ), + const Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + HMSCrossButton(), + ], + ) + ], + ), + ]), Padding( padding: const EdgeInsets.only(top: 16, bottom: 16), child: Divider( 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 3bcd3860c..b1fa98ce5 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 @@ -45,24 +45,28 @@ class _HLSMoreOptionsBottomSheetBottomSheetState const EdgeInsets.only(top: 16.0, left: 20, right: 20, bottom: 24), child: SingleChildScrollView( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, + Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - HMSTitleText( - text: "Options", - textColor: HMSThemeColors.onSurfaceHighEmphasis, - letterSpacing: 0.15, + Row( + children: [ + HMSTitleText( + text: "Options", + textColor: HMSThemeColors.onSurfaceHighEmphasis, + letterSpacing: 0.15, + ) + ], + ), + const Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [HMSCrossButton()], ) ], ), - const Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [HMSCrossButton()], - ) ], ), Padding( diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/poll_and_quiz_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/poll_and_quiz_bottom_sheet.dart index 6d2350ce6..fca01a832 100644 --- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/poll_and_quiz_bottom_sheet.dart +++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/poll_and_quiz_bottom_sheet.dart @@ -1,5 +1,7 @@ ///Package imports import 'package:flutter/material.dart'; +import 'package:hms_room_kit/src/widgets/poll_widgets/poll_creation_widgets/poll_quiz_form.dart'; +import 'package:hms_room_kit/src/widgets/poll_widgets/poll_quiz_selection_widget.dart'; import 'package:provider/provider.dart'; import 'package:tuple/tuple.dart'; @@ -8,7 +10,6 @@ import 'package:hms_room_kit/hms_room_kit.dart'; import 'package:hms_room_kit/src/meeting/meeting_store.dart'; import 'package:hms_room_kit/src/model/poll_store.dart'; import 'package:hms_room_kit/src/widgets/common_widgets/hms_cross_button.dart'; -import 'package:hms_room_kit/src/widgets/poll_widgets/poll_creation_widgets/poll_form.dart'; import 'package:hms_room_kit/src/widgets/poll_widgets/poll_creation_widgets/poll_question_card.dart'; ///[PollAndQuizBottomSheet] renders the poll and quiz creation UI @@ -20,6 +21,17 @@ class PollAndQuizBottomSheet extends StatefulWidget { } class _PollAndQuizBottomSheetState extends State { + bool isPollSelected = true; + + void _updatePollQuizSelection(int index) { + if (index == 0) { + isPollSelected = true; + } else { + isPollSelected = false; + } + setState(() {}); + } + @override void initState() { super.initState(); @@ -64,15 +76,16 @@ class _PollAndQuizBottomSheetState extends State { ), ///Poll and Quiz selection buttons - ///Will be added in upcoming release - // if (context - // .read() - // .localPeer - // ?.role - // .permissions - // .pollWrite ?? - // false) - // const PollQuizSelectionWidget(), + if (context + .read() + .localPeer + ?.role + .permissions + .pollWrite ?? + false) + PollQuizSelectionWidget( + updateSelectionCallback: _updatePollQuizSelection, + ), if (context .read() @@ -86,14 +99,14 @@ class _PollAndQuizBottomSheetState extends State { ), ///Poll or Quiz Section - if (context + if ((context .read() .localPeer ?.role .permissions .pollWrite ?? - false) - const PollForm(), + false)) + PollQuizForm(isPoll: isPollSelected), ///This section shows all the previous polls ///which are either started or stopped @@ -159,7 +172,7 @@ class _PollAndQuizBottomSheetState extends State { true))) { return Center( child: HMSTitleText( - text: "No polls started in this session", + text: "No polls/quizzes started in this session", textColor: HMSThemeColors.onPrimaryHighEmphasis), ); } else { diff --git a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/poll_vote_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/poll_vote_bottom_sheet.dart index 281d4432f..214a7f246 100644 --- a/packages/hms_room_kit/lib/src/widgets/bottom_sheets/poll_vote_bottom_sheet.dart +++ b/packages/hms_room_kit/lib/src/widgets/bottom_sheets/poll_vote_bottom_sheet.dart @@ -19,7 +19,9 @@ import 'package:hms_room_kit/src/widgets/poll_widgets/voting_flow_widgets/poll_v ///[PollVoteBottomSheet] renders the voting bottom sheet for polls class PollVoteBottomSheet extends StatefulWidget { - const PollVoteBottomSheet({super.key}); + final bool isPoll; + + const PollVoteBottomSheet({super.key, required this.isPoll}); @override State createState() => _PollVoteBottomSheetState(); @@ -107,8 +109,9 @@ class _PollVoteBottomSheetState extends State { ), ), HMSTitleText( - text: - "${hmsPollStore.poll.createdBy?.name.substring(0, math.min(15, hmsPollStore.poll.createdBy?.name.length ?? 0)) ?? ""} started a poll", + text: hmsPollStore.poll.createdBy == null + ? "Participant started a new ${hmsPollStore.poll.category == HMSPollCategory.poll ? "poll" : "quiz"}" + : "${hmsPollStore.poll.createdBy?.name.substring(0, math.min(15, hmsPollStore.poll.createdBy?.name.length ?? 0)) ?? ""} started a ${widget.isPoll ? "poll" : "quiz"}", textColor: HMSThemeColors.onSurfaceHighEmphasis, letterSpacing: 0.15, ), @@ -144,12 +147,15 @@ class _PollVoteBottomSheetState extends State { question: poll.questions![index], totalVotes: totalVotes, isVoteCountHidden: isVoteCountHidden, + isPoll: poll.category == HMSPollCategory.poll, + isPollEnded: poll.state == HMSPollState.stopped, ); } else { return PollVoteCard( questionNumber: index, totalQuestions: poll.questions?.length ?? 0, - question: poll.questions![index]); + question: poll.questions![index], + isPoll: poll.category == HMSPollCategory.poll); } }); }), @@ -176,7 +182,8 @@ class _PollVoteBottomSheetState extends State { .stopPoll(hmsPollStore.poll); }, childWidget: HMSTitleText( - text: "End Poll", + text: + "End ${widget.isPoll ? "Poll" : "Quiz"}", textColor: HMSThemeColors.onPrimaryHighEmphasis), buttonBackgroundColor: diff --git a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/create_poll_form.dart b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/create_poll_form.dart index daa7efc2f..4d58d6a2b 100644 --- a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/create_poll_form.dart +++ b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/create_poll_form.dart @@ -3,7 +3,6 @@ import 'package:dropdown_button2/dropdown_button2.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; import 'package:hmssdk_flutter/hmssdk_flutter.dart'; -import 'package:tuple/tuple.dart'; ///Project imports import 'package:hms_room_kit/hms_room_kit.dart'; @@ -38,15 +37,6 @@ class CreatePollForm extends StatefulWidget { class _CreatePollFormState extends State { late TextEditingController _questionController; late List _optionsTextController; - // bool _isSkippable = false; - // bool _canChangeResponse = false; - - List> getPollQuestionType() { - return const [ - Tuple2("Single Choice", HMSPollQuestionType.singleChoice), - Tuple2("Multiple Choice", HMSPollQuestionType.multiChoice) - ]; - } @override void initState() { @@ -79,23 +69,6 @@ class _CreatePollFormState extends State { super.dispose(); } - ///This function set's whether the question is skippable or not - // void setIsSkippable(value) { - // widget.questionBuilder.withCanSkip = value; - // setState(() { - // _isSkippable = value; - // }); - // } - - ///This function set's [canChangeResponse] which decides can the answer be changed - ///once voted - // void setCanChangeResponse(value) { - // widget.questionBuilder.withCanChangeResponse = value; - // setState(() { - // _canChangeResponse = value; - // }); - // } - ///This adds a new option controller void _addOption() { _optionsTextController.add(TextEditingController()); @@ -172,7 +145,7 @@ class _CreatePollFormState extends State { ///Dropdown for poll type DropdownButtonHideUnderline( child: HMSDropDown( - dropDownItems: getPollQuestionType() + dropDownItems: Utilities.getQuestionTypeForPollQuiz() .map((e) => DropdownMenuItem( value: e.item2, child: HMSTitleText( diff --git a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_question_bottom_sheet.dart b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_question_bottom_sheet.dart index c0e1b3f0d..07374c38a 100644 --- a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_question_bottom_sheet.dart +++ b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_question_bottom_sheet.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:hms_room_kit/src/widgets/poll_widgets/poll_creation_widgets/create_poll_form.dart'; +import 'package:hms_room_kit/src/widgets/poll_widgets/quiz_creation_widgets/create_quiz_form.dart'; import 'package:hmssdk_flutter/hmssdk_flutter.dart'; import 'package:provider/provider.dart'; @@ -16,8 +17,14 @@ import 'package:hms_room_kit/src/widgets/poll_widgets/poll_creation_widgets/save ///[PollQuestionBottomSheet] renders the poll question form sheet class PollQuestionBottomSheet extends StatefulWidget { final String pollName; + final bool isPoll; + final List? rolesThatCanViewResponse; - const PollQuestionBottomSheet({Key? key, required this.pollName}) + const PollQuestionBottomSheet( + {Key? key, + required this.pollName, + required this.isPoll, + this.rolesThatCanViewResponse}) : super(key: key); @override @@ -27,49 +34,55 @@ class PollQuestionBottomSheet extends StatefulWidget { class _PollQuestionBottomSheetState extends State { late HMSPollBuilder pollBuilder; - bool _isPollValid = false; - Map pollQuestionBuilders = {}; + bool _isQuestionValid = false; + Map pollQuizQuestionBuilders = {}; @override void initState() { ///Here we create a new poll builder object with single question pollBuilder = HMSPollBuilder(); - pollQuestionBuilders[HMSPollQuestionBuilder()] = false; + pollQuizQuestionBuilders[HMSPollQuestionBuilder()] = false; ///Setting the title of the poll pollBuilder.withTitle = widget.pollName; + + ///If hide vote count is true + if (widget.rolesThatCanViewResponse != null) { + pollBuilder.withRolesThatCanViewResponses = + widget.rolesThatCanViewResponse!; + } super.initState(); } ///This function adds a new question builder void _addQuestion() { - pollQuestionBuilders[HMSPollQuestionBuilder()] = false; + pollQuizQuestionBuilders[HMSPollQuestionBuilder()] = false; setState(() {}); } - void _deleteQuestionCallback(HMSPollQuestionBuilder pollQuestionBuilder) { - pollQuestionBuilders.remove(pollQuestionBuilder); + void _deleteCallback(HMSPollQuestionBuilder pollQuestionBuilder) { + pollQuizQuestionBuilders.remove(pollQuestionBuilder); setState(() {}); } - void _savePollCallback(HMSPollQuestionBuilder pollQuestionBuilder) { - pollQuestionBuilders[pollQuestionBuilder] = true; - _checkPollValidity(); + void _saveCallback(HMSPollQuestionBuilder pollQuestionBuilder) { + pollQuizQuestionBuilders[pollQuestionBuilder] = true; + _checkValidity(); setState(() {}); } - void _editPollCallback(HMSPollQuestionBuilder pollQuestionBuilder) { - pollQuestionBuilders[pollQuestionBuilder] = false; - _isPollValid = false; + void _editCallback(HMSPollQuestionBuilder pollQuestionBuilder) { + pollQuizQuestionBuilders[pollQuestionBuilder] = false; + _isQuestionValid = false; setState(() {}); } - void _checkPollValidity() { + void _checkValidity() { var isValid = true; - pollQuestionBuilders.forEach((key, value) { + pollQuizQuestionBuilders.forEach((key, value) { isValid &= value; }); - _isPollValid = isValid; + _isQuestionValid = isValid; } @override @@ -136,47 +149,79 @@ class _PollQuestionBottomSheetState extends State { ///List to render poll form ListView.builder( physics: const NeverScrollableScrollPhysics(), - itemCount: pollQuestionBuilders.length, + itemCount: pollQuizQuestionBuilders.length, shrinkWrap: true, itemBuilder: (context, index) => Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), - child: pollQuestionBuilders.values + child: pollQuizQuestionBuilders.values .elementAt(index) ? SavedQuestionWidget( questionNumber: index, totalQuestions: - pollQuestionBuilders.length, - pollQuestionBuilder: pollQuestionBuilders - .keys - .elementAt(index), - editPollCallback: _editPollCallback, - ) - : CreatePollForm( - questionNumber: index, - totalQuestions: - pollQuestionBuilders.length, - questionType: pollQuestionBuilders.keys - .elementAt(index) - .type, - questionController: TextEditingController( - text: pollQuestionBuilders.keys + pollQuizQuestionBuilders.length, + pollQuestionBuilder: + pollQuizQuestionBuilders.keys + .elementAt(index), + editCallback: _editCallback, + isPoll: widget.isPoll) + : widget.isPoll + ? CreatePollForm( + questionNumber: index, + totalQuestions: + pollQuizQuestionBuilders.length, + questionType: pollQuizQuestionBuilders + .keys .elementAt(index) - .text), - optionsTextController: - pollQuestionBuilders.keys - .elementAt(index) - .pollOptions - .map((e) => TextEditingController( - text: e)) - .toList(), - deleteQuestionCallback: - _deleteQuestionCallback, - questionBuilder: pollQuestionBuilders.keys - .elementAt(index), - savePollCallback: _savePollCallback, - ), + .type, + questionController: + TextEditingController( + text: pollQuizQuestionBuilders + .keys + .elementAt(index) + .text), + optionsTextController: + pollQuizQuestionBuilders.keys + .elementAt(index) + .pollOptions + .map((e) => + TextEditingController( + text: e)) + .toList(), + deleteQuestionCallback: + _deleteCallback, + questionBuilder: + pollQuizQuestionBuilders.keys + .elementAt(index), + savePollCallback: _saveCallback, + ) + : CreateQuizForm( + questionNumber: index, + totalQuestions: + pollQuizQuestionBuilders.length, + questionController: + TextEditingController( + text: pollQuizQuestionBuilders + .keys + .elementAt(index) + .text), + optionsTextController: + pollQuizQuestionBuilders.keys + .elementAt(index) + .quizOptions + .map((e) => + TextEditingController( + text: e.text)) + .toList(), + deleteQuestionCallback: + _deleteCallback, + questionBuilder: + pollQuizQuestionBuilders.keys + .elementAt(index), + saveQuizCallback: _saveCallback, + ), )), + Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: GestureDetector( @@ -208,7 +253,7 @@ class _PollQuestionBottomSheetState extends State { style: ButtonStyle( shadowColor: MaterialStateProperty.all( HMSThemeColors.surfaceDim), - backgroundColor: _isPollValid + backgroundColor: _isQuestionValid ? MaterialStateProperty.all( HMSThemeColors.primaryDefault) : MaterialStateProperty.all( @@ -219,14 +264,16 @@ class _PollQuestionBottomSheetState extends State { borderRadius: BorderRadius.circular(8.0), ))), onPressed: () { - if (_isPollValid) { - pollQuestionBuilders.forEach((key, value) { + if (_isQuestionValid) { + pollQuizQuestionBuilders.forEach((key, value) { if (value) { pollBuilder.addQuestion(key); } }); pollBuilder.withAnonymous = false; - pollBuilder.withCategory = HMSPollCategory.poll; + pollBuilder.withCategory = widget.isPoll + ? HMSPollCategory.poll + : HMSPollCategory.quiz; pollBuilder.withMode = HMSPollUserTrackingMode.user_id; @@ -239,8 +286,8 @@ class _PollQuestionBottomSheetState extends State { }, child: Center( child: HMSTitleText( - text: "Launch Poll", - textColor: _isPollValid + text: "Launch ${widget.isPoll ? "Poll" : "Quiz"}", + textColor: _isQuestionValid ? HMSThemeColors.onPrimaryHighEmphasis : HMSThemeColors.onPrimaryLowEmphasis, )), diff --git a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_question_card.dart b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_question_card.dart index 0543c44dc..bc8f46bd3 100644 --- a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_question_card.dart +++ b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_question_card.dart @@ -81,7 +81,9 @@ class PollQuestionCard extends StatelessWidget { value: meetingStore, child: ChangeNotifierProvider.value( value: pollStore, - child: const PollVoteBottomSheet(), + child: PollVoteBottomSheet( + isPoll: pollStore.poll.category == + HMSPollCategory.poll), ), )); }, diff --git a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_form.dart b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_quiz_form.dart similarity index 88% rename from packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_form.dart rename to packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_quiz_form.dart index b36bedda5..9c9dd0343 100644 --- a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_form.dart +++ b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/poll_quiz_form.dart @@ -10,18 +10,19 @@ import 'package:hms_room_kit/src/meeting/meeting_store.dart'; import 'package:hms_room_kit/src/widgets/common_widgets/hms_listenable_button.dart'; import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart'; -///[PollForm] widget renders the poll creation form with poll title. -class PollForm extends StatefulWidget { - const PollForm({super.key}); +///[PollQuizForm] widget renders the poll creation form with poll title. +class PollQuizForm extends StatefulWidget { + final bool isPoll; + + const PollQuizForm({Key? key, required this.isPoll}) : super(key: key); @override - State createState() => _PollFormState(); + State createState() => _PollQuizFormState(); } -class _PollFormState extends State { +class _PollQuizFormState extends State { late TextEditingController _pollNameController; bool _hideVoteCount = false; - // bool _isAnonymous = false; @override void initState() { @@ -42,20 +43,14 @@ class _PollFormState extends State { }); } - ///This method sets the value of the is anonymous switch - // void setIsAnonymous(bool value) { - // setState(() { - // _isAnonymous = value; - // }); - // } - @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ HMSSubheadingText( - text: "Poll Name", textColor: HMSThemeColors.onSurfaceHighEmphasis), + text: "${widget.isPoll ? "Poll" : "Quiz"} Name", + textColor: HMSThemeColors.onSurfaceHighEmphasis), const SizedBox( height: 8, ), @@ -81,7 +76,7 @@ class _PollFormState extends State { const EdgeInsets.symmetric(horizontal: 16, vertical: 12), fillColor: HMSThemeColors.surfaceDefault, filled: true, - hintText: "Name this Poll", + hintText: "Name this ${widget.isPoll ? "Poll" : "Quiz"}", hintStyle: HMSTextStyle.setTextStyle( color: HMSThemeColors.onSurfaceLowEmphasis, height: 1.5, @@ -207,11 +202,17 @@ class _PollFormState extends State { value: meetingStore, child: PollQuestionBottomSheet( pollName: _pollNameController.text.trim(), + isPoll: widget.isPoll, + rolesThatCanViewResponse: _hideVoteCount + ? meetingStore.localPeer != null + ? [meetingStore.localPeer!.role] + : null + : null, )), ); }, childWidget: HMSTitleText( - text: 'Create Poll', + text: 'Create ${widget.isPoll ? "Poll" : "Quiz"}', textColor: _pollNameController.text.isEmpty ? HMSThemeColors.onPrimaryLowEmphasis : HMSThemeColors.onPrimaryHighEmphasis, diff --git a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/saved_question_widget.dart b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/saved_question_widget.dart index bfd793927..ad5493815 100644 --- a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/saved_question_widget.dart +++ b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_creation_widgets/saved_question_widget.dart @@ -11,14 +11,15 @@ class SavedQuestionWidget extends StatelessWidget { final int questionNumber; final int totalQuestions; final HMSPollQuestionBuilder pollQuestionBuilder; - final Function editPollCallback; - + final Function editCallback; + final bool isPoll; const SavedQuestionWidget( {super.key, required this.questionNumber, required this.totalQuestions, required this.pollQuestionBuilder, - required this.editPollCallback}); + required this.editCallback, + required this.isPoll}); @override Widget build(BuildContext context) { @@ -68,16 +69,31 @@ class SavedQuestionWidget extends StatelessWidget { fontWeight: FontWeight.w400, maxLines: 3, ), - children: pollQuestionBuilder.pollOptions - .map((e) => Padding( - padding: const EdgeInsets.symmetric(vertical: 8.0), - child: HMSSubheadingText( - text: e, - textColor: HMSThemeColors.onSurfaceMediumEmphasis, - maxLines: 3, - ), - )) - .toList()), + children: isPoll + ? pollQuestionBuilder.pollOptions + .map((e) => Padding( + padding: + const EdgeInsets.symmetric(vertical: 8.0), + child: HMSSubheadingText( + text: e, + textColor: + HMSThemeColors.onSurfaceMediumEmphasis, + maxLines: 3, + ), + )) + .toList() + : pollQuestionBuilder.quizOptions + .map((e) => Padding( + padding: + const EdgeInsets.symmetric(vertical: 8.0), + child: HMSSubheadingText( + text: e.text, + textColor: + HMSThemeColors.onSurfaceMediumEmphasis, + maxLines: 3, + ), + )) + .toList()), ), Row( mainAxisAlignment: MainAxisAlignment.end, @@ -108,7 +124,7 @@ class SavedQuestionWidget extends StatelessWidget { borderRadius: BorderRadius.circular(8.0), ))), onPressed: () { - editPollCallback(pollQuestionBuilder); + editCallback(pollQuestionBuilder); }, child: HMSTitleText( text: "Edit", diff --git a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_quiz_selection_widget.dart b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_quiz_selection_widget.dart index 5f86b1b4b..9acd53436 100644 --- a/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_quiz_selection_widget.dart +++ b/packages/hms_room_kit/lib/src/widgets/poll_widgets/poll_quiz_selection_widget.dart @@ -3,9 +3,11 @@ import 'package:flutter/cupertino.dart'; import 'package:hms_room_kit/hms_room_kit.dart'; import 'package:hms_room_kit/src/widgets/poll_widgets/poll_quiz_selection_button.dart'; -///[PollQuizSelectionWidget] renders the widget for poll or quiz selection class PollQuizSelectionWidget extends StatefulWidget { - const PollQuizSelectionWidget({super.key}); + final Function updateSelectionCallback; + + const PollQuizSelectionWidget( + {super.key, required this.updateSelectionCallback}); @override State createState() => @@ -16,6 +18,7 @@ class _PollQuizSelectionWidgetState extends State { int index = 0; void updateSelection(newIndex) { + widget.updateSelectionCallback(newIndex); setState(() { index = newIndex; }); diff --git a/packages/hms_room_kit/lib/src/widgets/poll_widgets/quiz_creation_widgets/create_quiz_form.dart b/packages/hms_room_kit/lib/src/widgets/poll_widgets/quiz_creation_widgets/create_quiz_form.dart new file mode 100644 index 000000000..c766a93f2 --- /dev/null +++ b/packages/hms_room_kit/lib/src/widgets/poll_widgets/quiz_creation_widgets/create_quiz_form.dart @@ -0,0 +1,500 @@ +///Package imports +import 'package:dropdown_button2/dropdown_button2.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:hmssdk_flutter/hmssdk_flutter.dart'; + +///Project imports +import 'package:hms_room_kit/hms_room_kit.dart'; +import 'package:hms_room_kit/src/widgets/common_widgets/hms_dropdown.dart'; +import 'package:hms_room_kit/src/widgets/common_widgets/hms_subheading_text.dart'; + +///[CreateQuizForm] widget renders the poll creation form +class CreateQuizForm extends StatefulWidget { + final int questionNumber; + final int totalQuestions; + final TextEditingController questionController; + final List optionsTextController; + final HMSPollQuestionBuilder questionBuilder; + final Function deleteQuestionCallback; + final Function saveQuizCallback; + const CreateQuizForm( + {super.key, + required this.questionNumber, + required this.totalQuestions, + required this.optionsTextController, + required this.questionController, + required this.questionBuilder, + required this.deleteQuestionCallback, + required this.saveQuizCallback}); + + @override + State createState() => _CreatePollFormState(); +} + +class _CreatePollFormState extends State { + late TextEditingController _questionController; + late List _optionsTextController; + + ///Quiz variables + HMSPollQuizOption? _correctOption; + List? _correctOptions = []; + + @override + void initState() { + ///Here we initialise the quesetion controller with + ///the value passed from widget. It's empty when a fresh poll is created + ///while it has `text` value when it's being edited + _questionController = widget.questionController; + + ///Here options text controller gets initialised. + ///If controllers are passed on to the widget then we just + ///assign those controllers to _optionsTextController + if (widget.optionsTextController.isEmpty) { + _optionsTextController = [ + TextEditingController(), + TextEditingController() + ]; + } else { + _optionsTextController = widget.optionsTextController; + } + + if (widget.questionBuilder.type == HMSPollQuestionType.singleChoice) { + int index = widget.questionBuilder.quizOptions + .indexWhere((element) => element.isOptionCorrect); + if (index != -1) { + _correctOption = widget.questionBuilder.quizOptions[index]; + } + } else if (widget.questionBuilder.type == HMSPollQuestionType.multiChoice) { + _correctOptions = widget.questionBuilder.quizOptions + .where((element) => element.isOptionCorrect) + .toList(); + } + super.initState(); + } + + @override + void dispose() { + ///Here we dispose the question and options controller + _questionController.dispose(); + for (var element in _optionsTextController) { + element.dispose(); + } + super.dispose(); + } + + ///This adds a new option controller + void _addOption() { + _optionsTextController.add(TextEditingController()); + setState(() {}); + } + + ///This function checks whether the poll is valid or not + ///This is checked before launching the poll + bool _isQuizValid() { + bool areOptionsFilled = _optionsTextController.length >= 2; + for (var optionController in _optionsTextController) { + areOptionsFilled = areOptionsFilled && (optionController.text.isNotEmpty); + } + if (widget.questionBuilder.type == HMSPollQuestionType.singleChoice) { + areOptionsFilled = areOptionsFilled && (_correctOption != null); + } else if (widget.questionBuilder.type == HMSPollQuestionType.multiChoice) { + areOptionsFilled = + areOptionsFilled && (_correctOptions?.isNotEmpty ?? false); + } + return (areOptionsFilled && _questionController.text.isNotEmpty); + } + + ///This function set's the text for the question + void _setText(String text) { + widget.questionBuilder.withText = text; + } + + ///This function save the poll option + void _saveQuizOption(String option, int index) { + _optionsTextController[index].text = option; + } + + ///This function saves the option and also fires a callback + ///to save the question + void saveQuestion() { + List quizOptions = []; + for (var option in _optionsTextController) { + var quizOption = HMSPollQuizOption(text: option.text); + quizOption.isCorrect = + widget.questionBuilder.type == HMSPollQuestionType.singleChoice + ? _correctOption?.text == option.text + : _isCorrectAnswer(option.text); + quizOptions.add(quizOption); + } + widget.questionBuilder.addQuizOption = quizOptions; + if (_isQuizValid()) { + widget.saveQuizCallback(widget.questionBuilder); + } + } + + ///This function updates the poll type selection + void _updateQuizType(HMSPollQuestionType questionType) { + widget.questionBuilder.withType = questionType; + setState(() {}); + } + + bool _isCorrectAnswer(String optionText) { + if (_correctOptions != null) { + for (var option in _correctOptions!) { + if (option.text == optionText) { + return true; + } + } + } + return false; + } + + @override + Widget build(BuildContext context) { + return Container( + width: double.infinity, + decoration: BoxDecoration( + color: HMSThemeColors.surfaceDefault, + borderRadius: BorderRadius.circular(8), + ), + child: Padding( + padding: const EdgeInsets.all(16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + HMSTitleText( + text: + "QUESTION ${widget.questionNumber + 1} OF ${widget.totalQuestions}", + textColor: HMSThemeColors.onSurfaceLowEmphasis, + fontSize: 10, + letterSpacing: 1.5, + lineHeight: 16), + const SizedBox( + height: 8, + ), + HMSSubheadingText( + text: "Question Type", + textColor: HMSThemeColors.onSurfaceHighEmphasis, + ), + const SizedBox( + height: 8, + ), + + ///Dropdown for poll type + DropdownButtonHideUnderline( + child: HMSDropDown( + dropDownItems: Utilities.getQuestionTypeForPollQuiz() + .map((e) => DropdownMenuItem( + value: e.item2, + child: HMSTitleText( + text: e.item1, + textColor: HMSThemeColors.onSurfaceHighEmphasis, + fontWeight: FontWeight.w400, + ), + )) + .toList(), + buttonStyleData: ButtonStyleData( + width: double.infinity, + padding: const EdgeInsets.symmetric( + horizontal: 8, + ), + decoration: BoxDecoration( + color: HMSThemeColors.surfaceBright, + borderRadius: BorderRadius.circular(8), + )), + dropdownStyleData: DropdownStyleData( + padding: const EdgeInsets.symmetric( + vertical: 12, horizontal: 16), + decoration: BoxDecoration( + color: HMSThemeColors.surfaceBright, + )), + selectedValue: widget.questionBuilder.type, + updateSelectedValue: (value) { + _updateQuizType(value); + })), + const SizedBox( + height: 8, + ), + HMSSubheadingText( + text: "Question", + textColor: HMSThemeColors.onSurfaceHighEmphasis, + ), + const SizedBox( + height: 8, + ), + + ///Textfield for setting the question + SizedBox( + height: 48, + child: TextField( + cursorColor: HMSThemeColors.onSurfaceHighEmphasis, + onTapOutside: (event) => + FocusManager.instance.primaryFocus?.unfocus(), + textInputAction: TextInputAction.done, + textCapitalization: TextCapitalization.words, + style: HMSTextStyle.setTextStyle( + color: HMSThemeColors.onSurfaceHighEmphasis), + controller: _questionController, + keyboardType: TextInputType.multiline, + maxLines: null, + onChanged: (value) { + _setText(value.trim()); + setState(() {}); + }, + decoration: InputDecoration( + contentPadding: const EdgeInsets.symmetric( + horizontal: 16, vertical: 12), + fillColor: HMSThemeColors.surfaceBright, + filled: true, + hintText: "e.g. Solve for 2x + ½ = 21", + hintStyle: HMSTextStyle.setTextStyle( + color: HMSThemeColors.onSurfaceLowEmphasis, + height: 1.5, + fontSize: 16, + letterSpacing: 0.5, + fontWeight: FontWeight.w400), + focusedBorder: OutlineInputBorder( + borderRadius: + const BorderRadius.all(Radius.circular(8)), + borderSide: + BorderSide(color: HMSThemeColors.primaryDefault)), + border: + const OutlineInputBorder(borderSide: BorderSide.none)), + ), + ), + const SizedBox( + height: 8, + ), + + ///Divider + Padding( + padding: const EdgeInsets.symmetric( + vertical: 12.0, + ), + child: Divider( + height: 5, + color: HMSThemeColors.borderBright, + ), + ), + + HMSSubheadingText( + text: "Select one of the radio button to mark the correct answer", + textColor: HMSThemeColors.onSurfaceMediumEmphasis, + maxLines: 2, + ), + + const SizedBox( + height: 8, + ), + + ///Here we set the options + ListView.builder( + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + itemCount: _optionsTextController.length, + itemBuilder: (context, index) { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Row( + children: [ + Checkbox( + activeColor: + HMSThemeColors.onSurfaceHighEmphasis, + checkColor: HMSThemeColors.surfaceDefault, + value: (widget.questionBuilder.type == + HMSPollQuestionType.singleChoice) + ? (_optionsTextController[index].text == + _correctOption?.text) + : _isCorrectAnswer( + _optionsTextController[index].text), + shape: widget.questionBuilder.type == + HMSPollQuestionType.singleChoice + ? const CircleBorder() + : const RoundedRectangleBorder( + borderRadius: BorderRadius.all( + Radius.circular(4))), + onChanged: (value) { + if (value == true && + _optionsTextController[index] + .text + .isNotEmpty) { + if (widget.questionBuilder.type == + HMSPollQuestionType.singleChoice) { + _correctOption = HMSPollQuizOption( + text: _optionsTextController[index] + .text); + _correctOption?.isCorrect = true; + } else if (widget.questionBuilder.type == + HMSPollQuestionType.multiChoice) { + var selectedOption = HMSPollQuizOption( + text: _optionsTextController[index] + .text); + selectedOption.isCorrect = true; + _correctOptions?.add(selectedOption); + } + } else { + if (widget.questionBuilder.type == + HMSPollQuestionType.multiChoice) { + _correctOptions?.removeWhere((element) => + element.text == + _optionsTextController[index].text); + } + } + + setState(() {}); + }), + const SizedBox( + width: 4, + ) + ], + ), + Expanded( + child: SizedBox( + height: 48, + child: TextField( + cursorColor: HMSThemeColors.onSurfaceHighEmphasis, + onTapOutside: (event) => + FocusManager.instance.primaryFocus?.unfocus(), + textInputAction: TextInputAction.done, + textCapitalization: TextCapitalization.words, + style: HMSTextStyle.setTextStyle( + color: HMSThemeColors.onSurfaceHighEmphasis), + controller: _optionsTextController[index], + keyboardType: TextInputType.text, + onChanged: (value) { + _saveQuizOption(value.trim(), index); + }, + decoration: InputDecoration( + contentPadding: const EdgeInsets.symmetric( + horizontal: 16, vertical: 12), + fillColor: HMSThemeColors.surfaceBright, + filled: true, + hintText: "Option ${index + 1}", + hintStyle: HMSTextStyle.setTextStyle( + color: + HMSThemeColors.onSurfaceLowEmphasis, + height: 1.5, + fontSize: 16, + letterSpacing: 0.5, + fontWeight: FontWeight.w400), + focusedBorder: OutlineInputBorder( + borderRadius: const BorderRadius.all( + Radius.circular(8)), + borderSide: BorderSide( + color: + HMSThemeColors.primaryDefault)), + border: const OutlineInputBorder( + borderSide: BorderSide.none)), + ), + ), + ), + if (_optionsTextController.length > 2) + IconButton( + onPressed: () { + _optionsTextController.removeAt(index); + setState(() {}); + }, + icon: SvgPicture.asset( + "packages/hms_room_kit/lib/src/assets/icons/delete_poll.svg", + width: 24, + height: 24, + colorFilter: ColorFilter.mode( + HMSThemeColors.onSurfaceLowEmphasis, + BlendMode.srcIn))) + ], + ), + ); + }), + if (_optionsTextController.length < 8) + Padding( + padding: const EdgeInsets.symmetric(vertical: 8.0), + child: GestureDetector( + onTap: () { + _addOption(); + }, + child: Row( + children: [ + SvgPicture.asset( + "packages/hms_room_kit/lib/src/assets/icons/add_option.svg", + width: 24, + height: 24, + colorFilter: ColorFilter.mode( + HMSThemeColors.onSurfaceMediumEmphasis, + BlendMode.srcIn)), + const SizedBox( + width: 16, + ), + HMSSubheadingText( + text: "Add an option", + textColor: HMSThemeColors.onSurfaceMediumEmphasis, + ), + ], + ), + ), + ), + + Padding( + padding: const EdgeInsets.symmetric( + vertical: 12.0, + ), + child: Divider( + height: 5, + color: HMSThemeColors.borderBright, + ), + ), + + ///Save the question + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + // if (widget.totalQuestions > 1) + // HMSEmbeddedButton( + // onTap: () => + // widget.deleteQuestionCallback(widget.questionBuilder), + // isActive: true, + // onColor: HMSThemeColors.surfaceDefault, + // child: SvgPicture.asset( + // "packages/hms_room_kit/lib/src/assets/icons/delete_poll.svg", + // colorFilter: ColorFilter.mode( + // HMSThemeColors.onSurfaceHighEmphasis, + // BlendMode.srcIn), + // fit: BoxFit.scaleDown, + // ), + // ), + // const SizedBox( + // width: 8, + // ), + ElevatedButton( + style: ButtonStyle( + elevation: MaterialStateProperty.all(0), + backgroundColor: (_questionController.text.isNotEmpty) + ? MaterialStateProperty.all( + HMSThemeColors.secondaryDefault) + : MaterialStateProperty.all( + HMSThemeColors.secondaryDim), + shape: + MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(8.0), + ))), + onPressed: () { + saveQuestion(); + }, + child: HMSTitleText( + text: "Save", + textColor: _isQuizValid() + ? HMSThemeColors.onSecondaryHighEmphasis + : HMSThemeColors.onSecondaryLowEmphasis)) + ], + ) + ], + ), + ), + ); + } +} diff --git a/packages/hms_room_kit/lib/src/widgets/poll_widgets/voting_flow_widgets/poll_result_card.dart b/packages/hms_room_kit/lib/src/widgets/poll_widgets/voting_flow_widgets/poll_result_card.dart index 60b7f46f5..b5f6fa717 100644 --- a/packages/hms_room_kit/lib/src/widgets/poll_widgets/voting_flow_widgets/poll_result_card.dart +++ b/packages/hms_room_kit/lib/src/widgets/poll_widgets/voting_flow_widgets/poll_result_card.dart @@ -13,6 +13,8 @@ class PollResultCard extends StatelessWidget { final HMSPollQuestion question; final int totalVotes; final bool isVoteCountHidden; + final bool isPoll; + final bool isPollEnded; const PollResultCard( {super.key, @@ -20,7 +22,9 @@ class PollResultCard extends StatelessWidget { required this.totalQuestions, required this.question, required this.totalVotes, - required this.isVoteCountHidden}); + required this.isVoteCountHidden, + required this.isPoll, + required this.isPollEnded}); bool isSelectedOption(int index) { if (question.type == HMSPollQuestionType.singleChoice) { @@ -39,15 +43,60 @@ class PollResultCard extends StatelessWidget { return false; } + bool isMyOptionCorrect() { + if (question.myResponses.isNotEmpty) { + if (question.type == HMSPollQuestionType.singleChoice) { + if (question.correctAnswer?.option != null) { + return question.correctAnswer?.option == + question.myResponses[questionNumber].selectedOption; + } + } else if (question.type == HMSPollQuestionType.multiChoice) { + if (question.myResponses.length != + question.correctAnswer?.options?.length) { + return false; + } + if (question.correctAnswer?.options != null) { + for (var option in question.correctAnswer!.options!) { + if (!(question.myResponses[questionNumber].selectedOptions + ?.contains(option) ?? + true)) { + return false; + } + } + return true; + } + } + } + return false; + } + + bool isCorrectAnswer(HMSPollQuestionOption option) { + if (question.type == HMSPollQuestionType.singleChoice) { + return question.correctAnswer?.option == option.index; + } else if (question.type == HMSPollQuestionType.multiChoice) { + if (question.correctAnswer?.options != null) { + return question.correctAnswer?.options?.contains(option.index) ?? false; + } + } + return false; + } + @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.only(bottom: 24), child: Container( decoration: BoxDecoration( - color: HMSThemeColors.surfaceDefault, - borderRadius: BorderRadius.circular(8), - ), + color: HMSThemeColors.surfaceDefault, + borderRadius: BorderRadius.circular(8), + border: isPollEnded + ? (isPoll || question.myResponses.isEmpty) + ? const Border() + : Border.all( + color: isMyOptionCorrect() + ? HMSThemeColors.alertSuccess + : HMSThemeColors.alertErrorDefault) + : null), child: Padding( padding: const EdgeInsets.all(16), child: Column( @@ -95,6 +144,23 @@ class PollResultCard extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ + if (isPollEnded && + isCorrectAnswer(question.options[index])) + Padding( + padding: const EdgeInsets.only(right: 8.0), + child: SizedBox( + height: 20, + width: 20, + child: Checkbox( + activeColor: HMSThemeColors + .onSurfaceHighEmphasis, + checkColor: + HMSThemeColors.surfaceDefault, + shape: const CircleBorder(), + value: true, + onChanged: (value) {}), + ), + ), Expanded( child: HMSSubheadingText( text: question.options[index].text ?? "", @@ -102,17 +168,26 @@ class PollResultCard extends StatelessWidget { textColor: HMSThemeColors.onSurfaceHighEmphasis), ), - if (isVoteCountHidden && + + ///If it's not a poll and selected option show checkbox + ///If its a poll then only show when vote count is hidden + if ((!isPoll || isVoteCountHidden) && isSelectedOption( question.options[index].index)) - Checkbox( - activeColor: - HMSThemeColors.onSurfaceHighEmphasis, - checkColor: HMSThemeColors.surfaceDefault, - shape: const CircleBorder(), - value: true, - onChanged: (value) {}), - if (!isVoteCountHidden) + isPoll + ? Checkbox( + activeColor: HMSThemeColors + .onSurfaceHighEmphasis, + checkColor: + HMSThemeColors.surfaceDefault, + shape: const CircleBorder(), + value: true, + onChanged: (value) {}) + : HMSSubheadingText( + text: "Your Answer", + textColor: HMSThemeColors + .onSurfaceMediumEmphasis), + if (!isVoteCountHidden && isPoll) Padding( padding: const EdgeInsets.only(left: 8.0), child: HMSSubheadingText( @@ -123,11 +198,11 @@ class PollResultCard extends StatelessWidget { ) ], ), - if (!isVoteCountHidden) + if (!isVoteCountHidden && isPoll) const SizedBox( height: 8, ), - if (!isVoteCountHidden) + if (!isVoteCountHidden && isPoll) Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), @@ -164,7 +239,7 @@ class PollResultCard extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.end, children: [ HMSTitleText( - text: "Voted", + text: isPoll ? "Voted" : "Answered", textColor: HMSThemeColors.onSurfaceLowEmphasis) ], ) diff --git a/packages/hms_room_kit/lib/src/widgets/poll_widgets/voting_flow_widgets/poll_vote_card.dart b/packages/hms_room_kit/lib/src/widgets/poll_widgets/voting_flow_widgets/poll_vote_card.dart index 2d8e393a2..506be2a26 100644 --- a/packages/hms_room_kit/lib/src/widgets/poll_widgets/voting_flow_widgets/poll_vote_card.dart +++ b/packages/hms_room_kit/lib/src/widgets/poll_widgets/voting_flow_widgets/poll_vote_card.dart @@ -15,12 +15,14 @@ class PollVoteCard extends StatefulWidget { final int questionNumber; final int totalQuestions; final HMSPollQuestion question; + final bool isPoll; const PollVoteCard( {super.key, required this.questionNumber, required this.totalQuestions, - required this.question}); + required this.question, + required this.isPoll}); @override State createState() => _PollVoteCardState(); @@ -137,7 +139,8 @@ class _PollVoteCardState extends State { mainAxisAlignment: MainAxisAlignment.end, children: [ HMSButton( - width: MediaQuery.of(context).size.width * 0.21, + width: MediaQuery.of(context).size.width * + (widget.isPoll ? 0.21 : 0.30), onPressed: () { if (isPollAnswerValid) { if (widget.question.type == @@ -149,6 +152,7 @@ class _PollVoteCardState extends State { context.read().poll, widget.question, selectedOption!); + selectedOption = null; } else if (widget.question.type == HMSPollQuestionType.multiChoice && selectedOptions.isNotEmpty) { @@ -158,6 +162,7 @@ class _PollVoteCardState extends State { context.read().poll, widget.question, selectedOptions); + selectedOptions = []; } } }, @@ -165,7 +170,7 @@ class _PollVoteCardState extends State { ? HMSThemeColors.primaryDefault : HMSThemeColors.primaryDisabled, childWidget: HMSTitleText( - text: "Vote", + text: widget.isPoll ? "Vote" : "Answer", textColor: isPollAnswerValid ? HMSThemeColors.onPrimaryHighEmphasis : HMSThemeColors.onPrimaryLowEmphasis)) diff --git a/packages/hms_room_kit/lib/src/widgets/toasts/hms_poll_start_toast.dart b/packages/hms_room_kit/lib/src/widgets/toasts/hms_poll_start_toast.dart index 42967add7..2d175497b 100644 --- a/packages/hms_room_kit/lib/src/widgets/toasts/hms_poll_start_toast.dart +++ b/packages/hms_room_kit/lib/src/widgets/toasts/hms_poll_start_toast.dart @@ -35,8 +35,9 @@ class HMSPollStartToast extends StatelessWidget { subtitle: SizedBox( width: MediaQuery.of(context).size.width * 0.5, child: HMSSubheadingText( - text: - "${poll.createdBy?.name.substring(0, math.min(8, poll.createdBy?.name.length ?? 0)) ?? ""}${(poll.createdBy?.name.length ?? 0) > 8 ? "..." : ""} started a new poll", + text: poll.createdBy == null + ? "Participant started a new ${poll.category == HMSPollCategory.poll ? "poll" : "quiz"}" + : "${poll.createdBy?.name.substring(0, math.min(8, poll.createdBy?.name.length ?? 0)) ?? ""}${(poll.createdBy?.name.length ?? 0) > 8 ? "..." : ""} started a new ${poll.category == HMSPollCategory.poll ? "poll" : "quiz"}", textColor: HMSThemeColors.onSurfaceHighEmphasis, fontWeight: FontWeight.w600, letterSpacing: 0.1, @@ -44,7 +45,7 @@ class HMSPollStartToast extends StatelessWidget { ), ), action: HMSToastButton( - buttonTitle: "Vote", + buttonTitle: poll.category == HMSPollCategory.poll ? "Vote" : "Answer", action: () { var pollStore = context.read(); showModalBottomSheet( @@ -60,7 +61,9 @@ class HMSPollStartToast extends StatelessWidget { value: meetingStore, child: ChangeNotifierProvider.value( value: pollStore, - child: const PollVoteBottomSheet(), + child: PollVoteBottomSheet( + isPoll: pollStore.poll.category == HMSPollCategory.poll, + ), ))); meetingStore.removeToast(HMSToastsType.pollStartedToast, data: poll.pollId); diff --git a/packages/hms_room_kit/pubspec.lock b/packages/hms_room_kit/pubspec.lock index d803a2f6b..bb5ff7740 100644 --- a/packages/hms_room_kit/pubspec.lock +++ b/packages/hms_room_kit/pubspec.lock @@ -146,10 +146,10 @@ packages: dependency: "direct main" description: name: flutter_foreground_task - sha256: e48d2d810a2d643362e64de41146ed8e95d4dd282bae6abbb32309d9f0bf5d67 + sha256: "9bcfcb43bba4a5446a056e723d21118ff6e184926b5557365c32c13caca157c2" url: "https://pub.dev" source: hosted - version: "6.1.2" + version: "6.1.3" flutter_linkify: dependency: "direct main" description: @@ -203,11 +203,10 @@ packages: hmssdk_flutter: dependency: "direct main" description: - name: hmssdk_flutter - sha256: bad4ff87c677970f0c9acfcd4e84b60089461e1c1eef23e3a3ae6ab191484b95 - url: "https://pub.dev" - source: hosted - version: "1.9.9" + path: "../hmssdk_flutter" + relative: true + source: path + version: "1.9.10" http: dependency: transitive description: @@ -452,10 +451,10 @@ packages: dependency: "direct main" description: name: share_plus - sha256: f74fc3f1cbd99f39760182e176802f693fa0ec9625c045561cfad54681ea93dd + sha256: "3ef39599b00059db0990ca2e30fca0a29d8b37aae924d60063f8e0184cf20900" url: "https://pub.dev" source: hosted - version: "7.2.1" + version: "7.2.2" share_plus_platform_interface: dependency: transitive description: @@ -609,10 +608,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f" + sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745 url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.3.0" url_launcher_ios: dependency: transitive description: @@ -641,10 +640,10 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" url_launcher_web: dependency: transitive description: @@ -673,26 +672,26 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "18f6690295af52d081f6808f2f7c69f0eed6d7e23a71539d75f4aeb8f0062172" + sha256: "4ac59808bbfca6da38c99f415ff2d3a5d7ca0a6b4809c71d9cf30fba5daf9752" url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.10+1" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "531d20465c10dfac7f5cd90b60bbe4dd9921f1ec4ca54c83ebb176dbacb7bb2d" + sha256: f3247e7ab0ec77dc759263e68394990edc608fb2b480b80db8aa86ed09279e33 url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.10+1" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad" + sha256: "18489bdd8850de3dd7ca8a34e0c446f719ec63e2bab2e7a8cc66a9028dd76c5a" url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.10+1" vector_math: dependency: transitive description: diff --git a/packages/hms_room_kit/pubspec.yaml b/packages/hms_room_kit/pubspec.yaml index 2916cfb6c..884e2af23 100644 --- a/packages/hms_room_kit/pubspec.yaml +++ b/packages/hms_room_kit/pubspec.yaml @@ -1,6 +1,6 @@ name: hms_room_kit description: 100ms Room Kit provides simple & easy to use UI components to build Live Streaming & Video Conferencing experiences in your apps. -version: 1.0.12 +version: 1.0.13 homepage: https://www.100ms.live/ repository: https://github.com/100mslive/100ms-flutter issue_tracker: https://github.com/100mslive/100ms-flutter/issues @@ -14,7 +14,8 @@ dependencies: flutter: sdk: flutter - hmssdk_flutter: 1.9.9 + hmssdk_flutter: + path: ../hmssdk_flutter intl: ^0.18.0 permission_handler: ^11.0.0 provider: ^6.0.5 diff --git a/packages/hmssdk_flutter/CHANGELOG.md b/packages/hmssdk_flutter/CHANGELOG.md index d47ace539..488ffe5d8 100644 --- a/packages/hmssdk_flutter/CHANGELOG.md +++ b/packages/hmssdk_flutter/CHANGELOG.md @@ -5,6 +5,21 @@ | hms_room_kit | [![Pub Version](https://img.shields.io/pub/v/hms_room_kit)](https://pub.dev/packages/hms_room_kit) | | hmssdk_flutter | [![Pub Version](https://img.shields.io/pub/v/hmssdk_flutter)](https://pub.dev/packages/hmssdk_flutter) | +# 1.9.10 - 2024-02-16 + +| Package | Version | +| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| hms_room_kit | 1.0.13 | +| hmssdk_flutter | 1.9.10 | + +### ✨ Added + +- Introducing Quizzes + + - Users can now seamlessly create, answer, and manage quizzes using HMSSDK. + +**Full Changelog**: [1.9.9...1.9.10](https://github.com/100mslive/100ms-flutter/compare/1.9.9...1.9.10) + # 1.9.9 - 2024-02-12 | Package | Version | 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 ab86242c6..1aec0af1f 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 @@ -209,7 +209,13 @@ class HMSPollBuilderExtension { val optionMap = ArrayList>() options.forEach { - optionMap.add(Pair(it.keys.first(),it.values.first())) + val text = it["text"] as String? + text?.let { optionText -> + val isCorrect = it["is_correct"] + isCorrect?.let { isCorrectOption -> + optionMap.add(Pair(optionText,isCorrectOption)) + } + } } optionMap }?:run { diff --git a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt index 751b44559..c5dde196a 100644 --- a/packages/hmssdk_flutter/example/ExampleAppChangelog.txt +++ b/packages/hmssdk_flutter/example/ExampleAppChangelog.txt @@ -1,33 +1,15 @@ Board: https://100ms.atlassian.net/jira/software/projects/FLUT/boards/34/ -- Polls: Create Polls initial Screen -https://100ms.atlassian.net/browse/FLUT-194 +- Polls: Create a Quiz +https://100ms.atlassian.net/browse/FLUT-210 -- Polls: Ask a Question Screen -https://100ms.atlassian.net/browse/FLUT-195 +- Polls: Launch a Quiz +https://100ms.atlassian.net/browse/FLUT-213 -- Polls: Single Choice Question Screen -https://100ms.atlassian.net/browse/FLUT-196 +- Polls: Quiz Panel with a single question +https://100ms.atlassian.net/browse/FLUT-211 -- Polls: Multiple Choice Question Screen -https://100ms.atlassian.net/browse/FLUT-197 - -- Polls: Launch Poll Screen -https://100ms.atlassian.net/browse/FLUT-202 - -- Polls: Poll Panel with a live Poll Screen -https://100ms.atlassian.net/browse/FLUT-204 - -- Created poll with hide count, can see count as VNRT -https://100ms.atlassian.net/browse/FLUT-233 - -- host created poll but VNRT getting notification instantly even when timed metadata is ON -https://100ms.atlassian.net/browse/FLUT-220 - -- VNRT user not able to see poll if rejoin session -https://100ms.atlassian.net/browse/FLUT-235 - -Room Kit: 1.0.12 -Core SDK: 1.9.9 +Room Kit: 1.0.13 +Core SDK: 1.9.10 Android SDK: 2.9.0 iOS SDK: 1.5.0 diff --git a/packages/hmssdk_flutter/example/android/Gemfile.lock b/packages/hmssdk_flutter/example/android/Gemfile.lock index 99a461c55..1b71d8707 100644 --- a/packages/hmssdk_flutter/example/android/Gemfile.lock +++ b/packages/hmssdk_flutter/example/android/Gemfile.lock @@ -1,7 +1,9 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.6) + CFPropertyList (3.0.7) + base64 + nkf rexml activesupport (7.0.8) concurrent-ruby (~> 1.0, >= 1.0.2) @@ -13,11 +15,12 @@ GEM artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.889.0) - aws-sdk-core (3.191.1) + aws-partitions (1.892.0) + aws-sdk-core (3.191.2) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) + base64 jmespath (~> 1, >= 1.6.1) aws-sdk-kms (1.77.0) aws-sdk-core (~> 3, >= 3.191.0) @@ -29,6 +32,7 @@ GEM aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) + base64 (0.2.0) claide (1.1.0) colored (1.2) colored2 (3.1.2) @@ -150,7 +154,7 @@ GEM google-cloud-core (~> 1.6) googleauth (~> 1.9) mini_mime (~> 1.0) - googleauth (1.10.0) + googleauth (1.11.0) faraday (>= 1.0, < 3.a) google-cloud-env (~> 2.1) jwt (>= 1.4, < 3.0) @@ -173,6 +177,7 @@ GEM multipart-post (2.4.0) nanaimo (0.3.0) naturally (2.2.1) + nkf (0.2.0) optparse (0.4.0) os (1.1.4) plist (3.7.1) @@ -188,7 +193,7 @@ GEM ruby2_keywords (0.0.5) rubyzip (2.3.2) security (0.1.3) - signet (0.18.0) + signet (0.19.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) diff --git a/packages/hmssdk_flutter/example/android/app/build.gradle b/packages/hmssdk_flutter/example/android/app/build.gradle index 3082e60b0..d5969f201 100644 --- a/packages/hmssdk_flutter/example/android/app/build.gradle +++ b/packages/hmssdk_flutter/example/android/app/build.gradle @@ -21,7 +21,7 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 34 + compileSdkVersion 33 sourceSets { main.java.srcDirs += 'src/main/kotlin' } @@ -30,9 +30,9 @@ android { defaultConfig { applicationId "live.hms.flutter" minSdkVersion 21 - targetSdkVersion 34 - versionCode 439 - versionName "1.5.139" + targetSdkVersion 33 + versionCode 441 + versionName "1.5.141" } signingConfigs { diff --git a/packages/hmssdk_flutter/example/ios/Gemfile.lock b/packages/hmssdk_flutter/example/ios/Gemfile.lock index 90a3dbf12..030558772 100644 --- a/packages/hmssdk_flutter/example/ios/Gemfile.lock +++ b/packages/hmssdk_flutter/example/ios/Gemfile.lock @@ -1,7 +1,9 @@ GEM remote: https://rubygems.org/ specs: - CFPropertyList (3.0.6) + CFPropertyList (3.0.7) + base64 + nkf rexml activesupport (7.0.8) concurrent-ruby (~> 1.0, >= 1.0.2) @@ -13,11 +15,12 @@ GEM artifactory (3.0.15) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.889.0) - aws-sdk-core (3.191.1) + aws-partitions (1.892.0) + aws-sdk-core (3.191.2) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.8) + base64 jmespath (~> 1, >= 1.6.1) aws-sdk-kms (1.77.0) aws-sdk-core (~> 3, >= 3.191.0) @@ -29,6 +32,7 @@ GEM aws-sigv4 (1.8.0) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) + base64 (0.2.0) claide (1.1.0) colored (1.2) colored2 (3.1.2) @@ -151,7 +155,7 @@ GEM google-cloud-core (~> 1.6) googleauth (~> 1.9) mini_mime (~> 1.0) - googleauth (1.10.0) + googleauth (1.11.0) faraday (>= 1.0, < 3.a) google-cloud-env (~> 2.1) jwt (>= 1.4, < 3.0) @@ -174,6 +178,7 @@ GEM multipart-post (2.4.0) nanaimo (0.3.0) naturally (2.2.1) + nkf (0.2.0) optparse (0.4.0) os (1.1.4) plist (3.7.1) @@ -189,7 +194,7 @@ GEM ruby2_keywords (0.0.5) rubyzip (2.3.2) security (0.1.3) - signet (0.18.0) + signet (0.19.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) jwt (>= 1.5, < 3.0) diff --git a/packages/hmssdk_flutter/example/ios/Podfile.lock b/packages/hmssdk_flutter/example/ios/Podfile.lock index 875258308..3210d6e96 100644 --- a/packages/hmssdk_flutter/example/ios/Podfile.lock +++ b/packages/hmssdk_flutter/example/ios/Podfile.lock @@ -25,15 +25,15 @@ PODS: - Firebase/Performance (= 10.9.0) - firebase_core - Flutter - - FirebaseABTesting (10.20.0): + - FirebaseABTesting (10.21.0): - FirebaseCore (~> 10.0) - FirebaseCore (10.9.0): - FirebaseCoreInternal (~> 10.0) - GoogleUtilities/Environment (~> 7.8) - GoogleUtilities/Logger (~> 7.8) - - FirebaseCoreExtension (10.20.0): + - FirebaseCoreExtension (10.21.0): - FirebaseCore (~> 10.0) - - FirebaseCoreInternal (10.20.0): + - FirebaseCoreInternal (10.21.0): - "GoogleUtilities/NSData+zlib (~> 7.8)" - FirebaseCrashlytics (10.9.0): - FirebaseCore (~> 10.5) @@ -45,7 +45,7 @@ PODS: - PromisesObjC (~> 2.1) - FirebaseDynamicLinks (10.9.0): - FirebaseCore (~> 10.0) - - FirebaseInstallations (10.20.0): + - FirebaseInstallations (10.21.0): - FirebaseCore (~> 10.0) - GoogleUtilities/Environment (~> 7.8) - GoogleUtilities/UserDefaults (~> 7.8) @@ -60,14 +60,14 @@ PODS: - GoogleUtilities/ISASwizzler (~> 7.8) - GoogleUtilities/MethodSwizzler (~> 7.8) - nanopb (< 2.30910.0, >= 2.30908.0) - - FirebaseRemoteConfig (10.20.0): + - FirebaseRemoteConfig (10.21.0): - FirebaseABTesting (~> 10.0) - FirebaseCore (~> 10.0) - FirebaseInstallations (~> 10.0) - FirebaseSharedSwift (~> 10.0) - GoogleUtilities/Environment (~> 7.8) - "GoogleUtilities/NSData+zlib (~> 7.8)" - - FirebaseSessions (10.20.0): + - FirebaseSessions (10.21.0): - FirebaseCore (~> 10.5) - FirebaseCoreExtension (~> 10.0) - FirebaseInstallations (~> 10.0) @@ -75,7 +75,7 @@ PODS: - GoogleUtilities/Environment (~> 7.10) - nanopb (< 2.30910.0, >= 2.30908.0) - PromisesSwift (~> 2.1) - - FirebaseSharedSwift (10.20.0) + - FirebaseSharedSwift (10.21.0) - Flutter (1.0.0) - flutter_foreground_task (0.0.1): - Flutter @@ -100,7 +100,7 @@ PODS: - HMSSDK (1.5.0): - HMSAnalyticsSDK (= 0.0.2) - HMSWebRTC (= 1.0.5116) - - hmssdk_flutter (1.9.6): + - hmssdk_flutter (1.9.10): - Flutter - HMSBroadcastExtensionSDK (= 0.0.9) - HMSHLSPlayerSDK (= 0.0.2) @@ -217,17 +217,17 @@ SPEC CHECKSUMS: firebase_crashlytics: 9b80d1944507cc07fa1c4455797f7d2eb7c8873f firebase_dynamic_links: db9f2ebcc3ea646e76a1d3ee37e9e57890ff0a83 firebase_performance: d11d1fd9591547f6b75f325aaadd6550eaf7e090 - FirebaseABTesting: 1d5d49804bcfc5fa782bc2491a8c1364e2cf7241 + FirebaseABTesting: 40774deef367dcc7b736b6c26dd59ce0fab42f41 FirebaseCore: b68d3616526ec02e4d155166bbafb8eca64af557 - FirebaseCoreExtension: 0659f035b88c5a7a15a9763c48c2e6ca8c0a2977 - FirebaseCoreInternal: efeeb171ac02d623bdaefe121539939821e10811 + FirebaseCoreExtension: 1c044fd46e95036cccb29134757c499613f3f564 + FirebaseCoreInternal: 43c1788eaeee9d1b97caaa751af567ce11010d00 FirebaseCrashlytics: b60329455285aff853e54139d8ddbfe1e5f2b9f9 FirebaseDynamicLinks: 8cb66c4f403aa6ddf86ff3bc3c383a652f344ce9 - FirebaseInstallations: 558b1da7d65afeb996fd5c814332f013234ece4e + FirebaseInstallations: 390ea1d10a4d02b20c965cbfd527ee9b3b412acb FirebasePerformance: eee2f5da94fd7e5d15487649f8fe10a90c87c174 - FirebaseRemoteConfig: b873a427a48159082361343a85649eed3f5377ea - FirebaseSessions: 2f348975f6d1c139231c180e12194161da2e0cd6 - FirebaseSharedSwift: 2fbf73618288b7a36b2014b957745dcdd781389e + FirebaseRemoteConfig: 1dd5164b2183aff07c7726df6b0212ad5154c1fe + FirebaseSessions: 80c2bbdd28166267b3d132debe5f7531efdb00bc + FirebaseSharedSwift: 19b3f709993d6fa1d84941d41c01e3c4c11eab93 Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 flutter_foreground_task: 21ef182ab0a29a3005cc72cd70e5f45cb7f7f817 GoogleDataTransport: 57c22343ab29bc686febbf7cbb13bad167c2d8fe @@ -236,7 +236,7 @@ SPEC CHECKSUMS: HMSBroadcastExtensionSDK: d80fe325f6c928bd8e5176290b5a4b7ae15d6fbb HMSHLSPlayerSDK: 6a54ad4d12f3dc2270d1ecd24019d71282a4f6a3 HMSSDK: 0d1901d64faf2661d1183c1ba2881e2531a5eeba - hmssdk_flutter: 9f3b16d9bfc1e9a2ccd63f5d9b6a6d51669ed5ac + hmssdk_flutter: 1ac7183583649a88afe02b16d34b10968f3e792a HMSWebRTC: ae54e9dd91b869051b283b43b14f57d43b7bf8e1 MTBBarcodeScanner: f453b33c4b7dfe545d8c6484ed744d55671788cb nanopb: d4d75c12cd1316f4a64e3c6963f879ecd4b5e0d5 diff --git a/packages/hmssdk_flutter/example/ios/Runner/Info.plist b/packages/hmssdk_flutter/example/ios/Runner/Info.plist index d7533962e..2bd5bb22d 100644 --- a/packages/hmssdk_flutter/example/ios/Runner/Info.plist +++ b/packages/hmssdk_flutter/example/ios/Runner/Info.plist @@ -21,7 +21,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.5.139 + 1.5.141 CFBundleSignature ???? CFBundleURLTypes @@ -48,7 +48,7 @@ CFBundleVersion - 439 + 441 ITSAppUsesNonExemptEncryption LSApplicationCategoryType diff --git a/packages/hmssdk_flutter/example/pubspec.lock b/packages/hmssdk_flutter/example/pubspec.lock index 3f81f85e8..dd3e5cd13 100644 --- a/packages/hmssdk_flutter/example/pubspec.lock +++ b/packages/hmssdk_flutter/example/pubspec.lock @@ -234,10 +234,10 @@ packages: dependency: transitive description: name: flutter_foreground_task - sha256: e48d2d810a2d643362e64de41146ed8e95d4dd282bae6abbb32309d9f0bf5d67 + sha256: "9bcfcb43bba4a5446a056e723d21118ff6e184926b5557365c32c13caca157c2" url: "https://pub.dev" source: hosted - version: "6.1.2" + version: "6.1.3" flutter_linkify: dependency: transitive description: @@ -286,15 +286,14 @@ packages: path: "../../hms_room_kit" relative: true source: path - version: "1.0.12" + version: "1.0.13" hmssdk_flutter: dependency: transitive description: - name: hmssdk_flutter - sha256: bad4ff87c677970f0c9acfcd4e84b60089461e1c1eef23e3a3ae6ab191484b95 - url: "https://pub.dev" - source: hosted - version: "1.9.9" + path: ".." + relative: true + source: path + version: "1.9.10" http: dependency: transitive description: @@ -327,6 +326,30 @@ packages: url: "https://pub.dev" source: hosted version: "0.6.7" + 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 + url: "https://pub.dev" + source: hosted + version: "2.0.1" linkify: dependency: transitive description: @@ -347,26 +370,26 @@ packages: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" mime: dependency: transitive description: @@ -403,10 +426,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_parsing: dependency: transitive description: @@ -555,10 +578,10 @@ packages: dependency: transitive description: name: share_plus - sha256: f74fc3f1cbd99f39760182e176802f693fa0ec9625c045561cfad54681ea93dd + sha256: "3ef39599b00059db0990ca2e30fca0a29d8b37aae924d60063f8e0184cf20900" url: "https://pub.dev" source: hosted - version: "7.2.1" + version: "7.2.2" share_plus_platform_interface: dependency: transitive description: @@ -736,10 +759,10 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f" + sha256: d4ed0711849dd8e33eb2dd69c25db0d0d3fdc37e0a62e629fe32f57a22db2745 url: "https://pub.dev" source: hosted - version: "6.2.2" + version: "6.3.0" url_launcher_ios: dependency: transitive description: @@ -768,10 +791,10 @@ packages: dependency: transitive description: name: url_launcher_platform_interface - sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f + sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.3.2" url_launcher_web: dependency: transitive description: @@ -800,26 +823,26 @@ packages: dependency: transitive description: name: vector_graphics - sha256: "18f6690295af52d081f6808f2f7c69f0eed6d7e23a71539d75f4aeb8f0062172" + sha256: "4ac59808bbfca6da38c99f415ff2d3a5d7ca0a6b4809c71d9cf30fba5daf9752" url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.10+1" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "531d20465c10dfac7f5cd90b60bbe4dd9921f1ec4ca54c83ebb176dbacb7bb2d" + sha256: f3247e7ab0ec77dc759263e68394990edc608fb2b480b80db8aa86ed09279e33 url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.10+1" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "03012b0a33775c5530576b70240308080e1d5050f0faf000118c20e6463bc0ad" + sha256: "18489bdd8850de3dd7ca8a34e0c446f719ec63e2bab2e7a8cc66a9028dd76c5a" url: "https://pub.dev" source: hosted - version: "1.1.9+2" + version: "1.1.10+1" vector_math: dependency: transitive description: @@ -836,14 +859,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.2.2" - web: + vm_service: dependency: transitive description: - name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "13.0.0" win32: dependency: transitive description: @@ -869,5 +892,5 @@ packages: source: hosted version: "6.3.0" sdks: - dart: ">=3.2.0-194.0.dev <4.0.0" + dart: ">=3.2.0-0 <4.0.0" flutter: ">=3.13.0" diff --git a/packages/hmssdk_flutter/example/pubspec.yaml b/packages/hmssdk_flutter/example/pubspec.yaml index d9065c665..4cf52f921 100644 --- a/packages/hmssdk_flutter/example/pubspec.yaml +++ b/packages/hmssdk_flutter/example/pubspec.yaml @@ -4,7 +4,7 @@ description: Demonstrates how to use the hmssdk_flutter plugin. # The following line prevents the package from being accidentally published to # pub.dev using `pub publish`. This is preferred for private packages. publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 1.9.9 +version: 1.9.10 environment: sdk: ">=2.16.0 <4.0.0" diff --git a/packages/hmssdk_flutter/ios/Classes/Models/polls/HMSPollBuilderExtension.swift b/packages/hmssdk_flutter/ios/Classes/Models/polls/HMSPollBuilderExtension.swift index ec455e3f1..a74e4e2b8 100644 --- a/packages/hmssdk_flutter/ios/Classes/Models/polls/HMSPollBuilderExtension.swift +++ b/packages/hmssdk_flutter/ios/Classes/Models/polls/HMSPollBuilderExtension.swift @@ -159,9 +159,9 @@ class HMSPollBuilderExtension{ } } - if let options = pollQuestion["options"] as? [[String: Bool]] { + if let options = pollQuestion["options"] as? [[String: Any?]] { options.forEach { option in - if let key = option.keys.first, let value = option.values.first { + if let key = option["text"] as? String, let value = option["is_correct"] as? Bool{ pollQuestionBuilder.addQuizOption(with: key, isCorrect: value) } } diff --git a/packages/hmssdk_flutter/lib/assets/sdk-versions.json b/packages/hmssdk_flutter/lib/assets/sdk-versions.json index 669853ab3..acfe8e6ce 100644 --- a/packages/hmssdk_flutter/lib/assets/sdk-versions.json +++ b/packages/hmssdk_flutter/lib/assets/sdk-versions.json @@ -1,5 +1,5 @@ { - "flutter": "1.9.9", + "flutter": "1.9.10", "ios": "1.5.0", "iOSBroadcastExtension": "0.0.9", "iOSHLSPlayerSDK": "0.0.2", diff --git a/packages/hmssdk_flutter/lib/src/enum/hms_audio_codec.dart b/packages/hmssdk_flutter/lib/src/enum/hms_audio_codec.dart index 211f4b629..a52aa7bca 100644 --- a/packages/hmssdk_flutter/lib/src/enum/hms_audio_codec.dart +++ b/packages/hmssdk_flutter/lib/src/enum/hms_audio_codec.dart @@ -1,8 +1,7 @@ -///{@nodoc} +///[HMSAudioCodec] contains audio codec supported by HMSSDK enum HMSAudioCodec { opus, unknown } -///{@nodoc} -///AudioCodec +///Utility method to return audio codec from string and vice versa extension HMSAudioCodecValues on HMSAudioCodec { static HMSAudioCodec getHMSCodecFromName(String name) { switch (name) { diff --git a/packages/hmssdk_flutter/lib/src/hmssdk.dart b/packages/hmssdk_flutter/lib/src/hmssdk.dart index fe28339d6..c1f26fde3 100644 --- a/packages/hmssdk_flutter/lib/src/hmssdk.dart +++ b/packages/hmssdk_flutter/lib/src/hmssdk.dart @@ -577,7 +577,7 @@ class HMSSDK { arguments: arguments); if (hmsActionResultListener != null) { - if (result == null) + if (result == null) { hmsActionResultListener.onSuccess( methodType: HMSActionResultListenerMethod.changeRoleOfPeer, arguments: { @@ -585,7 +585,7 @@ class HMSSDK { 'role_name': toRole, 'force_change': force }); - else + } else { hmsActionResultListener.onException( arguments: { 'peer': forPeer, @@ -594,6 +594,7 @@ class HMSSDK { }, methodType: HMSActionResultListenerMethod.changeRoleOfPeer, hmsException: HMSException.fromMap(result["error"])); + } } } diff --git a/packages/hmssdk_flutter/lib/src/model/polls/hms_poll_interactivity_center.dart b/packages/hmssdk_flutter/lib/src/model/polls/hms_poll_interactivity_center.dart index 4e4c0e846..5c29370d3 100644 --- a/packages/hmssdk_flutter/lib/src/model/polls/hms_poll_interactivity_center.dart +++ b/packages/hmssdk_flutter/lib/src/model/polls/hms_poll_interactivity_center.dart @@ -31,9 +31,7 @@ abstract class HMSPollInteractivityCenter { /// Future - A Future representing the asynchronous operation. It will return either null if the operation is successful, or an [HMSException] if an error occurs. /// ///Refer [Quick Start Poll](Add docs link here) - static void quickStartPoll( - {required HMSPollBuilder pollBuilder, - required HMSActionResultListener? hmsActionResultListener}) async { + static void quickStartPoll({required HMSPollBuilder pollBuilder}) async { PlatformService.invokeMethod(PlatformMethod.quickStartPoll, arguments: {"poll_builder": pollBuilder.toMap()}); } @@ -227,14 +225,14 @@ class HMSPollBuilder { if (_rolesThatCanViewResponse == null) { _rolesThatCanViewResponse = []; } - _rolesThatCanViewResponse?.addAll(rolesThatCanViewResponses); + _rolesThatCanViewResponse = rolesThatCanViewResponses; } set withRolesThatCanVote(List rolesThatCanVote) { if (_rolesThatCanVote == null) { _rolesThatCanVote = []; } - _rolesThatCanVote?.addAll(rolesThatCanVote); + _rolesThatCanVote = rolesThatCanVote; } set withTitle(String title) { diff --git a/packages/hmssdk_flutter/lib/src/model/polls/hms_poll_question_builder.dart b/packages/hmssdk_flutter/lib/src/model/polls/hms_poll_question_builder.dart index a899f5c23..6c774ce48 100644 --- a/packages/hmssdk_flutter/lib/src/model/polls/hms_poll_question_builder.dart +++ b/packages/hmssdk_flutter/lib/src/model/polls/hms_poll_question_builder.dart @@ -62,11 +62,13 @@ class HMSPollQuestionBuilder { } set addQuizOption(List options) { - _options.addAll(options); + _options = options; } List get pollOptions => _pollOptions; + List get quizOptions => _options; + String? get title => _title; String? get text => _text; @@ -78,7 +80,7 @@ class HMSPollQuestionBuilder { 'can_skip': _canSkip, 'title': _title, 'duration': _duration?.inMilliseconds, - 'options': _options, + 'options': _options.map((e) => e.toMap()).toList(), 'poll_options': _pollOptions, 'text': _text, 'type': HMSPollQuestionTypeValues.getStringFromHMSPollQuestionType(_type), @@ -93,14 +95,20 @@ class HMSPollQuestionBuilder { class HMSPollQuizOption { final String text; - final bool isCorrect; + bool _isCorrect = false; + + set isCorrect(bool isCorrect) { + _isCorrect = isCorrect; + } + + bool get isOptionCorrect => _isCorrect; - HMSPollQuizOption({required this.text, required this.isCorrect}); + HMSPollQuizOption({required this.text}); Map toMap() { return { 'text': text, - 'is_correct': isCorrect, + 'is_correct': _isCorrect, }; } } diff --git a/packages/hmssdk_flutter/pubspec.lock b/packages/hmssdk_flutter/pubspec.lock index 53939cd59..207cb2beb 100644 --- a/packages/hmssdk_flutter/pubspec.lock +++ b/packages/hmssdk_flutter/pubspec.lock @@ -59,38 +59,62 @@ packages: description: flutter source: sdk version: "0.0.0" + 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 + url: "https://pub.dev" + source: hosted + version: "2.0.1" matcher: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" path: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" sky_engine: dependency: transitive description: flutter @@ -152,14 +176,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" - web: + vm_service: dependency: transitive description: - name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "13.0.0" sdks: - dart: ">=3.2.0-194.0.dev <4.0.0" + dart: ">=3.2.0-0 <4.0.0" flutter: ">=2.10.0" diff --git a/packages/hmssdk_flutter/pubspec.yaml b/packages/hmssdk_flutter/pubspec.yaml index 45d0130d6..2632c329a 100644 --- a/packages/hmssdk_flutter/pubspec.yaml +++ b/packages/hmssdk_flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: hmssdk_flutter description: Add Real Time Audio & Video calls, Interactive Live Streaming & Recording, Chat, HLS, RTMP, PiP, CallKit, VoIP, Video conferencing, Stream Player & WebRTC-based communications API -version: 1.9.9 +version: 1.9.10 homepage: https://www.100ms.live/ repository: https://github.com/100mslive/100ms-flutter issue_tracker: https://github.com/100mslive/100ms-flutter/issues