1/* 2 * Copyright (c) 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 { Log } from '../../utils/Log'; 17import { Dispatch, OhCombinedState } from '../../redux/store'; 18import { getStore } from '../../redux/store'; 19import { Action } from '../../redux/actions/Action'; 20import { EventBus } from '../../worker/eventbus/EventBus'; 21import { EventBusManager } from '../../worker/eventbus/EventBusManager'; 22import ReportUtil from '../../utils/ReportUtil'; 23import { CameraService } from '../../camera/CameraService'; 24import { GlobalContext } from '../../utils/GlobalContext'; 25import Want from '@ohos.app.ability.Want'; 26 27class StateStruct { 28 thumbnail: Resource = $r('app.media.ic_camera_thumbnail_default_white'); 29} 30 31class UpdateThumbnailStruct { 32 thumbnail: PixelMap | undefined = undefined; 33 resourceUri: string = ''; 34} 35 36class ThumbnailStruct { 37 thumbnail: PixelMap | undefined = undefined; 38} 39 40class StartAbilityParameterStruct { 41 uri: string = ''; 42} 43 44class ThumbnailViewDispatcher { 45 private mDispatch: Dispatch = (data) => data; 46 47 public setDispatch(dispatch: Dispatch) { 48 this.mDispatch = dispatch; 49 } 50} 51 52@Component 53export struct ThumbnailView { 54 private TAG: string = '[ThumbnailView]:' 55 private appEventBus: EventBus = EventBusManager.getInstance().getEventBus() 56 @State thumbnailBorder: BorderOptions = {}; 57 @State state: StateStruct = new StateStruct() 58 @State thumbnail: Resource | PixelMap = $r('app.media.ic_camera_thumbnail_default_white') 59 @State hasThumbnail: boolean = false 60 @State scaleValue: number = 1 61 @State tempOpacity: number = 1 62 private cameraService = CameraService.getInstance() 63 private mAction: ThumbnailViewDispatcher = new ThumbnailViewDispatcher(); 64 65 private async onThumbnailUpdate(data: UpdateThumbnailStruct): Promise<void> { 66 Log.info(`${this.TAG} onThumbnailUpdate data: ${JSON.stringify(data)} E`) 67 this.thumbnail = (data.thumbnail == null ? $r('app.media.ic_camera_thumbnail_default_white') : data.thumbnail) 68 this.hasThumbnail = data.thumbnail != undefined 69 if (this.hasThumbnail) { 70 this.thumbnailBorder = { width: 1, color: Color.White, style: BorderStyle.Solid } 71 } else { 72 this.thumbnailBorder = { width: 0 } 73 } 74 this.scaleValue = 1.5 75 this.tempOpacity = 0.0 76 animateTo({ duration: 100, curve: Curve.Sharp }, () => { 77 this.tempOpacity = 1 78 }) 79 animateTo({ duration: 300, curve: Curve.Sharp }, () => { 80 this.scaleValue = 1 81 }) 82 Log.info(`${this.TAG} onThumbnailUpdate this.state.thumbnail: ${JSON.stringify(this.thumbnail)} X`) 83 } 84 85 private async onThumbnailLoad(data: ThumbnailStruct): Promise<void> { 86 Log.info(`${this.TAG} onThumbnailLoad data: ${JSON.stringify(data)} E`) 87 this.thumbnail = (data.thumbnail == null ? $r('app.media.ic_camera_thumbnail_default_white') : data.thumbnail) 88 this.hasThumbnail = data.thumbnail != undefined 89 if (this.hasThumbnail) { 90 this.thumbnailBorder = { width: 1, color: Color.White, style: BorderStyle.Solid } 91 } else { 92 this.thumbnailBorder = { width: 0 } 93 } 94 this.scaleValue = 1 95 this.tempOpacity = 1 96 Log.info(`${this.TAG} onThumbnailLoad this.state.thumbnail: ${JSON.stringify(this.thumbnail)} X`) 97 } 98 99 aboutToAppear() { 100 Log.info(`${this.TAG} aboutToAppear E`) 101 getStore().subscribe((state: OhCombinedState) => { 102 this.state = { 103 thumbnail: state.cameraInitReducer.thumbnail 104 }; 105 }, (dispatch: Dispatch) => { 106 this.mAction.setDispatch(dispatch); 107 }); 108 this.appEventBus.on(Action.ACTION_UPDATE_THUMBNAIL, (data: UpdateThumbnailStruct) => this.onThumbnailUpdate(data)); 109 this.appEventBus.on(Action.ACTION_LOAD_THUMBNAIL, (data: ThumbnailStruct) => this.onThumbnailLoad(data)); 110 Log.info(`${this.TAG} aboutToAppear X`) 111 } 112 113 aboutToDisappear(): void { 114 Log.info(`${this.TAG} aboutToDisappear E`) 115 this.appEventBus.off(Action.ACTION_UPDATE_THUMBNAIL, (data: UpdateThumbnailStruct) => this.onThumbnailUpdate(data)) 116 this.appEventBus.off(Action.ACTION_LOAD_THUMBNAIL, (data: ThumbnailStruct) => this.onThumbnailLoad(data)); 117 Log.info(`${this.TAG} aboutToDisappear X`) 118 } 119 120 build() { 121 Column() { 122 Stack() { 123 Image(this.thumbnail) 124 .width('100%').aspectRatio(1).borderRadius(22).objectFit(ImageFit.Fill) 125 } 126 .width('100%').height('100%') 127 .enabled(this.hasThumbnail) 128 .onClick(async () => { 129 Log.info(`${this.TAG} launch bundle com.ohos.photos`) 130 ReportUtil.write(ReportUtil.CLICK_THUMBNAIL) 131 GlobalContext.get().setObject('keepCameraZoomRatio', true); 132 const recentUri: string = this.cameraService.getRecentFileUri(); 133 Log.info(`${this.TAG} uri === ` + recentUri) 134 const abilityParameter: Record<string, string> = { 'uri': recentUri }; 135 await GlobalContext.get().getCameraAbilityContext().startAbility(this.buildCameraAbilityWant(abilityParameter)) 136 }) 137 } 138 .width(44) 139 .aspectRatio(1) 140 .borderRadius(22) 141 .border(this.thumbnailBorder) 142 .opacity(this.tempOpacity) 143 .scale({ x: this.scaleValue, y: this.scaleValue }) 144 } 145 146 private buildCameraAbilityWant(parameter: Record<string, string>): Want { 147 let res: Want = { 148 parameters: parameter, 149 action: 'ohos.want.action.viewData', 150 bundleName: 'com.ohos.photos', 151 abilityName: 'com.ohos.photos.MainAbility' 152 }; 153 return res; 154 } 155}