improve settings ui

This commit is contained in:
pa
2026-03-16 11:30:11 +09:00
parent 8e3c1e0054
commit dcec53cdc3
9 changed files with 881 additions and 897 deletions

View File

@@ -108,7 +108,7 @@
:value="it.value"
:class="[
'pt-4 outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 ring-offset-background',
fill ? 'min-h-0 flex-1' : ''
fill ? 'min-h-0 flex-1 overflow-y-auto' : ''
]">
<slot :name="it.value" />
</TabsContent>

View File

@@ -1,13 +1,13 @@
<template>
<div class="x-container">
<div class="options-container mt-0 p-1.5">
<span class="header">{{ t('view.settings.header') }}</span>
<div class="x-container flex flex-col overflow-hidden!">
<div class="shrink-0 p-1.5">
<span class="text-lg font-semibold text-foreground">{{ t('view.settings.header') }}</span>
</div>
<TabsUnderline
default-value="general"
:items="settingsTabs"
:unmount-on-hide="false"
style="height: calc(100% - 51px)">
fill>
<template #general>
<GeneralTab />
</template>

View File

@@ -1,6 +1,11 @@
<template>
<div class="flex flex-col gap-3.5">
<h3 v-if="title" class="text-base font-semibold pl-0.5 text-foreground m-0">{{ title }}</h3>
<div v-if="title || $slots.description" class="flex flex-col gap-1.5 pl-0.5">
<h3 v-if="title" class="text-base font-semibold text-foreground m-0">{{ title }}</h3>
<div v-if="$slots.description" class="text-sm text-muted-foreground">
<slot name="description" />
</div>
</div>
<Card class="p-0">
<CardContent class="flex flex-col gap-1 py-4.5 px-5.5">
<slot />

View File

