choose-image.js 4.4 KB
Newer Older
fxy060608's avatar
fxy060608 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
import {
  TEMP_PATH
} from '../constants'

import {
  invoke
} from '../../bridge'

/**
 * 获取文件信息
 * @param {string} filePath 文件路径
 * @returns {Promise} 文件信息Promise
 */
function getFileInfo (filePath) {
  return new Promise((resolve, reject) => {
    plus.io.resolveLocalFileSystemURL(filePath, function (entry) {
      entry.getMetadata(function (meta) {
        resolve({
          size: meta.size
        })
      }, reject, false)
    }, reject)
  })
}

const invokeChooseImage = function (callbackId, type, sizeType, tempFilePaths = []) {
  if (!tempFilePaths.length) {
    invoke(callbackId, {
      code: sizeType,
      errMsg: `chooseImage:${type}`
    })
    return
  }
  var tempFiles = []
  // plus.zip.compressImage 压缩文件并发调用在iOS端容易出现问题(图像错误、闪退),改为队列执行
  tempFilePaths.reduce((promise, tempFilePath, index, array) => {
    return promise
      .then(() => {
        return getFileInfo(tempFilePath)
      })
      .then(fileInfo => {
        var size = fileInfo.size
        // 压缩阈值 0.5 兆
        var threshold = 1024 * 1024 * 0.5
        // 判断是否需要压缩
        if ((sizeType.indexOf('compressed') >= 0 && sizeType.indexOf('original') < 0) || (((
          sizeType.indexOf(
            'compressed') < 0 && sizeType.indexOf('original') < 0) || (sizeType
          .indexOf('compressed') >= 0 && sizeType.indexOf(
          'original') >= 0)) && size > threshold)) {
          return new Promise((resolve, reject) => {
            var dstPath = TEMP_PATH + '/compressed/' + Date.now() + (
              tempFilePath.match(/\.\S+$/) || [''])[0]
            plus.nativeUI.showWaiting()
            plus.zip.compressImage({
              src: tempFilePath,
              dst: dstPath,
              overwrite: true
            }, () => {
              resolve(dstPath)
            }, (error) => {
              reject(error)
            })
          })
            .then(dstPath => {
              array[index] = tempFilePath = dstPath
              return getFileInfo(tempFilePath)
            })
            .then(fileInfo => {
              return tempFiles.push({
                path: tempFilePath,
                size: fileInfo.size
              })
            })
        }
        return tempFiles.push({
          path: tempFilePath,
          size: size
        })
      })
  }, Promise.resolve())
    .then(() => {
      plus.nativeUI.closeWaiting()
      invoke(callbackId, {
        errMsg: `chooseImage:${type}`,
        tempFilePaths,
        tempFiles
      })
    }).catch(() => {
      plus.nativeUI.closeWaiting()
      invoke(callbackId, {
        errMsg: `chooseImage:${type}`
      })
    })
}
const openCamera = function (callbackId, sizeType) {
  const camera = plus.camera.getCamera()
  camera.captureImage(e => invokeChooseImage(callbackId, 'ok', sizeType, [e]),
    e => invokeChooseImage(callbackId, 'fail', 1), {
100 101
      filename: TEMP_PATH + '/camera/',
      resolution: 'high'
fxy060608's avatar
fxy060608 已提交
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
    })
}
const openAlbum = function (callbackId, sizeType, count) {
  // TODO Android 需要拷贝到 temp 目录
  plus.gallery.pick(e => invokeChooseImage(callbackId, 'ok', sizeType, e.files.map(file => {
    return file
  })), e => {
    invokeChooseImage(callbackId, 'fail', 2)
  }, {
    maximum: count,
    multiple: true,
    system: false,
    filename: TEMP_PATH + '/gallery/'
  })
}

export function chooseImage ({
  count = 9,
  sizeType = ['original', 'compressed'],
  sourceType = ['album', 'camera']
} = {}, callbackId) {
  let fallback = true
  if (sourceType.length === 1) {
    if (sourceType[0] === 'album') {
      fallback = false
      openAlbum(callbackId, sizeType, count)
    } else if (sourceType[0] === 'camera') {
      fallback = false
      openCamera(callbackId, sizeType)
    }
  }
  if (fallback) {
    plus.nativeUI.actionSheet({
      cancel: '取消',
      buttons: [{
        title: '拍摄'
      }, {
        title: '从手机相册选择'
      }]
    }, (e) => {
      switch (e.index) {
        case 0:
          invokeChooseImage(callbackId, 'fail', 0)
          break
        case 1:
          openCamera(callbackId, sizeType)
          break
        case 2:
          openAlbum(callbackId, sizeType, count)
          break
      }
    })
  }
}