From e2f48dc7eaa57171829a99c21e1eeca5d43ecfaf Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Fri, 7 Jun 2024 15:29:30 +0500 Subject: [PATCH] Improve office click handler (#5751) Signed-off-by: Denis Bykhov --- packages/theme/styles/love.scss | 3 + plugins/love-assets/assets/icons.svg | 5 ++ plugins/love-assets/lang/en.json | 2 + plugins/love-assets/lang/es.json | 4 +- plugins/love-assets/lang/pt.json | 4 +- plugins/love-assets/lang/ru.json | 2 + plugins/love-assets/src/index.ts | 3 +- .../src/components/ControlExt.svelte | 44 +++++++----- .../src/components/PersonActionPopup.svelte | 45 ++++++++++++ .../src/components/RoomPreview.svelte | 72 +++++++++++++++---- plugins/love-resources/src/plugin.ts | 4 +- plugins/love/src/index.ts | 3 +- 12 files changed, 155 insertions(+), 36 deletions(-) create mode 100644 plugins/love-resources/src/components/PersonActionPopup.svelte diff --git a/packages/theme/styles/love.scss b/packages/theme/styles/love.scss index 4c22e42a11..1fafbb1d48 100644 --- a/packages/theme/styles/love.scss +++ b/packages/theme/styles/love.scss @@ -30,6 +30,9 @@ } .floorGrid-room { + &.hovered:hover { + z-index: 10; + } &__header { align-items: center; top: calc(100% / var(--huly-floor-roomHeight) / 3 * -1.6 + 0.375rem + 1px); diff --git a/plugins/love-assets/assets/icons.svg b/plugins/love-assets/assets/icons.svg index 57f410da0e..bed5788e0a 100644 --- a/plugins/love-assets/assets/icons.svg +++ b/plugins/love-assets/assets/icons.svg @@ -72,4 +72,9 @@ + + + + + diff --git a/plugins/love-assets/lang/en.json b/plugins/love-assets/lang/en.json index a50f4bdb49..61f42b4332 100644 --- a/plugins/love-assets/lang/en.json +++ b/plugins/love-assets/lang/en.json @@ -44,6 +44,8 @@ "NoiseCancellation": "Noise cancellation", "KnockingLabel": "Knocking", "InivitingLabel": "Invite", + "Invite": "Invite", + "KnockAction": "Knock", "NoiseCancellationNotSupported": "Noise cancellation is not supported in this browser", "Blur": "Background blur", "BlurRadius": "Radius", diff --git a/plugins/love-assets/lang/es.json b/plugins/love-assets/lang/es.json index b4f3328288..a2fbaa0971 100644 --- a/plugins/love-assets/lang/es.json +++ b/plugins/love-assets/lang/es.json @@ -43,7 +43,9 @@ "YouInivite": "Estás invitando a unirte", "NoiseCancellation": "Cancelación de ruido", "KnockingLabel": "Tocando", - "InivitingLabel": "Invitar", + "InivitingLabel": "Invitación", + "Invite": "Invitar", + "KnockAction": "Golpear", "NoiseCancellationNotSupported": "La cancelación de ruido no es compatible con tu navegador", "Blur": "Desenfoque de fondo", "BlurRadius": "Radio de desenfoque", diff --git a/plugins/love-assets/lang/pt.json b/plugins/love-assets/lang/pt.json index 402c36e916..2d44a75641 100644 --- a/plugins/love-assets/lang/pt.json +++ b/plugins/love-assets/lang/pt.json @@ -43,7 +43,9 @@ "YouInivite": "Você está convidando para entrar", "NoiseCancellation": "Cancelamento de ruído", "KnockingLabel": "Batendo", - "InivitingLabel": "Convidar", + "InivitingLabel": "Convite", + "Invite": "Convidar", + "KnockAction": "Bater", "NoiseCancellationNotSupported": "Seu navegador não suporta cancelamento de ruído", "Blur": "Desfoque de fundo", "BlurRadius": "Raio de desfoque", diff --git a/plugins/love-assets/lang/ru.json b/plugins/love-assets/lang/ru.json index a3d452d54e..0a45693643 100644 --- a/plugins/love-assets/lang/ru.json +++ b/plugins/love-assets/lang/ru.json @@ -39,6 +39,8 @@ "RenameAFloor": "Переименовать этаж", "StartWithoutVideo": "Всегда начинать с выключенной камерой", "StartWithMutedMic": "Всегда начинать с выключенным звуком", + "Invite": "Пригласить", + "KnockAction": "Постучать", "InvitingYou": "{name} приглашает вас присоединиться", "YouInivite": "Вы приглашаете присоединиться", "NoiseCancellation": "Подавление шума", diff --git a/plugins/love-assets/src/index.ts b/plugins/love-assets/src/index.ts index 37803b9f8d..190ec541fd 100644 --- a/plugins/love-assets/src/index.ts +++ b/plugins/love-assets/src/index.ts @@ -33,5 +33,6 @@ loadMetadata(love.icon, { Knock: `${icons}#knock`, DND: `${icons}#dnd`, Record: `${icons}#record`, - StopRecord: `${icons}#stopRecord` + StopRecord: `${icons}#stopRecord`, + Invite: `${icons}#invite` }) diff --git a/plugins/love-resources/src/components/ControlExt.svelte b/plugins/love-resources/src/components/ControlExt.svelte index 7e41ac7ed3..e4cefc9f43 100644 --- a/plugins/love-resources/src/components/ControlExt.svelte +++ b/plugins/love-resources/src/components/ControlExt.svelte @@ -16,6 +16,18 @@ import { PersonAccount, formatName } from '@hcengineering/contact' import { Avatar, personByIdStore } from '@hcengineering/contact-resources' import { IdMap, Ref, getCurrentAccount, toIdMap } from '@hcengineering/core' + import { + Floor, + Invite, + JoinRequest, + Office, + ParticipantInfo, + RequestStatus, + Room, + RoomType, + isOffice, + loveId + } from '@hcengineering/love' import { getEmbeddedLabel } from '@hcengineering/platform' import { MessageBox, createQuery, getClient } from '@hcengineering/presentation' import { @@ -30,18 +42,6 @@ tooltip } from '@hcengineering/ui' import view from '@hcengineering/view' - import { - Floor, - Invite, - JoinRequest, - Office, - ParticipantInfo, - RequestStatus, - Room, - RoomType, - isOffice, - loveId - } from '@hcengineering/love' import { onDestroy } from 'svelte' import love from '../plugin' import { @@ -60,7 +60,6 @@ connectRoom, disconnect, getRoomName, - invite, isCameraEnabled, isConnected, isCurrentInstanceConnected, @@ -77,6 +76,7 @@ import FloorPopup from './FloorPopup.svelte' import InvitePopup from './InvitePopup.svelte' import MicSettingPopup from './MicSettingPopup.svelte' + import PersonActionPopup from './PersonActionPopup.svelte' import RequestPopup from './RequestPopup.svelte' import RequestingPopup from './RequestingPopup.svelte' import RoomPopup from './RoomPopup.svelte' @@ -338,6 +338,18 @@ const camKeys = client.getModel().findAllSync(view.class.Action, { _id: love.action.ToggleVideo })?.[0]?.keyBinding const micKeys = client.getModel().findAllSync(view.class.Action, { _id: love.action.ToggleMic })?.[0]?.keyBinding + + function participantClickHandler (e: MouseEvent, participant: ParticipantInfo): void { + if ($myInfo !== undefined) { + showPopup(PersonActionPopup, { room: reception, person: participant.person }, eventToHTMLElement(e)) + } + } + + function getParticipantClickHandler (participant: ParticipantInfo): (e: MouseEvent) => void { + return (e: MouseEvent) => { + participantClickHandler(e, participant) + } + }
@@ -422,11 +434,7 @@ {#each receptionParticipants as participant (participant._id)}
{ - if (myInfo) { - invite(participant.person, $myInfo?.room) - } - }} + on:click={getParticipantClickHandler(participant)} >
diff --git a/plugins/love-resources/src/components/PersonActionPopup.svelte b/plugins/love-resources/src/components/PersonActionPopup.svelte new file mode 100644 index 0000000000..e4b3364a11 --- /dev/null +++ b/plugins/love-resources/src/components/PersonActionPopup.svelte @@ -0,0 +1,45 @@ + + +
+ {#if $myInfo?.room !== room._id} + { + invite(person, $myInfo?.room) + }} + /> + {#if room.access === RoomAccess.Knock} + { + tryConnect($personByIdStore, $myInfo, room, info, $myRequests, $invites) + }} + /> + {/if} + {/if} +
+ + diff --git a/plugins/love-resources/src/components/RoomPreview.svelte b/plugins/love-resources/src/components/RoomPreview.svelte index 95b5430a51..4666cf6512 100644 --- a/plugins/love-resources/src/components/RoomPreview.svelte +++ b/plugins/love-resources/src/components/RoomPreview.svelte @@ -16,12 +16,13 @@ import { Person, type PersonAccount } from '@hcengineering/contact' import { Avatar, personByIdStore } from '@hcengineering/contact-resources' import { IdMap, getCurrentAccount } from '@hcengineering/core' - import { Icon, Label } from '@hcengineering/ui' import { ParticipantInfo, Room, RoomAccess, RoomType } from '@hcengineering/love' + import { Icon, Label, eventToHTMLElement, showPopup, showTooltip } from '@hcengineering/ui' + import { createEventDispatcher } from 'svelte' import love from '../plugin' import { invites, myInfo, myRequests } from '../stores' - import { getRoomLabel, invite, tryConnect } from '../utils' - import { createEventDispatcher } from 'svelte' + import { getRoomLabel, tryConnect } from '../utils' + import PersonActionPopup from './PersonActionPopup.svelte' export let room: Room export let info: ParticipantInfo[] @@ -51,17 +52,60 @@ } function mouseEnter (): void { + hovered = true dispatch('hover', { name: getRoomLabel(room, $personByIdStore) }) } - function clickHandler (x: number, y: number, person: Person | undefined): void { + function mouseLeave (): void { + hovered = false + } + + function clickHandler (e: MouseEvent, x: number, y: number, person: Person | undefined): void { if (person !== undefined) { - if (room._id === $myInfo?.room) return - invite(person._id, $myInfo?.room) + if (room._id === $myInfo?.room || $myInfo === undefined) return + showPopup(PersonActionPopup, { room, person: person._id }, eventToHTMLElement(e)) } else { tryConnect($personByIdStore, $myInfo, room, info, $myRequests, $invites, { x, y }) } } + + $: extraRow = calcExtraRows(hovered, room, info, $myInfo) + + function calcExtraRows ( + hovered: boolean, + room: Room, + info: ParticipantInfo[], + myInfo: ParticipantInfo | undefined + ): number { + if (!hovered) return 0 + let maxX = info.reduce((acc, p) => { + acc = Math.max(acc, p.x) + return acc + }, 0) + maxX++ + let init = maxX > room.width ? maxX - room.width : 0 + + for (let y = 0; y < room.height; y++) { + for (let x = 0; x < room.width; x++) { + if (info.find((p) => p.x === x && p.y === y) === undefined) { + return init + } + } + } + if (myInfo?.room !== room._id) { + init++ + while (init < 5) { + const x = room.width + init + for (let y = 0; y < room.height; y++) { + if (info.find((p) => p.x === x && p.y === y) === undefined) { + return init + } + } + init++ + } + } + return init + } @@ -73,17 +117,19 @@ class:hovered class:disabled class:myOffice={$myInfo?.room === room._id} - style:--huly-floor-roomWidth={room.width} + style:--huly-floor-roomWidth={room.width + extraRow} style:--huly-floor-roomHeight={room.height} - style:grid-column={`${room.x + 2} / span ${room.width}`} + style:grid-column={`${room.x + 2} / span ${room.width + extraRow}`} style:grid-row={`${room.y + 2} / span ${room.height}`} - style:grid-template-columns={`repeat(${room.width}, 1fr)`} + style:grid-template-columns={`repeat(${room.width + extraRow}, 1fr)`} style:grid-template-rows={`repeat(${room.height}, 1fr)`} - style:aspect-ratio={`${room.width} / ${room.height}`} + style:aspect-ratio={`${room.width + extraRow} / ${room.height}`} + on:mouseover|stopPropagation on:mouseenter|stopPropagation={mouseEnter} + on:mouseleave|stopPropagation={mouseLeave} > {#each new Array(room.height) as _, y} - {#each new Array(room.width) as _, x} + {#each new Array(room.width + extraRow) as _, x} {@const personInfo = getPersonInfo(y, x, info)} {@const person = getPerson(personInfo, $personByIdStore)} @@ -101,8 +147,8 @@ hoveredRoomX = undefined hoveredRoomY = undefined }} - on:click={() => { - clickHandler(x, y, person) + on:click={(e) => { + clickHandler(e, x, y, person) }} > {#if personInfo} diff --git a/plugins/love-resources/src/plugin.ts b/plugins/love-resources/src/plugin.ts index e1cfcf09d3..f1863a47cd 100644 --- a/plugins/love-resources/src/plugin.ts +++ b/plugins/love-resources/src/plugin.ts @@ -66,6 +66,8 @@ export default mergeIds(loveId, love, { CopyGuestLink: '' as IntlString, Record: '' as IntlString, StopRecord: '' as IntlString, - ServiceNotConfigured: '' as IntlString + ServiceNotConfigured: '' as IntlString, + Invite: '' as IntlString, + KnockAction: '' as IntlString } }) diff --git a/plugins/love/src/index.ts b/plugins/love/src/index.ts index 6fd3ca35b0..6fb6fbe9f6 100644 --- a/plugins/love/src/index.ts +++ b/plugins/love/src/index.ts @@ -134,7 +134,8 @@ const love = plugin(loveId, { Knock: '' as Asset, DND: '' as Asset, Record: '' as Asset, - StopRecord: '' as Asset + StopRecord: '' as Asset, + Invite: '' as Asset }, metadata: { WebSocketURL: '' as Metadata,