Merge pull request #20461 from GuiLeme/update-data-channel-function
feat(plugin): implement `ReplaceEntry()` function for data-channel
This commit is contained in:
commit
de686a2b8e
@ -140,26 +140,26 @@ object ClientSettings extends SystemConfiguration {
|
||||
} yield {
|
||||
if (dataChannel.contains("name")) {
|
||||
val channelName = dataChannel("name").toString
|
||||
val writePermission = {
|
||||
if (dataChannel.contains("writePermission")) {
|
||||
dataChannel("writePermission") match {
|
||||
val pushPermission = {
|
||||
if (dataChannel.contains("pushPermission")) {
|
||||
dataChannel("pushPermission") match {
|
||||
case wPerm: List[String] => wPerm
|
||||
case _ => {
|
||||
logger.warn(s"Invalid writePermission for channel $channelName in plugin $pluginName")
|
||||
logger.warn(s"Invalid pushPermission for channel $channelName in plugin $pluginName")
|
||||
List()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
logger.warn(s"Missing config writePermission for channel $channelName in plugin $pluginName")
|
||||
logger.warn(s"Missing config pushPermission for channel $channelName in plugin $pluginName")
|
||||
List()
|
||||
}
|
||||
}
|
||||
val deletePermission = {
|
||||
if (dataChannel.contains("deletePermission")) {
|
||||
dataChannel("deletePermission") match {
|
||||
val replaceOrDeletePermission = {
|
||||
if (dataChannel.contains("replaceOrDeletePermission")) {
|
||||
dataChannel("replaceOrDeletePermission") match {
|
||||
case dPerm: List[String] => dPerm
|
||||
case _ => {
|
||||
logger.warn(s"Invalid deletePermission for channel $channelName in plugin $pluginName")
|
||||
logger.warn(s"Invalid replaceOrDeletePermission for channel $channelName in plugin $pluginName")
|
||||
List()
|
||||
}
|
||||
}
|
||||
@ -168,7 +168,7 @@ object ClientSettings extends SystemConfiguration {
|
||||
}
|
||||
}
|
||||
|
||||
pluginDataChannels += (channelName -> DataChannel(channelName, writePermission, deletePermission))
|
||||
pluginDataChannels += (channelName -> DataChannel(channelName, pushPermission, replaceOrDeletePermission))
|
||||
}
|
||||
}
|
||||
case _ => logger.warn(s"Plugin $pluginName has an invalid dataChannels format")
|
||||
@ -184,7 +184,7 @@ object ClientSettings extends SystemConfiguration {
|
||||
pluginsFromConfig
|
||||
}
|
||||
|
||||
case class DataChannel(name: String, writePermission: List[String], deletePermission: List[String])
|
||||
case class DataChannel(name: String, pushPermission: List[String], replaceOrDeletePermission: List[String])
|
||||
case class Plugin(name: String, url: String, dataChannels: Map[String, DataChannel])
|
||||
|
||||
}
|
||||
|
@ -25,21 +25,21 @@ trait PluginDataChannelDeleteEntryMsgHdlr extends HandlerHelpers {
|
||||
println(s"Data channel '${msg.body.channelName}' not found in plugin '${msg.body.pluginName}'.")
|
||||
} else {
|
||||
val hasPermission = for {
|
||||
deletePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).deletePermission
|
||||
replaceOrDeletePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).replaceOrDeletePermission
|
||||
} yield {
|
||||
deletePermission.toLowerCase match {
|
||||
replaceOrDeletePermission.toLowerCase match {
|
||||
case "all" => true
|
||||
case "moderator" => user.role == Roles.MODERATOR_ROLE
|
||||
case "presenter" => user.presenter
|
||||
case "sender" => {
|
||||
val senderUserId = PluginDataChannelEntryDAO.getMessageSender(
|
||||
case "creator" => {
|
||||
val creatorUserId = PluginDataChannelEntryDAO.getEntryCreator(
|
||||
meetingId,
|
||||
msg.body.pluginName,
|
||||
msg.body.channelName,
|
||||
msg.body.subChannelName,
|
||||
msg.body.entryId
|
||||
)
|
||||
senderUserId == msg.header.userId
|
||||
creatorUserId == msg.header.userId
|
||||
}
|
||||
case _ => false
|
||||
}
|
||||
|
@ -25,9 +25,9 @@ trait PluginDataChannelPushEntryMsgHdlr extends HandlerHelpers {
|
||||
println(s"Data channel '${msg.body.channelName}' not found in plugin '${msg.body.pluginName}'.")
|
||||
} else {
|
||||
val hasPermission = for {
|
||||
writePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).writePermission
|
||||
pushPermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).pushPermission
|
||||
} yield {
|
||||
writePermission.toLowerCase match {
|
||||
pushPermission.toLowerCase match {
|
||||
case "all" => true
|
||||
case "moderator" => user.role == Roles.MODERATOR_ROLE
|
||||
case "presenter" => user.presenter
|
||||
|
@ -0,0 +1,63 @@
|
||||
package org.bigbluebutton.core.apps.plugin
|
||||
|
||||
import org.bigbluebutton.ClientSettings
|
||||
import org.bigbluebutton.common2.msgs.PluginDataChannelReplaceEntryMsg
|
||||
import org.bigbluebutton.core.db.{JsonUtils, PluginDataChannelEntryDAO}
|
||||
import org.bigbluebutton.core.domain.MeetingState2x
|
||||
import org.bigbluebutton.core.models.{Roles, Users2x}
|
||||
import org.bigbluebutton.core.running.{HandlerHelpers, LiveMeeting}
|
||||
|
||||
trait PluginDataChannelReplaceEntryMsgHdlr extends HandlerHelpers {
|
||||
|
||||
def handle(msg: PluginDataChannelReplaceEntryMsg, state: MeetingState2x, liveMeeting: LiveMeeting): Unit = {
|
||||
val pluginsDisabled: Boolean = liveMeeting.props.meetingProp.disabledFeatures.contains("plugins")
|
||||
val meetingId = liveMeeting.props.meetingProp.intId
|
||||
|
||||
for {
|
||||
_ <- if (!pluginsDisabled) Some(()) else None
|
||||
user <- Users2x.findWithIntId(liveMeeting.users2x, msg.header.userId)
|
||||
} yield {
|
||||
val pluginsConfig = ClientSettings.getPluginsFromConfig(ClientSettings.clientSettingsFromFile)
|
||||
|
||||
if (!pluginsConfig.contains(msg.body.pluginName)) {
|
||||
println(s"Plugin '${msg.body.pluginName}' not found.")
|
||||
} else if (!pluginsConfig(msg.body.pluginName).dataChannels.contains(msg.body.channelName)) {
|
||||
println(s"Data channel '${msg.body.channelName}' not found in plugin '${msg.body.pluginName}'.")
|
||||
} else {
|
||||
val hasPermission = for {
|
||||
replaceOrDeletePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).replaceOrDeletePermission
|
||||
} yield {
|
||||
replaceOrDeletePermission.toLowerCase match {
|
||||
case "all" => true
|
||||
case "moderator" => user.role == Roles.MODERATOR_ROLE
|
||||
case "presenter" => user.presenter
|
||||
case "creator" => {
|
||||
val creatorUserId = PluginDataChannelEntryDAO.getEntryCreator(
|
||||
meetingId,
|
||||
msg.body.pluginName,
|
||||
msg.body.channelName,
|
||||
msg.body.subChannelName,
|
||||
msg.body.entryId
|
||||
)
|
||||
creatorUserId == msg.header.userId
|
||||
}
|
||||
case _ => false
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasPermission.contains(true)) {
|
||||
println(s"No permission to write in plugin: '${msg.body.pluginName}', data channel: '${msg.body.channelName}'.")
|
||||
} else {
|
||||
PluginDataChannelEntryDAO.replace(
|
||||
msg.header.meetingId,
|
||||
msg.body.pluginName,
|
||||
msg.body.channelName,
|
||||
msg.body.subChannelName,
|
||||
msg.body.entryId,
|
||||
JsonUtils.mapToJson(msg.body.payloadJson),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -25,9 +25,9 @@ trait PluginDataChannelResetMsgHdlr extends HandlerHelpers {
|
||||
println(s"Data channel '${msg.body.channelName}' not found in plugin '${msg.body.pluginName}'.")
|
||||
} else {
|
||||
val hasPermission = for {
|
||||
deletePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).deletePermission
|
||||
replaceOrDeletePermission <- pluginsConfig(msg.body.pluginName).dataChannels(msg.body.channelName).replaceOrDeletePermission
|
||||
} yield {
|
||||
deletePermission.toLowerCase match {
|
||||
replaceOrDeletePermission.toLowerCase match {
|
||||
case "all" => true
|
||||
case "moderator" => user.role == Roles.MODERATOR_ROLE
|
||||
case "presenter" => user.presenter
|
||||
|
@ -6,6 +6,7 @@ import org.bigbluebutton.common2.msgs.PluginDataChannelDeleteEntryMsgBody
|
||||
|
||||
class PluginHdlrs(implicit val context: ActorContext)
|
||||
extends PluginDataChannelPushEntryMsgHdlr
|
||||
with PluginDataChannelReplaceEntryMsgHdlr
|
||||
with PluginDataChannelDeleteEntryMsgHdlr
|
||||
with PluginDataChannelResetMsgHdlr {
|
||||
|
||||
|
@ -2,6 +2,7 @@ package org.bigbluebutton.core.db
|
||||
|
||||
import PostgresProfile.api._
|
||||
import org.bigbluebutton.core.db.DatabaseConnection.{db, logger}
|
||||
import org.bigbluebutton.core.util.RandomStringGenerator
|
||||
import spray.json.JsValue
|
||||
|
||||
import scala.concurrent.ExecutionContext.Implicits.global
|
||||
@ -18,9 +19,9 @@ case class PluginDataChannelEntryDbModel(
|
||||
pluginName: String,
|
||||
channelName: String,
|
||||
subChannelName: String,
|
||||
// entryId: Option[String] = None,
|
||||
entryId: Option[String] = None,
|
||||
payloadJson: JsValue,
|
||||
fromUserId: String,
|
||||
createdBy: String,
|
||||
toRoles: Option[List[String]],
|
||||
toUserIds: Option[List[String]],
|
||||
createdAt: java.sql.Timestamp,
|
||||
@ -32,28 +33,29 @@ class PluginDataChannelEntryDbTableDef(tag: Tag) extends Table[PluginDataChannel
|
||||
val pluginName = column[String]("pluginName", O.PrimaryKey)
|
||||
val channelName = column[String]("channelName", O.PrimaryKey)
|
||||
val subChannelName = column[String]("subChannelName")
|
||||
// val entryId = column[Option[String]]("messageId", O.PrimaryKey) //// The messageId is generated by the database
|
||||
val entryId = column[Option[String]]("entryId", O.PrimaryKey)
|
||||
val payloadJson = column[JsValue]("payloadJson")
|
||||
val fromUserId = column[String]("fromUserId")
|
||||
val createdBy = column[String]("createdBy")
|
||||
val toRoles = column[Option[List[String]]]("toRoles")
|
||||
val toUserIds = column[Option[List[String]]]("toUserIds")
|
||||
val createdAt = column[java.sql.Timestamp]("createdAt")
|
||||
val deletedAt = column[Option[java.sql.Timestamp]]("deletedAt")
|
||||
override def * = (meetingId, pluginName, channelName, subChannelName, payloadJson, fromUserId, toRoles, toUserIds, createdAt, deletedAt) <> (PluginDataChannelEntryDbModel.tupled, PluginDataChannelEntryDbModel.unapply)
|
||||
override def * = (meetingId, pluginName, channelName, subChannelName, entryId, payloadJson, createdBy, toRoles, toUserIds, createdAt, deletedAt) <> (PluginDataChannelEntryDbModel.tupled, PluginDataChannelEntryDbModel.unapply)
|
||||
}
|
||||
|
||||
object PluginDataChannelEntryDAO {
|
||||
def insert(meetingId: String, pluginName: String, channelName: String, subChannelName: String, senderUserId: String,
|
||||
def insert(meetingId: String, pluginName: String, channelName: String, subChannelName: String, createdBy: String,
|
||||
payloadJson: Map[String, Any], toRoles: List[String], toUserIds: List[String]) = {
|
||||
DatabaseConnection.db.run(
|
||||
TableQuery[PluginDataChannelEntryDbTableDef].forceInsert(
|
||||
PluginDataChannelEntryDbModel(
|
||||
entryId = Some(RandomStringGenerator.randomAlphanumericString(50)),
|
||||
meetingId = meetingId,
|
||||
pluginName = pluginName,
|
||||
channelName = channelName,
|
||||
subChannelName = subChannelName,
|
||||
payloadJson = JsonUtils.mapToJson(payloadJson),
|
||||
fromUserId = senderUserId,
|
||||
createdBy = createdBy,
|
||||
toRoles = toRoles.map(_.toUpperCase).filter(Permission.allowedRoles.contains) match {
|
||||
case Nil => None
|
||||
case filtered => Some(filtered)
|
||||
@ -86,9 +88,9 @@ object PluginDataChannelEntryDAO {
|
||||
}
|
||||
}
|
||||
|
||||
def getMessageSender(meetingId: String, pluginName: String, channelName: String,
|
||||
subChannelName: String, entryId: String): String = {
|
||||
val query = sql"""SELECT "fromUserId"
|
||||
def getEntryCreator(meetingId: String, pluginName: String, channelName: String,
|
||||
subChannelName: String, entryId: String): String = {
|
||||
val query = sql"""SELECT "createdBy"
|
||||
FROM "pluginDataChannelEntry"
|
||||
WHERE "deletedAt" is null
|
||||
AND "meetingId" = ${meetingId}
|
||||
@ -123,4 +125,23 @@ object PluginDataChannelEntryDAO {
|
||||
}
|
||||
}
|
||||
|
||||
def replace(meetingId: String, pluginName: String, channelName: String,
|
||||
subChannelName: String, entryId: String, payloadJson: JsValue) = {
|
||||
|
||||
DatabaseConnection.db.run(
|
||||
TableQuery[PluginDataChannelEntryDbTableDef]
|
||||
.filter(_.meetingId === meetingId)
|
||||
.filter(_.pluginName === pluginName)
|
||||
.filter(_.channelName === channelName)
|
||||
.filter(_.subChannelName === subChannelName)
|
||||
.filter(_.entryId === entryId)
|
||||
.filter(_.deletedAt.isEmpty)
|
||||
.map(_.payloadJson)
|
||||
.update(payloadJson)
|
||||
).onComplete {
|
||||
case Success(rowsAffected) => DatabaseConnection.logger.debug(s"$rowsAffected row(s) updated with new payloadJson on pluginDataChannelEntry table!")
|
||||
case Failure(e) => DatabaseConnection.logger.debug(s"Error updating with new payloadJson for table pluginDataChannelEntry: $e")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -418,6 +418,9 @@ class ReceivedJsonMsgHandlerActor(
|
||||
case PluginDataChannelPushEntryMsg.NAME =>
|
||||
routeGenericMsg[PluginDataChannelPushEntryMsg](envelope, jsonNode)
|
||||
|
||||
case PluginDataChannelReplaceEntryMsg.NAME =>
|
||||
routeGenericMsg[PluginDataChannelReplaceEntryMsg](envelope, jsonNode)
|
||||
|
||||
case PluginDataChannelDeleteEntryMsg.NAME =>
|
||||
routeGenericMsg[PluginDataChannelDeleteEntryMsg](envelope, jsonNode)
|
||||
|
||||
|
@ -714,9 +714,10 @@ class MeetingActor(
|
||||
state = groupChatApp.handle(m, state, liveMeeting, msgBus)
|
||||
|
||||
// Plugin
|
||||
case m: PluginDataChannelPushEntryMsg => pluginHdlrs.handle(m, state, liveMeeting)
|
||||
case m: PluginDataChannelDeleteEntryMsg => pluginHdlrs.handle(m, state, liveMeeting)
|
||||
case m: PluginDataChannelResetMsg => pluginHdlrs.handle(m, state, liveMeeting)
|
||||
case m: PluginDataChannelPushEntryMsg => pluginHdlrs.handle(m, state, liveMeeting)
|
||||
case m: PluginDataChannelReplaceEntryMsg => pluginHdlrs.handle(m, state, liveMeeting)
|
||||
case m: PluginDataChannelDeleteEntryMsg => pluginHdlrs.handle(m, state, liveMeeting)
|
||||
case m: PluginDataChannelResetMsg => pluginHdlrs.handle(m, state, liveMeeting)
|
||||
|
||||
// Webcams
|
||||
case m: UserBroadcastCamStartMsg =>
|
||||
|
@ -16,20 +16,30 @@ case class PluginDataChannelPushEntryMsgBody(
|
||||
toUserIds: List[String],
|
||||
)
|
||||
|
||||
object PluginDataChannelReplaceEntryMsg { val NAME = "PluginDataChannelReplaceEntryMsg" }
|
||||
case class PluginDataChannelReplaceEntryMsg(header: BbbClientMsgHeader, body: PluginDataChannelReplaceEntryMsgBody) extends StandardMsg
|
||||
case class PluginDataChannelReplaceEntryMsgBody(
|
||||
pluginName: String,
|
||||
channelName: String,
|
||||
subChannelName: String,
|
||||
payloadJson: Map[String, Any],
|
||||
entryId: String,
|
||||
)
|
||||
|
||||
object PluginDataChannelDeleteEntryMsg { val NAME = "PluginDataChannelDeleteEntryMsg" }
|
||||
case class PluginDataChannelDeleteEntryMsg(header: BbbClientMsgHeader, body: PluginDataChannelDeleteEntryMsgBody) extends StandardMsg
|
||||
case class PluginDataChannelDeleteEntryMsgBody(
|
||||
pluginName: String,
|
||||
subChannelName: String,
|
||||
channelName: String,
|
||||
entryId: String
|
||||
)
|
||||
pluginName: String,
|
||||
subChannelName: String,
|
||||
channelName: String,
|
||||
entryId: String
|
||||
)
|
||||
|
||||
|
||||
object PluginDataChannelResetMsg { val NAME = "PluginDataChannelResetMsg" }
|
||||
case class PluginDataChannelResetMsg(header: BbbClientMsgHeader, body: PluginDataChannelResetMsgBody) extends StandardMsg
|
||||
case class PluginDataChannelResetMsgBody(
|
||||
pluginName: String,
|
||||
subChannelName: String,
|
||||
channelName: String
|
||||
)
|
||||
pluginName: String,
|
||||
subChannelName: String,
|
||||
channelName: String
|
||||
)
|
||||
|
@ -0,0 +1,38 @@
|
||||
import { RedisMessage } from '../types';
|
||||
import { ValidationError } from '../types/ValidationError';
|
||||
import {throwErrorIfInvalidInput} from "../imports/validation";
|
||||
|
||||
export default function buildRedisMessage(sessionVariables: Record<string, unknown>, input: Record<string, unknown>): RedisMessage {
|
||||
throwErrorIfInvalidInput(input,
|
||||
[
|
||||
{name: 'pluginName', type: 'string', required: true},
|
||||
{name: 'subChannelName', type: 'string', required: true},
|
||||
{name: 'channelName', type: 'string', required: true},
|
||||
{name: 'payloadJson', type: 'json', required: true},
|
||||
{name: 'entryId', type: 'string', required: true},
|
||||
]
|
||||
)
|
||||
|
||||
const eventName = `PluginDataChannelReplaceEntryMsg`;
|
||||
|
||||
const routing = {
|
||||
meetingId: sessionVariables['x-hasura-meetingid'] as String,
|
||||
userId: sessionVariables['x-hasura-userid'] as String
|
||||
};
|
||||
|
||||
const header = {
|
||||
name: eventName,
|
||||
meetingId: routing.meetingId,
|
||||
userId: routing.userId
|
||||
};
|
||||
|
||||
const body = {
|
||||
pluginName: input.pluginName,
|
||||
channelName: input.channelName,
|
||||
subChannelName: input.subChannelName,
|
||||
payloadJson: input.payloadJson,
|
||||
entryId: input.entryId,
|
||||
};
|
||||
|
||||
return { eventName, routing, header, body };
|
||||
}
|
@ -2033,13 +2033,13 @@ CREATE TABLE "pluginDataChannelEntry" (
|
||||
"entryId" varchar(50) DEFAULT uuid_generate_v4(),
|
||||
"subChannelName" varchar(255),
|
||||
"payloadJson" jsonb,
|
||||
"fromUserId" varchar(50),
|
||||
"createdBy" varchar(50),
|
||||
"toRoles" varchar[], --MODERATOR, VIEWER, PRESENTER
|
||||
"toUserIds" varchar[],
|
||||
"createdAt" timestamp with time zone DEFAULT current_timestamp,
|
||||
"deletedAt" timestamp with time zone,
|
||||
CONSTRAINT "pluginDataChannel_pkey" PRIMARY KEY ("meetingId","pluginName","channelName","entryId", "subChannelName"),
|
||||
FOREIGN KEY ("meetingId", "fromUserId") REFERENCES "user"("meetingId","userId") ON DELETE CASCADE
|
||||
FOREIGN KEY ("meetingId", "createdBy") REFERENCES "user"("meetingId","userId") ON DELETE CASCADE
|
||||
);
|
||||
create index "idx_pluginDataChannelEntry_pk_reverse" on "pluginDataChannelEntry"("pluginName", "meetingId", "channelName", "subChannelName");
|
||||
create index "idx_pluginDataChannelEntry_pk_reverse_b" on "pluginDataChannelEntry"("channelName", "pluginName", "meetingId", "subChannelName");
|
||||
@ -2048,7 +2048,7 @@ create index "idx_pluginDataChannelEntry_channelName" on "pluginDataChannelEntry
|
||||
create index "idx_pluginDataChannelEntry_roles" on "pluginDataChannelEntry"("meetingId", "toRoles", "toUserIds", "createdAt") where "deletedAt" is null;
|
||||
|
||||
CREATE OR REPLACE VIEW "v_pluginDataChannelEntry" AS
|
||||
SELECT u."meetingId", u."userId", m."pluginName", m."channelName", m."subChannelName", m."entryId", m."payloadJson", m."fromUserId", m."toRoles", m."createdAt"
|
||||
SELECT u."meetingId", u."userId", m."pluginName", m."channelName", m."subChannelName", m."entryId", m."payloadJson", m."createdBy", m."toRoles", m."createdAt"
|
||||
FROM "user" u
|
||||
JOIN "pluginDataChannelEntry" m ON m."meetingId" = u."meetingId"
|
||||
AND ((m."toRoles" IS NULL AND m."toUserIds" IS NULL)
|
||||
|
@ -234,6 +234,16 @@ type Mutation {
|
||||
): Boolean
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
pluginDataChannelReplaceEntry(
|
||||
pluginName: String!
|
||||
subChannelName: String!
|
||||
channelName: String!
|
||||
entryId: String!
|
||||
payloadJson: String!
|
||||
): Boolean
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
pluginDataChannelReset(
|
||||
pluginName: String!
|
||||
|
@ -203,6 +203,12 @@ actions:
|
||||
handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}'
|
||||
permissions:
|
||||
- role: bbb_client
|
||||
- name: pluginDataChannelReplaceEntry
|
||||
definition:
|
||||
kind: synchronous
|
||||
handler: '{{HASURA_BBB_GRAPHQL_ACTIONS_ADAPTER_URL}}'
|
||||
permissions:
|
||||
- role: bbb_client
|
||||
- name: pluginDataChannelReset
|
||||
definition:
|
||||
kind: synchronous
|
||||
|
@ -7,11 +7,11 @@ configuration:
|
||||
custom_name: pluginDataChannelEntry
|
||||
custom_root_fields: {}
|
||||
object_relationships:
|
||||
- name: sender
|
||||
- name: creator
|
||||
using:
|
||||
manual_configuration:
|
||||
column_mapping:
|
||||
fromUserId: userId
|
||||
createdBy: userId
|
||||
meetingId: meetingId
|
||||
insertion_order: null
|
||||
remote_table:
|
||||
@ -27,7 +27,7 @@ select_permissions:
|
||||
- channelName
|
||||
- entryId
|
||||
- payloadJson
|
||||
- fromUserId
|
||||
- createdBy
|
||||
- toRoles
|
||||
filter:
|
||||
_and:
|
||||
|
@ -5,12 +5,16 @@ import * as PluginSdk from 'bigbluebutton-html-plugin-sdk';
|
||||
import {
|
||||
DataChannelArguments,
|
||||
PushEntryFunction, ObjectTo, ToRole, ToUserId,
|
||||
ReplaceEntryFunctionArguments,
|
||||
} from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-channel/types';
|
||||
import { DataChannelHooks } from 'bigbluebutton-html-plugin-sdk/dist/cjs/data-channel/enums';
|
||||
import { HookEvents } from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/enum';
|
||||
import { HookEventWrapper, UpdatedEventDetails } from 'bigbluebutton-html-plugin-sdk/dist/cjs/core/types';
|
||||
|
||||
import { PLUGIN_DATA_CHANNEL_DELETE_MUTATION, PLUGIN_DATA_CHANNEL_PUSH_MUTATION, PLUGIN_DATA_CHANNEL_RESET_MUTATION } from '../mutations';
|
||||
import {
|
||||
PLUGIN_DATA_CHANNEL_DELETE_MUTATION, PLUGIN_DATA_CHANNEL_PUSH_MUTATION,
|
||||
PLUGIN_DATA_CHANNEL_REPLACE_MUTATION, PLUGIN_DATA_CHANNEL_RESET_MUTATION,
|
||||
} from '../mutations';
|
||||
|
||||
export interface DataChannelItemManagerWriterProps {
|
||||
pluginName: string;
|
||||
@ -46,9 +50,10 @@ const DataChannelItemManagerWriter: React.ElementType<DataChannelItemManagerWrit
|
||||
dataChannelIdentifier,
|
||||
} = props;
|
||||
|
||||
const [pushEntryFunctionPluginDataChannelMessage] = useMutation(PLUGIN_DATA_CHANNEL_PUSH_MUTATION);
|
||||
const [deleteEntryFunctionPluginDataChannelMessage] = useMutation(PLUGIN_DATA_CHANNEL_DELETE_MUTATION);
|
||||
const [resetFunctionPluginDataChannelMessage] = useMutation(PLUGIN_DATA_CHANNEL_RESET_MUTATION);
|
||||
const [pushEntryFunctionPluginDataChannel] = useMutation(PLUGIN_DATA_CHANNEL_PUSH_MUTATION);
|
||||
const [deleteEntryFunctionPluginDataChannel] = useMutation(PLUGIN_DATA_CHANNEL_DELETE_MUTATION);
|
||||
const [resetFunctionPluginDataChannel] = useMutation(PLUGIN_DATA_CHANNEL_RESET_MUTATION);
|
||||
const [replaceEntryFunctionPluginDataChannel] = useMutation(PLUGIN_DATA_CHANNEL_REPLACE_MUTATION);
|
||||
|
||||
const useDataChannelHandlerFunction = ((msg: object, objectsTo?: ObjectTo[]) => {
|
||||
const argumentsOfPushEntryFunction = {
|
||||
@ -82,7 +87,7 @@ const DataChannelItemManagerWriter: React.ElementType<DataChannelItemManagerWrit
|
||||
if (rolesTo.length > 0) argumentsOfPushEntryFunction.variables.toRoles = rolesTo;
|
||||
if (usersTo.length > 0) argumentsOfPushEntryFunction.variables.toUserIds = usersTo;
|
||||
}
|
||||
pushEntryFunctionPluginDataChannelMessage(argumentsOfPushEntryFunction);
|
||||
pushEntryFunctionPluginDataChannel(argumentsOfPushEntryFunction);
|
||||
}) as PushEntryFunction;
|
||||
|
||||
pluginApi.mapOfPushEntryFunctions[dataChannelIdentifier] = useDataChannelHandlerFunction;
|
||||
@ -93,7 +98,7 @@ const DataChannelItemManagerWriter: React.ElementType<DataChannelItemManagerWrit
|
||||
if (event.detail.hook === DataChannelHooks.DATA_CHANNEL_DELETE) {
|
||||
const eventDetails = event.detail as UpdatedEventDetails<string>;
|
||||
const hookArguments = eventDetails?.hookArguments as DataChannelArguments | undefined;
|
||||
deleteEntryFunctionPluginDataChannelMessage({
|
||||
deleteEntryFunctionPluginDataChannel({
|
||||
variables: {
|
||||
pluginName: hookArguments?.pluginName,
|
||||
channelName: hookArguments?.channelName,
|
||||
@ -104,7 +109,7 @@ const DataChannelItemManagerWriter: React.ElementType<DataChannelItemManagerWrit
|
||||
} else if (event.detail.hook === DataChannelHooks.DATA_CHANNEL_RESET) {
|
||||
const eventDetails = event.detail as UpdatedEventDetails<void>;
|
||||
const hookArguments = eventDetails?.hookArguments as DataChannelArguments | undefined;
|
||||
resetFunctionPluginDataChannelMessage({
|
||||
resetFunctionPluginDataChannel({
|
||||
variables: {
|
||||
pluginName: hookArguments?.pluginName,
|
||||
channelName: hookArguments?.channelName,
|
||||
@ -114,10 +119,29 @@ const DataChannelItemManagerWriter: React.ElementType<DataChannelItemManagerWrit
|
||||
}
|
||||
}) as EventListener;
|
||||
|
||||
const replaceEntryHandler: EventListener = (
|
||||
(event: HookEventWrapper<void>) => {
|
||||
if (event.detail.hook === DataChannelHooks.DATA_CHANNEL_REPLACE) {
|
||||
const eventDetails = event.detail as UpdatedEventDetails<ReplaceEntryFunctionArguments<object>>;
|
||||
const hookArguments = eventDetails?.hookArguments as DataChannelArguments | undefined;
|
||||
replaceEntryFunctionPluginDataChannel({
|
||||
variables: {
|
||||
pluginName: hookArguments?.pluginName,
|
||||
channelName: hookArguments?.channelName,
|
||||
subChannelName: hookArguments?.subChannelName,
|
||||
entryId: eventDetails.data.entryId,
|
||||
payloadJson: eventDetails.data.payloadJson,
|
||||
},
|
||||
});
|
||||
}
|
||||
}) as EventListener;
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener(HookEvents.UPDATED, deleteOrResetHandler);
|
||||
window.addEventListener(HookEvents.UPDATED, replaceEntryHandler);
|
||||
return () => {
|
||||
window.removeEventListener(HookEvents.UPDATED, deleteOrResetHandler);
|
||||
window.removeEventListener(HookEvents.UPDATED, replaceEntryHandler);
|
||||
};
|
||||
}, []);
|
||||
return null;
|
||||
|
@ -36,3 +36,17 @@ export const PLUGIN_DATA_CHANNEL_DELETE_MUTATION = gql`
|
||||
)
|
||||
}
|
||||
`;
|
||||
|
||||
export const PLUGIN_DATA_CHANNEL_REPLACE_MUTATION = gql`
|
||||
mutation PluginDataChannelReplaceEntry($pluginName: String!,
|
||||
$subChannelName: String!, $channelName: String!,
|
||||
$payloadJson: json!, $entryId: String!) {
|
||||
pluginDataChannelReplaceEntry(
|
||||
entryId: $entryId,
|
||||
pluginName: $pluginName,
|
||||
channelName: $channelName,
|
||||
subChannelName: $subChannelName,
|
||||
payloadJson: $payloadJson
|
||||
)
|
||||
}
|
||||
`;
|
||||
|
@ -16,7 +16,7 @@ const PLUGIN_DATA_CHANNEL_NEW_ITEMS = gql`
|
||||
subChannelName,
|
||||
entryId,
|
||||
payloadJson,
|
||||
fromUserId,
|
||||
createdBy,
|
||||
pluginName,
|
||||
toRoles,
|
||||
}
|
||||
@ -40,7 +40,7 @@ const PLUGIN_DATA_CHANNEL_All_ITEMS = gql`
|
||||
subChannelName,
|
||||
entryId,
|
||||
payloadJson,
|
||||
fromUserId,
|
||||
createdBy,
|
||||
pluginName,
|
||||
toRoles,
|
||||
}
|
||||
@ -65,7 +65,7 @@ const PLUGIN_DATA_CHANNEL_LATEST_ITEM = gql`
|
||||
subChannelName,
|
||||
entryId,
|
||||
payloadJson,
|
||||
fromUserId,
|
||||
createdBy,
|
||||
pluginName,
|
||||
toRoles,
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user