Implemented a button to clear chat history.

New conversation joiners will not receive the history previous to the clearing.
Current conversation users will clear the local chat history and be notified that a moderator cleared the chat.

refs #1931
This commit is contained in:
RafaFP 2016-02-22 22:10:04 +00:00
parent c1024c86d3
commit 65b181198c
30 changed files with 328 additions and 19 deletions

View File

@ -106,6 +106,7 @@ public interface IBigBlueButtonInGW {
void getChatHistory(String meetingID, String requesterID, String replyTo); void getChatHistory(String meetingID, String requesterID, String replyTo);
void sendPublicMessage(String meetingID, String requesterID, Map<String, String> message); void sendPublicMessage(String meetingID, String requesterID, Map<String, String> message);
void sendPrivateMessage(String meetingID, String requesterID, Map<String, String> message); void sendPrivateMessage(String meetingID, String requesterID, Map<String, String> message);
void clearChatHistory(String meetingID, String requesterID, String replyTo);
// Whiteboard // Whiteboard
void sendWhiteboardAnnotation(String meetingID, String requesterID, java.util.Map<String, Object> annotation); void sendWhiteboardAnnotation(String meetingID, String requesterID, java.util.Map<String, Object> annotation);

View File

@ -4,6 +4,7 @@ import org.bigbluebutton.common.messages.GetChatHistoryRequestMessage;
import org.bigbluebutton.common.messages.MessagingConstants; import org.bigbluebutton.common.messages.MessagingConstants;
import org.bigbluebutton.common.messages.SendPrivateChatMessage; import org.bigbluebutton.common.messages.SendPrivateChatMessage;
import org.bigbluebutton.common.messages.SendPublicChatMessage; import org.bigbluebutton.common.messages.SendPublicChatMessage;
import org.bigbluebutton.common.messages.ClearChatHistoryRequestMessage;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
@ -36,6 +37,9 @@ public class ChatMessageReceiver implements MessageHandler{
} else if (SendPrivateChatMessage.SEND_PRIVATE_CHAT_MESSAGE.equals(messageName)){ } else if (SendPrivateChatMessage.SEND_PRIVATE_CHAT_MESSAGE.equals(messageName)){
SendPrivateChatMessage msg = SendPrivateChatMessage.fromJson(message); SendPrivateChatMessage msg = SendPrivateChatMessage.fromJson(message);
bbbGW.sendPrivateMessage(msg.meetingId, msg.requesterId, msg.messageInfo); bbbGW.sendPrivateMessage(msg.meetingId, msg.requesterId, msg.messageInfo);
} else if (ClearChatHistoryRequestMessage.CLEAR_CHAT_HISTORY_REQUEST.equals(messageName)){
ClearChatHistoryRequestMessage msg = ClearChatHistoryRequestMessage.fromJson(message);
bbbGW.clearChatHistory(msg.meetingId, msg.requesterId, msg.replyTo);
} }
} }
} }

View File

@ -363,6 +363,10 @@ class BigBlueButtonInGW(val system: ActorSystem, recorderApp: RecorderApplicatio
bbbActor ! new SendPrivateMessageRequest(meetingID, requesterID, mapAsScalaMap(message).toMap) bbbActor ! new SendPrivateMessageRequest(meetingID, requesterID, mapAsScalaMap(message).toMap)
} }
def clearChatHistory(meetingID: String, requesterID: String, replyTo: String) {
bbbActor ! new ClearChatHistoryRequest(meetingID, requesterID, replyTo)
}
/** /**
* ******************************************************************* * *******************************************************************
* Message Interface for Whiteboard * Message Interface for Whiteboard

View File

@ -103,6 +103,8 @@ class MeetingActor(val mProps: MeetingProperties, val outGW: OutMessageGateway)
handleSendPublicMessageRequest(msg) handleSendPublicMessageRequest(msg)
case msg: SendPrivateMessageRequest => case msg: SendPrivateMessageRequest =>
handleSendPrivateMessageRequest(msg) handleSendPrivateMessageRequest(msg)
case msg: ClearChatHistoryRequest =>
handleClearChatHistoryRequest(msg)
case msg: UserConnectedToGlobalAudio => case msg: UserConnectedToGlobalAudio =>
handleUserConnectedToGlobalAudio(msg) handleUserConnectedToGlobalAudio(msg)
case msg: UserDisconnectedFromGlobalAudio => case msg: UserDisconnectedFromGlobalAudio =>

View File

@ -45,6 +45,7 @@ class MessageSenderActor(val meetingId: String, val service: MessageSender)
case msg: GetChatHistoryReply => handleGetChatHistoryReply(msg) case msg: GetChatHistoryReply => handleGetChatHistoryReply(msg)
case msg: SendPublicMessageEvent => handleSendPublicMessageEvent(msg) case msg: SendPublicMessageEvent => handleSendPublicMessageEvent(msg)
case msg: SendPrivateMessageEvent => handleSendPrivateMessageEvent(msg) case msg: SendPrivateMessageEvent => handleSendPrivateMessageEvent(msg)
case msg: ClearChatHistoryReply => handleClearChatHistoryReply(msg)
case msg: MeetingCreated => handleMeetingCreated(msg) case msg: MeetingCreated => handleMeetingCreated(msg)
case msg: VoiceRecordingStarted => handleVoiceRecordingStarted(msg) case msg: VoiceRecordingStarted => handleVoiceRecordingStarted(msg)
case msg: VoiceRecordingStopped => handleVoiceRecordingStopped(msg) case msg: VoiceRecordingStopped => handleVoiceRecordingStopped(msg)
@ -146,6 +147,11 @@ class MessageSenderActor(val meetingId: String, val service: MessageSender)
service.send(MessagingConstants.FROM_CHAT_CHANNEL, json) service.send(MessagingConstants.FROM_CHAT_CHANNEL, json)
} }
private def handleClearChatHistoryReply(msg: ClearChatHistoryReply) {
val json = ChatMessageToJsonConverter.clearChatHistoryReplyToJson(msg)
service.send(MessagingConstants.FROM_CHAT_CHANNEL, json)
}
private def handleStartRecordingVoiceConf(msg: StartRecordingVoiceConf) { private def handleStartRecordingVoiceConf(msg: StartRecordingVoiceConf) {
val m = new StartRecordingVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId) val m = new StartRecordingVoiceConfRequestMessage(msg.meetingID, msg.voiceConfId)
service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson()) service.send(MessagingConstants.TO_VOICE_CONF_SYSTEM_CHAN, m.toJson())

View File

@ -47,6 +47,7 @@ case class GetRecordingStatus(meetingID: String, userId: String) extends InMessa
case class GetChatHistoryRequest(meetingID: String, requesterID: String, replyTo: String) extends InMessage case class GetChatHistoryRequest(meetingID: String, requesterID: String, replyTo: String) extends InMessage
case class SendPublicMessageRequest(meetingID: String, requesterID: String, message: Map[String, String]) extends InMessage case class SendPublicMessageRequest(meetingID: String, requesterID: String, message: Map[String, String]) extends InMessage
case class SendPrivateMessageRequest(meetingID: String, requesterID: String, message: Map[String, String]) extends InMessage case class SendPrivateMessageRequest(meetingID: String, requesterID: String, message: Map[String, String]) extends InMessage
case class ClearChatHistoryRequest(meetingID: String, requesterID: String, replyTo: String) extends InMessage
case class UserConnectedToGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String, case class UserConnectedToGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String,
userid: String, name: String) extends InMessage userid: String, name: String) extends InMessage
case class UserDisconnectedFromGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String, case class UserDisconnectedFromGlobalAudio(meetingID: String, /** Not used. Just to satisfy trait **/ voiceConf: String,

