Insert Poll result as Chat msg in graphql
This commit is contained in:
parent
ed2c94eaea
commit
d1a60157e5
@ -33,7 +33,12 @@ object GroupChatApp {
|
||||
|
||||
def addGroupChatMessage(meetingId: String, chat: GroupChat, chats: GroupChats,
|
||||
msg: GroupChatMessage): GroupChats = {
|
||||
ChatMessageDAO.insert(meetingId, chat.id, msg)
|
||||
if (msg.sender.id == SystemUser.ID) {
|
||||
ChatMessageDAO.insertSystemMsg(meetingId, chat.id, msg.message, "default", Map(), msg.sender.name)
|
||||
} else {
|
||||
ChatMessageDAO.insert(meetingId, chat.id, msg)
|
||||
}
|
||||
|
||||
val c = chat.add(msg)
|
||||
chats.update(c)
|
||||
}
|
||||
|
@ -2,12 +2,15 @@ package org.bigbluebutton.core.apps.polls
|
||||
|
||||
import org.bigbluebutton.common2.domain.SimplePollResultOutVO
|
||||
import org.bigbluebutton.common2.msgs._
|
||||
import org.bigbluebutton.core.apps.groupchats.GroupChatApp
|
||||
import org.bigbluebutton.core.bus.MessageBus
|
||||
import org.bigbluebutton.core.domain.MeetingState2x
|
||||
import org.bigbluebutton.core.models.Polls
|
||||
import org.bigbluebutton.core.running.LiveMeeting
|
||||
import org.bigbluebutton.core.apps.{ PermissionCheck, RightsManagementTrait }
|
||||
import org.bigbluebutton.core2.message.senders.{ MsgBuilder }
|
||||
import org.bigbluebutton.core.db.{ ChatMessageDAO, JsonUtils }
|
||||
import org.bigbluebutton.core2.message.senders.MsgBuilder
|
||||
import spray.json.DefaultJsonProtocol.jsonFormat2
|
||||
|
||||
trait ShowPollResultReqMsgHdlr extends RightsManagementTrait {
|
||||
this: PollApp2x =>
|
||||
@ -54,6 +57,27 @@ trait ShowPollResultReqMsgHdlr extends RightsManagementTrait {
|
||||
for {
|
||||
(result, annotationProp) <- Polls.handleShowPollResultReqMsg(state, msg.header.userId, msg.body.pollId, liveMeeting)
|
||||
} yield {
|
||||
//it will be used to render the chat message (will be stored as json in chat-msg metadata)
|
||||
val resultAsSimpleMap = Map(
|
||||
"id" -> result.id,
|
||||
"questionType" -> result.questionType,
|
||||
"questionText" -> result.questionText.getOrElse(""),
|
||||
"answers" -> {
|
||||
for {
|
||||
answer <- result.answers
|
||||
} yield {
|
||||
Map(
|
||||
"id" -> answer.id,
|
||||
"key" -> answer.key,
|
||||
"numVotes" -> answer.numVotes
|
||||
)
|
||||
}
|
||||
},
|
||||
"numRespondents" -> result.numRespondents,
|
||||
"numResponders" -> result.numResponders,
|
||||
)
|
||||
|
||||
ChatMessageDAO.insertSystemMsg(liveMeeting.props.meetingProp.intId, GroupChatApp.MAIN_PUBLIC_CHAT, "", "poll", resultAsSimpleMap, "")
|
||||
broadcastEvent(msg, result, annotationProp)
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
package org.bigbluebutton.core.db
|
||||
|
||||
import slick.jdbc.PostgresProfile.api._
|
||||
import org.bigbluebutton.core.models.GroupChatMessage
|
||||
import org.bigbluebutton.core.models.{GroupChatFactory, GroupChatMessage}
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.util.{ Failure, Success }
|
||||
import scala.util.{Failure, Success}
|
||||
|
||||
case class ChatMessageDbModel(
|
||||
messageId: String,
|
||||
@ -14,7 +14,9 @@ case class ChatMessageDbModel(
|
||||
createdTime: Long,
|
||||
chatEmphasizedText: Boolean,
|
||||
message: String,
|
||||
senderId: String,
|
||||
messageType: String,
|
||||
messageMetadata: String,
|
||||
senderId: Option[String],
|
||||
senderName: String,
|
||||
senderRole: String
|
||||
)
|
||||
@ -27,13 +29,15 @@ class ChatMessageDbTableDef(tag: Tag) extends Table[ChatMessageDbModel](tag, Non
|
||||
val createdTime = column[Long]("createdTime")
|
||||
val chatEmphasizedText = column[Boolean]("chatEmphasizedText")
|
||||
val message = column[String]("message")
|
||||
val senderId = column[String]("senderId")
|
||||
val messageType = column[String]("messageType")
|
||||
val messageMetadata = column[String]("messageMetadata")
|
||||
val senderId = column[Option[String]]("senderId")
|
||||
val senderName = column[String]("senderName")
|
||||
val senderRole = column[String]("senderRole")
|
||||
// val chat = foreignKey("chat_message_chat_fk", (chatId, meetingId), ChatTable.chats)(c => (c.chatId, c.meetingId), onDelete = ForeignKeyAction.Cascade)
|
||||
// val sender = foreignKey("chat_message_sender_fk", senderId, UserTable.users)(_.userId, onDelete = ForeignKeyAction.SetNull)
|
||||
|
||||
override def * = (messageId, chatId, meetingId, correlationId, createdTime, chatEmphasizedText, message, senderId, senderName, senderRole) <> (ChatMessageDbModel.tupled, ChatMessageDbModel.unapply)
|
||||
override def * = (messageId, chatId, meetingId, correlationId, createdTime, chatEmphasizedText, message, messageType, messageMetadata, senderId, senderName, senderRole) <> (ChatMessageDbModel.tupled, ChatMessageDbModel.unapply)
|
||||
}
|
||||
|
||||
object ChatMessageDAO {
|
||||
@ -48,7 +52,9 @@ object ChatMessageDAO {
|
||||
createdTime = groupChatMessage.timestamp,
|
||||
chatEmphasizedText = groupChatMessage.chatEmphasizedText,
|
||||
message = groupChatMessage.message,
|
||||
senderId = groupChatMessage.sender.id,
|
||||
messageType = "default",
|
||||
messageMetadata = "",
|
||||
senderId = Some(groupChatMessage.sender.id),
|
||||
senderName = groupChatMessage.sender.name,
|
||||
senderRole = groupChatMessage.sender.role,
|
||||
)
|
||||
@ -63,4 +69,34 @@ object ChatMessageDAO {
|
||||
case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting ChatMessage: $e")
|
||||
}
|
||||
}
|
||||
|
||||
def insertSystemMsg(meetingId: String, chatId: String, message: String, messageType: String, messageMetadata: Map[String,Any], senderName: String) = {
|
||||
DatabaseConnection.db.run(
|
||||
TableQuery[ChatMessageDbTableDef].insertOrUpdate(
|
||||
ChatMessageDbModel(
|
||||
messageId = GroupChatFactory.genId(),
|
||||
chatId = chatId,
|
||||
meetingId = meetingId,
|
||||
correlationId = "",
|
||||
createdTime = System.currentTimeMillis(),
|
||||
chatEmphasizedText = false,
|
||||
message = message,
|
||||
messageType = messageType,
|
||||
messageMetadata = JsonUtils.mapToJson(messageMetadata),
|
||||
senderId = None,
|
||||
senderName = senderName,
|
||||
senderRole = ""
|
||||
)
|
||||
)
|
||||
).onComplete {
|
||||
case Success(rowsAffected) => {
|
||||
DatabaseConnection.logger.debug(s"$rowsAffected row(s) inserted on ChatMessage(system) table!")
|
||||
|
||||
//Set chat visible for all participant users
|
||||
ChatUserDAO.updateChatVisible(meetingId, chatId)
|
||||
}
|
||||
case Failure(e) => DatabaseConnection.logger.debug(s"Error inserting ChatMessage(system): $e")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -33,12 +33,12 @@ object JsonUtils {
|
||||
case d: Double => JsNumber(d)
|
||||
case m: Map[_, _] => JsObject(m.asInstanceOf[Map[String, Any]].map { case (k, v) => k -> write(v) })
|
||||
case l: List[_] => JsArray(l.map(write).toVector)
|
||||
case a: Array[_] => JsArray(a.map(write).toVector)
|
||||
case _ => throw new IllegalArgumentException(s"Unsupported type: ${x.getClass.getName}")
|
||||
// case _ => JsNull
|
||||
}
|
||||
}
|
||||
|
||||
// Cria um JsonWriter implícito para o tipo Map[String, Any]
|
||||
implicit val mapFormat: JsonWriter[Map[String, Any]] = new JsonWriter[Map[String, Any]] {
|
||||
def write(m: Map[String, Any]): JsValue = {
|
||||
JsObject(m.map { case (k, v) => k -> AnyJsonWriter.write(v) })
|
||||
|
@ -19,6 +19,18 @@ DROP TABLE IF EXISTS "chat_user";
|
||||
DROP TABLE IF EXISTS "chat_message";
|
||||
DROP TABLE IF EXISTS "chat";
|
||||
|
||||
drop view if exists "v_poll_response";
|
||||
drop view if exists "v_poll_user";
|
||||
drop view if exists "v_poll_option";
|
||||
drop view if exists "v_poll";
|
||||
drop table if exists "poll_response";
|
||||
drop table if exists "poll_option";
|
||||
drop table if exists "poll";
|
||||
drop view if exists "v_external_video";
|
||||
drop table if exists "external_video";
|
||||
drop view if exists "v_screenshare";
|
||||
drop table if exists "screenshare";
|
||||
|
||||
DROP VIEW IF EXISTS "v_user_camera";
|
||||
DROP VIEW IF EXISTS "v_user_voice";
|
||||
--DROP VIEW IF EXISTS "v_user_whiteboard";
|
||||
@ -54,18 +66,6 @@ DROP TABLE IF EXISTS "meeting_usersPolicies";
|
||||
DROP TABLE IF EXISTS "meeting_group";
|
||||
DROP TABLE IF EXISTS "meeting";
|
||||
|
||||
drop view if exists "v_poll_response";
|
||||
drop view if exists "v_poll_user";
|
||||
drop view if exists "v_poll_option";
|
||||
drop view if exists "v_poll";
|
||||
drop table if exists "poll_response";
|
||||
drop table if exists "poll_option";
|
||||
drop table if exists "poll";
|
||||
drop view if exists "v_external_video";
|
||||
drop table if exists "external_video";
|
||||
drop view if exists "v_screenshare";
|
||||
drop table if exists "screenshare";
|
||||
|
||||
|
||||
DROP FUNCTION IF EXISTS "update_user_presenter_trigger_func";
|
||||
DROP FUNCTION IF EXISTS "update_pres_presentation_current_trigger_func";
|
||||
@ -494,14 +494,7 @@ create index "idx_user_connectionStatus_meetingId" on "user_connectionStatus"("m
|
||||
--FROM "user" u
|
||||
--LEFT JOIN "user_connectionStatus" uc ON uc."userId" = u."userId";
|
||||
|
||||
create table "user_custom_parameter"(
|
||||
"userId" varchar(50) PRIMARY KEY REFERENCES "user"("userId") ON DELETE CASCADE,
|
||||
"meetingId" varchar(100) REFERENCES "meeting"("meetingId") ON DELETE CASCADE,
|
||||
"parameter" varchar(255),
|
||||
"value" varchar(255)
|
||||
);
|
||||
create index "idx_user_custom_parameter_parameter" on "user_custom_parameter"("userId","parameter");
|
||||
create index "idx_user_custom_parameter_meetingId" on "user_custom_parameter"("meetingId");
|
||||
|
||||
|
||||
-- ===================== CHAT TABLES
|
||||
|
||||
@ -565,7 +558,9 @@ CREATE TABLE "chat_message" (
|
||||
"correlationId" varchar(100),
|
||||
"createdTime" bigint,
|
||||
"chatEmphasizedText" boolean,
|
||||
"message" TEXT,
|
||||
"message" text,
|
||||
"messageType" varchar(50),
|
||||
"messageMetadata" text,
|
||||
"senderId" varchar(100),
|
||||
"senderName" varchar(255),
|
||||
"senderRole" varchar(20),
|
||||
|
@ -27,6 +27,8 @@ select_permissions:
|
||||
- createdTimeAsDate
|
||||
- message
|
||||
- messageId
|
||||
- messageMetadata
|
||||
- messageType
|
||||
- senderId
|
||||
- senderName
|
||||
- senderRole
|
||||
|
@ -20,16 +20,18 @@ select_permissions:
|
||||
- role: bbb_client
|
||||
permission:
|
||||
columns:
|
||||
- createdTime
|
||||
- chatEmphasizedText
|
||||
- chatId
|
||||
- correlationId
|
||||
- createdTime
|
||||
- createdTimeAsDate
|
||||
- message
|
||||
- messageId
|
||||
- messageMetadata
|
||||
- messageType
|
||||
- senderId
|
||||
- senderName
|
||||
- senderRole
|
||||
- message
|
||||
- createdTimeAsDate
|
||||
filter:
|
||||
meetingId:
|
||||
_eq: X-Hasura-MeetingId
|
||||
|
36
bbb-graphql-server/update_graphql_data.sh
Executable file
36
bbb-graphql-server/update_graphql_data.sh
Executable file
@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
|
||||
export LANGUAGE="en_US.UTF-8"
|
||||
export LC_ALL="en_US.UTF-8"
|
||||
|
||||
akka_apps_status=$(systemctl is-active "bbb-apps-akka")
|
||||
hasura_status=$(systemctl is-active "bbb-graphql-server")
|
||||
|
||||
if [ "$akka_apps_status" = "active" ]; then
|
||||
echo "Stopping Akka-apps"
|
||||
sudo systemctl stop bbb-apps-akka
|
||||
fi
|
||||
if [ "$hasura_status" = "active" ]; then
|
||||
echo "Stopping Hasura"
|
||||
sudo systemctl start bbb-graphql-server
|
||||
fi
|
||||
|
||||
echo "Restarting database bbb_graphql"
|
||||
sudo -u postgres psql -c "SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity WHERE datname = 'bbb_graphql'"
|
||||
sudo -u postgres psql -c "drop database if exists bbb_graphql"
|
||||
sudo -u postgres psql -c "create database bbb_graphql"
|
||||
|
||||
echo "Creating tables in bbb_graphql"
|
||||
sudo -u postgres psql -U postgres -d bbb_graphql -a -f bbb_schema.sql --set ON_ERROR_STOP=on
|
||||
|
||||
echo "Applying new metadata to Hasura"
|
||||
/usr/local/bin/hasura metadata apply
|
||||
|
||||
if [ "$hasura_status" = "active" ]; then
|
||||
echo "Starting Hasura"
|
||||
sudo systemctl start bbb-graphql-server
|
||||
fi
|
||||
if [ "$akka_apps_status" = "active" ]; then
|
||||
echo "Starting Akka-apps"
|
||||
sudo systemctl start bbb-apps-akka
|
||||
fi
|
@ -38,11 +38,11 @@ const ChatMesssage: React.FC<ChatMessageProps> = ({ message, previousMessage, la
|
||||
{
|
||||
sameSender ? null : (
|
||||
<ChatAvatar
|
||||
avatar={message.user.avatar}
|
||||
color={message.user.color}
|
||||
moderator={message.user.isModerator}
|
||||
avatar={message.user?.avatar}
|
||||
color={message.user?.color}
|
||||
moderator={message.user?.isModerator}
|
||||
>
|
||||
{message.user.name.toLowerCase().slice(0, 2) || " "}
|
||||
{message.user?.name.toLowerCase().slice(0, 2) || " "}
|
||||
</ChatAvatar>
|
||||
)
|
||||
}
|
||||
@ -52,10 +52,10 @@ const ChatMesssage: React.FC<ChatMessageProps> = ({ message, previousMessage, la
|
||||
<ChatUserContent>
|
||||
<ChatUserName
|
||||
>
|
||||
{message.user.name}
|
||||
{message.user?.name}
|
||||
</ChatUserName>
|
||||
{
|
||||
message.user.isOnline ? null : (
|
||||
message.user?.isOnline ? null : (
|
||||
<ChatUserOffline
|
||||
>
|
||||
{`(${intl.formatMessage(intlMessages.offline)})`}
|
||||
@ -71,7 +71,7 @@ const ChatMesssage: React.FC<ChatMessageProps> = ({ message, previousMessage, la
|
||||
}
|
||||
<ChatMessage
|
||||
sameSender={sameSender}
|
||||
emphasizedMessage={message.user.isModerator}
|
||||
emphasizedMessage={message.user?.isModerator}
|
||||
>
|
||||
{message.message}
|
||||
</ChatMessage>
|
||||
@ -80,4 +80,4 @@ const ChatMesssage: React.FC<ChatMessageProps> = ({ message, previousMessage, la
|
||||
);
|
||||
};
|
||||
|
||||
export default ChatMesssage;
|
||||
export default ChatMesssage;
|
||||
|
@ -36,8 +36,8 @@ const verifyIfIsPrivateChat = (message: unknown): message is ChatMessagePrivateS
|
||||
}
|
||||
|
||||
|
||||
const ChatListPage: React.FC<ChatListPageProps> = ({ messages, lastSenderPreviousPage, page }) => {
|
||||
|
||||
const ChatListPage: React.FC<ChatListPageProps> = ({ messages, lastSenderPreviousPage, page }) => {
|
||||
|
||||
return (
|
||||
<div id={`messagePage-${page}`}>
|
||||
{
|
||||
@ -68,7 +68,7 @@ const ChatListPageContainer: React.FC<ChatListPageContainerProps> = ({
|
||||
const chatQuery = isPublicChat
|
||||
? CHAT_MESSAGE_PUBLIC_SUBSCRIPTION
|
||||
: CHAT_MESSAGE_PRIVATE_SUBSCRIPTION;
|
||||
const defaultVariables = { offset: (page)*pageSize, limit: pageSize };
|
||||
const defaultVariables = { offset: (page)*pageSize, limit: pageSize };
|
||||
const variables = isPublicChat ? defaultVariables : { ...defaultVariables, requestedChatId: chatId };
|
||||
const {
|
||||
data: chatMessageData,
|
||||
@ -89,9 +89,9 @@ const ChatListPageContainer: React.FC<ChatListPageContainerProps> = ({
|
||||
}
|
||||
|
||||
if (messages.length > 0) {
|
||||
setLastSender(page, messages[messages.length-1].user.userId);
|
||||
setLastSender(page, messages[messages.length-1].user?.userId);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<ChatListPage
|
||||
messages={messages}
|
||||
@ -101,4 +101,4 @@ const ChatListPageContainer: React.FC<ChatListPageContainerProps> = ({
|
||||
);
|
||||
}
|
||||
|
||||
export default ChatListPageContainer;
|
||||
export default ChatListPageContainer;
|
||||
|
Loading…
Reference in New Issue
Block a user