This commit is contained in:
Binary file not shown.
@@ -7,7 +7,5 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
console.group('Build Info')
|
||||
console.log(`COMMIT_SHA: ${__COMMIT_SHA__}`)
|
||||
console.groupEnd()
|
||||
const route = useRoute()
|
||||
</script>
|
||||
|
||||
@@ -6,8 +6,25 @@ body {
|
||||
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background-image: radial-gradient(var(--p-surface-700), var(--p-surface-800));
|
||||
background-size: 200% 200%;
|
||||
background-position: left -100% top -100%;
|
||||
}
|
||||
|
||||
#__nuxt {
|
||||
--p-scrollpanel-bar-size: 5px;
|
||||
--p-scrollpanel-bar-background: var(--p-surface-950);
|
||||
--p-divider-horizontal-margin: 2rem 0 1rem;
|
||||
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.p-divider {
|
||||
&:first-child {
|
||||
--p-divider-horizontal-margin: 1rem 0 1rem;
|
||||
}
|
||||
}
|
||||
|
||||
.p-scrollpanel-bar-y {
|
||||
translate: -0.25rem;
|
||||
}
|
||||
2
client/app/components.d.ts
vendored
2
client/app/components.d.ts
vendored
@@ -13,7 +13,9 @@ declare module 'vue' {
|
||||
PrimeButton: typeof import('primevue/button')['default']
|
||||
PrimeButtonGroup: typeof import('primevue/buttongroup')['default']
|
||||
PrimeCard: typeof import('primevue/card')['default']
|
||||
PrimeChip: typeof import('primevue/chip')['default']
|
||||
PrimeDivider: typeof import('primevue/divider')['default']
|
||||
PrimeFieldset: typeof import('primevue/fieldset')['default']
|
||||
PrimeFloatLabel: typeof import('primevue/floatlabel')['default']
|
||||
PrimeInputText: typeof import('primevue/inputtext')['default']
|
||||
PrimeMenu: typeof import('primevue/menu')['default']
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
<template>
|
||||
<div
|
||||
class="flex items-center justify-between gap-2 border-b-2 border-surface-800 px-3 py-3"
|
||||
:class="{
|
||||
'bg-surface-950': !secondary,
|
||||
'bg-surface-900': secondary,
|
||||
}"
|
||||
style="height: 75px;"
|
||||
>
|
||||
<slot name="left">
|
||||
<h1 v-if="!!title">
|
||||
{{ title }}
|
||||
</h1>
|
||||
</slot>
|
||||
|
||||
<slot name="right" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
title?: string
|
||||
secondary?: boolean
|
||||
}>()
|
||||
|
||||
defineSlots<{
|
||||
left: () => unknown
|
||||
right: () => unknown
|
||||
}>()
|
||||
</script>
|
||||
@@ -42,6 +42,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { ChadClient } from '#shared/types'
|
||||
import type { MenuItem } from 'primevue/menuitem'
|
||||
import { useLocalStorage } from '@vueuse/core'
|
||||
import { User } from 'lucide-vue-next'
|
||||
|
||||
const props = defineProps<{
|
||||
@@ -52,9 +53,9 @@ const { outputMuted } = useApp()
|
||||
const { getClientConsumers, micProducer } = useMediasoup()
|
||||
const { me } = useClients()
|
||||
|
||||
const menuRef = useTemplateRef<HTMLAudioElement>('menu')
|
||||
const volume = useLocalStorage<number>(computed(() => `CLIENT_VOLUME_${props.client.userId}`), 100, { writeDefaults: false })
|
||||
|
||||
const volume = ref(100)
|
||||
const menuRef = useTemplateRef<HTMLAudioElement>('menu')
|
||||
|
||||
const menuItems: MenuItem[] = [
|
||||
{
|
||||
@@ -101,7 +102,7 @@ watch(volume, (volume) => {
|
||||
// return
|
||||
|
||||
setGain(volume * 0.01)
|
||||
})
|
||||
}, { immediate: true })
|
||||
|
||||
// watch(outputMuted, (outputMuted) => {
|
||||
// setGain(outputMuted ? 0 : (volume.value * 0.01))
|
||||
|
||||
@@ -8,6 +8,8 @@ export const useApp = createGlobalState(() => {
|
||||
const mediasoup = useMediasoup()
|
||||
const toast = useToast()
|
||||
|
||||
const ready = ref(false)
|
||||
|
||||
const inputMuted = ref(false)
|
||||
const outputMuted = ref(false)
|
||||
|
||||
@@ -15,8 +17,38 @@ export const useApp = createGlobalState(() => {
|
||||
|
||||
const isTauri = computed(() => '__TAURI_INTERNALS__' in window)
|
||||
|
||||
const commitSha = __COMMIT_SHA__
|
||||
|
||||
const version = computedAsync(() => isTauri.value ? getVersion() : 'web', '-')
|
||||
|
||||
watch(inputMuted, async (inputMuted) => {
|
||||
if (inputMuted) {
|
||||
await mediasoup.pauseProducer('microphone')
|
||||
}
|
||||
else {
|
||||
if (outputMuted.value) {
|
||||
outputMuted.value = false
|
||||
}
|
||||
await mediasoup.resumeProducer('microphone')
|
||||
}
|
||||
|
||||
const toastText = inputMuted ? 'Microphone muted' : 'Microphone activated'
|
||||
toast.add({ severity: 'info', summary: toastText, closable: false, life: 1000 })
|
||||
})
|
||||
|
||||
watch(outputMuted, (outputMuted) => {
|
||||
if (outputMuted) {
|
||||
previousInputMuted.value = inputMuted.value
|
||||
muteInput()
|
||||
}
|
||||
else {
|
||||
inputMuted.value = previousInputMuted.value
|
||||
}
|
||||
|
||||
const toastText = outputMuted ? 'Sound muted' : 'Sound resumed'
|
||||
toast.add({ severity: 'info', summary: toastText, closable: false, life: 1000 })
|
||||
})
|
||||
|
||||
function muteInput() {
|
||||
inputMuted.value = true
|
||||
}
|
||||
@@ -47,35 +79,8 @@ export const useApp = createGlobalState(() => {
|
||||
muteOutput()
|
||||
}
|
||||
|
||||
watch(inputMuted, async (inputMuted) => {
|
||||
if (inputMuted) {
|
||||
await mediasoup.pauseProducer('microphone')
|
||||
}
|
||||
else {
|
||||
if (outputMuted.value) {
|
||||
outputMuted.value = false
|
||||
}
|
||||
await mediasoup.resumeProducer('microphone')
|
||||
}
|
||||
|
||||
const toastText = inputMuted ? 'Microphone muted' : 'Microphone activated'
|
||||
toast.add({ severity: 'info', summary: toastText, closable: false, life: 1000 })
|
||||
})
|
||||
|
||||
watch(outputMuted, (outputMuted) => {
|
||||
if (outputMuted) {
|
||||
previousInputMuted.value = inputMuted.value
|
||||
muteInput()
|
||||
}
|
||||
else {
|
||||
inputMuted.value = previousInputMuted.value
|
||||
}
|
||||
|
||||
const toastText = outputMuted ? 'Sound muted' : 'Sound resumed'
|
||||
toast.add({ severity: 'info', summary: toastText, closable: false, life: 1000 })
|
||||
})
|
||||
|
||||
return {
|
||||
ready,
|
||||
clients,
|
||||
inputMuted,
|
||||
muteInput,
|
||||
@@ -87,5 +92,6 @@ export const useApp = createGlobalState(() => {
|
||||
toggleOutput,
|
||||
version,
|
||||
isTauri,
|
||||
commitSha,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
import { createGlobalState, useDevicesList, useLocalStorage } from '@vueuse/core'
|
||||
import chadApi from '#shared/chad-api'
|
||||
import { createGlobalState, useDevicesList, useLocalStorage, watchDebounced } from '@vueuse/core'
|
||||
|
||||
export interface SyncedPreferences {
|
||||
toggleInputHotkey: string
|
||||
toggleOutputHotkey: string
|
||||
volumes: Record<Client['id'], number>
|
||||
}
|
||||
|
||||
export const usePreferences = createGlobalState(() => {
|
||||
const synced = ref(false)
|
||||
|
||||
const inputDeviceId = useLocalStorage<MediaDeviceInfo['deviceId']>('INPUT_DEVICE_ID', 'default')
|
||||
const outputDeviceId = useLocalStorage<MediaDeviceInfo['deviceId']>('OUTPUT_DEVICE_ID', 'default')
|
||||
|
||||
@@ -8,6 +17,9 @@ export const usePreferences = createGlobalState(() => {
|
||||
const noiseSuppression = useLocalStorage('NOISE_SUPPRESSION', true)
|
||||
const echoCancellation = useLocalStorage('ECHO_CANCELLATION', true)
|
||||
|
||||
const toggleInputHotkey = ref<SyncedPreferences['toggleInputHotkey']>('')
|
||||
const toggleOutputHotkey = ref<SyncedPreferences['toggleOutputHotkey']>('')
|
||||
|
||||
const {
|
||||
ensurePermissions,
|
||||
permissionGranted,
|
||||
@@ -24,12 +36,35 @@ export const usePreferences = createGlobalState(() => {
|
||||
return audioOutputs.value.some(device => device.deviceId === outputDeviceId.value)
|
||||
})
|
||||
|
||||
watchDebounced(
|
||||
[toggleInputHotkey, toggleOutputHotkey],
|
||||
async ([toggleInputHotkey, toggleOutputHotkey]) => {
|
||||
try {
|
||||
await chadApi(
|
||||
'/preferences',
|
||||
{
|
||||
method: 'PATCH',
|
||||
body: {
|
||||
toggleInputHotkey,
|
||||
toggleOutputHotkey,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
catch {}
|
||||
},
|
||||
{ debounce: 1000 },
|
||||
)
|
||||
|
||||
return {
|
||||
synced,
|
||||
inputDeviceId,
|
||||
outputDeviceId,
|
||||
autoGainControl,
|
||||
noiseSuppression,
|
||||
echoCancellation,
|
||||
toggleInputHotkey,
|
||||
toggleOutputHotkey,
|
||||
inputDeviceExist,
|
||||
outputDeviceExist,
|
||||
videoInputs: computed(() => JSON.parse(JSON.stringify(videoInputs.value))),
|
||||
|
||||
@@ -3,9 +3,9 @@ import chadApi from '#shared/chad-api'
|
||||
export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||
const { me, setMe } = useAuth()
|
||||
|
||||
if (!me.value && !from?.name) {
|
||||
if (!me.value) {
|
||||
try {
|
||||
setMe(await chadApi('/me'))
|
||||
setMe(await chadApi('/me', { method: 'GET' }))
|
||||
}
|
||||
catch {
|
||||
if (to.meta.auth !== 'guest') {
|
||||
|
||||
26
client/app/middleware/02.user-preferences.global.ts
Normal file
26
client/app/middleware/02.user-preferences.global.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import type { SyncedPreferences } from '~/composables/use-preferences'
|
||||
import chadApi from '#shared/chad-api'
|
||||
|
||||
export default defineNuxtRouteMiddleware(async () => {
|
||||
const { me } = useAuth()
|
||||
|
||||
if (!me.value)
|
||||
return
|
||||
|
||||
const { synced, toggleInputHotkey, toggleOutputHotkey } = usePreferences()
|
||||
|
||||
if (synced.value)
|
||||
return
|
||||
|
||||
try {
|
||||
const preferences = await chadApi<SyncedPreferences>('/preferences', { method: 'GET' })
|
||||
|
||||
if (!preferences)
|
||||
return
|
||||
|
||||
toggleInputHotkey.value = preferences.toggleInputHotkey ?? toggleInputHotkey.value
|
||||
toggleOutputHotkey.value = preferences.toggleOutputHotkey ?? toggleOutputHotkey.value
|
||||
synced.value = true
|
||||
}
|
||||
catch {}
|
||||
})
|
||||
@@ -1,13 +1,17 @@
|
||||
<template>
|
||||
<div>
|
||||
<PrimeDivider align="left">
|
||||
Audio
|
||||
</PrimeDivider>
|
||||
|
||||
<PrimeFloatLabel variant="on">
|
||||
<PrimeSelect
|
||||
v-model="inputDeviceId"
|
||||
:options="audioInputs"
|
||||
option-label="label"
|
||||
option-value="deviceId"
|
||||
fluid
|
||||
input-id="inputDevice"
|
||||
fluid
|
||||
:invalid="!inputDeviceExist"
|
||||
/>
|
||||
<label for="inputDevice">Input device</label>
|
||||
@@ -43,18 +47,41 @@
|
||||
<!-- <label for="outputDevice">Output device</label> -->
|
||||
<!-- </PrimeFloatLabel> -->
|
||||
|
||||
<template v-if="isTauri">
|
||||
<PrimeDivider />
|
||||
<PrimeDivider align="left">
|
||||
Hotkeys
|
||||
</PrimeDivider>
|
||||
|
||||
<PrimeButton
|
||||
size="small"
|
||||
label="Check for Updates"
|
||||
fluid
|
||||
severity="info"
|
||||
:loading="checking"
|
||||
@click="onCheckForUpdates"
|
||||
/>
|
||||
</template>
|
||||
<PrimeFloatLabel variant="on">
|
||||
<PrimeInputText id="microphoneToggle" :model-value="toggleInputHotkey" fluid @keydown="setupToggleInputHotkey" />
|
||||
<label for="microphoneToggle">Toggle microphone</label>
|
||||
</PrimeFloatLabel>
|
||||
|
||||
<PrimeFloatLabel variant="on" class="mt-3">
|
||||
<PrimeInputText id="soundToggle" :model-value="toggleOutputHotkey" fluid @keydown="setupToggleOutputHotkey" />
|
||||
<label for="soundToggle">Toggle sound</label>
|
||||
</PrimeFloatLabel>
|
||||
|
||||
<PrimeDivider align="left">
|
||||
About
|
||||
</PrimeDivider>
|
||||
|
||||
<p v-if="version" class="text-muted-color text-sm">
|
||||
VERSION: {{ version }}
|
||||
</p>
|
||||
<p class="text-muted-color text-sm mt-2">
|
||||
COMMIT_SHA: {{ commitSha }}
|
||||
</p>
|
||||
|
||||
<PrimeButton
|
||||
v-if="isTauri"
|
||||
class="mt-3"
|
||||
size="small"
|
||||
label="Check for Updates"
|
||||
fluid
|
||||
severity="info"
|
||||
:loading="checking"
|
||||
@click="onCheckForUpdates"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<PrimeToast position="bottom-center" group="updater">
|
||||
@@ -73,10 +100,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { RemovableRef } from '@vueuse/core'
|
||||
|
||||
definePageMeta({
|
||||
name: 'Preferences',
|
||||
})
|
||||
const { isTauri } = useApp()
|
||||
const { isTauri, version, commitSha } = useApp()
|
||||
const { checking, checkForUpdates } = useUpdater()
|
||||
const {
|
||||
inputDeviceId,
|
||||
@@ -84,6 +113,8 @@ const {
|
||||
autoGainControl,
|
||||
noiseSuppression,
|
||||
echoCancellation,
|
||||
toggleInputHotkey,
|
||||
toggleOutputHotkey,
|
||||
inputDeviceExist,
|
||||
outputDeviceExist,
|
||||
audioInputs,
|
||||
@@ -92,6 +123,46 @@ const {
|
||||
|
||||
const toast = useToast()
|
||||
|
||||
const setupToggleInputHotkey = (event: KeyboardEvent) => setupHotkey(event, toggleInputHotkey)
|
||||
const setupToggleOutputHotkey = (event: KeyboardEvent) => setupHotkey(event, toggleOutputHotkey)
|
||||
|
||||
function setupHotkey(event: KeyboardEvent, model: RemovableRef<string>) {
|
||||
if (event.key === 'Tab' || event.key === 'Enter') {
|
||||
return
|
||||
}
|
||||
|
||||
event.preventDefault()
|
||||
|
||||
const hotkey = []
|
||||
|
||||
if (event.ctrlKey || event.metaKey)
|
||||
hotkey.push('CommandOrControl')
|
||||
if (event.altKey)
|
||||
hotkey.push('Alt')
|
||||
if (event.shiftKey)
|
||||
hotkey.push('Shift')
|
||||
|
||||
const modifierApplied = hotkey.length > 0
|
||||
|
||||
if (!modifierApplied && ['Escape', 'Backspace', 'Delete'].includes(event.key)) {
|
||||
model.value = ''
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if (!['Control', 'Shift', 'Alt'].includes(event.key)) {
|
||||
hotkey.push(event.key.toUpperCase())
|
||||
}
|
||||
|
||||
if (modifierApplied && hotkey.length === 1) {
|
||||
model.value = ''
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
model.value = hotkey.join('+')
|
||||
}
|
||||
|
||||
async function onCheckForUpdates() {
|
||||
const update = await checkForUpdates()
|
||||
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
<template>
|
||||
<form @submit.prevent="save()">
|
||||
<PrimeDivider align="left">
|
||||
General
|
||||
</PrimeDivider>
|
||||
|
||||
<PrimeFloatLabel variant="on">
|
||||
<PrimeInputText id="displayName" v-model="displayName" fluid autocomplete="off" />
|
||||
<label for="displayName">Display name</label>
|
||||
</PrimeFloatLabel>
|
||||
|
||||
<PrimeDivider />
|
||||
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="flex items-center gap-3 mt-6">
|
||||
<PrimeButton label="Save" :disabled="!valid" :loading="saving" fluid type="submit" />
|
||||
<PrimeButton severity="danger" class="shrink-0" @click="logout()">
|
||||
<template #icon>
|
||||
|
||||
7
client/app/plugins/00.build-info.ts
Normal file
7
client/app/plugins/00.build-info.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export default defineNuxtPlugin({
|
||||
setup() {
|
||||
console.group('Build Info')
|
||||
console.log(`COMMIT_SHA: ${__COMMIT_SHA__}`)
|
||||
console.groupEnd()
|
||||
},
|
||||
})
|
||||
45
client/app/plugins/01.register-hotkeys.ts
Normal file
45
client/app/plugins/01.register-hotkeys.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { isRegistered, register, unregister, unregisterAll } from '@tauri-apps/plugin-global-shortcut'
|
||||
|
||||
export default defineNuxtPlugin({
|
||||
async setup() {
|
||||
const { isTauri, toggleInput, toggleOutput } = useApp()
|
||||
const preferences = usePreferences()
|
||||
|
||||
if (!isTauri.value)
|
||||
return
|
||||
|
||||
await unregisterAll()
|
||||
|
||||
watch(preferences.toggleInputHotkey, async (shortcut, prevShortcut) => {
|
||||
await registerHotkey(shortcut, prevShortcut, toggleInput)
|
||||
}, {
|
||||
immediate: true,
|
||||
})
|
||||
|
||||
watch(preferences.toggleOutputHotkey, async (shortcut, prevShortcut) => {
|
||||
await registerHotkey(shortcut, prevShortcut, toggleOutput)
|
||||
}, {
|
||||
immediate: true,
|
||||
})
|
||||
|
||||
async function registerHotkey(shortcut: string, prevShortcut: string | undefined, cb: () => void) {
|
||||
if (!!prevShortcut && await isRegistered(prevShortcut)) {
|
||||
await unregister(prevShortcut)
|
||||
}
|
||||
|
||||
if (!shortcut)
|
||||
return
|
||||
|
||||
if (await isRegistered(shortcut)) {
|
||||
await unregister(shortcut)
|
||||
}
|
||||
|
||||
await register(shortcut, ({ state }) => {
|
||||
if (state !== 'Released')
|
||||
return
|
||||
|
||||
cb()
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -14,9 +14,11 @@
|
||||
"@nuxt/fonts": "^0.11.4",
|
||||
"@primeuix/themes": "^1.2.5",
|
||||
"@tailwindcss/vite": "^4.1.14",
|
||||
"@tauri-apps/plugin-global-shortcut": "~2",
|
||||
"@tauri-apps/plugin-process": "~2",
|
||||
"@tauri-apps/plugin-updater": "~2",
|
||||
"@vueuse/core": "^13.9.0",
|
||||
"hotkeys-js": "^4.0.0",
|
||||
"lucide-vue-next": "^0.562.0",
|
||||
"mediasoup-client": "^3.16.7",
|
||||
"nuxt": "^4.2.2",
|
||||
|
||||
@@ -4,10 +4,13 @@ const instance = $fetch.create({
|
||||
baseURL: __API_BASE_URL__,
|
||||
credentials: 'include',
|
||||
retry: false,
|
||||
onResponseError({ response }) {
|
||||
onResponseError({ request, response }) {
|
||||
if (!import.meta.client)
|
||||
return
|
||||
|
||||
if (typeof request === 'string' && request.endsWith('/me'))
|
||||
return
|
||||
|
||||
const message = response._data.error || 'Something went wrong'
|
||||
|
||||
ToastEventBus.emit('add', { severity: 'error', summary: 'Error', detail: message, closable: false, life: 3000 })
|
||||
|
||||
87
client/src-tauri/Cargo.lock
generated
87
client/src-tauri/Cargo.lock
generated
@@ -93,6 +93,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tauri-plugin-global-shortcut",
|
||||
"tauri-plugin-log",
|
||||
"tauri-plugin-process",
|
||||
"tauri-plugin-single-instance",
|
||||
@@ -292,7 +293,7 @@ dependencies = [
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-link 0.2.0",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -603,7 +604,7 @@ dependencies = [
|
||||
"iana-time-zone",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"windows-link 0.2.0",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1375,6 +1376,16 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gethostname"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
|
||||
dependencies = [
|
||||
"rustix",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
@@ -1504,6 +1515,24 @@ version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280"
|
||||
|
||||
[[package]]
|
||||
name = "global-hotkey"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9247516746aa8e53411a0db9b62b0e24efbcf6a76e0ba73e5a91b512ddabed7"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"keyboard-types",
|
||||
"objc2 0.6.2",
|
||||
"objc2-app-kit",
|
||||
"once_cell",
|
||||
"serde",
|
||||
"thiserror 2.0.17",
|
||||
"windows-sys 0.59.0",
|
||||
"x11rb",
|
||||
"xkeysym",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gobject-sys"
|
||||
version = "0.18.0"
|
||||
@@ -4180,6 +4209,21 @@ dependencies = [
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-global-shortcut"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "424af23c7e88d05e4a1a6fc2c7be077912f8c76bd7900fd50aa2b7cbf5a2c405"
|
||||
dependencies = [
|
||||
"global-hotkey",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror 2.0.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-log"
|
||||
version = "2.7.0"
|
||||
@@ -5227,7 +5271,7 @@ checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9"
|
||||
dependencies = [
|
||||
"windows-implement",
|
||||
"windows-interface",
|
||||
"windows-link 0.2.0",
|
||||
"windows-link 0.2.1",
|
||||
"windows-result 0.4.0",
|
||||
"windows-strings 0.5.0",
|
||||
]
|
||||
@@ -5273,9 +5317,9 @@ checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-numerics"
|
||||
@@ -5302,7 +5346,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7084dcc306f89883455a206237404d3eaf961e5bd7e0f312f7c91f57eb44167f"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5320,7 +5364,7 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7218c655a553b0bed4426cf54b20d7ba363ef543b52d515b3e48d7fd55318dda"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5365,7 +5409,7 @@ version = "0.61.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5405,7 +5449,7 @@ version = "0.53.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d42b7b7f66d2a06854650af09cfdf8713e427a439c97ad65a6375318033ac4b"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
"windows-link 0.2.1",
|
||||
"windows_aarch64_gnullvm 0.53.0",
|
||||
"windows_aarch64_msvc 0.53.0",
|
||||
"windows_i686_gnu 0.53.0",
|
||||
@@ -5431,7 +5475,7 @@ version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "700dad7c058606087f6fdc1f88da5841e06da40334413c6cd4367b25ef26d24e"
|
||||
dependencies = [
|
||||
"windows-link 0.2.0",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5687,6 +5731,23 @@ dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11rb"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414"
|
||||
dependencies = [
|
||||
"gethostname",
|
||||
"rustix",
|
||||
"x11rb-protocol",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "x11rb-protocol"
|
||||
version = "0.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.6.1"
|
||||
@@ -5697,6 +5758,12 @@ dependencies = [
|
||||
"rustix",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xkeysym"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56"
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.0"
|
||||
|
||||
@@ -26,5 +26,6 @@ tauri-plugin-log = "2"
|
||||
tauri-plugin-process = "2"
|
||||
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||
tauri-plugin-global-shortcut = "2"
|
||||
tauri-plugin-single-instance = "2"
|
||||
tauri-plugin-updater = "2"
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
"main"
|
||||
],
|
||||
"permissions": [
|
||||
"updater:default"
|
||||
"updater:default",
|
||||
"global-shortcut:allow-is-registered",
|
||||
"global-shortcut:allow-register",
|
||||
"global-shortcut:allow-unregister",
|
||||
"global-shortcut:allow-unregister-all"
|
||||
]
|
||||
}
|
||||
@@ -1,10 +1,10 @@
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_global_shortcut::Builder::new().build())
|
||||
.plugin(tauri_plugin_process::init())
|
||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||
.plugin(tauri_plugin_single_instance::init(|_, _, _| {
|
||||
}))
|
||||
.plugin(tauri_plugin_single_instance::init(|_, _, _| {}))
|
||||
.setup(|app| {
|
||||
if cfg!(debug_assertions) {
|
||||
app.handle().plugin(
|
||||
|
||||
Reference in New Issue
Block a user