View File

@ -30,6 +30,7 @@ object MessageNames {
val GET_CHAT_HISTORY = "get_chat_history_request" val GET_CHAT_HISTORY = "get_chat_history_request"
val SEND_PUBLIC_MESSAGE = "send_public_chat_message_request" val SEND_PUBLIC_MESSAGE = "send_public_chat_message_request"
val SEND_PRIVATE_MESSAGE = "send_private_chat_message_request" val SEND_PRIVATE_MESSAGE = "send_private_chat_message_request"
val CLEAR_CHAT_HISTORY = "clear_chat_history_request"
val GET_CURRENT_LAYOUT = "get_current_layout_request" val GET_CURRENT_LAYOUT = "get_current_layout_request"
val SET_LAYOUT = "set_layout_request" val SET_LAYOUT = "set_layout_request"
val BROADCAST_LAYOUT = "broadcast_layout_request" val BROADCAST_LAYOUT = "broadcast_layout_request"
@ -128,6 +129,7 @@ object MessageNames {
val GET_CHAT_HISTORY_REPLY = "get_chat_history_reply" val GET_CHAT_HISTORY_REPLY = "get_chat_history_reply"
val SEND_PUBLIC_CHAT_MESSAGE = "send_public_chat_message" val SEND_PUBLIC_CHAT_MESSAGE = "send_public_chat_message"
val SEND_PRIVATE_CHAT_MESSAGE = "send_private_chat_message" val SEND_PRIVATE_CHAT_MESSAGE = "send_private_chat_message"
val CLEAR_CHAT_HISTORY_REPLY = "clear_chat_history_reply"
val GET_CURRENT_LAYOUT_REPLY = "get_current_layout_reply" val GET_CURRENT_LAYOUT_REPLY = "get_current_layout_reply"
val SET_LAYOUT_REPLY = "set_layout_reply" val SET_LAYOUT_REPLY = "set_layout_reply"
val BROADCAST_LAYOUT_REPLY = "broadcast_layout_reply" val BROADCAST_LAYOUT_REPLY = "broadcast_layout_reply"

View File

@ -74,6 +74,8 @@ case class SendPublicMessageEvent(meetingID: String, recorded: Boolean, requeste
message: Map[String, String]) extends IOutMessage message: Map[String, String]) extends IOutMessage
case class SendPrivateMessageEvent(meetingID: String, recorded: Boolean, requesterID: String, case class SendPrivateMessageEvent(meetingID: String, recorded: Boolean, requesterID: String,
message: Map[String, String]) extends IOutMessage message: Map[String, String]) extends IOutMessage
case class ClearChatHistoryReply(meetingID: String, recorded: Boolean, requesterID: String,
replyTo: String) extends IOutMessage
// Layout // Layout
case class GetCurrentLayoutReply(meetingID: String, recorded: Boolean, requesterID: String, layoutID: String, case class GetCurrentLayoutReply(meetingID: String, recorded: Boolean, requesterID: String, layoutID: String,

View File

@ -26,4 +26,10 @@ trait ChatApp {
val privMsg = msg.message.toMap val privMsg = msg.message.toMap
outGW.send(new SendPrivateMessageEvent(mProps.meetingID, mProps.recorded, msg.requesterID, privMsg)) outGW.send(new SendPrivateMessageEvent(mProps.meetingID, mProps.recorded, msg.requesterID, privMsg))
} }
def handleClearChatHistoryRequest(msg: ClearChatHistoryRequest) {
chatModel.clearChatHistory()
outGW.send(new ClearChatHistoryReply(mProps.meetingID, mProps.recorded, msg.requesterID, msg.replyTo))
}
} }

