提交 66e6b3c9 编写于 作者: D DCloud_LXH

feat(H5): judge user activation when choose file

上级 4f6e2b57
......@@ -10,7 +10,11 @@ const passiveOptions = passive(true)
const states: UserActionState[] = []
let userInteract: number = 0
let inited: boolean
function addInteractListener(vm: UserActionState) {
const setUserAction = (userAction: boolean) =>
states.forEach((vm) => (vm.userAction = userAction))
export function addInteractListener(
vm: UserActionState = { userAction: false }
) {
if (!inited) {
const eventNames = [
'touchstart',
......@@ -23,16 +27,12 @@ function addInteractListener(vm: UserActionState) {
document.addEventListener(
eventName,
function () {
states.forEach((vm) => {
vm.userAction = true
userInteract++
setTimeout(() => {
userInteract--
if (!userInteract) {
vm.userAction = false
}
}, 0)
})
!userInteract && setUserAction(true)
userInteract++
setTimeout(() => {
!--userInteract && setUserAction(false)
}, 0)
},
passiveOptions
)
......@@ -47,6 +47,7 @@ function removeInteractListener(vm: UserActionState) {
states.splice(index, 1)
}
}
export const getInteractStatus = () => !!userInteract
export function useUserAction() {
const state: UserActionState = reactive({
......
......@@ -13,7 +13,11 @@ export type {
} from './helpers/useEvent'
export * from './helpers/scroller'
export { parseText } from './helpers/text'
export { useUserAction } from './helpers/useUserAction'
export {
useUserAction,
addInteractListener,
getInteractStatus,
} from './helpers/useUserAction'
export { useAttrs } from './helpers/useAttrs'
export { useBooleanAttr } from './helpers/useBooleanAttr'
export { useTouchtrack } from './helpers/useTouchtrack'
......
......@@ -12,6 +12,7 @@
"uni.chooseVideo.cancel": "Cancel",
"uni.chooseVideo.sourceType.album": "Album",
"uni.chooseVideo.sourceType.camera": "Camera",
"uni.chooseFile.notUserActivation": "File chooser dialog can only be shown with a user activation",
"uni.previewImage.cancel": "Cancel",
"uni.previewImage.button.save": "Save Image",
"uni.previewImage.save.success": "Saved successfully",
......
......@@ -12,6 +12,7 @@
"uni.chooseVideo.cancel": "Cancelar",
"uni.chooseVideo.sourceType.album": "Álbum",
"uni.chooseVideo.sourceType.camera": "Cámara",
"uni.chooseFile.notUserActivation": "El cuadro de diálogo del selector de archivos solo se puede mostrar con la activación del usuario",
"uni.previewImage.cancel": "Cancelar",
"uni.previewImage.button.save": "Guardar imagen",
"uni.previewImage.save.success": "Guardado exitosamente",
......
......@@ -12,6 +12,7 @@
"uni.chooseVideo.cancel": "Annuler",
"uni.chooseVideo.sourceType.album": "Album",
"uni.chooseVideo.sourceType.camera": "Caméra",
"uni.chooseFile.notUserActivation": "La boîte de dialogue du sélecteur de fichier ne peut être affichée qu'avec une activation par l'utilisateur",
"uni.previewImage.cancel": "Annuler",
"uni.previewImage.button.save": "Guardar imagen",
"uni.previewImage.save.success": "Enregistré avec succès",
......
......@@ -344,6 +344,51 @@ export const initI18nChooseVideoMsgsOnce = /*#__PURE__*/ once(() => {
)
}
})
export const initI18nChooseFileMsgsOnce = /*#__PURE__*/ once(() => {
const name = 'uni.chooseFile.'
const keys = ['notUserActivation']
if (__UNI_FEATURE_I18N_EN__) {
useI18n().add(
LOCALE_EN,
normalizeMessages(name, keys, [
'File chooser dialog can only be shown with a user activation',
]),
false
)
}
if (__UNI_FEATURE_I18N_ES__) {
useI18n().add(
LOCALE_ES,
normalizeMessages(name, keys, [
'El cuadro de diálogo del selector de archivos solo se puede mostrar con la activación del usuario',
]),
false
)
}
if (__UNI_FEATURE_I18N_FR__) {
useI18n().add(
LOCALE_FR,
normalizeMessages(name, keys, [
"La boîte de dialogue du sélecteur de fichier ne peut être affichée qu'avec une activation par l'utilisateur",
]),
false
)
}
if (__UNI_FEATURE_I18N_ZH_HANS__) {
useI18n().add(
LOCALE_ZH_HANS,
normalizeMessages(name, keys, ['文件选择器对话框只能在用户激活时显示']),
false
)
}
if (__UNI_FEATURE_I18N_ZH_HANT__) {
useI18n().add(
LOCALE_ZH_HANT,
normalizeMessages(name, keys, ['文件選擇器對話框只能在用戶激活時顯示']),
false
)
}
})
export const initI18nPreviewImageMsgsOnce = /*#__PURE__*/ once(() => {
const name = 'uni.previewImage.'
const keys = ['cancel', 'button.save', 'save.success', 'save.fail']
......
......@@ -12,6 +12,7 @@
"uni.chooseVideo.cancel": "取消",
"uni.chooseVideo.sourceType.album": "从相册选择",
"uni.chooseVideo.sourceType.camera": "拍摄",
"uni.chooseFile.notUserActivation": "文件选择器对话框只能在用户激活时显示",
"uni.previewImage.cancel": "取消",
"uni.previewImage.button.save": "保存图像",
"uni.previewImage.save.success": "保存图像到相册成功",
......
......@@ -12,6 +12,7 @@
"uni.chooseVideo.cancel": "取消",
"uni.chooseVideo.sourceType.album": "從相冊選擇",
"uni.chooseVideo.sourceType.camera": "拍攝",
"uni.chooseFile.notUserActivation": "文件選擇器對話框只能在用戶激活時顯示",
"uni.previewImage.cancel": "取消",
"uni.previewImage.button.save": "保存圖像",
"uni.previewImage.save.success": "保存圖像到相冊成功",
......
......@@ -7,6 +7,8 @@ import {
} from '@dcloudio/uni-api'
import { fileToUrl } from '../../../helpers/file'
import _createInput from './createInput'
import { getInteractStatus } from '@dcloudio/uni-components'
import { useI18n, initI18nChooseFileMsgsOnce } from '@dcloudio/uni-core'
//#endregion
//#region types
......@@ -29,6 +31,8 @@ export const chooseFile = defineAsyncApi<API_TYPE_CHOOSE_FILE>(
},
{ resolve, reject }
) => {
initI18nChooseFileMsgsOnce()
const { t } = useI18n()
// TODO handle sizeType 尝试通过 canvas 压缩
if (fileInput) {
document.body.removeChild(fileInput)
......@@ -75,7 +79,11 @@ export const chooseFile = defineAsyncApi<API_TYPE_CHOOSE_FILE>(
// TODO 用户取消选择时,触发 fail,目前尚未找到合适的方法。
})
fileInput.click()
if (getInteractStatus()) {
fileInput.click()
} else {
reject(t('uni.chooseFile.notUserActivation'))
}
},
ChooseFileProtocol,
ChooseFileOptions
......
......@@ -7,6 +7,8 @@ import {
} from '@dcloudio/uni-api'
import { fileToUrl } from '../../../helpers/file'
import _createInput from './createInput'
import { getInteractStatus } from '@dcloudio/uni-components'
import { useI18n, initI18nChooseFileMsgsOnce } from '@dcloudio/uni-core'
//#endregion
//#region types
......@@ -29,6 +31,8 @@ export const chooseImage = defineAsyncApi<API_TYPE_CHOOSE_IMAGE>(
{ resolve, reject }
) => {
// TODO handle sizeType 尝试通过 canvas 压缩
initI18nChooseFileMsgsOnce()
const { t } = useI18n()
if (imageInput) {
document.body.removeChild(imageInput)
......@@ -75,7 +79,11 @@ export const chooseImage = defineAsyncApi<API_TYPE_CHOOSE_IMAGE>(
// TODO 用户取消选择时,触发 fail,目前尚未找到合适的方法。
})
imageInput.click()
if (getInteractStatus()) {
imageInput.click()
} else {
reject(t('uni.chooseFile.notUserActivation'))
}
},
ChooseImageProtocol,
ChooseImageOptions
......
......@@ -8,6 +8,8 @@ import {
} from '@dcloudio/uni-api'
import { fileToUrl, revokeObjectURL } from '../../../helpers/file'
import _createInput from './createInput'
import { getInteractStatus } from '@dcloudio/uni-components'
import { useI18n, initI18nChooseFileMsgsOnce } from '@dcloudio/uni-core'
//#endregion
//#region types
......@@ -20,6 +22,8 @@ let videoInput: HTMLInputElement = null as any
export const chooseVideo = defineAsyncApi<API_TYPE_CHOOSE_VIDEO>(
API_CHOOSE_VIDEO,
({ sourceType, extension }, { resolve, reject }) => {
initI18nChooseFileMsgsOnce()
const { t } = useI18n()
if (videoInput) {
document.body.removeChild(videoInput)
videoInput = null as any
......@@ -80,7 +84,11 @@ export const chooseVideo = defineAsyncApi<API_TYPE_CHOOSE_VIDEO>(
// TODO 用户取消选择时,触发 fail,目前尚未找到合适的方法。
})
videoInput.click()
if (getInteractStatus()) {
videoInput.click()
} else {
reject(t('uni.chooseFile.notUserActivation'))
}
},
ChooseVideoProtocol,
ChooseVideoOptions
......
import { updateElementStyle } from '@dcloudio/uni-shared'
import MIMEType from './MIMEType'
import { addInteractListener } from '@dcloudio/uni-components'
export type createInputOptions = Pick<
UniApp.ChooseFileOptions,
......@@ -7,6 +8,7 @@ export type createInputOptions = Pick<
>
const ALL = 'all'
addInteractListener()
function isWXEnv(): boolean {
const ua = window.navigator.userAgent.toLowerCase()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册