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  Action,
19  ActionBarProp,
20  AlbumDefine,
21  AlbumSetDataInfo,
22  AlbumSetDataSource,
23  BroadCast,
24  BroadCastConstants,
25  BroadCastManager,
26  CommonObserverCallback,
27  Constants,
28  Log,
29  MediaObserver,
30  ScreenManager,
31  ThirdSelectManager,
32  UiUtil,
33  UserFileManagerAccess
34} from '@ohos/common';
35import { NoPhotoIndexComponent } from '@ohos/common/CommonComponents';
36import { ThirdAlbumGridItem } from './ThirdAlbumGridItem';
37import { ThirdSelectedPageActionBar } from './ThirdSelectedPageActionBar';
38import { IS_SIDE_BAR, IS_SPLIT_MODE, LEFT_BLANK, SelectParams } from '../utils/ThirdSelectConstants';
39
40const TAG: string = 'thiSel_ThirdSelectAlbumPageBase';
41
42interface Params {
43  bundleName: string;
44  isMultiPick: boolean;
45  isFromFa: boolean;
46  isFromFaPhoto: boolean;
47  filterMediaType?: string;
48  isFirstEnter: boolean;
49  isFromWallpaper: boolean;
50  remainingOfWallpapers: number;
51  maxSelectCount: number;
52};
53
54// Third Select AlbumSet Page
55@Component
56export struct ThirdSelectAlbumPageBase {
57  @State isEmpty: boolean = false;
58
59  @State totalSelectedCount: number = 0;
60  @Provide broadCast: BroadCast = new BroadCast();
61  private albums: AlbumSetDataSource = new AlbumSetDataSource(this.broadCast);
62  @Provide isSelectedMode: boolean = true;
63  @Provide moreMenuList: Action[] = [];
64  selectManager?: ThirdSelectManager;
65  @Provide gridColumnsCount: number = 3;
66  isActive = false;
67  @StorageLink(IS_SPLIT_MODE) isSplitMode: boolean = ScreenManager.getInstance().isSplitMode();
68  @StorageLink(LEFT_BLANK) leftBlank: number[] =
69    [0, ScreenManager.getInstance().getStatusBarHeight(), 0, ScreenManager.getInstance().getNaviBarHeight()];
70  @StorageLink(IS_SIDE_BAR) isSidebar: boolean = ScreenManager.getInstance().isSidebar();
71  dataObserver: CommonObserverCallback = new CommonObserverCallback(this);
72  @State title: string = '';
73  isFirstEnter: boolean = false;
74  @Prop @Watch('onPageChanged') pageStatus: boolean = false;
75  @Provide selectParams: SelectParams = SelectParams.defaultParam();
76  scroller: Scroller = new Scroller();
77  private appBroadCast: BroadCast = BroadCastManager.getInstance().getBroadCast();
78  private initGridRowCountFunc: Function = (): void => this.initGridRowCount();
79  private onLoadingFinishedFunc: Function = (size: number): void => this.onLoadingFinished(size);
80
81  private onLoadingFinished(size: number): void {
82    Log.info(TAG, `ON_LOADING_FINISHED size: ${size}`);
83    if (size === 1 && this.albums?.mediaSetList[0].albumName === AlbumDefine.ALBUM_ID_RECYCLE) {
84      this.isEmpty = true;
85    } else {
86      this.isEmpty = size == 0;
87    }
88  }
89
90  aboutToAppear(): void {
91    this.albums = new AlbumSetDataSource(this.broadCast);
92    let param: Params = router.getParams() as Params;
93    this.initSelectParams(param);
94    if (this.selectParams.isFromFa) {
95      this.selectParams.filterMediaType = AlbumDefine.FILTER_MEDIA_TYPE_IMAGE;
96    }
97    if (this.selectParams.filterMediaType == AlbumDefine.FILTER_MEDIA_TYPE_IMAGE) {
98      let userFile: UserFileManagerAccess = UserFileManagerAccess.getInstance();
99      this.albums.setBlackList([userFile.getSystemAlbumUri(UserFileManagerAccess.TRASH_ALBUM_SUB_TYPE),
100      userFile.getSystemAlbumUri(UserFileManagerAccess.VIDEO_ALBUM_SUB_TYPE),
101      userFile.getSystemAlbumUri(UserFileManagerAccess.FAVORITE_ALBUM_SUB_TYPE)]);
102    }
103    this.albums.setFilterMediaType(this.selectParams.filterMediaType);
104    this.selectManager = AppStorage.get<ThirdSelectManager>(Constants.THIRD_SELECT_MANAGER) as ThirdSelectManager;
105    Log.debug(TAG, `select params ${JSON.stringify(this.selectParams)}`);
106    this.broadCast.on(Constants.ON_LOADING_FINISHED, this.onLoadingFinishedFunc);
107    if (this.selectParams.isMultiPick) {
108      this.selectManager.registerCallback('thirdSelectUpdateCount', (newState: number) => {
109        Log.info(TAG, `thirdSelectUpdateCount ${newState}`);
110        this.totalSelectedCount = newState;
111      });
112    }
113    MediaObserver.getInstance().registerObserver(this.dataObserver);
114    this.initGridRowCount();
115    // 后续phone缩略图支持横竖屏后再放开
116    if (AppStorage.get('deviceType') as string !== Constants.DEFAULT_DEVICE_TYPE) {
117      ScreenManager.getInstance().on(ScreenManager.ON_WIN_SIZE_CHANGED, this.initGridRowCountFunc);
118    }
119    let titleRes = ActionBarProp.SINGLE_TAB_ALBUM_TITLE;
120    UiUtil.getResourceString(titleRes).then((stringResource) => {
121      this.title = stringResource;
122    })
123  }
124
125  onPageChanged() {
126    if (this.pageStatus) {
127      this.onPageShow();
128    } else {
129      this.onPageHide();
130    }
131  }
132
133  onPageShow() {
134    Log.debug(TAG, 'onPageShow');
135    MediaObserver.getInstance().registerObserver(this.dataObserver);
136    this.appBroadCast.emit(BroadCastConstants.THIRD_ROUTE_PAGE, []);
137    this.onActive();
138  }
139
140  aboutToDisappear() {
141    if (this.broadCast) {
142      this.broadCast.off(Constants.ON_LOADING_FINISHED, this.onLoadingFinishedFunc);
143    }
144    ScreenManager.getInstance().off(ScreenManager.ON_WIN_SIZE_CHANGED, this.initGridRowCountFunc);
145    MediaObserver.getInstance().unregisterObserver(this.dataObserver);
146    this.dataObserver.clearSource();
147  }
148
149  onMediaLibDataChange(changeType: string): void {
150    Log.info(TAG, `onMediaLibDataChange type: ${changeType}`);
151    this.albums?.onChange(changeType);
152  }
153
154  onPageHide() {
155    Log.debug(TAG, 'onPageHide');
156    this.onInActive();
157  }
158
159  onActive() {
160    if (!this.isActive) {
161      Log.info(TAG, 'onActive');
162      this.isActive = true;
163      this.albums && this.albums.onActive();
164    }
165  }
166
167  onInActive() {
168    if (this.isActive) {
169      Log.info(TAG, 'onInActive');
170      this.isActive = false;
171      this.albums && this.albums.onInActive();
172    }
173  }
174
175  onMenuClicked(action: Action) {
176    Log.info(TAG, `onMenuClicked, action: ${action.actionID}`);
177    if (action.actionID === Action.BACK.actionID) {
178      router.back();
179    }
180  }
181
182  @Builder
183  buildItem(item: AlbumSetDataInfo) {
184    ThirdAlbumGridItem({
185      item: item.data,
186      isFirstEnter: this.isFirstEnter
187    })
188  }
189
190  build() {
191    Flex({
192      direction: FlexDirection.Column,
193      justifyContent: FlexAlign.Start,
194      alignItems: ItemAlign.Start
195    }) {
196      ThirdSelectedPageActionBar({
197        leftAction: Action.BACK,
198        isSelectPhotoGrid: false,
199        title: $title,
200        onMenuClicked: (action: Action): void => this.onMenuClicked(action),
201        totalSelectedCount: $totalSelectedCount
202      })
203      Stack() {
204        if (this.isEmpty) {
205          NoPhotoIndexComponent({ index: Constants.ALBUM_PAGE_INDEX, hasBarSpace: false })
206        }
207        Grid(this.scroller) {
208          LazyForEach(this.albums, (item: AlbumSetDataInfo, index?: number) => {
209            if (item.data.albumName != AlbumDefine.ALBUM_ID_RECYCLE) {
210              GridItem() {
211                this.buildItem(item)
212              }
213            }
214          }, (item: AlbumSetDataInfo) => 'uri:' + item.data.uri)
215        }
216        .edgeEffect(EdgeEffect.Spring)
217        .scrollBar(BarState.Auto)
218        .columnsTemplate('1fr '.repeat(this.gridColumnsCount))
219        .padding({
220          left: $r('sys.float.ohos_id_card_margin_start'),
221          right: $r('sys.float.ohos_id_card_margin_end'),
222          top: $r('app.float.album_set_page_padding_top'),
223          bottom: $r('sys.float.ohos_id_default_padding_bottom_fixed')
224        })
225        .columnsGap($r('sys.float.ohos_id_card_margin_middle'))
226        .rowsGap($r('sys.float.ohos_id_elements_margin_vertical_l'))
227      }
228    }
229    .backgroundColor($r('sys.color.ohos_id_color_sub_background'))
230    .padding({
231      top: this.leftBlank[1],
232      bottom: this.leftBlank[3]
233    })
234  }
235
236  private initSelectParams(param: Params | null): void {
237    if (param != null) {
238      this.selectParams.bundleName = param.bundleName;
239      this.selectParams.isMultiPick = param.isMultiPick;
240      if (param.isFromFa != undefined || param.isFromFa != null) {
241        this.selectParams.isFromFa = param.isFromFa;
242      }
243      if (param.isFromFaPhoto != undefined || param.isFromFaPhoto != null) {
244        this.selectParams.isFromFaPhoto = param.isFromFaPhoto;
245      }
246      if (param.filterMediaType != undefined || param.filterMediaType != null) {
247        this.selectParams.filterMediaType = param.filterMediaType;
248      }
249      if (param.isFirstEnter != undefined || param.isFirstEnter != null) {
250        this.isFirstEnter = param.isFirstEnter;
251      }
252      this.selectParams.isFromWallpaper = param.isFromWallpaper;
253      if (this.selectParams.isFromWallpaper) {
254        this.selectParams.maxSelectCount = param.remainingOfWallpapers;
255      } else if (!!param.maxSelectCount && param.maxSelectCount > 0) {
256        this.selectParams.maxSelectCount = param.maxSelectCount > Constants.LIMIT_MAX_THIRD_SELECT_COUNT
257          ? Constants.LIMIT_MAX_THIRD_SELECT_COUNT
258          : param.maxSelectCount;
259      }
260      Log.info(TAG, `select param ${JSON.stringify(this.selectParams)}`);
261    }
262  }
263
264  private initGridRowCount(): void {
265    this.gridColumnsCount = UiUtil.getAlbumGridCount(false);
266    Log.info(TAG, `the grid count in a line is: ${this.gridColumnsCount}`);
267  }
268}