提交 bb6ef672 编写于 作者: D DCloud_LXH

feat(App): chooseImage、chooseVideo

上级 da4440c4
export function getFileName(path: string) {
const array = path.split('/')
return array[array.length - 1]
}
export function getExtName(path: string) {
const array = path.split('.')
return array.length > 1 ? '.' + array[array.length - 1] : ''
}
......@@ -24,7 +24,7 @@ export function warpPlusErrorCallback(
reject: (errMsg: string, errRes?: any) => void,
errMsg?: string
) {
return function errorCallback(error: PlusError) {
return function errorCallback(error?: PlusError) {
error = error || {}
// 一键登录errorCallback新增 appid、metadata、uid 参数返回
errMsg = error.message || errMsg || ''
......
import { TEMP_PATH } from '../constants'
import { warpPlusErrorCallback } from '../../../helpers/plus'
import { getFileName } from '../../../helpers/file'
import {
API_TYPE_CHOOSE_IMAGE,
API_CHOOSE_IMAGE,
ChooseImageProtocol,
ChooseImageOptions,
defineAsyncApi,
} from '@dcloudio/uni-api'
import { initI18nChooseImageMsgsOnce, useI18n } from '@dcloudio/uni-core'
/**
* 获取文件信息
* @param {string} filePath 文件路径
* @returns {Promise} 文件信息Promise
*/
function getFileInfo(filePath: string): Promise<PlusIoMetadata> {
return new Promise((resolve, reject) => {
plus.io.resolveLocalFileSystemURL(
filePath,
function (entry) {
entry.getMetadata(resolve, reject, false)
},
reject
)
})
}
function compressImage(tempFilePath: string): Promise<string> {
const dst = `${TEMP_PATH}/compressed/${Date.now()}_${getFileName(
tempFilePath
)}`
return new Promise((resolve) => {
plus.nativeUI.showWaiting()
plus.zip.compressImage(
{
src: tempFilePath,
dst,
overwrite: true,
},
() => {
plus.nativeUI.closeWaiting()
resolve(dst)
},
() => {
plus.nativeUI.closeWaiting()
resolve(tempFilePath)
}
)
})
}
type File = {
path: string
size: number
}
export const chooseImage = defineAsyncApi<API_TYPE_CHOOSE_IMAGE>(
API_CHOOSE_IMAGE,
// @ts-ignore crop 属性App特有
({ count, sizeType, sourceType, crop } = {}, { resolve, reject }) => {
initI18nChooseImageMsgsOnce()
const { t } = useI18n()
const errorCallback = warpPlusErrorCallback(reject)
function successCallback(paths: string[]) {
const tempFiles: File[] = []
const tempFilePaths: string[] = []
// plus.zip.compressImage 压缩文件并发调用在iOS端容易出现问题(图像错误、闪退),改为队列执行
paths
.reduce((promise, path) => {
return promise
.then(() => {
return getFileInfo(path)
})
.then((fileInfo) => {
const size = fileInfo.size!
// 压缩阈值 0.5 兆
const THRESHOLD = 1024 * 1024 * 0.5
// 判断是否需要压缩
if (
!crop &&
sizeType!.includes('compressed') &&
size > THRESHOLD
) {
return compressImage(path).then((dstPath) => {
path = dstPath
return getFileInfo(path)
})
}
return fileInfo
})
.then(({ size }) => {
tempFilePaths.push(path)
tempFiles.push({
path,
size: size!,
})
})
}, Promise.resolve())
.then(() => {
resolve({
tempFilePaths,
tempFiles,
})
})
.catch(errorCallback)
}
function openCamera() {
const camera = plus.camera.getCamera()
camera.captureImage((path) => successCallback([path]), errorCallback, {
filename: TEMP_PATH + '/camera/',
resolution: 'high',
crop,
})
}
function openAlbum() {
// NOTE 5+此API分单选和多选,多选返回files:string[]
// @ts-ignore
plus.gallery.pick(({ files }) => successCallback(files), errorCallback, {
maximum: count,
multiple: true,
system: false,
filename: TEMP_PATH + '/gallery/',
permissionAlert: true,
crop,
})
}
if (sourceType!.length === 1) {
if (sourceType!.includes('album')) {
openAlbum()
return
} else if (sourceType!.includes('camera')) {
openCamera()
return
}
}
plus.nativeUI.actionSheet(
{
cancel: t('uni.chooseImage.cancel'),
buttons: [
{
title: t('uni.chooseImage.sourceType.camera'),
},
{
title: t('uni.chooseImage.sourceType.album'),
},
],
},
(e) => {
switch (e.index) {
case 1:
openCamera()
break
case 2:
openAlbum()
break
default:
errorCallback()
break
}
}
)
},
ChooseImageProtocol,
ChooseImageOptions
)
import { TEMP_PATH } from '../constants'
import { warpPlusErrorCallback } from '../../../helpers/plus'
import { getFileName } from '../../../helpers/file'
import { initI18nChooseVideoMsgsOnce, useI18n } from '@dcloudio/uni-core'
import {
API_TYPE_CHOOSE_VIDEO,
API_CHOOSE_VIDEO,
ChooseVideoOptions,
ChooseVideoProtocol,
defineAsyncApi,
} from '@dcloudio/uni-api'
export const chooseVideo = defineAsyncApi<API_TYPE_CHOOSE_VIDEO>(
API_CHOOSE_VIDEO,
({ sourceType, compressed, maxDuration, camera }, { resolve, reject }) => {
initI18nChooseVideoMsgsOnce()
const { t } = useI18n()
const errorCallback = warpPlusErrorCallback(reject)
function successCallback(tempFilePath: string = '') {
const filename = `${TEMP_PATH}/compressed/${Date.now()}_${getFileName(
tempFilePath
)}`
const compressVideo: Promise<string> = compressed
? new Promise((resolve) => {
plus.zip.compressVideo(
{
src: tempFilePath,
filename,
},
({ tempFilePath }: { tempFilePath: string }) => {
resolve(tempFilePath)
},
() => {
resolve(tempFilePath)
}
)
})
: Promise.resolve(tempFilePath)
if (compressed) {
plus.nativeUI.showWaiting()
}
compressVideo.then((tempFilePath: string) => {
if (compressed) {
plus.nativeUI.closeWaiting()
}
plus.io.getVideoInfo({
filePath: tempFilePath,
success(videoInfo) {
const result = {
errMsg: 'chooseVideo:ok',
tempFilePath: tempFilePath,
size: videoInfo.size,
duration: videoInfo.duration,
width: videoInfo.width,
height: videoInfo.height,
}
resolve(result as any)
},
fail: errorCallback,
})
})
}
function openAlbum() {
plus.gallery.pick(
// NOTE 5+此API分单选和多选,多选返回files:string[]
// @ts-ignore
({ files }) => successCallback(files[0]),
errorCallback,
{
filter: 'video',
system: false,
// 不启用 multiple 时 system 无效
multiple: true,
maximum: 1,
filename: TEMP_PATH + '/gallery/',
permissionAlert: true,
}
)
}
function openCamera() {
const plusCamera = plus.camera.getCamera()
plusCamera.startVideoCapture(successCallback, errorCallback, {
index: camera === 'front' ? '2' : '1',
videoMaximumDuration: maxDuration,
filename: TEMP_PATH + '/camera/',
})
}
if (sourceType!.length === 1) {
if (sourceType!.includes('album')) {
openAlbum()
return
} else if (sourceType!.includes('camera')) {
openCamera()
return
}
}
plus.nativeUI.actionSheet(
{
cancel: t('uni.chooseVideo.cancel'),
buttons: [
{
title: t('uni.chooseVideo.sourceType.camera'),
},
{
title: t('uni.chooseVideo.sourceType.album'),
},
],
},
(e) => {
switch (e.index) {
case 1:
openCamera()
break
case 2:
openAlbum()
break
default:
errorCallback()
break
}
}
)
},
ChooseVideoProtocol,
ChooseVideoOptions
)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册