View File

@ -16,4 +16,8 @@ class ChatModel {
def addNewChatMessage(msg: Map[String, String]) { def addNewChatMessage(msg: Map[String, String]) {
messages append msg messages append msg
} }
def clearChatHistory() {
messages.clear();
}
} }

View File

@ -64,4 +64,13 @@ object ChatMessageToJsonConverter {
val header = Util.buildHeader(MessageNames.SEND_PRIVATE_CHAT_MESSAGE, None) val header = Util.buildHeader(MessageNames.SEND_PRIVATE_CHAT_MESSAGE, None)
Util.buildJson(header, payload) Util.buildJson(header, payload)
} }
def clearChatHistoryReplyToJson(msg: ClearChatHistoryReply): String = {
val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.REQUESTER_ID, msg.requesterID)
val header = Util.buildHeader(MessageNames.CLEAR_CHAT_HISTORY_REPLY, None)
Util.buildJson(header, payload)
}
} }

View File

@ -0,0 +1,55 @@
package org.bigbluebutton.common.messages;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class ClearChatHistoryReplyMessage implements ISubscribedMessage {
public static final String CLEAR_CHAT_HISTORY_REPLY = "clear_chat_history_reply";
public static final String VERSION = "0.0.1";
public final String meetingId;
public final String requesterId;
public ClearChatHistoryReplyMessage(String meetingId, String requesterId) {
this.meetingId = meetingId;
this.requesterId = requesterId;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(Constants.MEETING_ID, meetingId);
payload.put(Constants.REQUESTER_ID, requesterId);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(CLEAR_CHAT_HISTORY_REPLY, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static ClearChatHistoryReplyMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (CLEAR_CHAT_HISTORY_REPLY.equals(messageName)) {
if (payload.has(Constants.MEETING_ID)
&& payload.has(Constants.REQUESTER_ID)) {
String meetingId = payload.get(Constants.MEETING_ID).getAsString();
String requesterId = payload.get(Constants.REQUESTER_ID).getAsString();
return new ClearChatHistoryReplyMessage(meetingId, requesterId);
}
}
}
}
return null;
}
}

View File

@ -0,0 +1,56 @@
package org.bigbluebutton.common.messages;
import java.util.HashMap;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
public class ClearChatHistoryRequestMessage implements IBigBlueButtonMessage {
public static final String CLEAR_CHAT_HISTORY_REQUEST = "clear_chat_history_request";
public static final String VERSION = "0.0.1";
public final String meetingId;
public final String replyTo;
public final String requesterId;
public ClearChatHistoryRequestMessage(String meetingId, String requesterId, String replyTo) {
this.meetingId = meetingId;
this.replyTo = replyTo;
this.requesterId = requesterId;
}
public String toJson() {
HashMap<String, Object> payload = new HashMap<String, Object>();
payload.put(Constants.MEETING_ID, meetingId);
payload.put(Constants.REPLY_TO, replyTo);
payload.put(Constants.REQUESTER_ID, requesterId);
java.util.HashMap<String, Object> header = MessageBuilder.buildHeader(CLEAR_CHAT_HISTORY_REQUEST, VERSION, null);
return MessageBuilder.buildJson(header, payload);
}
public static ClearChatHistoryRequestMessage fromJson(String message) {
JsonParser parser = new JsonParser();
JsonObject obj = (JsonObject) parser.parse(message);
if (obj.has("header") && obj.has("payload")) {
JsonObject header = (JsonObject) obj.get("header");
JsonObject payload = (JsonObject) obj.get("payload");
if (header.has("name")) {
String messageName = header.get("name").getAsString();
if (CLEAR_CHAT_HISTORY_REQUEST.equals(messageName)) {
if (payload.has(Constants.MEETING_ID)
&& payload.has(Constants.REPLY_TO)
&& payload.has(Constants.REQUESTER_ID)) {
String meetingId = payload.get(Constants.MEETING_ID).getAsString();
String replyTo = payload.get(Constants.REPLY_TO).getAsString();
String requesterId = payload.get(Constants.REQUESTER_ID).getAsString();
return new ClearChatHistoryRequestMessage(meetingId, requesterId, replyTo);
}
}
}
}
return null;
}
}

View File

@ -6,6 +6,7 @@ import java.util.Map;
import org.bigbluebutton.common.messages.GetChatHistoryReplyMessage; import org.bigbluebutton.common.messages.GetChatHistoryReplyMessage;
import org.bigbluebutton.common.messages.SendPrivateChatMessage; import org.bigbluebutton.common.messages.SendPrivateChatMessage;
import org.bigbluebutton.common.messages.SendPublicChatMessage; import org.bigbluebutton.common.messages.SendPublicChatMessage;
import org.bigbluebutton.common.messages.ClearChatHistoryReplyMessage;
import org.bigbluebutton.red5.client.messaging.BroadcastClientMessage; import org.bigbluebutton.red5.client.messaging.BroadcastClientMessage;
import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService; import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService;
import org.bigbluebutton.red5.client.messaging.DirectClientMessage; import org.bigbluebutton.red5.client.messaging.DirectClientMessage;
@ -54,6 +55,13 @@ public class ChatClientMessageSender {
processGetChatHistoryReply(gch); processGetChatHistoryReply(gch);
} }
break; break;
case ClearChatHistoryReplyMessage.CLEAR_CHAT_HISTORY_REPLY:
ClearChatHistoryReplyMessage gcl = ClearChatHistoryReplyMessage.fromJson(message);
if (gcl != null) {
processClearChatHistoryReply(gcl);
}
break;
} }
} }
} }
@ -111,4 +119,19 @@ public class ChatClientMessageSender {
service.sendMessage(m); service.sendMessage(m);
} }
private void processClearChatHistoryReply(ClearChatHistoryReplyMessage gcl) {
Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingId", gcl.meetingId);
args.put("requester_id", gcl.requesterId);
args.put("message", "ClearChat");
Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson();
message.put("msg", gson.toJson(args.get("message")));
BroadcastClientMessage m = new BroadcastClientMessage(gcl.meetingId, "ChatClearPublicMessageCommand", message);
service.sendMessage(m);
}
} }

