fix(overlay): 修复手机端图片/视频本地选择兼容性问题
- 将 local-files 事件类型由 FileList 改为 File[],避免 WebView 中 FileList 在 input 清空后失效 - 屏蔽文件选择器关闭后 500ms 内的 backdrop click,防止 touch 穿透误关 overlay - 延迟 200ms 清空 input value,避免国产手机 WebView 异步填充 files 被截断
This commit is contained in:
parent
7c08031413
commit
d639278182
@ -79,12 +79,14 @@ const props = withDefaults(
|
||||
const emit = defineEmits<{
|
||||
(e: 'close'): void;
|
||||
(e: 'confirm', list: string[]): void;
|
||||
(e: 'local-files', files: FileList | null): void;
|
||||
(e: 'local-files', files: File[] | null): void;
|
||||
}>();
|
||||
|
||||
const selectedSet = ref<Set<string>>(new Set(props.initialSelected || []));
|
||||
const localInput = ref<HTMLInputElement | null>(null);
|
||||
|
||||
let ignoreBackdropClickUntil = 0;
|
||||
|
||||
watch(
|
||||
() => props.initialSelected,
|
||||
(val) => {
|
||||
@ -106,25 +108,35 @@ const toggle = (path: string) => {
|
||||
selectedSet.value = set;
|
||||
};
|
||||
|
||||
const close = () => emit('close');
|
||||
const close = () => {
|
||||
if (Date.now() < ignoreBackdropClickUntil) return;
|
||||
emit('close');
|
||||
};
|
||||
|
||||
const confirm = () => emit('confirm', Array.from(selectedSet.value));
|
||||
|
||||
const triggerLocal = () => {
|
||||
if (props.uploading) return;
|
||||
// 屏蔽接下来 500ms 内的 backdrop click,防止系统文件选择器关闭后的 touch 穿透误关 overlay
|
||||
ignoreBackdropClickUntil = Date.now() + 500;
|
||||
localInput.value?.click();
|
||||
};
|
||||
|
||||
const onLocalChange = (event: Event) => {
|
||||
const target = event.target as HTMLInputElement;
|
||||
const files = target?.files || null;
|
||||
const rawFiles = target?.files;
|
||||
// 某些 WebView(尤其国产手机)在 input value 被清空后 FileList 会失效,先深拷贝
|
||||
const files = rawFiles && rawFiles.length ? Array.from(rawFiles) : null;
|
||||
if (!files || files.length === 0) {
|
||||
console.warn('[ImagePicker] change fired but files empty — likely WebView compat issue');
|
||||
emit('local-files', null);
|
||||
} else {
|
||||
emit('local-files', files);
|
||||
}
|
||||
emit('local-files', files);
|
||||
if (target) {
|
||||
target.value = '';
|
||||
}
|
||||
// 延迟清空:国产手机 WebView 中 files 填充可能是异步的,立即清空会导致 files 被截断
|
||||
setTimeout(() => {
|
||||
if (target) target.value = '';
|
||||
}, 200);
|
||||
};
|
||||
|
||||
const previewUrl = (path: string) => `/api/gui/files/download?path=${encodeURIComponent(path)}`;
|
||||
|
||||
@ -81,12 +81,14 @@ const props = withDefaults(
|
||||
const emit = defineEmits<{
|
||||
(e: 'close'): void;
|
||||
(e: 'confirm', list: string[]): void;
|
||||
(e: 'local-files', files: FileList | null): void;
|
||||
(e: 'local-files', files: File[] | null): void;
|
||||
}>();
|
||||
|
||||
const selectedSet = ref<Set<string>>(new Set(props.initialSelected || []));
|
||||
const localInput = ref<HTMLInputElement | null>(null);
|
||||
|
||||
let ignoreBackdropClickUntil = 0;
|
||||
|
||||
watch(
|
||||
() => props.initialSelected,
|
||||
(val) => {
|
||||
@ -108,18 +110,25 @@ const toggle = (path: string) => {
|
||||
selectedSet.value = set;
|
||||
};
|
||||
|
||||
const close = () => emit('close');
|
||||
const close = () => {
|
||||
if (Date.now() < ignoreBackdropClickUntil) return;
|
||||
emit('close');
|
||||
};
|
||||
|
||||
const confirm = () => emit('confirm', Array.from(selectedSet.value));
|
||||
|
||||
const triggerLocal = () => {
|
||||
if (props.uploading) return;
|
||||
// 屏蔽接下来 500ms 内的 backdrop click,防止系统文件选择器关闭后的 touch 穿透误关 overlay
|
||||
ignoreBackdropClickUntil = Date.now() + 500;
|
||||
localInput.value?.click();
|
||||
};
|
||||
|
||||
const onLocalChange = (event: Event) => {
|
||||
const target = event.target as HTMLInputElement;
|
||||
const files = target?.files || null;
|
||||
const rawFiles = target?.files;
|
||||
// 某些 WebView(尤其国产手机)在 input value 被清空后 FileList 会失效,先深拷贝
|
||||
const files = rawFiles && rawFiles.length ? Array.from(rawFiles) : null;
|
||||
if (!files || files.length === 0) {
|
||||
console.warn('[VideoPicker] change fired but files empty — likely WebView compat issue');
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user