replace ElMessageBox.prompt

This commit is contained in:
pa
2026-01-15 11:46:03 +09:00
committed by Natsumi
parent 87dc871578
commit fc13dca0a4
22 changed files with 413 additions and 408 deletions

View File

@@ -1,5 +1,4 @@
import { reactive, ref, watch } from 'vue';
import { ElMessageBox } from 'element-plus';
import { defineStore } from 'pinia';
import { toast } from 'vue-sonner';
import { useI18n } from 'vue-i18n';
@@ -255,15 +254,21 @@ export const useAuthStore = defineStore('Auth', () => {
if (advancedSettingsStore.enablePrimaryPassword) {
enablePrimaryPasswordDialog.value.visible = true;
} else {
ElMessageBox.prompt(
t('prompt.primary_password.description'),
t('prompt.primary_password.header'),
{
inputType: 'password',
inputPattern: /[\s\S]{1,32}/
}
)
.then(async ({ value }) => {
modalStore
.prompt({
title: t('prompt.primary_password.header'),
description: t('prompt.primary_password.description'),
pattern: /[\s\S]{1,32}/
})
.then(async ({ ok, value }) => {
if (!ok) {
advancedSettingsStore.enablePrimaryPassword = true;
advancedSettingsStore.setEnablePrimaryPasswordConfigRepository(
true
);
return;
}
const savedCredentials = JSON.parse(
await configRepository.getString(
'savedCredentials',
@@ -299,7 +304,8 @@ export const useAuthStore = defineStore('Auth', () => {
});
}
})
.catch(async () => {
.catch((err) => {
console.error(err);
advancedSettingsStore.enablePrimaryPassword = true;
advancedSettingsStore.setEnablePrimaryPasswordConfigRepository(
true
@@ -378,16 +384,19 @@ export const useAuthStore = defineStore('Auth', () => {
return new Promise((resolve, reject) => {
if (!advancedSettingsStore.enablePrimaryPassword) {
resolve(args.password);
return;
}
ElMessageBox.prompt(
t('prompt.primary_password.description'),
t('prompt.primary_password.header'),
{
inputType: 'password',
inputPattern: /[\s\S]{1,32}/
}
)
.then(({ value }) => {
modalStore
.prompt({
title: t('prompt.primary_password.header'),
description: t('prompt.primary_password.description'),
pattern: /[\s\S]{1,32}/
})
.then(({ ok, value }) => {
if (!ok) {
reject(new Error('primary password prompt cancelled'));
return;
}
security
.decrypt(args.password, value)
.then(resolve)
@@ -536,15 +545,16 @@ export const useAuthStore = defineStore('Auth', () => {
loginForm.value.saveCredentials &&
advancedSettingsStore.enablePrimaryPassword
) {
ElMessageBox.prompt(
t('prompt.primary_password.description'),
t('prompt.primary_password.header'),
{
inputType: 'password',
inputPattern: /[\s\S]{1,32}/
}
)
.then(async ({ value }) => {
modalStore
.prompt({
title: t('prompt.primary_password.header'),
description: t(
'prompt.primary_password.description'
),
pattern: /[\s\S]{1,32}/
})
.then(async ({ ok, value }) => {
if (!ok) return;
const savedCredentials = JSON.parse(
await configRepository.getString(
'savedCredentials'
@@ -613,41 +623,39 @@ export const useAuthStore = defineStore('Auth', () => {
}
AppApi.FlashWindow();
twoFactorAuthDialogVisible.value = true;
ElMessageBox.prompt(
t('prompt.totp.description'),
t('prompt.totp.header'),
{
distinguishCancelAndClose: true,
cancelButtonText: t('prompt.totp.use_otp'),
confirmButtonText: t('prompt.totp.verify'),
inputPlaceholder: t('prompt.totp.input_placeholder'),
inputPattern: /^[0-9]{6}$/,
inputErrorMessage: t('prompt.totp.input_error'),
beforeClose: (action, instance, done) => {
twoFactorAuthDialogVisible.value = false;
if (action === 'cancel') {
promptOTP();
}
done();
}
}
)
.then(({ value, action }) => {
if (action === 'confirm') {
authRequest
.verifyTOTP({
code: value.trim()
})
.catch((err) => {
console.error(err);
clearCookiesTryLogin();
})
.then(() => {
userStore.getCurrentUser();
});
}
modalStore
.prompt({
title: t('prompt.totp.header'),
description: t('prompt.totp.description'),
cancelText: t('prompt.totp.use_otp'),
confirmText: t('prompt.totp.verify'),
pattern: /^[0-9]{6}$/,
errorMessage: t('prompt.totp.input_error')
})
.catch(() => {});
.then(({ ok, reason, value }) => {
twoFactorAuthDialogVisible.value = false;
if (reason === 'cancel') {
promptOTP();
return;
}
if (!ok) return;
authRequest
.verifyTOTP({
code: value.trim()
})
.catch((err) => {
console.error(err);
clearCookiesTryLogin();
})
.then(() => {
userStore.getCurrentUser();
});
})
.catch(() => {
twoFactorAuthDialogVisible.value = false;
});
}
function promptOTP() {
@@ -655,41 +663,39 @@ export const useAuthStore = defineStore('Auth', () => {
return;
}
twoFactorAuthDialogVisible.value = true;
ElMessageBox.prompt(
t('prompt.otp.description'),
t('prompt.otp.header'),
{
distinguishCancelAndClose: true,
cancelButtonText: t('prompt.otp.use_totp'),
confirmButtonText: t('prompt.otp.verify'),
inputPlaceholder: t('prompt.otp.input_placeholder'),
inputPattern: /^[a-z0-9]{4}-[a-z0-9]{4}$/,
inputErrorMessage: t('prompt.otp.input_error'),
beforeClose: (action, instance, done) => {
twoFactorAuthDialogVisible.value = false;
if (action === 'cancel') {
promptTOTP();
}
done();
}
}
)
.then(({ value, action }) => {
if (action === 'confirm') {
authRequest
.verifyOTP({
code: value.trim()
})
.catch((err) => {
console.error(err);
clearCookiesTryLogin();
})
.then(() => {
userStore.getCurrentUser();
});
}
modalStore
.prompt({
title: t('prompt.otp.header'),
description: t('prompt.otp.description'),
cancelText: t('prompt.otp.use_totp'),
confirmText: t('prompt.otp.verify'),
pattern: /^[a-z0-9]{4}-[a-z0-9]{4}$/,
errorMessage: t('prompt.otp.input_error')
})
.catch(() => {});
.then(({ ok, reason, value }) => {
twoFactorAuthDialogVisible.value = false;
if (reason === 'cancel') {
promptTOTP();
return;
}
if (!ok) return;
authRequest
.verifyOTP({
code: value.trim()
})
.catch((err) => {
console.error(err);
clearCookiesTryLogin();
})
.then(() => {
userStore.getCurrentUser();
});
})
.catch(() => {
twoFactorAuthDialogVisible.value = false;
});
}
function promptEmailOTP() {
@@ -698,42 +704,39 @@ export const useAuthStore = defineStore('Auth', () => {
}
AppApi.FlashWindow();
twoFactorAuthDialogVisible.value = true;
ElMessageBox.prompt(
t('prompt.email_otp.description'),
t('prompt.email_otp.header'),
{
distinguishCancelAndClose: true,
cancelButtonText: t('prompt.email_otp.resend'),
confirmButtonText: t('prompt.email_otp.verify'),
inputPlaceholder: t('prompt.email_otp.input_placeholder'),
inputPattern: /^[0-9]{6}$/,
inputErrorMessage: t('prompt.email_otp.input_error'),
beforeClose: (action, instance, done) => {
twoFactorAuthDialogVisible.value = false;
if (action === 'cancel') {
resendEmail2fa();
return;
}
done();
}
}
)
.then(({ value, action }) => {
if (action === 'confirm') {
authRequest
.verifyEmailOTP({
code: value.trim()
})
.catch((err) => {
console.error(err);
promptEmailOTP();
})
.then(() => {
userStore.getCurrentUser();
});
}
modalStore
.prompt({
title: t('prompt.email_otp.header'),
description: t('prompt.email_otp.description'),
cancelText: t('prompt.email_otp.resend'),
confirmText: t('prompt.email_otp.verify'),
pattern: /^[0-9]{6}$/,
errorMessage: t('prompt.email_otp.input_error')
})
.catch(() => {});
.then(({ ok, reason, value }) => {
twoFactorAuthDialogVisible.value = false;
if (reason === 'cancel') {
resendEmail2fa();
return;
}
if (!ok) return;
authRequest
.verifyEmailOTP({
code: value.trim()
})
.catch((err) => {
console.error(err);
promptEmailOTP();
})
.then(() => {
userStore.getCurrentUser();
});
})
.catch(() => {
twoFactorAuthDialogVisible.value = false;
});
}
/**

View File

@@ -1,5 +1,4 @@
import { computed, reactive, ref } from 'vue';
import { ElMessageBox } from 'element-plus';
import { defineStore } from 'pinia';
import { toast } from 'vue-sonner';
import { useI18n } from 'vue-i18n';
@@ -24,6 +23,7 @@ import { useFriendStore } from './friend';
import { useGameLogStore } from './gameLog';
import { useInstanceStore } from './instance';
import { useLocationStore } from './location';
import { useModalStore } from './modal';
import { useNotificationStore } from './notification';
import { useSharedFeedStore } from './sharedFeed';
import { useUserStore } from './user';
@@ -39,6 +39,7 @@ export const usePhotonStore = defineStore('Photon', () => {
const friendStore = useFriendStore();
const instanceStore = useInstanceStore();
const gameLogStore = useGameLogStore();
const modalStore = useModalStore();
const notificationStore = useNotificationStore();
const locationStore = useLocationStore();
const sharedFeedStore = useSharedFeedStore();
@@ -440,24 +441,21 @@ export const usePhotonStore = defineStore('Photon', () => {
}
function promptPhotonOverlayMessageTimeout() {
ElMessageBox.prompt(
t('prompt.overlay_message_timeout.description'),
t('prompt.overlay_message_timeout.header'),
{
distinguishCancelAndClose: true,
confirmButtonText: t('prompt.overlay_message_timeout.ok'),
cancelButtonText: t('prompt.overlay_message_timeout.cancel'),
modalStore
.prompt({
title: t('prompt.overlay_message_timeout.header'),
description: t('prompt.overlay_message_timeout.description'),
confirmText: t('prompt.overlay_message_timeout.ok'),
cancelText: t('prompt.overlay_message_timeout.cancel'),
inputValue: (
state.photonOverlayMessageTimeout / 1000
).toString(),
inputPattern: /\d+$/,
inputErrorMessage: t(
'prompt.overlay_message_timeout.input_error'
)
}
)
.then(({ value, action }) => {
if (action === 'confirm' && value && !isNaN(Number(value))) {
pattern: /\d+$/,
errorMessage: t('prompt.overlay_message_timeout.input_error')
})
.then(({ ok, value }) => {
if (!ok) return;
if (value && !isNaN(Number(value))) {
state.photonOverlayMessageTimeout = Math.trunc(
Number(value) * 1000
);
@@ -468,22 +466,21 @@ export const usePhotonStore = defineStore('Photon', () => {
}
function promptPhotonLobbyTimeoutThreshold() {
ElMessageBox.prompt(
t('prompt.photon_lobby_timeout.description'),
t('prompt.photon_lobby_timeout.header'),
{
distinguishCancelAndClose: true,
confirmButtonText: t('prompt.photon_lobby_timeout.ok'),
cancelButtonText: t('prompt.photon_lobby_timeout.cancel'),
modalStore
.prompt({
title: t('prompt.photon_lobby_timeout.header'),
description: t('prompt.photon_lobby_timeout.description'),
confirmText: t('prompt.photon_lobby_timeout.ok'),
cancelText: t('prompt.photon_lobby_timeout.cancel'),
inputValue: (
state.photonLobbyTimeoutThreshold / 1000
).toString(),
inputPattern: /\d+$/,
inputErrorMessage: t('prompt.photon_lobby_timeout.input_error')
}
)
.then(({ value, action }) => {
if (action === 'confirm' && value && !isNaN(Number(value))) {
pattern: /\d+$/,
errorMessage: t('prompt.photon_lobby_timeout.input_error')
})
.then(({ ok, value }) => {
if (!ok) return;
if (value && !isNaN(Number(value))) {
state.photonLobbyTimeoutThreshold = Math.trunc(
Number(value) * 1000
);

View File

@@ -1,5 +1,4 @@
import { computed, ref, watch } from 'vue';
import { ElMessageBox } from 'element-plus';
import { defineStore } from 'pinia';
import { toast } from 'vue-sonner';
import { useI18n } from 'vue-i18n';
@@ -13,6 +12,7 @@ import { useAppearanceSettingsStore } from './settings/appearance';
import { useAvatarStore } from './avatar';
import { useFriendStore } from './friend';
import { useGroupStore } from './group';
import { useModalStore } from './modal';
import { useUserStore } from './user';
import { useWorldStore } from './world';
import { watchState } from '../service/watchState';
@@ -25,6 +25,7 @@ export const useSearchStore = defineStore('Search', () => {
const worldStore = useWorldStore();
const avatarStore = useAvatarStore();
const groupStore = useGroupStore();
const modalStore = useModalStore();
const { t } = useI18n();
const searchText = ref('');
@@ -350,22 +351,20 @@ export const useSearchStore = defineStore('Search', () => {
async function promptOmniDirectDialog() {
if (directAccessPrompt.value) return;
directAccessPrompt.value = ElMessageBox.prompt(
t('prompt.direct_access_omni.description'),
t('prompt.direct_access_omni.header'),
{
distinguishCancelAndClose: true,
confirmButtonText: t('prompt.direct_access_omni.ok'),
cancelButtonText: t('prompt.direct_access_omni.cancel'),
inputPattern: /\S+/,
inputErrorMessage: t('prompt.direct_access_omni.input_error')
}
);
// Element Plus: prompt(message, title, options)
directAccessPrompt.value = modalStore.prompt({
title: t('prompt.direct_access_omni.header'),
description: t('prompt.direct_access_omni.description'),
confirmText: t('prompt.direct_access_omni.ok'),
cancelText: t('prompt.direct_access_omni.cancel'),
pattern: /\S+/,
errorMessage: t('prompt.direct_access_omni.input_error')
});
try {
const { value, action } = await directAccessPrompt.value;
const { ok, value } = await directAccessPrompt.value;
if (action === 'confirm' && value) {
if (ok && value) {
const input = value.trim();
if (!directAccessParse(input)) {
toast.error(t('prompt.direct_access_omni.message.error'));

View File

@@ -1,5 +1,4 @@
import { reactive, ref, watch } from 'vue';
import { ElMessageBox } from 'element-plus';
import { defineStore } from 'pinia';
import { toast } from 'vue-sonner';
import { useI18n } from 'vue-i18n';
@@ -855,23 +854,22 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => {
}
function promptAutoClearVRCXCacheFrequency() {
ElMessageBox.prompt(
t('prompt.auto_clear_cache.description'),
t('prompt.auto_clear_cache.header'),
{
distinguishCancelAndClose: true,
confirmButtonText: t('prompt.auto_clear_cache.ok'),
cancelButtonText: t('prompt.auto_clear_cache.cancel'),
modalStore
.prompt({
title: t('prompt.auto_clear_cache.header'),
description: t('prompt.auto_clear_cache.description'),
confirmText: t('prompt.auto_clear_cache.ok'),
cancelText: t('prompt.auto_clear_cache.cancel'),
inputValue: (
vrcxStore.clearVRCXCacheFrequency /
3600 /
2
).toString(),
inputPattern: /\d+$/,
inputErrorMessage: t('prompt.auto_clear_cache.input_error')
}
)
.then(async ({ value }) => {
pattern: /\d+$/,
errorMessage: t('prompt.auto_clear_cache.input_error')
})
.then(async ({ ok, value }) => {
if (!ok) return;
if (value && !isNaN(parseInt(value, 10))) {
vrcxStore.clearVRCXCacheFrequency = Math.trunc(
parseInt(value, 10) * 3600 * 2

View File

@@ -1,5 +1,4 @@
import { computed, ref, watch } from 'vue';
import { ElMessageBox } from 'element-plus';
import { defineStore } from 'pinia';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
@@ -17,6 +16,7 @@ import { loadLocalizedStrings } from '../../plugin';
import { useElementTheme } from '../../composables/useElementTheme';
import { useFeedStore } from '../feed';
import { useGameLogStore } from '../gameLog';
import { useModalStore } from '../modal';
import { useUiStore } from '../ui';
import { useUserStore } from '../user';
import { useVrStore } from '../vr';
@@ -36,6 +36,7 @@ export const useAppearanceSettingsStore = defineStore(
const userStore = useUserStore();
const router = useRouter();
const uiStore = useUiStore();
const modalStore = useModalStore();
const { t, locale } = useI18n();
@@ -746,19 +747,18 @@ export const useAppearanceSettingsStore = defineStore(
}
function promptMaxTableSizeDialog() {
ElMessageBox.prompt(
t('prompt.change_table_size.description'),
t('prompt.change_table_size.header'),
{
distinguishCancelAndClose: true,
confirmButtonText: t('prompt.change_table_size.save'),
cancelButtonText: t('prompt.change_table_size.cancel'),
modalStore
.prompt({
title: t('prompt.change_table_size.header'),
description: t('prompt.change_table_size.description'),
confirmText: t('prompt.change_table_size.save'),
cancelText: t('prompt.change_table_size.cancel'),
inputValue: vrcxStore.maxTableSize.toString(),
inputPattern: /\d+$/,
inputErrorMessage: t('prompt.change_table_size.input_error')
}
)
.then(async ({ value }) => {
pattern: /\d+$/,
errorMessage: t('prompt.change_table_size.input_error')
})
.then(async ({ ok, value }) => {
if (!ok) return;
if (value) {
let processedValue = Number(value);
if (processedValue > 10000) {

View File

@@ -1,9 +1,9 @@
import { ElMessageBox } from 'element-plus';
import { defineStore } from 'pinia';
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { useFriendStore } from '../friend';
import { useModalStore } from '../modal';
import { useVRCXUpdaterStore } from '../vrcxUpdater';
import { useVrcxStore } from '../vrcx';
@@ -15,6 +15,7 @@ export const useGeneralSettingsStore = defineStore('GeneralSettings', () => {
const vrcxStore = useVrcxStore();
const VRCXUpdaterStore = useVRCXUpdaterStore();
const friendStore = useFriendStore();
const modalStore = useModalStore();
const { t } = useI18n();
@@ -231,32 +232,32 @@ export const useGeneralSettingsStore = defineStore('GeneralSettings', () => {
}
function promptProxySettings() {
ElMessageBox.prompt(
t('prompt.proxy_settings.description'),
t('prompt.proxy_settings.header'),
{
distinguishCancelAndClose: true,
confirmButtonText: t('prompt.proxy_settings.restart'),
cancelButtonText: t('prompt.proxy_settings.close'),
inputValue: vrcxStore.proxyServer,
inputPlaceholder: t('prompt.proxy_settings.placeholder')
}
)
.then(async ({ value }) => {
vrcxStore.proxyServer = value;
await VRCXStorage.Set(
'VRCX_ProxyServer',
vrcxStore.proxyServer
);
await VRCXStorage.Save();
await new Promise((resolve) => {
workerTimers.setTimeout(resolve, 100);
});
const { restartVRCX } = VRCXUpdaterStore;
const isUpgrade = false;
restartVRCX(isUpgrade);
// Element Plus: prompt(message, title, options)
modalStore
.prompt({
title: t('prompt.proxy_settings.header'),
description: t('prompt.proxy_settings.description'),
confirmText: t('prompt.proxy_settings.restart'),
cancelText: t('prompt.proxy_settings.close'),
inputValue: vrcxStore.proxyServer
})
.catch(async () => {
.then(async ({ ok, value }) => {
if (ok) {
vrcxStore.proxyServer = value;
await VRCXStorage.Set(
'VRCX_ProxyServer',
vrcxStore.proxyServer
);
await VRCXStorage.Save();
await new Promise((resolve) => {
workerTimers.setTimeout(resolve, 100);
});
const { restartVRCX } = VRCXUpdaterStore;
const isUpgrade = false;
restartVRCX(isUpgrade);
return;
}
// User clicked close/cancel, still save the value but don't restart
if (vrcxStore.proxyServer !== undefined) {
await VRCXStorage.Set(
@@ -268,6 +269,9 @@ export const useGeneralSettingsStore = defineStore('GeneralSettings', () => {
workerTimers.setTimeout(resolve, 100);
});
}
})
.catch((err) => {
console.error(err);
});
}

View File

@@ -1,9 +1,9 @@
import { ElMessageBox } from 'element-plus';
import { defineStore } from 'pinia';
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { sharedFeedFiltersDefaults } from '../../shared/constants';
import { useModalStore } from '../modal';
import { useVrStore } from '../vr';
import configRepository from '../../service/config';
@@ -12,6 +12,7 @@ export const useNotificationsSettingsStore = defineStore(
'NotificationsSettings',
() => {
const vrStore = useVrStore();
const modalStore = useModalStore();
const { t } = useI18n();
@@ -410,21 +411,18 @@ export const useNotificationsSettingsStore = defineStore(
}
function promptNotificationTimeout() {
ElMessageBox.prompt(
t('prompt.notification_timeout.description'),
t('prompt.notification_timeout.header'),
{
distinguishCancelAndClose: true,
confirmButtonText: t('prompt.notification_timeout.ok'),
cancelButtonText: t('prompt.notification_timeout.cancel'),
modalStore
.prompt({
title: t('prompt.notification_timeout.header'),
description: t('prompt.notification_timeout.description'),
confirmText: t('prompt.notification_timeout.ok'),
cancelText: t('prompt.notification_timeout.cancel'),
inputValue: notificationTimeout.value / 1000,
inputPattern: /\d+$/,
inputErrorMessage: t(
'prompt.notification_timeout.input_error'
)
}
)
.then(async ({ value }) => {
pattern: /\d+$/,
errorMessage: t('prompt.notification_timeout.input_error')
})
.then(async ({ ok, value }) => {
if (!ok) return;
if (value && !isNaN(value)) {
notificationTimeout.value = Math.trunc(
Number(value) * 1000