View File

@ -243,6 +243,10 @@ public class MessagePublisher {
sender.send(MessagingConstants.TO_CHAT_CHANNEL, msg.toJson()); sender.send(MessagingConstants.TO_CHAT_CHANNEL, msg.toJson());
} }
public void clearPublicChatMessages(String meetingID, String requesterID, String replyTo) {
ClearChatHistoryRequestMessage msg = new ClearChatHistoryRequestMessage(meetingID, requesterID, replyTo);
sender.send(MessagingConstants.TO_CHAT_CHANNEL, msg.toJson());
}
public void sendPublicMessage(String meetingID, String requesterID, Map<String, String> message) { public void sendPublicMessage(String meetingID, String requesterID, Map<String, String> message) {
SendPublicChatMessage msg = new SendPublicChatMessage(meetingID, requesterID, message); SendPublicChatMessage msg = new SendPublicChatMessage(meetingID, requesterID, message);

View File

@ -27,7 +27,7 @@ import org.bigbluebutton.red5.pubsub.MessagePublisher;
import org.red5.logging.Red5LoggerFactory; import org.red5.logging.Red5LoggerFactory;
import org.red5.server.api.Red5; import org.red5.server.api.Red5;
import org.slf4j.Logger; import org.slf4j.Logger;
public class ChatService { public class ChatService {
private static Logger log = Red5LoggerFactory.getLogger( ChatService.class, "bigbluebutton" ); private static Logger log = Red5LoggerFactory.getLogger( ChatService.class, "bigbluebutton" );
@ -43,6 +43,15 @@ public class ChatService {
red5BBBInGw.getChatHistory(meetingID, requesterID, replyTo); red5BBBInGw.getChatHistory(meetingID, requesterID, replyTo);
} }
public void clearPublicChatMessages() {
String meetingID = Red5.getConnectionLocal().getScope().getName();
String requesterID = getBbbSession().getInternalUserID();
// Just hardcode as we don't really need it for flash client. (ralam may 7, 2014)
String replyTo = meetingID + "/" + requesterID;
red5BBBInGw.clearPublicChatMessages(meetingID, requesterID, replyTo);
}
private BigBlueButtonSession getBbbSession() { private BigBlueButtonSession getBbbSession() {
return (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION); return (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION);
} }

View File

@ -93,7 +93,7 @@ DataGrid {
} }
.whiteboardUndoButtonStyle, .whiteboardCircleButtonStyle, .whiteboardClearButtonStyle, .whiteboardUndoButtonStyle, .whiteboardCircleButtonStyle, .dlearButtonStyle,
.whiteboardTriangleButtonStyle, .whiteboardTextButtonStyle, .whiteboardRectangleButtonStyle, .whiteboardTriangleButtonStyle, .whiteboardTextButtonStyle, .whiteboardRectangleButtonStyle,
.whiteboardPanZoomButtonStyle, .whiteboardLineButtonStyle, .whiteboardScribbleButtonStyle .whiteboardPanZoomButtonStyle, .whiteboardLineButtonStyle, .whiteboardScribbleButtonStyle
{ {
@ -123,7 +123,7 @@ DataGrid {
icon: Embed('assets/images/ellipse.png'); icon: Embed('assets/images/ellipse.png');
} }
.whiteboardClearButtonStyle { .dlearButtonStyle {
icon: Embed('assets/images/delete.png'); icon: Embed('assets/images/delete.png');
} }

View File

@ -209,7 +209,7 @@ DataGrid {
} }
.whiteboardUndoButtonStyle, .whiteboardCircleButtonStyle, .whiteboardClearButtonStyle, .whiteboardUndoButtonStyle, .whiteboardCircleButtonStyle, .clearButtonStyle,
.whiteboardTriangleButtonStyle, .whiteboardTextButtonStyle, .whiteboardRectangleButtonStyle, .whiteboardTriangleButtonStyle, .whiteboardTextButtonStyle, .whiteboardRectangleButtonStyle,
.whiteboardPanZoomButtonStyle, .whiteboardLineButtonStyle, .whiteboardScribbleButtonStyle .whiteboardPanZoomButtonStyle, .whiteboardLineButtonStyle, .whiteboardScribbleButtonStyle
{ {
@ -239,7 +239,7 @@ DataGrid {
icon: Embed('assets/images/ellipse.png'); icon: Embed('assets/images/ellipse.png');
} }
.whiteboardClearButtonStyle { .clearButtonStyle {
icon: Embed('assets/images/delete.png'); icon: Embed('assets/images/delete.png');
} }

View File

@ -280,6 +280,8 @@ bbb.chat.copyBtn.toolTip = Copy chat
bbb.chat.copyBtn.accessibilityName = Copy chat to clipboard bbb.chat.copyBtn.accessibilityName = Copy chat to clipboard
bbb.chat.copyBtn.label = Copy bbb.chat.copyBtn.label = Copy
bbb.chat.copy.complete = Chat copied to clipboard bbb.chat.copy.complete = Chat copied to clipboard
bbb.chat.clearBtn.toolTip = Clear chat
bbb.chat.clearBtn.accessibilityName = Clear the chat history
bbb.chat.contextmenu.copyalltext = Copy All Text bbb.chat.contextmenu.copyalltext = Copy All Text
bbb.chat.publicChatUsername = Public bbb.chat.publicChatUsername = Public
bbb.chat.optionsTabName = Options bbb.chat.optionsTabName = Options

View File

@ -281,6 +281,8 @@ bbb.chat.copyBtn.toolTip = Copiar bate-papo
bbb.chat.copyBtn.accessibilityName = Copiar bate-papo para a área de transferência bbb.chat.copyBtn.accessibilityName = Copiar bate-papo para a área de transferência
bbb.chat.copyBtn.label = Copiar bbb.chat.copyBtn.label = Copiar
bbb.chat.copy.complete = Bate-papo copiado para a área de transferência bbb.chat.copy.complete = Bate-papo copiado para a área de transferência
bbb.chat.clearBtn.toolTip = Limpar bate-papo
bbb.chat.clearBtn.accessibilityName = Limpar conteúdo do histórico do Bate-papo
bbb.chat.publicChatUsername = Público bbb.chat.publicChatUsername = Público
bbb.chat.optionsTabName = Opções bbb.chat.optionsTabName = Opções
bbb.chat.privateChatSelect = Selecione uma pessoa para um bate-papo privado bbb.chat.privateChatSelect = Selecione uma pessoa para um bate-papo privado

View File

@ -6,6 +6,7 @@ package org.bigbluebutton.modules.chat.events
{ {
public static const SAVE_CHAT_TOOLBAR_EVENT:String = "SAVE_CHAT_TOOLBAR_EVENT"; public static const SAVE_CHAT_TOOLBAR_EVENT:String = "SAVE_CHAT_TOOLBAR_EVENT";
public static const COPY_CHAT_TOOLBAR_EVENT:String = "COPY_CHAT_TOOLBAR_EVENT"; public static const COPY_CHAT_TOOLBAR_EVENT:String = "COPY_CHAT_TOOLBAR_EVENT";
public static const CLEAR_CHAT_TOOLBAR_EVENT:String = "CLEAR_CHAT_TOOLBAR_EVENT";
public function ChatToolbarButtonEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false) public function ChatToolbarButtonEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{ {

View File

@ -0,0 +1,36 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.chat.events
{
import flash.events.Event;
import org.bigbluebutton.modules.chat.vo.ChatMessageVO;
public class ClearPublicChatEvent extends Event
{
public static const CLEAR_PUBLIC_CHAT_EVENT:String = 'CLEAR_PUBLIC_CHAT_EVENT';
public function ClearPublicChatEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -33,6 +33,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.chat.events.ChatCopyEvent; import org.bigbluebutton.modules.chat.events.ChatCopyEvent;
import org.bigbluebutton.modules.chat.events.ChatEvent; import org.bigbluebutton.modules.chat.events.ChatEvent;
import org.bigbluebutton.modules.chat.events.ChatSaveEvent; import org.bigbluebutton.modules.chat.events.ChatSaveEvent;
import org.bigbluebutton.modules.chat.events.ChatToolbarButtonEvent;
import org.bigbluebutton.modules.chat.events.SendPrivateChatMessageEvent; import org.bigbluebutton.modules.chat.events.SendPrivateChatMessageEvent;
import org.bigbluebutton.modules.chat.events.SendPublicChatMessageEvent; import org.bigbluebutton.modules.chat.events.SendPublicChatMessageEvent;
import org.bigbluebutton.modules.chat.events.StartChatModuleEvent; import org.bigbluebutton.modules.chat.events.StartChatModuleEvent;
@ -97,6 +98,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<MethodInvoker generator="{ChatCopy}" method="copyAllText" arguments="{event}"/> <MethodInvoker generator="{ChatCopy}" method="copyAllText" arguments="{event}"/>
</EventHandlers> </EventHandlers>
<EventHandlers type="{ChatToolbarButtonEvent.CLEAR_CHAT_TOOLBAR_EVENT}">
<MethodInvoker generator="{ChatMessageService}" method="clearPublicChatMessages"/>
</EventHandlers>
<Injectors target="{ChatMessageService}"> <Injectors target="{ChatMessageService}">
<PropertyInjector targetKey="dispatcher" source="{scope.dispatcher}"/> <PropertyInjector targetKey="dispatcher" source="{scope.dispatcher}"/>
<PropertyInjector targetKey="receiver" source="{MessageReceiver}"/> <PropertyInjector targetKey="receiver" source="{MessageReceiver}"/>

View File

@ -86,6 +86,17 @@ package org.bigbluebutton.modules.chat.model
var msg:ChatMessage = messages.getItemAt(messages.length - 1) as ChatMessage; var msg:ChatMessage = messages.getItemAt(messages.length - 1) as ChatMessage;
return msg.time; return msg.time;
} }
public function clearChat():void{
var cm:ChatMessage = new ChatMessage();
cm.time = getLastTime();
cm.text = "The chat was cleared by a moderator";
cm.name = "";
cm.senderColor = uint(0x086187);
messages.removeAll();
messages.addItem(cm);
}
} }
} }

View File

@ -75,6 +75,10 @@ package org.bigbluebutton.modules.chat.services
} }
public function clearPublicChatMessages():void {
sender.clearPublicChatMessages();
}
public function sendPublicMessage(message:ChatMessageVO):void { public function sendPublicMessage(message:ChatMessageVO):void {
sender.sendPublicMessage(message); sender.sendPublicMessage(message);
} }
@ -103,14 +107,14 @@ package org.bigbluebutton.modules.chat.services
welcomeMsg.toUserID = SPACE; welcomeMsg.toUserID = SPACE;
welcomeMsg.toUsername = SPACE; welcomeMsg.toUsername = SPACE;
welcomeMsg.message = welcome; welcomeMsg.message = welcome;
var welcomeMsgEvent:PublicChatMessageEvent = new PublicChatMessageEvent(PublicChatMessageEvent.PUBLIC_CHAT_MESSAGE_EVENT); var welcomeMsgEvent:PublicChatMessageEvent = new PublicChatMessageEvent(PublicChatMessageEvent.PUBLIC_CHAT_MESSAGE_EVENT);
welcomeMsgEvent.message = welcomeMsg; welcomeMsgEvent.message = welcomeMsg;
welcomeMsgEvent.history = false; welcomeMsgEvent.history = false;
dispatcher.dispatchEvent(welcomeMsgEvent); dispatcher.dispatchEvent(welcomeMsgEvent);
//Say that client is ready when sending the welcome message //Say that client is ready when sending the welcome message
ExternalInterface.call("clientReady", ResourceUtil.getInstance().getString('bbb.accessibility.clientReady')); ExternalInterface.call("clientReady", ResourceUtil.getInstance().getString('bbb.accessibility.clientReady'));
} }
if (UsersUtil.amIModerator()) { if (UsersUtil.amIModerator()) {
@ -125,11 +129,11 @@ package org.bigbluebutton.modules.chat.services
moderatorOnlyMsg.toUserID = SPACE; moderatorOnlyMsg.toUserID = SPACE;
moderatorOnlyMsg.toUsername = SPACE; moderatorOnlyMsg.toUsername = SPACE;
moderatorOnlyMsg.message = MeetingModel.getInstance().modOnlyMessage; moderatorOnlyMsg.message = MeetingModel.getInstance().modOnlyMessage;
var moderatorOnlyMsgEvent:PublicChatMessageEvent = new PublicChatMessageEvent(PublicChatMessageEvent.PUBLIC_CHAT_MESSAGE_EVENT); var moderatorOnlyMsgEvent:PublicChatMessageEvent = new PublicChatMessageEvent(PublicChatMessageEvent.PUBLIC_CHAT_MESSAGE_EVENT);
moderatorOnlyMsgEvent.message = moderatorOnlyMsg; moderatorOnlyMsgEvent.message = moderatorOnlyMsg;
moderatorOnlyMsgEvent.history = false; moderatorOnlyMsgEvent.history = false;
dispatcher.dispatchEvent(moderatorOnlyMsgEvent); dispatcher.dispatchEvent(moderatorOnlyMsgEvent);
} }
} }
} }