@@ -1,193 +1,183 @@
<template>
<div>
<div class="options-container mt-2!">
<div class="header">{{ t('view.settings.advanced.advanced.vrchat_settings.header') }}</div>
<span class="sub-header">{{ t('view.settings.advanced.advanced.relaunch_vrchat.header') }}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.relaunch_vrchat.description')"
:value="relaunchVRChatAfterCrash"
:long-label="true"
@change="setRelaunchVRChatAfterCrash" />
<div class="flex flex-col gap-10 py-2">
<SettingsGroup :title="t('view.settings.advanced.advanced.vrchat_settings.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.relaunch_vrchat.header')"
:description="t('view.settings.advanced.advanced.relaunch_vrchat.description')">
<Switch :model-value="relaunchVRChatAfterCrash" @update:modelValue="setRelaunchVRChatAfterCrash" />
</SettingsItem>
<span class="sub-header">{{ t('view.settings.advanced.advanced.vrchat_quit_fix.header') }}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.vrchat_quit_fix.description')"
:value="vrcQuitFix"
:long-label="true"
@change="setVrcQuitFix" />
<SettingsItem :label="t('view.settings.advanced.advanced.vrchat_quit_fix.header')"
:description="t('view.settings.advanced.advanced.vrchat_quit_fix.description')">
<Switch :model-value="vrcQuitFix" @update:modelValue="setVrcQuitFix" />
</SettingsItem>
<span class="sub-header">{{ t('view.settings.advanced.advanced.auto_cache_management.header') }}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.auto_cache_management.description')"
:value="autoSweepVRChatCache"
:long-label="true"
@change="setAutoSweepVRChatCache" />
<SettingsItem :label="t('view.settings.advanced.advanced.auto_cache_management.header')"
:description="t('view.settings.advanced.advanced.auto_cache_management.description')">
<Switch :model-value="autoSweepVRChatCache" @update:modelValue="setAutoSweepVRChatCache" />
</SettingsItem>
<span class="sub-header">{{ t('view.settings.advanced.advanced.self_invite.header') }}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.self_invite.description')"
:value="selfInviteOverride"
:long-label="true"
@change="setSelfInviteOverride" />
</div>
<div class="options-container">
<div class="header">{{ t('view.settings.advanced.advanced.vrcx_settings.header') }}</div>
<span class="sub-header">{{ t('view.settings.advanced.advanced.primary_password.header') }}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.primary_password.description')"
:value="enablePrimaryPassword"
:disabled="!enablePrimaryPassword"
:long-label="true"
@change="enablePrimaryPasswordChange" />
<SettingsItem :label="t('view.settings.advanced.advanced.self_invite.header')"
:description="t('view.settings.advanced.advanced.self_invite.description')">
<Switch :model-value="selfInviteOverride" @update:modelValue="setSelfInviteOverride" />
</SettingsItem>
</SettingsGroup>
<div v-if="branch === 'Nightly'">
<span class="sub-header">{{
t('view.settings.advanced.advanced.anonymous_error_reporting.header')
}}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.anonymous_error_reporting.description')"
:value="sentryErrorReporting"
:long-label="true"
@change="setSentryErrorReporting()" />
</div>
<SettingsGroup :title="t('view.settings.advanced.advanced.vrcx_settings.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.primary_password.header')"
:description="t('view.settings.advanced.advanced.primary_password.description')">
<Switch
:model-value="enablePrimaryPassword"
:disabled="!enablePrimaryPassword"
@update:modelValue="enablePrimaryPasswordChange" />
</SettingsItem>
<span class="sub-header">{{ t('view.settings.general.logging.header') }}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.cache_debug.udon_exception_logging')"
:value="udonExceptionLogging"
@change="setUdonExceptionLogging" />
<simple-switch
:label="t('view.settings.general.logging.resource_load')"
:value="logResourceLoad"
@change="setLogResourceLoad" />
<simple-switch
:label="t('view.settings.general.logging.empty_avatar')"
:value="logEmptyAvatars"
@change="setLogEmptyAvatars" />
<simple-switch
:label="t('view.settings.general.logging.auto_login_delay')"
:value="autoLoginDelayEnabled"
@change="setAutoLoginDelayEnabled" />
<div v-if="autoLoginDelayEnabled" class="options-container-item">
<template v-if="branch === 'Nightly'">
<SettingsItem :label="t('view.settings.advanced.advanced.anonymous_error_reporting.header')"
:description="t('view.settings.advanced.advanced.anonymous_error_reporting.description')">
<Switch :model-value="sentryErrorReporting" @update:modelValue="setSentryErrorReporting()" />
</SettingsItem>
</template>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.general.logging.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.cache_debug.udon_exception_logging')">
<Switch :model-value="udonExceptionLogging" @update:modelValue="setUdonExceptionLogging" />
</SettingsItem>
<SettingsItem :label="t('view.settings.general.logging.resource_load')">
<Switch :model-value="logResourceLoad" @update:modelValue="setLogResourceLoad" />
</SettingsItem>
<SettingsItem :label="t('view.settings.general.logging.empty_avatar')">
<Switch :model-value="logEmptyAvatars" @update:modelValue="setLogEmptyAvatars" />
</SettingsItem>
<SettingsItem :label="t('view.settings.general.logging.auto_login_delay')">
<Switch :model-value="autoLoginDelayEnabled" @update:modelValue="setAutoLoginDelayEnabled" />
</SettingsItem>
<SettingsItem v-if="autoLoginDelayEnabled"
:label="t('view.settings.general.logging.auto_login_delay_button')">
<Button size="sm" variant="outline" @click="promptAutoLoginDelaySeconds">
{{ t('view.settings.general.logging.auto_login_delay_button') }}
</Button>
</div>
</div>
<div class="options-container">
<span class="header">{{ t('view.profile.game_info.header') }}</span>
<div class="px-2.5 overflow-y-auto overflow-x-hidden mt-2">
<div class="box-border flex items-center p-1.5 text-[13px] cursor-pointer">
<div class="flex-1 overflow-hidden" @click="getVisits">
<span class="block truncate font-medium leading-[18px]">{{
t('view.profile.game_info.online_users')
}}</span>
<span v-if="visits" class="block truncate text-xs">{{
t('view.profile.game_info.user_online', { count: visits })
}}</span>
<span v-else class="block truncate text-xs">{{ t('view.profile.game_info.refresh') }}</span>
</div>
</SettingsItem>
</SettingsGroup>
<SettingsGroup :title="t('view.profile.game_info.header')">
<div class="px-1 py-1">
<div class="flex-1 cursor-pointer" @click="getVisits">
<span class="block truncate font-medium text-sm leading-[18px]">{{
t('view.profile.game_info.online_users')
}}</span>
<span v-if="visits" class="block truncate text-xs text-muted-foreground">{{
t('view.profile.game_info.user_online', { count: visits })
}}</span>
<span v-else class="block truncate text-xs text-muted-foreground">{{
t('view.profile.game_info.refresh')
}}</span>
</div>
</div>
</div>
<div class="options-container">
<span class="header">{{ t('view.settings.advanced.advanced.remote_database.header') }}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.remote_database.enable')"
:value="avatarRemoteDatabase"
:long-label="true"
@change="setAvatarRemoteDatabase(!avatarRemoteDatabase)" />
<div class="options-container-item">
</SettingsGroup>
<SettingsGroup :title="t('view.settings.advanced.advanced.remote_database.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.remote_database.enable')">
<Switch
:model-value="avatarRemoteDatabase"
@update:modelValue="setAvatarRemoteDatabase(!avatarRemoteDatabase)" />
</SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.remote_database.avatar_database_provider')">
<Button size="sm" variant="outline" @click="showAvatarProviderDialog">{{
t('view.settings.advanced.advanced.remote_database.avatar_database_provider')
}}</Button>
</div>
</div>
</SettingsItem>
</SettingsGroup>
<template v-if="!isLinux">
<div class="options-container">
<span class="header">{{ t('view.settings.advanced.advanced.app_launcher.header') }}</span>
<br />
<Button class="mt-1.5" size="sm" variant="outline" @click="openShortcutFolder()">{{
t('view.settings.advanced.advanced.app_launcher.folder')
}}</Button>
<simple-switch
:label="t('view.settings.advanced.advanced.remote_database.enable')"
:value="enableAppLauncher"
:tooltip="t('view.settings.advanced.advanced.app_launcher.folder_tooltip')"
:long-label="true"
@change="setEnableAppLauncher" />
<simple-switch
:label="t('view.settings.advanced.advanced.app_launcher.auto_close')"
:value="enableAppLauncherAutoClose"
:long-label="true"
@change="setEnableAppLauncherAutoClose" />
<simple-switch
:label="t('view.settings.advanced.advanced.app_launcher.run_process_once')"
:value="enableAppLauncherRunProcessOnce"
:long-label="true"
@change="setEnableAppLauncherRunProcessOnce" />
</div>
<SettingsGroup :title="t('view.settings.advanced.advanced.app_launcher.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.app_launcher.folder')">
<Button size="sm" variant="outline" @click="openShortcutFolder()">{{
t('view.settings.advanced.advanced.app_launcher.folder')
}}</Button>
</SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.remote_database.enable')"
:description="t('view.settings.advanced.advanced.app_launcher.folder_tooltip')">
<Switch :model-value="enableAppLauncher" @update:modelValue="setEnableAppLauncher" />
</SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.app_launcher.auto_close')">
<Switch
:model-value="enableAppLauncherAutoClose"
@update:modelValue="setEnableAppLauncherAutoClose" />
</SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.app_launcher.run_process_once')">
<Switch
:model-value="enableAppLauncherRunProcessOnce"
@update:modelValue="setEnableAppLauncherRunProcessOnce" />
</SettingsItem>
</SettingsGroup>
</template>
<div class="options-container">
<span class="header">{{ t('view.settings.advanced.advanced.youtube_api.header') }}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.youtube_api.enable')"
:value="youTubeApi"
:tooltip="t('view.settings.advanced.advanced.youtube_api.enable_tooltip')"
:long-label="true"
@change="changeYouTubeApi('VRCX_youtubeAPI')" />
<div class="options-container-item">
<SettingsGroup :title="t('view.settings.advanced.advanced.youtube_api.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.youtube_api.enable')"
:description="t('view.settings.advanced.advanced.youtube_api.enable_tooltip')">
<Switch :model-value="youTubeApi" @update:modelValue="changeYouTubeApi('VRCX_youtubeAPI')" />
</SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.youtube_api.youtube_api_key')">
<Button size="sm" variant="outline" @click="showYouTubeApiDialog">{{
t('view.settings.advanced.advanced.youtube_api.youtube_api_key')
}}</Button>
</div>
</div>
<div class="options-container">
<span class="header">{{ t('view.settings.advanced.advanced.translation_api.header') }}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.translation_api.enable')"
:value="translationApi"
:tooltip="t('view.settings.advanced.advanced.translation_api.enable_tooltip')"
:long-label="true"
@change="changeTranslationAPI('VRCX_translationAPI')" />
<div class="options-container-item">
</SettingsItem>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.advanced.advanced.translation_api.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.translation_api.enable')"
:description="t('view.settings.advanced.advanced.translation_api.enable_tooltip')">
<Switch :model-value="translationApi" @update:modelValue="changeTranslationAPI('VRCX_translationAPI')" />
</SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.translation_api.translation_api_key')">
<Button size="sm" variant="outline" @click="showTranslationApiDialog">
<Languages class="h-4 w-4" style="margin-right: 6px" />
<Languages class="h-4 w-4 mr-1.5" />
{{ t('view.settings.advanced.advanced.translation_api.translation_api_key') }}
</Button>
</div>
</div>
<div class="options-container">
<span class="header">{{ t('view.settings.advanced.advanced.video_progress_pie.header') }}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.video_progress_pie.enable')"
:value="progressPie"
:disabled="!openVR"
:tooltip="t('view.settings.advanced.advanced.video_progress_pie.enable_tooltip')"
:long-label="true"
@change="changeYouTubeApi('VRCX_progressPie')" />
<simple-switch
:label="t('view.settings.advanced.advanced.video_progress_pie.dance_world_only')"
:value="progressPieFilter"
:disabled="!openVR"
:long-label="true"
@change="changeYouTubeApi('VRCX_progressPieFilter')" />
</div>
<div class="options-container">
<span class="header">{{ t('view.settings.advanced.advanced.launch_commands.header') }}</span>
<simple-switch
</SettingsItem>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.advanced.advanced.video_progress_pie.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.video_progress_pie.enable')"
:description="t('view.settings.advanced.advanced.video_progress_pie.enable_tooltip')">
<Switch
:model-value="progressPie"
:disabled="!openVR"
@update:modelValue="changeYouTubeApi('VRCX_progressPie')" />
</SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.video_progress_pie.dance_world_only')">
<Switch
:model-value="progressPieFilter"
:disabled="!openVR"
@update:modelValue="changeYouTubeApi('VRCX_progressPieFilter')" />
</SettingsItem>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.advanced.advanced.launch_commands.header')">
<SettingsItem
:label="t('view.settings.advanced.advanced.launch_commands.show_confirmation_on_switch_avatar_enable')"
:value="showConfirmationOnSwitchAvatar"
:tooltip="
t('view.settings.advanced.advanced.launch_commands.show_confirmation_on_switch_avatar_tooltip')
"
:long-label="true"
@change="setShowConfirmationOnSwitchAvatar" />
<div class="options-container-item">
:description="t('view.settings.advanced.advanced.launch_commands.show_confirmation_on_switch_avatar_tooltip')">
<Switch
:model-value="showConfirmationOnSwitchAvatar"
@update:modelValue="setShowConfirmationOnSwitchAvatar" />
</SettingsItem>
<div class="flex gap-2">
<Button
size="sm"
variant="outline"
class="mr-2"
@click="openExternalLink('https://github.com/vrcx-team/VRCX/wiki/Launch-parameters-&-VRCX.json')"
>{{ t('view.settings.advanced.advanced.launch_commands.docs') }}</Button
>
@@ -198,15 +188,14 @@
>{{ t('view.settings.advanced.advanced.launch_commands.website_userscript') }}</Button
>
</div>
</div>
<div class="options-container">
<span class="header">{{ t('view.settings.advanced.advanced.cache_debug.header') }}</span>
<br />
<div class="options-container-item">
<Button size="sm" variant="outline" class="mr-2" @click="clearVRCXCache">{{
</SettingsGroup>
<SettingsGroup :title="t('view.settings.advanced.advanced.cache_debug.header')">
<div class="flex gap-2 flex-wrap">
<Button size="sm" variant="outline" @click="clearVRCXCache">{{
t('view.settings.advanced.advanced.cache_debug.clear_cache')
}}</Button>
<Button size="sm" variant="outline" class="mr-2" @click="promptAutoClearVRCXCacheFrequency">{{
<Button size="sm" variant="outline" @click="promptAutoClearVRCXCacheFrequency">{{
t('view.settings.advanced.advanced.cache_debug.auto_clear_cache')
}}</Button>
<Button size="sm" variant="outline" @click="refreshCacheSize">{{
@@ -214,146 +203,61 @@
}}</Button>
</div>
<simple-switch
:label="`${t('view.settings.advanced.advanced.cache_debug.disable_gamelog')} ${t('view.settings.advanced.advanced.cache_debug.disable_gamelog_notice')}`"
:value="gameLogDisabled"
:long-label="true"
@change="disableGameLogDialog()" />
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.cache_debug.user_cache') }}
<span v-text="cacheSize.cachedUsers"></span>
</span>
<SettingsItem
:label="`${t('view.settings.advanced.advanced.cache_debug.disable_gamelog')} ${t('view.settings.advanced.advanced.cache_debug.disable_gamelog_notice')}`">
<Switch :model-value="gameLogDisabled" @update:modelValue="disableGameLogDialog()" />
</SettingsItem>
<div class="flex flex-col gap-1 text-sm">
<span>{{ t('view.settings.advanced.advanced.cache_debug.user_cache') }} <span v-text="cacheSize.cachedUsers"></span></span>
<span>{{ t('view.settings.advanced.advanced.cache_debug.world_cache') }} <span v-text="cacheSize.cachedWorlds"></span></span>
<span>{{ t('view.settings.advanced.advanced.cache_debug.avatar_cache') }} <span v-text="cacheSize.cachedAvatars"></span></span>
<span>{{ t('view.settings.advanced.advanced.cache_debug.group_cache') }} <span v-text="cacheSize.cachedGroups"></span></span>
<span>{{ t('view.settings.advanced.advanced.cache_debug.avatar_name_cache') }} <span v-text="cacheSize.cachedAvatarNames"></span></span>
<span>{{ t('view.settings.advanced.advanced.cache_debug.instance_cache') }} <span v-text="cacheSize.cachedInstances"></span></span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.cache_debug.world_cache') }}
<span v-text="cacheSize.cachedWorlds"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.cache_debug.avatar_cache') }}
<span v-text="cacheSize.cachedAvatars"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.cache_debug.group_cache') }}
<span v-text="cacheSize.cachedGroups"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.cache_debug.avatar_name_cache') }}
<span v-text="cacheSize.cachedAvatarNames"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.cache_debug.instance_cache') }}
<span v-text="cacheSize.cachedInstances"></span>
</span>
</div>
<div class="options-container-item">
<SettingsItem :label="t('view.settings.advanced.advanced.cache_debug.show_console')">
<Button size="sm" variant="outline" @click="showConsole">{{
t('view.settings.advanced.advanced.cache_debug.show_console')
}}</Button>
</div>
</div>
<div class="options-container">
<span class="sub-header">{{ t('view.settings.advanced.advanced.sqlite_table_size.header') }}</span>
<div class="options-container-item">
</SettingsItem>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.advanced.advanced.sqlite_table_size.header')">
<SettingsItem :label="t('view.settings.advanced.advanced.sqlite_table_size.refresh')">
<Button size="sm" variant="outline" @click="getSqliteTableSizes">{{
t('view.settings.advanced.advanced.sqlite_table_size.refresh')
}}</Button>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.gps') }}
<span v-text="sqliteTableSizes.gps"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.status') }}
<span v-text="sqliteTableSizes.status"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.bio') }}
<span v-text="sqliteTableSizes.bio"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.avatar') }}
<span v-text="sqliteTableSizes.avatar"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.online_offline') }}
<span v-text="sqliteTableSizes.onlineOffline"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.friend_log_history') }}
<span v-text="sqliteTableSizes.friendLogHistory"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.notification') }}
<span v-text="sqliteTableSizes.notification"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.location') }}
<span v-text="sqliteTableSizes.location"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.join_leave') }}
<span v-text="sqliteTableSizes.joinLeave"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.portal_spawn') }}
<span v-text="sqliteTableSizes.portalSpawn"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.video_play') }}
<span v-text="sqliteTableSizes.videoPlay"></span>
</span>
</div>
<div class="options-container-item">
<span class="name">
{{ t('view.settings.advanced.advanced.sqlite_table_size.event') }}
<span v-text="sqliteTableSizes.event"></span>
</span>
</div>
</div>
</SettingsItem>
<div class="options-container">
<div class="header-bar">
<span class="header">{{ t('view.profile.config_json') }}</span>
<div class="flex flex-col gap-1 text-sm">
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.gps') }} <span v-text="sqliteTableSizes.gps"></span></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.status') }} <span v-text="sqliteTableSizes.status"></span></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.bio') }} <span v-text="sqliteTableSizes.bio"></span></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.avatar') }} <span v-text="sqliteTableSizes.avatar"></span></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.online_offline') }} <span v-text="sqliteTableSizes.onlineOffline"></span></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.friend_log_history') }} <span v-text="sqliteTableSizes.friendLogHistory"></span></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.notification') }} <span v-text="sqliteTableSizes.notification"></span></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.location') }} <span v-text="sqliteTableSizes.location"></span></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.join_leave') }} <span v-text="sqliteTableSizes.joinLeave"></span></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.portal_spawn') }} <span v-text="sqliteTableSizes.portalSpawn"></span></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.video_play') }} <span v-text="sqliteTableSizes.videoPlay"></span></span>
<span>{{ t('view.settings.advanced.advanced.sqlite_table_size.event') }} <span v-text="sqliteTableSizes.event"></span></span>
</div>
</SettingsGroup>
<SettingsGroup :title="t('view.profile.config_json')">
<div class="flex items-center gap-2">
<TooltipWrapper side="top" :content="t('view.profile.refresh_tooltip')">
<Button class="rounded-full mr-2" size="icon-sm" variant="outline" @click="refreshConfigTreeData()">
<Button class="rounded-full" size="icon-sm" variant="outline" @click="refreshConfigTreeData()">
<RefreshCcw />
</Button>
</TooltipWrapper>
<TooltipWrapper side="top" :content="t('view.profile.clear_results_tooltip')">
<Button class="rounded-full" size="icon-sm" variant="outline" @click="configTreeData = {}">
<Trash2
/></Button>
<Trash2 />
</Button>
</TooltipWrapper>
</div>
<vue-json-pretty
@@ -365,7 +269,7 @@
:dynamic-height="false"
virtual
show-icon />
</div>
</SettingsGroup>
<RegistryBackupDialog />
<YouTubeApiDialog v-model:isYouTubeApiDialogVisible="isYouTubeApiDialogVisible" />
@@ -379,6 +283,7 @@
import { Languages, RefreshCcw, Trash2 } from 'lucide-vue-next';
import { computed, reactive, ref } from 'vue';
import { Button } from '@/components/ui/button';
import { Switch } from '@/components/ui/switch';
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
@@ -400,18 +305,19 @@
useVRCXUpdaterStore,
useVrStore,
useWorldStore
} from '../../../../stores';
import { authRequest, queryRequest } from '../../../../api';
import { disableGameLogDialog } from '../../../../coordinators/gameLogCoordinator';
import { clearVRCXCache } from '../../../../coordinators/vrcxCoordinator';
import { openExternalLink } from '../../../../shared/utils';
} from '@/stores';
import { authRequest, queryRequest } from '@/api';
import { disableGameLogDialog } from '@/coordinators/gameLogCoordinator';
import { clearVRCXCache } from '@/coordinators/vrcxCoordinator';
import { openExternalLink } from '@/shared/utils';
import AvatarProviderDialog from '../../dialogs/AvatarProviderDialog.vue';
import PhotonSettings from '../PhotonSettings.vue';
import RegistryBackupDialog from '../../../Tools/dialogs/RegistryBackupDialog.vue';
import SimpleSwitch from '../SimpleSwitch.vue';
import TranslationApiDialog from '../../dialogs/TranslationApiDialog.vue';
import YouTubeApiDialog from '../../dialogs/YouTubeApiDialog.vue';
import SettingsGroup from '../SettingsGroup.vue';
import SettingsItem from '../SettingsItem.vue';
const { t } = useI18n();

