Add Chat collections to Hasura/Postgres
This commit is contained in:
parent
7b7d2636ad
commit
7f88d2efa4
@ -20,7 +20,7 @@ trait SendMessageToBreakoutRoomInternalMsgHdlr {
|
||||
} yield {
|
||||
val groupChatMsgFromUser = GroupChatMsgFromUser(sender.id, sender.copy(name = msg.senderName), true, msg.msg)
|
||||
val gcm = GroupChatApp.toGroupChatMessage(sender.copy(name = msg.senderName), groupChatMsgFromUser)
|
||||
val gcs = GroupChatApp.addGroupChatMessage(chat, state.groupChats, gcm)
|
||||
val gcs = GroupChatApp.addGroupChatMessage(liveMeeting.props.meetingProp.intId, chat, state.groupChats, gcm)
|
||||
|
||||
val event = buildGroupChatMessageBroadcastEvtMsg(
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
|
@ -2,6 +2,7 @@ package org.bigbluebutton.core.apps.groupchats
|
||||
|
||||
import org.bigbluebutton.common2.msgs._
|
||||
import org.bigbluebutton.core.bus.MessageBus
|
||||
import org.bigbluebutton.core.db.ChatDAO
|
||||
import org.bigbluebutton.core.domain.MeetingState2x
|
||||
import org.bigbluebutton.core.models.GroupChat
|
||||
import org.bigbluebutton.core.running.LiveMeeting
|
||||
@ -33,6 +34,7 @@ trait CreateDefaultPublicGroupChat {
|
||||
|
||||
bus.outGW.send(respMsg)
|
||||
val groupChats = state.groupChats.add(groupChat)
|
||||
ChatDAO.insert(liveMeeting.props.meetingProp.intId, groupChat)
|
||||
state.update(groupChats)
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import org.bigbluebutton.core.models.GroupChat
|
||||
import org.bigbluebutton.core.running.LiveMeeting
|
||||
import org.bigbluebutton.core.apps.PermissionCheck
|
||||
import org.bigbluebutton.SystemConfiguration
|
||||
import org.bigbluebutton.core.db.ChatDAO
|
||||
import org.bigbluebutton.core.models.Users2x
|
||||
import org.bigbluebutton.core.models.Roles
|
||||
import org.bigbluebutton.core2.MeetingStatus2x
|
||||
@ -66,6 +67,7 @@ trait CreateGroupChatReqMsgHdlr extends SystemConfiguration {
|
||||
sendMessages(msg, gc, liveMeeting, bus)
|
||||
|
||||
val groupChats = state.groupChats.add(gc)
|
||||
ChatDAO.insert(liveMeeting.props.meetingProp.intId, gc)
|
||||
state.update(groupChats)
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
package org.bigbluebutton.core.apps.groupchats
|
||||
|
||||
import org.bigbluebutton.common2.msgs.{ GroupChatAccess, GroupChatMsgFromUser, GroupChatMsgToUser, GroupChatUser }
|
||||
import org.bigbluebutton.core.db.ChatMessageDAO
|
||||
import org.bigbluebutton.core.domain.MeetingState2x
|
||||
import org.bigbluebutton.core.models._
|
||||
import org.bigbluebutton.core.running.LiveMeeting
|
||||
@ -26,8 +27,9 @@ object GroupChatApp {
|
||||
sender = msg.sender, chatEmphasizedText = msg.chatEmphasizedText, message = msg.message)
|
||||
}
|
||||
|
||||
def addGroupChatMessage(chat: GroupChat, chats: GroupChats,
|
||||
def addGroupChatMessage(meetingId: String, chat: GroupChat, chats: GroupChats,
|
||||
msg: GroupChatMessage): GroupChats = {
|
||||
ChatMessageDAO.insert(meetingId, chat.id, msg)
|
||||
val c = chat.add(msg)
|
||||
chats.update(c)
|
||||
}
|
||||
@ -71,7 +73,7 @@ object GroupChatApp {
|
||||
} yield {
|
||||
|
||||
val gcm1 = GroupChatApp.toGroupChatMessage(sender, msg)
|
||||
val gcs1 = GroupChatApp.addGroupChatMessage(chat, state.groupChats, gcm1)
|
||||
val gcs1 = GroupChatApp.addGroupChatMessage(liveMeeting.props.meetingProp.intId, chat, state.groupChats, gcm1)
|
||||
state.update(gcs1)
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ trait SendGroupChatMessageMsgHdlr extends HandlerHelpers {
|
||||
|
||||
if ((chatIsPrivate && userIsAParticipant) || !chatIsPrivate) {
|
||||
val gcm = GroupChatApp.toGroupChatMessage(sender, msg.body.msg)
|
||||
val gcs = GroupChatApp.addGroupChatMessage(chat, state.groupChats, gcm)
|
||||
val gcs = GroupChatApp.addGroupChatMessage(liveMeeting.props.meetingProp.intId, chat, state.groupChats, gcm)
|
||||
|
||||
val event = buildGroupChatMessageBroadcastEvtMsg(
|
||||
liveMeeting.props.meetingProp.intId,
|
||||
|
@ -0,0 +1,56 @@
|
||||
package org.bigbluebutton.core.db
|
||||
|
||||
import slick.jdbc.PostgresProfile.api._
|
||||
import org.bigbluebutton.core.models.GroupChat
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.util.{ Failure, Success }
|
||||
|
||||
case class ChatDbModel(
|
||||
chatId: String,
|
||||
meetingId: String,
|
||||
access: String,
|
||||
createdBy: String,
|
||||
// participants: List[String],
|
||||
// users: List[String]
|
||||
)
|
||||
|
||||
class ChatDbTableDef(tag: Tag) extends Table[ChatDbModel](tag, None, "chat") {
|
||||
val chatId = column[String]("chatId", O.PrimaryKey)
|
||||
val meetingId = column[String]("meetingId", O.PrimaryKey)
|
||||
val access = column[String]("access")
|
||||
val createdBy = column[String]("createdBy")
|
||||
// val participants = column[List[String]]("participants")
|
||||
// val users = column[List[String]]("users")
|
||||
// val meeting = foreignKey("chat_meeting_fk", (meetingId), ChatDbTableDef.meetings)(_.meetingId, onDelete = ForeignKeyAction.Cascade)
|
||||
override def * = (chatId, meetingId, access, createdBy) <> (ChatDbModel.tupled, ChatDbModel.unapply)
|
||||
}
|
||||
|
||||
object ChatDAO {
|
||||
def insert(meetingId: String, groupChat: GroupChat) = {
|
||||
DatabaseConnection.db.run(
|
||||
TableQuery[ChatDbTableDef].insertOrUpdate(
|
||||
ChatDbModel(
|
||||
chatId = groupChat.id,
|
||||
meetingId = meetingId,
|
||||
access = groupChat.access,
|
||||
createdBy = groupChat.createdBy.id,
|
||||
// participants = groupChat.users.map(u => u.id).toList,
|
||||
// users = groupChat.users.map(u => u.id).toList
|
||||
)
|
||||
)
|
||||
).onComplete {
|
||||
case Success(rowsAffected) => {
|
||||
println(s"$rowsAffected row(s) inserted on Chat table!")
|
||||
|
||||
for {
|
||||
user <- groupChat.users
|
||||
} yield {
|
||||
ChatUserDAO.insert(meetingId, groupChat.id, user)
|
||||
}
|
||||
|
||||
}
|
||||
case Failure(e) => println(s"Error inserting Chat: $e")
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package org.bigbluebutton.core.db
|
||||
|
||||
import slick.jdbc.PostgresProfile.api._
|
||||
import org.bigbluebutton.core.models.GroupChatMessage
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.util.{ Failure, Success }
|
||||
|
||||
case class ChatMessageDbModel(
|
||||
messageId: String,
|
||||
chatId: String,
|
||||
meetingId: String,
|
||||
correlationId: String,
|
||||
createdTime: Long,
|
||||
chatEmphasizedText: Boolean,
|
||||
message: String,
|
||||
senderId: String,
|
||||
senderName: String,
|
||||
senderRole: String
|
||||
)
|
||||
|
||||
class ChatMessageDbTableDef(tag: Tag) extends Table[ChatMessageDbModel](tag, None, "chat_message") {
|
||||
val messageId = column[String]("messageId", O.PrimaryKey)
|
||||
val chatId = column[String]("chatId")
|
||||
val meetingId = column[String]("meetingId")
|
||||
val correlationId = column[String]("correlationId")
|
||||
val createdTime = column[Long]("createdTime")
|
||||
val chatEmphasizedText = column[Boolean]("chatEmphasizedText")
|
||||
val message = column[String]("message")
|
||||
val senderId = column[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)
|
||||
}
|
||||
|
||||
object ChatMessageDAO {
|
||||
def insert(meetingId: String, chatId: String, groupChatMessage: GroupChatMessage) = {
|
||||
DatabaseConnection.db.run(
|
||||
TableQuery[ChatMessageDbTableDef].insertOrUpdate(
|
||||
ChatMessageDbModel(
|
||||
messageId = groupChatMessage.id,
|
||||
chatId = chatId,
|
||||
meetingId = meetingId,
|
||||
correlationId = groupChatMessage.correlationId,
|
||||
createdTime = groupChatMessage.timestamp,
|
||||
chatEmphasizedText = groupChatMessage.chatEmphasizedText,
|
||||
message = groupChatMessage.message,
|
||||
senderId = groupChatMessage.sender.id,
|
||||
senderName = groupChatMessage.sender.name,
|
||||
senderRole = groupChatMessage.sender.role,
|
||||
)
|
||||
)
|
||||
).onComplete {
|
||||
case Success(rowsAffected) => println(s"$rowsAffected row(s) inserted on ChatMessage table!")
|
||||
case Failure(e) => println(s"Error inserting ChatMessage: $e")
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package org.bigbluebutton.core.db
|
||||
|
||||
import slick.jdbc.PostgresProfile.api._
|
||||
import org.bigbluebutton.common2.msgs.GroupChatUser
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
import scala.util.{ Failure, Success }
|
||||
|
||||
case class ChatUserDbModel(
|
||||
chatId: String,
|
||||
meetingId: String,
|
||||
userId: String,
|
||||
lastSeenAt: Long,
|
||||
userName: String,
|
||||
userRole: String
|
||||
)
|
||||
|
||||
class ChatUserDbTableDef(tag: Tag) extends Table[ChatUserDbModel](tag, None, "chat_user") {
|
||||
val chatId = column[String]("chatId", O.PrimaryKey)
|
||||
val meetingId = column[String]("meetingId", O.PrimaryKey)
|
||||
val userId = column[String]("userId", O.PrimaryKey)
|
||||
val lastSeenAt = column[Long]("lastSeenAt")
|
||||
val userName = column[String]("userName")
|
||||
val userRole = column[String]("userRole")
|
||||
// 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 * = (chatId, meetingId, userId, lastSeenAt, userName, userRole) <> (ChatUserDbModel.tupled, ChatUserDbModel.unapply)
|
||||
}
|
||||
|
||||
object ChatUserDAO {
|
||||
def insert(meetingId: String, chatId: String, groupChatUser: GroupChatUser) = {
|
||||
DatabaseConnection.db.run(
|
||||
TableQuery[ChatUserDbTableDef].insertOrUpdate(
|
||||
ChatUserDbModel(
|
||||
userId = groupChatUser.id,
|
||||
chatId = chatId,
|
||||
meetingId = meetingId,
|
||||
lastSeenAt = 0,
|
||||
userName = groupChatUser.name,
|
||||
userRole = groupChatUser.role
|
||||
)
|
||||
)
|
||||
).onComplete {
|
||||
case Success(rowsAffected) => println(s"$rowsAffected row(s) inserted on ChatUser table!")
|
||||
case Failure(e) => println(s"Error inserting ChatUser: $e")
|
||||
}
|
||||
}
|
||||
}
|
@ -10,10 +10,14 @@ import TotalOfModerators from './TotalOfModerators';
|
||||
import TotalOfViewers from './TotalOfViewers';
|
||||
import TotalOfUsersTalking from './TotalOfUsersTalking';
|
||||
import TotalOfUniqueNames from './TotalOfUniqueNames';
|
||||
import ChatMessages from "./ChatMessages";
|
||||
import ChatsInfo from "./ChatsInfo";
|
||||
import ChatPublicMessages from "./ChatPublicMessages";
|
||||
|
||||
|
||||
function App() {
|
||||
const [sessionToken, setSessionToken] = useState(null);
|
||||
const [userId, setUserId] = useState(null);
|
||||
const [joining, setJoining] = useState(false);
|
||||
const [graphqlClient, setGraphqlClient] = useState(null);
|
||||
const [enterApiResponse, setEnterApiResponse] = useState('');
|
||||
@ -33,6 +37,9 @@ function App() {
|
||||
.then((json) => {
|
||||
console.log(json.response);
|
||||
setEnterApiResponse(json.response.returncode);
|
||||
if(json?.response?.internalUserID) {
|
||||
setUserId(json.response.internalUserID);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -80,8 +87,17 @@ function App() {
|
||||
}}
|
||||
>
|
||||
<ApolloProvider client={graphqlClient}>
|
||||
User Id: {userId}
|
||||
<MeetingInfo />
|
||||
<br />
|
||||
<UserList />
|
||||
<br />
|
||||
<ChatsInfo />
|
||||
<br />
|
||||
<ChatMessages />
|
||||
<br />
|
||||
<ChatPublicMessages />
|
||||
<br />
|
||||
<TotalOfUsers />
|
||||
<TotalOfModerators />
|
||||
<TotalOfViewers />
|
||||
|
52
bbb-graphql-client-test/src/ChatMessages.js
Normal file
52
bbb-graphql-client-test/src/ChatMessages.js
Normal file
@ -0,0 +1,52 @@
|
||||
import {useSubscription, gql, useQuery} from '@apollo/client';
|
||||
import React, { useState } from "react";
|
||||
|
||||
export default function ChatMessages() {
|
||||
const { loading, error, data } = useSubscription(
|
||||
gql`subscription {
|
||||
chat_message_private(order_by: {createdTime: asc}) {
|
||||
chatEmphasizedText
|
||||
chatId
|
||||
correlationId
|
||||
createdTime
|
||||
createdTimeAsDate
|
||||
meetingId
|
||||
message
|
||||
messageId
|
||||
senderId
|
||||
senderName
|
||||
senderRole
|
||||
}
|
||||
}`
|
||||
);
|
||||
|
||||
return !loading && !error &&
|
||||
(<table border="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colSpan="4">Private Chat Messages</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>ChatId</th>
|
||||
<th>Sender</th>
|
||||
<th>Message</th>
|
||||
<th>Sent At</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.chat_message_private.map((curr) => {
|
||||
console.log('message', curr);
|
||||
return (
|
||||
<tr key={curr.messageId}>
|
||||
{/*<td>{user.userId}</td>*/}
|
||||
<td>{curr.chatId}</td>
|
||||
<td>{curr.senderName}</td>
|
||||
<td>{curr.message}</td>
|
||||
<td>{curr.createdTimeAsDate} ({curr.createdTime})</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>);
|
||||
}
|
||||
|
51
bbb-graphql-client-test/src/ChatPublicMessages.js
Normal file
51
bbb-graphql-client-test/src/ChatPublicMessages.js
Normal file
@ -0,0 +1,51 @@
|
||||
import {useSubscription, gql, useQuery} from '@apollo/client';
|
||||
import React, { useState } from "react";
|
||||
|
||||
export default function ChatPublicMessages() {
|
||||
const { loading, error, data } = useSubscription(
|
||||
gql`subscription {
|
||||
chat_message_public(order_by: {createdTime: asc}) {
|
||||
chatId
|
||||
chatEmphasizedText
|
||||
correlationId
|
||||
createdTime
|
||||
createdTimeAsDate
|
||||
meetingId
|
||||
message
|
||||
messageId
|
||||
senderId
|
||||
senderName
|
||||
senderRole
|
||||
}
|
||||
}`
|
||||
);
|
||||
|
||||
return !loading && !error &&
|
||||
(<table border="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colSpan="4">Public Chat Messages</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>ChatId</th>
|
||||
<th>Sender</th>
|
||||
<th>Message</th>
|
||||
<th>Sent At</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.chat_message_public.map((curr) => {
|
||||
console.log('message', curr);
|
||||
return (
|
||||
<tr key={curr.messageId}>
|
||||
<td>{curr.chatId}</td>
|
||||
<td>{curr.senderName}</td>
|
||||
<td>{curr.message}</td>
|
||||
<td>{curr.createdTimeAsDate} ({curr.createdTime})</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>);
|
||||
}
|
||||
|
48
bbb-graphql-client-test/src/ChatsInfo.js
Normal file
48
bbb-graphql-client-test/src/ChatsInfo.js
Normal file
@ -0,0 +1,48 @@
|
||||
import {useSubscription, gql, useQuery} from '@apollo/client';
|
||||
import React, { useState } from "react";
|
||||
|
||||
export default function ChatsInfo() {
|
||||
const { loading, error, data } = useSubscription(
|
||||
gql`subscription {
|
||||
chat {
|
||||
chatId
|
||||
meetingId
|
||||
participantsId
|
||||
participantsName
|
||||
totalMessages
|
||||
totalUnread
|
||||
}
|
||||
}`
|
||||
);
|
||||
|
||||
return !loading && !error &&
|
||||
(<table border="1">
|
||||
<thead>
|
||||
<tr>
|
||||
<th colSpan="5">Chats available</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Id</th>
|
||||
<th>Meeting</th>
|
||||
<th>Participants</th>
|
||||
<th>Total Mgs</th>
|
||||
<th>Unread</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{data.chat.map((curr) => {
|
||||
console.log('chat', curr);
|
||||
return (
|
||||
<tr key={curr.chatId}>
|
||||
<td>{curr.chatId}</td>
|
||||
<td>{curr.meetingId}</td>
|
||||
<td>{curr.participantsName}</td>
|
||||
<td>{curr.totalMessages}</td>
|
||||
<td>{curr.totalUnread}</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>);
|
||||
}
|
||||
|
@ -223,3 +223,83 @@ SELECT
|
||||
"user_breakoutRoom" .*
|
||||
FROM "user_breakoutRoom"
|
||||
JOIN "user" u ON u."userId" = "user_breakoutRoom"."userId";
|
||||
|
||||
-- ===================== CHAT TABLES
|
||||
|
||||
DROP VIEW IF EXISTS "v_chat";
|
||||
DROP VIEW IF EXISTS "v_chat_message_public";
|
||||
DROP VIEW IF EXISTS "v_chat_message_private";
|
||||
DROP TABLE IF EXISTS "chat_user";
|
||||
DROP TABLE IF EXISTS "chat_message";
|
||||
DROP TABLE IF EXISTS "chat";
|
||||
|
||||
CREATE TABLE "chat" (
|
||||
"chatId" varchar(100),
|
||||
"meetingId" varchar(100) REFERENCES "meeting"("meetingId") ON DELETE CASCADE,
|
||||
"access" varchar(20),
|
||||
"createdBy" varchar(25),
|
||||
CONSTRAINT "chat_pkey" PRIMARY KEY ("chatId","meetingId")
|
||||
);
|
||||
|
||||
CREATE INDEX "chat_meetingId" ON "chat"("meetingId");
|
||||
|
||||
CREATE TABLE "chat_user" (
|
||||
"chatId" varchar(100),
|
||||
"meetingId" varchar(100),
|
||||
"userId" varchar(100),
|
||||
"userName" varchar(255),
|
||||
"userRole" varchar(20),
|
||||
"lastSeenAt" bigint,
|
||||
CONSTRAINT "chat_user_pkey" PRIMARY KEY ("chatId","meetingId","userId"),
|
||||
CONSTRAINT chat_fk FOREIGN KEY ("chatId", "meetingId") REFERENCES "chat"("chatId", "meetingId") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX "chat_user_chatId" ON "chat_user"("chatId","meetingId");
|
||||
|
||||
CREATE TABLE "chat_message" (
|
||||
"messageId" varchar(100) PRIMARY KEY,
|
||||
"chatId" varchar(100),
|
||||
"meetingId" varchar(100),
|
||||
"correlationId" varchar(100),
|
||||
"createdTime" bigint,
|
||||
"chatEmphasizedText" boolean,
|
||||
"message" TEXT,
|
||||
"senderId" varchar(100),
|
||||
"senderName" varchar(255),
|
||||
"senderRole" varchar(20),
|
||||
CONSTRAINT chat_fk FOREIGN KEY ("chatId", "meetingId") REFERENCES "chat"("chatId", "meetingId") ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX "chat_message_chatId" ON "chat_message"("chatId","meetingId");
|
||||
|
||||
|
||||
CREATE OR REPLACE VIEW "v_chat" AS
|
||||
SELECT cu."userId",
|
||||
chat."meetingId",
|
||||
chat."chatId",
|
||||
array_remove(array_agg(DISTINCT chat_with."userId"),NULL) "participantsId",
|
||||
string_agg(DISTINCT chat_with."userName" ,', ') AS "participantsName",
|
||||
count(DISTINCT cm."messageId") "totalMessages",
|
||||
sum(CASE WHEN cm."createdTime" > cu."lastSeenAt" THEN 1 ELSE 0 end) "totalUnread"
|
||||
FROM "user"
|
||||
LEFT JOIN "chat_user" cu ON cu."meetingId" = "user"."meetingId" AND cu."userId" = "user"."userId"
|
||||
JOIN "chat" ON cu."meetingId" = chat."meetingId" AND (cu."chatId" = chat."chatId" OR chat."chatId" = 'MAIN-PUBLIC-GROUP-CHAT')
|
||||
LEFT JOIN "chat_user" chat_with ON chat_with."meetingId" = chat."meetingId" AND chat_with."chatId" = chat."chatId" AND chat_with."userId" != cu."userId"
|
||||
LEFT JOIN chat_message cm ON cm."meetingId" = chat."meetingId" AND cm."chatId" = chat."chatId"
|
||||
GROUP BY cu."userId", chat."meetingId", chat."chatId";
|
||||
|
||||
|
||||
CREATE OR REPLACE VIEW "v_chat_message_public" AS
|
||||
SELECT cm.*, to_timestamp("createdTime" / 1000) AS "createdTimeAsDate"
|
||||
FROM chat_message cm
|
||||
WHERE cm."chatId" = 'MAIN-PUBLIC-GROUP-CHAT';
|
||||
|
||||
CREATE OR REPLACE VIEW "v_chat_message_private" AS
|
||||
SELECT cu."userId", cm.*, to_timestamp("createdTime" / 1000) AS "createdTimeAsDate"
|
||||
FROM chat_message cm
|
||||
JOIN chat_user cu ON cu."meetingId" = cm."meetingId" AND cu."chatId" = cm."chatId";
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -0,0 +1,24 @@
|
||||
table:
|
||||
name: v_chat
|
||||
schema: public
|
||||
configuration:
|
||||
column_config: {}
|
||||
custom_column_names: {}
|
||||
custom_name: chat
|
||||
custom_root_fields: {}
|
||||
select_permissions:
|
||||
- role: bbb_client
|
||||
permission:
|
||||
columns:
|
||||
- chatId
|
||||
- meetingId
|
||||
- participantsId
|
||||
- participantsName
|
||||
- totalMessages
|
||||
- totalUnread
|
||||
filter:
|
||||
_and:
|
||||
- meetingId:
|
||||
_eq: X-Hasura-MeetingId
|
||||
- userId:
|
||||
_eq: X-Hasura-UserId
|
@ -0,0 +1,29 @@
|
||||
table:
|
||||
name: v_chat_message_private
|
||||
schema: public
|
||||
configuration:
|
||||
column_config: {}
|
||||
custom_column_names: {}
|
||||
custom_name: chat_message_private
|
||||
custom_root_fields: {}
|
||||
select_permissions:
|
||||
- role: bbb_client
|
||||
permission:
|
||||
columns:
|
||||
- chatEmphasizedText
|
||||
- chatId
|
||||
- correlationId
|
||||
- createdTime
|
||||
- createdTimeAsDate
|
||||
- meetingId
|
||||
- message
|
||||
- messageId
|
||||
- senderId
|
||||
- senderName
|
||||
- senderRole
|
||||
filter:
|
||||
_and:
|
||||
- meetingId:
|
||||
_eq: X-Hasura-MeetingId
|
||||
- userId:
|
||||
_eq: X-Hasura-UserId
|
@ -0,0 +1,26 @@
|
||||
table:
|
||||
name: v_chat_message_public
|
||||
schema: public
|
||||
configuration:
|
||||
column_config: {}
|
||||
custom_column_names: {}
|
||||
custom_name: chat_message_public
|
||||
custom_root_fields: {}
|
||||
select_permissions:
|
||||
- role: bbb_client
|
||||
permission:
|
||||
columns:
|
||||
- createdTime
|
||||
- chatEmphasizedText
|
||||
- chatId
|
||||
- correlationId
|
||||
- meetingId
|
||||
- messageId
|
||||
- senderId
|
||||
- senderName
|
||||
- senderRole
|
||||
- message
|
||||
- createdTimeAsDate
|
||||
filter:
|
||||
meetingId:
|
||||
_eq: X-Hasura-MeetingId
|
@ -2,6 +2,9 @@
|
||||
- "!include public_user.yaml"
|
||||
- "!include public_user_camera.yaml"
|
||||
- "!include public_user_voice.yaml"
|
||||
- "!include public_v_chat.yaml"
|
||||
- "!include public_v_chat_message_private.yaml"
|
||||
- "!include public_v_chat_message_public.yaml"
|
||||
- "!include public_v_user_breakoutRoom.yaml"
|
||||
- "!include public_v_user_camera.yaml"
|
||||
- "!include public_v_user_voice.yaml"
|
||||
|
Loading…
Reference in New Issue
Block a user