1/* 2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an 'AS IS' BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15const pickerHelper = requireInternal('file.picker'); 16 17let gContext = undefined; 18 19const PhotoViewMIMETypes = { 20 IMAGE_TYPE: 'image/*', 21 VIDEO_TYPE: 'video/*', 22 IMAGE_VIDEO_TYPE: '*/*', 23 INVALID_TYPE: '' 24}; 25 26const DocumentSelectMode = { 27 FILE: 0, 28 FOLDER: 1, 29 MIXED: 2, 30}; 31 32const DocumentPickerMode = { 33 DEFAULT: 0, 34 DOWNLOAD: 1, 35}; 36 37const ExtTypes = { 38 DOWNLOAD_TYPE: 'filePicker', 39 AUDIO_PICKER_TYPE: 'audioPicker', 40 PHOTO_PICKER_TYPE: 'photoPicker', 41}; 42 43const PickerDetailType = { 44 FILE_MGR_AUTH: 'downloadAuth', 45 FILE_MGR_SELECT:'select', 46 FILE_MGR_SAVE:'save', 47}; 48 49const ErrCode = { 50 INVALID_ARGS: 13900020, 51 RESULT_ERROR: 13900042, 52 NAME_TOO_LONG: 13900030, 53 CONTEXT_NO_EXIST: 16000011, 54}; 55 56const ERRCODE_MAP = new Map([ 57 [ErrCode.INVALID_ARGS, 'Invalid argument'], 58 [ErrCode.RESULT_ERROR, 'Unknown error'], 59 [ErrCode.NAME_TOO_LONG, 'File name too long'], 60 [ErrCode.CONTEXT_NO_EXIST, 'Current ability failed to obtain context'], 61]); 62 63const PHOTO_VIEW_MIME_TYPE_MAP = new Map([ 64 [PhotoViewMIMETypes.IMAGE_TYPE, 'FILTER_MEDIA_TYPE_IMAGE'], 65 [PhotoViewMIMETypes.VIDEO_TYPE, 'FILTER_MEDIA_TYPE_VIDEO'], 66 [PhotoViewMIMETypes.IMAGE_VIDEO_TYPE, 'FILTER_MEDIA_TYPE_ALL'], 67]); 68 69const ACTION = { 70 SELECT_ACTION: 'ohos.want.action.OPEN_FILE', 71 SELECT_ACTION_MODAL: 'ohos.want.action.OPEN_FILE_SERVICE', 72 SAVE_ACTION: 'ohos.want.action.CREATE_FILE', 73 SAVE_ACTION_MODAL: 'ohos.want.action.CREATE_FILE_SERVICE', 74}; 75 76const CREATE_FILE_NAME_LENGTH_LIMIT = 256; 77const ARGS_ZERO = 0; 78const ARGS_ONE = 1; 79const ARGS_TWO = 2; 80const RESULT_CODE_ERROR = -1; 81const RESULT_CODE_OK = 0; 82const FILENAME_LENGTH = 3; 83 84/* 85* UTF-8字符编码数值对应的存储长度: 86* 0000 - 0x007F (eg: a~z A~Z 0~9) 87* 0080 - 0x07FF (eg: 希腊字母) 88* 0800 - 0xFFFF (eg: 中文) 89* 其他 (eg: 平面符号) 90*/ 91function strSizeUTF8(str) { 92 let strLen = str.length; 93 let bytesLen = 0; 94 let greeceLen = 2; 95 let chineseLen = 3; 96 let othersLen = 4; 97 for (let i = 0; i < strLen; i++) { 98 let charCode = str.charCodeAt(i); 99 if (charCode <= 0x007f) { 100 bytesLen++; 101 } else if (charCode <= 0x07ff) { 102 bytesLen += greeceLen; 103 } else if (charCode <= 0xffff) { 104 bytesLen += chineseLen; 105 } else { 106 bytesLen += othersLen; 107 } 108 } 109 return bytesLen; 110} 111 112function checkArguments(args) { 113 let checkArgumentsResult = undefined; 114 if (args.length === ARGS_TWO && typeof args[ARGS_ONE] !== 'function') { 115 checkArgumentsResult = getErr(ErrCode.INVALID_ARGS); 116 } 117 118 if (args.length > 0 && typeof args[ARGS_ZERO] === 'object') { 119 let option = args[ARGS_ZERO]; 120 if (option.maxSelectNumber !== undefined) { 121 if (option.maxSelectNumber.toString().indexOf('.') !== -1) { 122 checkArgumentsResult = getErr(ErrCode.INVALID_ARGS); 123 } 124 } 125 126 if (option.newFileNames === undefined || option.newFileNames.length <= 0) { 127 return checkArgumentsResult; 128 } 129 130 for (let i = 0; i < option.newFileNames.length; i++) { 131 let value = option.newFileNames[i]; 132 if (strSizeUTF8(value) >= CREATE_FILE_NAME_LENGTH_LIMIT) { 133 console.log('[picker] checkArguments Invalid name: ' + value); 134 checkArgumentsResult = getErr(ErrCode.NAME_TOO_LONG); 135 } 136 } 137 } 138 139 return checkArgumentsResult; 140} 141 142function getErr(errCode) { 143 return {code: errCode, message: ERRCODE_MAP.get(errCode)}; 144} 145 146function parsePhotoPickerSelectOption(args) { 147 let config = { 148 action: 'ohos.want.action.photoPicker', 149 type: 'multipleselect', 150 parameters: { 151 uri: 'multipleselect', 152 extType: ExtTypes.PHOTO_PICKER_TYPE, 153 }, 154 }; 155 156 if (args.length > ARGS_ZERO && typeof args[ARGS_ZERO] === 'object') { 157 let option = args[ARGS_ZERO]; 158 if (option.maxSelectNumber && option.maxSelectNumber > 0) { 159 let select = (option.maxSelectNumber === 1) ? 'singleselect' : 'multipleselect'; 160 config.type = select; 161 config.parameters.uri = select; 162 config.parameters.maxSelectCount = option.maxSelectNumber; 163 } 164 if (option.MIMEType && PHOTO_VIEW_MIME_TYPE_MAP.has(option.MIMEType)) { 165 config.parameters.filterMediaType = PHOTO_VIEW_MIME_TYPE_MAP.get(option.MIMEType); 166 } 167 } 168 169 return config; 170} 171 172function anonymousPathArray(geturi) { 173 let anonymousPathArrays = []; 174 let anonymousPath = ''; 175 if (geturi === undefined) { 176 return anonymousPathArrays; 177 } 178 for (let i = 0; i < geturi.length; ++i) { 179 let lastSlashIndex = geturi[i].lastIndexOf('/'); 180 if (lastSlashIndex === -1) { 181 anonymousPathArrays.push(geturi[i]); 182 } else { 183 let dirPath = geturi[i].substring(0, lastSlashIndex + 1); 184 let fileName = geturi[i].substring(lastSlashIndex + 1); 185 if (fileName.length <= 0) { 186 anonymousPath = '******'; 187 } else { 188 let lastLetter = fileName.slice(-1); 189 let maskedName = '******' + lastLetter; 190 anonymousPath = dirPath + maskedName; 191 } 192 anonymousPathArrays.push(anonymousPath); 193 } 194 } 195 return anonymousPathArrays; 196} 197 198function getPhotoPickerSelectResult(args) { 199 let selectResult = { 200 error: undefined, 201 data: undefined, 202 }; 203 204 if (args.resultCode === 0) { 205 let uris = args.photoUris; 206 let isOriginal = args.isOriginal; 207 selectResult.data = new PhotoSelectResult(uris, isOriginal); 208 } else if (args.resultCode === -1) { 209 selectResult.data = new PhotoSelectResult([], undefined); 210 } else { 211 selectResult.error = getErr(ErrCode.RESULT_ERROR); 212 } 213 214 return selectResult; 215} 216 217async function photoPickerSelect(...args) { 218 let checkPhotoArgsResult = checkArguments(args); 219 if (checkPhotoArgsResult !== undefined) { 220 console.log('[picker] Photo Invalid argument'); 221 throw checkPhotoArgsResult; 222 } 223 224 const config = parsePhotoPickerSelectOption(args); 225 console.log('[picker] Photo config: ' + JSON.stringify(config)); 226 227 let photoSelectContext = undefined; 228 let photoSelectWindow = undefined; 229 try { 230 if (this.context !== undefined) { 231 photoSelectContext = this.context; 232 } else { 233 photoSelectContext = getContext(this); 234 } 235 } catch (getContextError) { 236 console.error('[picker] getContext error: ' + getContextError); 237 throw getErr(ErrCode.CONTEXT_NO_EXIST); 238 } 239 try { 240 if (photoSelectContext === undefined) { 241 console.error('[picker] photoSelectContext == undefined'); 242 throw getErr(ErrCode.CONTEXT_NO_EXIST); 243 } 244 let modalSelectResult = await modalPicker(photoSelectContext, config, photoSelectWindow); 245 console.log('[picker] photo select result: ' + JSON.stringify(modalSelectResult)); 246 const photoSelectResult = getPhotoPickerSelectResult(modalSelectResult); 247 console.log('[picker] photoSelectResult: ' + JSON.stringify(photoSelectResult)); 248 if (args.length === ARGS_TWO && typeof args[ARGS_ONE] === 'function') { 249 return args[ARGS_ONE](photoSelectResult.error, photoSelectResult.data); 250 } else if (args.length === ARGS_ONE && typeof args[ARGS_ZERO] === 'function') { 251 return args[ARGS_ZERO](photoSelectResult.error, photoSelectResult.data); 252 } 253 return new Promise((resolve, reject) => { 254 if (photoSelectResult.data !== undefined) { 255 resolve(photoSelectResult.data); 256 } else { 257 reject(photoSelectResult.error); 258 } 259 }); 260 } catch (error) { 261 console.error('[picker] photo select error: ' + error); 262 } 263 return undefined; 264} 265 266function parseDocumentPickerSelectOption(args, action) { 267 let config = { 268 action: action, 269 parameters: { 270 startMode: 'choose', 271 extType: ExtTypes.DOWNLOAD_TYPE, 272 pickerType: PickerDetailType.FILE_MGR_SELECT, 273 } 274 }; 275 276 if (args.length > ARGS_ZERO && typeof args[ARGS_ZERO] === 'object') { 277 let option = args[ARGS_ZERO]; 278 config.parameters.key_select_mode = option.selectMode; 279 console.log('[picker] parseDocumentPickerSelectOption: ' + JSON.stringify(option)); 280 281 if ((option.maxSelectNumber !== undefined) && option.maxSelectNumber > 0) { 282 config.parameters.key_pick_num = option.maxSelectNumber; 283 } 284 if (option.defaultFilePathUri !== undefined) { 285 config.parameters.key_pick_dir_path = option.defaultFilePathUri; 286 } 287 if ((option.fileSuffixFilters !== undefined) && option.fileSuffixFilters.length > 0) { 288 config.parameters.key_file_suffix_filter = option.fileSuffixFilters; 289 } 290 if (option.authMode !== undefined) { 291 config.parameters.key_auth_mode = option.authMode; 292 } 293 } 294 295 console.log('[picker] document select config: ' + JSON.stringify(config)); 296 return config; 297} 298 299function parseAudioPickerSelectOption(args, action) { 300 let config = { 301 action: action, 302 parameters: { 303 extType: ExtTypes.AUDIO_PICKER_TYPE, 304 } 305 }; 306 if (args.length > ARGS_ZERO && typeof args[ARGS_ZERO] === 'object') { 307 let option = args[ARGS_ZERO]; 308 if ((option.maxSelectNumber !== undefined) && option.maxSelectNumber > 0) { 309 config.parameters.key_pick_num = option.maxSelectNumber; 310 } 311 } 312 console.log('[picker] audio select config: ' + JSON.stringify(config)); 313 return config; 314} 315 316function getDocumentPickerSelectResult(args) { 317 let selectResult = { 318 error: undefined, 319 data: undefined 320 }; 321 if (args === undefined || args.resultCode === undefined) { 322 selectResult.error = getErr(ErrCode.RESULT_ERROR); 323 console.log('[picker] document select selectResult: ' + JSON.stringify(selectResult)); 324 return selectResult; 325 } 326 if (args.resultCode === RESULT_CODE_OK) { 327 if (args.ability_params_stream) { 328 selectResult.data = args.ability_params_stream; 329 selectResult.error = args.resultCode; 330 } 331 } else if (args.resultCode === RESULT_CODE_ERROR) { 332 selectResult.data = []; 333 selectResult.error = args.resultCode; 334 } 335 336 console.log('[picker] document select selectResult: : errorcode is = ' + selectResult.error + 337 ', selecturi is = ' + anonymousPathArray(selectResult.data)); 338 return selectResult; 339} 340 341async function documentPickerSelect(...args) { 342 let checkDocumentSelectArgsResult = checkArguments(args); 343 if (checkDocumentSelectArgsResult !== undefined) { 344 console.log('[picker] Document Select Invalid argument'); 345 throw checkDocumentSelectArgsResult; 346 } 347 348 let documentSelectContext = undefined; 349 let documentSelectConfig = undefined; 350 let documentSelectResult = undefined; 351 let selectResult = undefined; 352 let documentSelectWindow = undefined; 353 354 try { 355 if (this.context !== undefined) { 356 documentSelectContext = this.context; 357 } else { 358 documentSelectContext = getContext(this); 359 } 360 } catch (getContextError) { 361 console.error('[picker] getContext error: ' + getContextError); 362 throw getErr(ErrCode.CONTEXT_NO_EXIST); 363 } 364 try { 365 if (documentSelectContext === undefined) { 366 console.error('[picker] documentSelectContext == undefined'); 367 throw getErr(ErrCode.CONTEXT_NO_EXIST); 368 } 369 if (this.window !== undefined) { 370 documentSelectWindow = this.window; 371 } 372 documentSelectConfig = parseDocumentPickerSelectOption(args, ACTION.SELECT_ACTION_MODAL); 373 console.error('[picker] DocumentSelect documentSelectConfig: ' + JSON.stringify(documentSelectConfig)); 374 documentSelectResult = await modalPicker(documentSelectContext, documentSelectConfig, documentSelectWindow); 375 } catch (paramError) { 376 console.error('[picker] DocumentSelect paramError: ' + JSON.stringify(paramError)); 377 } 378 selectResult = getDocumentPickerSelectResult(documentSelectResult); 379 return sendResult(args, selectResult); 380} 381 382function parseDocumentPickerSaveOption(args, action) { 383 let config = { 384 action: action, 385 parameters: { 386 startMode: 'save', 387 pickerMode: DocumentPickerMode.DEFAULT, 388 extType: ExtTypes.DOWNLOAD_TYPE, 389 pickerType: PickerDetailType.FILE_MGR_SAVE, 390 } 391 }; 392 393 if (args.length > ARGS_ZERO && typeof args[ARGS_ZERO] === 'object') { 394 let option = args[ARGS_ZERO]; 395 console.log('[picker] document save option: ' + JSON.stringify(option)); 396 if ((option.newFileNames !== undefined) && option.newFileNames.length > 0) { 397 config.parameters.key_pick_file_name = option.newFileNames; 398 config.parameters.saveFile = option.newFileNames[0]; 399 } 400 401 if (option.defaultFilePathUri !== undefined) { 402 config.parameters.key_pick_dir_path = option.defaultFilePathUri; 403 } 404 if ((option.fileSuffixChoices !== undefined) && option.fileSuffixChoices.length > 0) { 405 config.parameters.key_file_suffix_choices = option.fileSuffixChoices; 406 } 407 if (option.pickerMode === DocumentPickerMode.DOWNLOAD) { 408 config.parameters.pickerMode = option.pickerMode; 409 config.parameters.pickerType = PickerDetailType.FILE_MGR_AUTH; 410 } 411 } 412 413 console.log('[picker] document save config: ' + JSON.stringify(config)); 414 return config; 415} 416 417function getAudioPickerSelectResult(args) { 418 let selectResult = { 419 error: undefined, 420 data: undefined 421 }; 422 if (args === undefined || args.resultCode === undefined) { 423 selectResult.error = getErr(ErrCode.RESULT_ERROR); 424 console.log('[picker] getAudioPickerSelectResult selectResult: ' + JSON.stringify(selectResult)); 425 return selectResult; 426 } 427 if (args.resultCode === RESULT_CODE_OK) { 428 if (args.uriArr) { 429 selectResult.data = args.uriArr; 430 selectResult.error = args.resultCode; 431 } else { 432 selectResult.data = []; 433 selectResult.error = args.resultCode; 434 } 435 } else if (args.resultCode === RESULT_CODE_ERROR) { 436 selectResult.data = []; 437 selectResult.error = args.resultCode; 438 } 439 440 console.log('[picker] getAudioPickerSelectResult selectResult: errorcode is = ' + selectResult.error + 441 ', selecturi is = ' + anonymousPathArray(selectResult.data)); 442 return selectResult; 443} 444 445 446function getDocumentPickerSaveResult(args) { 447 let saveResult = { 448 error: undefined, 449 data: undefined 450 }; 451 if (args === undefined || args.resultCode === undefined) { 452 saveResult.error = getErr(ErrCode.RESULT_ERROR); 453 console.log('[picker] getDocumentPickerSaveResult saveResult: ' + JSON.stringify(saveResult)); 454 return saveResult; 455 } 456 if (args.resultCode === RESULT_CODE_OK) { 457 if (args.ability_params_stream) { 458 saveResult.data = args.ability_params_stream; 459 saveResult.error = args.resultCode; 460 } 461 } else if (args.resultCode === RESULT_CODE_ERROR) { 462 saveResult.data = []; 463 saveResult.error = args.resultCode; 464 } 465 466 console.log('[picker] getDocumentPickerSaveResult saveResult: errorcode is = ' + saveResult.error + 467 ', selecturi is = ' + anonymousPathArray(saveResult.data)); 468 return saveResult; 469} 470 471function startModalPicker(context, config, window) { 472 if (context === undefined) { 473 throw Error('[picker] Context undefined.'); 474 } 475 if (config === undefined) { 476 throw Error('[picker] Config undefined.'); 477 } 478 gContext = context; 479 if (pickerHelper === undefined) { 480 throw Error('[picker] PickerHelper undefined.'); 481 } 482 let helper; 483 if (window !== undefined) { 484 helper = pickerHelper.startModalPicker(gContext, config, window); 485 } else { 486 helper = pickerHelper.startModalPicker(gContext, config); 487 } 488 if (helper === undefined) { 489 throw Error('[picker] Please check the parameter you entered.'); 490 } 491 return helper; 492} 493 494async function modalPicker(context, config, window) { 495 try { 496 console.log('[picker] Config: ' + JSON.stringify(config)); 497 let modalResult = await startModalPicker(context, config, window); 498 return modalResult; 499 } catch (resultError) { 500 console.error('[picker] Result error: ' + resultError); 501 return undefined; 502 } 503} 504 505async function documentPickerSave(...args) { 506 let checkDocumentSaveArgsResult = checkArguments(args); 507 if (checkDocumentSaveArgsResult !== undefined) { 508 console.log('[picker] Document Save Invalid argument'); 509 throw checkDocumentSaveArgsResult; 510 } 511 512 let documentSaveContext = undefined; 513 let documentSaveConfig = undefined; 514 let documentSaveResult = undefined; 515 let saveResult = undefined; 516 let documentSaveWindow = undefined; 517 518 try { 519 if (this.context !== undefined) { 520 documentSaveContext = this.context; 521 } else { 522 documentSaveContext = getContext(this); 523 } 524 } catch (getContextError) { 525 console.error('[picker] getContext error: ' + getContextError); 526 throw getErr(ErrCode.CONTEXT_NO_EXIST); 527 } 528 if (this.window !== undefined) { 529 documentSaveWindow = this.window; 530 } 531 532 documentSaveConfig = parseDocumentPickerSaveOption(args, ACTION.SAVE_ACTION_MODAL); 533 console.log('[picker] document save start'); 534 535 documentSaveResult = await modalPicker(documentSaveContext, documentSaveConfig, documentSaveWindow); 536 saveResult = getDocumentPickerSaveResult(documentSaveResult); 537 return sendResult(args, saveResult); 538} 539 540async function sendResult(args, result) { 541 try { 542 if (result === undefined) { 543 console.log('[picker] modal picker: result is undefined.'); 544 return undefined; 545 } 546 if (args.length === ARGS_TWO && typeof args[ARGS_ONE] === 'function') { 547 return args[ARGS_ONE](result.error, result.data); 548 } else if (args.length === ARGS_ONE && typeof args[ARGS_ZERO] === 'function') { 549 return args[ARGS_ZERO](result.error, result.data); 550 } 551 return new Promise((resolve, reject) => { 552 if (result.data !== undefined) { 553 resolve(result.data); 554 } else { 555 reject(result.error); 556 } 557 }); 558 } catch (resultError) { 559 console.error('[picker] Result error: ' + resultError); 560 } 561 return undefined; 562} 563 564async function audioPickerSelect(...args) { 565 let checkAudioArgsResult = checkArguments(args); 566 if (checkAudioArgsResult !== undefined) { 567 console.log('[picker] Audio Invalid argument'); 568 throw checkAudioArgsResult; 569 } 570 571 const audioSelectConfig = parseAudioPickerSelectOption(args, ACTION.SELECT_ACTION); 572 console.log('[picker] audio select config: ' + JSON.stringify(audioSelectConfig)); 573 574 let audioSelectContext = undefined; 575 let audipSelectWindow = undefined; 576 try { 577 if (this.context !== undefined) { 578 audioSelectContext = this.context; 579 } else { 580 audioSelectContext = getContext(this); 581 } 582 } catch (getContextError) { 583 console.error('[picker] getContext error: ' + getContextError); 584 throw getErr(ErrCode.CONTEXT_NO_EXIST); 585 } 586 try { 587 if (audioSelectContext === undefined) { 588 console.error('[picker] audioSelectContext == undefined'); 589 throw getErr(ErrCode.CONTEXT_NO_EXIST); 590 } 591 let modalSelectResult = await modalPicker(audioSelectContext, audioSelectConfig, audipSelectWindow); 592 let saveResult = getAudioPickerSelectResult(modalSelectResult); 593 return sendResult(args, saveResult); 594 } catch (error) { 595 console.error('[picker] audio select error: ' + error); 596 } 597 return undefined; 598} 599 600function PhotoSelectOptions() { 601 this.MIMEType = PhotoViewMIMETypes.INVALID_TYPE; 602 this.maxSelectNumber = -1; 603} 604 605function PhotoSelectResult(uris, isOriginalPhoto) { 606 this.photoUris = uris; 607 this.isOriginalPhoto = isOriginalPhoto; 608} 609 610function PhotoSaveOptions() { 611 this.newFileNames = undefined; 612} 613 614function DocumentSelectOptions() { 615 this.defaultFilePathUri = undefined; 616 this.fileSuffixFilters = undefined; 617 this.maxSelectNumber = undefined; 618 this.selectMode = DocumentSelectMode.FILE; 619} 620 621function DocumentSaveOptions() { 622 this.newFileNames = undefined; 623 this.defaultFilePathUri = undefined; 624 this.fileSuffixChoices = undefined; 625 this.pickerMode = DocumentPickerMode.DEFAULT; 626} 627 628function AudioSelectOptions() {} 629 630function AudioSaveOptions() { 631 this.newFileNames = undefined; 632} 633 634function ParseContext(args) 635{ 636 if (args.length > ARGS_TWO || args.length < ARGS_ZERO || typeof args[ARGS_ZERO] !== 'object') { 637 return undefined; 638 } 639 return args[ARGS_ZERO]; 640} 641 642function parseWindow(args) 643{ 644 if (args.length !== ARGS_TWO) { 645 console.log('[picker] ParseWindow: not window mode.'); 646 return undefined; 647 } 648 if (args.length === ARGS_TWO && typeof args[ARGS_ONE] !== 'object') { 649 console.log('[picker] ParseWindow: not window mode or type err.'); 650 return undefined; 651 } 652 console.log('[picker] ParseWindow: window mode.'); 653 return args[ARGS_ONE]; 654} 655 656function PhotoViewPicker(...args) { 657 this.select = photoPickerSelect; 658 this.save = documentPickerSave; 659 this.context = ParseContext(args); 660} 661 662function DocumentViewPicker(...args) { 663 this.select = documentPickerSelect; 664 this.save = documentPickerSave; 665 this.context = ParseContext(args); 666 this.window = parseWindow(args); 667} 668 669function AudioViewPicker(...args) { 670 this.select = audioPickerSelect; 671 this.save = documentPickerSave; 672 this.context = ParseContext(args); 673} 674 675export default { 676 startModalPicker, 677 ExtTypes : ExtTypes, 678 PickerDetailType: PickerDetailType, 679 PhotoViewMIMETypes : PhotoViewMIMETypes, 680 PhotoSelectOptions : PhotoSelectOptions, 681 PhotoSelectResult : PhotoSelectResult, 682 PhotoSaveOptions : PhotoSaveOptions, 683 DocumentSelectMode : DocumentSelectMode, 684 DocumentPickerMode : DocumentPickerMode, 685 DocumentSelectOptions : DocumentSelectOptions, 686 DocumentSaveOptions : DocumentSaveOptions, 687 AudioSelectOptions : AudioSelectOptions, 688 AudioSaveOptions : AudioSaveOptions, 689 PhotoViewPicker : PhotoViewPicker, 690 DocumentViewPicker: DocumentViewPicker, 691 AudioViewPicker : AudioViewPicker, 692}; 693