1/* 2 * Copyright (c) 2022-2023 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 */ 15 16import router from '@ohos.router'; 17import { 18 AlbumDefine, 19 BigDataConstants, 20 BroadCast, 21 BroadCastConstants, 22 BroadCastManager, 23 ColumnSize, 24 Constants as Cons, 25 DataStoreUtil, 26 Log, 27 ReportToBigDataUtil, 28 ScreenManager, 29 UiUtil, 30 UserFileManagerAccess, 31 WindowUtil 32} from '@ohos/common'; 33import { Constants, FormControllerManager } from '@ohos/formAbility'; 34import formBindingData from '@ohos.application.formBindingData'; 35import formProvider from '@ohos.application.formProvider'; 36import userFileManager from '@ohos.filemanagement.userFileManager'; 37import common from '@ohos.app.ability.common'; 38import { BusinessError } from '@ohos.base'; 39import { Router } from '@ohos.arkui.UIContext'; 40 41 42const TAG: string = 'FormEditorPage'; 43declare type UnionType = number | boolean | string; 44declare type DisplayNameUnionType = Resource | string; 45 46@Entry 47@Component 48struct FormEditorPage { 49 @StorageLink('FASetting_FormId') formId: string = '0'; 50 @StorageLink('isHorizontal') isHorizontal: boolean = ScreenManager.getInstance().isHorizontal(); 51 @StorageLink('isSidebar') isSidebar: boolean = ScreenManager.getInstance().isSidebar(); 52 @StorageLink('leftBlank') leftBlank: number[] = 53 [0, ScreenManager.getInstance().getStatusBarHeight(), 0, ScreenManager.getInstance().getNaviBarHeight()]; 54 currentIndex: number = 0; 55 @State isShowName: boolean = true; 56 isShowAlbums: boolean = true; 57 fd: number = Constants.FA_FD_NULL; 58 fileAsset: userFileManager.FileAsset | null = null; 59 displayName: string = ''; 60 albumUri: string = ''; 61 uri: string = ''; 62 @State time: number = 30; 63 private appBroadCast: BroadCast = BroadCastManager.getInstance().getBroadCast(); 64 private saveDataFunc = async ( 65 albumName: string, albumUri: string, displayName: DisplayNameUnionType, uri: string, isShowAlbums: boolean 66 ): Promise<void> => await this.saveData(albumName, albumUri, displayName, uri, isShowAlbums); 67 private indexValue: number = 0; 68 @State private selectAlbumsStr: string = ''; 69 70 async getItems(albumUri?: string, startIndex?: number, count?: number, filterMediaType?: string): 71 Promise<Array<userFileManager.FileAsset>> { 72 let result: userFileManager.FileAsset[] = []; 73 74 // Get from target album if albumUri is not undefined, otherwise getAllObject 75 if (albumUri) { 76 let album: userFileManager.Album = 77 await UserFileManagerAccess.getInstance().getAlbumByUri(albumUri) as userFileManager.Album; 78 let fetchOpt = AlbumDefine.getFileFetchOpt(startIndex, count, filterMediaType); 79 let fetchResult = await album.getPhotoAssets(fetchOpt); 80 result = await fetchResult.getAllObject(); 81 fetchResult.close(); 82 } else { 83 let fetchOpt = AlbumDefine.getFileFetchOpt(startIndex, count, filterMediaType); 84 Log.debug(TAG, `getMediaItem start ${JSON.stringify(fetchOpt)}`); 85 result = await UserFileManagerAccess.getInstance().getAllObject(fetchOpt); 86 } 87 return result; 88 } 89 90 async GetMediaData(albumUri: string, uri: string): Promise<void> { 91 Log.debug(TAG, `GetMediaData start uri: ${uri} albumUri: ${albumUri}`); 92 let dataList = await this.getItems(albumUri); 93 if (uri != '') { 94 for (let i = 0; i < dataList.length; i++) { 95 let temUri = dataList[i].uri; 96 if (temUri === uri) { 97 this.currentIndex = i; 98 break; 99 } 100 } 101 } else { 102 this.currentIndex = 0; 103 } 104 this.fileAsset = dataList[this.currentIndex]; 105 Log.debug(TAG, 'GetMediaData fileAsset: ' + JSON.stringify(this.fileAsset)); 106 } 107 108 async openCurrentFd(): Promise<void> { 109 this.fd = (this.fileAsset != null) ? await UserFileManagerAccess.getInstance().openAsset('R', this.fileAsset) as number 110 : Constants.FA_FD_NULL; 111 } 112 113 bindFormData(): formBindingData.FormBindingData { 114 Log.debug(TAG, `bindFormData start formId: ${this.formId}`); 115 let image: string = 'image_' + this.fd + '_formId_' + this.formId + '_uri_' + this.uri; 116 interface DataObjectType { 117 fd: boolean; 118 image0: string; 119 image1: string; 120 albumName: string; 121 currentIndex: number; 122 isShow: boolean; 123 formImages: object; 124 uri: string; 125 albumUri: string; 126 currentUri: string; 127 } 128 let dataObj1: DataObjectType = { 129 fd: this.fd != Constants.FA_FD_NULL, 130 image0: 'memory://' + image, 131 image1: 'memory://' + image, 132 albumName: this.displayName, 133 currentIndex: this.currentIndex, 134 isShow: Boolean(this.isShowName) && Boolean(this.isShowAlbums), 135 formImages: JSON.parse(`{ "${image}": ${this.fd} }`) as object, 136 uri: (this.uri != '') ? Cons.ACTION_URI_FORM_ABILITY : Cons.ACTION_URI_FORM_ABILITY_NONE, 137 albumUri: `${this.albumUri}`, 138 currentUri: this.uri 139 }; 140 Log.debug(TAG, `bindFormData, createFormBindingData dataObj2.data: ${JSON.stringify(dataObj1)}`); 141 let obj = formBindingData.createFormBindingData(JSON.stringify(dataObj1)); 142 Log.debug(TAG, `bindFormData, createFormBindingData obj2.data: ${JSON.stringify(obj.data)}`); 143 return obj; 144 } 145 146 terminate(): void { 147 let context: common.UIAbilityContext = AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext; 148 context.terminateSelf((result: BusinessError<void>) => { 149 Log.info(TAG, `terminateSelf result: ${JSON.stringify(result)}`); 150 }) 151 } 152 153 async updateFormData(): Promise<void> { 154 Log.debug(TAG, `updateFormData formId: ${JSON.stringify(this.formId)}`); 155 let dataStore = DataStoreUtil.getInstance(); 156 await dataStore.init(); 157 let temp: number = await dataStore.getData(Constants.FA_INDEX_VALUE, 0) as number; 158 this.indexValue = (temp + 1) % 2; 159 await dataStore.putData(Constants.FA_INDEX_VALUE, this.indexValue); 160 await dataStore.flush(); 161 let obj3 = this.bindFormData(); 162 Log.debug(TAG, `updateFormData obj: ${JSON.stringify(obj3)}`); 163 formProvider.updateForm(this.formId, obj3) 164 .then((): void => { 165 Log.debug(TAG, 'updateFormData, success'); 166 this.terminate(); 167 }).catch((error: BusinessError) => { 168 Log.error(TAG, `updateForm failed. Cause: ${JSON.stringify(error)}`); 169 interface Msg { 170 err: string; 171 } 172 let msg: Msg = { 173 err: JSON.stringify(error) 174 } 175 ReportToBigDataUtil.errEventReport(BigDataConstants.CHANGE_FA_CARD_IMAGE_ERROR, msg); 176 this.terminate(); 177 }); 178 } 179 180 async saveData(albumName: string, albumUri: string, displayName: DisplayNameUnionType, 181 uri: string, isShowAlbums: boolean): Promise<void> { 182 Log.debug(TAG, `saveData start! ${albumUri} ${displayName} ${uri}`); 183 ReportToBigDataUtil.report(BigDataConstants.CHANGE_FA_CARD_IMAGE_ID, undefined); 184 let msgDisplayName = ''; 185 if (displayName instanceof Object) { 186 Log.debug(TAG, `saveData object ${displayName}`); 187 msgDisplayName = await UiUtil.getResourceString(displayName as Resource) as string; 188 } else { 189 msgDisplayName = displayName as string; 190 } 191 this.isShowAlbums = isShowAlbums; 192 this.displayName = msgDisplayName; 193 this.albumUri = albumUri; 194 this.uri = uri; 195 Log.debug(TAG, `saveData msgDisplayName ${msgDisplayName}`); 196 await DataStoreUtil.getInstance().init(); 197 await this.GetMediaData(albumUri, uri); 198 await this.openCurrentFd(); 199 let formIdKey = 'formId_' + this.formId; 200 let hasFormId = await DataStoreUtil.getInstance().hasData(formIdKey); 201 Log.debug(TAG, `The value of hasFormId is ${hasFormId}`); 202 if (hasFormId) { 203 let displayNameKey = 'displayName_' + this.formId; 204 await DataStoreUtil.getInstance().putData(displayNameKey, msgDisplayName); 205 let albumNameKey = 'albumName_' + this.formId; 206 await DataStoreUtil.getInstance().putData(albumNameKey, albumName); 207 let albumUriKey = 'albumUri_' + this.formId; 208 await DataStoreUtil.getInstance().putData(albumUriKey, albumUri); 209 let currentUriKey = 'currentUri_' + this.formId; 210 await DataStoreUtil.getInstance().putData(currentUriKey, uri); 211 let currentIndexKey = 'currentIndex_' + this.formId; 212 await DataStoreUtil.getInstance().putData(currentIndexKey, this.currentIndex); 213 await DataStoreUtil.getInstance().flush(); 214 this.updateFormData(); 215 } else { 216 let context: common.UIAbilityContext = AppStorage.get<common.UIAbilityContext>('photosAbilityContext') as common.UIAbilityContext; 217 context.terminateSelf((result: BusinessError<void>) => { 218 Log.info(TAG, `terminateSelf result: ${JSON.stringify(result)}`); 219 }) 220 } 221 Log.debug(TAG, 'saveData end!'); 222 } 223 224 routerPhotos(isSelectPhoto: boolean): void { 225 let albumUriKey = 'albumUri_' + this.formId; 226 DataStoreUtil.getInstance().getData(albumUriKey, '').then((theAlbumUri: UnionType) => { 227 let options: router.RouterOptions = { 228 url: 'pages/ThirdSelectPhotoGridPage', 229 params: { 230 itemCoverUri: '', 231 uri: theAlbumUri, 232 itemCount: 1, 233 bundleName: '', 234 isMultiPick: false, 235 filterMediaType: AlbumDefine.FILTER_MEDIA_TYPE_IMAGE, 236 maxSelectCount: 1, 237 itemDisplayName: $r('app.string.album_photos'), 238 isFromFa: isSelectPhoto, 239 isFromFaPhoto: isSelectPhoto, 240 isFirstEnter: true 241 } 242 }; 243 router.pushUrl(options); 244 }) 245 } 246 247 selectPhoto(): void { 248 this.routerPhotos(true); 249 } 250 251 aboutToAppear(): void { 252 Log.debug(TAG, 'aboutToAppear start!'); 253 ScreenManager.getInstance().setSystemUi(false); 254 this.appBroadCast.on(BroadCastConstants.SAVE_FORM_EDITOR_DATA, this.saveDataFunc); 255 } 256 257 aboutToDisappear() { 258 this.appBroadCast.off(BroadCastConstants.SAVE_FORM_EDITOR_DATA, this.saveDataFunc); 259 } 260 261 onPageShow() { 262 BroadCastManager.getInstance().getBroadCast().emit(BroadCastConstants.THIRD_ROUTE_PAGE, []); 263 } 264 265 onBackPress() { 266 this.terminate(); 267 } 268 269 build() { 270 Column() { 271 Row() { 272 Row() { 273 Image($r('app.media.ic_gallery_public_cancel')) 274 .fillColor($r('app.color.white')) 275 .width($r('app.float.ic_size_default')) 276 .height($r('app.float.ic_size_default')) 277 .margin({ left: $r('app.float.FA_back_margin_left') }) 278 } 279 .alignItems(VerticalAlign.Center) 280 .height($r('app.float.tab_bar_vertical_height')) 281 } 282 .padding({ 283 top: $r('app.float.album_set_page_action_bar_padding_top') 284 }) 285 .width('100%') 286 .onClick(() => { 287 this.onBackPress(); 288 }) 289 290 Column() { 291 Text($r('app.string.fa_title_text')) 292 .fontSize($r('sys.float.ohos_id_text_size_headline8')) 293 .fontColor($r('app.color.FA_title_text_color')) 294 .fontWeight(FontWeight.Medium) 295 296 Text($r('app.string.fa_subTitle_text')) 297 .fontSize($r('sys.float.ohos_id_text_size_body1')) 298 .margin({ top: $r('app.float.tab_bar_padding_top') }) 299 .fontColor($r('app.color.FA_subTitle_text_color')) 300 } 301 .margin({ top: $r('app.float.FA_subTitle_margin_top'), bottom: $r('app.float.FA_title_margin_bottom') }) 302 303 Row() { 304 Row() { 305 Text($r('app.string.fa_select_image_text')) 306 .fontWeight(FontWeight.Medium) 307 .fontSize($r('sys.float.ohos_id_text_size_body1')) 308 .fontColor($r('app.color.black')) 309 .flexGrow(Constants.FLEX_GROW) 310 Row() { 311 Image($r('app.media.ic_gallery_form_arrow')) 312 .width($r('app.float.form_list_card_more_arrow_w')) 313 .height($r('app.float.form_list_card_more_arrow_h')) 314 .fillColor($r('sys.color.ohos_id_color_fourth')) 315 } 316 } 317 .height($r('app.float.title_default')) 318 .width('100%') 319 .key('FASelectPhoto') 320 .padding({ 321 left: $r('app.float.FA_ListCard_padding_left'), right: $r('app.float.FA_ListCard_padding_left'), 322 }) 323 .backgroundColor($r('app.color.white')) 324 .borderRadius($r('app.float.FA_ListCard_radius')) 325 .onClick((): void => { 326 this.selectPhoto(); 327 }) 328 } 329 .padding({ left: $r('app.float.FA_select_album_padding'), right: $r('app.float.FA_select_album_padding') }) 330 } 331 .backgroundColor($r('app.color.FA_background_color')) 332 .width('100%') 333 .height('100%') 334 } 335}