From 92e667e44e220b1e39ac17eb7897fabd9992bbc9 Mon Sep 17 00:00:00 2001 From: Adam Sharpe Date: Tue, 22 Jul 2014 18:49:34 -0400 Subject: [PATCH] Implemented polling module as regular viewer (non-moderator, non-presenter) --- src/Default.css | 49 ++++ src/Main.mxml | 6 + src/assets/res/drawable-hdpi/polling.png | Bin 0 -> 825 bytes src/assets/res/drawable-mdpi/polling.png | Bin 0 -> 459 bytes src/assets/res/drawable-xhdpi/polling.png | Bin 0 -> 1086 bytes src/assets/res/drawable-xxhdpi/polling.png | Bin 0 -> 2256 bytes src/assets/res/drawable-xxxhdpi/polling.png | Bin 0 -> 3540 bytes src/locale/en_US/resources.properties | 11 +- src/org/bigbluebutton/AppConfig.as | 4 +- .../bigbluebutton/command/ConnectCommand.as | 16 +- src/org/bigbluebutton/core/IPollService.as | 11 + .../bigbluebutton/core/PollMessageReceiver.as | 180 +++++++++++++++ .../bigbluebutton/core/PollMessageSender.as | 33 +++ src/org/bigbluebutton/core/PollService.as | 34 +++ src/org/bigbluebutton/model/IUserSession.as | 7 +- src/org/bigbluebutton/model/UserList.as | 18 +- src/org/bigbluebutton/model/UserSession.as | 20 +- src/org/bigbluebutton/model/polling/Poll.as | 96 ++++++++ .../bigbluebutton/model/polling/PollModel.as | 132 +++++++++++ .../bigbluebutton/model/polling/Question.as | 43 ++++ .../bigbluebutton/model/polling/Responder.as | 21 ++ .../bigbluebutton/model/polling/Response.as | 31 +++ .../bigbluebutton/model/polling/Responses.as | 21 ++ .../navigation/PagesNavigatorViewMediator.as | 8 +- .../view/navigation/pages/PagesENUM.as | 9 + .../navigation/pages/common/MenuButtons.mxml | 1 + .../pages/common/MenuButtonsView.as | 4 + .../pages/common/MenuButtonsViewMediator.as | 7 + .../pages/pollresults/IPollResultsView.as | 11 + .../pages/pollresults/PollResultsConfig.as | 54 +++++ .../pages/pollresults/PollResultsView.as | 19 ++ .../pollresults/PollResultsViewBase.mxml | 20 ++ .../pollresults/PollResultsViewMediator.as | 114 ++++++++++ .../pages/pollresults/ResponseListView.mxml | 16 ++ .../pages/pollresults/ResponseView.mxml | 21 ++ .../pages/pollslist/IPollsListView.as | 11 + .../pages/pollslist/PollsListConfig.as | 54 +++++ .../pollslist/PollsListItemRenderer.mxml | 46 ++++ .../pages/pollslist/PollsListView.as | 21 ++ .../pages/pollslist/PollsListViewBase.mxml | 40 ++++ .../pages/pollslist/PollsListViewMediator.as | 85 +++++++ .../pages/takepoll/ITakePollView.as | 14 ++ .../pages/takepoll/QuestionView.mxml | 32 +++ .../pages/takepoll/TakePollConfig.as | 54 +++++ .../navigation/pages/takepoll/TakePollView.as | 30 +++ .../pages/takepoll/TakePollViewBase.mxml | 23 ++ .../pages/takepoll/TakePollViewMediator.as | 213 ++++++++++++++++++ .../view/skins/CheckBoxSkin.mxml | 163 ++++++++++++++ .../view/skins/RadioButtonSkin.mxml | 4 +- 49 files changed, 1779 insertions(+), 28 deletions(-) create mode 100644 src/assets/res/drawable-hdpi/polling.png create mode 100644 src/assets/res/drawable-mdpi/polling.png create mode 100644 src/assets/res/drawable-xhdpi/polling.png create mode 100644 src/assets/res/drawable-xxhdpi/polling.png create mode 100644 src/assets/res/drawable-xxxhdpi/polling.png create mode 100644 src/org/bigbluebutton/core/IPollService.as create mode 100644 src/org/bigbluebutton/core/PollMessageReceiver.as create mode 100644 src/org/bigbluebutton/core/PollMessageSender.as create mode 100644 src/org/bigbluebutton/core/PollService.as create mode 100644 src/org/bigbluebutton/model/polling/Poll.as create mode 100644 src/org/bigbluebutton/model/polling/PollModel.as create mode 100644 src/org/bigbluebutton/model/polling/Question.as create mode 100644 src/org/bigbluebutton/model/polling/Responder.as create mode 100644 src/org/bigbluebutton/model/polling/Response.as create mode 100644 src/org/bigbluebutton/model/polling/Responses.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollresults/IPollResultsView.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsConfig.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsView.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsViewBase.mxml create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsViewMediator.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollresults/ResponseListView.mxml create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollresults/ResponseView.mxml create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollslist/IPollsListView.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListConfig.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListItemRenderer.mxml create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListView.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListViewBase.mxml create mode 100644 src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListViewMediator.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/takepoll/ITakePollView.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/takepoll/QuestionView.mxml create mode 100644 src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollConfig.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollView.as create mode 100644 src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollViewBase.mxml create mode 100644 src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollViewMediator.as create mode 100644 src/org/bigbluebutton/view/skins/CheckBoxSkin.mxml diff --git a/src/Default.css b/src/Default.css index 0c77804..457c75b 100644 --- a/src/Default.css +++ b/src/Default.css @@ -115,6 +115,11 @@ s|RadioButton skinClass: ClassReference("org.bigbluebutton.view.skins.RadioButtonSkin"); } +s|CheckBox +{ + skinClass: ClassReference("org.bigbluebutton.view.skins.CheckBoxSkin") +} + s|Image.bbbLogoStyle { verticalCenter: 0; @@ -254,6 +259,11 @@ global backgroundImage: Embed(source="assets/res/drawable-mdpi/deskshare.png"); } + ui|NavigationButton.pollsBtnStyle + { + backgroundImage: Embed(source="assets/res/drawable-mdpi/polling.png"); + } + s|Button.logoutButtonStyle { height: 50; @@ -369,6 +379,12 @@ global eclipseBottom: 10; } + s|CheckBox + { + height: 40; + width: 40; + } + s|Image.bbbLogoStyle { imageSource: Embed(source="assets/res/drawable-mdpi/ic_launcher.png"); @@ -510,6 +526,11 @@ global backgroundImage: Embed(source="assets/res/drawable-hdpi/deskshare.png"); } + ui|NavigationButton.pollsBtnStyle + { + backgroundImage: Embed(source="assets/res/drawable-hdpi/polling.png"); + } + s|Button.topButtonStyle { width: 45; @@ -602,6 +623,12 @@ global eclipseBottom: 15; } + s|CheckBox + { + height: 60; + width: 60; + } + s|Image.bbbLogoStyle { imageSource: Embed(source="assets/res/drawable-hdpi/ic_launcher.png"); @@ -742,6 +769,11 @@ global backgroundImage: Embed(source="assets/res/drawable-xhdpi/deskshare.png"); } + ui|NavigationButton.pollsBtnStyle + { + backgroundImage: Embed(source="assets/res/drawable-xhdpi/polling.png"); + } + s|Button.topButtonStyle { width: 60; @@ -829,6 +861,12 @@ global eclipseBottom: 20; } + s|CheckBox + { + height: 80; + width: 80; + } + s|Image.bbbLogoStyle { imageSource: Embed(source="assets/res/drawable-xhdpi/ic_launcher.png"); @@ -951,6 +989,11 @@ global backgroundImage: Embed(source="assets/res/drawable-xxhdpi/deskshare.png"); } + ui|NavigationButton.pollsBtnStyle + { + backgroundImage: Embed(source="assets/res/drawable-xxhdpi/polling.png"); + } + s|Button.logoutButtonStyle { height: 150; @@ -1071,6 +1114,12 @@ global eclipseBottom: 30; } + s|CheckBox + { + height: 120; + width: 120; + } + s|Group.userDetailGroupStyle { height: 90; diff --git a/src/Main.mxml b/src/Main.mxml index be34c86..3985ffb 100644 --- a/src/Main.mxml +++ b/src/Main.mxml @@ -48,6 +48,9 @@ import org.bigbluebutton.view.navigation.pages.selectparticipant.SelectParticipantConfig; import org.bigbluebutton.view.navigation.pages.userdetails.UserDetaisConfig; import org.bigbluebutton.view.navigation.pages.videochat.VideoChatConfig; + import org.bigbluebutton.view.navigation.pages.pollslist.PollsListConfig; + import org.bigbluebutton.view.navigation.pages.takepoll.TakePollConfig; + import org.bigbluebutton.view.navigation.pages.pollresults.PollResultsConfig; import org.bigbluebutton.view.ui.MicButtonConfig; import org.bigbluebutton.view.ui.NavigationButtonConfig; import org.bigbluebutton.view.ui.SwapCameraConfig; @@ -123,6 +126,9 @@ .configure(DisconnectPageConfig) .configure(DeskshareConfig) .configure(MenuButtonsConfig) + .configure(PollsListConfig) + .configure(TakePollConfig) + .configure(PollResultsConfig) .configure(new ContextView(this)); diff --git a/src/assets/res/drawable-hdpi/polling.png b/src/assets/res/drawable-hdpi/polling.png new file mode 100644 index 0000000000000000000000000000000000000000..a8dd9432b57d05c74d42ff1f9642538886be867e GIT binary patch literal 825 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@Zgyv2U}o@iaSW-L^Y+gD?8^Zn>>u)H zP1>?EH+a($&l3IYml@kRHBX=M*8JVfGM_cDP2tD>6U!FmKdOH?=dk+6+;{mM{5zK} zF0n|Y)Xe5T+G-`XheR#D0f1Fhi&)a zha2Lz?Yg_JTXNbp2R4Rk6RFtr$g-)aH}e;*yJWKW-S^-AfjJW-FUXu=xv)(~dwcHg zkjQCMj~D)tY3K#o$HcKmBo4(pOtBh44^YuUC4+<*P`mow06!wWTrKvICYvGD}V z$0cmLUhkQF&B1N^?b6V+xoph`-x+DlZQx-@TYtTJ(z48#mCG+?l=R-z=>O(WCUg9J z$n&`jTMAFlo0RA9Rii6z#X9z*Jy#CNSKV!pvAnaCOT-9l0mK>*dBL8Y>+pxGObfiH z%FTOTJBR&~&HKq-{KpIHbQr95<}c{Wat6Bk4uesvK;YW2-zzU2F1>qxhHPFCJD4Vq93d8vlnnY;5hJDbt==1$&W7EiUjMGusZ~8Izopr041GarT_o{ literal 0 HcmV?d00001 diff --git a/src/assets/res/drawable-mdpi/polling.png b/src/assets/res/drawable-mdpi/polling.png new file mode 100644 index 0000000000000000000000000000000000000000..802c6f7fda0a49572e97118c35a41e70224190f3 GIT binary patch literal 459 zcmV;+0W|)JP)~7Rc zR-7LUgk;#v=MTJkKAe)9J&i%Jcj&P17O8*VRkF`d~0vx~kvr9|1LA z0d3bnz%oga6Cm^zpuPb(6Mz5&AOHaf;D>-9%d#ui0$?;6EhxV5UINy%);F$RrPKn5 zd<8VL*7qfVH=rc|0SG_<0{HiUAWhR@*>VBP+TI61t=H=vmMs^6bzcFY*7~??4vGbY zpMWGuPQL+A0uX=z1fbqZ0C(O2;yAwe1T>q?cUNz>+kN^3bUK}9SFbs%1%z=NpZ^xH z0Zf1cOYH$$1`q+ez|7LS4{QT#rgqG|RlPHFR%FiJGVij@F)_1#NoXD@OSLKfyayB; zgeI`*=xvzZz+AU2y_@E&n(3`OdXU}5!iaSW-L^Y-rDJZV>nV;}#k zm6hLpvu@*`jjv5z6{>ls-n!NOMAS z9Ho|1g$-%5mi13R{q)zLKYKn!tPOkpv*zEX`|po)EDVzQ)O5FZ(TnJWy{|bAf7tG~ z{IlFoYexpv#}n$mump~Qm7DYOZ56@?!utD zne)SxSqzQ>K7tNQISv%DBv>+SkYSAIW6*JDn5N8dTCm|My0B<)`s12n=GtOA#wk6_ zCYMa+F3+@@@1quZb>gy@HlCB@ZmUbO1SlQ7mz!-iJ62Duo7?!`Is?5;I=f~1kIygK zny=k3sj$J?;dtrYtEknd_VQY0vCH6uXtEyY_{GrQXvVZc1iw2G&hL{<_$*dCH~L3d@fwDsab=V5<~^u> zay?G^j?Klw3o_CUfom>b%=q%I#;$&A)Y`ILt@~s2u3vun#abtx!9J`ZO~h6H$G-o2 z&fPiu@B`;>K*mF)npr-N5^RLEUrG zm$J7q0XFZ&LKvs8Wb_?>><?fQnIt$J7+@{{ zx(SWBj`_;FInu5d&DS&jSb1*GzW4j9?yBzHym_;I*1Dh1qp!)#5)Y1T2>Q*)SN%%% z?)&fc57OShSaAF8zo7JcVXMEUOSB2E`?qkjbDi&3=kuTct=jo4e&@|R%Z^1ae%mrk zxg}U^aQAZK_eORHwwjotlmpHQOguOCeW}UX*LUV|zt)+#jK&Y_3i|(q?z$pF7I&@~ z^uIUSp3PPCSG+R%tkt)TY3HwO3i{2Qp8V#w$_=|`dvo6<$828o=lo}WC)tSm+rpPv Q1Iq;lPgg&ebxsLQ062H+Hvj+t literal 0 HcmV?d00001 diff --git a/src/assets/res/drawable-xxhdpi/polling.png b/src/assets/res/drawable-xxhdpi/polling.png new file mode 100644 index 0000000000000000000000000000000000000000..e58df61d782277b372054df676b628d4d8817747 GIT binary patch literal 2256 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 literal 0 HcmV?d00001 diff --git a/src/locale/en_US/resources.properties b/src/locale/en_US/resources.properties index 9ceec95..4d2e2bb 100644 --- a/src/locale/en_US/resources.properties +++ b/src/locale/en_US/resources.properties @@ -41,4 +41,13 @@ disconnect.reason.userLoggedOut=You have logged out of the meeting disconnect.reason.userKickedOut=You have been kicked out of the meeting disconnect.reason.userExit=Exit deskshare.noDeskshare = No desktop stream to display -deskshare.title = Desktop Sharing \ No newline at end of file +deskshare.title = Desktop Sharing +pollsList.title=Poll List +pollsList.notStarted=[Not Started] +pollsList.closed=[Closed - View Results] +pollsList.alreadyVoted=[Already Voted - View Results] +pollsList.voteNow=[Vote Now] +takePoll.title=Take Poll +takePoll.submit=Submit +takePoll.errorMessage=Please make sure to respond to each question +pollResults.title=Poll Results \ No newline at end of file diff --git a/src/org/bigbluebutton/AppConfig.as b/src/org/bigbluebutton/AppConfig.as index 8fcf638..48df782 100644 --- a/src/org/bigbluebutton/AppConfig.as +++ b/src/org/bigbluebutton/AppConfig.as @@ -38,7 +38,8 @@ package org.bigbluebutton import org.bigbluebutton.model.UserUISession; import org.bigbluebutton.model.chat.ChatMessagesSession; import org.bigbluebutton.model.chat.IChatMessagesSession; - + import org.bigbluebutton.core.IPollService; + import org.bigbluebutton.core.PollService; import robotlegs.bender.extensions.signalCommandMap.api.ISignalCommandMap; @@ -63,6 +64,7 @@ package org.bigbluebutton injector.map(IChatMessageService).toSingleton(ChatMessageService); injector.map(IPresentationService).toSingleton(PresentationService); injector.map(IChatMessagesSession).toSingleton(ChatMessagesSession); + injector.map(IPollService).toSingleton(PollService); injector.map(IDeskshareConnection).toSingleton(DeskshareConnection); // Type mapping diff --git a/src/org/bigbluebutton/command/ConnectCommand.as b/src/org/bigbluebutton/command/ConnectCommand.as index a446b32..a766b7a 100644 --- a/src/org/bigbluebutton/command/ConnectCommand.as +++ b/src/org/bigbluebutton/command/ConnectCommand.as @@ -16,9 +16,10 @@ package org.bigbluebutton.command import org.bigbluebutton.model.IUserSession; import org.bigbluebutton.model.IUserUISession; import org.bigbluebutton.view.navigation.pages.PagesENUM; + import org.bigbluebutton.core.IPollService; import org.osmf.logging.Log; - import robotlegs.bender.bundles.mvcs.Command; + import robotlegs.bender.bundles.mvcs.Command; public class ConnectCommand extends Command { @@ -55,6 +56,9 @@ package org.bigbluebutton.command [Inject] public var presentationService: IPresentationService; + [Inject] + public var pollService:IPollService; + override public function execute():void { connection.uri = uri; @@ -88,6 +92,7 @@ package org.bigbluebutton.command // Set up remaining message sender and receivers: chatService.setupMessageSenderReceiver(); presentationService.setupMessageSenderReceiver(); + pollService.setupMessageSenderReceiver(); // set up and connect the remaining connections videoConnection.uri = userSession.config.getConfigFor("VideoConfModule").@uri + "/" + conferenceParameters.room; @@ -108,20 +113,21 @@ package org.bigbluebutton.command deskshareConnection.connect(); userSession.deskshareConnection = deskshareConnection; - - // Query the server for chat, users, and presentation info + + // Query the server for chat, users, polls, and presentation info chatService.sendWelcomeMessage(); chatService.getPublicChatMessages(); presentationService.getPresentationInfo(); - + userSession.userList.allUsersAddedSignal.add(successUsersAdded); usersService.queryForParticipants(); usersService.queryForRecordingStatus(); + pollService.getPolls(); + userSession.successJoiningMeetingSignal.remove(successJoiningMeeting); userSession.unsuccessJoiningMeetingSignal.remove(unsuccessJoiningMeeting); - usersService.getRoomLockState(); } private function unsuccessJoiningMeeting():void { diff --git a/src/org/bigbluebutton/core/IPollService.as b/src/org/bigbluebutton/core/IPollService.as new file mode 100644 index 0000000..f7a34ca --- /dev/null +++ b/src/org/bigbluebutton/core/IPollService.as @@ -0,0 +1,11 @@ +package org.bigbluebutton.core +{ + import org.bigbluebutton.model.polling.Responses; + + public interface IPollService + { + function setupMessageSenderReceiver():void; + function getPolls():void; + function respondPoll(pollID:String, responses:Array):void; + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/core/PollMessageReceiver.as b/src/org/bigbluebutton/core/PollMessageReceiver.as new file mode 100644 index 0000000..0cdfe26 --- /dev/null +++ b/src/org/bigbluebutton/core/PollMessageReceiver.as @@ -0,0 +1,180 @@ +package org.bigbluebutton.core +{ + import org.bigbluebutton.model.IMessageListener; + import org.bigbluebutton.model.IUserSession; + import org.bigbluebutton.model.polling.Poll; + import org.bigbluebutton.model.polling.Question; + import org.bigbluebutton.model.polling.Responder; + import org.bigbluebutton.model.polling.Response; + + + public class PollMessageReceiver implements IMessageListener + { + public var userSession:IUserSession; + + public function PollMessageReceiver(userSession:IUserSession) { + this.userSession = userSession; + } + + public function onMessage(messageName:String, message:Object):void { + switch(messageName) { + case "pollGetPollsReply": + handleGetPollsReply(message); + break; + case "pollCreatedMessage": + handlePollCreatedMessage(message); + break; + case "pollUpdatedMessage": + handlePollUpdatedMessage(message); + break; + case "pollDestroyedMessage": + handlePollDestroyedMessage(message); + break; + case "pollStartedMessage": + handlePollStartedMessage(message); + break; + case "pollStoppedMessage": + handlePollStoppedMessage(message); + break; + case "pollResultUpdatedMessage": + handlePollResultUpdatedMessage(message); + break; + default: + break; + } + } + + private function handleGetPollsReply(m:Object):void { + var polls:Array = JSON.parse(m.msg) as Array; + trace("PollMessageReceiver::handleGetPollsReply() -- [" + polls.length + "] polls received from server"); + + for(var i:int = 0; i < polls.length; i++) { + userSession.pollModel.createPoll(buildPoll(polls[i])); + } + } + + private function handlePollCreatedMessage(m:Object):void { + var poll:Object = JSON.parse(m.msg); + trace("PollMessageReceiver::handlePollCreatedMessage() -- creating poll [" + poll.title + "]"); + userSession.pollModel.createPoll(buildPoll(poll)); + } + + private function handlePollUpdatedMessage(m:Object):void { + var poll:Object = JSON.parse(m.msg); + trace("PollMessageReceiver::handlePollUpdatedMessage() -- updating poll [" + poll.title + "]"); + if(userSession.pollModel.hasPoll(poll.id)) { + userSession.pollModel.updatePoll(buildPoll(poll)); + } + } + + private function handlePollDestroyedMessage(m:Object):void { + var poll:Object = JSON.parse(m.msg); + trace("PollMessageReceiver::handlePollDestroyedMessage() -- destroying poll [" + poll.title + "]"); + if(userSession.pollModel.hasPoll(poll.pollID)) { + userSession.pollModel.destroyPoll(poll.pollID); + } + } + + private function handlePollStartedMessage(m:Object):void { + var poll:Object = JSON.parse(m.msg); + trace("PollMessageReceiver::handlePollStartedMessage() -- starting poll [" + poll.title + "]"); + if(userSession.pollModel.hasPoll(poll.pollID)) { + userSession.pollModel.startPoll(poll.pollID); + } + } + + private function handlePollStoppedMessage(m:Object):void { + var poll:Object = JSON.parse(m.msg); + trace("PollMessageReceiver::handlePollStoppedMessage() -- stopping poll [" + poll.title + "]"); + if(userSession.pollModel.hasPoll(poll.pollID)) { + userSession.pollModel.stopPoll(poll.pollID); + } + } + + private function handlePollResultUpdatedMessage(m:Object):void { + var message:Object = JSON.parse(m.msg); + + /*** The format of 'message': + * { + * "response": + * { + * "pollID":"pollID-103", + * "responses": + * [ + * { + * "questionID":"q1", + * "responseIDs":["0","1"] + * }, + * + * ... + * ] + * }, + * + * "responder": + * { + * "userID":"enfjadjc5xnn", + * "name":"RED" + * } + * } + */ + + var response:Object = message.response; + + if(userSession.pollModel.hasPoll(response.pollID)) { + var responses:Array = response.responses; + var responder:Responder = buildResponder(message.responder); + + for(var i:int = 0; i < responses.length; i++) { + var individualResponse:Object = responses[i]; + var responseIDs:Array = individualResponse.responseIDs; + + for(var j:int = 0; j < responseIDs.length; j++) { + userSession.pollModel.updateResults(response.pollID, individualResponse.questionID, responseIDs[j], responder); + } + } + } + } + + private function buildPoll(pollObj:Object):Poll { + trace("PollMessageReceiver::handleGetPollsReply() -- building poll [" + pollObj.title + "]"); + var questions:Array = pollObj.questions; + var qs:Array = new Array(); + + for(var i:int = 0; i < questions.length; i++) { + qs.push(buildQuestion(questions[i])); + } + + return new Poll(pollObj.id, pollObj.title, qs, pollObj.started, pollObj.stopped); + } + + private function buildQuestion(questionObj:Object):Question { + trace("PollMessageReceiver::buildQuestion() -- building question [" + questionObj.question + "]"); + var responses:Array = questionObj.responses; + var rs:Array = new Array(); + + for(var i:int = 0; i < responses.length; i++) { + rs.push(buildResponse(responses[i])); + } + + return new Question(questionObj.id, questionObj.multiResponse, questionObj.question, rs); + } + + private function buildResponse(responseObj:Object):Response { + trace("PollMessageReceiver::buildResponse -- building response [" + responseObj.text + "]"); + var responders:Array = responseObj.responders; + var rs:Array = new Array(); + + for(var i:int = 0; i < responders.length; i++) { + rs.push(buildResponder(responders[i])); + } + + return new Response(responseObj.id, responseObj.text, rs); + } + + private function buildResponder(responderObj:Object):Responder { + trace("PollMessageReceiver::buildResponder -- building responder for userID [" + responderObj.userID + "], name [" + responderObj.name + "]"); + return new Responder(responderObj.userID, responderObj.name); + } + + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/core/PollMessageSender.as b/src/org/bigbluebutton/core/PollMessageSender.as new file mode 100644 index 0000000..f08ecbb --- /dev/null +++ b/src/org/bigbluebutton/core/PollMessageSender.as @@ -0,0 +1,33 @@ +package org.bigbluebutton.core +{ + import org.bigbluebutton.model.IUserSession; + + public class PollMessageSender + { + public var userSession:IUserSession; + + // The default callbacks of userSession.mainconnection.sendMessage + private var defaultSuccessResponse:Function = function(result:String):void { trace(result); }; + private var defaultFailureResponse:Function = function(status:String):void { trace(status); }; + + public function PollMessageSender(userSession:IUserSession) { + this.userSession = userSession; + } + + public function getPolls():void { + trace("PollMessageSender::getPolls() -- Sending [poll.getPolls] message to server"); + userSession.mainConnection.sendMessage("poll.getPolls", defaultSuccessResponse, defaultFailureResponse); + } + + public function respondPoll(pollID:String, responses:Array):void { + var messageObject:Object = new Object(); + messageObject["pollID"] = pollID; + messageObject["questions"] = responses; + + var message:String = JSON.stringify(messageObject); + trace("PollMessageSender::getPolls() -- Sending [poll.respondPoll] message to server with message: " + message); + + userSession.mainConnection.sendMessage("poll.respondPoll", defaultSuccessResponse, defaultFailureResponse, message); + } + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/core/PollService.as b/src/org/bigbluebutton/core/PollService.as new file mode 100644 index 0000000..1535026 --- /dev/null +++ b/src/org/bigbluebutton/core/PollService.as @@ -0,0 +1,34 @@ +package org.bigbluebutton.core +{ + import org.bigbluebutton.model.IMessageListener; + import org.bigbluebutton.model.IUserSession; + + public class PollService implements IPollService + { + [Inject] + public var userSession: IUserSession; + + public var pollMessageSender:PollMessageSender; + public var pollMessageReceiver:PollMessageReceiver; + + public function PollService() { + + } + + public function setupMessageSenderReceiver():void { + pollMessageSender = new PollMessageSender(userSession); + pollMessageReceiver = new PollMessageReceiver(userSession); + + userSession.mainConnection.addMessageListener(pollMessageReceiver as IMessageListener); + } + + public function getPolls():void { + pollMessageSender.getPolls(); + } + + public function respondPoll(pollID:String, responses:Array):void { + pollMessageSender.respondPoll(pollID, responses); + } + + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/model/IUserSession.as b/src/org/bigbluebutton/model/IUserSession.as index 75fdba7..5e5371f 100644 --- a/src/org/bigbluebutton/model/IUserSession.as +++ b/src/org/bigbluebutton/model/IUserSession.as @@ -3,17 +3,17 @@ package org.bigbluebutton.model import flash.net.NetConnection; import org.bigbluebutton.core.IBigBlueButtonConnection; + import org.bigbluebutton.core.IDeskshareConnection; import org.bigbluebutton.core.IVideoConnection; import org.bigbluebutton.core.IVoiceConnection; import org.bigbluebutton.core.VideoConnection; import org.bigbluebutton.core.VoiceConnection; import org.bigbluebutton.core.VoiceStreamManager; import org.bigbluebutton.model.chat.ChatMessages; + import org.bigbluebutton.model.polling.PollModel; import org.bigbluebutton.model.presentation.PresentationList; import org.osflash.signals.ISignal; - import org.osflash.signals.Signal; - import org.bigbluebutton.core.IVoiceConnection; - import org.bigbluebutton.core.IDeskshareConnection; + import org.osflash.signals.Signal; public interface IUserSession @@ -34,6 +34,7 @@ package org.bigbluebutton.model function get deskshareConnection():IDeskshareConnection; function set deskshareConnection(value:IDeskshareConnection):void; function get presentationList():PresentationList; + function get pollModel():PollModel; function get guestSignal():ISignal; function get successJoiningMeetingSignal():ISignal; function get unsuccessJoiningMeetingSignal():ISignal; diff --git a/src/org/bigbluebutton/model/UserList.as b/src/org/bigbluebutton/model/UserList.as index ada420e..06b6708 100644 --- a/src/org/bigbluebutton/model/UserList.as +++ b/src/org/bigbluebutton/model/UserList.as @@ -21,6 +21,15 @@ package org.bigbluebutton.model private var _users:ArrayCollection; + public function UserList() + { + _me = new User(); + _users = new ArrayCollection(); + _sort = new Sort(); + _sort.compareFunction = sortFunction; + _users.sort = _sort; + } + [Bindable] public function get users():ArrayCollection { @@ -46,15 +55,6 @@ package org.bigbluebutton.model private var _sort:Sort; - public function UserList() - { - _me = new User(); - _users = new ArrayCollection(); - _sort = new Sort(); - _sort.compareFunction = sortFunction; - _users.sort = _sort; - } - /** * Dispatched when all participants are added */ diff --git a/src/org/bigbluebutton/model/UserSession.as b/src/org/bigbluebutton/model/UserSession.as index 322a5fa..f5f958a 100644 --- a/src/org/bigbluebutton/model/UserSession.as +++ b/src/org/bigbluebutton/model/UserSession.as @@ -11,6 +11,7 @@ package org.bigbluebutton.model import org.bigbluebutton.core.VoiceConnection; import org.bigbluebutton.core.VoiceStreamManager; import org.bigbluebutton.model.chat.ChatMessages; + import org.bigbluebutton.model.polling.PollModel; import org.bigbluebutton.model.presentation.PresentationList; import org.hamcrest.core.throws; import org.osflash.signals.ISignal; @@ -28,6 +29,7 @@ package org.bigbluebutton.model protected var _userList:UserList; protected var _presentationList:PresentationList; protected var _recording:Boolean; + protected var _pollModel:PollModel; protected var _guestSignal:ISignal = new Signal(); protected var _successJoiningMeetingSignal:ISignal = new Signal(); @@ -35,6 +37,14 @@ package org.bigbluebutton.model protected var _recordingStatusChangedSignal:ISignal = new Signal(); protected var _logoutSignal:Signal = new Signal(); + + public function UserSession() + { + _userList = new UserList(); + _presentationList = new PresentationList(); + _pollModel = new PollModel(); + } + public function get userList():UserList { return _userList; @@ -110,18 +120,16 @@ package org.bigbluebutton.model { _deskshareConnection = value; } - - public function UserSession() - { - _userList = new UserList(); - _presentationList = new PresentationList(); - } public function get presentationList():PresentationList { return _presentationList } + public function get pollModel():PollModel { + return _pollModel; + } + public function get guestSignal():ISignal { return _guestSignal; diff --git a/src/org/bigbluebutton/model/polling/Poll.as b/src/org/bigbluebutton/model/polling/Poll.as new file mode 100644 index 0000000..c7fa902 --- /dev/null +++ b/src/org/bigbluebutton/model/polling/Poll.as @@ -0,0 +1,96 @@ +package org.bigbluebutton.model.polling +{ + public class Poll + { + private var _id:String; + private var _title:String; + private var _questions:Array; + + private var _started:Boolean = false; + private var _stopped:Boolean = false; + + private var _startedOn:Date; + private var _stoppedOn:Date; + private var _durationInMinutes:int = 5; + + private var _hasResponded:Boolean = false; + + public function Poll(id:String, title:String, questions:Array, started:Boolean, stopped:Boolean) { + _id = id; + _title = title; + _questions = questions; + _started = started; + _stopped = stopped; + } + + public function get id():String { + return _id; + } + + public function get title():String { + return _title; + } + + public function get questions():Array { + return _questions; + } + + public function get started():Boolean { + return _started; + } + + public function get stopped():Boolean { + return _stopped; + } + + public function get duration():int { + return _durationInMinutes; + } + + public function start():void { + _started = true; + _startedOn = new Date(); + } + + public function stop():void { + _stopped = true; + _stoppedOn = new Date(); + } + + public function timeRemainingInSeconds():int { + var timeRemainingInSeconds:Number = (_durationInMinutes * 60) - (new Date().time - _startedOn.time) / 1000; + if(timeRemainingInSeconds <= 0) { + return 0; + } + else { + return timeRemainingInSeconds; + } + } + + private function getQuestion(questionID:String):Question { + for (var i:int = 0; i < _questions.length; i++) { + var q:Question = _questions[i] as Question; + if(q && q.id == questionID) { + return q; + } + } + + return null; + } + + public function updateResults(questionID:String, responseID:String, responder:Responder):void { + var q:Question = getQuestion(questionID); + if(q) { + q.updateResult(responseID, responder); + } + } + + public function userResponded():void { + _hasResponded = true; + } + + public function get hasResponded():Boolean { + return _hasResponded; + } + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/model/polling/PollModel.as b/src/org/bigbluebutton/model/polling/PollModel.as new file mode 100644 index 0000000..ecf3d57 --- /dev/null +++ b/src/org/bigbluebutton/model/polling/PollModel.as @@ -0,0 +1,132 @@ +package org.bigbluebutton.model.polling +{ + import mx.collections.ArrayCollection; + + import org.osflash.signals.ISignal; + import org.osflash.signals.Signal; + + public class PollModel + { + public static const POLL_CREATED:int = 0; + public static const POLL_DESTROYED:int = 1; + public static const POLL_STARTED:int = 2; + public static const POLL_STOPPED:int = 3; + public static const POLL_UPDATED:int = 4; + public static const POLL_RESULTS_UPDATED:int = 5; + public static const I_RESPONDED_TO_POLL:int = 6; + + public var pollsChangedSignal:ISignal = new Signal(); + public var responseToPollSignal:ISignal = new Signal(); + + private var _polls:ArrayCollection; + + public function PollModel() { + _polls = new ArrayCollection(); + } + + public function get Polls():ArrayCollection { + return _polls; + } + + public function createPoll(poll:Poll):void { + if(poll && !hasPoll(poll.id)) { + _polls.addItem(poll); + } + + pollsChangedSignal.dispatch(POLL_CREATED, poll.id); + } + + public function destroyPoll(pollID:String):void { + if(hasPoll(pollID)) { + _polls.removeItemAt(getPollIndex(pollID)); + } + + pollsChangedSignal.dispatch(POLL_DESTROYED, pollID); + } + + public function startPoll(pollID:String):void { + if(hasPoll(pollID)) { + var poll:Poll = getPoll(pollID); + poll.start(); + } + + pollsChangedSignal.dispatch(POLL_STARTED, pollID); + } + + public function stopPoll(pollID:String):void { + if(hasPoll(pollID)) { + var poll:Poll = getPoll(pollID); + poll.stop(); + } + + pollsChangedSignal.dispatch(POLL_STOPPED, pollID); + } + + public function updatePoll(poll:Poll):void { + if(hasPoll(poll.id)) { + _polls.removeItemAt(getPollIndex(poll.id)); + _polls.addItem(poll); + } + + pollsChangedSignal.dispatch(POLL_UPDATED, poll.id); + } + + public function updateResults(pollID:String, questionID:String, responseID:String, responder:Responder):void { + if(hasPoll(pollID)) { + var poll:Poll = getPoll(pollID); + poll.updateResults(questionID, responseID, responder); + } + + responseToPollSignal.dispatch(pollID, questionID, responseID); + } + + public function getPoll(pollID:String):Poll { + if(hasPoll(pollID)) { + return _polls.getItemAt(getPollIndex(pollID)) as Poll; + } + return null; + } + + private function getPollIndex(pollID:String):int { + for(var i:int = 0; i < _polls.length; i++) { + var p:Poll = _polls.getItemAt(i) as Poll; + if(p && p.id == pollID) { + return i; + } + } + return -1; + } + + public function hasPoll(pollID:String):Boolean { + for(var i:int = 0; i < _polls.length; i++) { + var p:Poll = _polls.getItemAt(i) as Poll; + if(p && p.id == pollID) { + return true; + } + } + return false; + } + + public function userHasResponded(pollID:String):void { + for(var i:int = 0; i < _polls.length; i++) { + var p:Poll = _polls.getItemAt(i) as Poll; + if(p && p.id == pollID) { + p.userResponded(); + } + } + + pollsChangedSignal.dispatch(I_RESPONDED_TO_POLL, pollID); + } + + public function hasUserResponded(pollID:String):Boolean { + for(var i:int = 0; i < _polls.length; i++) { + var p:Poll = _polls.getItemAt(i) as Poll; + if(p && p.id == pollID) { + return p.hasResponded; + } + } + return false; + } + + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/model/polling/Question.as b/src/org/bigbluebutton/model/polling/Question.as new file mode 100644 index 0000000..6b12060 --- /dev/null +++ b/src/org/bigbluebutton/model/polling/Question.as @@ -0,0 +1,43 @@ +package org.bigbluebutton.model.polling +{ + public class Question + { + private var _id: String; + private var _multiResponse:Boolean; + private var _question:String; + private var _responses:Array; + + public function Question(id:String, multiResponse:Boolean, question:String, responses:Array) { + _id = id; + _multiResponse = multiResponse; + _question = question; + _responses = responses; + } + + public function get id():String { + return _id; + } + + public function get multiResponse():Boolean { + return _multiResponse; + } + + public function get question():String { + return _question; + } + + public function get responses():Array { + return _responses; + } + + public function updateResult(responseID:String, responder:Responder):void { + for(var i:int = 0; i < _responses.length; i++) { + var r:Response = _responses[i] as Response; + if(r && r.id == responseID) { + r.addResponder(responder); + } + } + } + + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/model/polling/Responder.as b/src/org/bigbluebutton/model/polling/Responder.as new file mode 100644 index 0000000..86e4cf4 --- /dev/null +++ b/src/org/bigbluebutton/model/polling/Responder.as @@ -0,0 +1,21 @@ +package org.bigbluebutton.model.polling +{ + public class Responder + { + private var _userID:String; + private var _username:String; + + public function Responder(userID:String, username:String) { + _userID = userID; + _username = username; + } + + public function get userID():String { + return _userID; + } + + public function get username():String { + return _username; + } + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/model/polling/Response.as b/src/org/bigbluebutton/model/polling/Response.as new file mode 100644 index 0000000..fec85eb --- /dev/null +++ b/src/org/bigbluebutton/model/polling/Response.as @@ -0,0 +1,31 @@ +package org.bigbluebutton.model.polling +{ + public class Response + { + private var _id:String; + private var _response:String; + private var _responders:Array; + + public function Response(id:String, response:String, responders:Array) { + _id = id; + _response = response; + _responders = responders; + } + + public function get id():String { + return _id; + } + + public function get response():String { + return _response; + } + + public function addResponder(r:Responder):void { + _responders.push(r); + } + + public function get numResponses():int { + return _responders.length; + } + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/model/polling/Responses.as b/src/org/bigbluebutton/model/polling/Responses.as new file mode 100644 index 0000000..cbb0c91 --- /dev/null +++ b/src/org/bigbluebutton/model/polling/Responses.as @@ -0,0 +1,21 @@ +package org.bigbluebutton.model.polling +{ + public class Responses + { + private var _questionID:String; + private var _responses:Array; + + public function Responses(questionID:String, responses:Array) { + _questionID = questionID; + _responses = responses; + } + + public function get questionID():String { + return _questionID; + } + + public function get responseIDs():Array { + return _responses; + } + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/view/navigation/PagesNavigatorViewMediator.as b/src/org/bigbluebutton/view/navigation/PagesNavigatorViewMediator.as index bce96d0..28a91cb 100644 --- a/src/org/bigbluebutton/view/navigation/PagesNavigatorViewMediator.as +++ b/src/org/bigbluebutton/view/navigation/PagesNavigatorViewMediator.as @@ -69,7 +69,13 @@ package org.bigbluebutton.view.navigation break; } } - if(pageName == PagesENUM.PARTICIPANTS || pageName == PagesENUM.PRESENTATION || pageName == PagesENUM.VIDEO_CHAT || pageName == PagesENUM.CHATROOMS) + + if(pageName == PagesENUM.PARTICIPANTS + || pageName == PagesENUM.PRESENTATION + || pageName == PagesENUM.VIDEO_CHAT + || pageName == PagesENUM.CHATROOMS + || pageName == PagesENUM.DESKSHARE + || pageName == PagesENUM.POLLS_LIST) { view.popAll(); view.pushView(PagesENUM.getClassfromName(pageName), null, null, transition); diff --git a/src/org/bigbluebutton/view/navigation/pages/PagesENUM.as b/src/org/bigbluebutton/view/navigation/pages/PagesENUM.as index 6a18fff..4908996 100644 --- a/src/org/bigbluebutton/view/navigation/pages/PagesENUM.as +++ b/src/org/bigbluebutton/view/navigation/pages/PagesENUM.as @@ -13,6 +13,9 @@ package org.bigbluebutton.view.navigation.pages import org.bigbluebutton.view.navigation.pages.userdetails.UserDetaisView; import org.bigbluebutton.view.navigation.pages.videochat.VideoChatView; import org.bigbluebutton.view.navigation.pages.deskshare.DeskshareView; + import org.bigbluebutton.view.navigation.pages.pollslist.PollsListView; + import org.bigbluebutton.view.navigation.pages.takepoll.TakePollView; + import org.bigbluebutton.view.navigation.pages.pollresults.PollResultsView; public class PagesENUM { @@ -27,6 +30,9 @@ package org.bigbluebutton.view.navigation.pages public static const SELECT_PARTICIPANT:String = "selectparticipant"; public static const DISCONNECT:String = "Disconnect"; public static const DESKSHARE:String = "Deskshare"; + public static const POLLS_LIST:String = "PollsList"; + public static const TAKE_POLL:String = "TakePoll"; + public static const POLL_RESULTS:String = "PollResults"; /** * Especials @@ -48,6 +54,9 @@ package org.bigbluebutton.view.navigation.pages dic[SELECT_PARTICIPANT] = SelectParticipantView; dic[DISCONNECT] = DisconnectPageView; dic[DESKSHARE] = DeskshareView; + dic[POLLS_LIST] = PollsListView; + dic[TAKE_POLL] = TakePollView; + dic[POLL_RESULTS] = PollResultsView; dicInitiated = true; } diff --git a/src/org/bigbluebutton/view/navigation/pages/common/MenuButtons.mxml b/src/org/bigbluebutton/view/navigation/pages/common/MenuButtons.mxml index b9d35ad..75a5151 100644 --- a/src/org/bigbluebutton/view/navigation/pages/common/MenuButtons.mxml +++ b/src/org/bigbluebutton/view/navigation/pages/common/MenuButtons.mxml @@ -18,6 +18,7 @@ + diff --git a/src/org/bigbluebutton/view/navigation/pages/common/MenuButtonsView.as b/src/org/bigbluebutton/view/navigation/pages/common/MenuButtonsView.as index a3d3aec..1b97428 100644 --- a/src/org/bigbluebutton/view/navigation/pages/common/MenuButtonsView.as +++ b/src/org/bigbluebutton/view/navigation/pages/common/MenuButtonsView.as @@ -4,6 +4,10 @@ package org.bigbluebutton.view.navigation.pages.common public class MenuButtonsView extends MenuButtons implements IMenuButtonsView { + public function get menuPollsButton():NavigationButton + { + return pollsBtn0; + } public function get menuDeskshareButton():NavigationButton { diff --git a/src/org/bigbluebutton/view/navigation/pages/common/MenuButtonsViewMediator.as b/src/org/bigbluebutton/view/navigation/pages/common/MenuButtonsViewMediator.as index aefb9c5..3ecd5a4 100644 --- a/src/org/bigbluebutton/view/navigation/pages/common/MenuButtonsViewMediator.as +++ b/src/org/bigbluebutton/view/navigation/pages/common/MenuButtonsViewMediator.as @@ -30,8 +30,15 @@ package org.bigbluebutton.view.navigation.pages.common userUISession.loadingSignal.remove(loadingFinished); view.menuDeskshareButton.visible = view.menuDeskshareButton.includeInLayout = userSession.deskshareConnection.isStreaming; userSession.deskshareConnection.isStreamingSignal.add(onDeskshareStreamChange); + userSession.pollModel.pollsChangedSignal.add(onPollChange); } } + + public function onPollChange(change:int, pollID:String):void + { + view.menuPollsButton.visible = view.menuPollsButton.includeInLayout = true; + } + /** * If we recieve signal that deskshare stream is on - include Deskshare button to the layout */ diff --git a/src/org/bigbluebutton/view/navigation/pages/pollresults/IPollResultsView.as b/src/org/bigbluebutton/view/navigation/pages/pollresults/IPollResultsView.as new file mode 100644 index 0000000..089b256 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollresults/IPollResultsView.as @@ -0,0 +1,11 @@ +package org.bigbluebutton.view.navigation.pages.pollresults +{ + import org.bigbluebutton.core.view.IView; + + import spark.components.Group; + + public interface IPollResultsView extends IView + { + function get resultsList():Group + } +} diff --git a/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsConfig.as b/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsConfig.as new file mode 100644 index 0000000..d850cb2 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsConfig.as @@ -0,0 +1,54 @@ +package org.bigbluebutton.view.navigation.pages.pollresults +{ + + import robotlegs.bender.extensions.mediatorMap.api.IMediatorMap; + import robotlegs.bender.extensions.signalCommandMap.api.ISignalCommandMap; + import robotlegs.bender.framework.api.IConfig; + import robotlegs.bender.framework.api.IInjector; + + + public class PollResultsConfig implements IConfig + { + [Inject] + public var injector: IInjector; + + [Inject] + public var mediatorMap: IMediatorMap; + + [Inject] + public var signalCommandMap: ISignalCommandMap; + + public function configure(): void + { + dependencies(); + mediators(); + signals(); + } + + /** + * Specifies all the dependencies for the feature + * that will be injected onto objects used by the + * application. + */ + private function dependencies(): void + { + + } + + /** + * Maps view mediators to views. + */ + private function mediators(): void + { + mediatorMap.map(IPollResultsView).toMediator(PollResultsViewMediator); + } + + /** + * Maps signals to commands using the signalCommandMap. + */ + private function signals(): void + { + + } + } +} diff --git a/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsView.as b/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsView.as new file mode 100644 index 0000000..9413878 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsView.as @@ -0,0 +1,19 @@ +package org.bigbluebutton.view.navigation.pages.pollresults +{ + import spark.components.Group; + + public class PollResultsView extends PollResultsViewBase implements IPollResultsView + { + public function get resultsList():Group { + return resultsList0; + } + + override protected function childrenCreated():void { + super.childrenCreated(); + } + + public function dispose():void { + + } + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsViewBase.mxml b/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsViewBase.mxml new file mode 100644 index 0000000..937f33a --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsViewBase.mxml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + diff --git a/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsViewMediator.as b/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsViewMediator.as new file mode 100644 index 0000000..6da4bbe --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollresults/PollResultsViewMediator.as @@ -0,0 +1,114 @@ +package org.bigbluebutton.view.navigation.pages.pollresults +{ + import mx.core.FlexGlobals; + import mx.resources.ResourceManager; + + import org.bigbluebutton.model.IUserSession; + import org.bigbluebutton.model.IUserUISession; + import org.bigbluebutton.model.polling.PollModel; + import org.bigbluebutton.model.polling.Question; + import org.bigbluebutton.model.polling.Response; + import org.bigbluebutton.view.navigation.pages.PagesENUM; + + import robotlegs.bender.bundles.mvcs.Mediator; + + import spark.components.Group; + + public class PollResultsViewMediator extends Mediator + { + [Inject] + public var userSession:IUserSession; + + [Inject] + public var userUISession: IUserUISession; + + [Inject] + public var view:IPollResultsView; + + private var id:String; + + override public function initialize():void { + id = userUISession.currentPageDetails.id; + + userSession.pollModel.responseToPollSignal.add(handleResponseToPoll); + userSession.pollModel.pollsChangedSignal.add(handlePollModelChanged); + + FlexGlobals.topLevelApplication.pageName.text = ResourceManager.getInstance().getString('resources', 'pollResults.title'); + + addPollResults(); + } + + private function addPollResults():void { + var questions:Array = userSession.pollModel.getPoll(id).questions; + + for(var i:int = 0; i < questions.length; i++) { + var question:Question = questions[i]; + var responseListView:ResponseListView = new ResponseListView(); + + responseListView.initialize(); + responseListView.id = question.id; + responseListView.question.text = question.question; + + var responses:Array = question.responses; + + for(var j:int = 0; j < responses.length; j++) { + var response:Response = responses[j]; + var responseView:ResponseView = new ResponseView(); + + responseView.initialize(); + responseView.id = response.id; + responseView.response.text = response.response; + responseView.numberOfResponses.text = response.numResponses.toString(); + + responseListView.responsesList.addElement(responseView); + } + view.resultsList.addElement(responseListView); + } + } + + private function handleResponseToPoll(pollID:String, questionID:String, responseID:String): void { + if(id == pollID) { + var responseListView:ResponseListView = getResponseListView(questionID); + if(responseListView) { + var responsesList:Group = responseListView.responsesList; + for(var i:int = 0; i < responsesList.numElements; i++) { + var responseView:ResponseView = responsesList.getElementAt(i) as ResponseView; + if(responseView && responseID == responseView.id) { + var temp:Number = Number(responseView.numberOfResponses.text); + temp++; + responseView.numberOfResponses.text = temp.toString(); + } + } + } + } + } + + private function getResponseListView(questionID:String):ResponseListView { + var resultsList:Group = view.resultsList; + for(var i:int = 0; i < resultsList.numElements; i++) { + var responseListView:ResponseListView = resultsList.getElementAt(i) as ResponseListView; + if(responseListView && questionID == responseListView.id) { + return responseListView; + } + } + return null; + } + + private function handlePollModelChanged(change:int, pollID:String):void { + if(change == PollModel.POLL_DESTROYED && id == pollID) { + userUISession.pushPage(PagesENUM.POLLS_LIST); + } + } + + override public function destroy():void { + super.destroy(); + + userSession.pollModel.responseToPollSignal.remove(handleResponseToPoll); + userSession.pollModel.pollsChangedSignal.remove(handlePollModelChanged); + + view.dispose(); + view = null; + } + + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/view/navigation/pages/pollresults/ResponseListView.mxml b/src/org/bigbluebutton/view/navigation/pages/pollresults/ResponseListView.mxml new file mode 100644 index 0000000..fc45990 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollresults/ResponseListView.mxml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + diff --git a/src/org/bigbluebutton/view/navigation/pages/pollresults/ResponseView.mxml b/src/org/bigbluebutton/view/navigation/pages/pollresults/ResponseView.mxml new file mode 100644 index 0000000..01149d4 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollresults/ResponseView.mxml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + diff --git a/src/org/bigbluebutton/view/navigation/pages/pollslist/IPollsListView.as b/src/org/bigbluebutton/view/navigation/pages/pollslist/IPollsListView.as new file mode 100644 index 0000000..f129032 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollslist/IPollsListView.as @@ -0,0 +1,11 @@ +package org.bigbluebutton.view.navigation.pages.pollslist +{ + import org.bigbluebutton.core.view.IView; + + import spark.components.List; + + public interface IPollsListView extends IView + { + function get list():List; + } +} diff --git a/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListConfig.as b/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListConfig.as new file mode 100644 index 0000000..9f5fda5 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListConfig.as @@ -0,0 +1,54 @@ +package org.bigbluebutton.view.navigation.pages.pollslist +{ + + import robotlegs.bender.extensions.mediatorMap.api.IMediatorMap; + import robotlegs.bender.extensions.signalCommandMap.api.ISignalCommandMap; + import robotlegs.bender.framework.api.IConfig; + import robotlegs.bender.framework.api.IInjector; + + + public class PollsListConfig implements IConfig + { + [Inject] + public var injector: IInjector; + + [Inject] + public var mediatorMap: IMediatorMap; + + [Inject] + public var signalCommandMap: ISignalCommandMap; + + public function configure(): void + { + dependencies(); + mediators(); + signals(); + } + + /** + * Specifies all the dependencies for the feature + * that will be injected onto objects used by the + * application. + */ + private function dependencies(): void + { + + } + + /** + * Maps view mediators to views. + */ + private function mediators(): void + { + mediatorMap.map(IPollsListView).toMediator(PollsListViewMediator); + } + + /** + * Maps signals to commands using the signalCommandMap. + */ + private function signals(): void + { + + } + } +} diff --git a/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListItemRenderer.mxml b/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListItemRenderer.mxml new file mode 100644 index 0000000..878ff1e --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListItemRenderer.mxml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListView.as b/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListView.as new file mode 100644 index 0000000..8cd8d88 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListView.as @@ -0,0 +1,21 @@ +package org.bigbluebutton.view.navigation.pages.pollslist +{ + + import spark.components.List; + + public class PollsListView extends PollsListViewBase implements IPollsListView + { + public function get list():List { + return pollsList; + } + + override protected function childrenCreated():void { + super.childrenCreated(); + } + + public function dispose():void { + + } + + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListViewBase.mxml b/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListViewBase.mxml new file mode 100644 index 0000000..5f0f00a --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListViewBase.mxml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + diff --git a/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListViewMediator.as b/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListViewMediator.as new file mode 100644 index 0000000..3d27e3d --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/pollslist/PollsListViewMediator.as @@ -0,0 +1,85 @@ +package org.bigbluebutton.view.navigation.pages.pollslist +{ + import mx.collections.ArrayCollection; + import mx.core.FlexGlobals; + import mx.resources.ResourceManager; + + import org.bigbluebutton.model.IUserSession; + import org.bigbluebutton.model.IUserUISession; + import org.bigbluebutton.model.polling.PollModel; + import org.bigbluebutton.view.navigation.pages.PagesENUM; + + import robotlegs.bender.bundles.mvcs.Mediator; + + import spark.components.List; + import spark.events.IndexChangeEvent; + + + public class PollsListViewMediator extends Mediator + { + [Inject] + public var userSession:IUserSession; + + [Inject] + public var userUISession: IUserUISession; + + [Inject] + public var view:IPollsListView; + + private var pollsList:List; + + private var dataProvider:ArrayCollection = new ArrayCollection(); + + override public function initialize():void { + dataProvider = userSession.pollModel.Polls; + + pollsList = view.list; + pollsList.dataProvider = dataProvider; + + userSession.pollModel.pollsChangedSignal.add(handlePollModelChanged); + pollsList.addEventListener(IndexChangeEvent.CHANGE, onIndexChangeHandler); + + FlexGlobals.topLevelApplication.pageName.text = ResourceManager.getInstance().getString('resources', 'pollsList.title'); + } + + private function onIndexChangeHandler(event:IndexChangeEvent):void { + var item:Object = dataProvider.getItemAt(event.newIndex); + if(item) { + if(!item.started) { + return; + } + else if(item.stopped || item.hasResponded) { + userUISession.pushPage(PagesENUM.POLL_RESULTS, item) + } + else { + userUISession.pushPage(PagesENUM.TAKE_POLL, item); + } + } + } + + private function handlePollModelChanged(change:int, pollID:String):void { + switch(change) { + case PollModel.POLL_CREATED: + case PollModel.POLL_DESTROYED: + case PollModel.POLL_STARTED: + case PollModel.POLL_STOPPED: + case PollModel.I_RESPONDED_TO_POLL: + dataProvider.refresh(); + break; + default: + break; + } + } + + override public function destroy():void { + super.destroy(); + + pollsList.removeEventListener(IndexChangeEvent.CHANGE, onIndexChangeHandler); + userSession.pollModel.pollsChangedSignal.remove(handlePollModelChanged); + + view.dispose(); + view = null; + } + + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/view/navigation/pages/takepoll/ITakePollView.as b/src/org/bigbluebutton/view/navigation/pages/takepoll/ITakePollView.as new file mode 100644 index 0000000..fd3d965 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/takepoll/ITakePollView.as @@ -0,0 +1,14 @@ +package org.bigbluebutton.view.navigation.pages.takepoll +{ + import org.bigbluebutton.core.view.IView; + + import spark.components.Button; + import spark.components.Group; + import spark.components.Label; + + public interface ITakePollView extends IView { + function get questionViews():Group; + function get submitButton():Button; + function get errorMessage():Label; + } +} diff --git a/src/org/bigbluebutton/view/navigation/pages/takepoll/QuestionView.mxml b/src/org/bigbluebutton/view/navigation/pages/takepoll/QuestionView.mxml new file mode 100644 index 0000000..22531ad --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/takepoll/QuestionView.mxml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollConfig.as b/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollConfig.as new file mode 100644 index 0000000..fa9b591 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollConfig.as @@ -0,0 +1,54 @@ +package org.bigbluebutton.view.navigation.pages.takepoll +{ + + import robotlegs.bender.extensions.mediatorMap.api.IMediatorMap; + import robotlegs.bender.extensions.signalCommandMap.api.ISignalCommandMap; + import robotlegs.bender.framework.api.IConfig; + import robotlegs.bender.framework.api.IInjector; + + + public class TakePollConfig implements IConfig + { + [Inject] + public var injector: IInjector; + + [Inject] + public var mediatorMap: IMediatorMap; + + [Inject] + public var signalCommandMap: ISignalCommandMap; + + public function configure(): void + { + dependencies(); + mediators(); + signals(); + } + + /** + * Specifies all the dependencies for the feature + * that will be injected onto objects used by the + * application. + */ + private function dependencies(): void + { + + } + + /** + * Maps view mediators to views. + */ + private function mediators(): void + { + mediatorMap.map(ITakePollView).toMediator(TakePollViewMediator); + } + + /** + * Maps signals to commands using the signalCommandMap. + */ + private function signals(): void + { + + } + } +} diff --git a/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollView.as b/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollView.as new file mode 100644 index 0000000..693d2dd --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollView.as @@ -0,0 +1,30 @@ +package org.bigbluebutton.view.navigation.pages.takepoll +{ + import spark.components.Button; + import spark.components.Group; + import spark.components.Label; + + public class TakePollView extends TakePollViewBase implements ITakePollView + { + override protected function childrenCreated():void { + super.childrenCreated(); + } + + public function get questionViews():Group { + return questionViewGroup; + } + + public function get submitButton():Button { + return submitButton0; + } + + public function get errorMessage():Label { + return errorMessage0; + } + + public function dispose():void { + + } + + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollViewBase.mxml b/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollViewBase.mxml new file mode 100644 index 0000000..0d89286 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollViewBase.mxml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollViewMediator.as b/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollViewMediator.as new file mode 100644 index 0000000..a301418 --- /dev/null +++ b/src/org/bigbluebutton/view/navigation/pages/takepoll/TakePollViewMediator.as @@ -0,0 +1,213 @@ +package org.bigbluebutton.view.navigation.pages.takepoll +{ + + import flash.events.MouseEvent; + + import mx.core.FlexGlobals; + import mx.resources.ResourceManager; + + import org.bigbluebutton.core.IPollService; + import org.bigbluebutton.model.IUserSession; + import org.bigbluebutton.model.IUserUISession; + import org.bigbluebutton.model.polling.Poll; + import org.bigbluebutton.model.polling.PollModel; + import org.bigbluebutton.model.polling.Question; + import org.bigbluebutton.model.polling.Responses; + import org.bigbluebutton.view.navigation.pages.PagesENUM; + + import robotlegs.bender.bundles.mvcs.Mediator; + + import spark.components.CheckBox; + import spark.components.Group; + import spark.components.RadioButton; + + + public class TakePollViewMediator extends Mediator + { + [Inject] + public var userSession:IUserSession; + + [Inject] + public var userUISession: IUserUISession; + + [Inject] + public var pollService:IPollService; + + [Inject] + public var view:ITakePollView; + + private var id:String; + private var questionViewGroup:Group; + + override public function initialize():void { + id = userUISession.currentPageDetails.id + questionViewGroup = view.questionViews; + + userSession.pollModel.pollsChangedSignal.add(handlePollModelChanged); + view.submitButton.addEventListener(MouseEvent.CLICK, onSubmit); + + FlexGlobals.topLevelApplication.pageName.text = ResourceManager.getInstance().getString('resources', 'takePoll.title'); + + addPollToView(userSession.pollModel.getPoll(id)); + } + + private function addPollToView(poll:Poll):void { + var questions:Array = poll.questions; + + for(var i:int = 0; i < questions.length; i++) { + var question:Question = questions[i]; + addQuestionToView(question.id, question.question, question.multiResponse, question.responses); + } + } + + private function addQuestionToView(questionID:String, questionText:String, multiResponse:Boolean, responses:Array):void { + var qv:QuestionView = new QuestionView(); + + qv.initialize(); + qv.id = questionID; + qv.question.text = questionText; + qv.multiResponse = multiResponse; + + if(multiResponse) { + for(var i:int = 0; i < responses.length; i++) { + qv.responses.addElement(buildCheckBoxFromResponse(responses[i])); + } + } + else { + for(var j:int = 0; j < responses.length; j++) { + qv.responses.addElement(buildRadioButtonFromResponse(responses[j])); + } + } + + questionViewGroup.addElement(qv); + } + + private function buildCheckBoxFromResponse(response:Object):CheckBox { + var checkBox:CheckBox = new CheckBox(); + checkBox.id = response.id; + checkBox.label = response.response; + checkBox.percentWidth = 100; + return checkBox; + } + + private function buildRadioButtonFromResponse(response:Object):RadioButton { + var radioButton:RadioButton = new RadioButton(); + radioButton.id = response.id; + radioButton.label = response.response; + radioButton.percentWidth = 100; + return radioButton; + } + + private function onSubmit(event:MouseEvent):void { + var questionResponseArray:Array = new Array(); + + for(var i:int = 0; i < questionViewGroup.numElements; i++) { + var q:QuestionView = questionViewGroup.getElementAt(i) as QuestionView; + + if(q) { + if(q.multiResponse) { + var cb_responses:Array = getCheckBoxResponses(q.responses); + if(cb_responses.length == 0) { // User did not respond + view.errorMessage.visible = true; + return; + } + questionResponseArray.push(new Responses(q.id, cb_responses)); + } + else { + var rb_responses:Array = getRadioButtonResponses(q.responses); + if(rb_responses.length == 0) { // User did not respond + view.errorMessage.visible = true; + return; + } + questionResponseArray.push(new Responses(q.id, rb_responses)); + } + } + } + + view.submitButton.enabled = false; + pollService.respondPoll(id, questionResponseArray); + userSession.pollModel.userHasResponded(id); + } + + private function getCheckBoxResponses(groupOfCheckBoxes:Group):Array { + var responses:Array = new Array(); + + for(var j:int = 0; j < groupOfCheckBoxes.numElements; j++) { + var cb:CheckBox = groupOfCheckBoxes.getElementAt(j) as CheckBox; + if(cb && cb.selected) { + responses.push(cb.id); + } + } + + return responses; + } + + private function getRadioButtonResponses(groupOfRadioButton:Group):Array { + var responses:Array = new Array(); + + for(var i:int = 0; i < groupOfRadioButton.numElements; i++) { + var rb:RadioButton = groupOfRadioButton.getElementAt(i) as RadioButton; + if(rb && rb.selected) { + responses.push(rb.id); + } + } + + return responses; + } + + private function handlePollModelChanged(change:int, pollID:String):void { + switch(change) { + case PollModel.POLL_DESTROYED: + handlePollDestroyed(pollID); + break; + case PollModel.POLL_STOPPED: + handlePollStopped(pollID); + break; + case PollModel.POLL_UPDATED: + handlePollUpdated(pollID); + break; + case PollModel.I_RESPONDED_TO_POLL: + handleIRespondedToPoll(pollID); + break; + default: + break; + } + } + + private function handlePollDestroyed(pollID:String):void { + if(id == pollID) { + userUISession.popPage(); + } + } + + private function handlePollStopped(pollID:String):void { + if(id == pollID) { + userUISession.popPage(); + } + } + + private function handlePollUpdated(pollID:String):void { + if(id == pollID) { + questionViewGroup.removeAllElements(); + addPollToView(userSession.pollModel.getPoll(pollID)); + } + } + + private function handleIRespondedToPoll(pollID:String):void { + if(id == pollID) { + userUISession.pushPage(PagesENUM.POLL_RESULTS, {id: id}); + } + } + + override public function destroy():void { + super.destroy(); + + userSession.pollModel.pollsChangedSignal.remove(handlePollModelChanged); + view.submitButton.removeEventListener(MouseEvent.CLICK, onSubmit); + + view.dispose(); + view = null; + } + + } +} \ No newline at end of file diff --git a/src/org/bigbluebutton/view/skins/CheckBoxSkin.mxml b/src/org/bigbluebutton/view/skins/CheckBoxSkin.mxml new file mode 100644 index 0000000..2348cdb --- /dev/null +++ b/src/org/bigbluebutton/view/skins/CheckBoxSkin.mxml @@ -0,0 +1,163 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/org/bigbluebutton/view/skins/RadioButtonSkin.mxml b/src/org/bigbluebutton/view/skins/RadioButtonSkin.mxml index bd367fd..e5b0722 100644 --- a/src/org/bigbluebutton/view/skins/RadioButtonSkin.mxml +++ b/src/org/bigbluebutton/view/skins/RadioButtonSkin.mxml @@ -132,8 +132,8 @@ in accordance with the terms of the license agreement accompanying it. + left="{hostComponent.getStyle('width')}" textAlign="left" verticalCenter="2" fontWeight="normal" />