From 3bf38ac5d0369a8b7950af44722fa5ec42f40c19 Mon Sep 17 00:00:00 2001 From: Dominik9906 Date: Sat, 29 Aug 2026 00:26:00 +0200 Subject: [PATCH] ADD - manage custom phone tones --- frontend/src/App.vue | 4 + .../src/components/AdminCustomToneManager.vue | 809 ++++++++++++++++++ .../components/AdminPanel.contract.test.ts | 1 + frontend/src/components/AdminPanel.vue | 133 ++- frontend/src/customTones.contract.test.ts | 117 +++ frontend/src/permissions.contract.test.ts | 8 +- frontend/src/stores/admin.ts | 101 +++ frontend/src/stores/calls.ts | 29 +- frontend/src/stores/notifications.ts | 30 +- frontend/src/stores/phone.ts | 85 ++ frontend/src/types/admin.ts | 20 + frontend/src/utils/customAppBridge.ts | 10 +- frontend/src/utils/customTones.test.ts | 156 ++++ frontend/src/utils/customTones.ts | 240 ++++++ frontend/src/utils/phoneAudio.ts | 6 + frontend/src/utils/preferences.test.ts | 32 + frontend/src/utils/preferences.ts | 43 +- frontend/src/utils/tones.test.ts | 56 +- frontend/src/utils/tones.ts | 51 +- frontend/src/views/apps/SettingsApp.vue | 47 +- frontend/testserver/configurator-fixture.cjs | 1 + .../testserver/configurator-fixture.test.ts | 3 +- frontend/testserver/index.cjs | 91 ++ sky_phone/config/config.lua | 27 + sky_phone/config/custom_tones/README.md | 7 + sky_phone/config/locales/de.lua | 47 +- sky_phone/config/locales/en.lua | 47 +- sky_phone/config/locales/es.lua | 47 +- sky_phone/fxmanifest.lua | 2 + sky_phone/source/client/custom_tones.lua | 76 ++ sky_phone/source/client/main.lua | 18 + sky_phone/source/client/nui_server_bridge.lua | 2 + sky_phone/source/server/admin.lua | 110 +++ sky_phone/source/server/custom_tones.lua | 698 +++++++++++++++ sky_phone/source/server/db_migrate.lua | 23 + .../source/server/phone_configurator.lua | 11 +- sky_phone/sql/install.sql | 16 + 37 files changed, 3153 insertions(+), 51 deletions(-) create mode 100644 frontend/src/components/AdminCustomToneManager.vue create mode 100644 frontend/src/customTones.contract.test.ts create mode 100644 frontend/src/utils/customTones.test.ts create mode 100644 frontend/src/utils/customTones.ts create mode 100644 sky_phone/config/custom_tones/README.md create mode 100644 sky_phone/source/client/custom_tones.lua create mode 100644 sky_phone/source/server/custom_tones.lua diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 73f4c88..f9f619e 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -87,6 +87,7 @@ import { getHairlinePixelStyle } from '@/utils/rendering' import { isTextInputElement } from '@/utils/textInputFocus' import { configurePhoneNumberFormat } from '@/utils/phone' import { consumeEscape } from '@/utils/keyboard' +import type { CustomPhoneToneCatalog } from '@/utils/customTones' import { isTrustedRootMessageSource } from '@/utils/windowMessages' import SpringboardView from '@/views/SpringboardView.vue' @@ -118,6 +119,7 @@ type AppMessage = { | CustomAppEventData | NavigationEventData | AdminPanelOpenPayload + | CustomPhoneToneCatalog } type AdminPanelOpenPayload = Required< @@ -750,6 +752,8 @@ function onMessage(event: MessageEvent): void { adminPanelOpen.value = true } else if (event.data?.type === 'admin:close') { adminPanelOpen.value = false + } else if (event.data?.type === 'phone:tones') { + phone.setCustomTones(event.data.data) } else if (event.data?.type === 'custom-apps:catalog') { appCatalog.replaceCatalog(event.data.data) const catalogPayload = event.data.data as diff --git a/frontend/src/components/AdminCustomToneManager.vue b/frontend/src/components/AdminCustomToneManager.vue new file mode 100644 index 0000000..2cc9eb4 --- /dev/null +++ b/frontend/src/components/AdminCustomToneManager.vue @@ -0,0 +1,809 @@ + + + + + diff --git a/frontend/src/components/AdminPanel.contract.test.ts b/frontend/src/components/AdminPanel.contract.test.ts index 07f4463..e48f36d 100644 --- a/frontend/src/components/AdminPanel.contract.test.ts +++ b/frontend/src/components/AdminPanel.contract.test.ts @@ -144,6 +144,7 @@ describe('standalone admin panel contracts', () => { 'messages', 'calls', 'moderation', + 'tones', 'audit', 'configurator', ]) { diff --git a/frontend/src/components/AdminPanel.vue b/frontend/src/components/AdminPanel.vue index 8f1e65d..df1d70f 100644 --- a/frontend/src/components/AdminPanel.vue +++ b/frontend/src/components/AdminPanel.vue @@ -2,6 +2,7 @@ import { ChartNoAxesCombined, BadgeDollarSign, + BellRing, BriefcaseBusiness, Check, ChevronRight, @@ -65,6 +66,7 @@ import { nuiCall } from '@/utils/nui' import AdminConfigValueEditor, { type AdminConfigEditorLabels, } from './AdminConfigValueEditor.vue' +import AdminCustomToneManager from './AdminCustomToneManager.vue' type AdminTab = | 'overview' @@ -75,6 +77,7 @@ type AdminTab = | 'messages' | 'calls' | 'moderation' + | 'tones' | 'audit' | 'configurator' type ConfiguratorScope = 'config' | 'media' @@ -538,8 +541,15 @@ function selectTab(nextTab: AdminTab): void { if (nextTab === 'overview' && admin.initialized && !admin.loading) { void admin.load() } - if (nextTab === 'configurator' && !admin.configurator) { - void admin.loadConfigurator().then((loaded) => { + if (nextTab === 'configurator') { + void ( + admin.configurator ? Promise.resolve(true) : admin.loadConfigurator() + ).then((loaded) => { + if (!loaded) showToast(errorText(), 'error') + }) + } + if (nextTab === 'tones') { + void admin.loadCustomTones().then((loaded) => { if (!loaded) showToast(errorText(), 'error') }) } @@ -863,7 +873,9 @@ onBeforeUnmount(() => { {{ tab === 'configurator' ? t('configurator.context') - : admin.selectedPlayer?.name || t('editor.noSelection') + : tab === 'tones' + ? t('configurator.customTones.context') + : admin.selectedPlayer?.name || t('editor.noSelection') }} @@ -969,6 +981,15 @@ onBeforeUnmount(() => { > + +