• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
17  Action,
18  BroadCast,
19  BroadCastConstants,
20  Constants,
21  DateUtil,
22  Log,
23  MediaDataSource,
24  MediaItem,
25  ScreenManager,
26  ThirdSelectManager,
27  UserFileManagerAccess
28} from '@ohos/common';
29import { IS_HORIZONTAL, THIRD_SELECT_IS_ORIGIN, THUMBNAIL_WIDTH } from '../utils/ThirdSelectConstants';
30
31const TAG: string = 'thiSel_ThirdSelectedPanel';
32
33@Component
34export struct ThirdSelectedPanel {
35  onMenuClicked: Function;
36  maxSelectCount: number;
37  @Provide selectedCount: number = 0;
38  @Link @Watch('onSelectedCountChanged') totalSelectedCount: number;
39  selectManager: ThirdSelectManager;
40  @State itemArray: Array<MediaItem> = [];
41  @StorageLink(THIRD_SELECT_IS_ORIGIN) isOriginalChecked: boolean = false;
42  @StorageLink(IS_HORIZONTAL) isHorizontal: boolean = ScreenManager.getInstance().isHorizontal();
43  @Consume broadCast: BroadCast;
44  @Link isShowBar: boolean;
45  @Prop currentUri: string;
46  isBrowserMode: boolean = false;
47  isMultiPick = true;
48  mTransition: string = '';
49  isFromFa: boolean = false;
50  dataSource: MediaDataSource;
51  private selectedScroller: Scroller = new Scroller();
52
53  aboutToAppear(): void {
54    this.selectManager = AppStorage.Get(Constants.THIRD_SELECT_MANAGER);
55    this.onSelectedCountChanged();
56  }
57
58  onSelectedCountChanged() {
59    this.selectedCount = this.totalSelectedCount;
60    this.itemArray = this.selectManager.getSelectItems();
61    Log.debug(TAG, `call scroll to edge, current count ${this.itemArray.length}`)
62    this.selectedScroller.scrollEdge(Edge.End);
63  }
64
65  getThumbnailSafe(sourceUri: string, path: string, size?) {
66    try {
67      if (size) {
68        if (size.width != 0 && size.height != 0) {
69          return `${sourceUri}?oper=thumbnail&width=${size.width}&height=${size.height}&path=${path}`;
70        } else {
71          Log.warn(TAG, 'getThumbnailSafe with width==0 and height==0, so do not use thumbnail' + JSON.stringify(size));
72          return `${sourceUri}`;
73        }
74      } else {
75        return `${sourceUri}?oper=thumbnail&width=${THUMBNAIL_WIDTH}&height=${THUMBNAIL_WIDTH}&path=${path}`;
76      }
77    } catch (err) {
78      Log.warn(TAG, `get Thumbnail Failed! msg:${err}`);
79      return null;
80    }
81  }
82
83  @Builder buildRadio() {
84    if (this.isBrowserMode) {
85      Image(this.isOriginalChecked ? $r('app.media.picker_radio_selected') : $r('app.media.picker_radio_unselected'))
86        .key('Original')
87        .width($r('app.float.icon_size'))
88        .aspectRatio(1)
89        .onClick(this.clickOriginButton.bind(this))
90    } else {
91      Radio({ value: '', group: this.mTransition })
92        .key('Original')
93        .checked(this.isOriginalChecked)
94        .margin(0)
95        .onClick(this.clickOriginButton.bind(this))
96    }
97  }
98
99  @Builder buildTitle() {
100    Stack() {
101      Row() {
102        Text($r('app.string.selected_photos_count', this.selectedCount, this.maxSelectCount))
103          .fontSize($r('sys.float.ohos_id_text_size_body1'))
104          .fontFamily($r('app.string.id_text_font_family_regular'))
105          .fontColor(this.selectTextColor())
106          .fontWeight(FontWeight.Regular)
107          .key('currentSelectCount')
108
109        Button($r('app.string.complete'))
110          .key('Complete')
111          .enabled(this.isButtonEnabled() ? true : false)
112          .opacity(this.isButtonEnabled() ? 1 : $r('app.float.disable_button_opacity'))
113          .fontSize($r('sys.float.ohos_id_text_size_button3'))
114          .fontFamily($r('app.string.id_text_font_family_regular'))
115          .backgroundColor(this.isBrowserMode ? $r('sys.color.ohos_id_color_activated_dark') : $r('sys.color.ohos_id_color_activated'))
116          .width($r('app.float.picker_panel_button_width'))
117          .height($r('app.float.picker_panel_button_height'))
118          .fontWeight(FontWeight.Medium)
119          .onClick(() => {
120            this.onMenuClicked(Action.OK);
121          })
122      }
123      .width('100%')
124      .height($r('app.float.third_selected_panel_title_height'))
125      .alignItems(VerticalAlign.Center)
126      .justifyContent(FlexAlign.SpaceBetween)
127      .padding({
128        left: $r('sys.float.ohos_id_max_padding_start'),
129        right: $r('sys.float.ohos_id_max_padding_end')
130      })
131
132      Row() {
133        this.buildRadio()
134        Text($r('app.string.filter_original_text'))
135          .fontSize($r('sys.float.ohos_id_text_size_body1'))
136          .fontFamily($r('app.string.id_text_font_family_regular'))
137          .fontColor(this.isBrowserMode ? $r('sys.color.ohos_id_color_text_primary_dark') : $r('sys.color.ohos_id_color_text_primary'))
138          .fontWeight(FontWeight.Regular)
139          .margin({ left: $r('app.float.third_selected_toggle_icon_margin_right') })
140      }
141      .align(Alignment.Center)
142      .alignItems(VerticalAlign.Center)
143      .visibility(this.isFromFa ? Visibility.Hidden : Visibility.Visible)
144    }
145  }
146
147  @Builder buildThumbnailItem(item: MediaItem, index: number) {
148    Stack({ alignContent: Alignment.Start }) {
149      Image(item.thumbnail)
150        .height('100%')
151        .aspectRatio(1)
152        .objectFit(ImageFit.Cover)
153        .autoResize(false)
154        .onError(() => {
155          Log.error(TAG, 'item Image error');
156        })
157        .onComplete(() => {
158          Log.debug(TAG, `Draw the image! ${item.uri}`);
159        })
160        .onClick(() => {
161          this.broadCast.emit(BroadCastConstants.JUMP_THIRD_PHOTO_BROWSER, [
162            '',
163            item,
164          this.getPosition(item),
165            'thiSel_ThirdSelectPhotoGridBase' + item.getHashCode() + true,
166            true
167          ]);
168        })
169      // video duration
170      if (item.mediaType == UserFileManagerAccess.MEDIA_TYPE_VIDEO) {
171        Row() {
172          Text(DateUtil.getFormattedDuration(item.duration))
173            .fontSize($r('sys.float.ohos_id_text_size_caption'))
174            .fontFamily($r('app.string.id_text_font_family_regular'))
175            .fontColor($r('app.color.text_color_above_picture'))
176            .lineHeight(12)
177            .margin({
178              left: $r('app.float.grid_item_text_margin_lr'),
179              bottom: $r('app.float.grid_item_text_margin_bottom')
180            })
181        }
182        .height('100%')
183        .width('100%')
184        .hitTestBehavior(HitTestMode.None)
185        .alignItems(VerticalAlign.Bottom)
186      }
187      Image($r('app.media.ic_gallery_public_cancel_bg'))
188        .height($r('app.float.icon_size'))
189        .width($r('app.float.icon_size'))
190        .key('ThirdSelectCancel' + item.uri)
191        .objectFit(ImageFit.Contain)
192        .position({
193          x: $r('app.float.picker_panel_cancel_x'),
194          y: $r('app.float.picker_panel_cancel_y')
195        })
196        .onClick(() => {
197          Log.debug(TAG, `click cancel item ${item.uri}`);
198          this.broadCast.emit(BroadCastConstants.SELECT, [0, item.uri, false]);
199        })
200      Image($r('app.media.picker_border_img'))
201        .height('100%')
202        .aspectRatio(1)
203        .fillColor($r('sys.color.ohos_id_color_focused_bg_dark'))
204        .objectFit(ImageFit.Cover)
205        .autoResize(false)
206        .visibility(item.uri === this.currentUri ? Visibility.Visible : Visibility.None)
207        .hitTestBehavior(HitTestMode.None)
208    }
209    .height('100%')
210    .aspectRatio(1)
211  }
212
213  @Builder buildThumbnailList() {
214    List({ scroller: this.selectedScroller, space: 8 }) {
215      ForEach(this.itemArray, (item: MediaItem, index: number) => {
216        ListItem() {
217          this.buildThumbnailItem(item, index)
218        }
219        .width($r('app.float.third_selected_panel_image_height'))
220        .aspectRatio(1)
221        .margin({
222          left: index == 0 ? $r('sys.float.ohos_id_max_padding_start') : 0,
223          right: index == this.itemArray.length - 1 ? $r('sys.float.ohos_id_max_padding_end') : 0
224        })
225      }, item => item.getHashCode())
226    }
227    .width('100%')
228    .height('100%')
229    .listDirection(Axis.Horizontal)
230    .edgeEffect(EdgeEffect.Spring)
231    .scrollBar(BarState.Off)
232  }
233
234  @Builder buildDefault() {
235    Column() {
236      Text($r('app.string.select_items_to_add'))
237        .fontSize($r('sys.float.ohos_id_text_size_body2'))
238        .fontFamily($r('app.string.id_text_font_family_regular'))
239        .fontColor(this.isBrowserMode ? $r('sys.color.ohos_id_color_secondary_dark') : $r('sys.color.ohos_id_color_secondary'))
240        .fontWeight(FontWeight.Regular)
241    }
242    .width('100%')
243    .height($r('app.float.third_selected_panel_empty_height'))
244    .justifyContent(FlexAlign.Center)
245    .alignItems(HorizontalAlign.Center)
246    .margin({
247      top: $r('app.float.third_selected_panel_image_padding_top'),
248    })
249    .padding({
250      left: $r('sys.float.ohos_id_max_padding_start'),
251      right: $r('sys.float.ohos_id_max_padding_end')
252    })
253  }
254
255  build() {
256    Column() {
257      this.buildTitle()
258
259      if (this.isMultiPick) {
260        if (this.selectedCount > 0) {
261          Row() {
262            this.buildThumbnailList()
263          }
264          .width('100%')
265          .padding({
266            top: $r('app.float.third_selected_panel_image_padding_top'),
267            bottom: $r('sys.float.ohos_id_default_padding_bottom_fixed')
268          })
269        } else {
270          this.buildDefault()
271        }
272      }
273    }
274    .width('100%')
275    .height(this.isMultiPick ? $r('app.float.third_selected_panel_height') : $r('app.float.third_selected_panel_title_height'))
276    .backgroundColor(this.isBrowserMode ? $r('sys.color.ohos_id_color_card_bg_dark') : $r('sys.color.ohos_id_color_card_bg'))
277    .sharedTransition('ThirdSelectPhotoBrowserActionBar', {
278      curve: Curve.Linear,
279      zIndex: Constants.NUMBER_1,
280      type: SharedTransitionEffectType.Static
281    })
282    .visibility(this.isShowBar ? Visibility.Visible : Visibility.Hidden)
283  }
284
285  private getPosition(item: MediaItem): number {
286    return this.dataSource.getDataIndex(item) + this.dataSource.getGroupCountBeforeItem(item);
287  }
288
289  private selectTextColor() {
290    let normalColor = this.isBrowserMode ?
291    $r('sys.color.ohos_id_color_text_primary_dark') : $r('sys.color.ohos_id_color_text_primary');
292    if (!this.isHorizontal) {
293      return normalColor;
294    }
295    let warnColor = this.isBrowserMode ?
296    $r('sys.color.ohos_id_color_warning_dark') : $r('sys.color.ohos_id_color_warning');
297    return this.isMultiPick && this.selectedCount >= this.maxSelectCount ? warnColor : normalColor;
298  }
299
300  private isButtonEnabled(): boolean {
301    return!this.isMultiPick || this.selectedCount > 0;
302  }
303
304  private clickOriginButton() {
305    this.isOriginalChecked = !this.isOriginalChecked;
306    Log.info(TAG, `origin clicked: ${this.isOriginalChecked}`);
307  }
308}