diff --git a/lib/apis.js b/lib/apis.js index 4bbf77c2e3f588b4034c68d9647e03ff96e5fcfe..7d1669424bd393f92a10ff9bf6716cbf502fc0f2 100644 --- a/lib/apis.js +++ b/lib/apis.js @@ -49,6 +49,7 @@ const location = [ const media = [ 'chooseImage', + 'chooseFile', 'previewImage', 'getImageInfo', 'saveImageToPhotosAlbum', @@ -170,7 +171,7 @@ const ui = [ 'showRightWindow', 'hideTopWindow', 'hideLeftWindow', - 'hideRightWindow', + 'hideRightWindow' ] const event = [ diff --git a/lib/modules.json b/lib/modules.json index 3ee506e9c8fec8cb34db444d707aabd005ceefa7..42c953af51968e554fa107f8dcc7277f7486976f 100644 --- a/lib/modules.json +++ b/lib/modules.json @@ -55,6 +55,7 @@ "title": "媒体", "apiList": { "uni.chooseImage": true, + "uni.chooseFile": true, "uni.previewImage": true, "uni.getImageInfo": true, "uni.saveImageToPhotosAlbum": true, @@ -216,7 +217,7 @@ "name": "ad", "title": "广告", "apiList": { - "uni.createRewardedVideoAd": true, + "uni.createRewardedVideoAd": true, "uni.createFullScreenVideoAd": true } }] diff --git a/src/core/helpers/protocol/media/choose-file.js b/src/core/helpers/protocol/media/choose-file.js new file mode 100644 index 0000000000000000000000000000000000000000..febdc92382224b7763b9111b8441f0b2cd71692b --- /dev/null +++ b/src/core/helpers/protocol/media/choose-file.js @@ -0,0 +1,37 @@ +const MEDIA_TYPE = ['all', 'image', 'video'] +const SOURCE_TYPES = ['album', 'camera'] + +export const chooseFile = { + count: { + type: Number, + required: false, + default: 100, + validator (count, params) { + if (count <= 0) { + params.count = 100 + } + } + }, + sourceType: { + type: Array, + required: false, + default: SOURCE_TYPES, + validator (sourceType, params) { + sourceType = sourceType.filter(sourceType => SOURCE_TYPES.includes(sourceType)) + params.sourceType = sourceType.length ? sourceType : SOURCE_TYPES + } + }, + type: { + type: String, + required: false, + default: 'all', + validator (type, params) { + if (!MEDIA_TYPE.includes(type)) params.type = MEDIA_TYPE[0] + params.type = params.type === 'all' ? params.type = '*' : params.type + } + }, + extension: { + type: Array, + default: ['*'] + } +} diff --git a/src/core/helpers/protocol/media/choose-image.js b/src/core/helpers/protocol/media/choose-image.js index d73829c6f09aff51c07fdd0bfdaee7b7357f98ee..3cbb6dc26d7521e5c29a08c8a535afc1e94eaeaa 100644 --- a/src/core/helpers/protocol/media/choose-image.js +++ b/src/core/helpers/protocol/media/choose-image.js @@ -30,5 +30,9 @@ export const chooseImage = { sourceType = sourceType.filter(sourceType => SOURCE_TYPES.includes(sourceType)) params.sourceType = sourceType.length ? sourceType : SOURCE_TYPES } + }, + extension: { + type: Array, + default: ['*'] } } diff --git a/src/core/helpers/protocol/media/choose-video.js b/src/core/helpers/protocol/media/choose-video.js index 4efbf0d9a99f60ba608956caea23646cb74ee3e1..0d5a5caa0d9eb840244bb3bee948fb9505f3a3d0 100644 --- a/src/core/helpers/protocol/media/choose-video.js +++ b/src/core/helpers/protocol/media/choose-video.js @@ -17,5 +17,9 @@ export const chooseVideo = { camera: { type: String, default: 'back' + }, + extension: { + type: Array, + default: ['*'] } } diff --git a/src/platforms/h5/service/api/media/choose-file.js b/src/platforms/h5/service/api/media/choose-file.js new file mode 100644 index 0000000000000000000000000000000000000000..949b8de8cb0f6aa22661843723930908b446143b --- /dev/null +++ b/src/platforms/h5/service/api/media/choose-file.js @@ -0,0 +1,59 @@ +import { fileToUrl } from 'uni-platform/helpers/file' +import _createInput from './create_input' + +const { + invokeCallbackHandler: invoke +} = UniServiceJSBridge + +let fileInput = null + +export function chooseFile ({ + // sizeType, + count, + sourceType, + type, + extension +}, callbackId) { + // TODO handle sizeType 尝试通过 canvas 压缩 + + if (fileInput) { + document.body.removeChild(fileInput) + fileInput = null + } + + fileInput = _createInput({ + count, + sourceType, + type, + extension + }) + document.body.appendChild(fileInput) + + fileInput.addEventListener('change', function (event) { + const tempFiles = [] + const fileCount = event.target.files.length + for (let i = 0; i < fileCount; i++) { + const file = event.target.files[i] + let filePath + Object.defineProperty(file, 'path', { + get () { + filePath = filePath || fileToUrl(file) + return filePath + } + }) + if (i < count) tempFiles.push(file) + } + const res = { + errMsg: 'chooseFile:ok', + get tempFilePaths () { + return tempFiles.map(({ path }) => path) + }, + tempFiles: tempFiles + } + invoke(callbackId, res) + + // TODO 用户取消选择时,触发 fail,目前尚未找到合适的方法。 + }) + + fileInput.click() +} diff --git a/src/platforms/h5/service/api/media/choose-image.js b/src/platforms/h5/service/api/media/choose-image.js index 817b0d4da5125524dbe26802c323745524364556..ab7e69bb6f9466760b29bd9712d3c101729c8cf8 100644 --- a/src/platforms/h5/service/api/media/choose-image.js +++ b/src/platforms/h5/service/api/media/choose-image.js @@ -1,5 +1,5 @@ import { fileToUrl } from 'uni-platform/helpers/file' -import { updateElementStyle } from 'uni-shared' +import _createInput from './create_input' const { invokeCallbackHandler: invoke @@ -7,34 +7,11 @@ const { let imageInput = null -const _createInput = function (options) { - const inputEl = document.createElement('input') - inputEl.type = 'file' - updateElementStyle(inputEl, { - position: 'absolute', - visibility: 'hidden', - 'z-index': -999, - width: 0, - height: 0, - top: 0, - left: 0 - }) - inputEl.accept = 'image/*' - if (options.count > 1) { - inputEl.multiple = 'multiple' - } - // 经过测试,仅能限制只通过相机拍摄,不能限制只允许从相册选择。 - if (options.sourceType.length === 1 && options.sourceType[0] === 'camera') { - inputEl.capture = 'camera' - } - - return inputEl -} - export function chooseImage ({ count, // sizeType, - sourceType + sourceType, + extension }, callbackId) { // TODO handle sizeType 尝试通过 canvas 压缩 @@ -44,8 +21,10 @@ export function chooseImage ({ } imageInput = _createInput({ - count: count, - sourceType: sourceType + count, + sourceType, + extension, + type: 'image' }) document.body.appendChild(imageInput) @@ -61,7 +40,7 @@ export function chooseImage ({ return filePath } }) - tempFiles.push(file) + if (i < count) tempFiles.push(file) } const res = { errMsg: 'chooseImage:ok', diff --git a/src/platforms/h5/service/api/media/choose-video.js b/src/platforms/h5/service/api/media/choose-video.js index 30939f575526663c2a6e79f27a79bbc9a4a0071e..5b9c704149d8e3d30417dc549dfd87c607193e8d 100644 --- a/src/platforms/h5/service/api/media/choose-video.js +++ b/src/platforms/h5/service/api/media/choose-video.js @@ -1,5 +1,5 @@ import { fileToUrl, revokeObjectURL } from 'uni-platform/helpers/file' -import { updateElementStyle } from 'uni-shared' +import _createInput from './create_input' const { invokeCallbackHandler: invoke @@ -7,28 +7,9 @@ const { let videoInput = null -const _createInput = function (options) { - const inputEl = document.createElement('input') - inputEl.type = 'file' - updateElementStyle(inputEl, { - position: 'absolute', - visibility: 'hidden', - 'z-index': -999, - width: 0, - height: 0, - top: 0, - left: 0 - }) - inputEl.accept = 'video/*' - // 经过测试,仅能限制只通过相机拍摄,不能限制只允许从相册选择。 - if (options.sourceType.length === 1 && options.sourceType[0] === 'camera') { - inputEl.capture = 'camera' - } - return inputEl -} - export function chooseVideo ({ - sourceType + sourceType, + extension }, callbackId) { if (videoInput) { document.body.removeChild(videoInput) @@ -36,7 +17,9 @@ export function chooseVideo ({ } videoInput = _createInput({ - sourceType: sourceType + sourceType: sourceType, + extension, + type: 'video' }) document.body.appendChild(videoInput) diff --git a/src/platforms/h5/service/api/media/create_input.js b/src/platforms/h5/service/api/media/create_input.js new file mode 100644 index 0000000000000000000000000000000000000000..d0a73eae15843e60c32c992c3eb76b5a1187f3e9 --- /dev/null +++ b/src/platforms/h5/service/api/media/create_input.js @@ -0,0 +1,37 @@ +import { updateElementStyle } from 'uni-shared' + +export default function ({ count, sourceType, type, extension }) { + const inputEl = document.createElement('input') + inputEl.type = 'file' + + updateElementStyle(inputEl, { + position: 'absolute', + visibility: 'hidden', + 'z-index': -999, + width: 0, + height: 0, + top: 0, + left: 0 + }) + + inputEl.accept = extension.map(item => { + if (type !== '*') { + // 剔除.拼接在type后 + return `${type}/${item.replace('.', '')}` + } else { + // 在后缀前方加上. + return item.indexOf('.') === 0 ? item : `.${item}` + } + }).join(',') + + if (count > 1) { + inputEl.multiple = 'multiple' + } + + // 经过测试,仅能限制只通过相机拍摄,不能限制只允许从相册选择。 + if (sourceType.length === 1 && sourceType[0] === 'camera') { + inputEl.capture = 'camera' + } + + return inputEl +}