View File

@ -29,6 +29,7 @@ package org.bigbluebutton.modules.chat.services
import org.bigbluebutton.modules.chat.events.PrivateChatMessageEvent; import org.bigbluebutton.modules.chat.events.PrivateChatMessageEvent;
import org.bigbluebutton.modules.chat.events.PublicChatMessageEvent; import org.bigbluebutton.modules.chat.events.PublicChatMessageEvent;
import org.bigbluebutton.modules.chat.events.TranscriptEvent; import org.bigbluebutton.modules.chat.events.TranscriptEvent;
import org.bigbluebutton.modules.chat.events.ClearPublicChatEvent;
import org.bigbluebutton.modules.chat.vo.ChatMessageVO; import org.bigbluebutton.modules.chat.vo.ChatMessageVO;
public class MessageReceiver implements IMessageListener public class MessageReceiver implements IMessageListener
@ -57,6 +58,9 @@ package org.bigbluebutton.modules.chat.services
case "ChatRequestMessageHistoryReply": case "ChatRequestMessageHistoryReply":
handleChatRequestMessageHistoryReply(message); handleChatRequestMessageHistoryReply(message);
break; break;
case "ChatClearPublicMessageCommand":
handleChatClearPublicMessageCommand(message);
break;
default: default:
// LogUtil.warn("Cannot handle message [" + messageName + "]"); // LogUtil.warn("Cannot handle message [" + messageName + "]");
} }
@ -79,7 +83,7 @@ package org.bigbluebutton.modules.chat.services
private function handleChatReceivePublicMessageCommand(message:Object, history:Boolean = false):void { private function handleChatReceivePublicMessageCommand(message:Object, history:Boolean = false):void {
LOGGER.debug("Handling public chat message [{0}]", [message.message]); LOGGER.debug("Handling public chat message [{0}]", [message.message]);
var msg:ChatMessageVO = new ChatMessageVO(); var msg:ChatMessageVO = new ChatMessageVO();
msg.chatType = message.chatType; msg.chatType = message.chatType;
msg.fromUserID = message.fromUserID; msg.fromUserID = message.fromUserID;
@ -123,5 +127,12 @@ package org.bigbluebutton.modules.chat.services
pcCoreEvent.message = message; pcCoreEvent.message = message;
dispatcher.dispatchEvent(pcCoreEvent); dispatcher.dispatchEvent(pcCoreEvent);
} }
private function handleChatClearPublicMessageCommand(message:Object):void {
LOGGER.debug("Handling CLEAR chat history message [{0}]", [message.msg]);
var clearChatEvent:ClearPublicChatEvent = new ClearPublicChatEvent(ClearPublicChatEvent.CLEAR_PUBLIC_CHAT_EVENT);
dispatcher.dispatchEvent(clearChatEvent);
}
} }
} }

