mirror of
https://github.com/hcengineering/platform.git
synced 2024-11-27 01:13:27 +03:00
Meeting attach record (#7196)
This commit is contained in:
parent
a374f22acc
commit
13c03e3d24
@ -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
|
||||
|
@ -89,6 +89,7 @@ async function createReception (client: MigrationUpgradeClient): Promise<void> {
|
||||
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 }
|
||||
)
|
||||
}
|
||||
},
|
||||
{
|
||||
|
@ -77,6 +77,7 @@
|
||||
"MeetingEnd": "Meeting end",
|
||||
"Status": "Status",
|
||||
"Active": "Active",
|
||||
"Finished": "Finished"
|
||||
"Finished": "Finished",
|
||||
"StartWithRecording": "Start with recording"
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,7 @@
|
||||
"MeetingEnd": "Fin de la reunión",
|
||||
"Status": "Estado",
|
||||
"Active": "Activo",
|
||||
"Finished": "Terminado"
|
||||
"Finished": "Terminado",
|
||||
"StartWithRecording": "Iniciar con grabación"
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,7 @@
|
||||
"MeetingEnd": "Fin de la réunion",
|
||||
"Status": "Statut",
|
||||
"Active": "Actif",
|
||||
"Finished": "Terminé"
|
||||
"Finished": "Terminé",
|
||||
"StartWithRecording": "Démarrer avec l'enregistrement"
|
||||
}
|
||||
}
|
@ -77,6 +77,7 @@
|
||||
"MeetingEnd": "Fine riunione",
|
||||
"Status": "Stato",
|
||||
"Active": "Attivo",
|
||||
"Finished": "Finito"
|
||||
"Finished": "Finito",
|
||||
"StartWithRecording": "Inizia con la registrazione"
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,7 @@
|
||||
"MeetingEnd": "Fim da reunião",
|
||||
"Status": "Estado",
|
||||
"Active": "Ativo",
|
||||
"Finished": "Finalizado"
|
||||
"Finished": "Finalizado",
|
||||
"StartWithRecording": "Começar com gravação"
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,7 @@
|
||||
"MeetingEnd": "Конец встречи",
|
||||
"Status": "Статус",
|
||||
"Active": "Активно",
|
||||
"Finished": "Завершено"
|
||||
"Finished": "Завершено",
|
||||
"StartWithRecording": "Начинать с записью"
|
||||
}
|
||||
}
|
||||
|
@ -77,6 +77,7 @@
|
||||
"MeetingEnd": "会议结束",
|
||||
"Status": "状态",
|
||||
"Active": "活动",
|
||||
"Finished": "已完成"
|
||||
"Finished": "已完成",
|
||||
"StartWithRecording": "开始录制"
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -26,6 +26,10 @@
|
||||
async function toggleTranscribing (): Promise<void> {
|
||||
await client.diffUpdate(room, { startWithTranscription: !room.startWithTranscription })
|
||||
}
|
||||
|
||||
async function toggleRecording (): Promise<void> {
|
||||
await client.diffUpdate(room, { startWithRecording: !room.startWithRecording })
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="antiGrid">
|
||||
@ -41,4 +45,10 @@
|
||||
</div>
|
||||
<ModernToggle size="small" checked={room.startWithTranscription} on:change={toggleTranscribing} />
|
||||
</div>
|
||||
<div class="antiGrid-row">
|
||||
<div class="antiGrid-row__header">
|
||||
<Label label={love.string.StartWithRecording} />
|
||||
</div>
|
||||
<ModernToggle size="small" checked={room.startWithRecording} on:change={toggleRecording} />
|
||||
</div>
|
||||
</div>
|
||||
|
@ -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<void> {
|
||||
const wsURL = getMetadata(love.metadata.WebSocketURL)
|
||||
@ -869,7 +873,7 @@ export async function record (room: Room): Promise<void> {
|
||||
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) {
|
||||
|
@ -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<Floor>,
|
||||
|
@ -33,6 +33,7 @@ export function createDefaultRooms (employees: Ref<Employee>[]): (Data<Room | Of
|
||||
person: employees[index] ?? null,
|
||||
language: 'en',
|
||||
startWithTranscription: false,
|
||||
startWithRecording: false,
|
||||
description: makeCollaborativeDoc(_id, 'description')
|
||||
}
|
||||
res.push(office)
|
||||
@ -51,6 +52,7 @@ export function createDefaultRooms (employees: Ref<Employee>[]): (Data<Room | Of
|
||||
y: 0,
|
||||
language: 'en',
|
||||
startWithTranscription: true,
|
||||
startWithRecording: true,
|
||||
description: makeCollaborativeDoc(allHands, 'description')
|
||||
})
|
||||
|
||||
@ -67,6 +69,7 @@ export function createDefaultRooms (employees: Ref<Employee>[]): (Data<Room | Of
|
||||
y: 4,
|
||||
language: 'en',
|
||||
startWithTranscription: true,
|
||||
startWithRecording: true,
|
||||
description: makeCollaborativeDoc(meetingRoom1, 'description')
|
||||
})
|
||||
const meetingRoom2 = generateId<Room>()
|
||||
@ -82,6 +85,7 @@ export function createDefaultRooms (employees: Ref<Employee>[]): (Data<Room | Of
|
||||
y: 4,
|
||||
language: 'en',
|
||||
startWithTranscription: true,
|
||||
startWithRecording: true,
|
||||
description: makeCollaborativeDoc(meetingRoom2, 'description')
|
||||
})
|
||||
const voiceRoom1 = generateId<Room>()
|
||||
@ -97,6 +101,7 @@ export function createDefaultRooms (employees: Ref<Employee>[]): (Data<Room | Of
|
||||
y: 8,
|
||||
language: 'en',
|
||||
startWithTranscription: false,
|
||||
startWithRecording: false,
|
||||
description: makeCollaborativeDoc(voiceRoom1, 'description')
|
||||
})
|
||||
const voiceRoom2 = generateId<Room>()
|
||||
@ -112,6 +117,7 @@ export function createDefaultRooms (employees: Ref<Employee>[]): (Data<Room | Of
|
||||
y: 8,
|
||||
language: 'en',
|
||||
startWithTranscription: false,
|
||||
startWithRecording: false,
|
||||
description: makeCollaborativeDoc(voiceRoom2, 'description')
|
||||
})
|
||||
return res
|
||||
|
@ -54,6 +54,7 @@
|
||||
"typescript": "^5.3.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"@hcengineering/attachment": "^0.6.14",
|
||||
"@hcengineering/love": "^0.6.0",
|
||||
"@hcengineering/drive": "^0.6.0",
|
||||
"@hcengineering/core": "^0.6.32",
|
||||
|
@ -13,13 +13,13 @@
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
import { toWorkspaceString, WorkspaceId } from '@hcengineering/core'
|
||||
import { Ref, toWorkspaceString, WorkspaceId } from '@hcengineering/core'
|
||||
import { setMetadata } from '@hcengineering/platform'
|
||||
import serverClient from '@hcengineering/server-client'
|
||||
import { initStatisticsContext, StorageConfig, StorageConfiguration } from '@hcengineering/server-core'
|
||||
import { buildStorageFromConfig, storageConfigFromEnv } from '@hcengineering/server-storage'
|
||||
import serverToken, { decodeToken } from '@hcengineering/server-token'
|
||||
import { RoomMetadata, TranscriptionStatus } from '@hcengineering/love'
|
||||
import { RoomMetadata, TranscriptionStatus, MeetingMinutes } from '@hcengineering/love'
|
||||
import cors from 'cors'
|
||||
import express from 'express'
|
||||
import { IncomingHttpHeaders } from 'http'
|
||||
@ -70,6 +70,7 @@ export const main = async (): Promise<void> => {
|
||||
name: string
|
||||
workspace: string
|
||||
workspaceId: WorkspaceId
|
||||
meetingMinutes?: Ref<MeetingMinutes>
|
||||
}
|
||||
>()
|
||||
|
||||
@ -86,7 +87,7 @@ export const main = async (): Promise<void> => {
|
||||
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<void> => {
|
||||
|
||||
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)
|
||||
|
@ -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<void> {
|
||||
async saveFile (uuid: string, name: string, blob: Blob, meetingMinutes?: Ref<MeetingMinutes>): Promise<void> {
|
||||
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<Blob>,
|
||||
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<Data<Attachment>, 'attachedToClass' | 'attachedTo' | 'collection'>,
|
||||
ref?: Ref<MeetingMinutes>
|
||||
): Promise<void> {
|
||||
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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user