/*
* Copyright (c) 2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import { fileIo as fs, fileUri } from '@kit.CoreFileKit';
import { AsyncCallback, BusinessError } from '@kit.BasicServicesKit';
import { bundleManager } from '@kit.AbilityKit';
import { LengthMetrics, LengthUnit } from '@kit.ArkUI';
import { display } from @ohos.display;
const cooperation_multi_name = ['Cooperation-multi', 'Cooperation'];
const PHOTO_VIEW_MIME_TYPE_MAP = new Map([
['*/*', 'FILTER_MEDIA_TYPE_ALL'],
['image/*', 'FILTER_MEDIA_TYPE_IMAGE'],
['video/*', 'FILTER_MEDIA_TYPE_VIDEO'],
['image/movingPhoto', 'FILTER_MEDIA_TYPE_IMAGE_MOVING_PHOTO']
])
const PARAMETERS_VALIDATE_FAILED_MESSAGE =
'Scene parameters validate failed, possible causes:' +
' 1. An invalid enumeration value was passed. Only MOVING_PHOTO_ENABLE and' +
' MOVING_PHOTO_DISABLE are supported for configuration;';
const ILLEGAL_SCENARIO_CALL_ERROR_MESSAGE =
'Invalid call context. Possible causes:' +
' 1. The API is called outside the photo browsing scenario.' +
' 2. The API is called when isMovingPhotoBadgeShown is already set to true.'
const PARAMETERS_VALIDATE_FAILED_CODE = 23800151;
const ILLEGAL_SCENARIO_CALL_ERROR_CODE = 23800202;
const PERMISSION_DENNIED = 401;
class BusinessError extends Error {
constructor(msg, code) {
super(msg);
this.code = code || PERMISSION_DENNIED;
}
}
interface MimeTypeFilter {
mimeTypeArray: string[],
filterType: number
}
interface PhotoStateProps {
isPhotoBrowserShow: boolean;
isMovingPhotoBadgeShownValid: boolean;
}
@Component
export struct PhotoPickerComponent {
pickerOptions?: PickerOptions | undefined;
onSelect?: (uri: string) => void;
onDeselect?: (uri: string) => void;
onItemClicked?: (itemInfo: ItemInfo, clickType: ClickType) => boolean;
onItemClickedNotify?: (itemInfo: ItemInfo, clickType: ClickType) => void;
onEnterPhotoBrowser?: (photoBrowserInfo: PhotoBrowserInfo) => boolean;
onExitPhotoBrowser?: (photoBrowserInfo: PhotoBrowserInfo) => boolean;
onPickerControllerReady?: () => void;
onPhotoBrowserChanged?: (browserItemInfo: BaseItemInfo) => boolean;
onSelectedItemsDeleted?: ItemsDeletedCallback;
onExceedMaxSelected?: ExceedMaxSelectedCallback;
onPhotoBrowserChangeStart?: onPhotoBrowserChangeStartCallback;
onError?: onErrorCallback;
onCurrentAlbumDeleted?: CurrentAlbumDeletedCallback;
onVideoPlayStateChanged?: VideoPlayStateChangedCallback;
onMovingPhotoBadgeStateChanged?: (uri: string, state: MovingPhotoBadgeStateType) => void;
badgeConfig?: BadgeConfig;
batchBadgeConfigSize: number = 1000;
maxBadgeConfigSize: number = 200000;
batchPreselectedInfos: number = 200;
preselectedInfos = undefined;
onScrollStopAtStart: onScrollStopAtStartCallback;
onScrollStopAtEnd: onScrollStopAtEndCallback;
onPinchGridSwitched = undefined;
dpiFollowStrategy = SecurityDpiFollowStrategy.FOLLOW_UI_EXTENSION_ABILITY_DPI;
badgeConfigIsSending: boolean = false;
@ObjectLink @Watch('onChanged') pickerController: PickerController;
@State revokeIndex = 0;
isPickerKilled = false;
private proxy: UIExtensionProxy | undefined;
private isPhotoBrowserShow: boolean = false;
private isMovingPhotoBadgeShownValid: boolean = false;
private setPhotoStateProps(): void {
this.pickerController.getMovingPhotoState = (): PhotoStateProps => {
return {
isPhotoBrowserShow: this.isPhotoBrowserShow,
isMovingPhotoBadgeShownValid: this.isMovingPhotoBadgeShownValid
};
};
}
aboutToAppear(): void {
this.setPhotoStateProps();
}
pickerController.onEnterPhotoBrowser = () => {
return false;
}
pickerController.parseIsMovingPhotoBadgeShown = () => {
return false;
}
private onChanged(): void {
if (!this.proxy) {
return;
}
let data = this.pickerController?.data;
if (data?.has('SET_SELECTED_URIS')) {
this.proxy.send({ 'selectUris': data?.get('SET_SELECTED_URIS') as Array<string> });
console.info('PhotoPickerComponent onChanged: SET_SELECTED_URIS');
} else if (data?.has('SET_ALBUM_URI')) {
this.proxy.send({ 'albumUri': data?.get('SET_ALBUM_URI') as string });
console.info('PhotoPickerComponent onChanged: SET_ALBUM_URI');
} else if (data?.has('SET_SELECTED_INFO')) {
this.onChangeSelectedInfo(data)
console.info('PhotoPickerComponent onChanged: SET_SELECTED_INFO');
} else if (data?.has('SET_MOVINGPHOTO_STATE')) {
this.proxy.send({movingPhotoState: data?.get('SET_MOVINGPHOTO_STATE)});
console.info('PhotoPickerComponent onChanged: SET_SELECTED_INFO');
} else if (data?.has('SET_MAX_SELECT_COUNT')) {
this.onSetMaxSelectCount(data);
} else if (data?.has('SET_PHOTO_BROWSER_ITEM')) {
this.onSetPhotoBrowserItem(data);
} else {
this.otherOnChange(data);
}
}
private onChangedBadgeConfigs(data?: Map<string, Object>) {
console.log('controller onChanged: SET_BADGE_CONFIGS,badgeConfigIsSending:',this.badgeConfigIsSending)
if (this.badgeConfigIsSending !== true) {
this.badgeConfig = data.get('SET_BADGE_CONFIGS');
this.badgeConfigIsSending = true;
this.badgeConfig.uris?.splice(this.maxBadgeConfigSize);
this.proxy.send({needSendBadgeConfigs: true, BadgeOptionType: data.get('BADGE_CONFIGS_OPTION_TYPE')});
}
}
private otherOnChange(data?: Map<string, Object>) {
if (data?.has('EXIT_PHOTO_BROWSER')) {
this.handleExitPhotoBrowser();
} else if (data?.has('SET_PHOTO_BROWSER_UI_ELEMENT_VISIBILITY')) {
this.onSetPhotoBrowserUIElementVisibility(data);
} else if (data?.has('CREATE_URI')) {
this.onCreateUri(data);
console.info('PhotoPickerComponent onChanged: CREATE_URI');
} else if (data?.has('REPLACE_URI')) {
this.onReplaceUri(data);
console.info('PhotoPickerComponent onChanged: REPLACE_URI');
} else if (data?.has('SAVE_TRUSTED_PHOTO_ASSETS')) {
this.onSaveTrustedPhotoAssets(data);
console.info('PhotoPickerComponent onChanged: SAVE_REPLACE_PHOTO_ASSETS');
} else if (data?.has('SET_BADGE_CONFIGS')) {
this.onChangedBadgeConfigs(data);
} else if(data?.has('UPDATE_CONFIG')){
this.onUpdateConfig(data);
} else if (data?.has('SET_ITEM_CLICK_RESULT')) {
this.onChangeItemClickResult(data)
console.info('PhotoPickerComponent onChanged: SET_ITEM_CLICK_RESULT');
} else {
this.handleAnotherOnChanges(data);
}
}
private handleAnotherOnChanges(data?: Map<string, Object>) {
if (data?.has('COMPLETED')) {
this.onComplete(data)
console.info('PhotoPickerComponent onChanged: COMPLETED');
} else {
console.info('PhotoPickerComponent onChanged: other case');
}
}
onChangeSelectedInfo(data) {
this.preselectedInfos = null === data ? void 0 : data.get('SET_SELECTED_INFO');
console.log(`preselectedInfos start send1 ${data.get('SET_SELECTED_INFO').slice(0, this.batchPreselectedInfos).length}`);
this.proxy({ uriAndPickerIndexLists: null === data ? void 0 : data.get('SET_SELECTED_INFO').slice(0, this.batchPreselectedInfos),
index: 0, preselectedInfosIsOver: this.preselectedInfos.length <= this.batchPreselectedInfos });
}
private onChangeItemClickResult(data) {
let itemClickResult = data?.get('SET_ITEM_CLICK_RESULT') as Array<ClickResult>;
if (itemClickResult && itemClickResult instanceof Array && itemClickResult.length > 0) {
this.proxy.send({ itemClickResult: itemClickResult});
console.info(`PhotoPickerComponent send itemClickResult ${itemClickResult.length}`);
}
}
private onComplete(data?: Map<string, Object>) {
this.proxy.send({
completed: data?.get('COMPLETED'),
date: data?.get('COMPLETE_DATE')
});
console.info('PhotoPickerComponent onChanged: COMPLETED');
}
private onUpdateConfig(data?: Map<string, Object>) {
this.proxy.send({ updateConfig: data?.get('UPDATE_CONFIG') as UpdatablePickerConfigs });
console.info('PhotoPickerComponent onChanged: UPDATE_CONFIG');
}
private onSetMaxSelectCount(data?: Map<string, Object>): void {
let maxSelected: MaxSelected = data?.get('SET_MAX_SELECT_COUNT') as MaxSelected;
let map: Map<MaxCountType, number> | undefined = maxSelected?.data;
this.proxy.send({
'totalCount': map?.get(MaxCountType.TOTAL_MAX_COUNT),
'photoCount': map?.get(MaxCountType.PHOTO_MAX_COUNT),
'videoCount': map?.get(MaxCountType.VIDEO_MAX_COUNT)
});
console.info('PhotoPickerComponent onChanged: SET_MAX_SELECT_COUNT');
}
private onSetPhotoBrowserItem(data?: Map<string, Object>): void {
let photoBrowserRangeInfo: PhotoBrowserRangeInfo = data?.get('SET_PHOTO_BROWSER_ITEM') as PhotoBrowserRangeInfo;
this.proxy?.send({
'itemUri': photoBrowserRangeInfo?.uri,
'photoBrowserRange': photoBrowserRangeInfo?.photoBrowserRange
});
console.info('PhotoPickerComponent onChanged: SET_PHOTO_BROWSER_ITEM');
}
private handleExitPhotoBrowser(): void {
this.proxy.send({ 'exitPhotoBrowser': true });
console.info('PhotoPickerComponent onChanged: EXIT_PHOTO_BROWSER');
}
private onSetPhotoBrowserUIElementVisibility(data?: Map<string, Object>): void {
let photoBrowserUIElementVisibility: PhotoBrowserUIElementVisibility =
data?.get('SET_PHOTO_BROWSER_UI_ELEMENT_VISIBILITY') as PhotoBrowserUIElementVisibility;
this.proxy?.send({
'elements': photoBrowserUIElementVisibility?.elements,
'isVisible': photoBrowserUIElementVisibility?.isVisible
});
console.info('PhotoPickerComponent onChanged: SET_PHOTO_BROWSER_UI_ELEMENT_VISIBILITY');
}
private onCreateUri(data?: Map<string, Object>): void {
let array = data?.get('CREATE_URI') as Array<Object>;
this.proxy?.send({
selectedMediaUri: array[0],
createUri: array[1],
date: array[2]
});
console.info('PhotoPickerComponent onChanged CREATE_URI');
}
private onReplaceUri(data?: Map<string, Object>): void {
let array = data?.get('REPLACE_URI') as Array<Object>;
this.proxy?.send({
oriUri: array[0],
replaceUri: array[1],
date: array[2]
});
console.info('PhotoPickerComponent onChanged REPLACE_URI');
}
private onSaveTrustedPhotoAssets(data?: Map<string, Object>): void {
let array: Array<object> = data?.get('SAVE_TRUSTED_PHOTO_ASSETS') as Array<object>;
this.proxy?.send({
replaceUris: array[0],
config: array[1],
saveMode: array[2],
appName: array[3],
date: array[4]
});
console.info('PhotoPickerComponent onChanged SAVE_REPLACE_PHOTO_ASSETS');
}
private checkAssetFilterIncalid(assetFilter: photoAccessHelper.OperationItem[]): boolean {
// 获取所有有效的值
const validOperationTypes = Object.values(photoAccessHelper.OperationType);
const validPhotoKeys = Object.values(photoAccessHelper.PhotoKeys);
//遍历数组中的每个OperationItem
for (const item of assetFilter) {
//检查operationType是否有值且在枚举中
if (!item.operationType || !validOperationTypes.includes(item?.operationType)) {
console.log('PhotoPickerComponent, Invalid operationType');
return true;
}
//如果field有值,检查是否在枚举中
if (item.field !== undefined || item.field !== null) {
if (!validPhotoKeys.includes(item.field)) {
console.log('PhotoPickerComponent, Invalid photokeys');
return true;
}
// uri仅支持EQUAL_TO操作
if (item.field === photoAccessHelper.PhotoKeys.URI &&
item.operationType !== photoAccessHelper.OperationType.EQUAL_TO) {
console.log('PhotoPickerComponent, Invalid uri operation');
return true;
}
}
}
return false;
}
build() {
if (!this.pickerOptions?.assetFilter ||
!this.checkAssetFilterIncalid(this.pickerOptions?.assetFilter ?? [])) {
Row() {
Column() {
SecurityUIExtensionComponent({
parameters: {
errorRevokeIndex: this.revokeIndex,
"ability.want.params.uiExtensionTargetType": "photoPicker",
uri: "multipleselect",
targetPage: "photoPage",
filterMediaType: this.convertMIMETypeToFilterType(this.pickerOptions?.MIMEType),
mimeTypeFilter: this.parseMimeTypeFilter(this.pickerOptions?.mimeTypeFilter),
fileSizeFilter: this.pickerOptions?.fileSizeFilter,
videoDurationFilter: this.pickerOptions?.videoDurationFilter,
photoViewMimeTypeFileSizeFilters: this.pickerOptions?.photoViewMimeTypeFileSizeFilters,
maxSelectNumber: this.pickerOptions?.maxSelectNumber as number,
isPhotoTakingSupported: this.pickerOptions?.isPhotoTakingSupported as boolean,
isEditSupported: false,
recommendationOptions: this.pickerOptions?.recommendationOptions as photoAccessHelper.RecommendationOptions,
assetCompatibleCapability: null === (r = this.pickerOptions) || void 0 === r ? void 0 : r.assetCompatibleCapability,
preferredCompatibleMode: null === (r = this.pickerOptions) || void 0 === r ? void 0 : r.preferredCompatibleMode,
preselectedUri: this.pickerOptions?.preselectedUris as Array<string>,
isFromPickerView: true,
isNeedActionBar: false,
isNeedSelectBar: false,
isSearchSupported: this.pickerOptions?.isSearchSupported as boolean,
checkBoxColor: this.pickerOptions?.checkBoxColor as string,
backgroundColor: this.pickerOptions?.backgroundColor as string,
checkboxTextColor: this.pickerOptions?.checkboxTextColor as string,
photoBrowserBackgroundColorMode: this.pickerOptions?.photoBrowserBackgroundColorMode as PickerColorMode,
isRepeatSelectSupported: this.pickerOptions?.isRepeatSelectSupported as boolean,
maxSelectedReminderMode: this.pickerOptions?.maxSelectedReminderMode as ReminderMode,
orientation: this.pickerOptions?.orientation as PickerOrientation,
selectMode: this.pickerOptions?.selectMode as SelectMode,
maxPhotoSelectNumber: this.pickerOptions?.maxPhotoSelectNumber as number,
maxVideoSelectNumber: this.pickerOptions?.maxVideoSelectNumber as number,
isOnItemClickedSet: this.onItemClicked ? true : false,
isOnItemClickedNotifySet: this.onItemClickedNotify ? true : false,
isPreviewForSingleSelectionSupported: this.pickerOptions?.isPreviewForSingleSelectionSupported as boolean,
singleSelectionMode: this.pickerOptions?.singleSelectionMode as number,
isSlidingSelectionSupported: this.pickerOptions?.isSlidingSelectionSupported as boolean,
photoBrowserCheckboxPosition: this.pickerOptions?.photoBrowserCheckboxPosition as [number, number],
gridMargin: this.pickerOptions?.gridMargin as Margin,
photoBrowserMargin: this.pickerOptions?.photoBrowserMargin as Margin,
gridStartOffset: this.pickerOptions?.gridStartOffset as number,
gridEndOffset: this.pickerOptions?.gridEndOffset as number,
singleLineConfig: this.getSingleLineConfig(this.pickerOptions?.singleLineConfig as SingleLineConfig),
uiComponentColorMode: this.pickerOptions?.uiComponentColorMode as PickerColorMode,
combinedMediaTypeFilter: this.pickerOptions?.combinedMediaTypeFilter as Array<string>,
pickerIndex: this.pickerOptions?.pickerIndex as number,
isMovingPhotoBadgeShown: this.parseIsMovingPhotoBadgeShown(this.pickerOptions?.isMovingPhotoBadgeShown as boolean),
isSlidingSupported: this.pickerOptions?.isSlidingSupported as boolean,
assetFilter: this.pickerOptions?.assetFilter,
edgeEffect: this.pickerOptions?.edgeEffect,
isOnScrollStopAtStartSet: !!this.onScrollStopAtStart,
isOnScrollStopAtEndSet: !!this.onScrollStopAtEnd,
autoPlayScenes: this.parseAutoPlayScenes(this.pickerOptions?.autoPlayScenes as Array<photoAccessHelper.AutoPlayScene>),
appAlbumFilters: this.parseAppAlbumFilters(this.pickerOptions?.appAlbumFilters as Array<string>),
grindPinchMode: this.pickerOptions?.grindPinchMode
gridPinchMode: this.pickerOptions?.gridPinchMode,
globalMovingPhotoState: this.pickerOptions?.globalMovingPhotoState,
showDateOnScrollbar: this.pickerOptions?.showDateOnScrollbar,
backgroundOpacity: this.pickerOptions?.backgroundOpacity,
contextRecoveryInfo: this.pickerOptions?.contextRecoveryInfo
}
},
{
dpiFollowStategy: this.dpiFollowStrategy
})
.height('100%')
.width('100%')
.onRemoteReady((proxy) => {
this.proxy = proxy;
console.info('PhotoPickerComponent onRemoteReady');
})
.onReceive((data) => {
let wantParam: Record<string, Object> = data as Record<string, Object>;
this.handleOnReceive(wantParam);
})
.onError((error) => {
console.info('PhotoPickerComponent onError: ' + JSON.stringify(error));
console.info('PhotoPickerComponent revokeIndex: ' + this.revokeIndex);
if (error.code === 100014) {
console.log('PhotoPickerComponent is set isPickerKilled = true');
this.isPickerKilled = true;
let e = new PickerError();
e.functionName = error?.name || 'extension_exit_abnormally';
e.errorCode = error.code;
e.errorMessage = error?.message || 'the extension ability exited abnormally, please check AMS log.';
this.handleOnError(e);
}
});
}
.width('100%')
.onVisibleAreaChange([0.0, 1.0], (isExpanding, currentRatio) => {
if (this.isPickerKilled && currentRatio >= 0 && isExpanding) {
console.log(`photopickercomponent isRevoke revokeIndex = ${this.revokeIndex}`);
this.revokeIndex++;
this.isPickerKilled = false;
}
})
}
.height('100%')
}
}
private handleOnReceive(wantParam: Record<string, Object>): void {
let dataType = wantParam['dataType'] as string;
console.info('PhotoPickerComponent onReceive: dataType = ' + dataType);
if (dataType === 'selectOrDeselect') {
this.handleSelectOrDeselect(wantParam);
} else if (dataType === 'itemClick') {
this.handleItemClick(wantParam);
} else if (dataType === 'itemClickedNotify') {
this.handleItemClickedNotify(wantParam);
} else if (dataType === 'onPhotoBrowserStateChanged') {
this.handleEnterOrExitPhotoBrowser(wantParam);
} else if (dataType === 'remoteReady') {
if (this.onPickerControllerReady) {
this.onPickerControllerReady();
if(this.badgeConfig && this.badgeConfig.uris.length > 0) {
console.log('handleOnReceive: send msg to photo:uri.length:',this.badgeConfig?.uris?.length)
this.badgeConfigIsSending = true;
this.proxy.send({needSendBadgeConfigs : true, BadgeOptionType : BadgeOptionType.SET_DATA});
}
if (this.preselectedInfos && this.preselectedInfos.length > 0){
console.log('preselectedInfos start send');
this.proxy.send({ uriAndPickerIndexLists: this.preselectedInfos.slice(0, this.batchPreselectedInfos),
index: 0, preselectedInfosIsOver: this.preselectedInfos.length <= this.batchPreselectedInfos })
}
console.info('PhotoPickerComponent onReceive: onPickerControllerReady');
}
} else if (dataType === 'onPhotoBrowserChanged') {
this.handlePhotoBrowserChange(wantParam);
} else if (dataType === 'onVideoPlayStateChanged') {
this.handleVideoPlayStateChange(wantParam);
} else if (dataType === 'replaceCallback') {
this.handleReplaceCallback(wantParam);
} else if (dataType === 'createCallback') {
this.handleCreateCallback(wantParam);
} else if (dataType === 'saveCallback') {
this.handleSaveCallback(wantParam);
} else if (dataType === 'completed') {
this.handleCompletedCallback(wantParam);
} else if (dataType === 'onBadgeConfigSend') {
this.handleBadgeConfigSend(wantParam)
console.info('PhotoPickerComponent onReceive: onBadgeConfigSend');
} else if (dataType === 'onBackground') {
console.info('PhotoPickerComponent onReceive: onBackground');
this.revokeIndex = 0;
} else if (dataType === 'onMovingPhotoBadgeStateChange') {
this.onMovingPhotoBadgeStateChangeSend(wantParam)
console.info('PhotoPickerComponent onReceive: onMovingPhotoBadgeStateChangeSend');
} else if (dataType === 'onGridLevelChanged') {
if (this.onPinchGridSwitched) {
this.onPinchGridSwitched(e.gridLevel);
}
} else if (dataType === 'onPhotoBrowserChangeStart') {
this.onPhotoBrowserChangeStart(e);
} else if (dataType === 'onError') {
this.onError(e);
} else {
this.handleOtherOnReceive(wantParam);
console.info('PhotoPickerComponent onReceive: other case');
}
console.info('PhotoPickerComponent onReceive' + this.pickerController.encrypt(JSON.stringify(wantParam)));
}
private handleBadgeConfigSend(wantParam: Record<string, Object>): void {
let index = wantParam.nextIndex as string;
if (this.badgeConfig && this.badgeConfig.uris.length > 0) {
const unitBadgeConfig = this.badgeConfig.uris.slice(this.batchBadgeConfigSize * size, this.batchBadgeConfigSize * (index + 1));
console.log('handleBadgeConfigSend: send piece msg to photo index-:',index,'----',unitBadgeConfig.length)
this.proxy.send({badgeConfig : unitBadgeConfig, index: index,
isOver : index >= Math.ceil(this.badgeConfig.uris.length / this.batchBadgeConfigSize) ? true : false,
badgeConfigType : this.badgeConfig.badgeType});
}
if (index >= Math.ceil(this.badgeConfig.uris.length / this.batchBadgeConfigSize)) {
this.badgeConfigIsSending = false;
}
}
private onMovingPhotoBadgeStateChangeSend(wantParam: Record<string, Object>): void {
let uri = wantParam.uri as string;
let enabledMovingPhotoBadge = wantParam.enabledMovingPhotoBadge as MovingPhotoBadgeStateType;
if (uri && enabledMovingPhotoBadge !== undefined && this.onMovingPhotoBadgeStateChanged) {
this.onMovingPhotoBadgeStateChanged(uri, enabledMovingPhotoBadge);
}
}
private handleOtherOnReceive(wantParam: Record<string, Object>): void {
let dataType = wantParam.dataType as string;
if (dataType === 'exceedMaxSelected') {
if (this.onExceedMaxSelected) {
this.onExceedMaxSelected(wantParam.maxCountType as MaxCountType);
}
} else if (dataType === 'selectedItemsDeleted') {
if (this.onSelectedItemsDeleted) {
this.onSelectedItemsDeleted(wantParam.selectedItemInfos as Array<BaseItemInfo>);
}
} else if (dataType === 'currentAlbumDeleted') {
if (this.onCurrentAlbumDeleted) {
this.onCurrentAlbumDeleted();
}
} else if ('onPreselectedInfo' === o) {
console.log(`send preselectUris isOver=${e.nextIndex >= Math.ceil(this.preselectedInfos.length / this.batchPreselectedInfos)}`);
this.proxy.send({ uriAndPickerIndexLists: null == o ? void 0 :this.preselectedInfos.slice(e.nextIndex * this.batchPreselectedInfos, ( e.nextIndex + 1 ) * this.batchPreselectedInfos),
index: e.nextIndex, preselectedInfosIsOver: e.nextIndex >= Math.ceil(this.preselectedInfos.length / this.batchPreselectedInfos)})
} else if (dataType === 'onScrollStopAtStart') {
if (this.onScrollStopAtStart) {
this.onScrollStopAtStart();
}
} else if (dataType === 'onScrollStopAtEnd') {
if (this.onScrollStopAtEnd) {
this.onScrollStopAtEnd();
}
} else {
console.info('PhotoPickerComponent onReceive: other case');
}
}
private handleSelectOrDeselect(wantParam: Record<string, Object>): void {
let isSelect: boolean = wantParam['isSelect'] as boolean;
if (isSelect) {
if (this.onSelect) {
this.onSelect(wantParam['select-item-list'] as string);
console.info('PhotoPickerComponent onReceive: onSelect');
}
} else {
if (this.onDeselect) {
this.onDeselect(wantParam['select-item-list'] as string);
console.info('PhotoPickerComponent onReceive: onDeselect');
}
}
}
private handleItemClick(wantParam: Record<string, Object>): void {
if (this.onItemClicked) {
let clickType: ClickType = this.getClickType(wantParam);
let itemInfo: ItemInfo = this.getItemInfo(wantParam);
let itemType: string = wantParam['itemType'] as string;
let result: boolean = this.onItemClicked(itemInfo, clickType);
console.info('PhotoPickerComponent onReceive: onItemClicked = ' + clickType);
if (this.proxy) {
if (itemType === 'thumbnail' && clickType === ClickType.SELECTED) {
this.proxy.send({ 'clickConfirm': itemInfo.uri, 'isConfirm': result });
console.info('PhotoPickerComponent onReceive: click confirm: uri = ' +
this.pickerController.encrypt(itemInfo.uri) + 'isConfirm = ' + result);
}
if (itemType === 'camera') {
this.proxy.send({ 'enterCamera': result });
console.info('PhotoPickerComponent onReceive: enter camera ' + result);
}
}
}
}
private handleItemClickedNotify(wantParam: Record<string, Object>): void {
if (this.onItemClickedNotify) {
let clickType: ClickType = this.getClickType(wantParam);
let itemInfo: ItemInfo = this.getItemInfo(wantParam);
this.onItemClickedNotify(itemInfo, clickType);
console.info('PhotoPickerComponent onReceive: onItemClickNotify = ' + clickType);
}
}
private getClickType(wantParam: Record<string, Object>): ClickType {
let clickType: ClickType = ClickType.SELECTED;
let type = wantParam['clickType'] as string;
if (type === 'select') {
clickType = ClickType.SELECTED;
} else if (type === 'deselect') {
clickType = ClickType.DESELECTED;
} else {
console.info('PhotoPickerComponent onReceive: other clickType');
}
return clickType;
}
private getItemInfo(wantParam: Record<string, Object>): ItemInfo {
let itemInfo: ItemInfo = new ItemInfo();
let itemType: string = wantParam['itemType'] as string;
if (itemType === 'thumbnail') {
itemInfo.itemType = ItemType.THUMBNAIL;
} else if (itemType === 'camera') {
itemInfo.itemType = ItemType.CAMERA;
} else {
console.info('PhotoPickerComponent onReceive: other itemType');
}
itemInfo.uri = wantParam['uri'] as string;
itemInfo.mimeType = wantParam['mimeType'] as string;
itemInfo.width = wantParam['width'] as number;
itemInfo.height = wantParam['height'] as number;
itemInfo.size = wantParam['size'] as number;
itemInfo.duration = wantParam['duration'] as number;
itemInfo.photoSubType = wantParam['subtype'] as number;
itemInfo.dynamicRangeType = wantParam['dynamicRangeType'] as number;
itemInfo.orientation = wantParam['imageOrientation'] as number;
itemInfo.movingPhotoBadgeState = wantParam['movingPhotoBadgeState'] as number;
itemInfo.videoMode = wantParam['videoMode'] as number;
return itemInfo;
}
private handleEnterOrExitPhotoBrowser(wantParam: Record<string, Object>): void {
let isEnter: boolean = wantParam['isEnter'] as boolean;
let photoBrowserInfo: PhotoBrowserInfo = new PhotoBrowserInfo();
photoBrowserInfo.animatorParams = new AnimatorParams();
photoBrowserInfo.animatorParams.duration = wantParam['duration'] as number;
photoBrowserInfo.animatorParams.curve = wantParam['curve'] as Curve | ICurve | string;
if (isEnter) {
if (this.onEnterPhotoBrowser) {
this.onEnterPhotoBrowser(photoBrowserInfo);
}
} else {
if (this.onExitPhotoBrowser) {
this.onExitPhotoBrowser(photoBrowserInfo);
}
}
if (isEnter) {
this.isPhotoBrowserShow = true;
} else {
this.isPhotoBrowserShow = false;
}
console.info('PhotoPickerComponent onReceive: onPhotoBrowserStateChanged = ' + isEnter);
}
private handlePhotoBrowserChange(wantParam: Record<string, Object>): void {
let browserItemInfo: BaseItemInfo = new BaseItemInfo();
browserItemInfo.uri = wantParam['uri'] as string;
browserItemInfo.photoSubType = wantParam['photoSubType'] as photoAccessHelper.photoSubType;
browserItemInfo.mimeType = wantParam['mimeType'] as string;
if (this.onPhotoBrowserChanged) {
this.onPhotoBrowserChanged(browserItemInfo);
}
console.info('PhotoPickerComponent onReceive: onPhotoBrowserChanged = ' +
this.pickerController.encrypt(browserItemInfo.uri));
}
handleOnPhotoBrowserChangeStart(e) {
let o = new BaseItemInfo();
o.uri = e.uri;
o.photoSubType = e.photoSubType;
o.movingPhotoBadgeState = e.movingPhotoBadgeState;
if (this.onPhotoBrowserChangeStart) {
this.onPhotoBrowserChangeStart(o);
}
console.info('PhotoPickerComponent onReceive: onPhotoBrowserChangeStart = '
+ this.pickerController.encrypt(o.uri));
}
handleOnError(e) {
let pickerError = new PickerError();
pickerError.functionName = e.functionName;
pickerError.errorCode = e.errorCode;
pickerError.message = e.errorMessage;
console.info('PhotoPickerComponent onReceive: onError: '
+ JSON.stringify(e));
if (this.onError) {
this.onError(pickerError);
}
console.info('PhotoPickerComponent onReceive: onError: pickerError '
+ JSON.stringify(pickerError));
}
parseIsMovingPhotoBadgeShown(isMovingPhotoBadgeShown) {
console.log('PhotoPickerComponent, isMovingPhotoBadgeShownValid=' + isMovingPhotoBadgeShownValid
+ ',isMovingPhotoBadgeShown=' + isMovingPhotoBadgeShown);
if (isMovingPhotoBadgeShown === undefined || void 0 === isMovingPhotoBadgeShown) {
return undefined;
}
if (isMovingPhotoBadgeShown === true) {
this.isMovingPhotoBadgeShownValid = true;
} else {
this.isMovingPhotoBadgeShownValid = false;
}
return isMovingPhotoBadgeShown;
}
private handleVideoPlayStateChange(wantParam: Record<string, Object>): void {
if (this.onVideoPlayStateChanged) {
this.onVideoPlayStateChanged(wantParam.state as VideoPlayerState);
}
console.info('PhotoPickerComponent onReceive: onVideoPlayStateChanged = ' + JSON.stringify(wantParam));
}
private handleCreateCallback(wantParam: Record<string, Object>): void {
this.pickerController.actionCreateCallback(wantParam['grantUri'] as string, wantParam['date'] as number,
wantParam['code'] as number, wantParam['message'] as string);
console.info('PhotoPickerComponent onReceive: handleCreateCallback');
}
private handleReplaceCallback(wantParam: Record<string, Object>): void {
this.pickerController.actionReplaceCallback(wantParam['date'] as number,
{ 'name': '', 'code': wantParam['code'] as number, 'message': wantParam['message'] as string });
console.info('PhotoPickerComponent onReceive: handleReplaceCallback');
}
private handleSaveCallback(wantParam: Record<string, Object>): void {
this.pickerController.actionSaveCallback(wantParam['date'] as number,
{ 'name': '', 'code': wantParam['code'] as number, 'message': wantParam['error'] as string },
wantParam['data'] as Array<string>);
console.info('PhotoPickerComponent onReceive: handleSaveCallback');
}
private handleCompletedCallback(wantParam: Record<string, Object>): void {
this.pickerController.actionCompleteCallback(wantParam['date'] as number,
{ 'name': '', 'code': wantParam['code'] as number, 'message': wantParam['message'] as string },
wantParam['data'] as Array<string>, 'data': wantParam['data']);
console.info('PhotoPickerComponent onReceive: handleCompletedCallback');
}
private parseAutoPlayScenes(autoPlayScenes?: Array<photoAccessHelper.AutoPlayScene>): Array<photoAccessHelper.AutoPlayScene> | undefined {
if (!autoPlayScenes) {
return undefined;
}
if (autoPlayScenes.length > 2) {
return autoPlayScenes.slice(0, 2);
}
return autoPlayScenes;
}
private parseAppAlbumFilters(appAlbumFilters?: Array<string>): Array<string> | undefined {
if (!appAlbumFilters) {
return undefined;
}
if (appAlbumFilters.length > 3) {
return appAlbumFilters.slice(0, 3);
}
return appAlbumFilters;
}
parseMimeTypeFilter(filter?: photoAccessHelper.MimeTypeFilter): object | undefined {
if (!filter) {
return undefined;
}
let MimeTypeFilterObj: photoAccessHelper.MimeTypeFilter = {
mimeTypeArray: [],
};
if (filter.mimeTypeArray) {
for (let mimeType of filter.mimeTypeArray) {
if (PHOTO_VIEW_MIME_TYPE_MAP.has(mimeType)) {
o.mimeTypeArray.push(PHOTO_VIEW_MIME_TYPE_MAP.get(mimeType));
} else {
o.mimeTypeArray.push(mimeType);
}
}
}
return MimeTypeFilterObj;
}
private convertMIMETypeToFilterType(mimeType: photoAccessHelper.PhotoViewMIMETypes): string {
let filterType: string;
if (PHOTO_VIEW_MIME_TYPE_MAP.has(filterType)) {
filterType = PHOTO_VIEW_MIME_TYPE_MAP.get(mimeType);
}
else {
filterType = PHOTO_VIEW_MIME_TYPE_MAP.get('*/*');
}
console.info('PhotoPickerComponent convertMIMETypeToFilterType: ' + JSON.stringify(filterType));
return filterType;
}
private getSingleLineConfig(singleLineConfig: SingleLineConfig): SingleLineConfig | undefined {
if (singleLineConfig === null || singleLineConfig === undefined) {
return undefined;
}
singleLineConfig.itemDisplayRatio = (singleLineConfig.itemDisplayRatio === null ||
singleLineConfig.itemDisplayRatio === undefined) ? ItemDisplayRatio.SQUARE_RATIO :
singleLineConfig.itemDisplayRatio;
singleLineConfig.itemBorderRadius = this.getSingleLineConfigItemBorderRadius(singleLineConfig.itemBorderRadius);
singleLineConfig.itemGap = this.getLength(singleLineConfig.itemGap);
return singleLineConfig;
}
private getSingleLineConfigItemBorderRadius(itemBorderRadius?: Length | BorderRadiuses |
LocalizedBorderRadiuses): Length | BorderRadiuses | LocalizedBorderRadiuses {
if (itemBorderRadius === undefined || itemBorderRadius === null) {
return 0;
}
if (typeof itemBorderRadius === 'number' || typeof itemBorderRadius === 'string') {
return itemBorderRadius;
}
if (this.hasOwnProp(itemBorderRadius, ['topStart', 'topEnd', 'bottomStart', 'bottomEnd'])) {
const localizedBorderRadiuses: LocalizedBorderRadiuses = {
topStart: LengthMetrics.vp(0),
topEnd: LengthMetrics.vp(0),
bottomStart: LengthMetrics.vp(0),
bottomEnd: LengthMetrics.vp(0),
};
const itemBorderRadiusValue = itemBorderRadius as LocalizedBorderRadiuses;
localizedBorderRadiuses.topStart = itemBorderRadiusValue.topStart ? itemBorderRadiusValue.topStart :
LengthMetrics.vp(0);
localizedBorderRadiuses.topEnd = itemBorderRadiusValue.topEnd ? itemBorderRadiusValue.topEnd :
LengthMetrics.vp(0);
localizedBorderRadiuses.bottomStart = itemBorderRadiusValue.bottomStart ? itemBorderRadiusValue.bottomStart :
LengthMetrics.vp(0);
localizedBorderRadiuses.bottomEnd = itemBorderRadiusValue.bottomEnd ? itemBorderRadiusValue.bottomEnd :
LengthMetrics.vp(0);
return localizedBorderRadiuses;
}
if (this.hasOwnProp(itemBorderRadius, ['topLeft', 'topRight', 'bottomLeft', 'bottomRight'])) {
const borderRadiuses: BorderRadiuses = {
topLeft: 0,
topRight: 0,
bottomLeft: 0,
bottomRight: 0
};
const borderRadiusesValue = itemBorderRadius as BorderRadiuses;
borderRadiuses.topLeft = this.getLength(borderRadiusesValue.topLeft);
borderRadiuses.topRight = this.getLength(borderRadiusesValue.topRight);
borderRadiuses.bottomLeft = this.getLength(borderRadiusesValue.bottomLeft);
borderRadiuses.bottomRight = this.getLength(borderRadiusesValue.bottomRight);
return borderRadiuses;
}
const borderRadiusesValue = itemBorderRadius as Resource;
const resource = LengthMetrics.resource(borderRadiusesValue);
if (LengthUnitUtils.getInstance().isValid(resource)) {
return LengthUnitUtils.getInstance().stringify(resource);
}
return 0;
}
getLength(prop?: Length): Length {
if (prop === undefined || prop === null) {
return 0;
}
if (typeof prop === 'number' || typeof prop === 'string') {
return prop;
}
const resource = LengthMetrics.resource(prop);
if (LengthUnitUtils.getInstance().isValid(resource)) {
return LengthUnitUtils.getInstance().stringify(resource);
}
return 0;
}
private hasOwnProp(obj: Object, props: string[]): boolean {
for (const key of Object.keys(obj)) {
if (props.includes(key)) {
return true;
}
}
return false;
}
}
class LengthUnitUtils {
private static instance: LengthUnitUtils;
private constructor() {
}
public static getInstance(): LengthUnitUtils {
if (!LengthUnitUtils.instance) {
LengthUnitUtils.instance = new LengthUnitUtils();
}
return LengthUnitUtils.instance;
}
public stringify(metrics: LengthMetrics): string {
if (null === metrics || undefined === metrics || typeof metrics !== 'object' || null === metrics.unit ||
undefined === metrics.unit || null === metrics.value || undefined === metrics.value) {
return '0vp';
}
switch (metrics.unit) {
case LengthUnit.PX:
return `${metrics.value}px`;
case LengthUnit.VP:
return `${metrics.value}vp`;
case LengthUnit.FP:
return `${metrics.value}fp`;
case LengthUnit.PERCENT:
return `${metrics.value}%`;
case LengthUnit.LPX:
return `${metrics.value}lpx`;
default:
return '0vp';
}
}
public isValid(metrics: LengthMetrics): boolean {
if (null === metrics || undefined === metrics || typeof metrics !== 'object' ||
null === metrics.value || undefined === metrics.value) {
return false;
}
return metrics.value > 0;
}
}
export type ItemsDeletedCallback = (baseItemInfos: Array<BaseItemInfo>) => void;
export type ExceedMaxSelectedCallback = (exceedMaxCountType: MaxCountType) => void;
export type CurrentAlbumDeletedCallback = () => void;
export type VideoPlayStateChanged = (state: VideoPlayerState) => {} void;
export type onScrollStopAtStartCallback = () => void;
export type onScrollStopAtEndCallback = () => void;
@Observed
export class PickerController {
data?: Map<string, Object>;
replaceCallbackMap: Map<number, Object> = new Map<number, Object>();
saveCallbackMap: Map<number, Object> = new Map<number, Object>();
createCallbackMap: Map<number, Object> = new Map<number, Object>();
saveCallbackPromises: Map<number, Object> = new Map<number, Object>();
getMovingPhotoState?: () => PhotoStateProps;
completedPromises: Map<number, Object> = new Map<number, Object>();
setData(type: DataType, data: Object) {
if (data === undefined) {
return;
}
if (type === DataType.SET_SELECTED_URIS) {
if (data instanceof Array) {
let uriLists: Array<string> = data as Array<string>;
if (uriLists) {
this.data = new Map([['SET_SELECTED_URIS', [...uriLists]]]);
console.info('PhotoPickerComponent SET_SELECTED_URIS' + this.encrypt(JSON.stringify(uriLists)));
}
}
} else if (type === DataType.SET_ALBUM_URI) {
let albumUri: string = data as string;
if (albumUri !== undefined) {
this.data = new Map([['SET_ALBUM_URI', albumUri]]);
console.info('PhotoPickerComponent SET_ALBUM_URI' + this.encrypt(JSON.stringify(albumUri)));
}
} else if (type === DataType.SET_BADGE_CONFIGS) {
let uris: string = data as string;
if (uris !== undefined) {
this.data = new Map([['SET_BADGE_CONFIGS', uris], ['BADGE_CONFIGS_OPTION_TYPE',BadgeOptionType.SET_DATA]]);
console.info('PhotoPickerComponent SET_BADGE_CONFIGS' + this.encrypt(JSON.stringify(uris)));
} else if (type === DataType.SET_SELECTED_INFO) {
let uriAndPickerIndexLists: Array<PreselectedInfo> = data as Array<PreselectedInfo>;
if (uriAndPickerIndexLists !== undefined) {
this.data = new Map([['SET_SELECTED_INFO', uriAndPickerIndexLists]]);
console.info('PhotoPickerComponent SET_SELECTED_INFO' + this.encrypt(JSON.stringify(uriAndPickerIndexLists)));
}
} else {
console.info('PhotoPickerComponent setData: other case');
}
}
addData(type: DataType, data: Object) {
if (data === undefined) {
return;
}
if (type === DataType.SET_BADGE_CONFIGS) {
let uris = data as string;
if (uris !== undefined) {
this.data = new Map([['SET_BADGE_CONFIGS', e], ['BADGE_CONFIGS_OPTION_TYPE', BadgeOptionType.ADD_DATA]]);
}
return;
} else if (type === DataType.SET_ITEM_CLICK_RESULT) {
let clickResults: Array<ClickResult> = data as Array<ClickResult>;
if (clickResults !== undefined) {
this.data = new Map([['SET_ITEM_CLICK_RESULT', clickResults]]);
console.info('PhotoPickerComponent SET_ITEM_CLICK_RESULT' + this.encrypt(JSON.stringify(e)));
}
}
}
deleteData(type: DataType, data: Object) {
if (data === undefined) {
return;
}
if (type === DataType.SET_BADGE_CONFIGS) {
let uris = data as string;
if (uris !== undefined) {
this.data = new Map([['SET_BADGE_CONFIGS', e], ['BADGE_CONFIGS_OPTION_TYPE', BadgeOptionType.DELETE_DATA]]);
}
return;
}
}
async setMovingPhotoState(e) {
if (e !== MovingPhotoBadgeStateType.ADD_DATA && e !== MovingPhotoBadgeStateType.DELETE_DATA) {
throw new BusinessError(PARAMETERS_VALIDATE_FAILED_MESSAGE, PARAMETERS_VALIDATE_FAILED_CODE);
}
const props: PhotoStateProps = this.getMovingPhotoState();
console.info('SET_MOVINGPHOTO_STATE, props.isPhotoBrowserShow : ' + JSON.stringify(props.isPhotoBrowserShow) +
', props.isMovingPhotoBadgeShownValid=' + props.isMovingPhotoBadgeShownValid);
if (!props.isPhotoBrowserShow || props.isMovingPhotoBadgeShownValid) {
throw new BusinessError(ILLEGAL_SCENARIO_CALL_ERROR_MESSAGE, ILLEGAL_SCENARIO_CALL_ERROR_CODE);
}
if (e !== undefined) {
this.data = new Map([['SET_MOVINGPHOTO_STATE', e]]);
console.info('PhotoPickerComponent SET_MOVINGPHOTO_STATE: ' + this.encrypt(JSON.stringify(e)));
}
}
setMaxSelected(maxSelected: MaxSelected) {
if (maxSelected) {
this.data = new Map([['SET_MAX_SELECT_COUNT', maxSelected]]);
console.info('PhotoPickerComponent SET_MAX_SELECT_COUNT' + JSON.stringify(maxSelected));
}
}
async completed(): Promise<CompletedResult> {
return new Promise<CompletedResult>((resolve: (result: CompletedResult) => void,
reject: (reason: Error) => void) => {
let date: number = Math.random();
this.data = new Map<string, Object>([
['COMPLETED', {}],
['COMPLETE_DATE', date]
]);
this.completedPromises.set(date, [resolve, reject]);
console.info('PhotoPickerComponent COMPLETED');
});
}
updatePickerOptions(updateConfig: UpdatablePickerConfigs): Promise<void> {
return new Promise((resolve, reject) => {
if (e !== undefined) {
this.data = new Map([['UPDATE_CONFIG', updateConfig]]);
const bundleInfo = bundleManager.getBundleInfoForSelfSync(
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION
);
console.info('PhotoPickerComponent UPDATE_CONFIG bundleName: ' + bundleInfo.name + ', config: ' + JSON.stringify(updateConfig));
}
resolve();
});
}
setPhotoBrowserItem(uri: string, photoBrowserRange?: PhotoBrowserRange) {
let photoBrowserRangeInfo: PhotoBrowserRangeInfo = new PhotoBrowserRangeInfo();
photoBrowserRangeInfo.uri = uri;
let newPhotoBrowserRange = photoBrowserRange ? photoBrowserRange : PhotoBrowserRange.ALL;
photoBrowserRangeInfo.photoBrowserRange = newPhotoBrowserRange;
this.data = new Map([['SET_PHOTO_BROWSER_ITEM', photoBrowserRangeInfo]]);
console.info('PhotoPickerComponent SET_PHOTO_BROWSER_ITEM' + this.encrypt(JSON.stringify(photoBrowserRangeInfo)));
}
exitPhotoBrowser() {
this.data = new Map([['EXIT_PHOTO_BROWSER', true]]);
console.info('PhotoPickerComponent EXIT_PHOTO_BROWSER');
}
setPhotoBrowserUIElementVisibility(elements: Array<PhotoBrowserUIElement>, isVisible?: boolean) {
let photoBrowserUIElementVisibility: PhotoBrowserUIElementVisibility = new PhotoBrowserUIElementVisibility();
photoBrowserUIElementVisibility.elements = elements;
photoBrowserUIElementVisibility.isVisible = isVisible;
this.data = new Map([['SET_PHOTO_BROWSER_UI_ELEMENT_VISIBILITY', photoBrowserUIElementVisibility]]);
console.info('PhotoPickerComponent SET_PHOTO_BROWSER_UI_ELEMENT_VISIBILITY ' +
JSON.stringify(photoBrowserUIElementVisibility));
}
private async getAppName(): Promise<string> {
let flags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_ABILITY | // for appName
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_HAP_MODULE | // for appName
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_SIGNATURE_INFO | // for appId
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION; // for appInfo
let bundleInfo = bundleManager.getBundleInfoForSelfSync(flags);
let labelId = bundleInfo.appInfo.labelId;
let appName = '';
let moduleName = '';
for (let hapInfo of bundleInfo.hapModulesInfo) {
if (labelId === hapInfo.labelId) {
moduleName = hapInfo.name;
}
}
appName = await getContext(this).createModuleContext(moduleName).resourceManager.getStringValue(labelId);
return appName;
}
replacePhotoPickerPreview(selectedMediaUri: string, replaceUri: string, callback: AsyncCallback<void>) {
try {
let fd = fs.openSync(replaceUri).fd;
fs.close(fd);
} catch (err) {
callback({'code': 13900002, 'message': 'No such file', name: ''});
return;
}
let date = Math.random();
this.data = new Map([['CREATE_URI', [selectedMediaUri, replaceUri, date]]]);
this.createCallbackMap.set(date, (grantUri: string, code: number, message: string) => {
if (code !== 0) {
callback({ 'name': '', 'code': code, 'message': message });
return;
}
let createFd = 0;
let replaceFd = 0;
try {
createFd = fs.openSync(grantUri, fs.OpenMode.READ_WRITE).fd;
replaceFd = fs.openSync(replaceUri, fs.OpenMode.READ_ONLY).fd;
fs.copyFileSync(replaceFd, createFd);
this.data = new Map([['REPLACE_URI', [selectedMediaUri, grantUri, date]]]);
this.replaceCallbackMap.set(date, callback);
} catch (err) {
callback({ 'code': 14000011, 'message': 'System inner fail', name: '' });
} finally {
fs.close(createFd);
fs.close(replaceFd);
}
})
}
saveTrustedPhotoAssets(selectedMediaUris: Array<string>, callback: AsyncCallback<Array<string>>,
config?: Array<photoAccessHelper.PhotoCreationConfig>, saveMode?: SaveMode) {
if (!selectedMediaUris || selectedMediaUris.length === 0) {
callback({'code': 14000002, 'message': 'Invalid URI', name: ''}, []);
return;
}
this.getAppName().then((appName: string)=>{
let date = Math.random();
this.data = new Map([['SAVE_TRUSTED_PHOTO_ASSETS', [selectedMediaUris, config, saveMode, appName, date]]]);
this.saveCallbackMap.set(date, callback);
})
console.info('PhotoPickerComponent SAVE_TRUSTED_PHOTO_ASSETS ');
}
saveTrustedPhotoAssetsEx(selectedMediaUris: Array<string>, settings?: Array<photoAccessHelper.CreationSetting>,
saveMode?: SaveMode): Promise<Array<string>> {
return new Promise((resolve, reject) => {
if (!selectedMediaUris || selectedMediaUris.length === 0) {
reject({ 'code': 14000002, 'message': 'Invalid URI', name: '' });
return;
}
this.getAppName().then((appName: string) => {
let date = Math.random();
this.data = new Map([['SAVE_TRUSTED_PHOTO_ASSETS', [selectedMediaUris, settings, saveMode, appName, date]]]);
this.saveCallbackPromises.set(date, [resolve, reject]);
});
console.info('PhotoPickerComponent SAVE_TRUSTED_PHOTO_ASSETS_EX');
});
}
actionCreateCallback(grantUri: string, date: number, code: number, message: string) {
if (this.createCallbackMap.has(date)) {
let callback = this.createCallbackMap.get(date) as Function;
if (callback) {
callback(grantUri, code, message);
this.createCallbackMap.delete(date);
}
}
}
actionReplaceCallback(date: number, err: BusinessError) {
if (this.replaceCallbackMap.has(date)) {
let callback = this.replaceCallbackMap.get(date) as Function;
if (callback) {
callback(err);
this.replaceCallbackMap.delete(date);
}
}
}
actionSaveCallback(date: number, err: BusinessError, data: Array<string>) {
if (this.saveCallbackMap.has(date)) {
let callback = this.saveCallbackMap.get(date) as Function;
if (callback) {
callback(err, data);
this.saveCallbackMap.delete(date);
}
}
if (this.saveCallbackPromises.has(date)) {
let promiseFunc = this.saveCallbackPromises.get(date) as [Function, Function];
if (promiseFunc) {
if (err) {
promiseFunc[1](err);
} else {
promiseFunc[0](data);
}
this.saveCallbackPromises.delete(date);
}
}
}
actionCompleteCallback(date: number, err: Error, data: CompletedResult | undefined): void {
if (this.completedPromises.has(date)) {
let promiseFunc = this.completedPromises.get(date);
if (promiseFunc) {
if (data) {
promiseFunc[0](data);
} else {
promiseFunc[1](err);
}
this.completedPromises.delete(date);
}
}
}
encrypt(data) {
if (!data || data?.indexOf('file:///data/storage/') !== -1) {
return '';
}
let encryptedData = data.replace(/(\/[\w()%+-]+)\./g, '/******.');
encryptedData = encryptedData.replace(/"userComment":"([^"]|\")*"/g, '"userComment":"******"');
encryptedData = encryptedData.replace(/"albumName":"([^"]|\")*"/g, '"albumName":"******"');
encryptedData = encryptedData.replace(/"displayName":"([^"]|\")*"/g, '"displayName":"******"');
return encryptedData;
}
}
export class PickerOptions extends photoAccessHelper.BaseSelectOptions {
checkBoxColor?: string;
backgroundColor?: string;
isRepeatSelectSupported?: boolean;
checkboxTextColor?: string;
photoBrowserBackgroundColorMode?: PickerColorMode;
maxSelectedReminderMode?: ReminderMode;
orientation?: PickerOrientation;
selectMode?: SelectMode;
maxPhotoSelectNumber?: number;
maxVideoSelectNumber?: number;
isSlidingSelectionSupported?: boolean;
photoBrowserCheckboxPosition?: [number, number];
gridMargin?: Margin;
photoBrowserMargin?: Margin;
singleLineConfig?: SingleLineConfig;
uiComponentColorMode?: PickerColorMode;
combinedMediaTypeFilter?: Array<string>;
pickerIndex?: number;
preselectedInfos?: Array<PreselectedInfo>;
backgroundOpacity?: number;
}
export class UpdatablePickerConfigs {
mimeType?: photoAccessHelper.PhotoViewMIMETypes;
mimeTypeFilter?: photoAccessHelper.MimeTypeFilter;
maxSelectNumber?: number;
maxPhotoSelectNumber?: number;
maxVideoSelectNumber?: number;
selectMode?: SelectMode;
singleSelectionMode?: photoAccessHelper.SingleSelectionMode;
isRepeatSelectSupported?: boolean;
preselectedUris?: Array<string>;
checkBoxColor?: string;
checkboxTextColor?: string;
backgroundColor?: string;
photoBrowserBackgroundColorMode?: PickerColorMode,
uiComponentColorMode?: PickerColorMode;
appAlbumFilters?: Array<string>;
backgroundOpacity?: number;
}
export class GridPinchMode {
constructor() {
this.gridPinchModeType = undefined;
this.defaultGridLevel = GridLevel.STANDARD;
}
}
export class BaseItemInfo {
uri?: string;
mimeType?: string;
width?: number;
height?: number;
size?: number;
duration?: number;
movingPhotoBadgeState?: MovingPhotoBadgeStateType;
}
export class ItemInfo extends BaseItemInfo {
itemType?: ItemType;
}
export class PhotoBrowserInfo {
animatorParams?: AnimatorParams;
}
export class AnimatorParams {
duration?: number;
curve?: Curve | ICurve | string;
}
export class MaxSelected {
data?: Map<MaxCountType, number>;
}
export declare class CompletedResult {
photoUris: Array<string>;
contextRecoveryInfo: ContextRecoveryInfo;
movingPhotoBadgeStates: Array<MovingPhotoBadgeStateType>;
}
export class ContextRecoveryInfo {
albumUri: string;
time: number;
displayName: string;
recommendationType: int;
selectedRecommendationType: int;
version: int;
gridLevel?: GridLevel;
sortRule?: string;
fileSize?: int;
}
export class SingleLineConfig {
itemDisplayRatio?: ItemDisplayRatio;
itemBorderRadius?: Length | BorderRadiuses | LocalizedBorderRadiuses;
itemGap?: Length;
constructor() {
this.itemDisplayRatio = ItemDisplayRatio.SQUARE_RATIO;
this.itemBorderRadius = 0;
this.itemGap = 0;
}
}
class PhotoBrowserRangeInfo {
uri?: string;
photoBrowserRange?: PhotoBrowserRange;
}
class PhotoBrowserUIElementVisibility {
elements?: Array<PhotoBrowserUIElement>;
isVisible?: boolean;
}
export class BadgeConfig {
badgeConfigType?: BadgeTypes,
uris?: string[]
}
class PreselectedInfo {
uri:string;
preselectablePickerIndex?: number = -1;
}
class ClickResult {
uri: string;
isSelected: boolean;
}
class LivePhotoMode {
isAutoPlay: boolean;
sceneType: SceneType;
}
export enum DataType {
SET_SELECTED_URIS = 1,
SET_ALBUM_URI = 2,
SET_SELECTED_INFO = 3,
SET_ITEM_CLICK_RESULT = 5
}
export enum GridPinchModeType {
FULL_FUNCTION_GRID = 0,
}
export enum GridLevel {
SPACIOUS = 0,
STANDARD = 1,
COMPACT = 2,
}
export enum ItemType {
THUMBNAIL = 0,
CAMERA = 1
}
export enum ClickType {
SELECTED = 0,
DESELECTED = 1
}
export enum PickerOrientation {
VERTICAL = 0,
HORIZONTAL = 1
}
export enum SelectMode {
SINGLE_SELECT = 0,
MULTI_SELECT = 1
}
export enum PickerColorMode {
AUTO = 0,
LIGHT = 1,
DARK = 2
}
export enum ReminderMode {
NONE = 0,
TOAST = 1,
MASK = 2
}
export enum MaxCountType {
TOTAL_MAX_COUNT = 0,
PHOTO_MAX_COUNT = 1,
VIDEO_MAX_COUNT = 2
}
export enum PhotoBrowserRange {
ALL = 0,
SELECTED_ONLY = 1
}
export enum PhotoBrowserUIElement {
CHECKBOX = 0,
BACK_BUTTON = 1
}
export enum VideoPlayerState {
PLAYING = 0,
PAUSED = 1,
STOPPED = 2,
SEEK_START = 3,
SEEK_FINISH = 4
}
export enum SaveMode {
SAVE_AS = 0,
OVERWRITE = 1
}
export enum ItemDisplayRatio {
SQUARE_RATIO = 0,
ORIGINAL_SIZE_RATIO = 1
}
export enum BadgeTypes {
BADGE_UPLOADED = 1
}
export enum BadgeOptionType {
SET_DATA = 1,
ADD_DATA = 2,
DELETE_DATA = 3
}
export enum SingleSelectMode {
BROWSER_MODE = 0,
SELECT_MODE = 1,
BROWSER_AND_SELECT_MODE = 2
}
export enum MovingPhotoBadgeStateType {
NOT_MOVING_PHOTO = 0,
MOVING_PHOTO_ENABLED = 1,
MOVING_PHOTO_DISABLED = 2
}
export enum SceneType {
GRID_TO_PHOTO_BROWSER = 0;
PHOTO_BROWSER_SWIPE = 1;
}