Merge pull request #5098 from capilkey/update-air-2.1

First pass at chat in the AIR client for 2.1
This commit is contained in:
Fred Dixon 2018-02-05 20:22:15 -05:00 committed by GitHub
commit 799d17c7cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 578 additions and 297 deletions

View File

@ -11,7 +11,7 @@
@namespace lock "org.bigbluebutton.lib.settings.views.lock.*";
@namespace camera "org.bigbluebutton.lib.settings.views.camera.*";
@font-face {
@font-face {
src : url("../../shared/assets/fonts/SourceSansPro/SourceSansPro-Regular.ttf");
fontFamily : SourceSansPro;
fontStyle : normal;
@ -19,7 +19,7 @@
embedAsCFF : true;
}
@font-face {
@font-face {
src : url("../../shared/assets/fonts/SourceSansPro/SourceSansPro-Semibold.ttf");
fontFamily : SourceSansPro;
fontStyle : normal;
@ -27,7 +27,7 @@
embedAsCFF : true;
}
@font-face {
@font-face {
src : url("../../shared/assets/fonts/SourceSansPro/SourceSansPro-Italic.ttf");
fontFamily : SourceSansPro;
fontStyle : italic;
@ -35,7 +35,7 @@
embedAsCFF : true;
}
@font-face {
@font-face {
src : url("../../shared/assets/fonts/SourceSansPro/SourceSansPro-Bold.ttf");
fontFamily : SourceSansPro;
fontStyle : normal;
@ -43,7 +43,7 @@
embedAsCFF : true;
}
@font-face {
@font-face {
src : url("../../shared/assets/fonts/SourceSansPro/SourceSansPro-Regular.ttf");
fontFamily : SourceSansProMX;
fontStyle : normal;
@ -51,6 +51,29 @@
embedAsCFF : false;
}
@font-face {
src : url("../../shared/assets/fonts/SourceSansPro/SourceSansPro-Semibold.ttf");
fontFamily : SourceSansProMX;
fontStyle : normal;
fontWeight : bold;
embedAsCFF : false;
}
@font-face {
src : url("../../shared/assets/fonts/SourceSansPro/SourceSansPro-Italic.ttf");
fontFamily : SourceSansProMX;
fontStyle : italic;
fontWeight : normal;
embedAsCFF : false;
}
@font-face {
src : url("../../shared/assets/fonts/SourceSansPro/SourceSansPro-Bold.ttf");
fontFamily : SourceSansProMX;
fontStyle : normal;
fontWeight : heavy;
embedAsCFF : false;
}
/* Shared styles */
@ -64,6 +87,10 @@ s|Application {
backgroundColor : PropertyReference("bbbBlack");
}
s|Button {
fontFamily : SourceSansProMX;
}
/* Loading screen */
main|LoadingScreen {
color : PropertyReference("white");
@ -196,6 +223,7 @@ settings|SettingsItemRenderer {
}
.menuButton {
fontFamily : SourceSansPro;
backgroundColor : PropertyReference("bbbBlue");
selectedBackgroundColor : PropertyReference("bbbGrey");
color : PropertyReference("white");

16
clients/flash/air-client/src/css/hdpi.css Normal file → Executable file
View File

@ -12,6 +12,8 @@
@namespace users "org.bigbluebutton.lib.user.views.*";
@namespace usersAIR "org.bigbluebutton.air.users.views.*";
@namespace settings "org.bigbluebutton.lib.settings.views.*";
@namespace audio "org.bigbluebutton.lib.settings.views.audio.*";
@ -57,10 +59,12 @@
}
libChat|ChatItemRenderer {
padding: 22.50;
fontSize: 25.50;
nameFontSize: 25.50;
timeFontSize: 18.00;
padding: 10.50;
gap: 6.00;
leftIndent: 33.00;
fontSize: 21.00;
nameFontSize: 21.00;
timeFontSize: 21.00;
}
settings|SettingsViewBase, camera|CameraSettingsViewBase {
@ -70,6 +74,10 @@
audio|AudioSettingsViewBase, chat|ChatSettingsViewBase, lock|LockSettingsViewBase {
padding: 22.50;
}
usersAIR|UserDetailsView {
groupsPadding : 15.00;
}
settings|SettingsItemRenderer {
fontSize: 25.50;

16
clients/flash/air-client/src/css/ldpi.css Normal file → Executable file
View File

@ -12,6 +12,8 @@
@namespace users "org.bigbluebutton.lib.user.views.*";
@namespace usersAIR "org.bigbluebutton.air.users.views.*";
@namespace settings "org.bigbluebutton.lib.settings.views.*";
@namespace audio "org.bigbluebutton.lib.settings.views.audio.*";
@ -57,10 +59,12 @@
}
libChat|ChatItemRenderer {
padding: 11.250;
fontSize: 12.750;
nameFontSize: 12.750;
timeFontSize: 9.000;
padding: 5.25;
gap: 3.00;
leftIndent: 16.50;
fontSize: 10.50;
nameFontSize: 10.50;
timeFontSize: 10.50;
}
settings|SettingsViewBase, camera|CameraSettingsViewBase {
@ -70,6 +74,10 @@
audio|AudioSettingsViewBase, chat|ChatSettingsViewBase, lock|LockSettingsViewBase {
padding: 11.250;
}
usersAIR|UserDetailsView {
groupsPadding : 7.500;
}
settings|SettingsItemRenderer {
fontSize: 12.750;

16
clients/flash/air-client/src/css/mdpi.css Normal file → Executable file
View File

@ -12,6 +12,8 @@
@namespace users "org.bigbluebutton.lib.user.views.*";
@namespace usersAIR "org.bigbluebutton.air.users.views.*";
@namespace settings "org.bigbluebutton.lib.settings.views.*";
@namespace audio "org.bigbluebutton.lib.settings.views.audio.*";
@ -57,10 +59,12 @@
}
libChat|ChatItemRenderer {
padding: 15.0;
fontSize: 17.0;
nameFontSize: 17.0;
timeFontSize: 12.0;
padding: 7.00;
gap: 4.00;
leftIndent: 22.00;
fontSize: 14.00;
nameFontSize: 14.00;
timeFontSize: 14.00;
}
settings|SettingsViewBase, camera|CameraSettingsViewBase {
@ -70,6 +74,10 @@
audio|AudioSettingsViewBase, chat|ChatSettingsViewBase, lock|LockSettingsViewBase {
padding: 15.0;
}
usersAIR|UserDetailsView {
groupsPadding : 10;
}
settings|SettingsItemRenderer {
fontSize: 17.0;

View File

@ -47,12 +47,24 @@
}
libChat|ChatItemRenderer {
padding : 30;
fontSize : 34;
nameFontSize : 34;
timeFontSize : 24;
padding : 14;
gap : 8;
leftIndent : 44;
fontSize : 28;
nameFontSize : 28;
timeFontSize : 28;
}
libChat|ChatItemRenderer {
padding: 10.00;
gap: 6.00;
leftIndent: 33.00;
fontSize: 21.00;
nameFontSize: 21.00;
timeFontSize: 21.00;
}
settings|SettingsViewBase, camera|CameraSettingsViewBase {
groupsPadding : 40;
}
@ -62,7 +74,7 @@
}
usersAIR|UserDetailsView {
groupsPadding : 40;
groupsPadding : 20;
}
settings|SettingsItemRenderer {

16
clients/flash/air-client/src/css/xxhdpi.css Normal file → Executable file
View File

@ -12,6 +12,8 @@
@namespace users "org.bigbluebutton.lib.user.views.*";
@namespace usersAIR "org.bigbluebutton.air.users.views.*";
@namespace settings "org.bigbluebutton.lib.settings.views.*";
@namespace audio "org.bigbluebutton.lib.settings.views.audio.*";
@ -57,10 +59,12 @@
}
libChat|ChatItemRenderer {
padding: 45.0;
fontSize: 51.0;
nameFontSize: 51.0;
timeFontSize: 36.0;
padding: 21.00;
gap: 12.00;
leftIndent: 66.00;
fontSize: 42.00;
nameFontSize: 42.00;
timeFontSize: 42.00;
}
settings|SettingsViewBase, camera|CameraSettingsViewBase {
@ -70,6 +74,10 @@
audio|AudioSettingsViewBase, chat|ChatSettingsViewBase, lock|LockSettingsViewBase {
padding: 45.0;
}
usersAIR|UserDetailsView {
groupsPadding : 30.0;
}
settings|SettingsItemRenderer {
fontSize: 51.0;

16
clients/flash/air-client/src/css/xxxhdpi.css Normal file → Executable file
View File

@ -12,6 +12,8 @@
@namespace users "org.bigbluebutton.lib.user.views.*";
@namespace usersAIR "org.bigbluebutton.air.users.views.*";
@namespace settings "org.bigbluebutton.lib.settings.views.*";
@namespace audio "org.bigbluebutton.lib.settings.views.audio.*";
@ -57,10 +59,12 @@
}
libChat|ChatItemRenderer {
padding: 60;
fontSize: 68;
nameFontSize: 68;
timeFontSize: 48;
padding: 28.00;
gap: 16.00;
leftIndent: 88.00;
fontSize: 56.00;
nameFontSize: 56.00;
timeFontSize: 56.00;
}
settings|SettingsViewBase, camera|CameraSettingsViewBase {
@ -70,6 +74,10 @@
audio|AudioSettingsViewBase, chat|ChatSettingsViewBase, lock|LockSettingsViewBase {
padding: 60;
}
usersAIR|UserDetailsView {
groupsPadding : 40;
}
settings|SettingsItemRenderer {
fontSize: 68;

View File

@ -2,12 +2,16 @@ package org.bigbluebutton.air.chat {
import org.bigbluebutton.air.chat.views.ChatRoomsMediatorAIR;
import org.bigbluebutton.air.chat.views.ChatViewMediatorAIR;
import org.bigbluebutton.lib.chat.commands.RequestGroupChatHistoryCommand;
import org.bigbluebutton.lib.chat.commands.RequestGroupChatHistorySignal;
import org.bigbluebutton.lib.chat.commands.StartPrivateChatCommand;
import org.bigbluebutton.lib.chat.commands.StartPrivateChatSignal;
import org.bigbluebutton.lib.chat.views.ChatRoomsViewBase;
import org.bigbluebutton.lib.chat.views.ChatViewBase;
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.IConfig;
public class ChatConfig implements IConfig {
@ -19,6 +23,7 @@ package org.bigbluebutton.air.chat {
public function configure():void {
mediators();
signals();
}
/**
@ -28,5 +33,10 @@ package org.bigbluebutton.air.chat {
mediatorMap.map(ChatRoomsViewBase).toMediator(ChatRoomsMediatorAIR);
mediatorMap.map(ChatViewBase).toMediator(ChatViewMediatorAIR);
}
private function signals():void {
signalCommandMap.map(RequestGroupChatHistorySignal).toCommand(RequestGroupChatHistoryCommand);
signalCommandMap.map(StartPrivateChatSignal).toCommand(StartPrivateChatCommand);
}
}
}

View File

@ -12,8 +12,7 @@ package org.bigbluebutton.air.chat.views {
override protected function onListIndexChangeEvent(e:IndexChangeEvent):void {
var item:Object = dataProvider.getItemAt(e.newIndex);
uiSession.pushPage(PageEnum.CHAT, {intId: item.userId, publicChat: item.isPublic});
//uiSession.chatInfo = new ChatRoomVO(item.userId, item.isPublic);
uiSession.pushPage(PageEnum.CHAT, {chatId: item.chatId});
}
}
}

View File

@ -1,5 +1,6 @@
package org.bigbluebutton.air.chat.views {
import org.bigbluebutton.air.main.models.IUISession;
import org.bigbluebutton.lib.chat.models.GroupChat;
import org.bigbluebutton.lib.chat.views.ChatViewMediatorBase;
import org.bigbluebutton.lib.user.models.User2x;
@ -13,17 +14,9 @@ package org.bigbluebutton.air.chat.views {
var data:Object = uiSession.currentPageDetails;
if (data.publicChat) {
_user = null;
_publicChat = true;
openChat(chatMessagesSession.publicConversation);
} else {
var user:User2x = meetingData.users.getUser(data.intId);
_publicChat = false;
if (user != null) {
_user = user;
openChat(chatMessagesSession.getPrivateMessages(user.intId, user.name));
}
var chat:GroupChat = chatMessagesSession.getGroupByChatId(data.chatId);
if (chat) {
openChat(chat);
}
}
}

View File

@ -3,6 +3,8 @@ package org.bigbluebutton.air.main.views {
import org.bigbluebutton.air.common.PageEnum;
import org.bigbluebutton.air.main.models.IUISession;
import org.bigbluebutton.lib.chat.models.GroupChat;
import org.bigbluebutton.lib.chat.models.IChatMessagesSession;
import org.bigbluebutton.lib.main.views.TopToolbarMediatorBase;
import org.bigbluebutton.lib.user.models.User2x;
@ -11,16 +13,17 @@ package org.bigbluebutton.air.main.views {
[Inject]
public var uiSession:IUISession;
[Inject]
public var chatMessagesSession:IChatMessagesSession;
override protected function setTitle():void {
if (uiSession.currentPage == PageEnum.CHAT) {
var chatData:Object = uiSession.currentPageDetails;
if (chatData != null) {
if (chatData.publicChat) {
view.titleLabel.text = "Public Chat";
} else {
var userC:User2x = meetingData.users.getUser(chatData.intId);
view.titleLabel.text = userC.name;
var chat:GroupChat = chatMessagesSession.getGroupByChatId(chatData.chatId);
if (chat != null) {
view.titleLabel.text = chat.name;
}
}
} else if (uiSession.currentPage == PageEnum.PARTICIPANTS) {

View File

@ -136,7 +136,7 @@ package org.bigbluebutton.air.users.views {
sGroup.addElement(_clearStatusButton);
_makePresenterButton = new Button();
_makePresenterButton.percentWidth
_makePresenterButton.percentWidth = 90;
_makePresenterButton.label= "Make Presenter"; //{resourceManager.getString('resources', 'userDetail.presenterBtn.text')}"
_makePresenterButton.styleName="userSettingsButton logoutButton contentFontSize";
sGroup.addElement(_makePresenterButton);

View File

@ -6,6 +6,7 @@ package org.bigbluebutton.air.users.views {
import org.bigbluebutton.air.common.TransitionAnimationEnum;
import org.bigbluebutton.air.main.models.IUISession;
import org.bigbluebutton.air.users.views.models.UserDetailsVM;
import org.bigbluebutton.lib.chat.commands.StartPrivateChatSignal;
import org.bigbluebutton.lib.main.commands.ClearUserStatusSignal;
import org.bigbluebutton.lib.main.commands.LockUserSignal;
import org.bigbluebutton.lib.main.commands.PresenterSignal;
@ -15,7 +16,7 @@ package org.bigbluebutton.air.users.views {
import org.bigbluebutton.lib.user.models.UserChangeEnum;
import org.bigbluebutton.lib.user.models.UserRole;
import robotlegs.bender.bundles.mvcs.Mediator;
import robotlegs.bender.bundles.mvcs.Mediator;
public class UserDetailsViewMediator extends Mediator {
@ -28,6 +29,9 @@ package org.bigbluebutton.air.users.views {
[Inject]
public var userUISession:IUISession;
[Inject]
public var startPrivateChatSignal:StartPrivateChatSignal;
[Inject]
public var clearUserStatusSignal:ClearUserStatusSignal;
@ -86,7 +90,8 @@ package org.bigbluebutton.air.users.views {
}
protected function onShowPrivateChatButton(event:MouseEvent):void {
userUISession.pushPage(PageEnum.CHAT, {publicChat: false, intId: _user.intId}, TransitionAnimationEnum.APPEAR);
startPrivateChatSignal.dispatch(_user.intId);
userUISession.popPage();
}
protected function onClearStatusButton(event:MouseEvent):void {

View File

@ -0,0 +1,18 @@
package org.bigbluebutton.lib.chat.commands {
import org.bigbluebutton.lib.chat.services.IChatMessageService;
import robotlegs.bender.bundles.mvcs.Command;
public class RequestGroupChatHistoryCommand extends Command {
[Inject]
public var chatService:IChatMessageService;
[Inject]
public var chatId:String;
override public function execute():void {
chatService.getGroupChatHistory(chatId);
}
}
}

View File

@ -0,0 +1,9 @@
package org.bigbluebutton.lib.chat.commands {
import org.osflash.signals.Signal;
public class RequestGroupChatHistorySignal extends Signal {
public function RequestGroupChatHistorySignal() {
super(String);
}
}
}

View File

@ -0,0 +1,31 @@
package org.bigbluebutton.lib.chat.commands {
import org.bigbluebutton.lib.chat.models.GroupChat;
import org.bigbluebutton.lib.chat.services.IChatMessageService;
import org.bigbluebutton.lib.main.models.IMeetingData;
import org.bigbluebutton.lib.main.models.IUserSession;
import org.bigbluebutton.lib.user.models.User2x;
import robotlegs.bender.bundles.mvcs.Command;
public class StartPrivateChatCommand extends Command {
[Inject]
public var chatService:IChatMessageService;
[Inject]
public var userSession:IUserSession;
[Inject]
public var meetingData:IMeetingData;
[Inject]
public var userId:String;
override public function execute():void {
var user:User2x = meetingData.users.getUser(userId);
if (user) {
chatService.createGroupChat(user.name, false, [userId]);
}
}
}
}

View File

@ -0,0 +1,9 @@
package org.bigbluebutton.lib.chat.commands {
import org.osflash.signals.Signal;
public class StartPrivateChatSignal extends Signal {
public function StartPrivateChatSignal() {
super(String);
}
}
}

View File

@ -3,20 +3,20 @@ package org.bigbluebutton.lib.chat.models {
[Bindable]
public class ChatMessage {
public var lastSenderId:String;
public var senderId:String;
public var senderColor:uint;
public var color:uint;
public var name:String;
public var time:String;
public var lastTime:String;
public var message:String;
public var sameSender:Boolean;
public var sameTime:Boolean;
// Stores the time (millis) when the sender sent the message.
public var fromTime:Number;

View File

@ -1,7 +1,6 @@
package org.bigbluebutton.lib.chat.models {
public class ChatMessageVO {
// The sender
public var fromUserId:String;
public var fromUsername:String;
@ -11,15 +10,5 @@ package org.bigbluebutton.lib.chat.models {
public var fromTime:Number;
public var message:String;
public function toObj():Object {
var m:Object = new Object();
m.fromUserId = fromUserId;
m.fromUsername = fromUsername;
m.fromColor = fromColor;
m.fromTime = fromTime;
m.message = message;
return m;
}
}
}

View File

@ -2,78 +2,102 @@ package org.bigbluebutton.lib.chat.models {
import mx.collections.ArrayCollection;
import org.bigbluebutton.lib.chat.commands.RequestGroupChatHistorySignal;
import org.bigbluebutton.lib.main.models.IUserSession;
public class ChatMessagesSession implements IChatMessagesSession {
private var _chats:ArrayCollection;
private static const DEFAULT_CHAT_ID:String = "MAIN-PUBLIC-GROUP-CHAT";
[Inject]
public var userSession:IUserSession;
[Inject]
public var requestChatHistorySignal:RequestGroupChatHistorySignal;
[Bindable]
public function get chats():ArrayCollection {
return _chats;
}
public function set chats(val:ArrayCollection):void {
_chats = val;
}
public function get publicConversation():Conversation {
return _chats[0];
}
public var chats:ArrayCollection;
public function ChatMessagesSession():void {
_chats = new ArrayCollection();
_chats.addItem(new Conversation("", "Public Chat", true));
chats = new ArrayCollection();
}
public function newPublicMessage(newMessage:ChatMessageVO):void {
publicConversation.newChatMessage(newMessage);
}
/**
* Create private chat for the new user
*
**/
public function addUserToPrivateMessages(userId:String, userName:String):Conversation {
var conv:Conversation = new Conversation(userId, userName, false);
_chats.addItem(conv);
public function getGroupByChatId(chatId:String):GroupChat {
for each (var chat:GroupChat in chats) {
if (chat.chatId == chatId) {
return chat;
}
}
return conv;
return null;
}
/**
* Send private messages to a specific user based on a UserId
*
* @param UserId
* @param newMessage
*/
public function newPrivateMessage(userId:String, userName:String, newMessage:ChatMessageVO):void {
if (_chats != null) {
for each (var conv:Conversation in _chats) {
if (conv.userId == userId) {
conv.newChatMessage(newMessage);
return;
}
public function getGroupByUserId(userId:String):GroupChat {
for each (var chat:GroupChat in chats) {
if (chat.partnerId == userId) {
return chat;
}
// if chat wasn't added to _privateChats colletion yet
var newConv:Conversation = addUserToPrivateMessages(userId, userName);
newConv.newChatMessage(newMessage);
}
return null;
}
public function addGroupChatsList(chatVOs:Array):void {
for each (var chat:GroupChatVO in chatVOs) {
chats.addItem(convertGroupChatVO(chat));
requestChatHistorySignal.dispatch(chat.id);
}
}
/**
* Get a private chat messages based on a UserId
*
* @param UserId
*/
public function getPrivateMessages(userId:String, userName:String):Conversation {
if (_chats != null) {
for each (var conv:Conversation in _chats) {
if (conv.userId == userId) {
return conv;
public function addMessageHistory(chatId:String, messages:Array):void {
var chat:GroupChat = getGroupByChatId(chatId);
if (chat) {
chat.addChatHistory(messages);
}
}
public function clearPublicChat(chatId:String):void {
var chatGroup:GroupChat = getGroupByChatId(chatId);
if (chatGroup) {
chatGroup.clearMessages();
}
}
public function addChatMessage(chatId:String, newMessage:ChatMessageVO):void {
var chatGroup:GroupChat = getGroupByChatId(chatId);
if (chatGroup) {
chatGroup.newChatMessage(newMessage);
}
}
public function addGroupChat(vo:GroupChatVO):void {
chats.addItem(convertGroupChatVO(vo));
}
private function convertGroupChatVO(vo:GroupChatVO):GroupChat {
var partnerId:String = "";
if (vo.access == GroupChat.PRIVATE) {
var myUserId:String = userSession.userList.me.userId;
for each (var user:GroupChatUser in vo.users) {
if (user.id != myUserId) {
partnerId = user.id;
// The name of a private chat group is supposed to be who you're chatting
// with, but it comes in relative to who created it so we need to fix the name.
vo.name = user.name;
}
}
}
// if user is not in private messages yet, add one
return addUserToPrivateMessages(userId, userName);
// Need to replace the name with a more human redable version
if (vo.id == DEFAULT_CHAT_ID) {
vo.name = "Public Chat";
}
var newGroupChat:GroupChat = new GroupChat(vo.id, vo.name, vo.access == GroupChat.PUBLIC, partnerId);
return newGroupChat;
}
}
}

View File

@ -1,64 +0,0 @@
package org.bigbluebutton.lib.chat.models {
import mx.collections.ArrayCollection;
import org.bigbluebutton.lib.chat.utils.ChatUtil;
[Bindable]
public class Conversation {
public var userId:String;
public var userName:String;
public var isPublic:Boolean;
public var messages:ArrayCollection = new ArrayCollection();
public var newMessages:Number = 0;
public function Conversation(userId:String, userName:String, isPublic:Boolean) {
this.userId = userId;
this.userName = userName;
this.isPublic = isPublic;
}
public function newChatMessage(msg:ChatMessageVO):void {
var cm:ChatMessage = new ChatMessage();
if (messages.length == 0) {
cm.lastSenderId = "";
cm.lastTime = cm.time;
} else {
cm.lastSenderId = getLastSender();
cm.lastTime = getLastTime();
}
cm.senderId = msg.fromUserId;
cm.name = msg.fromUsername;
cm.senderColor = uint(msg.fromColor);
cm.message = msg.message;
cm.fromTime = msg.fromTime;
var sentTime:Date = new Date();
sentTime.setTime(cm.fromTime);
cm.time = ChatUtil.getHours(sentTime) + ":" + ChatUtil.getMinutes(sentTime);
messages.addItem(cm);
newMessages++;
}
private function getLastSender():String {
var msg:ChatMessage = messages.getItemAt(messages.length - 1) as ChatMessage;
return msg.senderId;
}
private function getLastTime():String {
var msg:ChatMessage = messages.getItemAt(messages.length - 1) as ChatMessage;
return msg.time;
}
public function getAllMessageAsString():String {
var allText:String = "";
for (var i:int = 0; i < messages.length; i++) {
var item:ChatMessage = messages.getItemAt(i) as ChatMessage;
allText += "\n" + item.name + " - " + item.time + " : " + item.message;
}
return allText;
}
}
}

View File

@ -0,0 +1,79 @@
package org.bigbluebutton.lib.chat.models {
import mx.collections.ArrayCollection;
import org.bigbluebutton.lib.chat.utils.ChatUtil;
[Bindable]
public class GroupChat {
public static const PUBLIC:String = "PUBLIC_ACCESS";
public static const PRIVATE:String = "PRIVATE_ACCESS";
public var chatId:String;
public var name:String;
public var isPublic:Boolean;
public var partnerId:String;
public var messages:ArrayCollection = new ArrayCollection();
public var newMessages:Number = 0;
public function GroupChat(chatId:String, name:String, isPublic:Boolean, partnerId:String) {
this.chatId = chatId;
this.name = name;
this.isPublic = isPublic;
this.partnerId = partnerId;
}
public function addChatHistory(messages:Array):void {
for each (var message:ChatMessageVO in messages) {
convertAndAddChatMessage(message);
}
newMessages += messages.length;
}
public function clearMessages():void {
messages.removeAll();
}
public function newChatMessage(message:ChatMessageVO):void {
convertAndAddChatMessage(message);
newMessages++;
}
private function convertAndAddChatMessage(message:ChatMessageVO):void {
var cm:ChatMessage = new ChatMessage();
cm.senderId = message.fromUserId;
cm.name = message.fromUsername;
cm.color = uint(message.fromColor);
cm.message = message.message;
cm.fromTime = message.fromTime;
var sentTime:Date = new Date();
sentTime.setTime(cm.fromTime);
cm.time = ChatUtil.getHours(sentTime) + ":" + ChatUtil.getMinutes(sentTime);
if (messages.length == 0) {
cm.sameSender = false;
cm.sameTime = false;
} else {
var lastMessage:ChatMessage = messages.getItemAt(messages.length - 1) as ChatMessage;
cm.sameSender = cm.senderId == lastMessage.senderId;
cm.sameTime = cm.time == lastMessage.time;
}
messages.addItem(cm);
}
public function getAllMessageAsString():String {
var allText:String = "";
for (var i:int = 0; i < messages.length; i++) {
var item:ChatMessage = messages.getItemAt(i) as ChatMessage;
allText += "\n" + item.name + " - " + item.time + " : " + item.message;
}
return allText;
}
}
}

View File

@ -0,0 +1,13 @@
package org.bigbluebutton.lib.chat.models {
public class GroupChatUser {
public var id:String;
public var name:String;
public function GroupChatUser(id:String, name:String) {
this.id = id;
this.name = name;
}
}
}

View File

@ -0,0 +1,15 @@
package org.bigbluebutton.lib.chat.models {
import mx.collections.ArrayCollection;
public class GroupChatVO {
public var id:String;
public var name:String;
public var access:String;
public var createdBy:GroupChatUser;
public var users:Array;
}
}

View File

@ -4,11 +4,12 @@ package org.bigbluebutton.lib.chat.models {
public interface IChatMessagesSession {
function get chats():ArrayCollection;
function set chats(val:ArrayCollection):void;
function get publicConversation():Conversation;
function newPublicMessage(newMessage:ChatMessageVO):void;
function getPrivateMessages(userId:String, userName:String):Conversation;
function newPrivateMessage(userId:String, userName:String, newMessage:ChatMessageVO):void;
function addUserToPrivateMessages(userId:String, userName:String):Conversation;
function getGroupByChatId(chatId:String):GroupChat;
function getGroupByUserId(userId:String):GroupChat;
function addGroupChatsList(chats:Array):void;
function addMessageHistory(chatId:String, messages:Array):void;
function clearPublicChat(chatId:String):void;
function addChatMessage(chatId:String, cm:ChatMessageVO):void;
function addGroupChat(groupChat:GroupChatVO):void;
}
}

View File

@ -3,10 +3,12 @@ package org.bigbluebutton.lib.chat.services {
import mx.collections.ArrayCollection;
import org.bigbluebutton.lib.chat.models.ChatMessageVO;
import org.bigbluebutton.lib.chat.models.GroupChatUser;
import org.bigbluebutton.lib.chat.models.GroupChatVO;
import org.bigbluebutton.lib.chat.models.IChatMessagesSession;
import org.bigbluebutton.lib.common.models.IMessageListener;
import org.bigbluebutton.lib.main.models.IConferenceParameters;
import org.bigbluebutton.lib.main.models.IUserSession;
import org.bigbluebutton.lib.main.models.IUserSession;
public class ChatMessageReceiver implements IMessageListener {
private const LOG:String = "ChatMessageReceiver::";
@ -25,52 +27,101 @@ package org.bigbluebutton.lib.chat.services {
public function onMessage(messageName:String, message:Object):void {
switch (messageName) {
case "GetChatHistoryRespMsg":
handleGetChatHistoryRespMsg(message);
case "GetGroupChatsRespMsg":
handleGetGroupChatsRespMsg(message);
break;
case "SendPublicMessageEvtMsg":
handleSendPublicMessageEvtMsg(message);
case "GetGroupChatMsgsRespMsg":
handleGetGroupChatMsgsRespMsg(message);
break;
case "ClearPublicChatHistoryEvtMsg":
handleClearPublicChatHistoryEvtMsg(message);
break;
case "GroupChatMessageBroadcastEvtMsg":
handleGroupChatMessageBroadcastEvtMsg(message);
break;
case "GroupChatCreatedEvtMsg":
handleGroupChatCreatedEvtMsg(message);
break;
default:
// LogUtil.warn("Cannot handle message [" + messageName + "]");
}
}
private function handleGetChatHistoryRespMsg(msg:Object):void {
trace(LOG + "Received [GetChatHistoryRespMsg] from server.");
var messages:Array = msg.body.history as Array;
var msgCount:Number = messages.length;
private function handleGetGroupChatsRespMsg(msg:Object):void {
var body:Object = msg.body as Object;
var allChats:Array = msg.body.chats as Array;
chatMessagesSession.publicConversation.messages = new ArrayCollection();
chatMessagesSession.publicConversation.newMessages = 0; //resetNewMessages();
for (var i:int = 0; i < msgCount; i++) {
var cm:ChatMessageVO = processIncomingChatMessage(messages[i]);
chatMessagesSession.newPublicMessage(cm);
var chats:Array = new Array();
if (allChats.length > 0) {
for (var i:int = 0; i < allChats.length; i++) {
var groupChat:GroupChatVO = processGroupChat(allChats[i]);
chats.push(groupChat);
}
}
userSession.loadedMessageHistorySignal.dispatch();
chatMessagesSession.addGroupChatsList(chats);
}
private function handleSendPublicMessageEvtMsg(msg:Object):void {
trace(LOG + "Received [SendPublicMessageEvtMsg] from server.");
var cm:ChatMessageVO = processIncomingChatMessage(msg.body.message);
private function handleGetGroupChatMsgsRespMsg(msg:Object):void {
trace(LOG + "Received [GetGroupChatMsgsRespMsg] from server.");
var chatId:String = msg.body.chatId as String;
var messages:Array = msg.body.msgs as Array;
var msgCount:Number = messages.length;
var processedMessages:Array = new Array();
chatMessagesSession.newPublicMessage(cm);
for (var i:int = 0; i < msgCount; i++) {
var cm:ChatMessageVO = processChatMessage(messages[i]);
processedMessages.push(cm);
}
chatMessagesSession.addMessageHistory(chatId, processedMessages);
}
private function handleClearPublicChatHistoryEvtMsg(message:Object):void {
trace(LOG + "Received [ClearPublicChatHistoryEvtMsg] from server.");
trace("ClearPublicChatHistoryEvtMsg isn't being handled yet");
chatMessagesSession.clearPublicChat(message.body.chatId);
}
private function processIncomingChatMessage(rawMessage:Object):ChatMessageVO {
private function handleGroupChatMessageBroadcastEvtMsg(msg:Object):void {
trace(LOG + "Received [GroupChatMessageBroadcastEvtMsg] from server.");
var chatId:String = msg.body.chatId as String;
var cm:ChatMessageVO = processChatMessage(msg.body.msg);
chatMessagesSession.addChatMessage(chatId, cm);
}
private function handleGroupChatCreatedEvtMsg(msg:Object):void {
var groupChat:GroupChatVO = processGroupChat(msg.body);
chatMessagesSession.addGroupChat(groupChat);
}
private function processGroupChat(rawGroupChat:Object):GroupChatVO {
var gc:GroupChatVO = new GroupChatVO();
gc.id = rawGroupChat.hasOwnProperty("chatId") ? rawGroupChat.chatId : rawGroupChat.id;
gc.name = rawGroupChat.name as String;
gc.access = rawGroupChat.access as String;
gc.createdBy = new GroupChatUser(rawGroupChat.createdBy.id as String, rawGroupChat.createdBy.name as String);
var users:Array = rawGroupChat.users as Array;
var chatUsers:Array = new Array();
if (users.length > 0) {
for (var i:int = 0; i < users.length; i++) {
var u:Object = users[i] as Object;
chatUsers.push(new GroupChatUser(u.id, u.name));
}
}
gc.users = chatUsers;
return gc;
}
private function processChatMessage(rawMessage:Object):ChatMessageVO {
var msg:ChatMessageVO = new ChatMessageVO();
msg.fromUserId = rawMessage.fromUserId;
msg.fromUsername = rawMessage.fromUsername;
msg.fromColor = rawMessage.fromColor;
msg.fromTime = rawMessage.fromTime;
msg.fromUserId = rawMessage.sender.id;
msg.fromUsername = rawMessage.sender.name;
msg.fromColor = rawMessage.color;
msg.fromTime = rawMessage.timestamp;
msg.message = rawMessage.message;
return msg;
}

View File

@ -4,7 +4,7 @@ package org.bigbluebutton.lib.chat.services {
import org.bigbluebutton.lib.chat.utils.ChatUtil;
import org.bigbluebutton.lib.main.models.IConferenceParameters;
import org.bigbluebutton.lib.main.models.IUserSession;
import org.osflash.signals.ISignal;
import org.osflash.signals.ISignal;
public class ChatMessageSender {
private const LOG:String = "ChatMessageSender::";
@ -26,24 +26,36 @@ package org.bigbluebutton.lib.chat.services {
public function getGroupChats():void {
trace(LOG + "Sending [GetGroupChatsReqMsg] to server.");
var message:Object = {
header: {name: "GetGroupChatsReqMsg", meetingId: conferenceParameters.meetingID, userId: conferenceParameters.internalUserID},
body: {}
};
var message:Object = {header: {name: "GetGroupChatsReqMsg", meetingId: conferenceParameters.meetingID, userId: conferenceParameters.internalUserID}, body: {}};
userSession.mainConnection.sendMessage2x(defaultSuccessResponse, defaultFailureResponse, message);
}
public function sendChatMessage(chatId: String, cm:ChatMessageVO):void {
public function getGroupChatHistory(chatId:String):void {
trace("Sending [GetGroupChatMsgsReqMsg] for chatId = " + chatId);
var message:Object = {header: {name: "GetGroupChatMsgsReqMsg", meetingId: conferenceParameters.meetingID, userId: conferenceParameters.internalUserID}, body: {chatId: chatId}};
userSession.mainConnection.sendMessage2x(defaultSuccessResponse, defaultFailureResponse, message);
}
public function createGroupChat(name:String, access:String, users:Array):void {
trace("Sending [GetGroupChatMsgsReqMsg]");
var myUserId:String = conferenceParameters.internalUserID;
var now:Date = new Date();
var corrId:String = myUserId + "-" + now.time;
var message:Object = {header: {name: "CreateGroupChatReqMsg", meetingId: conferenceParameters.meetingID, userId: myUserId}, body: {correlationId: corrId, name: name, access: access, users: users, msg: []}};
userSession.mainConnection.sendMessage2x(defaultSuccessResponse, defaultFailureResponse, message);
}
public function sendChatMessage(chatId:String, cm:ChatMessageVO):void {
trace("Sending [SendGroupChatMessageMsg] to server. [{0}]", [cm.message]);
var sender:Object = {id: cm.fromUserId, name: cm.fromUsername};
var corrId: String = ChatUtil.genCorrelationId(conferenceParameters.internalUserID);
var corrId:String = ChatUtil.genCorrelationId(conferenceParameters.internalUserID);
var msgFromUser:Object = {correlationId: corrId, sender: sender, color: cm.fromColor, message: cm.message};
var message:Object = {
header: {name: "SendGroupChatMessageMsg", meetingId: conferenceParameters.meetingID, userId: conferenceParameters.internalUserID},
body: {chatId: chatId, msg: msgFromUser}
};
var message:Object = {header: {name: "SendGroupChatMessageMsg", meetingId: conferenceParameters.meetingID, userId: conferenceParameters.internalUserID}, body: {chatId: chatId, msg: msgFromUser}};
userSession.mainConnection.sendMessage2x(sendChatSuccessResponse, sendChatFailureResponse, message);
}

View File

@ -1,6 +1,8 @@
package org.bigbluebutton.lib.chat.services {
import org.bigbluebutton.lib.chat.models.ChatMessageVO;
import org.bigbluebutton.lib.chat.models.ChatMessagesSession;
import org.bigbluebutton.lib.chat.models.GroupChat;
import org.bigbluebutton.lib.chat.models.IChatMessagesSession;
import org.bigbluebutton.lib.main.models.IConferenceParameters;
import org.bigbluebutton.lib.main.models.IUserSession;
@ -47,9 +49,17 @@ package org.bigbluebutton.lib.chat.services {
chatMessageSender.getGroupChats();
}
public function sendChatMessage(message:ChatMessageVO):void {
trace("CANT SEND CHAT MESSAGE BECAUSE MISSING CHAT ID");
//chatMessageSender.sendChatMessage(message);
public function getGroupChatHistory(chatId:String):void {
chatMessageSender.getGroupChatHistory(chatId);
}
public function createGroupChat(name:String, isPublic:Boolean, users:Array):void {
var access:String = isPublic ? GroupChat.PUBLIC : GroupChat.PRIVATE;
chatMessageSender.createGroupChat(name, access, users);
}
public function sendChatMessage(chatId:String, message:ChatMessageVO):void {
chatMessageSender.sendChatMessage(chatId, message);
}
/**
@ -67,7 +77,7 @@ package org.bigbluebutton.lib.chat.services {
msg.fromTime = new Date().time;
msg.message = welcome;
// imitate new public message being sent
chatMessagesSession.newPublicMessage(msg);
chatMessagesSession.addChatMessage("MAIN-PUBLIC-GROUP-CHAT", msg);
}
}
}

View File

@ -8,7 +8,9 @@ package org.bigbluebutton.lib.chat.services {
function get sendMessageOnFailureSignal():ISignal;
function setupMessageSenderReceiver():void;
function getGroupChats():void;
function sendChatMessage(message:ChatMessageVO):void;
function getGroupChatHistory(chatId:String):void;
function createGroupChat(name:String, isPublic:Boolean, users:Array):void;
function sendChatMessage(chatId:String, message:ChatMessageVO):void;
function sendWelcomeMessage():void;
}
}

View File

@ -13,8 +13,17 @@
import org.bigbluebutton.lib.user.utils.UserUtils;
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
wrapperGroup.padding = getStyle("padding");
titleGroup.gap = getStyle("padding");
var iPadding:int = getStyle("padding");
var iGap:int = getStyle("gap");
wrapperGroup.left = iPadding;
wrapperGroup.top = iPadding;
wrapperGroup.right = iPadding;
wrapperGroup.bottom = iPadding;
messageGroup.gap = iGap;
titleGroup.gap = iGap;
messageGroup.left = getStyle("leftIndent") + iGap;
username.setStyle("color", getStyle("nameColor"));
username.setStyle("fontSize", getStyle("nameFontSize"));
@ -34,25 +43,17 @@
} else {
message.textFlow = TextConverter.importToFlow(m.message, TextConverter.TEXT_FIELD_HTML_FORMAT);
}
var sameUser:Boolean = (m.lastSenderId == m.senderId);
var sameTime:Boolean = (m.lastTime == m.time);
if (sameUser && sameTime) {
username.includeInLayout = time.includeInLayout = false;
username.visible = time.visible = false;
participantIcon.visible = false;
if (m.sameSender && m.sameTime) {
titleGroup.includeInLayout = titleGroup.visible = false;
participantIcon.visible = participantIcon.includeInLayout = false;
} else {
username.includeInLayout = time.includeInLayout = true;
username.visible = time.visible = true;
titleGroup.includeInLayout = titleGroup.visible = true;
if (m.name == " ") {
participantIcon.visible = false;
username.visible = false;
username.includeInLayout = false;
participantIcon.visible = participantIcon.includeInLayout = false;
} else {
username.text = m.name;
participantIcon.displayInitials = UserUtils.getInitials(m.name);
participantIcon.visible = true;
username.visible = true;
username.includeInLayout = true;
participantIcon.visible = participantIcon.includeInLayout = true
}
}
}
@ -72,20 +73,21 @@
]]>
</fx:Script>
<s:VGroup id="wrapperGroup"
width="100%">
<s:HGroup id="titleGroup"
width="100%"
verticalAlign="middle">
<views:ParticipantIcon id="participantIcon" />
<s:Label id="username"
visible="true" />
<s:Label id="time" />
</s:HGroup>
<s:RichEditableText id="message"
paddingLeft="{participantIcon.width + getStyle('padding')}"
editable="false"
selectable="false"
width="100%" />
</s:VGroup>
<s:Group id="wrapperGroup"
width="100%">
<views:ParticipantIcon id="participantIcon" />
<s:VGroup id="messageGroup"
width="100%">
<s:HGroup id="titleGroup"
width="100%"
verticalAlign="bottom">
<s:Label id="username" />
<s:Label id="time" />
</s:HGroup>
<s:RichEditableText id="message"
editable="false"
selectable="false"
width="100%" />
</s:VGroup>
</s:Group>
</s:ItemRenderer>

View File

@ -24,12 +24,12 @@
override public function set data(obj:Object):void {
super.data = obj;
if (obj) {
title.text = obj.userName;
title.text = obj.name;
if (obj.isPublic == true) {
publicChatIcon.visible = publicChatIcon.includeInLayout = true;
participantIcon.visible = participantIcon.includeInLayout = false;
} else {
participantIcon.displayInitials = UserUtils.getInitials(obj.userName);
participantIcon.displayInitials = UserUtils.getInitials(obj.name);
participantIcon.visible = participantIcon.includeInLayout = true;
publicChatIcon.visible = publicChatIcon.includeInLayout = false;
}

View File

@ -6,7 +6,7 @@ package org.bigbluebutton.lib.chat.views {
import mx.utils.StringUtil;
import org.bigbluebutton.lib.chat.models.ChatMessageVO;
import org.bigbluebutton.lib.chat.models.Conversation;
import org.bigbluebutton.lib.chat.models.GroupChat;
import org.bigbluebutton.lib.chat.models.IChatMessagesSession;
import org.bigbluebutton.lib.chat.services.IChatMessageService;
import org.bigbluebutton.lib.main.models.IMeetingData;
@ -29,9 +29,7 @@ package org.bigbluebutton.lib.chat.views {
[Inject]
public var meetingData:IMeetingData;
protected var _publicChat:Boolean = true;
protected var _user:User2x;
protected var _chat:GroupChat;
override public function initialize():void {
chatMessageService.sendMessageOnSuccessSignal.add(onSendSuccess);
@ -42,9 +40,10 @@ package org.bigbluebutton.lib.chat.views {
view.sendButton.addEventListener(MouseEvent.CLICK, sendButtonClickHandler);
}
protected function openChat(conv:Conversation):void {
conv.newMessages = 0; //resetNewMessages();
view.chatList.dataProvider = conv.messages;
protected function openChat(chat:GroupChat):void {
_chat = chat;
_chat.newMessages = 0; //resetNewMessages();
view.chatList.dataProvider = _chat.messages;
}
private function onSendSuccess(result:String):void {
@ -72,7 +71,7 @@ package org.bigbluebutton.lib.chat.views {
* and disable text input
*/
protected function userRemoved(user:User2x):void {
if (view != null && _user && _user.intId == user.intId) {
if (view != null && _chat && _chat.partnerId == user.intId) {
view.textInput.enabled = false;
}
}
@ -81,8 +80,8 @@ package org.bigbluebutton.lib.chat.views {
* When user returned(refreshed the page) to the conference, remove '[Offline]' from the username
* and enable text input
*/
protected function userAdded(newuser:User2x):void {
if ((view != null) && (_user != null) && (_user.intId == newuser.intId)) {
protected function userAdded(newUser:User2x):void {
if ((view != null) && (_chat != null) && (_chat.partnerId == newUser.intId)) {
view.textInput.enabled = true;
}
}
@ -108,12 +107,8 @@ package org.bigbluebutton.lib.chat.views {
m.fromTime = currentDate.time;
m.message = message;
trace ("*** sendButtonClickHandler: CANT PROCESS WITHOUT CHAT ID");
/*if (_publicChat) {
chatMessageService.sendPublicMessage(m);
} else {
chatMessageService.sendPrivateMessage(m);
}*/
chatMessageService.sendChatMessage(_chat.chatId, m);
}
}

View File

@ -101,7 +101,6 @@ package org.bigbluebutton.lib.main.commands {
usersService.setupMessageSenderReceiver();
//send the join meeting message, then wait for the response
userSession.authTokenSignal.add(onAuthTokenReply);
userSession.loadedMessageHistorySignal.add(chatService.sendWelcomeMessage);
usersService.validateToken();
connection.connectionSuccessSignal.remove(connectionSuccess);
connection.connectionFailureSignal.remove(connectionFailure);

View File

@ -38,7 +38,6 @@ package org.bigbluebutton.lib.main.models {
function get presentationList():PresentationList;
function get successJoiningMeetingSignal():ISignal;
function get failureJoiningMeetingSignal():ISignal;
function get loadedMessageHistorySignal():ISignal;
function get assignedDeskshareSignal():ISignal;
function get logoutSignal():Signal;
function get recordingStatusChangedSignal():ISignal;

View File

@ -48,8 +48,6 @@ package org.bigbluebutton.lib.main.models {
protected var _pushToTalk:Boolean;
protected var _loadedMessageHistorySignal:ISignal = new Signal();
protected var _successJoiningMeetingSignal:ISignal = new Signal();
protected var _failureJoiningMeetingSignal:ISignal = new Signal();
@ -196,10 +194,6 @@ package org.bigbluebutton.lib.main.models {
return _presentationList;
}
public function get loadedMessageHistorySignal():ISignal {
return _loadedMessageHistorySignal;
}
public function get successJoiningMeetingSignal():ISignal {
return _successJoiningMeetingSignal;
}

View File

@ -112,7 +112,8 @@ package org.bigbluebutton.lib.video.services {
public function connect():void {
trace("Video connect");
baseConnection.connect(uri, conferenceParameters.meetingID, userSession.userId);
trace("Don't connect to video yet because it needs to have auth token added");
//baseConnection.connect(uri, conferenceParameters.meetingID, userSession.userId);
}
public function disconnect(onUserCommand:Boolean):void {

View File

@ -14,9 +14,9 @@ package org.bigbluebutton.lib.whiteboard.models {
protected var _annInfo:Object;
protected var _parentWidth:Number = -1;
protected var _parentWidth:Number = 0;
protected var _parentHeight:Number = -1;
protected var _parentHeight:Number = 0;
public function Annotation(id:String, userId:String, type:String, status:String, annInfo:Object) {
_id = id;
@ -75,13 +75,15 @@ package org.bigbluebutton.lib.whiteboard.models {
if (_parentWidth != width || _parentHeight != height) {
_parentWidth = width;
_parentHeight = height;
makeGraphic();
if (_parentWidth > 0 && _parentHeight > 0) {
makeGraphic();
}
}
}
public function remove(canvas:Group):void {
_parentWidth = -1;
_parentHeight = -1;
_parentWidth = 0;
_parentHeight = 0;
}
}
}