fix select ui
This commit is contained in:
@@ -33,6 +33,19 @@ const newSessionPartner = ref<Participant>({
|
|||||||
tone: 'Auto-detect'
|
tone: 'Auto-detect'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Custom Dropdown States for Modal
|
||||||
|
const meLangDropdownOpen = ref(false);
|
||||||
|
const meGenderDropdownOpen = ref(false);
|
||||||
|
const partnerLangDropdownOpen = ref(false);
|
||||||
|
const partnerGenderDropdownOpen = ref(false);
|
||||||
|
|
||||||
|
const closeAllModalDropdowns = () => {
|
||||||
|
meLangDropdownOpen.value = false;
|
||||||
|
meGenderDropdownOpen.value = false;
|
||||||
|
partnerLangDropdownOpen.value = false;
|
||||||
|
partnerGenderDropdownOpen.value = false;
|
||||||
|
};
|
||||||
|
|
||||||
// Current active session
|
// Current active session
|
||||||
const activeSession = computed(() =>
|
const activeSession = computed(() =>
|
||||||
settings.chatSessions.find(s => s.id === settings.activeSessionId) || null
|
settings.chatSessions.find(s => s.id === settings.activeSessionId) || null
|
||||||
@@ -179,6 +192,7 @@ const translateMessage = async (sender: 'me' | 'partner') => {
|
|||||||
|
|
||||||
const handleGlobalClick = () => {
|
const handleGlobalClick = () => {
|
||||||
myToneDropdownOpen.value = false;
|
myToneDropdownOpen.value = false;
|
||||||
|
closeAllModalDropdowns();
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(() => window.addEventListener('click', handleGlobalClick));
|
onMounted(() => window.addEventListener('click', handleGlobalClick));
|
||||||
@@ -464,8 +478,8 @@ onUnmounted(() => window.removeEventListener('click', handleGlobalClick));
|
|||||||
leave-to-class="opacity-0 scale-95"
|
leave-to-class="opacity-0 scale-95"
|
||||||
>
|
>
|
||||||
<div v-if="isCreatingSession" class="absolute inset-0 z-[100] flex items-center justify-center p-6 bg-slate-900/20 backdrop-blur-sm">
|
<div v-if="isCreatingSession" class="absolute inset-0 z-[100] flex items-center justify-center p-6 bg-slate-900/20 backdrop-blur-sm">
|
||||||
<div class="w-full max-w-lg bg-white dark:bg-slate-900 rounded-3xl shadow-2xl border dark:border-slate-800 overflow-hidden">
|
<div class="w-full max-w-lg bg-white dark:bg-slate-900 rounded-3xl shadow-2xl border dark:border-slate-800">
|
||||||
<div class="p-6 border-b dark:border-slate-800 flex items-center justify-between bg-slate-50 dark:bg-slate-950">
|
<div class="p-6 border-b dark:border-slate-800 flex items-center justify-between bg-slate-50 dark:bg-slate-950 rounded-t-3xl">
|
||||||
<h3 class="text-lg font-bold dark:text-slate-100 flex items-center gap-2">
|
<h3 class="text-lg font-bold dark:text-slate-100 flex items-center gap-2">
|
||||||
<Plus class="w-5 h-5 text-blue-500" />
|
<Plus class="w-5 h-5 text-blue-500" />
|
||||||
创建新会话
|
创建新会话
|
||||||
@@ -486,17 +500,41 @@ onUnmounted(() => window.removeEventListener('click', handleGlobalClick));
|
|||||||
</div>
|
</div>
|
||||||
<div class="space-y-1.5">
|
<div class="space-y-1.5">
|
||||||
<label class="text-[10px] font-bold text-slate-400 uppercase">使用语言</label>
|
<label class="text-[10px] font-bold text-slate-400 uppercase">使用语言</label>
|
||||||
<select v-model="newSessionMe.language" class="w-full px-4 py-2.5 bg-slate-50 dark:bg-slate-800 border dark:border-slate-700 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 text-sm dark:text-slate-200 appearance-none">
|
<div class="relative">
|
||||||
<option v-for="lang in LANGUAGES" :key="lang.code" :value="lang">{{ lang.displayName }}</option>
|
<button
|
||||||
</select>
|
@click.stop="closeAllModalDropdowns(); meLangDropdownOpen = !meLangDropdownOpen"
|
||||||
|
class="w-full flex items-center justify-between px-4 py-2.5 bg-slate-50 dark:bg-slate-800 border dark:border-slate-700 rounded-xl text-sm dark:text-slate-200"
|
||||||
|
>
|
||||||
|
{{ newSessionMe.language.displayName }}
|
||||||
|
<ChevronDown class="w-4 h-4 text-slate-400" />
|
||||||
|
</button>
|
||||||
|
<div v-if="meLangDropdownOpen" class="absolute left-0 top-full mt-1 w-full max-h-60 overflow-y-auto bg-white dark:bg-slate-800 border dark:border-slate-700 rounded-xl shadow-xl z-[110] py-2 custom-scrollbar">
|
||||||
|
<button v-for="lang in LANGUAGES" :key="lang.code" @click="newSessionMe.language = lang; meLangDropdownOpen = false" class="w-full px-4 py-2 text-sm text-left hover:bg-slate-100 dark:hover:bg-slate-700 dark:text-slate-200 transition-colors flex items-center justify-between">
|
||||||
|
{{ lang.displayName }}
|
||||||
|
<Check v-if="newSessionMe.language.code === lang.code" class="w-3.5 h-3.5 text-blue-500" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 gap-4">
|
<div class="grid grid-cols-2 gap-4">
|
||||||
<div class="space-y-1.5">
|
<div class="space-y-1.5">
|
||||||
<label class="text-[10px] font-bold text-slate-400 uppercase">性别</label>
|
<label class="text-[10px] font-bold text-slate-400 uppercase">性别</label>
|
||||||
<select v-model="newSessionMe.gender" class="w-full px-4 py-2.5 bg-slate-50 dark:bg-slate-800 border dark:border-slate-700 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 text-sm dark:text-slate-200 appearance-none">
|
<div class="relative">
|
||||||
<option v-for="opt in SPEAKER_IDENTITY_OPTIONS" :key="opt.value" :value="opt.value">{{ opt.label }}</option>
|
<button
|
||||||
</select>
|
@click.stop="closeAllModalDropdowns(); meGenderDropdownOpen = !meGenderDropdownOpen"
|
||||||
|
class="w-full flex items-center justify-between px-4 py-2.5 bg-slate-50 dark:bg-slate-800 border dark:border-slate-700 rounded-xl text-sm dark:text-slate-200"
|
||||||
|
>
|
||||||
|
{{ SPEAKER_IDENTITY_OPTIONS.find(o => o.value === newSessionMe.gender)?.label }}
|
||||||
|
<ChevronDown class="w-4 h-4 text-slate-400" />
|
||||||
|
</button>
|
||||||
|
<div v-if="meGenderDropdownOpen" class="absolute left-0 top-full mt-1 w-full bg-white dark:bg-slate-800 border dark:border-slate-700 rounded-xl shadow-xl z-[110] py-2">
|
||||||
|
<button v-for="opt in SPEAKER_IDENTITY_OPTIONS" :key="opt.value" @click="newSessionMe.gender = opt.value; meGenderDropdownOpen = false" class="w-full px-4 py-2 text-sm text-left hover:bg-slate-100 dark:hover:bg-slate-700 dark:text-slate-200 transition-colors flex items-center justify-between">
|
||||||
|
{{ opt.label }}
|
||||||
|
<Check v-if="newSessionMe.gender === opt.value" class="w-3.5 h-3.5 text-blue-500" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
@@ -511,17 +549,41 @@ onUnmounted(() => window.removeEventListener('click', handleGlobalClick));
|
|||||||
</div>
|
</div>
|
||||||
<div class="space-y-1.5">
|
<div class="space-y-1.5">
|
||||||
<label class="text-[10px] font-bold text-slate-400 uppercase">使用语言</label>
|
<label class="text-[10px] font-bold text-slate-400 uppercase">使用语言</label>
|
||||||
<select v-model="newSessionPartner.language" class="w-full px-4 py-2.5 bg-slate-50 dark:bg-slate-800 border dark:border-slate-700 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 text-sm dark:text-slate-200 appearance-none">
|
<div class="relative">
|
||||||
<option v-for="lang in LANGUAGES" :key="lang.code" :value="lang">{{ lang.displayName }}</option>
|
<button
|
||||||
</select>
|
@click.stop="closeAllModalDropdowns(); partnerLangDropdownOpen = !partnerLangDropdownOpen"
|
||||||
|
class="w-full flex items-center justify-between px-4 py-2.5 bg-slate-50 dark:bg-slate-800 border dark:border-slate-700 rounded-xl text-sm dark:text-slate-200"
|
||||||
|
>
|
||||||
|
{{ newSessionPartner.language.displayName }}
|
||||||
|
<ChevronDown class="w-4 h-4 text-slate-400" />
|
||||||
|
</button>
|
||||||
|
<div v-if="partnerLangDropdownOpen" class="absolute left-0 top-full mt-1 w-full max-h-60 overflow-y-auto bg-white dark:bg-slate-800 border dark:border-slate-700 rounded-xl shadow-xl z-[110] py-2 custom-scrollbar">
|
||||||
|
<button v-for="lang in LANGUAGES" :key="lang.code" @click="newSessionPartner.language = lang; partnerLangDropdownOpen = false" class="w-full px-4 py-2 text-sm text-left hover:bg-slate-100 dark:hover:bg-slate-700 dark:text-slate-200 transition-colors flex items-center justify-between">
|
||||||
|
{{ lang.displayName }}
|
||||||
|
<Check v-if="newSessionPartner.language.code === lang.code" class="w-3.5 h-3.5 text-blue-500" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-2 gap-4">
|
<div class="grid grid-cols-2 gap-4">
|
||||||
<div class="space-y-1.5">
|
<div class="space-y-1.5">
|
||||||
<label class="text-[10px] font-bold text-slate-400 uppercase">性别</label>
|
<label class="text-[10px] font-bold text-slate-400 uppercase">性别</label>
|
||||||
<select v-model="newSessionPartner.gender" class="w-full px-4 py-2.5 bg-slate-50 dark:bg-slate-800 border dark:border-slate-700 rounded-xl outline-none focus:ring-2 focus:ring-blue-500/20 text-sm dark:text-slate-200 appearance-none">
|
<div class="relative">
|
||||||
<option v-for="opt in SPEAKER_IDENTITY_OPTIONS" :key="opt.value" :value="opt.value">{{ opt.label }}</option>
|
<button
|
||||||
</select>
|
@click.stop="closeAllModalDropdowns(); partnerGenderDropdownOpen = !partnerGenderDropdownOpen"
|
||||||
|
class="w-full flex items-center justify-between px-4 py-2.5 bg-slate-50 dark:bg-slate-800 border dark:border-slate-700 rounded-xl text-sm dark:text-slate-200"
|
||||||
|
>
|
||||||
|
{{ SPEAKER_IDENTITY_OPTIONS.find(o => o.value === newSessionPartner.gender)?.label }}
|
||||||
|
<ChevronDown class="w-4 h-4 text-slate-400" />
|
||||||
|
</button>
|
||||||
|
<div v-if="partnerGenderDropdownOpen" class="absolute left-0 top-full mt-1 w-full bg-white dark:bg-slate-800 border dark:border-slate-700 rounded-xl shadow-xl z-[110] py-2">
|
||||||
|
<button v-for="opt in SPEAKER_IDENTITY_OPTIONS" :key="opt.value" @click="newSessionPartner.gender = opt.value; partnerGenderDropdownOpen = false" class="w-full px-4 py-2 text-sm text-left hover:bg-slate-100 dark:hover:bg-slate-700 dark:text-slate-200 transition-colors flex items-center justify-between">
|
||||||
|
{{ opt.label }}
|
||||||
|
<Check v-if="newSessionPartner.gender === opt.value" class="w-3.5 h-3.5 text-blue-500" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|||||||
Reference in New Issue
Block a user