• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 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 '@system.router';
17import { Log } from '@ohos/base/src/main/ets/utils/Log';
18import { Action } from '../../../common/view/browserOperation/Action';
19import { Constants } from '../../../common/model/common/Constants';
20import { RouterConstants } from '@ohos/base/src/main/ets/constants/RouterConstants';
21import { ThirdSelectPhotoBrowserActionBar } from '../../../common/view/ThirdSelectPhotoBrowserActionBar';
22import { PhotoBrowserBg } from '@ohos/browser/src/main/ets/components/PhotoBrowserBg';
23import { Constants as PhotoConstants } from '@ohos/browser/src/main/ets/constants/Constants';
24import { Broadcast } from '@ohos/base/src/main/ets/utils/Broadcast';
25import { BroadcastConstants } from '@ohos/base/src/main/ets/constants/BroadcastConstants';
26import broadcastManager from '@ohos/base/src/main/ets/manager/BroadcastManager';
27import { PhotoSwiper } from '@ohos/browser/src/main/ets/components/PhotoSwiper';
28import mMultimodalInputManager from '@ohos/base/src/main/ets/manager/MultimodalInputManager';
29import screenManager from '@ohos/base/src/main/ets/manager/ScreenManager';
30import { SimpleAlbumDataItem } from '@ohos/base/src/main/ets/data/SimpleAlbumDataItem';
31import { GroupItemDataSource } from '@ohos/base/src/main/ets/vm/GroupItemDataSource';
32import { MediaDataItem } from '@ohos/base/src/main/ets/data/MediaDataItem';
33import { terminateSelfWithResult } from '@ohos/base/src/main/ets/utils/AbilityUtils';
34
35const TAG = "SelectPhotoBrowser"
36// select mode
37@Entry
38@Component
39struct SelectPhotoBrowser {
40    @Provide browserBackgroundColor: Resource = $r('app.color.default_background_color');
41    @Provide('selectedCount') totalSelectedCount: number = 0;
42    @Provide broadCast: Broadcast = new Broadcast();
43    @Provide isSelected: boolean = true;
44    @Provide isShowBar: boolean = true;
45    @Provide isPullingDown: boolean = false;
46    @Provide moreMenuList: Array<Action> = new Array<Action>();
47    @Provide pageFrom: number = RouterConstants.ENTRY_FROM.NORMAL;
48    @Provide canSwipe: boolean = true;
49    isMultiPick = true;
50    selectPhotoTransition: string;
51    controller: SwiperController = new SwiperController();
52
53    // swiper currentIndex, there may not be onChanged callback during data refresh, so mediaItem cannot be saved
54    @Provide('transitionIndex') currentIndex: number = 0;
55
56    // The global Broadcast of the application process. Event registration and destruction should be paired
57    private appBroadcast: Broadcast = broadcastManager.getBroadcast();
58    private browserDataSource: GroupItemDataSource = new GroupItemDataSource();
59
60    aboutToAppear(): void {
61        Log.info(TAG, 'photoBrowser aboutToAppear');
62        screenManager.setNavigationBarColor('#FFF1F3F5', '#FF000000');
63        this.browserBackgroundColor = $r('app.color.black');
64        mMultimodalInputManager.registerListener((control: number) => {
65            Log.info(TAG, `key control : ${control} index ${this.currentIndex}`);
66            if (control == 0) {
67                if (this.currentIndex > 0) {
68                    this.onPhotoChanged(this.currentIndex - 1);
69                }
70            } else if (control == 1) {
71                if (this.currentIndex < this.browserDataSource.totalCount() - 1) {
72                    this.onPhotoChanged(this.currentIndex + 1);
73                }
74            } else {
75                this.onBackPress();
76            }
77        });
78        let param = router.getParams();
79        if (param.pageFrom) {
80            this.pageFrom = new Number(param.pageFrom).valueOf() || 0;
81        }
82        if (this.pageFrom == RouterConstants.ENTRY_FROM.DISTRIBUTED) {
83            this.browserDataSource.setDeviceId(param.deviceId ? param.deviceId.toString() : '');
84        }
85
86        if (this.isMultiPick == true) {
87            this.totalSelectedCount = this.browserDataSource.getSelectedCount();
88        }
89        if (param.albumInfo) {
90            this.browserDataSource.setAlbumId((param.albumInfo as SimpleAlbumDataItem).id);
91        }
92
93        this.browserDataSource.groupDataItem = AppStorage.Get(Constants.APP_KEY_PHOTO_BROWSER);
94        this.onPhotoChanged(new Number(param.position).valueOf() || 0);
95        this.isSelected = this.getCurrentPhoto().isSelect;
96        this.totalSelectedCount = this.browserDataSource.getSelectedCount();
97        this.selectPhotoTransition = param.transition ? param.transition.toString() : '';
98        this.onMenuClicked = this.onMenuClicked.bind(this);
99
100        // register event handling
101        this.broadCast.on(PhotoConstants.TOGGLE_BAR, (event) => {
102            Log.info(TAG, `TOGGLE_BAR : ${JSON.stringify(event)}`);
103        });
104
105        this.broadCast.on(PhotoConstants.PULL_DOWN_END, (event) => {
106            Log.info(TAG, `PULL_DOWN_END : ${JSON.stringify(event)}`);
107            this.onBackPress();
108        });
109
110        this.broadCast.on(PhotoConstants.DATA_SIZE_CHANGED, (size: number) => {
111            this.onDataSizeChanged(size);
112        });
113
114        this.broadCast.on(PhotoConstants.DATA_CONTENT_CHANGED, (size: number) => {
115            // onContentChanged only the current item is updated
116            Log.info(TAG, `DATA_CONTENT_CHANGED : ${size}`);
117            this.onPhotoChanged(this.currentIndex);
118        });
119
120        this.broadCast.on(PhotoConstants.SET_DISABLE_SWIPE, (value: boolean) => {
121            Log.info(TAG, `set swiper swipe ${value}`);
122            this.canSwipe = value;
123        });
124    }
125
126    aboutToDisappear(): void {
127        screenManager.setNavigationBarColor('#00FFFFFF', '#FF000000');
128        this.broadCast.release();
129        mMultimodalInputManager.unregisterListener();
130    }
131
132    onToggleBars() {
133    }
134
135    onDataSizeChanged(size: number): void {
136        Log.info(TAG, `onDataSizeChanged, size is ${size}`);
137        if (size == 0) {
138            this.onBackPress();
139        }
140    }
141
142    onPhotoChanged(index: number): void{
143        this.currentIndex = index;
144        this.isSelected = this.getCurrentPhoto().isSelect;
145        this.browserDataSource.notifyDataChange(index);
146    }
147
148    private selectStateChange() {
149        Log.info(TAG, 'change selected');
150        let currentPhoto = this.getCurrentPhoto();
151        if (currentPhoto == undefined) {
152            return;
153        }
154        currentPhoto.setSelect(!currentPhoto.isSelect);
155        this.isSelected = currentPhoto.isSelect;
156        this.totalSelectedCount = this.browserDataSource.getSelectedCount();
157        this.appBroadcast.emit(BroadcastConstants.UPDATE_DATA_SOURCE, [currentPhoto]);
158        Log.info(TAG, `totalSelectedCount: ${this.totalSelectedCount} after state change`);
159    }
160
161    onPageShow() {
162        Log.info(TAG, 'onPageShow');
163        this.appBroadcast.emit(BroadcastConstants.THIRD_ROUTE_PAGE, []);
164    }
165
166    onPageHide() {
167        Log.info(TAG, 'onPageHide');
168    }
169
170    onMenuClicked(action: Action) {
171        Log.debug(TAG, `onMenuClicked, action: ${action.actionID}`);
172        switch (action) {
173            case Action.BACK:
174                this.onBackPress();
175                return;
176            case Action.MATERIAL_SELECT:
177            case Action.SELECTED:
178                this.selectStateChange();
179                return;
180            case Action.OK:
181                Log.info(TAG, 'click OK');
182                this.setPickResult();
183                break;
184            default:
185                break;
186        }
187    }
188
189    getCurrentPhoto(): MediaDataItem {
190        return this.browserDataSource.groupDataItem[this.currentIndex];
191    }
192
193    onBackPress() {
194        Log.info(TAG, 'onBackPress');
195        router.back({ params: { index: this.currentIndex } });
196        return true;
197    }
198
199    build() {
200        Stack({ alignContent: Alignment.TopStart }) {
201            PhotoBrowserBg()
202            PhotoSwiper({
203                dataSource: this.browserDataSource,
204                photoSwiperTransition: this.selectPhotoTransition,
205                onPhotoChanged: this.onPhotoChanged.bind(this),
206                swiperController: this.controller
207            })
208            ThirdSelectPhotoBrowserActionBar({
209                isMultiPick: this.isMultiPick,
210                onMenuClicked: this.onMenuClicked
211            }).sharedTransition("selectPhotoBrowserActionBar", {
212                type: SharedTransitionEffectType.Static,
213                duration: Constants.SHARE_TRANSITION_DURATION,
214                zIndex: 2,
215            })
216        }
217    }
218
219    private setPickResult(): void {
220        let uriArray: string[];
221        if (this.isMultiPick) {
222            uriArray = this.browserDataSource.getSelectedUris();
223            Log.debug(TAG, `uri size: ${uriArray}`);
224        } else {
225            let currentPhoto = this.getCurrentPhoto();
226            if (currentPhoto == undefined) {
227                return;
228            }
229            uriArray = [currentPhoto.uri];
230        }
231        let abilityResult = {
232            'resultCode': 0,
233            'want': {
234                'parameters': {
235                    'select-item-list': uriArray
236                }
237            }
238        };
239        terminateSelfWithResult(abilityResult);
240    }
241
242    pageTransition() {
243        PageTransitionEnter({ type: RouteType.None, duration: PhotoConstants.PAGE_SHOW_ANIMATION_DURATION })
244            .opacity(0)
245        PageTransitionExit({ duration: PhotoConstants.PAGE_SHOW_ANIMATION_DURATION })
246            .opacity(0)
247    }
248}
249