Skip to content
Merged
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Change Log

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/) and this
project adheres to [Semantic Versioning](http://semver.org/).

## [1.1.0] 2024-08-30

### Added

- Support for breakout rooms.

## [1.0.0] - 2024-06-03

### Added

- Change message overlay for the main room in a VMR (only Pexip Infinity v35 and
later).
595 changes: 304 additions & 291 deletions package-lock.json

Large diffs are not rendered by default.

11 changes: 5 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
{
"name": "message-overlay",
"version": "1.0.0",
"version": "1.1.0",
"description": "Plugin that allows the host to display messages embedded in the video stream.",
"main": "index.js",
"scripts": {
"start": "vite",
"build": "vite build",
"test": "jest --detectOpenHandles --silent",
"lint": "eslint ."
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module",
"dependencies": {
"@pexip/plugin-api": "19.3.2"
"@pexip/plugin-api": "19.3.3"
},
"devDependencies": {
"eslint": "^8.1.0",
"eslint-config-love": "^47.0.0",
"eslint-config-prettier": "^9.1.0",
"prettier": "^3.3.0",
"prettier": "^3.3.3",
"typescript": "^5.4.5",
"vite": "^5.2.12",
"vite-plugin-mkcert": "^1.17.5"
"vite": "^5.4.2",
"vite-plugin-mkcert": "^1.17.6"
}
}
47 changes: 47 additions & 0 deletions src/forms/createInputMessageForm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { setMessageOverlay } from '../messageOverlay'
import { plugin } from '../plugin'

export const createInputMessageForm = async (
roomId: string,
currentMessage: string,
roomName?: string,
breakoutRooms?: Map<string, string>
): Promise<void> => {
const messageName =
roomName != null ? `"${roomName}" message` : 'Room message'

const form = await plugin.ui.addForm({
title: 'Set message overlay',
description:
'Write your message overlay text below. If you would like to get a new line press enter or make a new line in the textarea',
form: {
elements: {
message: {
name: messageName,
type: 'textarea',
isOptional: true,
placeholder: 'Enter your message',
value: currentMessage
}
},
submitBtnTitle: 'Submit'
}
})

form.onInput.add(async (result): Promise<void> => {
await form.remove()

if (result.message == null) {
return
}

if (roomId === '') {
setMessageOverlay('main', result.message).catch(console.error)
breakoutRooms?.forEach((_breakoutName, breakoutUuid) => {
setMessageOverlay(breakoutUuid, result.message).catch(console.error)
})
} else {
setMessageOverlay(roomId, result.message).catch(console.error)
}
})
}
64 changes: 64 additions & 0 deletions src/forms/createSelectRoomForm.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { createInputMessageForm } from './createInputMessageForm'
import { getMessageOverlay } from '../messageOverlay'
import { plugin } from '../plugin'

export const createSelectRoomForm = async (
breakoutRooms: Map<string, string>
): Promise<void> => {
const form = await plugin.ui.addForm({
title: 'Set message overlay',
description: 'Choose the room you want to set the message overlay for.',
form: {
elements: {
room: {
name: 'Select room',
type: 'select',
isOptional: true,
options: [
{
id: '',
label: 'All rooms'
},
{
id: 'main',
label: 'Main room'
},
...Array.from(breakoutRooms).map(([roomId, roomName]) => ({
id: roomId,
label: roomName
}))
]
}
},
submitBtnTitle: 'Choose'
}
})

form.onInput.add(async (result): Promise<void> => {
await form.remove()

if (result.room == null) {
return
}

const roomId = result.room
let currentMessage = ''

if (roomId !== '') {
try {
currentMessage = await getMessageOverlay(result.room)
} catch (e) {
console.error(e)
}
}

const roomName =
roomId === ''
? 'All rooms'
: roomId === 'main'
? 'Main room'
: breakoutRooms.get(roomId)

await createInputMessageForm(roomId, currentMessage, roomName)
})
}
97 changes: 36 additions & 61 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,46 @@
import { type Button, registerPlugin } from '@pexip/plugin-api'
import { createSelectRoomForm } from './forms/createSelectRoomForm'
import { getMessageOverlay } from './messageOverlay'
import { createInputMessageForm } from './forms/createInputMessageForm'
import { setPlugin } from './plugin'

const plugin = await registerPlugin({
id: 'message-overlay',
version: 0
version: 1
})

setPlugin(plugin)

let button: Button<'settingsMenu'> | null = null
let creatingButton = false

const breakoutRooms = new Map<string, string>()

plugin.events.authenticatedWithConference.add(async () => {
breakoutRooms.clear()
})
Comment thread
TsvetozarTsonev marked this conversation as resolved.

plugin.events.breakoutBegin.add(async (breakoutRoom) => {
breakoutRooms.set(breakoutRoom.breakout_uuid, '')
})

plugin.events.breakoutEnd.add(async (breakoutRoom) => {
breakoutRooms.delete(breakoutRoom.breakout_uuid)
})

plugin.events.conferenceStatus.add(async ({ id, status }) => {
if (id === 'main' && !status.directMedia && status.started) {
if (breakoutRooms.has(id) && status.breakoutName != null) {
Comment thread
TsvetozarTsonev marked this conversation as resolved.
breakoutRooms.set(id, status.breakoutName)
}

if (!status.directMedia && status.started) {
await addButton()
} else {
await removeButton()
}
})

const addButton = async (): Promise<void> => {
console.log('addButton')
if (button != null || creatingButton) {
return
}
Expand All @@ -43,65 +66,17 @@ const removeButton = async (): Promise<void> => {
}

const handleClickButton = async (): Promise<void> => {
let currentMessage = ''
try {
currentMessage = await getMessageOverlay()
console.log(currentMessage)
} catch (e) {
console.error(e)
}
await createForm(currentMessage)
}

const createForm = async (currentMessage: string): Promise<void> => {
const form = await plugin.ui.addForm({
title: 'Set message overlay',
description:
'Write your message overlay text below. If you would like to get a new line press enter or make a new line in the textarea',
form: {
elements: {
message: {
name: 'Enter text',
type: 'textarea',
isOptional: true,
placeholder: 'Enter your message',
value: currentMessage
}
},
submitBtnTitle: 'Submit'
}
})
if (breakoutRooms.size > 0) {
await createSelectRoomForm(breakoutRooms)
} else {
const roomId = 'main'
let currentMessage = ''

form.onInput.add((result): void => {
handleFormSubmit(form, result).catch((e) => {
try {
currentMessage = await getMessageOverlay(roomId)
} catch (e) {
console.error(e)
})
})
}

const handleFormSubmit = async (
form: any,
result: {
message: string
}
await createInputMessageForm(roomId, currentMessage)
}
): Promise<void> => {
form?.remove()
await setMessageOverlay(result.message)
}

const getMessageOverlay = async (): Promise<string> => {
const response = await (plugin.conference as any).sendRequest({
method: 'GET',
path: 'get_message_text'
})
console.log(response)
return response.data.result.text ?? ''
}

const setMessageOverlay = async (text: string): Promise<void> => {
await (plugin.conference as any).sendRequest({
method: 'POST',
path: 'set_message_text',
payload: { text }
})
}
31 changes: 31 additions & 0 deletions src/messageOverlay.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { plugin } from './plugin'

export const getMessageOverlay = async (roomId: string): Promise<string> => {
let path = 'get_message_text'
if (roomId !== 'main') {
path = `breakouts/${roomId}/${path}`
}

const response = await (plugin.conference as any).sendRequest({
method: 'GET',
path
})

return response.data.result.text ?? ''
}

export const setMessageOverlay = async (
roomId: string,
text: string
): Promise<void> => {
let path = 'set_message_text'
if (roomId !== 'main') {
path = `breakouts/${roomId}/${path}`
}

;(plugin.conference as any).sendRequest({
method: 'POST',
path,
payload: { text }
})
}
7 changes: 7 additions & 0 deletions src/plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { type Plugin } from '@pexip/plugin-api'

export let plugin: Plugin

export const setPlugin = (p: Plugin): void => {
plugin = p
}