mirror of
https://github.com/hcengineering/platform.git
synced 2025-05-01 12:47:46 +00:00
call invite sounds (#6013)
Signed-off-by: Vyacheslav Tumanov <me@slavatumanov.me>
This commit is contained in:
parent
987b8a8068
commit
0031ede489
@ -211,6 +211,16 @@ module.exports = [
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.(wav|ogg)$/,
|
||||
use: {
|
||||
loader: 'file-loader',
|
||||
options: {
|
||||
'name': 'snd/[contenthash].[ext]',
|
||||
esModule: false
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.svg$/,
|
||||
use: [
|
||||
|
@ -207,7 +207,8 @@ export function createModel (builder: Builder): void {
|
||||
objectClass: love.class.JoinRequest,
|
||||
providers: {
|
||||
[notification.providers.PlatformNotification]: true,
|
||||
[notification.providers.BrowserNotification]: true
|
||||
[notification.providers.BrowserNotification]: true,
|
||||
[notification.providers.SoundNotification]: true
|
||||
}
|
||||
},
|
||||
love.ids.KnockNotification
|
||||
|
@ -350,6 +350,15 @@ export function createModel (builder: Builder): void {
|
||||
notification.providers.BrowserNotification
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
notification.class.NotificationProvider,
|
||||
core.space.Model,
|
||||
{
|
||||
label: notification.string.Sound
|
||||
},
|
||||
notification.providers.SoundNotification
|
||||
)
|
||||
|
||||
builder.createDoc(
|
||||
notification.class.NotificationProvider,
|
||||
core.space.Model,
|
||||
|
@ -41,6 +41,7 @@
|
||||
"dependencies": {
|
||||
"@hcengineering/platform": "^0.6.11",
|
||||
"@hcengineering/core": "^0.6.32",
|
||||
"@hcengineering/notification": "^0.6.23",
|
||||
"@hcengineering/analytics": "^0.6.0",
|
||||
"@hcengineering/query": "^0.6.12",
|
||||
"@hcengineering/ui": "^0.6.15",
|
||||
|
@ -62,3 +62,4 @@ export * from './rules'
|
||||
export * from './search'
|
||||
export * from './image'
|
||||
export * from './preview'
|
||||
export * from './sound'
|
||||
|
54
packages/presentation/src/sound.ts
Normal file
54
packages/presentation/src/sound.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import { type Class, type Doc, type Ref } from '@hcengineering/core'
|
||||
import { type Asset, getMetadata } from '@hcengineering/platform'
|
||||
import { getClient } from '.'
|
||||
import notification from '@hcengineering/notification'
|
||||
|
||||
const sounds = new Map<Asset, AudioBufferSourceNode>()
|
||||
const context = new AudioContext()
|
||||
export async function prepareSound (key: string, _class?: Ref<Class<Doc>>, loop = false, play = false): Promise<void> {
|
||||
const notificationType =
|
||||
_class !== undefined
|
||||
? getClient().getModel().findAllSync(notification.class.NotificationType, { objectClass: _class })
|
||||
: undefined
|
||||
const notAllowed = notificationType?.[0].providers[notification.providers.SoundNotification] === false
|
||||
if (notificationType === undefined || notAllowed) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
const soundUrl = getMetadata(key as Asset) as string
|
||||
const audioBuffer = await fetch(soundUrl)
|
||||
.then(async (res) => await res.arrayBuffer())
|
||||
.then(async (ArrayBuffer) => await context.decodeAudioData(ArrayBuffer))
|
||||
const audio = context.createBufferSource()
|
||||
audio.buffer = audioBuffer
|
||||
audio.loop = loop
|
||||
sounds.set(key as Asset, audio)
|
||||
if (play) {
|
||||
playSound(key)
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('sound not found', key)
|
||||
}
|
||||
}
|
||||
|
||||
export function playSound (soundKey: string, _class?: Ref<Class<Doc>>, loop = false): void {
|
||||
const sound = sounds.get(soundKey as Asset)
|
||||
if (sound !== undefined) {
|
||||
try {
|
||||
sound.connect(context.destination)
|
||||
sound.start()
|
||||
} catch (err) {
|
||||
console.error('error happened during sound play', soundKey, err)
|
||||
}
|
||||
} else {
|
||||
void prepareSound(soundKey, _class, loop, true)
|
||||
}
|
||||
}
|
||||
|
||||
export function stopSound (soundKey: string): void {
|
||||
const sound = sounds.get(soundKey as Asset)
|
||||
if (sound !== undefined && sound?.context.state === 'running') {
|
||||
sound.stop()
|
||||
sound.disconnect(context.destination)
|
||||
}
|
||||
}
|
BIN
plugins/love-assets/assets/knock.wav
Normal file
BIN
plugins/love-assets/assets/knock.wav
Normal file
Binary file not shown.
@ -38,3 +38,6 @@ loadMetadata(love.icon, {
|
||||
ExitFullScreen: `${icons}#exitfullscreen`,
|
||||
Invite: `${icons}#invite`
|
||||
})
|
||||
loadMetadata(love.sound, {
|
||||
Knock: require('../assets/knock.wav')
|
||||
})
|
||||
|
@ -41,7 +41,6 @@
|
||||
)
|
||||
await connectRoom(place.x, place.y, $myInfo, myPerson, room)
|
||||
}
|
||||
|
||||
async function decline (): Promise<void> {
|
||||
await client.update(invite, { status: RequestStatus.Rejected })
|
||||
}
|
||||
|
@ -16,12 +16,13 @@
|
||||
import { PersonAccount, formatName } from '@hcengineering/contact'
|
||||
import { Avatar, personByIdStore } from '@hcengineering/contact-resources'
|
||||
import { getCurrentAccount } from '@hcengineering/core'
|
||||
import { getClient } from '@hcengineering/presentation'
|
||||
import { getClient, playSound, stopSound } from '@hcengineering/presentation'
|
||||
import { Button, Label } from '@hcengineering/ui'
|
||||
import { JoinRequest, RequestStatus } from '@hcengineering/love'
|
||||
import love from '../plugin'
|
||||
import { myInfo, myOffice } from '../stores'
|
||||
import { connectRoom, isConnected } from '../utils'
|
||||
import { onDestroy, onMount } from 'svelte'
|
||||
|
||||
export let request: JoinRequest
|
||||
|
||||
@ -42,6 +43,12 @@
|
||||
async function decline (): Promise<void> {
|
||||
await client.update(request, { status: RequestStatus.Rejected })
|
||||
}
|
||||
onMount(() => {
|
||||
playSound(love.sound.Knock, love.class.JoinRequest, true)
|
||||
})
|
||||
onDestroy(() => {
|
||||
stopSound(love.sound.Knock)
|
||||
})
|
||||
</script>
|
||||
|
||||
<div class="antiPopup flex-col-center">
|
||||
|
@ -140,6 +140,9 @@ const love = plugin(loveId, {
|
||||
ExitFullScreen: '' as Asset,
|
||||
Invite: '' as Asset
|
||||
},
|
||||
sound: {
|
||||
Knock: '' as Asset
|
||||
},
|
||||
metadata: {
|
||||
WebSocketURL: '' as Metadata<string>,
|
||||
ServiceEnpdoint: '' as Metadata<string>
|
||||
|
@ -48,6 +48,7 @@
|
||||
"Push": "Push",
|
||||
"Unreads": "Unreads",
|
||||
"EnablePush": "Enable push notifications",
|
||||
"NotificationBlockedInBrowser": "Notifications are blocked in your browser. Please enable notifications in your browser settings"
|
||||
"NotificationBlockedInBrowser": "Notifications are blocked in your browser. Please enable notifications in your browser settings",
|
||||
"Sound": "Sound"
|
||||
}
|
||||
}
|
||||
|
@ -47,6 +47,7 @@
|
||||
"UnstarDocument": "Desmarcar documento",
|
||||
"Push": "Push",
|
||||
"EnablePush": "Habilitar notificaciones push",
|
||||
"NotificationBlockedInBrowser": "Las notificaciones están bloqueadas en tu navegador. Por favor, habilita las notificaciones en la configuración de tu navegador."
|
||||
"NotificationBlockedInBrowser": "Las notificaciones están bloqueadas en tu navegador. Por favor, habilita las notificaciones en la configuración de tu navegador.",
|
||||
"Sound": "Sonido"
|
||||
}
|
||||
}
|
@ -48,6 +48,7 @@
|
||||
"Push": "Push",
|
||||
"Unreads": "Non lus",
|
||||
"EnablePush": "Activer les notifications push",
|
||||
"NotificationBlockedInBrowser": "Les notifications sont bloquées dans votre navigateur. Veuillez activer les notifications dans les paramètres de votre navigateur"
|
||||
"NotificationBlockedInBrowser": "Les notifications sont bloquées dans votre navigateur. Veuillez activer les notifications dans les paramètres de votre navigateur",
|
||||
"Sound": "Son"
|
||||
}
|
||||
}
|
@ -47,6 +47,7 @@
|
||||
"UnstarDocument": "Desmarcar documento",
|
||||
"Push": "Push",
|
||||
"EnablePush": "Ativar notificações push",
|
||||
"NotificationBlockedInBrowser": "Notificações bloqueadas no navegador. Por favor habilite las notificaciones en la configuración de su navegador."
|
||||
"NotificationBlockedInBrowser": "Notificações bloqueadas no navegador. Por favor habilite las notificaciones en la configuración de su navegador.",
|
||||
"Sound": "Som"
|
||||
}
|
||||
}
|
@ -48,6 +48,7 @@
|
||||
"Push": "Push",
|
||||
"Unreads": "Непрочитанные",
|
||||
"EnablePush": "Включить Push-уведомления",
|
||||
"NotificationBlockedInBrowser": "Уведомления заблокированы в вашем браузере. Пожалуйста, включите уведомления в настройках браузера"
|
||||
"NotificationBlockedInBrowser": "Уведомления заблокированы в вашем браузере. Пожалуйста, включите уведомления в настройках браузера",
|
||||
"Sound": "Звук"
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,7 @@
|
||||
"Push": "推送",
|
||||
"Unreads": "未读",
|
||||
"EnablePush": "启用推送通知",
|
||||
"NotificationBlockedInBrowser": "通知在您的浏览器中被阻止。请在浏览器设置中启用通知"
|
||||
"NotificationBlockedInBrowser": "通知在您的浏览器中被阻止。请在浏览器设置中启用通知",
|
||||
"Sound": "声音"
|
||||
}
|
||||
}
|
||||
|
@ -352,7 +352,8 @@ const notification = plugin(notificationId, {
|
||||
providers: {
|
||||
PlatformNotification: '' as Ref<NotificationProvider>,
|
||||
BrowserNotification: '' as Ref<NotificationProvider>,
|
||||
EmailNotification: '' as Ref<NotificationProvider>
|
||||
EmailNotification: '' as Ref<NotificationProvider>,
|
||||
SoundNotification: '' as Ref<NotificationProvider>
|
||||
},
|
||||
integrationType: {
|
||||
MobileApp: '' as Ref<IntegrationType>
|
||||
@ -400,7 +401,8 @@ const notification = plugin(notificationId, {
|
||||
ArchiveAllConfirmationMessage: '' as IntlString,
|
||||
YouAddedCollaborators: '' as IntlString,
|
||||
YouRemovedCollaborators: '' as IntlString,
|
||||
Push: '' as IntlString
|
||||
Push: '' as IntlString,
|
||||
Sound: '' as IntlString
|
||||
},
|
||||
function: {
|
||||
Notify: '' as Resource<NotifyFunc>,
|
||||
|
@ -36,7 +36,7 @@ export class NotificationsPage {
|
||||
documents = (): Locator => this.page.getByRole('button', { name: 'Documents' })
|
||||
requests = (): Locator => this.page.getByRole('button', { name: 'Requests' })
|
||||
todos = (): Locator => this.page.getByRole('button', { name: "Todo's" })
|
||||
chatMessageToggle = (): Locator => this.page.locator('div:nth-child(6) > .flex-between > .toggle > .toggle-switch')
|
||||
chatMessageToggle = (): Locator => this.page.locator('div:nth-child(7) > .flex-between > .toggle > .toggle-switch')
|
||||
|
||||
constructor (page: Page) {
|
||||
this.page = page
|
||||
|
Loading…
Reference in New Issue
Block a user