View File

@@ -1,87 +1,111 @@
<template>
<div class="options-container mt-0">
<span class="header">{{ t('view.settings.discord_presence.discord_presence.header') }}</span>
<div class="options-container-item">
<span>{{ t('view.settings.discord_presence.discord_presence.description') }}</span>
</div>
<div class="options-container-item" @click="showVRChatConfig" style="cursor: pointer">
<span>{{ t('view.settings.discord_presence.discord_presence.enable_tooltip') }}</span>
</div>
<br />
<simple-switch
:label="t('view.settings.discord_presence.discord_presence.enable')"
:value="discordActive"
@change="
setDiscordActive();
saveDiscordOption();
" />
<simple-switch
:label="t('view.settings.discord_presence.discord_presence.world_integration')"
:value="discordWorldIntegration"
:disabled="!discordActive"
@change="
setDiscordWorldIntegration();
saveDiscordOption();
"
:tooltip="t('view.settings.discord_presence.discord_presence.world_integration_tooltip')" />
<simple-switch
:label="t('view.settings.discord_presence.discord_presence.instance_type_player_count')"
:value="discordInstance"
:disabled="!discordActive"
@change="
setDiscordInstance();
saveDiscordOption();
" />
<simple-switch
:label="t('view.settings.discord_presence.discord_presence.show_current_platform')"
:value="discordShowPlatform"
:disabled="!discordActive || !discordInstance"
@change="
setDiscordShowPlatform();
saveDiscordOption();
" />
<simple-switch
:label="t('view.settings.discord_presence.discord_presence.show_details_in_private')"
:value="!discordHideInvite"
:disabled="!discordActive"
@change="
setDiscordHideInvite();
saveDiscordOption();
" />
<simple-switch
:label="t('view.settings.discord_presence.discord_presence.join_button')"
:value="discordJoinButton"
:disabled="!discordActive"
@change="
setDiscordJoinButton();
saveDiscordOption();
" />
<simple-switch
:label="t('view.settings.discord_presence.discord_presence.show_images')"
:value="!discordHideImage"
:disabled="!discordActive"
@change="
setDiscordHideImage();
saveDiscordOption();
" />
<simple-switch
:label="t('view.settings.discord_presence.discord_presence.display_world_name_as_discord_status')"
:value="discordWorldNameAsDiscordStatus"
:disabled="!discordActive"
@change="
setDiscordWorldNameAsDiscordStatus();
saveDiscordOption();
" />
<div class="flex flex-col gap-10 py-2">
<SettingsGroup :title="t('view.settings.discord_presence.discord_presence.header')">
<template #description>
<p class="m-0">{{ t('view.settings.discord_presence.discord_presence.description') }}</p>
<p class="m-0 cursor-pointer hover:text-foreground transition-colors" @click="showVRChatConfig">
{{ t('view.settings.discord_presence.discord_presence.enable_tooltip') }}
</p>
</template>
<SettingsItem :label="t('view.settings.discord_presence.discord_presence.enable')">
<Switch
:model-value="discordActive"
@update:modelValue="
setDiscordActive();
saveDiscordOption();
" />
</SettingsItem>
<SettingsItem
:label="t('view.settings.discord_presence.discord_presence.world_integration')"
:description="t('view.settings.discord_presence.discord_presence.world_integration_tooltip')">
<Switch
:model-value="discordWorldIntegration"
:disabled="!discordActive"
@update:modelValue="
setDiscordWorldIntegration();
saveDiscordOption();
" />
</SettingsItem>
<SettingsItem
:label="t('view.settings.discord_presence.discord_presence.instance_type_player_count')">
<Switch
:model-value="discordInstance"
:disabled="!discordActive"
@update:modelValue="
setDiscordInstance();
saveDiscordOption();
" />
</SettingsItem>
<SettingsItem :label="t('view.settings.discord_presence.discord_presence.show_current_platform')">
<Switch
:model-value="discordShowPlatform"
:disabled="!discordActive || !discordInstance"
@update:modelValue="
setDiscordShowPlatform();
saveDiscordOption();
" />
</SettingsItem>
<SettingsItem
:label="t('view.settings.discord_presence.discord_presence.show_details_in_private')">
<Switch
:model-value="!discordHideInvite"
:disabled="!discordActive"
@update:modelValue="
setDiscordHideInvite();
saveDiscordOption();
" />
</SettingsItem>
<SettingsItem :label="t('view.settings.discord_presence.discord_presence.join_button')">
<Switch
:model-value="discordJoinButton"
:disabled="!discordActive"
@update:modelValue="
setDiscordJoinButton();
saveDiscordOption();
" />
</SettingsItem>
<SettingsItem :label="t('view.settings.discord_presence.discord_presence.show_images')">
<Switch
:model-value="!discordHideImage"
:disabled="!discordActive"
@update:modelValue="
setDiscordHideImage();
saveDiscordOption();
" />
</SettingsItem>
<SettingsItem
:label="
t('view.settings.discord_presence.discord_presence.display_world_name_as_discord_status')
">
<Switch
:model-value="discordWorldNameAsDiscordStatus"
:disabled="!discordActive"
@update:modelValue="
setDiscordWorldNameAsDiscordStatus();
saveDiscordOption();
" />
</SettingsItem>
</SettingsGroup>
</div>
</template>
<script setup>
import { Switch } from '@/components/ui/switch';
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
import { useAdvancedSettingsStore, useDiscordPresenceSettingsStore } from '../../../../stores';
import { useAdvancedSettingsStore, useDiscordPresenceSettingsStore } from '@/stores';
import SimpleSwitch from '../SimpleSwitch.vue';
import SettingsGroup from '../SettingsGroup.vue';
import SettingsItem from '../SettingsItem.vue';
const { t } = useI18n();

