Skip to content

Add sound notification #3270

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/components/common/FormAudioUpload.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<template>
<FormFileUpload
:modelValue="modelValue"
@update:modelValue="emit('update:modelValue', $event)"
inputAccept="audio/*"
>
<template #preview>
<div
class="preview-box border rounded p-2 w-16 h-16 flex items-center justify-center"
:class="{ 'bg-gray-100 dark:bg-gray-800': !modelValue }"
>
<audio
v-if="modelValue"
:src="modelValue"
class="max-w-full max-h-full object-contain"
controls
/>
<i v-else class="pi pi-volume-up text-gray-400 text-xl"></i>
</div>
</template>
</FormFileUpload>
</template>

<script setup lang="ts">
import FormFileUpload from './FormFileUpload.vue'

defineProps<{
modelValue: string
}>()

const emit = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()
</script>
71 changes: 71 additions & 0 deletions src/components/common/FormFileUpload.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<template>
<div class="image-upload-wrapper">
<div class="flex gap-2 items-center">
<slot name="preview"></slot>

<div class="flex flex-col gap-2">
<Button
icon="pi pi-upload"
:label="$t('g.upload')"
size="small"
@click="triggerFileInput"
/>
<Button
v-if="modelValue"
class="w-full"
outlined
icon="pi pi-trash"
severity="danger"
size="small"
@click="clear"
/>
</div>
</div>
<input
ref="fileInput"
type="file"
class="hidden"
:accept="inputAccept"
@change="handleFileUpload"
/>
</div>
</template>

<script setup lang="ts">
import Button from 'primevue/button'
import { ref } from 'vue'

defineProps<{
modelValue: string
inputAccept: string
}>()

const emit = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()

const fileInput = ref<HTMLInputElement | null>(null)

const triggerFileInput = () => {
fileInput.value?.click()
}

const handleFileUpload = (event: Event) => {
const target = event.target as HTMLInputElement
if (target.files && target.files[0]) {
const file = target.files[0]
const reader = new FileReader()
reader.onload = (e) => {
emit('update:modelValue', e.target?.result as string)
}
reader.readAsDataURL(file)
}
}

const clear = () => {
emit('update:modelValue', '')
if (fileInput.value) {
fileInput.value.value = ''
}
}
</script>
65 changes: 9 additions & 56 deletions src/components/common/FormImageUpload.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<template>
<div class="image-upload-wrapper">
<div class="flex gap-2 items-center">
<FormFileUpload
:modelValue="modelValue"
@update:modelValue="emit('update:modelValue', $event)"
inputAccept="image/*"
>
<template #preview>
<div
class="preview-box border rounded p-2 w-16 h-16 flex items-center justify-center"
:class="{ 'bg-gray-100 dark:bg-gray-800': !modelValue }"
Expand All @@ -12,38 +16,12 @@
/>
<i v-else class="pi pi-image text-gray-400 text-xl"></i>
</div>

<div class="flex flex-col gap-2">
<Button
icon="pi pi-upload"
:label="$t('g.upload')"
size="small"
@click="triggerFileInput"
/>
<Button
v-if="modelValue"
class="w-full"
outlined
icon="pi pi-trash"
severity="danger"
size="small"
@click="clearImage"
/>
</div>
</div>
<input
ref="fileInput"
type="file"
class="hidden"
accept="image/*"
@change="handleFileUpload"
/>
</div>
</template>
</FormFileUpload>
</template>

<script setup lang="ts">
import Button from 'primevue/button'
import { ref } from 'vue'
import FormFileUpload from './FormFileUpload.vue'

