From 5924c4aef5ab824a9d039a436b398251b7351db6 Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Thu, 9 Jan 2025 17:39:22 +0500 Subject: [PATCH] Allow kick participant from office (#7620) Signed-off-by: Denis Bykhov --- plugins/love-assets/assets/icons.svg | 5 ++ plugins/love-assets/lang/cs.json | 4 +- plugins/love-assets/lang/en.json | 4 +- plugins/love-assets/lang/es.json | 4 +- plugins/love-assets/lang/fr.json | 4 +- plugins/love-assets/lang/it.json | 4 +- plugins/love-assets/lang/pt.json | 4 +- plugins/love-assets/lang/ru.json | 4 +- plugins/love-assets/lang/zh.json | 4 +- plugins/love-assets/src/index.ts | 3 +- .../src/components/ControlExt.svelte | 49 ++++++++----- .../src/components/PersonActionPopup.svelte | 20 ++++-- .../src/components/RoomPopup.svelte | 46 ++++++++---- .../src/components/RoomPreview.svelte | 2 +- .../src/components/WorkbenchExtension.svelte | 3 +- plugins/love-resources/src/utils.ts | 71 ++++++++++++------- plugins/love/src/index.ts | 7 +- 17 files changed, 164 insertions(+), 74 deletions(-) diff --git a/plugins/love-assets/assets/icons.svg b/plugins/love-assets/assets/icons.svg index 73fe21ad87..4e7d4cc5b3 100644 --- a/plugins/love-assets/assets/icons.svg +++ b/plugins/love-assets/assets/icons.svg @@ -89,4 +89,9 @@ + + + + + diff --git a/plugins/love-assets/lang/cs.json b/plugins/love-assets/lang/cs.json index 6c86bad07f..9b9c1f33c6 100644 --- a/plugins/love-assets/lang/cs.json +++ b/plugins/love-assets/lang/cs.json @@ -75,10 +75,12 @@ "JoinMeeting": "Připojit se ke schůzce", "MeetingStart": "Začátek schůzky", "MeetingEnd": "Konec schůzky", + "EndMeeting": "Ukončit schůzku", "Status": "Stav", "Active": "Aktivní", "Finished": "Dokončeno", "StartWithRecording": "Začít s nahráváním", - "Language": "Jazyk" + "Language": "Jazyk", + "Kick": "Vyhodit" } } \ No newline at end of file diff --git a/plugins/love-assets/lang/en.json b/plugins/love-assets/lang/en.json index 22cc2923a9..d86279790c 100644 --- a/plugins/love-assets/lang/en.json +++ b/plugins/love-assets/lang/en.json @@ -75,10 +75,12 @@ "JoinMeeting": "Join meeting", "MeetingStart": "Meeting start", "MeetingEnd": "Meeting end", + "EndMeeting": "End meeting", "Status": "Status", "Active": "Active", "Finished": "Finished", "StartWithRecording": "Start with recording", - "Language": "Language" + "Language": "Language", + "Kick": "Kick" } } diff --git a/plugins/love-assets/lang/es.json b/plugins/love-assets/lang/es.json index 8a50a54be6..d51bb0d0da 100644 --- a/plugins/love-assets/lang/es.json +++ b/plugins/love-assets/lang/es.json @@ -75,10 +75,12 @@ "JoinMeeting": "Unirse a la reunión", "MeetingStart": "Inicio de la reunión", "MeetingEnd": "Fin de la reunión", + "EndMeeting": "Terminar reunión", "Status": "Estado", "Active": "Activo", "Finished": "Terminado", "StartWithRecording": "Iniciar con grabación", - "Language": "Idioma" + "Language": "Idioma", + "Kick": "Expulsar" } } diff --git a/plugins/love-assets/lang/fr.json b/plugins/love-assets/lang/fr.json index 1c93c733a0..3f602a4675 100644 --- a/plugins/love-assets/lang/fr.json +++ b/plugins/love-assets/lang/fr.json @@ -75,10 +75,12 @@ "JoinMeeting": "Rejoindre la réunion", "MeetingStart": "Début de la réunion", "MeetingEnd": "Fin de la réunion", + "EndMeeting": "Terminer la réunion", "Status": "Statut", "Active": "Actif", "Finished": "Terminé", "StartWithRecording": "Démarrer avec l'enregistrement", - "Language": "Langue" + "Language": "Langue", + "Kick": "Expulser" } } \ No newline at end of file diff --git a/plugins/love-assets/lang/it.json b/plugins/love-assets/lang/it.json index aa569589fd..1a2bf3700a 100644 --- a/plugins/love-assets/lang/it.json +++ b/plugins/love-assets/lang/it.json @@ -75,10 +75,12 @@ "JoinMeeting": "Unisciti alla riunione", "MeetingStart": "Inizio riunione", "MeetingEnd": "Fine riunione", + "EndMeeting": "Termina riunione", "Status": "Stato", "Active": "Attivo", "Finished": "Finito", "StartWithRecording": "Inizia con la registrazione", - "Language": "Lingua" + "Language": "Lingua", + "Kick": "Espellere" } } diff --git a/plugins/love-assets/lang/pt.json b/plugins/love-assets/lang/pt.json index 28491c92a8..6547a98695 100644 --- a/plugins/love-assets/lang/pt.json +++ b/plugins/love-assets/lang/pt.json @@ -75,10 +75,12 @@ "JoinMeeting": "Participar na reunião", "MeetingStart": "Início da reunião", "MeetingEnd": "Fim da reunião", + "EndMeeting": "Terminar reunião", "Status": "Estado", "Active": "Ativo", "Finished": "Finalizado", "StartWithRecording": "Começar com gravação", - "Language": "Idioma" + "Language": "Idioma", + "Kick": "Expulsar" } } diff --git a/plugins/love-assets/lang/ru.json b/plugins/love-assets/lang/ru.json index 95ecdf8082..c430ccfb9b 100644 --- a/plugins/love-assets/lang/ru.json +++ b/plugins/love-assets/lang/ru.json @@ -75,10 +75,12 @@ "JoinMeeting": "Присоединиться к встрече", "MeetingStart": "Начало встречи", "MeetingEnd": "Конец встречи", + "EndMeeting": "Завершить встречу", "Status": "Статус", "Active": "Активно", "Finished": "Завершено", "StartWithRecording": "Начинать с записью", - "Language": "Язык" + "Language": "Язык", + "Kick": "Выгнать" } } diff --git a/plugins/love-assets/lang/zh.json b/plugins/love-assets/lang/zh.json index a665270a73..8c7415331e 100644 --- a/plugins/love-assets/lang/zh.json +++ b/plugins/love-assets/lang/zh.json @@ -75,10 +75,12 @@ "JoinMeeting": "加入会议", "MeetingStart": "会议开始", "MeetingEnd": "会议结束", + "EndMeeting": "结束会议", "Status": "状态", "Active": "活动", "Finished": "已完成", "StartWithRecording": "开始录制", - "Language": "语言" + "Language": "语言", + "Kick": "踢出" } } diff --git a/plugins/love-assets/src/index.ts b/plugins/love-assets/src/index.ts index 6e1f80e6cf..6ff830192f 100644 --- a/plugins/love-assets/src/index.ts +++ b/plugins/love-assets/src/index.ts @@ -36,7 +36,8 @@ loadMetadata(love.icon, { StopRecord: `${icons}#stopRecord`, FullScreen: `${icons}#fullscreen`, ExitFullScreen: `${icons}#exitfullscreen`, - Invite: `${icons}#invite` + Invite: `${icons}#invite`, + Kick: `${icons}#kick` }) loadMetadata(love.sound, { Knock: require('../assets/knock.wav') diff --git a/plugins/love-resources/src/components/ControlExt.svelte b/plugins/love-resources/src/components/ControlExt.svelte index 7ad226a8cf..1ecbd2ad66 100644 --- a/plugins/love-resources/src/components/ControlExt.svelte +++ b/plugins/love-resources/src/components/ControlExt.svelte @@ -14,7 +14,7 @@ -->
+ {#if isMyOffice && person !== $myInfo?.person} + { + kick(person, $rooms, $infos) + }} + /> + {/if} {#if $myInfo?.room !== room._id} p.room === room._id) @@ -104,6 +107,13 @@ dispatch('close') } + async function end (): Promise { + if (isOffice(room) && $myInfo !== undefined) { + await endMeeting(room, $rooms, $infos, $myInfo) + } + dispatch('close') + } + async function connect (): Promise { await tryConnect($personByIdStore, $myInfo, room, info, $myRequests, $invites) dispatch('close') @@ -218,17 +228,27 @@ />
{/if} - {#if $location.path[2] !== loveId || (joined && allowLeave) || !joined} + {#if $location.path[2] !== loveId || (joined && (allowLeave || isMyOffice)) || !joined}
- {#if joined && allowLeave} - - {:else if !joined} + {#if joined} + {#if allowLeave} + + {:else if isMyOffice} + + {/if} + {:else} - import { pushRootBarComponent, rootBarExtensions } from '@hcengineering/ui' + import { pushRootBarComponent } from '@hcengineering/ui' import { RemoteParticipant, RemoteTrack, RemoteTrackPublication, RoomEvent, Track } from 'livekit-client' import { onDestroy, onMount } from 'svelte' import love from '../plugin' import { disconnect, isCurrentInstanceConnected, lk } from '../utils' - import { generateId } from '@hcengineering/core' let parentElement: HTMLDivElement diff --git a/plugins/love-resources/src/utils.ts b/plugins/love-resources/src/utils.ts index 17bbe4c6c6..3dc80d9e00 100644 --- a/plugins/love-resources/src/utils.ts +++ b/plugins/love-resources/src/utils.ts @@ -1,19 +1,22 @@ +import aiBot from '@hcengineering/ai-bot' +import { connectMeeting, disconnectMeeting } from '@hcengineering/ai-bot-resources' import { Analytics } from '@hcengineering/analytics' import calendar, { type Event, getAllEvents } from '@hcengineering/calendar' +import chunter from '@hcengineering/chunter' import contact, { getName, type Person, type PersonAccount } from '@hcengineering/contact' import { personByIdStore } from '@hcengineering/contact-resources' import core, { AccountRole, concatLink, type Data, + type Doc, generateId, getCurrentAccount, + type Hierarchy, type IdMap, type Ref, type Space, - type TxOperations, - type Hierarchy, - type Doc + type TxOperations } from '@hcengineering/core' import login from '@hcengineering/login' import { @@ -24,16 +27,16 @@ import { LoveEvents, loveId, type Meeting, + type MeetingMinutes, + MeetingStatus, type Office, type ParticipantInfo, RequestStatus, type Room, RoomAccess, - RoomType, - TranscriptionStatus, type RoomMetadata, - type MeetingMinutes, - MeetingStatus + RoomType, + TranscriptionStatus } from '@hcengineering/love' import { getEmbeddedLabel, getMetadata, getResource, type IntlString } from '@hcengineering/platform' import presentation, { @@ -43,18 +46,29 @@ import presentation, { getClient } from '@hcengineering/presentation' import { + closePanel, type DropdownTextItem, getCurrentLocation, navigate, - showPopup, panelstore, - closePanel + showPopup } from '@hcengineering/ui' +import view from '@hcengineering/view' +import { getObjectLinkFragment } from '@hcengineering/view-resources' +import { type Widget, type WidgetTab } from '@hcengineering/workbench' +import { + currentWorkspaceStore, + openWidget, + openWidgetTab, + sidebarStore, + updateWidgetState +} from '@hcengineering/workbench-resources' import { isKrispNoiseFilterSupported, KrispNoiseFilter } from '@livekit/krisp-noise-filter' import { BackgroundBlur, type BackgroundOptions, type ProcessorWrapper } from '@livekit/track-processors' import { type AudioCaptureOptions, ConnectionState, + Room as LKRoom, LocalAudioTrack, type LocalTrack, type LocalTrackPublication, @@ -62,30 +76,16 @@ import { type RemoteParticipant, type RemoteTrack, type RemoteTrackPublication, - Room as LKRoom, RoomEvent, Track, type VideoCaptureOptions } from 'livekit-client' import { get, writable } from 'svelte/store' -import aiBot from '@hcengineering/ai-bot' -import { connectMeeting, disconnectMeeting } from '@hcengineering/ai-bot-resources' -import { - openWidget, - sidebarStore, - updateWidgetState, - currentWorkspaceStore, - openWidgetTab -} from '@hcengineering/workbench-resources' -import { type Widget, type WidgetTab } from '@hcengineering/workbench' -import view from '@hcengineering/view' -import chunter from '@hcengineering/chunter' -import { getObjectLinkFragment } from '@hcengineering/view-resources' import { sendMessage } from './broadcast' -import love from './plugin' -import { $myPreferences, currentRoom, currentMeetingMinutes, selectedRoomPlace, myOffice } from './stores' import RoomSettingsPopup from './components/RoomSettingsPopup.svelte' +import love from './plugin' +import { $myPreferences, currentMeetingMinutes, currentRoom, myOffice, selectedRoomPlace } from './stores' export const selectedCamId = 'selectedDevice_cam' export const selectedMicId = 'selectedDevice_mic' @@ -860,6 +860,27 @@ export async function tryConnect ( } } +export async function endMeeting ( + room: Office, + rooms: Room[], + infos: ParticipantInfo[], + currentInfo: ParticipantInfo +): Promise { + const roomInfos = infos.filter((p) => p.room === room._id && room.person !== p.person) + for (const roomInfo of roomInfos) { + await kick(roomInfo.person, rooms, infos) + } + await leaveRoom(currentInfo, room) +} + +export async function kick (person: Ref, rooms: Room[], infos: ParticipantInfo[]): Promise { + const personInfo = infos.find((p) => p.person === person) + if (personInfo === undefined) return + const personOffice = rooms.find((r) => isOffice(r) && r.person === personInfo.person) + const client = getClient() + await client.update(personInfo, { room: personOffice?._id ?? love.ids.Reception, x: 0, y: 0 }) +} + export async function invite (person: Ref, room: Ref | undefined): Promise { if (room === undefined || room === love.ids.Reception) return const client = getClient() diff --git a/plugins/love/src/index.ts b/plugins/love/src/index.ts index 33c4e1790b..cbb774f2b5 100644 --- a/plugins/love/src/index.ts +++ b/plugins/love/src/index.ts @@ -225,7 +225,9 @@ const love = plugin(loveId, { Status: '' as IntlString, Active: '' as IntlString, Finished: '' as IntlString, - StartWithRecording: '' as IntlString + StartWithRecording: '' as IntlString, + Kick: '' as IntlString, + EndMeeting: '' as IntlString }, ids: { MainFloor: '' as Ref, @@ -254,7 +256,8 @@ const love = plugin(loveId, { StopRecord: '' as Asset, FullScreen: '' as Asset, ExitFullScreen: '' as Asset, - Invite: '' as Asset + Invite: '' as Asset, + Kick: '' as Asset }, sound: { Knock: '' as Asset