View File

@@ -1,138 +1,141 @@
<template>
<div>
<div class="options-container mt-0">
<span class="header">{{ t('view.settings.general.general.header') }}</span>
<div class="px-2.5 overflow-y-auto overflow-x-hidden mt-2">
<div class="box-border flex items-center p-1.5 text-[13px] cursor-default">
<div class="flex-1 overflow-hidden">
<span class="block truncate font-medium leading-[18px]">{{
t('view.settings.general.general.version')
}}</span>
<span class="block truncate text-xs" v-text="appVersion"></span>
</div>
</div>
<div class="box-border flex items-center p-1.5 text-[13px] cursor-pointer" @click="checkForVRCXUpdate">
<div class="flex-1 overflow-hidden">
<span class="block truncate font-medium leading-[18px]">{{
t('view.settings.general.general.latest_app_version')
}}</span>
<span v-if="latestAppVersion" class="block truncate text-xs" v-text="latestAppVersion"></span>
<span v-else class="block truncate text-xs">{{
t('view.settings.general.general.latest_app_version_refresh')
}}</span>
</div>
</div>
<div
class="box-border flex items-center p-1.5 text-[13px] cursor-pointer"
@click="openExternalLink(links.github)">
<div class="flex-1 overflow-hidden">
<span class="block truncate font-medium leading-[18px]">{{
t('view.settings.general.general.repository_url')
}}</span>
<span v-once class="block truncate text-xs">{{ links.github }}</span>
</div>
</div>
<div
class="box-border flex items-center p-1.5 text-[13px] cursor-pointer"
@click="openExternalLink(links.discord)">
<div class="flex-1 overflow-hidden">
<span class="block truncate font-medium leading-[18px]">{{
t('view.settings.general.general.support')
}}</span>
<span v-once class="block truncate text-xs">{{ links.discord }}</span>
</div>
<div class="flex flex-col gap-10 py-2">
<SettingsGroup :title="t('view.settings.general.general.header')">
<div class="flex flex-col gap-0.5 px-1 py-1">
<div class="flex-1">
<span class="block truncate font-medium text-sm leading-[18px]">{{
t('view.settings.general.general.version')
}}</span>
<span class="block truncate text-xs text-muted-foreground" v-text="appVersion"></span>
</div>
</div>
</div>
<div class="options-container">
<span class="header">{{ t('view.settings.general.vrcx_updater.header') }}</span>
<div class="options-container-item">
<Button size="sm" variant="outline" class="mr-2" @click="showChangeLogDialog">{{
<div class="flex flex-col gap-0.5 px-1 py-1 cursor-pointer" @click="checkForVRCXUpdate">
<div class="flex-1">
<span class="block truncate font-medium text-sm leading-[18px]">{{
t('view.settings.general.general.latest_app_version')
}}</span>
<span v-if="latestAppVersion" class="block truncate text-xs text-muted-foreground" v-text="latestAppVersion"></span>
<span v-else class="block truncate text-xs text-muted-foreground">{{
t('view.settings.general.general.latest_app_version_refresh')
}}</span>
</div>
</div>
<div class="flex flex-col gap-0.5 px-1 py-1 cursor-pointer" @click="openExternalLink(links.github)">
<div class="flex-1">
<span class="block truncate font-medium text-sm leading-[18px]">{{
t('view.settings.general.general.repository_url')
}}</span>
<span v-once class="block truncate text-xs text-muted-foreground">{{ links.github }}</span>
</div>
</div>
<div class="flex flex-col gap-0.5 px-1 py-1 cursor-pointer" @click="openExternalLink(links.discord)">
<div class="flex-1">
<span class="block truncate font-medium text-sm leading-[18px]">{{
t('view.settings.general.general.support')
}}</span>
<span v-once class="block truncate text-xs text-muted-foreground">{{ links.discord }}</span>
</div>
</div>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.general.vrcx_updater.header')">
<div class="flex gap-2">
<Button size="sm" variant="outline" @click="showChangeLogDialog">{{
t('view.settings.general.vrcx_updater.change_log')
}}</Button>
<Button size="sm" variant="outline" v-if="!noUpdater" @click="showVRCXUpdateDialog()">{{
<Button v-if="!noUpdater" size="sm" variant="outline" @click="showVRCXUpdateDialog()">{{
t('view.settings.general.vrcx_updater.change_build')
}}</Button>
</div>
<div v-if="!noUpdater" class="text-sm mt-2 flex flex-col align-baseline">
<span class="name">{{ t('view.settings.general.vrcx_updater.update_action') }}</span>
<ToggleGroup
class="mt-1.5"
type="single"
required
variant="outline"
size="sm"
:model-value="autoUpdateVRCX"
@update:model-value="setAutoUpdateVRCX">
<ToggleGroupItem value="Off">{{
t('view.settings.general.vrcx_updater.auto_update_off')
}}</ToggleGroupItem>
<ToggleGroupItem value="Notify">{{
t('view.settings.general.vrcx_updater.auto_update_notify')
}}</ToggleGroupItem>
<ToggleGroupItem value="Auto Download">{{
t('view.settings.general.vrcx_updater.auto_update_download')
}}</ToggleGroupItem>
</ToggleGroup>
<template v-if="!noUpdater">
<SettingsItem :label="t('view.settings.general.vrcx_updater.update_action')">
<ToggleGroup
type="single"
required
variant="outline"
size="sm"
:model-value="autoUpdateVRCX"
@update:model-value="setAutoUpdateVRCX">
<ToggleGroupItem value="Off">{{
t('view.settings.general.vrcx_updater.auto_update_off')
}}</ToggleGroupItem>
<ToggleGroupItem value="Notify">{{
t('view.settings.general.vrcx_updater.auto_update_notify')
}}</ToggleGroupItem>
<ToggleGroupItem value="Auto Download">{{
t('view.settings.general.vrcx_updater.auto_update_download')
}}</ToggleGroupItem>
</ToggleGroup>
</SettingsItem>
</template>
<div v-else class="text-sm text-muted-foreground">
{{ t('view.settings.general.vrcx_updater.updater_disabled') }}
</div>
<div v-else class="options-container-item">
<span>{{ t('view.settings.general.vrcx_updater.updater_disabled') }}</span>
</div>
</div>
<div class="options-container">
<span class="header">{{ t('view.settings.general.application.header') }}</span>
<simple-switch
</SettingsGroup>
<SettingsGroup :title="t('view.settings.general.application.header')">
<SettingsItem v-if="!isLinux" :label="t('view.settings.general.application.startup')">
<Switch :model-value="isStartAtWindowsStartup" @update:modelValue="setIsStartAtWindowsStartup" />
</SettingsItem>
<SettingsItem
v-if="!isLinux"
:label="t('view.settings.general.application.startup')"
:value="isStartAtWindowsStartup"
@change="setIsStartAtWindowsStartup" />
<simple-switch
v-if="!isLinux"
:label="t('view.settings.general.application.minimized')"
:value="isStartAsMinimizedState"
@change="setIsStartAsMinimizedState" />
<simple-switch
:label="t('view.settings.general.application.minimized')">
<Switch :model-value="isStartAsMinimizedState" @update:modelValue="setIsStartAsMinimizedState" />
</SettingsItem>
<SettingsItem
v-else
:label="t('view.settings.general.application.minimized')"
:value="isStartAsMinimizedState"
:tooltip="t('view.settings.general.application.startup_linux')"
@change="setIsStartAsMinimizedState" />
<simple-switch
v-if="!isMacOS"
:label="t('view.settings.general.application.tray')"
:value="isCloseToTray"
@change="setIsCloseToTray" />
<simple-switch
:description="t('view.settings.general.application.startup_linux')">
<Switch :model-value="isStartAsMinimizedState" @update:modelValue="setIsStartAsMinimizedState" />
</SettingsItem>
<SettingsItem v-if="!isMacOS" :label="t('view.settings.general.application.tray')">
<Switch :model-value="isCloseToTray" @update:modelValue="setIsCloseToTray" />
</SettingsItem>
<SettingsItem
v-if="!isLinux"
:label="t('view.settings.general.application.disable_gpu_acceleration')"
:value="disableGpuAcceleration"
:tooltip="t('view.settings.general.application.disable_gpu_acceleration_tooltip')"
@change="setDisableGpuAcceleration" />
<simple-switch
:description="t('view.settings.general.application.disable_gpu_acceleration_tooltip')">
<Switch :model-value="disableGpuAcceleration" @update:modelValue="setDisableGpuAcceleration" />
</SettingsItem>
<SettingsItem
v-if="!isLinux"
:label="t('view.settings.general.application.disable_vr_overlay_gpu_acceleration')"
:value="disableVrOverlayGpuAcceleration"
:tooltip="t('view.settings.general.application.disable_gpu_acceleration_tooltip')"
@change="setDisableVrOverlayGpuAcceleration" />
<div class="options-container-item">
:description="t('view.settings.general.application.disable_gpu_acceleration_tooltip')">
<Switch
:model-value="disableVrOverlayGpuAcceleration"
@update:modelValue="setDisableVrOverlayGpuAcceleration" />
</SettingsItem>
<SettingsItem :label="t('view.settings.general.application.proxy')">
<Button size="sm" variant="outline" @click="promptProxySettings">{{
t('view.settings.general.application.proxy')
}}</Button>
</div>
</div>
<div class="options-container">
<span class="header inline-flex items-center"
>{{ t('view.settings.general.favorites.header') }}
<TooltipWrapper side="top" :content="t('view.settings.general.favorites.header_tooltip')">
<Info class="ml-1" style="width: 12px; height: 12px; vertical-align: middle; cursor: help" />
</TooltipWrapper>
</span>
<br />
</SettingsItem>
</SettingsGroup>
<SettingsGroup>
<template #description>
<div class="flex items-center gap-1.5">
<span class="text-base font-semibold text-foreground">{{ t('view.settings.general.favorites.header') }}</span>
<TooltipWrapper side="top" :content="t('view.settings.general.favorites.header_tooltip')">
<Info class="size-3 text-muted-foreground cursor-help" />
</TooltipWrapper>
</div>
</template>
<Select
:model-value="localFavoriteFriendsGroups"
multiple
@update:modelValue="setLocalFavoriteFriendsGroups">
<SelectTrigger class="mt-2">
<SelectTrigger>
<SelectValue :placeholder="t('view.settings.general.favorites.group_placeholder')" />
</SelectTrigger>
<SelectContent>
@@ -154,37 +157,39 @@
</template>
</SelectContent>
</Select>
</div>
<div class="options-container">
<span class="header">{{ t('view.settings.general.contributors.header') }}</span>
<div class="options-container-item">
</SettingsGroup>
<SettingsGroup :title="t('view.settings.general.contributors.header')">
<div>
<img
src="https://contrib.rocks/image?repo=vrcx-team/VRCX"
alt="Contributors"
style="cursor: pointer"
class="cursor-pointer"
@click="openExternalLink('https://github.com/vrcx-team/VRCX/graphs/contributors')" />
</div>
</div>
<div class="options-container border-t border-border" style="margin-top: 45px; padding-top: 30px">
<span class="header">{{ t('view.settings.general.legal_notice.header') }}</span>
<div class="options-container-item" style="display: block">
<p>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.general.legal_notice.header')">
<div class="flex flex-col gap-2 text-sm text-muted-foreground">
<p class="m-0">
&copy; 2019-2026
<a class="cursor-pointer" @click="openExternalLink('https://github.com/pypy-vrc')">pypy</a> &amp;
<a class="cursor-pointer" @click="openExternalLink('https://github.com/Natsumi-sama')">Natsumi</a>
&amp;
<a class="cursor-pointer" @click="openExternalLink('https://github.com/Map1en')">Map1en</a>
</p>
<p>{{ t('view.settings.general.legal_notice.info') }}</p>
<p>{{ t('view.settings.general.legal_notice.disclaimer1') }}</p>
<p>{{ t('view.settings.general.legal_notice.disclaimer2') }}</p>
<p class="m-0">{{ t('view.settings.general.legal_notice.info') }}</p>
<p class="m-0">{{ t('view.settings.general.legal_notice.disclaimer1') }}</p>
<p class="m-0">{{ t('view.settings.general.legal_notice.disclaimer2') }}</p>
</div>
<div class="options-container-item">
<SettingsItem :label="t('view.settings.general.legal_notice.open_source_software_notice')">
<Button size="sm" variant="outline" @click="openOSSDialog">{{
t('view.settings.general.legal_notice.open_source_software_notice')
}}</Button>
</div>
</div>
</SettingsItem>
</SettingsGroup>
<OpenSourceSoftwareNoticeDialog v-if="ossDialog" v-model:ossDialog="ossDialog" />
</div>
</template>
@@ -192,6 +197,7 @@
<script setup>
import { computed, defineAsyncComponent, ref } from 'vue';
import { Button } from '@/components/ui/button';
import { Switch } from '@/components/ui/switch';
import { Info } from 'lucide-vue-next';
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
@@ -204,14 +210,14 @@
SelectSeparator,
SelectTrigger,
SelectValue
} from '../../../../components/ui/select';
import { useFavoriteStore, useGeneralSettingsStore, useVRCXUpdaterStore } from '../../../../stores';
import { ToggleGroup, ToggleGroupItem } from '../../../../components/ui/toggle-group';
import { links } from '../../../../shared/constants';
import { openExternalLink } from '../../../../shared/utils';
} from '@/components/ui/select';
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
import { useFavoriteStore, useGeneralSettingsStore, useVRCXUpdaterStore } from '@/stores';
import { links } from '@/shared/constants';
import { openExternalLink } from '@/shared/utils';
import SimpleSwitch from '../SimpleSwitch.vue';
import TooltipWrapper from '../../../../components/ui/tooltip/TooltipWrapper.vue';
import SettingsGroup from '../SettingsGroup.vue';
import SettingsItem from '../SettingsItem.vue';
const { t } = useI18n();

View File

@@ -1,29 +1,23 @@
<template>
<div>
<div class="options-container mt-0">
<span class="header">{{ t('view.settings.notifications.notifications.header') }}</span>
<div class="options-container-item">
<div class="flex flex-col gap-10 py-2">
<SettingsGroup :title="t('view.settings.notifications.notifications.header')">
<SettingsItem :label="t('view.settings.notifications.notifications.notification_filter')">
<Button size="sm" variant="outline" @click="showNotyFeedFiltersDialog">{{
t('view.settings.notifications.notifications.notification_filter')
}}</Button>
</div>
<div class="options-container-item">
</SettingsItem>
<SettingsItem :label="t('view.settings.notifications.notifications.test_notification')">
<Button size="sm" variant="outline" @click="testNotification"
><Play />{{ t('view.settings.notifications.notifications.test_notification') }}</Button
>
</div>
</div>
<div class="options-container">
<span class="sub-header">{{
t('view.settings.notifications.notifications.steamvr_notifications.header')
}}</span>
<div class="options-container-item">
<span class="name">{{
t('view.settings.notifications.notifications.desktop_notifications.when_to_display')
}}</span>
<br />
</SettingsItem>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.notifications.notifications.steamvr_notifications.header')">
<SettingsItem
:label="t('view.settings.notifications.notifications.desktop_notifications.when_to_display')">
<ToggleGroup
class="mt-1.5"
type="single"
required
variant="outline"
@@ -52,24 +46,36 @@
t('view.settings.notifications.notifications.conditions.always')
}}</ToggleGroupItem>
</ToggleGroup>
</div>
<simple-switch
:label="t('view.settings.notifications.notifications.steamvr_notifications.steamvr_overlay')"
:value="openVR"
@change="
setOpenVR();
saveOpenVROption();
" />
<template v-if="openVR">
<simple-switch
:label="t('view.settings.notifications.notifications.steamvr_notifications.overlay_notifications')"
:value="overlayNotifications"
:disabled="!openVR"
@change="
setOverlayNotifications();
</SettingsItem>
<SettingsItem
:label="t('view.settings.notifications.notifications.steamvr_notifications.steamvr_overlay')">
<Switch
:model-value="openVR"
@update:modelValue="
setOpenVR();
saveOpenVROption();
" />
<div class="options-container-item">
</SettingsItem>
<template v-if="openVR">
<SettingsItem
:label="
t('view.settings.notifications.notifications.steamvr_notifications.overlay_notifications')
">
<Switch
:model-value="overlayNotifications"
:disabled="!openVR"
@update:modelValue="
setOverlayNotifications();
saveOpenVROption();
" />
</SettingsItem>
<SettingsItem
:label="
t('view.settings.notifications.notifications.steamvr_notifications.notification_position')
">
<Button
size="sm"
variant="outline"
@@ -79,17 +85,22 @@
t('view.settings.notifications.notifications.steamvr_notifications.notification_position')
}}</Button
>
</div>
</SettingsItem>
</template>
<div class="options-container-item">
<span class="name" style="vertical-align: top; padding-top: 8px">{{
<SettingsItem
:label="
t('view.settings.notifications.notifications.steamvr_notifications.notification_opacity')
}}</span>
<div style="flex: 0 0 300px; width: 300px; max-width: 100%; padding-top: 16px">
">
<div class="w-75 max-w-full pt-1">
<Slider v-model="notificationOpacityValue" :min="0" :max="100" />
</div>
</div>
<div class="options-container-item">
</SettingsItem>
<SettingsItem
:label="
t('view.settings.notifications.notifications.steamvr_notifications.notification_timeout')
">
<Button
size="sm"
variant="outline"
@@ -99,75 +110,85 @@
t('view.settings.notifications.notifications.steamvr_notifications.notification_timeout')
}}</Button
>
</div>
<simple-switch
:label="t('view.settings.notifications.notifications.steamvr_notifications.user_images')"
:value="imageNotifications"
@change="
setImageNotifications();
saveOpenVROption();
" />
</SettingsItem>
<SettingsItem
:label="t('view.settings.notifications.notifications.steamvr_notifications.user_images')">
<Switch
:model-value="imageNotifications"
@update:modelValue="
setImageNotifications();
saveOpenVROption();
" />
</SettingsItem>
<template v-if="!isLinux">
<simple-switch
<SettingsItem
:label="
t('view.settings.notifications.notifications.steamvr_notifications.xsoverlay_notifications')
"
:value="xsNotifications"
@change="
setXsNotifications();
saveOpenVROption();
" />
">
<Switch
:model-value="xsNotifications"
@update:modelValue="
setXsNotifications();
saveOpenVROption();
" />
</SettingsItem>
</template>
<template v-else>
<simple-switch
:label="t('view.settings.notifications.notifications.steamvr_notifications.wayvr_notifications')"
:value="xsNotifications"
@change="
setXsNotifications();
saveOpenVROption();
" />
<SettingsItem
:label="
t('view.settings.notifications.notifications.steamvr_notifications.wayvr_notifications')
">
<Switch
:model-value="xsNotifications"
@update:modelValue="
setXsNotifications();
saveOpenVROption();
" />
</SettingsItem>
</template>
<template v-if="!isLinux">
<simple-switch
<SettingsItem
:label="
t(
'view.settings.notifications.notifications.steamvr_notifications.ovrtoolkit_hud_notifications'
)
"
:value="ovrtHudNotifications"
@change="
setOvrtHudNotifications();
saveOpenVROption();
" />
<simple-switch
">
<Switch
:model-value="ovrtHudNotifications"
@update:modelValue="
setOvrtHudNotifications();
saveOpenVROption();
" />
</SettingsItem>
<SettingsItem
:label="
t(
'view.settings.notifications.notifications.steamvr_notifications.ovrtoolkit_wrist_notifications'
)
"
:value="ovrtWristNotifications"
@change="
setOvrtWristNotifications();
saveOpenVROption();
" />
">
<Switch
:model-value="ovrtWristNotifications"
@update:modelValue="
setOvrtWristNotifications();
saveOpenVROption();
" />
</SettingsItem>
</template>
</div>
<div class="options-container">
<span class="sub-header">{{
t('view.settings.notifications.notifications.desktop_notifications.header')
}}</span>
<div class="options-container-item">
<span class="name">{{
t('view.settings.notifications.notifications.desktop_notifications.when_to_display')
}}</span>
<br />
</SettingsGroup>
<SettingsGroup :title="t('view.settings.notifications.notifications.desktop_notifications.header')">
<SettingsItem
:label="t('view.settings.notifications.notifications.desktop_notifications.when_to_display')">
<ToggleGroup
type="single"
required
variant="outline"
size="sm"
:model-value="desktopToast"
style="margin-top: 6px"
@update:model-value="setDesktopToast(String($event))">
<ToggleGroupItem value="Never">{{
t('view.settings.notifications.notifications.conditions.never')
@@ -191,28 +212,25 @@
t('view.settings.notifications.notifications.conditions.always')
}}</ToggleGroupItem>
</ToggleGroup>
</div>
<simple-switch
</SettingsItem>
<SettingsItem
:label="
t('view.settings.notifications.notifications.desktop_notifications.desktop_notification_while_afk')
"
:value="afkDesktopToast"
@change="setAfkDesktopToast" />
</div>
<div class="options-container">
<span class="sub-header">{{ t('view.settings.notifications.notifications.text_to_speech.header') }}</span>
<div class="options-container-item">
<span class="name">{{
t('view.settings.notifications.notifications.text_to_speech.when_to_play')
}}</span>
<br />
">
<Switch :model-value="afkDesktopToast" @update:modelValue="setAfkDesktopToast" />
</SettingsItem>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.notifications.notifications.text_to_speech.header')">
<SettingsItem
:label="t('view.settings.notifications.notifications.text_to_speech.when_to_play')">
<ToggleGroup
type="single"
required
variant="outline"
size="sm"
:model-value="notificationTTS"
style="margin-top: 6px"
@update:model-value="saveNotificationTTS">
<ToggleGroupItem value="Never">{{
t('view.settings.notifications.notifications.conditions.never')
@@ -230,9 +248,9 @@
t('view.settings.notifications.notifications.conditions.always')
}}</ToggleGroupItem>
</ToggleGroup>
</div>
<div class="options-container-item">
<span class="name">{{ t('view.settings.notifications.notifications.text_to_speech.tts_voice') }}</span>
</SettingsItem>
<SettingsItem :label="t('view.settings.notifications.notifications.text_to_speech.tts_voice')">
<Select
:model-value="ttsVoiceIndex"
:disabled="notificationTTS === 'Never'"
@@ -248,28 +266,34 @@
</SelectGroup>
</SelectContent>
</Select>
</div>
<simple-switch
:label="t('view.settings.notifications.notifications.text_to_speech.use_memo_nicknames')"
:value="notificationTTSNickName"
:disabled="notificationTTS === 'Never'"
@change="setNotificationTTSNickName" />
<simple-switch
:label="t('view.settings.notifications.notifications.text_to_speech.tts_test_placeholder')"
:value="isTestTTSVisible"
@change="isTestTTSVisible = !isTestTTSVisible" />
<div v-if="isTestTTSVisible" style="margin-top: 6px">
</SettingsItem>
<SettingsItem
:label="t('view.settings.notifications.notifications.text_to_speech.use_memo_nicknames')">
<Switch
:model-value="notificationTTSNickName"
:disabled="notificationTTS === 'Never'"
@update:modelValue="setNotificationTTSNickName" />
</SettingsItem>
<SettingsItem
:label="t('view.settings.notifications.notifications.text_to_speech.tts_test_placeholder')">
<Switch :model-value="isTestTTSVisible" @update:modelValue="isTestTTSVisible = !isTestTTSVisible" />
</SettingsItem>
<div v-if="isTestTTSVisible" class="flex items-center gap-2 mt-1">
<InputGroupTextareaField
v-model="notificationTTSTest"
:placeholder="t('view.settings.notifications.notifications.text_to_speech.tts_test_placeholder')"
:rows="1"
style="width: 175px; display: inline-block"
class="w-44"
input-class="resize-none min-h-0" />
<Button size="sm" variant="outline" @click="testNotificationTTS">{{
t('view.settings.notifications.notifications.text_to_speech.play')
}}</Button>
</div>
</div>
</SettingsGroup>
<NotificationPositionDialog v-model:isNotificationPositionDialogVisible="isNotificationPositionDialogVisible" />
<FeedFiltersDialog v-model:feedFiltersDialogMode="feedFiltersDialogMode" />
</div>
@@ -277,6 +301,9 @@
<script setup>
import { Select, SelectContent, SelectGroup, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
import { Switch } from '@/components/ui/switch';
import { Slider } from '@/components/ui/slider';
import { computed, ref } from 'vue';
import { Button } from '@/components/ui/button';
import { InputGroupTextareaField } from '@/components/ui/input-group';
@@ -289,13 +316,12 @@
useNotificationStore,
useNotificationsSettingsStore,
useVrStore
} from '../../../../stores';
import { ToggleGroup, ToggleGroupItem } from '../../../../components/ui/toggle-group';
import { Slider } from '../../../../components/ui/slider';
} from '@/stores';
import FeedFiltersDialog from '../../dialogs/FeedFiltersDialog.vue';
import NotificationPositionDialog from '../../dialogs/NotificationPositionDialog.vue';
import SimpleSwitch from '../SimpleSwitch.vue';
import SettingsGroup from '../SettingsGroup.vue';
import SettingsItem from '../SettingsItem.vue';
const { t } = useI18n();