defineProps<{
modelValue: string
Expand All @@ -52,29 +30,4 @@ defineProps<{
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()

const fileInput = ref<HTMLInputElement | null>(null)

const triggerFileInput = () => {
fileInput.value?.click()
}

const handleFileUpload = (event: Event) => {
const target = event.target as HTMLInputElement
if (target.files && target.files[0]) {
const file = target.files[0]
const reader = new FileReader()
reader.onload = (e) => {
emit('update:modelValue', e.target?.result as string)
}
reader.readAsDataURL(file)
}
}

const clearImage = () => {
emit('update:modelValue', '')
if (fileInput.value) {
fileInput.value.value = ''
}
}
</script>
3 changes: 3 additions & 0 deletions src/components/common/FormItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import ToggleSwitch from 'primevue/toggleswitch'
import { type Component, markRaw } from 'vue'

import CustomFormValue from '@/components/common/CustomFormValue.vue'
import FormAudioUpload from '@/components/common/FormAudioUpload.vue'
import FormColorPicker from '@/components/common/FormColorPicker.vue'
import FormImageUpload from '@/components/common/FormImageUpload.vue'
import InputKnob from '@/components/common/InputKnob.vue'
Expand Down Expand Up @@ -98,6 +99,8 @@ function getFormComponent(item: FormItem): Component {
return Select
case 'image':
return FormImageUpload
case 'audio':
return FormAudioUpload
case 'color':
return FormColorPicker
case 'url':
Expand Down
1 change: 1 addition & 0 deletions src/extensions/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import './saveImageExtraOutput'
import './saveMesh'
import './simpleTouchSupport'
import './slotDefaults'
import './soundNotification'
import './uploadAudio'
import './uploadImage'
import './webcamCapture'
Expand Down
56 changes: 56 additions & 0 deletions src/extensions/core/soundNotification.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { StatusWsMessageStatus } from '../../schemas/apiSchema'
import { api } from '../../scripts/api'
import { app } from '../../scripts/app'

app.registerExtension({
name: 'Comfy.SoundNotification',
init() {
app.ui.settings.addSetting({
id: 'Comfy.SoundNotification.AfterOnePrompt',
name: 'After executing a prompt',
type: 'audio',
defaultValue: undefined
})
app.ui.settings.addSetting({
id: 'Comfy.SoundNotification.AfterAllPrompts',
name: 'After executing all the prompts',
type: 'audio',
defaultValue: undefined
})

let lastQueueRemaining: number = 0
let audio: HTMLAudioElement | null = null

function playAudio(settingId: string) {
if (!audio || audio.paused) {
const soundData = app.ui.settings.getSettingValue(settingId)
if (soundData) {
audio = new Audio(soundData)
audio.play()
}
}
}

api.addEventListener(
'status',
(event: CustomEvent<StatusWsMessageStatus>): void => {
const queueRemaining = event.detail.exec_info.queue_remaining
if (lastQueueRemaining > 0 && queueRemaining === 0) {
// In order to prevent "AfterAllPrompts" sound from being played when another prompt is immediately queued,
// checking again after a short delay.
// TODO: more reliable way
setTimeout(() => {
if (lastQueueRemaining === 0) {
playAudio('Comfy.SoundNotification.AfterAllPrompts')
} else {
playAudio('Comfy.SoundNotification.AfterOnePrompt')
}
}, 500)
} else if (queueRemaining < lastQueueRemaining) {
playAudio('Comfy.SoundNotification.AfterOnePrompt')
}
lastQueueRemaining = queueRemaining
}
)
}
})
1 change: 1 addition & 0 deletions src/locales/en/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,7 @@
"Server": "Server",
"Settings": "Settings",
"Sidebar": "Sidebar",
"SoundNotification": "Sound Notification",
"Tree Explorer": "Tree Explorer",
"Validation": "Validation",
"Window": "Window",
Expand Down
6 changes: 6 additions & 0 deletions src/locales/en/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
{
"Comfy_SoundNotification_AfterAllPrompts": {
"name": "After executing all prompts"
},
"Comfy_SoundNotification_AfterOnePrompt": {
"name": "After executing a prompt"
},
"Comfy-Desktop_AutoUpdate": {
"name": "Automatically check for updates"
},
Expand Down
1 change: 1 addition & 0 deletions src/locales/es/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@
"Server-Config": "Configuración del Servidor",
"Settings": "Configuraciones",
"Sidebar": "Barra Lateral",
"SoundNotification": "Notificación de Sonido",
"Tree Explorer": "Explorador de Árbol",
"UV": "UV",
"Validation": "Validación",
Expand Down
6 changes: 6 additions & 0 deletions src/locales/es/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
{
"Comfy_SoundNotification_AfterAllPrompts": {
"name": "Después de ejecutar todas las indicaciones"
},
"Comfy_SoundNotification_AfterOnePrompt": {
"name": "Después de ejecutar una indicación"
},
"Comfy-Desktop_AutoUpdate": {
"name": "Verificar actualizaciones automáticamente"
},
Expand Down
1 change: 1 addition & 0 deletions src/locales/fr/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@
"Server-Config": "Config-Serveur",
"Settings": "Paramètres",
"Sidebar": "Barre Latérale",
"SoundNotification": "Notification Sonore",
"Tree Explorer": "Explorateur d'Arbre",
"UV": "UV",
"Validation": "Validation",
Expand Down
6 changes: 6 additions & 0 deletions src/locales/fr/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
{
"Comfy_SoundNotification_AfterAllPrompts": {
"name": "Après avoir exécuté toutes les invites"
},
"Comfy_SoundNotification_AfterOnePrompt": {
"name": "Après avoir exécuté une invite"
},
"Comfy-Desktop_AutoUpdate": {
"name": "Vérifier automatiquement les mises à jour"
},
Expand Down
1 change: 1 addition & 0 deletions src/locales/ja/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@
"Server-Config": "サーバー設定",
"Settings": "設定",
"Sidebar": "サイドバー",
"SoundNotification": "サウンド通知",
"Tree Explorer": "ツリーエクスプローラー",
"UV": "UV",
"Validation": "検証",
Expand Down
6 changes: 6 additions & 0 deletions src/locales/ja/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
{
"Comfy_SoundNotification_AfterAllPrompts": {
"name": "全てのプロンプト実行後"
},
"Comfy_SoundNotification_AfterOnePrompt": {
"name": "プロンプト実行後"
},
"Comfy-Desktop_AutoUpdate": {
"name": "自動的に更新を確認する"
},
Expand Down
1 change: 1 addition & 0 deletions src/locales/ko/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@
"Server-Config": "서버 구성",
"Settings": "설정",
"Sidebar": "사이드바",
"SoundNotification": "소리 알림",
"Tree Explorer": "트리 탐색기",
"UV": "UV",
"Validation": "검증",
Expand Down
6 changes: 6 additions & 0 deletions src/locales/ko/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
{
"Comfy_SoundNotification_AfterAllPrompts": {
"name": "모든 프롬프트를 실행한 후"
},
"Comfy_SoundNotification_AfterOnePrompt": {
"name": "프롬프트를 실행한 후"
},
"Comfy-Desktop_AutoUpdate": {
"name": "자동 업데이트 확인"
},
Expand Down
1 change: 1 addition & 0 deletions src/locales/ru/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@
"Server-Config": "Настройки сервера",
"Settings": "Настройки",
"Sidebar": "Боковая панель",
"SoundNotification": "Звуковое оповещение",
"Tree Explorer": "Дерево проводника",
"UV": "UV",
"Validation": "Валидация",
Expand Down
6 changes: 6 additions & 0 deletions src/locales/ru/settings.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
{
"Comfy_SoundNotification_AfterAllPrompts": {
"name": "после выполнения всех подсказок"
},
"Comfy_SoundNotification_AfterOnePrompt": {
"name": "после выполнения приглашения"
},
"Comfy-Desktop_AutoUpdate": {
"name": "Автоматически проверять обновления"
},
Expand Down
1 change: 1 addition & 0 deletions src/locales/zh/main.json
Original file line number Diff line number Diff line change
Expand Up @@ -838,6 +838,7 @@
"Server-Config": "服务器配置",
"Settings": "设置",
"Sidebar": "侧边栏",
"SoundNotification": "声音通知",
"Tree Explorer": "树形浏览器",
"UV": "UV",
"Validation": "验证",
Expand Down
Loading