View File

@ -60,7 +60,7 @@ package org.bigbluebutton.modules.chat.services
message.toObj() message.toObj()
); );
} }
public function sendPrivateMessage(message:ChatMessageVO):void public function sendPrivateMessage(message:ChatMessageVO):void
{ {
LOGGER.debug("Sending [chat.sendPrivateMessage] to server."); LOGGER.debug("Sending [chat.sendPrivateMessage] to server.");
@ -76,5 +76,19 @@ package org.bigbluebutton.modules.chat.services
message.toObj() message.toObj()
); );
} }
public function clearPublicChatMessages():void
{
LOGGER.debug("Sending [chat.clearPublicChatMessages] to server.");
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage("chat.clearPublicChatMessages",
function(result:String):void { // On successful result
LOGGER.debug(result);
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
}
);
}
} }
} }

View File

@ -56,6 +56,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
<mate:Listener type="{ShortcutEvent.GOREAD_MESSAGE}" method="goToLatestReadMessage" /> <mate:Listener type="{ShortcutEvent.GOREAD_MESSAGE}" method="goToLatestReadMessage" />
<mate:Listener type="{PrivateChatMessageEvent.PRIVATE_CHAT_MESSAGE_EVENT}" method="handlePrivateChatMessageEvent"/> <mate:Listener type="{PrivateChatMessageEvent.PRIVATE_CHAT_MESSAGE_EVENT}" method="handlePrivateChatMessageEvent"/>
<mate:Listener type="{PublicChatMessageEvent.PUBLIC_CHAT_MESSAGE_EVENT}" method="handlePublicChatMessageEvent"/> <mate:Listener type="{PublicChatMessageEvent.PUBLIC_CHAT_MESSAGE_EVENT}" method="handlePublicChatMessageEvent"/>
<mate:Listener type="{ClearPublicChatEvent.CLEAR_PUBLIC_CHAT_EVENT}" method="handleClearChatBoxMessages"/>
<mate:Listener type="{ShortcutEvent.FOCUS_CHAT_INPUT}" method="focusChatInput" /> <mate:Listener type="{ShortcutEvent.FOCUS_CHAT_INPUT}" method="focusChatInput" />
<mate:Listener type="{UserLeftEvent.LEFT}" method="handleUserLeftEvent"/> <mate:Listener type="{UserLeftEvent.LEFT}" method="handleUserLeftEvent"/>
<mate:Listener type="{UserJoinedEvent.JOINED}" method="handleUserJoinedEvent"/> <mate:Listener type="{UserJoinedEvent.JOINED}" method="handleUserJoinedEvent"/>
@ -99,6 +100,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
import org.bigbluebutton.modules.chat.events.SendPrivateChatMessageEvent; import org.bigbluebutton.modules.chat.events.SendPrivateChatMessageEvent;
import org.bigbluebutton.modules.chat.events.SendPublicChatMessageEvent; import org.bigbluebutton.modules.chat.events.SendPublicChatMessageEvent;
import org.bigbluebutton.modules.chat.events.TranscriptEvent; import org.bigbluebutton.modules.chat.events.TranscriptEvent;
import org.bigbluebutton.modules.chat.events.ClearPublicChatEvent;
import org.bigbluebutton.modules.chat.model.ChatConversation; import org.bigbluebutton.modules.chat.model.ChatConversation;
import org.bigbluebutton.modules.chat.model.ChatOptions; import org.bigbluebutton.modules.chat.model.ChatOptions;
import org.bigbluebutton.modules.chat.vo.ChatMessageVO; import org.bigbluebutton.modules.chat.vo.ChatMessageVO;
@ -764,6 +766,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
} }
} }
private function handleClearChatBoxMessages(event:ClearPublicChatEvent):void{
chatMessages.clearChat();
invalidateDisplayList();
validateNow();
}
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledWidth, unscaledHeight); super.updateDisplayList(unscaledWidth, unscaledHeight);
@ -775,7 +783,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
chatToolbar.width = 45; chatToolbar.width = 45;
chatToolbar.x = (chatMessagesCanvas.width - chatToolbar.width) - 10; chatToolbar.x = (chatMessagesCanvas.width - chatToolbar.width) - 10;
chatToolbar.y = 10; chatToolbar.y = 20;
if(chatMessagesList.mx_internal::scroll_verticalScrollBar != null && chatMessagesList.mx_internal::scroll_verticalScrollBar.visible){ if(chatMessagesList.mx_internal::scroll_verticalScrollBar != null && chatMessagesList.mx_internal::scroll_verticalScrollBar.visible){
chatToolbar.width -= chatMessagesList.mx_internal::scroll_verticalScrollBar.width; chatToolbar.width -= chatMessagesList.mx_internal::scroll_verticalScrollBar.width;

View File

@ -3,7 +3,8 @@
<mx:VBox xmlns="flexlib.containers.*" <mx:VBox xmlns="flexlib.containers.*"
initialize="init()" initialize="init()"
xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/" xmlns:mate="http://mate.asfusion.com/"
xmlns:common="org.bigbluebutton.common.*"
creationComplete="onCreationComplete()" creationComplete="onCreationComplete()"
visible="{toolbarVisible}" visible="{toolbarVisible}"
styleName="whiteboardToolbarStyle" styleName="whiteboardToolbarStyle"
@ -11,6 +12,8 @@
hideEffect="{fadeOut}" showEffect="{fadeIn}" hideEffect="{fadeOut}" showEffect="{fadeIn}"
backgroundColor="{bgColor}"> backgroundColor="{bgColor}">
<mate:Listener type="{ChangeMyRole.CHANGE_MY_ROLE_EVENT}" method="onChangeMyRole" />
<mx:Script> <mx:Script>
<![CDATA[ <![CDATA[
import mx.core.UIComponent; import mx.core.UIComponent;
@ -20,6 +23,8 @@
import org.bigbluebutton.modules.chat.events.ChatToolbarButtonEvent; import org.bigbluebutton.modules.chat.events.ChatToolbarButtonEvent;
import org.bigbluebutton.modules.chat.model.ChatOptions; import org.bigbluebutton.modules.chat.model.ChatOptions;
import org.bigbluebutton.util.i18n.ResourceUtil; import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.main.model.users.events.ChangeMyRole;
//import org.bigbluebutton.main.model.users.events.ChangeRoleEvent;
[Bindable] public var chatOptions:ChatOptions; [Bindable] public var chatOptions:ChatOptions;
[Bindable] private var baseIndex:int; [Bindable] private var baseIndex:int;
@ -80,6 +85,17 @@
globalDispatcher.dispatchEvent(copyEvent); globalDispatcher.dispatchEvent(copyEvent);
} }
public function sendClearEvent():void{
var clearEvent:ChatToolbarButtonEvent = new ChatToolbarButtonEvent(ChatToolbarButtonEvent.CLEAR_CHAT_TOOLBAR_EVENT);
globalDispatcher.dispatchEvent(clearEvent);
}
public function onChangeMyRole(e:ChangeMyRole):void{
clearBtn.visible = UsersUtil.amIModerator();
clearBtn.enabled = UsersUtil.amIModerator();
clearBtn.includeInLayout = UsersUtil.amIModerator();
}
public function registerListeners(component:UIComponent):void { public function registerListeners(component:UIComponent):void {
component.addEventListener(MouseEvent.ROLL_OVER, handleMouseIn); component.addEventListener(MouseEvent.ROLL_OVER, handleMouseIn);
component.addEventListener(MouseEvent.ROLL_OUT, handleMouseOut); component.addEventListener(MouseEvent.ROLL_OUT, handleMouseOut);
@ -87,6 +103,8 @@
]]> ]]>
</mx:Script> </mx:Script>
<common:TabIndexer id="tabIndexer" tabIndices="{[saveBtn, copyBtn, clearBtn]}"/>
<mx:Fade id="fadeOut" duration="200" alphaFrom="1.0" alphaTo="0.0" /> <mx:Fade id="fadeOut" duration="200" alphaFrom="1.0" alphaTo="0.0" />
<mx:Fade id="fadeIn" duration="200" alphaFrom="0.0" alphaTo="1.0" /> <mx:Fade id="fadeIn" duration="200" alphaFrom="0.0" alphaTo="1.0" />
@ -96,8 +114,7 @@
height="22" height="22"
toolTip="{ResourceUtil.getInstance().getString('bbb.chat.saveBtn.toolTip')}" toolTip="{ResourceUtil.getInstance().getString('bbb.chat.saveBtn.toolTip')}"
click="sendSaveEvent()" click="sendSaveEvent()"
tabIndex="{baseIndex+1}" accessibilityName="{ResourceUtil.getInstance().getString('bbb.chat.saveBtn.accessibilityName')}"/>
accessibilityName="{ResourceUtil.getInstance().getString('bbb.chat.copyBtn.accessibilityName')}"/>
<mx:Button id="copyBtn" <mx:Button id="copyBtn"
styleName="copyButtonStyle" styleName="copyButtonStyle"
@ -105,7 +122,17 @@
height="22" height="22"
toolTip="{ResourceUtil.getInstance().getString('bbb.chat.copyBtn.toolTip')}" toolTip="{ResourceUtil.getInstance().getString('bbb.chat.copyBtn.toolTip')}"
click="sendCopyEvent()" click="sendCopyEvent()"
tabIndex="{baseIndex+2}" accessibilityName="{ResourceUtil.getInstance().getString('bbb.chat.copyBtn.accessibilityName')}"/>
accessibilityName="{ResourceUtil.getInstance().getString('bbb.chat.copyBtn.accessibilityName')}"/>
<mx:Button id="clearBtn"
styleName="clearButtonStyle"
width="22"
height="22"
visible = "{UsersUtil.amIModerator()}"
enabled = "{UsersUtil.amIModerator()}"
includeInLayout = "{UsersUtil.amIModerator()}"
toolTip="{ResourceUtil.getInstance().getString('bbb.chat.clearBtn.toolTip')}"
click="sendClearEvent()"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.chat.clearBtn.accessibilityName')}"/>
</mx:VBox> </mx:VBox>

View File

@ -20,9 +20,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
--> -->
<mx:Button xmlns:mx="http://www.adobe.com/2006/mxml" <mx:Button xmlns:mx="http://www.adobe.com/2006/mxml"
width="30" height="30" width="30" height="30"
click="onClick()" styleName="whiteboardClearButtonStyle" click="onClick()" styleName="clearButtonStyle"
toolTip="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.clear')}" toolTip="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.clear')}"
accessibilityName="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.clear.accessibilityName')}"> accessibilityName="{ResourceUtil.getInstance().getString('bbb.highlighter.toolbar.clear.accessibilityName')}">
<mx:Script> <mx:Script>
<![CDATA[ <![CDATA[
import org.bigbluebutton.modules.whiteboard.business.shapes.WhiteboardConstants; import org.bigbluebutton.modules.whiteboard.business.shapes.WhiteboardConstants;