diff --git a/models/love/src/index.ts b/models/love/src/index.ts index 8a8295404b..567edb65c4 100644 --- a/models/love/src/index.ts +++ b/models/love/src/index.ts @@ -108,6 +108,7 @@ export class TRoom extends TDoc implements Room { language!: RoomLanguage startWithTranscription!: boolean + startWithRecording!: boolean @Prop(Collection(attachment.class.Attachment), attachment.string.Attachments, { shortLabel: attachment.string.Files }) attachments?: number diff --git a/models/love/src/migration.ts b/models/love/src/migration.ts index 916c9b96dc..be65d9912d 100644 --- a/models/love/src/migration.ts +++ b/models/love/src/migration.ts @@ -89,6 +89,7 @@ async function createReception (client: MigrationUpgradeClient): Promise { y: 0, language: 'en', startWithTranscription: false, + startWithRecording: false, description: makeCollaborativeDoc(love.ids.Reception, 'description') }, love.ids.Reception @@ -105,7 +106,7 @@ export const loveOperation: MigrateOperation = { } }, { - state: 'setup-defaults-settings', + state: 'setup-defaults-settings-v2', func: async (client: MigrationClient) => { await client.update( DOMAIN_LOVE, @@ -132,6 +133,21 @@ export const loveOperation: MigrateOperation = { { _class: love.class.Office, startWithTranscription: { $exists: false } }, { startWithTranscription: false } ) + await client.update( + DOMAIN_LOVE, + { _class: love.class.Room, type: RoomType.Video, startWithRecording: { $exists: false } }, + { startWithRecording: true } + ) + await client.update( + DOMAIN_LOVE, + { _class: love.class.Room, startWithRecording: { $exists: false } }, + { startWithRecording: false } + ) + await client.update( + DOMAIN_LOVE, + { _class: love.class.Office, startWithRecording: { $exists: false } }, + { startWithRecording: false } + ) } }, { diff --git a/plugins/love-assets/lang/en.json b/plugins/love-assets/lang/en.json index fe6e60c5f2..cfa427d098 100644 --- a/plugins/love-assets/lang/en.json +++ b/plugins/love-assets/lang/en.json @@ -77,6 +77,7 @@ "MeetingEnd": "Meeting end", "Status": "Status", "Active": "Active", - "Finished": "Finished" + "Finished": "Finished", + "StartWithRecording": "Start with recording" } } diff --git a/plugins/love-assets/lang/es.json b/plugins/love-assets/lang/es.json index d08f405c88..58b63972be 100644 --- a/plugins/love-assets/lang/es.json +++ b/plugins/love-assets/lang/es.json @@ -77,6 +77,7 @@ "MeetingEnd": "Fin de la reunión", "Status": "Estado", "Active": "Activo", - "Finished": "Terminado" + "Finished": "Terminado", + "StartWithRecording": "Iniciar con grabación" } } diff --git a/plugins/love-assets/lang/fr.json b/plugins/love-assets/lang/fr.json index 09ecb5916a..736318a6a3 100644 --- a/plugins/love-assets/lang/fr.json +++ b/plugins/love-assets/lang/fr.json @@ -77,6 +77,7 @@ "MeetingEnd": "Fin de la réunion", "Status": "Statut", "Active": "Actif", - "Finished": "Terminé" + "Finished": "Terminé", + "StartWithRecording": "Démarrer avec l'enregistrement" } } \ No newline at end of file diff --git a/plugins/love-assets/lang/it.json b/plugins/love-assets/lang/it.json index a89f600003..7463abbfb0 100644 --- a/plugins/love-assets/lang/it.json +++ b/plugins/love-assets/lang/it.json @@ -77,6 +77,7 @@ "MeetingEnd": "Fine riunione", "Status": "Stato", "Active": "Attivo", - "Finished": "Finito" + "Finished": "Finito", + "StartWithRecording": "Inizia con la registrazione" } } diff --git a/plugins/love-assets/lang/pt.json b/plugins/love-assets/lang/pt.json index 72c7b969b4..97412fb5c5 100644 --- a/plugins/love-assets/lang/pt.json +++ b/plugins/love-assets/lang/pt.json @@ -77,6 +77,7 @@ "MeetingEnd": "Fim da reunião", "Status": "Estado", "Active": "Ativo", - "Finished": "Finalizado" + "Finished": "Finalizado", + "StartWithRecording": "Começar com gravação" } } diff --git a/plugins/love-assets/lang/ru.json b/plugins/love-assets/lang/ru.json index 8dc27fe01d..124e1647d1 100644 --- a/plugins/love-assets/lang/ru.json +++ b/plugins/love-assets/lang/ru.json @@ -77,6 +77,7 @@ "MeetingEnd": "Конец встречи", "Status": "Статус", "Active": "Активно", - "Finished": "Завершено" + "Finished": "Завершено", + "StartWithRecording": "Начинать с записью" } } diff --git a/plugins/love-assets/lang/zh.json b/plugins/love-assets/lang/zh.json index 1270a31582..4902ff5397 100644 --- a/plugins/love-assets/lang/zh.json +++ b/plugins/love-assets/lang/zh.json @@ -77,6 +77,7 @@ "MeetingEnd": "会议结束", "Status": "状态", "Active": "活动", - "Finished": "已完成" + "Finished": "已完成", + "StartWithRecording": "开始录制" } } diff --git a/plugins/love-resources/src/components/AddRoomPopup.svelte b/plugins/love-resources/src/components/AddRoomPopup.svelte index 61093edc75..4d61e0b1fd 100644 --- a/plugins/love-resources/src/components/AddRoomPopup.svelte +++ b/plugins/love-resources/src/components/AddRoomPopup.svelte @@ -63,6 +63,7 @@ access: val.access, language: 'en', startWithTranscription: val._class !== love.class.Office && val.type === RoomType.Video, + startWithRecording: val._class !== love.class.Office && val.type === RoomType.Video, description: makeCollaborativeDoc(_id, 'description') } if (val._class === love.class.Office) { diff --git a/plugins/love-resources/src/components/RoomTranscriptionSettings.svelte b/plugins/love-resources/src/components/RoomTranscriptionSettings.svelte index 8a3a696678..36ef552fa6 100644 --- a/plugins/love-resources/src/components/RoomTranscriptionSettings.svelte +++ b/plugins/love-resources/src/components/RoomTranscriptionSettings.svelte @@ -26,6 +26,10 @@ async function toggleTranscribing (): Promise { await client.diffUpdate(room, { startWithTranscription: !room.startWithTranscription }) } + + async function toggleRecording (): Promise { + await client.diffUpdate(room, { startWithRecording: !room.startWithRecording }) + }
@@ -41,4 +45,10 @@
+
+
+
+ +
diff --git a/plugins/love-resources/src/utils.ts b/plugins/love-resources/src/utils.ts index 8b23e9cc39..49ffd92888 100644 --- a/plugins/love-resources/src/utils.ts +++ b/plugins/love-resources/src/utils.ts @@ -420,6 +420,10 @@ function initRoomMetadata (metadata: string | undefined): void { ) { void startTranscription(room) } + + if (get(isRecordingAvailable) && data.recording == null && room?.startWithRecording === true) { + void record(room) + } } export async function connect (name: string, room: Room, _id: string): Promise { const wsURL = getMetadata(love.metadata.WebSocketURL) @@ -869,7 +873,7 @@ export async function record (room: Room): Promise { Authorization: 'Bearer ' + token, 'Content-Type': 'application/json' }, - body: JSON.stringify({ roomName, room: room.name }) + body: JSON.stringify({ roomName, room: room.name, meetingMinutes: get(currentMeetingMinutes)?._id }) }) } } catch (err: any) { diff --git a/plugins/love/src/index.ts b/plugins/love/src/index.ts index 752f4bfb74..b6b8644db0 100644 --- a/plugins/love/src/index.ts +++ b/plugins/love/src/index.ts @@ -102,6 +102,7 @@ export interface Room extends Doc { y: number language: RoomLanguage startWithTranscription: boolean + startWithRecording: boolean description: CollaborativeDoc attachments?: number meetings?: number @@ -225,7 +226,8 @@ const love = plugin(loveId, { MeetingEnd: '' as IntlString, Status: '' as IntlString, Active: '' as IntlString, - Finished: '' as IntlString + Finished: '' as IntlString, + StartWithRecording: '' as IntlString }, ids: { MainFloor: '' as Ref, diff --git a/plugins/love/src/utils.ts b/plugins/love/src/utils.ts index 9eaa2c2d40..cb46f9aa75 100644 --- a/plugins/love/src/utils.ts +++ b/plugins/love/src/utils.ts @@ -33,6 +33,7 @@ export function createDefaultRooms (employees: Ref[]): (Data[]): (Data[]): (Data() @@ -82,6 +85,7 @@ export function createDefaultRooms (employees: Ref[]): (Data() @@ -97,6 +101,7 @@ export function createDefaultRooms (employees: Ref[]): (Data() @@ -112,6 +117,7 @@ export function createDefaultRooms (employees: Ref[]): (Data => { name: string workspace: string workspaceId: WorkspaceId + meetingMinutes?: Ref } >() @@ -86,7 +87,7 @@ export const main = async (): Promise => { const storedBlob = await storageAdapter.stat(ctx, data.workspaceId, filename) if (storedBlob !== undefined) { const client = await WorkspaceClient.create(data.workspace) - await client.saveFile(filename, data.name, storedBlob) + await client.saveFile(filename, data.name, storedBlob, data.meetingMinutes) await client.close() } dataByUUID.delete(res.filename) @@ -128,13 +129,14 @@ export const main = async (): Promise => { const roomName = req.body.roomName const room = req.body.room + const meetingMinutes = req.body.meetingMinutes const { workspace } = decodeToken(token) try { const dateStr = new Date().toISOString().replace('T', '_').slice(0, 19) const name = `${room}_${dateStr}.mp4` const id = await startRecord(storageConfig, egressClient, roomClient, roomName, workspace) - dataByUUID.set(id, { name, workspace: workspace.name, workspaceId: workspace }) + dataByUUID.set(id, { name, workspace: workspace.name, workspaceId: workspace, meetingMinutes }) res.send() } catch (e) { console.error(e) diff --git a/services/love/src/workspaceClient.ts b/services/love/src/workspaceClient.ts index 99ee6de361..f8293d7735 100644 --- a/services/love/src/workspaceClient.ts +++ b/services/love/src/workspaceClient.ts @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -import core, { Client, Ref, TxOperations, type Blob } from '@hcengineering/core' +import core, { Client, Ref, TxOperations, type Blob, Data } from '@hcengineering/core' import drive, { createFile } from '@hcengineering/drive' -import love from '@hcengineering/love' +import love, { MeetingMinutes } from '@hcengineering/love' import { generateToken } from '@hcengineering/server-token' +import attachment, { Attachment } from '@hcengineering/attachment' import { getClient } from './client' import config from './config' @@ -41,7 +42,7 @@ export class WorkspaceClient { return this.client } - async saveFile (uuid: string, name: string, blob: Blob): Promise { + async saveFile (uuid: string, name: string, blob: Blob, meetingMinutes?: Ref): Promise { const current = await this.client.findOne(drive.class.Drive, { _id: love.space.Drive }) if (current === undefined) { await this.client.createDoc( @@ -61,7 +62,6 @@ export class WorkspaceClient { } const data = { file: uuid as Ref, - title: name, size: blob.size, type: blob.contentType, lastModified: blob.modifiedOn, @@ -72,6 +72,26 @@ export class WorkspaceClient { originalWidth: 1280 } } - await createFile(this.client, love.space.Drive, drive.ids.Root, data) + await createFile(this.client, love.space.Drive, drive.ids.Root, { ...data, title: name }) + await this.attachToMeetingMinutes({ ...data, name }, meetingMinutes) + } + + async attachToMeetingMinutes ( + data: Omit, 'attachedToClass' | 'attachedTo' | 'collection'>, + ref?: Ref + ): Promise { + if (ref === undefined) return + + const meeting = await this.client.findOne(love.class.MeetingMinutes, { _id: ref }) + if (meeting === undefined) return + + await this.client.addCollection( + attachment.class.Attachment, + meeting.space, + meeting._id, + meeting._class, + 'attachments', + data + ) } }