提交 8c0d1970 编写于 作者: L liuxiaohang

feat(h5): add uni.chooseFile()

上级 ea8e420c
...@@ -49,6 +49,7 @@ const location = [ ...@@ -49,6 +49,7 @@ const location = [
const media = [ const media = [
'chooseImage', 'chooseImage',
'chooseFile',
'previewImage', 'previewImage',
'getImageInfo', 'getImageInfo',
'saveImageToPhotosAlbum', 'saveImageToPhotosAlbum',
...@@ -170,7 +171,7 @@ const ui = [ ...@@ -170,7 +171,7 @@ const ui = [
'showRightWindow', 'showRightWindow',
'hideTopWindow', 'hideTopWindow',
'hideLeftWindow', 'hideLeftWindow',
'hideRightWindow', 'hideRightWindow'
] ]
const event = [ const event = [
......
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
"title": "媒体", "title": "媒体",
"apiList": { "apiList": {
"uni.chooseImage": true, "uni.chooseImage": true,
"uni.chooseFile": true,
"uni.previewImage": true, "uni.previewImage": true,
"uni.getImageInfo": true, "uni.getImageInfo": true,
"uni.saveImageToPhotosAlbum": true, "uni.saveImageToPhotosAlbum": true,
...@@ -216,7 +217,7 @@ ...@@ -216,7 +217,7 @@
"name": "ad", "name": "ad",
"title": "广告", "title": "广告",
"apiList": { "apiList": {
"uni.createRewardedVideoAd": true, "uni.createRewardedVideoAd": true,
"uni.createFullScreenVideoAd": true "uni.createFullScreenVideoAd": true
} }
}] }]
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: ['*']
}
}
...@@ -30,5 +30,9 @@ export const chooseImage = { ...@@ -30,5 +30,9 @@ export const chooseImage = {
sourceType = sourceType.filter(sourceType => SOURCE_TYPES.includes(sourceType)) sourceType = sourceType.filter(sourceType => SOURCE_TYPES.includes(sourceType))
params.sourceType = sourceType.length ? sourceType : SOURCE_TYPES params.sourceType = sourceType.length ? sourceType : SOURCE_TYPES
} }
},
extension: {
type: Array,
default: ['*']
} }
} }
...@@ -17,5 +17,9 @@ export const chooseVideo = { ...@@ -17,5 +17,9 @@ export const chooseVideo = {
camera: { camera: {
type: String, type: String,
default: 'back' default: 'back'
},
extension: {
type: Array,
default: ['*']
} }
} }
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()
}
import { fileToUrl } from 'uni-platform/helpers/file' import { fileToUrl } from 'uni-platform/helpers/file'
import { updateElementStyle } from 'uni-shared' import _createInput from './create_input'
const { const {
invokeCallbackHandler: invoke invokeCallbackHandler: invoke
...@@ -7,34 +7,11 @@ const { ...@@ -7,34 +7,11 @@ const {
let imageInput = null 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 ({ export function chooseImage ({
count, count,
// sizeType, // sizeType,
sourceType sourceType,
extension
}, callbackId) { }, callbackId) {
// TODO handle sizeType 尝试通过 canvas 压缩 // TODO handle sizeType 尝试通过 canvas 压缩
...@@ -44,8 +21,10 @@ export function chooseImage ({ ...@@ -44,8 +21,10 @@ export function chooseImage ({
} }
imageInput = _createInput({ imageInput = _createInput({
count: count, count,
sourceType: sourceType sourceType,
extension,
type: 'image'
}) })
document.body.appendChild(imageInput) document.body.appendChild(imageInput)
...@@ -61,7 +40,7 @@ export function chooseImage ({ ...@@ -61,7 +40,7 @@ export function chooseImage ({
return filePath return filePath
} }
}) })
tempFiles.push(file) if (i < count) tempFiles.push(file)
} }
const res = { const res = {
errMsg: 'chooseImage:ok', errMsg: 'chooseImage:ok',
......
import { fileToUrl, revokeObjectURL } from 'uni-platform/helpers/file' import { fileToUrl, revokeObjectURL } from 'uni-platform/helpers/file'
import { updateElementStyle } from 'uni-shared' import _createInput from './create_input'
const { const {
invokeCallbackHandler: invoke invokeCallbackHandler: invoke
...@@ -7,28 +7,9 @@ const { ...@@ -7,28 +7,9 @@ const {
let videoInput = null 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 ({ export function chooseVideo ({
sourceType sourceType,
extension
}, callbackId) { }, callbackId) {
if (videoInput) { if (videoInput) {
document.body.removeChild(videoInput) document.body.removeChild(videoInput)
...@@ -36,7 +17,9 @@ export function chooseVideo ({ ...@@ -36,7 +17,9 @@ export function chooseVideo ({
} }
videoInput = _createInput({ videoInput = _createInput({
sourceType: sourceType sourceType: sourceType,
extension,
type: 'video'
}) })
document.body.appendChild(videoInput) document.body.appendChild(videoInput)
......
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
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册