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}