mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-06 22:46:06 +02:00
Add language selection dropdown to the login view
This commit is contained in:
@@ -74,29 +74,22 @@
|
|||||||
@click="copyUserDisplayName(currentUser.username)"></span>
|
@click="copyUserDisplayName(currentUser.username)"></span>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 5px" v-show="!userDialog.loading">
|
<div class="mt-2 flex items-center gap-1" v-show="!userDialog.loading">
|
||||||
<TooltipWrapper side="top" :content="t('dialog.user.tags.trust_level')">
|
<TooltipWrapper side="top" :content="t('dialog.user.tags.trust_level')">
|
||||||
<Badge
|
<Badge variant="outline" class="name" :class="userDialog.ref.$trustClass">
|
||||||
variant="outline"
|
<Shield class="h-4 w-4" /> {{ userDialog.ref.$trustLevel }}
|
||||||
class="name"
|
|
||||||
:class="userDialog.ref.$trustClass"
|
|
||||||
style="margin-right: 5px; margin-top: 5px">
|
|
||||||
<Shield class="mr-1 h-4 w-4 inline-block" /> {{ userDialog.ref.$trustLevel }}
|
|
||||||
</Badge>
|
</Badge>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
<TooltipWrapper
|
<TooltipWrapper
|
||||||
v-if="userDialog.ref.ageVerified && userDialog.ref.ageVerificationStatus"
|
v-if="userDialog.ref.ageVerified && userDialog.ref.ageVerificationStatus"
|
||||||
side="top"
|
side="top"
|
||||||
:content="t('dialog.user.tags.age_verified')">
|
:content="t('dialog.user.tags.age_verified')">
|
||||||
<Badge
|
<Badge variant="outline" class="x-tag-age-verification">
|
||||||
variant="outline"
|
|
||||||
class="x-tag-age-verification"
|
|
||||||
style="margin-right: 5px; margin-top: 5px">
|
|
||||||
<template v-if="userDialog.ref.ageVerificationStatus === '18+'">
|
<template v-if="userDialog.ref.ageVerificationStatus === '18+'">
|
||||||
<IdCard class="mr-1 h-4 w-4 inline-block" /> 18+
|
<IdCard class="h-4 w-4" /> 18+
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<IdCard class="mr-1 h-4 w-4 inline-block" />
|
<IdCard class="h-4 w-4" />
|
||||||
</template>
|
</template>
|
||||||
</Badge>
|
</Badge>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
@@ -104,8 +97,8 @@
|
|||||||
v-if="userDialog.isFriend && userDialog.friend"
|
v-if="userDialog.isFriend && userDialog.friend"
|
||||||
side="top"
|
side="top"
|
||||||
:content="t('dialog.user.tags.friend_number')">
|
:content="t('dialog.user.tags.friend_number')">
|
||||||
<Badge variant="outline" class="x-tag-friend" style="margin-right: 5px; margin-top: 5px">
|
<Badge variant="outline" class="x-tag-friend">
|
||||||
<UserPlus class="mr-1 h-4 w-4 inline-block" />
|
<UserPlus class="h-4 w-4" />
|
||||||
{{ userDialog.ref.$friendNumber ? userDialog.ref.$friendNumber : '' }}
|
{{ userDialog.ref.$friendNumber ? userDialog.ref.$friendNumber : '' }}
|
||||||
</Badge>
|
</Badge>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
@@ -113,11 +106,8 @@
|
|||||||
v-if="userDialog.mutualFriendCount"
|
v-if="userDialog.mutualFriendCount"
|
||||||
side="top"
|
side="top"
|
||||||
:content="t('dialog.user.tags.mutual_friends')">
|
:content="t('dialog.user.tags.mutual_friends')">
|
||||||
<Badge
|
<Badge variant="outline" class="x-tag-mutual-friend border-zinc-500/50! dark:border-zinc-400!">
|
||||||
variant="outline"
|
<Users class="h-4 w-4" />
|
||||||
class="x-tag-mutual-friend border-zinc-500/50! dark:border-zinc-400!"
|
|
||||||
style="margin-right: 5px; margin-top: 5px">
|
|
||||||
<Users class="mr-1 h-4 w-4 inline-block" />
|
|
||||||
{{ userDialog.mutualFriendCount }}
|
{{ userDialog.mutualFriendCount }}
|
||||||
</Badge>
|
</Badge>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
@@ -128,60 +118,35 @@
|
|||||||
<Badge
|
<Badge
|
||||||
variant="outline"
|
variant="outline"
|
||||||
class="x-tag-discord cursor-pointer"
|
class="x-tag-discord cursor-pointer"
|
||||||
style="margin-right: 5px; margin-top: 5px"
|
|
||||||
@click="openDiscordProfile(userDialog.ref.discordId)">
|
@click="openDiscordProfile(userDialog.ref.discordId)">
|
||||||
<i class="ri-discord-line mr-1 h-4 w-4 inline-block" style="height: 1em; width: 1em"></i>
|
<i class="ri-discord-line text-xs"></i>
|
||||||
{{ t('dialog.user.tags.discord') }}
|
{{ t('dialog.user.tags.discord') }}
|
||||||
</Badge>
|
</Badge>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
<Badge
|
<Badge v-if="userDialog.ref.$isTroll" variant="outline" class="x-tag-troll"> Nuisance </Badge>
|
||||||
v-if="userDialog.ref.$isTroll"
|
<Badge v-if="userDialog.ref.$isProbableTroll" variant="outline" class="x-tag-troll">
|
||||||
variant="outline"
|
|
||||||
class="x-tag-troll"
|
|
||||||
style="margin-right: 5px; margin-top: 5px">
|
|
||||||
Nuisance
|
|
||||||
</Badge>
|
|
||||||
<Badge
|
|
||||||
v-if="userDialog.ref.$isProbableTroll"
|
|
||||||
variant="outline"
|
|
||||||
class="x-tag-troll"
|
|
||||||
style="margin-right: 5px; margin-top: 5px">
|
|
||||||
Almost Nuisance
|
Almost Nuisance
|
||||||
</Badge>
|
</Badge>
|
||||||
<Badge
|
<Badge v-if="userDialog.ref.$isModerator" variant="outline" class="x-tag-vip">
|
||||||
v-if="userDialog.ref.$isModerator"
|
|
||||||
variant="outline"
|
|
||||||
class="x-tag-vip"
|
|
||||||
style="margin-right: 5px; margin-top: 5px">
|
|
||||||
{{ t('dialog.user.tags.vrchat_team') }}
|
{{ t('dialog.user.tags.vrchat_team') }}
|
||||||
</Badge>
|
</Badge>
|
||||||
|
|
||||||
<TooltipWrapper v-if="userDialog.ref.$platform === 'standalonewindows'" side="top" content="PC">
|
<TooltipWrapper v-if="userDialog.ref.$platform === 'standalonewindows'" side="top" content="PC">
|
||||||
<Badge variant="outline" class="x-tag-platform-pc" style="margin-right: 5px; margin-top: 5px">
|
<Badge variant="outline" class="x-tag-platform-pc">
|
||||||
<Monitor class="h-4 w-4 x-tag-platform-pc" />
|
<Monitor class="m-0.5 x-tag-platform-pc" />
|
||||||
</Badge>
|
</Badge>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
<TooltipWrapper v-else-if="userDialog.ref.$platform === 'android'" side="top" content="Android">
|
<TooltipWrapper v-else-if="userDialog.ref.$platform === 'android'" side="top" content="Android">
|
||||||
<Badge
|
<Badge variant="outline" class="x-tag-platform-quest">
|
||||||
variant="outline"
|
<Smartphone class="m-0.5 x-tag-platform-quest" />
|
||||||
class="x-tag-platform-quest"
|
|
||||||
style="margin-right: 5px; margin-top: 5px">
|
|
||||||
<Smartphone class="h-4 w-4 x-tag-platform-quest" />
|
|
||||||
</Badge>
|
</Badge>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
<TooltipWrapper v-else-if="userDialog.ref.$platform === 'ios'" side="top" content="iOS">
|
<TooltipWrapper v-else-if="userDialog.ref.$platform === 'ios'" side="top" content="iOS">
|
||||||
<Badge
|
<Badge variant="outline" class="text-[#8e8e93] border-[#8e8e93]">
|
||||||
variant="outline"
|
<Apple class="m-0.5 text-[#8e8e93]" />
|
||||||
class="text-[#8e8e93] border-[#8e8e93]"
|
|
||||||
style="margin-right: 5px; margin-top: 5px">
|
|
||||||
<Apple class="h-4 w-4 text-[#8e8e93]" />
|
|
||||||
</Badge>
|
</Badge>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
<Badge
|
<Badge v-else-if="userDialog.ref.$platform" variant="outline" class="x-tag-platform-other">
|
||||||
v-else-if="userDialog.ref.$platform"
|
|
||||||
variant="outline"
|
|
||||||
class="x-tag-platform-other"
|
|
||||||
style="margin-right: 5px; margin-top: 5px">
|
|
||||||
{{ userDialog.ref.$platform }}
|
{{ userDialog.ref.$platform }}
|
||||||
</Badge>
|
</Badge>
|
||||||
|
|
||||||
@@ -193,10 +158,10 @@
|
|||||||
color: userDialog.ref.$customTagColour,
|
color: userDialog.ref.$customTagColour,
|
||||||
'border-color': userDialog.ref.$customTagColour
|
'border-color': userDialog.ref.$customTagColour
|
||||||
}"
|
}"
|
||||||
style="margin-right: 5px; margin-top: 5px"
|
|
||||||
>{{ userDialog.ref.$customTag }}</Badge
|
>{{ userDialog.ref.$customTag }}</Badge
|
||||||
>
|
>
|
||||||
<br />
|
</div>
|
||||||
|
<div class="mt-1">
|
||||||
<TooltipWrapper v-for="badge in userDialog.ref.badges" :key="badge.badgeId" side="top">
|
<TooltipWrapper v-for="badge in userDialog.ref.badges" :key="badge.badgeId" side="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
<span>{{ badge.badgeName }}</span>
|
<span>{{ badge.badgeName }}</span>
|
||||||
@@ -261,7 +226,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-top: 5px">
|
<div>
|
||||||
<span style="font-size: 12px" v-text="userDialog.ref.statusDescription"></span>
|
<span style="font-size: 12px" v-text="userDialog.ref.statusDescription"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+41
-10
@@ -3,14 +3,30 @@
|
|||||||
<div style="position: absolute; top: 0; left: 0; margin: 5px">
|
<div style="position: absolute; top: 0; left: 0; margin: 5px">
|
||||||
<TooltipWrapper v-if="!noUpdater" side="top" :content="t('view.login.updater')">
|
<TooltipWrapper v-if="!noUpdater" side="top" :content="t('view.login.updater')">
|
||||||
<Button class="rounded-full mr-2 text-xs" size="icon-sm" variant="ghost" @click="showVRCXUpdateDialog"
|
<Button class="rounded-full mr-2 text-xs" size="icon-sm" variant="ghost" @click="showVRCXUpdateDialog"
|
||||||
><CircleArrowDown
|
><ArrowBigDownDash
|
||||||
/></Button>
|
/></Button>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
<TooltipWrapper side="top" :content="t('view.login.proxy_settings')">
|
<TooltipWrapper side="top" :content="t('view.login.proxy_settings')">
|
||||||
<Button class="rounded-full text-xs" size="icon-sm" variant="ghost" @click="promptProxySettings"
|
<Button class="rounded-full mr-2 text-xs" size="icon-sm" variant="ghost" @click="promptProxySettings"
|
||||||
><Route
|
><Earth
|
||||||
/></Button>
|
/></Button>
|
||||||
</TooltipWrapper>
|
</TooltipWrapper>
|
||||||
|
<DropdownMenu>
|
||||||
|
<DropdownMenuTrigger as-child>
|
||||||
|
<Button class="rounded-full text-xs" size="icon-sm" variant="ghost">
|
||||||
|
<Languages />
|
||||||
|
</Button>
|
||||||
|
</DropdownMenuTrigger>
|
||||||
|
<DropdownMenuContent class="max-h-80 overflow-y-auto text-xs">
|
||||||
|
<DropdownMenuCheckboxItem
|
||||||
|
v-for="language in languageCodes"
|
||||||
|
:key="language"
|
||||||
|
:model-value="appLanguage === language"
|
||||||
|
@select="changeAppLanguage(language)">
|
||||||
|
{{ getLanguageName(language) }}
|
||||||
|
</DropdownMenuCheckboxItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
</div>
|
</div>
|
||||||
<div class="x-login">
|
<div class="x-login">
|
||||||
<div class="x-login-form-container">
|
<div class="x-login-form-container">
|
||||||
@@ -60,11 +76,11 @@
|
|||||||
</Field>
|
</Field>
|
||||||
</VeeField>
|
</VeeField>
|
||||||
</FieldGroup>
|
</FieldGroup>
|
||||||
<label class="inline-flex items-center gap-2 mr-2">
|
<label class="inline-flex items-center gap-2 mr-2 text-sm">
|
||||||
<Checkbox v-model="loginForm.saveCredentials" />
|
<Checkbox v-model="loginForm.saveCredentials" />
|
||||||
<span>{{ t('view.login.field.saveCredentials') }}</span>
|
<span>{{ t('view.login.field.saveCredentials') }}</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="inline-flex items-center gap-2" style="margin-top: 10px">
|
<label class="inline-flex items-center gap-2 text-sm" style="margin-top: 10px">
|
||||||
<Checkbox v-model="enableCustomEndpoint" @update:modelValue="handleCustomEndpointToggle" />
|
<Checkbox v-model="enableCustomEndpoint" @update:modelValue="handleCustomEndpointToggle" />
|
||||||
<span>{{ t('view.login.field.devEndpoint') }}</span>
|
<span>{{ t('view.login.field.devEndpoint') }}</span>
|
||||||
</label>
|
</label>
|
||||||
@@ -145,12 +161,11 @@
|
|||||||
<span class="block truncate text-xs" v-text="user.loginParams.endpoint"></span>
|
<span class="block truncate text-xs" v-text="user.loginParams.endpoint"></span>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<Button
|
||||||
class="rounded-full"
|
|
||||||
size="icon-sm"
|
size="icon-sm"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
style="margin-left: 10px"
|
class="cursor-pointer ml-2"
|
||||||
@click.stop="clickDeleteSavedLogin(user.user.id)"
|
@click.stop="clickDeleteSavedLogin(user.user.id)"
|
||||||
><Trash2 class="h-3 w-3"
|
><Minus class="text-sm"
|
||||||
/></Button>
|
/></Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -186,8 +201,14 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { Field, FieldContent, FieldError, FieldGroup, FieldLabel } from '@/components/ui/field';
|
import { Field, FieldContent, FieldError, FieldGroup, FieldLabel } from '@/components/ui/field';
|
||||||
|
import { ArrowBigDownDash, Earth, Languages, Minus } from 'lucide-vue-next';
|
||||||
|
import {
|
||||||
|
DropdownMenu,
|
||||||
|
DropdownMenuCheckboxItem,
|
||||||
|
DropdownMenuContent,
|
||||||
|
DropdownMenuTrigger
|
||||||
|
} from '@/components/ui/dropdown-menu';
|
||||||
import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue';
|
import { onBeforeMount, onBeforeUnmount, ref, watch } from 'vue';
|
||||||
import { CircleArrowDown, Route, Trash2 } from 'lucide-vue-next';
|
|
||||||
import { Field as VeeField, useForm } from 'vee-validate';
|
import { Field as VeeField, useForm } from 'vee-validate';
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
@@ -198,7 +219,13 @@
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
|
|
||||||
import { useAuthStore, useGeneralSettingsStore, useVRCXUpdaterStore } from '../../stores';
|
import {
|
||||||
|
useAppearanceSettingsStore,
|
||||||
|
useAuthStore,
|
||||||
|
useGeneralSettingsStore,
|
||||||
|
useVRCXUpdaterStore
|
||||||
|
} from '../../stores';
|
||||||
|
import { getLanguageName, languageCodes } from '../../localization';
|
||||||
import { openExternalLink, userImage } from '../../shared/utils';
|
import { openExternalLink, userImage } from '../../shared/utils';
|
||||||
import { AppDebug } from '../../service/appConfig';
|
import { AppDebug } from '../../service/appConfig';
|
||||||
import { watchState } from '../../service/watchState';
|
import { watchState } from '../../service/watchState';
|
||||||
@@ -211,6 +238,10 @@
|
|||||||
const { promptProxySettings } = useGeneralSettingsStore();
|
const { promptProxySettings } = useGeneralSettingsStore();
|
||||||
const { noUpdater } = storeToRefs(useVRCXUpdaterStore());
|
const { noUpdater } = storeToRefs(useVRCXUpdaterStore());
|
||||||
|
|
||||||
|
const appearanceSettingsStore = useAppearanceSettingsStore();
|
||||||
|
const { appLanguage } = storeToRefs(appearanceSettingsStore);
|
||||||
|
const { changeAppLanguage } = appearanceSettingsStore;
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
const savedCredentials = ref({});
|
const savedCredentials = ref({});
|
||||||
|
|||||||
Reference in New Issue
Block a user