View File

@@ -1,117 +1,110 @@
<template>
<!--//- Pictures | Screenshot Helper-->
<div class="options-container mt-0">
<span class="header">{{ t('view.settings.advanced.advanced.screenshot_helper.header') }}</span>
<div class="options-container-item">
<span class="name">{{ t('view.settings.advanced.advanced.screenshot_helper.description') }}</span>
</div>
<simple-switch
:label="t('view.settings.advanced.advanced.screenshot_helper.enable')"
:value="screenshotHelper"
@change="setScreenshotHelper()"
:tooltip="t('view.settings.advanced.advanced.screenshot_helper.description_tooltip')"
:long-label="true" />
<simple-switch
:label="t('view.settings.advanced.advanced.screenshot_helper.modify_filename')"
:value="screenshotHelperModifyFilename"
@change="setScreenshotHelperModifyFilename()"
:disabled="!screenshotHelper"
:tooltip="t('view.settings.advanced.advanced.screenshot_helper.modify_filename_tooltip')"
:long-label="true" />
<simple-switch
:label="t('view.settings.advanced.advanced.screenshot_helper.copy_to_clipboard')"
:value="screenshotHelperCopyToClipboard"
@change="setScreenshotHelperCopyToClipboard()"
:long-label="true" />
<Button size="sm" variant="outline" class="mt-2" @click="askDeleteAllScreenshotMetadata()">{{
t('view.settings.advanced.advanced.delete_all_screenshot_metadata.button')
}}</Button>
</div>
<div class="flex flex-col gap-10 py-2">
<SettingsGroup :title="t('view.settings.advanced.advanced.screenshot_helper.header')">
<template #description>
{{ t('view.settings.advanced.advanced.screenshot_helper.description') }}
</template>
<div class="options-container">
<span class="header">{{ t('view.settings.pictures.pictures.auto_delete_old_prints') }}</span>
<simple-switch
:label="t('view.settings.pictures.pictures.auto_delete_prints_from_vrc')"
:value="autoDeleteOldPrints"
@change="setAutoDeleteOldPrints()"
:long-label="true" />
</div>
<SettingsItem
:label="t('view.settings.advanced.advanced.screenshot_helper.enable')"
:description="t('view.settings.advanced.advanced.screenshot_helper.description_tooltip')">
<Switch :model-value="screenshotHelper" @update:modelValue="setScreenshotHelper()" />
</SettingsItem>
<!-- //- Pictures | User Generated Content -->
<div class="options-container">
<span class="header">{{ t('view.settings.advanced.advanced.user_generated_content.header') }}</span>
<br />
<div class="options-container-item mb-1.5">
<span class="name" style="min-width: 300px">{{
t('view.settings.advanced.advanced.user_generated_content.description')
}}</span>
</div>
<div class="flex gap-2 mt-2">
<Button size="sm" variant="outline" @click="openUGCFolder()">{{
t('view.settings.advanced.advanced.user_generated_content.folder')
}}</Button>
<Button size="sm" variant="outline" @click="openUGCFolderSelector()">{{
t('view.settings.advanced.advanced.user_generated_content.set_folder')
}}</Button>
<Button size="sm" variant="outline" @click="resetUGCFolder()" v-if="ugcFolderPath">{{
t('view.settings.advanced.advanced.user_generated_content.reset_override')
}}</Button>
</div>
<SettingsItem
:label="t('view.settings.advanced.advanced.screenshot_helper.modify_filename')"
:description="t('view.settings.advanced.advanced.screenshot_helper.modify_filename_tooltip')">
<Switch
:model-value="screenshotHelperModifyFilename"
:disabled="!screenshotHelper"
@update:modelValue="setScreenshotHelperModifyFilename()" />
</SettingsItem>
<br />
<br />
<br />
<span class="sub-header mr-1.5">{{
t('view.settings.advanced.advanced.save_instance_prints_to_file.header')
}}</span>
<TooltipWrapper
side="top"
:content="t('view.settings.advanced.advanced.save_instance_prints_to_file.header_tooltip')">
<Info class="inline-block" />
</TooltipWrapper>
<simple-switch
:label="t('view.settings.advanced.advanced.save_instance_prints_to_file.description')"
:value="saveInstancePrints"
@change="setSaveInstancePrints()"
:long-label="true" />
<simple-switch
:label="t('view.settings.advanced.advanced.save_instance_prints_to_file.crop')"
:value="cropInstancePrints"
@change="setCropInstancePrints()"
:long-label="true" />
<br />
<span class="sub-header">{{ t('view.settings.advanced.advanced.save_instance_stickers_to_file.header') }}</span>
<simple-switch
:label="t('view.settings.advanced.advanced.save_instance_stickers_to_file.description')"
:value="saveInstanceStickers"
@change="setSaveInstanceStickers()"
:long-label="true" />
<br />
<span class="sub-header mr-1.5"
>{{ t('view.settings.advanced.advanced.save_instance_emoji_to_file.header') }}
</span>
<TooltipWrapper
side="top"
:content="t('view.settings.advanced.advanced.save_instance_prints_to_file.header_tooltip')">
<Info class="inline-block" />
</TooltipWrapper>
<simple-switch
:label="t('view.settings.advanced.advanced.save_instance_emoji_to_file.description')"
:value="saveInstanceEmoji"
@change="setSaveInstanceEmoji()"
:long-label="true" />
<SettingsItem :label="t('view.settings.advanced.advanced.screenshot_helper.copy_to_clipboard')">
<Switch
:model-value="screenshotHelperCopyToClipboard"
@update:modelValue="setScreenshotHelperCopyToClipboard()" />
</SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.delete_all_screenshot_metadata.button')">
<Button size="sm" variant="outline" @click="askDeleteAllScreenshotMetadata()">{{
t('view.settings.advanced.advanced.delete_all_screenshot_metadata.button')
}}</Button>
</SettingsItem>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.pictures.pictures.auto_delete_old_prints')">
<SettingsItem :label="t('view.settings.pictures.pictures.auto_delete_prints_from_vrc')">
<Switch :model-value="autoDeleteOldPrints" @update:modelValue="setAutoDeleteOldPrints()" />
</SettingsItem>
</SettingsGroup>
<!-- //- Pictures | User Generated Content -->
<SettingsGroup :title="t('view.settings.advanced.advanced.user_generated_content.header')">
<template #description>
{{ t('view.settings.advanced.advanced.user_generated_content.description') }}
</template>
<div class="flex gap-2">
<Button size="sm" variant="outline" @click="openUGCFolder()">{{
t('view.settings.advanced.advanced.user_generated_content.folder')
}}</Button>
<Button size="sm" variant="outline" @click="openUGCFolderSelector()">{{
t('view.settings.advanced.advanced.user_generated_content.set_folder')
}}</Button>
<Button v-if="ugcFolderPath" size="sm" variant="outline" @click="resetUGCFolder()">{{
t('view.settings.advanced.advanced.user_generated_content.reset_override')
}}</Button>
</div>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.advanced.advanced.save_instance_prints_to_file.header')">
<template #description>
{{ t('view.settings.advanced.advanced.save_instance_prints_to_file.header_tooltip') }}
</template>
<SettingsItem
:label="t('view.settings.advanced.advanced.save_instance_prints_to_file.description')">
<Switch :model-value="saveInstancePrints" @update:modelValue="setSaveInstancePrints()" />
</SettingsItem>
<SettingsItem :label="t('view.settings.advanced.advanced.save_instance_prints_to_file.crop')">
<Switch :model-value="cropInstancePrints" @update:modelValue="setCropInstancePrints()" />
</SettingsItem>
</SettingsGroup>
<SettingsGroup
:title="t('view.settings.advanced.advanced.save_instance_stickers_to_file.header')">
<SettingsItem
:label="t('view.settings.advanced.advanced.save_instance_stickers_to_file.description')">
<Switch :model-value="saveInstanceStickers" @update:modelValue="setSaveInstanceStickers()" />
</SettingsItem>
</SettingsGroup>
<SettingsGroup :title="t('view.settings.advanced.advanced.save_instance_emoji_to_file.header')">
<template #description>
{{ t('view.settings.advanced.advanced.save_instance_prints_to_file.header_tooltip') }}
</template>
<SettingsItem
:label="t('view.settings.advanced.advanced.save_instance_emoji_to_file.description')">
<Switch :model-value="saveInstanceEmoji" @update:modelValue="setSaveInstanceEmoji()" />
</SettingsItem>
</SettingsGroup>
</div>
</template>
<script setup>
import { Button } from '@/components/ui/button';
import { Info } from 'lucide-vue-next';
import { Switch } from '@/components/ui/switch';
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
import { useAdvancedSettingsStore } from '../../../../stores';
import { useAdvancedSettingsStore } from '@/stores';
import SimpleSwitch from '../SimpleSwitch.vue';
import SettingsGroup from '../SettingsGroup.vue';
import SettingsItem from '../SettingsItem.vue';
const { t } = useI18n();

