useNativeAPI.js 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. import { miniprogramThis } from '../internals/global'
  2. const fakeMediaResult = (request, response) => {
  3. if ('type' in response) {
  4. return response
  5. }
  6. if (request.mediaType.includes('video')) {
  7. return {
  8. tempFiles: [{
  9. tempFilePath: response.tempFilePath,
  10. size: response.size,
  11. duration: response.duration,
  12. height: response.height,
  13. width: response.width,
  14. thumbTempFilePath: response.tempFilePath,
  15. fileType: 'video',
  16. }],
  17. type: 'video',
  18. }
  19. }
  20. const { tempFilePaths = [], tempFiles = [] } = response
  21. return {
  22. tempFiles: tempFilePaths.map((tempFilePath, index) => ({
  23. tempFilePath: tempFiles[index].path || tempFilePath,
  24. size: tempFiles[index].size,
  25. fileType: 'image',
  26. })),
  27. type: 'image',
  28. }
  29. }
  30. /**
  31. * ## 拍摄或从手机相册中选择图片或视频。
  32. *
  33. * @see https://developers.weixin.qq.com/miniprogram/dev/api/media/video/wx.chooseMedia.html
  34. * @export
  35. * @param {*} options
  36. * @return {*}
  37. */
  38. export function chooseMedia(options) {
  39. const {
  40. count = 9,
  41. mediaType = ['image', 'video'],
  42. sourceType = ['album', 'camera'],
  43. maxDuration = 10,
  44. sizeType = ['original', 'compressed'],
  45. camera = 'back',
  46. // @deprecated
  47. compressed = true,
  48. ...resetCbs
  49. } = options
  50. const success = (res) => {
  51. if (resetCbs.success) {
  52. resetCbs.success(fakeMediaResult(options, res))
  53. }
  54. }
  55. if (typeof miniprogramThis.chooseMedia === 'function') {
  56. return miniprogramThis.chooseMedia({ ...options, success })
  57. }
  58. if (mediaType.includes('video')) {
  59. const videoOptions = {
  60. sourceType,
  61. compressed,
  62. maxDuration: options.maxDuration === undefined ? 60 : maxDuration,
  63. camera,
  64. ...resetCbs,
  65. success,
  66. }
  67. return miniprogramThis.chooseVideo(videoOptions)
  68. }
  69. const imageOptions = {
  70. count,
  71. sizeType,
  72. sourceType,
  73. ...resetCbs,
  74. success,
  75. }
  76. return miniprogramThis.chooseImage(imageOptions)
  77. }
  78. export function uploadFile(options) {
  79. const {
  80. url,
  81. filePath,
  82. name = 'file',
  83. header = {},
  84. formData = {},
  85. timeout = 20,
  86. enableProfile = true,
  87. enableHttp2 = false,
  88. ...resetCbs
  89. } = options
  90. return miniprogramThis.uploadFile({
  91. url,
  92. filePath,
  93. name,
  94. header,
  95. formData,
  96. timeout,
  97. enableProfile,
  98. enableHttp2,
  99. ...resetCbs,
  100. })
  101. }
  102. export function getSystemInfoSync(keys = ['window', 'device', 'appBase']) {
  103. return typeof miniprogramThis.getWindowInfo === 'function'
  104. ? keys.reduce((acc, key) => ({
  105. ...acc,
  106. ...miniprogramThis[`get${key.charAt(0).toUpperCase() + key.substring(1)}Info`](),
  107. }), {})
  108. : miniprogramThis.getSystemInfoSync()
  109. }
  110. export function vibrateShort(options) {
  111. if (getSystemInfoSync(['window', 'device']).platform === 'devtools') {
  112. return
  113. }
  114. return miniprogramThis.vibrateShort(options)
  115. }
  116. export function getMenuButtonBoundingClientRectSync() {
  117. let menuRect
  118. try {
  119. menuRect = miniprogramThis.getMenuButtonBoundingClientRect ? miniprogramThis.getMenuButtonBoundingClientRect() : null
  120. if (menuRect === null) {
  121. throw 'getMenuButtonBoundingClientRect error'
  122. }
  123. // 取值为 0 的情况 有可能 width 不为 0, top 为 0 的情况
  124. if (!menuRect.width || !menuRect.top || !menuRect.left || !menuRect.height) {
  125. throw 'getMenuButtonBoundingClientRect error'
  126. }
  127. } catch (e) {
  128. const windowInfo = getSystemInfoSync(['window', 'device'])
  129. const isIOS = !!(windowInfo.system.toLowerCase().search('ios') + 1)
  130. const height = 32 // 胶囊的高度
  131. let width = 88 // 胶囊的宽度
  132. let gap = 4 // 胶囊按钮上下间距 使导航内容居中
  133. if (windowInfo.platform === 'android') {
  134. gap = 8
  135. width = 96
  136. } else if (windowInfo.platform === 'devtools') {
  137. if (isIOS) {
  138. gap = 5.5 // 开发工具中 ios 手机
  139. } else {
  140. gap = 7.5 // 开发工具中 android 和其他手机
  141. }
  142. }
  143. // 开启 wifi 的情况下修复 statusBarHeight 值获取不到
  144. if (!windowInfo.statusBarHeight) {
  145. windowInfo.statusBarHeight = windowInfo.screenHeight - windowInfo.windowHeight - 20
  146. }
  147. // 获取不到胶囊信息就自定义重置一个
  148. menuRect = {
  149. bottom: windowInfo.statusBarHeight + gap + height,
  150. height,
  151. left: windowInfo.windowWidth - width - 10,
  152. right: windowInfo.windowWidth - 10,
  153. top: windowInfo.statusBarHeight + gap,
  154. width,
  155. }
  156. }
  157. return menuRect
  158. }
  159. export function nextTick(cb) {
  160. if (typeof miniprogramThis.nextTick === 'function') {
  161. return miniprogramThis.nextTick(cb)
  162. } else if (typeof Promise !== 'undefined') {
  163. return Promise.resolve().then(cb)
  164. } else {
  165. setTimeout(() => cb(), 0)
  166. }
  167. }