• 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 { ImageGridItemComponent } from '@ohos/base/src/main/ets/components/ImageGridItemComponent';
19import { Action } from '../../../common/view/browserOperation/Action';
20import { ActionBar } from '../../../common/view/actionbar/ActionBar';
21import { ActionBarProp } from '../../../common/view/browserOperation/ActionBarProp';
22import { Broadcast } from '@ohos/base/src/main/ets/utils/Broadcast';
23import { BroadcastConstants } from '@ohos/base/src/main/ets/constants/BroadcastConstants';
24import { Constants } from '../../../common/model/common/Constants';
25import { NoPhotoComponent } from '../../../common/view/NoPhotoComponent';
26import screenManager from '@ohos/base/src/main/ets/manager/ScreenManager';
27import { GridScrollBar } from '@ohos/base/src/main/ets/components/scrollBar/GridScrollBar';
28import broadcastManager from '@ohos/base/src/main/ets/manager/BroadcastManager';
29import { ThirdSelectBarModel } from '../model/ThirdSelectBarModel';
30import { GroupItemDataSource } from '@ohos/base/src/main/ets/vm/GroupItemDataSource';
31import { MediaDataItem } from '@ohos/base/src/main/ets/data/MediaDataItem';
32import { MediaConstants } from '@ohos/base/src/main/ets/constants/MediaConstants';
33import { terminateSelfWithResult } from '@ohos/base/src/main/ets/utils/AbilityUtils';
34import { LazyItem } from '@ohos/base/src/main/ets/vm/ItemDataSource';
35import { CameraGridItemComponent } from './CameraGridItemComponent'
36import { SelectUtil } from '@ohos/base/src/main/ets/utils/SelectUtil';
37import { ThirdSelectedPanel } from './ThirdSelectedPanel';
38import { showToast } from '@ohos/base/src/main/ets/utils/UiUtil';
39import { getResourceString } from '@ohos/base/src/main/ets/utils/ResourceUtils';
40// Third Select Album Page
41
42const TAG = "ThirdSelectPhotoGridPage"
43
44@Entry
45@Component
46struct ThirdSelectPhotoGridPage {
47    @Provide @Watch('updateActionBar') selectedCount: number = 0;
48    @Provide('isSelectedMode') @Watch('updateActionBar') isMultiPick: boolean = false;
49    @Provide moreMenuList: Array<Action> = new Array<Action>();
50    @Provide broadCast: Broadcast = new Broadcast();
51    @Provide isShow: boolean = true;
52    isActive = false;
53    title: any;
54    @State isEmpty: boolean = false;
55    @StorageLink('isSplitMode') isSplitMode: boolean = screenManager.isSplitMode();
56    @StorageLink('leftBlank') leftBlank: [number, number, number, number] = [0, 0, 0, 0];
57    DEFAULT_TOAST_DURATION = 2000;
58    isFromWallpaper: boolean;
59    @Provide @Watch('updateActionBar') maxSelectCount: number = Constants.DEFAULT_MAX_THIRD_SELECT_COUNT;
60    @State gridRowCount: number = 0;
61    @State isHideScrollBar: boolean = true;
62    isFromFa: boolean = false;
63    isFromFaPhoto: boolean = false;
64    scroller: Scroller = new Scroller();
65    private appBroadcast: Broadcast = broadcastManager.getBroadcast();
66    private barModel: ThirdSelectBarModel = new ThirdSelectBarModel();
67    private groupDataSource: GroupItemDataSource = new GroupItemDataSource();
68    private albumId: string;
69    @State actionBarProp: ActionBarProp = new ActionBarProp();
70    bundleName: string = "";
71    filterMediaType: number = MediaConstants.SELECT_TYPE_ALL;
72    isSelectPhotoGrid: boolean = true;
73    @Provide isOriginalChecked: boolean = false;
74    @State isSelectUpperLimited: boolean = false;
75
76    updateActionBar(): void {
77        this.actionBarProp = this.barModel.createActionBar(this.bundleName == "" ? Action.BACK : Action.CANCEL, this.title, this.isMultiPick,
78                                                    this.selectedCount, this.maxSelectCount, this.isSelectPhotoGrid);
79    }
80
81    onMenuClicked(action: Action) {
82        Log.info(TAG, `onMenuClicked, action: ${action.actionID}`);
83        switch (action) {
84            case Action.BACK:
85                router.back();
86            case Action.CANCEL:
87                Log.info(TAG, 'click cancel');
88                let abilityResult = {
89                    'resultCode': 0,
90                    'want': {
91                        'parameters': {
92                            'select-item-list': []
93                        }
94                    }
95                };
96                terminateSelfWithResult(abilityResult)
97                break;
98            case Action.OK:
99                this.setPickResult();
100                break;
101            case Action.NAVIGATION_ALBUMS:
102                router.push({
103                    uri: 'feature/thirdSelect/view/ThirdSelectAlbumSetPage',
104                    params: {
105                        isMultiPick: this.isMultiPick,
106                        isFromFa: this.isFromFa,
107                        isFromFaPhoto: true,
108                    }
109                });
110                break;
111            default:
112                break;
113        }
114    }
115
116    private initGridRowCount(): void {
117        let contentWidth = screenManager.getWinWidth();
118        let margin = 0;
119        let maxThumbWidth = px2vp(Constants.GRID_IMAGE_SIZE) * Constants.GRID_MAX_SIZE_RATIO;
120        this.gridRowCount = Math.max(Constants.GRID_MIN_COUNT, Math.ceil(((contentWidth - Constants.NUMBER_2 * margin)
121        + Constants.GRID_GUTTER) / (maxThumbWidth + Constants.GRID_GUTTER)));
122        Log.info(TAG, `initGridRowCount contentWidth: ${contentWidth}`);
123    }
124
125    aboutToAppear(): void {
126        let param = router.getParams();
127        if (param != null) {
128            Log.info(TAG, `itemId: ${param.itemId}`);
129            this.title = param.itemDisplayName;
130            if (param.itemId) {
131                this.groupDataSource.setAlbumId(param.itemId.toString());
132                this.albumId = param.itemId.toString()
133            }
134            this.bundleName = new String(param.bundleName).valueOf();
135            this.isMultiPick = new Boolean(param.isMultiPick).valueOf();
136            this.isFromFa = new Boolean(param.isFromFa).valueOf();
137            this.isFromFaPhoto = new Boolean(param.isFromFaPhoto).valueOf();
138            if (!!param.maxSelectCount && param.maxSelectCount > 0) {
139                this.maxSelectCount = new Number(param.maxSelectCount).valueOf() || 0
140            }
141            if (param.filterMediaType) {
142                this.filterMediaType = new Number(param.filterMediaType).valueOf();
143                Log.info(TAG, `filterMediaType: ${this.filterMediaType}`)
144            }
145        }
146        if (this.isFromFa || this.isFromFaPhoto) {
147            this.filterMediaType = MediaConstants.SELECT_TYPE_IMAGE;
148            AppStorage.SetOrCreate(Constants.FORM_ITEM_NAME, param.itemName);
149            AppStorage.SetOrCreate(Constants.FORM_ITEM_ALBUM_ID, param.itemId);
150            AppStorage.SetOrCreate(Constants.FORM_ITEM_DISPLAY_NAME, param.itemDisplayName);
151        }
152        if(this.maxSelectCount) {
153            this.filterMediaType = MediaConstants.SELECT_TYPE_IMAGE;
154        }
155        this.groupDataSource.setSelectType(this.filterMediaType);
156        Log.info(TAG, `ThirdSelectPhotoGridPage isMultiPick: ${this.isMultiPick},\
157                isFromWallpaper: ${param.isFromWallpaper}, maxSelectCount: ${this.maxSelectCount}, filterMediaType: ${this.filterMediaType}`);
158        this.groupDataSource.reloadGroupItemData(true).then((isEmpty: boolean) => {
159            this.isEmpty = isEmpty;
160            this.selectedCount = this.groupDataSource.getSelectedCount();
161            this.groupDataSource.notifyDataReload();
162            this.isHideScrollBar = (this.groupDataSource.totalCount() <= Constants.GRID_SCROLL_BAR_VISIBLE_THRESHOLD)
163        })
164        this.initGridRowCount();
165
166        this.onMenuClicked = this.onMenuClicked.bind(this);
167        this.broadCast.on(BroadcastConstants.SELECT, (index: number) => this.onSelect(index));
168        this.broadCast.on(BroadcastConstants.JUMP_THIRD_PHOTO_BROWSER, (name: string, item: MediaDataItem) => {
169            this.jumpToThirdPhotoBrowser(name, item);
170        })
171        this.broadCast.on(Constants.ON_LOADING_FINISHED,
172            (size: number) => {
173                Log.info(TAG, `ON_LOADING_FINISHED size: ${size}`);
174                this.isEmpty = size == 0;
175                Log.info(TAG, `isEmpty: ${this.isEmpty}`)
176            });
177        this.isActive = true;
178
179        this.updateActionBar();
180    }
181
182    onPageShow() {
183        this.appBroadcast.emit(BroadcastConstants.THIRD_ROUTE_PAGE, []);
184        this.isShow = true;
185        this.onActive();
186    }
187
188    onPageHide() {
189        this.isShow = false;
190        this.onInActive();
191    }
192
193    private onActive() {
194        if (!this.isActive) {
195            Log.info(TAG, 'onActive');
196            this.isActive = true;
197        }
198    }
199
200    private onInActive() {
201        if (this.isActive) {
202            Log.info(TAG, 'onInActive');
203            this.isActive = false;
204        }
205    }
206
207    private async onSelect(index: number) {
208        Log.info(TAG, "onSelect");
209        let lastSelectedCount = this.selectedCount;
210        this.selectedCount = this.groupDataSource.getSelectedCount();
211        if (lastSelectedCount == this.selectedCount && this.selectedCount >= this.maxSelectCount) {
212            let toastMsg = await getResourceString($r('app.string.up_to_limit_tips'));
213            showToast(toastMsg);
214            return;
215        }
216        this.isSelectUpperLimited = this.selectedCount >= this.maxSelectCount;
217        this.groupDataSource.onDataUpdate(index);
218    }
219
220    private jumpToThirdPhotoBrowser(name: string, item: MediaDataItem) {
221        let children: MediaDataItem[] = this.groupDataSource.getItems();
222        let targetIndex = children.indexOf(item);
223        if (targetIndex == Constants.NOT_FOUND) {
224            Log.warn(TAG, 'targetIndex is not found');
225            return;
226        }
227        AppStorage.SetOrCreate(Constants.APP_KEY_PHOTO_BROWSER, children);
228        router.push({
229            uri: 'feature/thirdSelect/view/ThirdSelectPhotoBrowser',
230            params: {
231                position: targetIndex,
232                bundleName: this.bundleName,
233                transition: name,
234                isFromFa: this.isFromFa,
235                albumId: this.albumId,
236                isMultiPick: this.isMultiPick,
237                isSelectUpperLimited: this.isSelectUpperLimited
238            }
239        })
240    }
241
242    aboutToDisappear(): void {
243        this.broadCast.off(null, null);
244    }
245
246    build() {
247        Column() {
248            ActionBar({
249                actionBarProp: $actionBarProp,
250                onMenuClicked: this.onMenuClicked
251            })
252            if (this.isEmpty && this.isFromFa) {
253                NoPhotoComponent({ title: $r('app.string.no_distributed_photo_head_title_album') })
254            }
255            Grid(this.scroller) {
256                if (!this.isFromFa) {
257                    GridItem() {
258                        CameraGridItemComponent({
259                            bundleName: this.bundleName,
260                            filterMediaType: this.filterMediaType
261                        })
262                    }
263                    .aspectRatio(1)
264                }
265                LazyForEach(this.groupDataSource, (item: LazyItem<MediaDataItem>) => {
266                    GridItem() {
267                        ImageGridItemComponent({
268                            lazyItem: item,
269                            mediaItem: item.get(),
270                            pageName: Constants.PHOTO_TRANSITION_ALBUM,
271                            isThird: true,
272                            isSelectUpperLimited: $isSelectUpperLimited
273                        })
274                    }
275		    .aspectRatio(1)
276                }, (item: LazyItem<MediaDataItem>) => item == null && item.get() ? JSON.stringify(item) : item.getHashCode())
277            }
278            .columnsTemplate('1fr '.repeat(this.gridRowCount))
279            .columnsGap(Constants.GRID_GUTTER)
280            .rowsGap(Constants.GRID_GUTTER)
281            .cachedCount(Constants.GRID_CACHE_ROW_COUNT)
282            .layoutWeight(1)
283
284            if (this.isMultiPick) {
285                Column() {
286                    ThirdSelectedPanel({
287                        onMenuClicked: this.onMenuClicked,
288                        groupDataSource: this.groupDataSource
289                    })
290                }
291                .width("100%")
292                .height($r('app.float.third_selected_panel_height'))
293            }
294
295            GridScrollBar({ scroller: this.scroller, isHideScrollBar: $isHideScrollBar});
296        }
297        .backgroundColor($r('app.color.default_background_color'))
298        .padding({
299            top: px2vp(this.leftBlank[1]),
300            bottom: px2vp(this.leftBlank[3])
301        })
302    }
303
304    private setPickResult(): void {
305        let uriArray = this.groupDataSource.getSelectedUris()
306        let abilityResult = {
307            'resultCode': 0,
308            'want': {
309                'parameters': {
310                    'select-item-list': uriArray,
311                    'isOriginal': this.isOriginalChecked
312                }
313            }
314        };
315        Log.info(TAG, `uri: ${uriArray}`)
316        let self = this;
317        if (uriArray == null && uriArray == undefined) {
318            globalThis.appContext.terminateSelfWithResult(abilityResult).then((result) => {
319                Log.info(TAG, `terminateSelfWithResult result: ${result}`);
320            });
321        } else {
322            SelectUtil.grantPermissionForUris(uriArray, self.bundleName);
323            try {
324                Log.info(TAG, `grant permission success.`);
325                globalThis.appContext.terminateSelfWithResult(abilityResult).then((result) => {
326                    Log.info(TAG, `terminateSelfWithResult result: ${result}`);
327                });
328            } catch (err) {
329                Log.info(TAG, `grant permission error: ${JSON.stringify(err)}`);
330            }
331        }
332    }
333}
334