View File

@@ -1,168 +1,192 @@
<template>
<div class="options-container mt-0">
<span class="header">{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.header') }}</span>
<div class="options-container-item">
<Button
size="sm"
variant="outline"
:disabled="!openVR || !overlayWrist"
@click="emit('open-feed-filters')"
>{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.wrist_feed_filters') }}</Button
>
</div>
<div class="options-container-item">
<span>{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.description') }}</span>
</div>
<div class="options-container-item">
<span>{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.grip') }}</span>
</div>
<div class="options-container-item">
<span>{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.menu') }}</span>
</div>
<simple-switch
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.steamvr_overlay')"
:value="openVR"
@change="
setOpenVR();
saveOpenVROption();
" />
<simple-switch
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.wrist_feed_overlay')"
:value="overlayWrist"
:disabled="!openVR"
@change="
setOverlayWrist();
saveOpenVROption();
"></simple-switch>
<simple-switch
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.hide_private_worlds')"
:value="hidePrivateFromFeed"
@change="
setHidePrivateFromFeed();
saveOpenVROption();
" />
<div class="options-container-item" style="min-width: 118px">
<span class="name">{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.start_overlay_with') }}</span>
<RadioGroup
:model-value="openVRAlways ? 'true' : 'false'"
:disabled="!openVR"
class="gap-2 flex mt-2"
@update:modelValue="handleOpenVRAlwaysRadio">
<div class="flex items-center space-x-2">
<RadioGroupItem id="openVRAlways-false" value="false" />
<label for="openVRAlways-false">{{ 'VRChat' }}</label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem id="openVRAlways-true" value="true" />
<label for="openVRAlways-true">{{ 'SteamVR' }}</label>
</div>
</RadioGroup>
</div>
<div class="options-container-item">
<span class="name">{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button') }}</span>
<RadioGroup
:model-value="overlaybutton ? 'true' : 'false'"
:disabled="!openVR || !overlayWrist"
class="gap-2 flex mt-2"
@update:modelValue="handleOverlayButtonRadio">
<div class="flex items-center space-x-2">
<RadioGroupItem id="overlaybutton-false" value="false" />
<label for="overlaybutton-false">{{
t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button_grip')
}}</label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem id="overlaybutton-true" value="true" />
<label for="overlaybutton-true">{{
t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button_menu')
}}</label>
</div>
</RadioGroup>
</div>
<div class="options-container-item">
<span class="name">{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on') }}</span>
<ToggleGroup
type="single"
required
variant="outline"
size="sm"
:model-value="overlayHand"
@update:model-value="
setOverlayHand($event);
saveOpenVROption();
">
<ToggleGroupItem value="1">{{
t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_left')
}}</ToggleGroupItem>
<ToggleGroupItem value="2">{{
t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_right')
}}</ToggleGroupItem>
<ToggleGroupItem value="0">{{
t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_both')
}}</ToggleGroupItem>
</ToggleGroup>
</div>
<simple-switch
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.grey_background')"
:value="vrBackgroundEnabled"
:disabled="!openVR || !overlayWrist"
@change="
setVrBackgroundEnabled();
saveOpenVROption();
" />
<simple-switch
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.minimal_feed_icons')"
:value="minimalFeed"
:disabled="!openVR || !overlayWrist"
@change="
setMinimalFeed();
saveOpenVROption();
" />
<simple-switch
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.show_vr_devices')"
:value="!hideDevicesFromFeed"
:disabled="!openVR || !overlayWrist"
@change="
setHideDevicesFromFeed();
saveOpenVROption();
" />
<simple-switch
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.show_cpu_usage')"
:value="vrOverlayCpuUsage"
:disabled="!openVR || !overlayWrist"
@change="
setVrOverlayCpuUsage();
saveOpenVROption();
" />
<simple-switch
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.show_game_uptime')"
:value="!hideUptimeFromFeed"
:disabled="!openVR || !overlayWrist"
@change="
setHideUptimeFromFeed();
saveOpenVROption();
" />
<simple-switch
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.show_pc_uptime')"
:value="pcUptimeOnFeed"
:disabled="!openVR || !overlayWrist"
@change="
setPcUptimeOnFeed();
saveOpenVROption();
"></simple-switch>
<div class="flex flex-col gap-10 py-2">
<SettingsGroup :title="t('view.settings.wrist_overlay.steamvr_wrist_overlay.header')">
<template #description>
<p class="m-0">{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.description') }}</p>
<p class="m-0">{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.grip') }}</p>
<p class="m-0">{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.menu') }}</p>
</template>
<SettingsItem :label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.wrist_feed_filters')">
<Button
size="sm"
variant="outline"
:disabled="!openVR || !overlayWrist"
@click="emit('open-feed-filters')"
>{{ t('view.settings.wrist_overlay.steamvr_wrist_overlay.wrist_feed_filters') }}</Button
>
</SettingsItem>
<SettingsItem :label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.steamvr_overlay')">
<Switch
:model-value="openVR"
@update:modelValue="
setOpenVR();
saveOpenVROption();
" />
</SettingsItem>
<SettingsItem :label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.wrist_feed_overlay')">
<Switch
:model-value="overlayWrist"
:disabled="!openVR"
@update:modelValue="
setOverlayWrist();
saveOpenVROption();
" />
</SettingsItem>
<SettingsItem
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.hide_private_worlds')">
<Switch
:model-value="hidePrivateFromFeed"
@update:modelValue="
setHidePrivateFromFeed();
saveOpenVROption();
" />
</SettingsItem>
<SettingsItem
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.start_overlay_with')">
<RadioGroup
:model-value="openVRAlways ? 'true' : 'false'"
:disabled="!openVR"
class="gap-2 flex"
@update:modelValue="handleOpenVRAlwaysRadio">
<div class="flex items-center space-x-2">
<RadioGroupItem id="openVRAlways-false" value="false" />
<label for="openVRAlways-false">{{ 'VRChat' }}</label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem id="openVRAlways-true" value="true" />
<label for="openVRAlways-true">{{ 'SteamVR' }}</label>
</div>
</RadioGroup>
</SettingsItem>
<SettingsItem :label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button')">
<RadioGroup
:model-value="overlaybutton ? 'true' : 'false'"
:disabled="!openVR || !overlayWrist"
class="gap-2 flex"
@update:modelValue="handleOverlayButtonRadio">
<div class="flex items-center space-x-2">
<RadioGroupItem id="overlaybutton-false" value="false" />
<label for="overlaybutton-false">{{
t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button_grip')
}}</label>
</div>
<div class="flex items-center space-x-2">
<RadioGroupItem id="overlaybutton-true" value="true" />
<label for="overlaybutton-true">{{
t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button_menu')
}}</label>
</div>
</RadioGroup>
</SettingsItem>
<SettingsItem
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on')">
<ToggleGroup
type="single"
required
variant="outline"
size="sm"
:model-value="overlayHand"
@update:model-value="
setOverlayHand($event);
saveOpenVROption();
">
<ToggleGroupItem value="1">{{
t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_left')
}}</ToggleGroupItem>
<ToggleGroupItem value="2">{{
t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_right')
}}</ToggleGroupItem>
<ToggleGroupItem value="0">{{
t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_both')
}}</ToggleGroupItem>
</ToggleGroup>
</SettingsItem>
<SettingsItem
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.grey_background')">
<Switch
:model-value="vrBackgroundEnabled"
:disabled="!openVR || !overlayWrist"
@update:modelValue="
setVrBackgroundEnabled();
saveOpenVROption();
" />
</SettingsItem>
<SettingsItem
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.minimal_feed_icons')">
<Switch
:model-value="minimalFeed"
:disabled="!openVR || !overlayWrist"
@update:modelValue="
setMinimalFeed();
saveOpenVROption();
" />
</SettingsItem>
<SettingsItem :label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.show_vr_devices')">
<Switch
:model-value="!hideDevicesFromFeed"
:disabled="!openVR || !overlayWrist"
@update:modelValue="
setHideDevicesFromFeed();
saveOpenVROption();
" />
</SettingsItem>
<SettingsItem :label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.show_cpu_usage')">
<Switch
:model-value="vrOverlayCpuUsage"
:disabled="!openVR || !overlayWrist"
@update:modelValue="
setVrOverlayCpuUsage();
saveOpenVROption();
" />
</SettingsItem>
<SettingsItem
:label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.show_game_uptime')">
<Switch
:model-value="!hideUptimeFromFeed"
:disabled="!openVR || !overlayWrist"
@update:modelValue="
setHideUptimeFromFeed();
saveOpenVROption();
" />
</SettingsItem>
<SettingsItem :label="t('view.settings.wrist_overlay.steamvr_wrist_overlay.show_pc_uptime')">
<Switch
:model-value="pcUptimeOnFeed"
:disabled="!openVR || !overlayWrist"
@update:modelValue="
setPcUptimeOnFeed();
saveOpenVROption();
" />
</SettingsItem>
</SettingsGroup>
</div>
</template>
<script setup>
import { Button } from '@/components/ui/button';
import { Switch } from '@/components/ui/switch';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { ToggleGroup, ToggleGroupItem } from '@/components/ui/toggle-group';
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
import { useNotificationsSettingsStore, useVrStore, useWristOverlaySettingsStore } from '../../../stores';
import { RadioGroup, RadioGroupItem } from '../../../components/ui/radio-group';
import { ToggleGroup, ToggleGroupItem } from '../../../components/ui/toggle-group';
import { useNotificationsSettingsStore, useVrStore, useWristOverlaySettingsStore } from '@/stores';
import SimpleSwitch from './SimpleSwitch.vue';
import SettingsGroup from './SettingsGroup.vue';
import SettingsItem from './SettingsItem.vue';
const emit = defineEmits(['open-feed-filters']);
const { t } = useI18n();