• 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 Matrix4 from '@ohos.matrix4';
17import { PhotoItem } from './PhotoItem';
18import { BroadCastConstants } from '../model/common/BroadCastConstants';
19import { Log } from '../utils/Log';
20import { BroadCast } from '../utils/BroadCast';
21import Curves from '@ohos.curves';
22import { Constants } from '../model/common/Constants';
23import { Constants as BrowserConstants } from '../model/browser/photo/Constants';
24import { PhotoDataSource } from '../model/browser/photo/PhotoDataSource';
25import { MediaItem } from '../model/browser/photo/MediaItem';
26
27const TAG: string = 'common_PhotoSwiper';
28
29export interface Results {
30  data: MediaItem;
31  pos: number;
32  thumbnail: string;
33};
34
35@Component
36export struct PhotoSwiper {
37  mTransition: string = '';
38  @Consume currentIndex: number;
39  @Link broadCast: BroadCast;
40  @State mDuration: number = 300;
41  onPhotoChanged: Function = (): void => {};
42  swiperController?: SwiperController;
43  isInSelectedMode: boolean = false;
44  @Consume canSwipe: boolean;
45  swiperItemSpace: number = Constants.NUMBER_8;
46  verifyPhotoScaledFunc: (matrix?: Matrix4.Matrix4Transit) => void = (matrix?: Matrix4.Matrix4Transit): void => {}
47  @Link isRunningAnimation: boolean;
48  isLeftSwiper: boolean = false;
49  @Consume isDeleting: boolean;
50  @State isOnSwiperAnimation: boolean = false;
51  private dataSource?: PhotoDataSource;
52  private geometryTransitionEnable: boolean = false;
53  private isFromFACard: boolean = false;
54  private SWIPE_CACHE_COUNT: number = 2;
55  private onDataReloadFunc: Function = (addCount: number): void => this.onDataReload(addCount);
56  private onChangeSwiperDurationFunc: Function = (value: number): void => this.onChangeSwiperDuration(value);
57
58  private onDataReload(addCount: number): void {
59    let totalCount = this.dataSource == null ? 0 : this.dataSource.totalCount();
60    let add = addCount;
61    if (add > Constants.NUMBER_0) {
62      if (this.dataSource != null) {
63        this.dataSource.onDataReloaded();
64      }
65      if (this.currentIndex + add < totalCount) {
66        this.currentIndex += add;
67      }
68      Log.info(TAG, `ON_DATA_RELOADED: ${this.currentIndex}, ${add}`);
69      return;
70    }
71    Log.debug(TAG, 'animate to data reloaded start');
72    animateTo({
73      duration: 300, // 删除动画时长
74      curve: Curves.cubicBezier(0.0, 0.0, 0.2, 1.0), // 减速曲线参数
75      onFinish: () => {
76        if (this.dataSource != null) {
77          let totalCount = this.dataSource.totalCount();
78          this.dataSource.onDataChanged(this.currentIndex);
79          // UPDATE NEXT TWO DATA FOR AVOID NOT LOADING DATA
80          if (this.currentIndex + 1 < totalCount) {
81            this.dataSource.onDataChanged(this.currentIndex + 1);
82          }
83          if (this.currentIndex + 2 < totalCount) {
84            this.dataSource.onDataChanged(this.currentIndex + 2);
85          }
86          this.dataSource.onDataReloaded();
87        }
88      } }, () => {
89      if (this.dataSource != null && this.isDeleting) {
90        this.dataSource.deleteData(this.currentIndex);
91      }
92      if (this.dataSource != null && this.currentIndex === this.dataSource.totalCount() || (this.isDeleting && this.isLeftSwiper && this.currentIndex > 0)) {
93        this.currentIndex--;
94      }
95      this.isDeleting = false;
96    })
97  }
98
99  private onChangeSwiperDuration(value: number): void {
100    Log.debug(TAG, `change duration start ${value}`);
101    this.mDuration = value;
102  }
103
104  aboutToAppear() {
105    this.broadCast.on(BroadCastConstants.ON_DATA_RELOADED, this.onDataReloadFunc);
106    this.broadCast.on(BroadCastConstants.CHANGE_SWIPER_DURATION, this.onChangeSwiperDurationFunc);
107  }
108
109  aboutToDisappear(): void {
110    this.swiperController = undefined;
111    this.broadCast.off(BroadCastConstants.ON_DATA_RELOADED, this.onDataReloadFunc);
112    this.broadCast.off(BroadCastConstants.CHANGE_SWIPER_DURATION, this.onChangeSwiperDurationFunc);
113  }
114
115  build() {
116    Swiper(this.swiperController) {
117      LazyForEach(this.dataSource as PhotoDataSource, (item: Results, index?: number) => {
118        if (!!item) {
119          Column() {
120            PhotoItem({
121              item: item.data,
122              mPosition: item.pos,
123              thumbnail: item.thumbnail,
124              transitionTag: this.mTransition ? this.mTransition : 'default_id',
125              verifyPhotoScaled: this.verifyPhotoScaledFunc,
126              albumUri: (this.dataSource == null ? '' : this.dataSource.getAlbumUri()),
127              geometryTransitionEnable: this.geometryTransitionEnable,
128              broadCast: $broadCast,
129              isRunningAnimation: $isRunningAnimation,
130              isFromFACard: this.isFromFACard,
131              isInSelectedMode: this.isInSelectedMode,
132              isOnSwiperAnimation: $isOnSwiperAnimation,
133              dataSource: this.dataSource
134            })
135          }.zIndex(item.pos == this.currentIndex ? 2 : 1)
136        }
137      }, (item: Results, index?: number) => {
138        if (item == null || item == undefined) {
139          return JSON.stringify(item) + index;
140        }
141        return `${item.data.uri}_${item.data.size}_${item.data.orientation}_${index}`;
142      })
143    }
144    .cachedCount(this.SWIPE_CACHE_COUNT)
145    .duration(BrowserConstants.PHOTO_SWIPE_DURATION)
146    .itemSpace(this.swiperItemSpace)
147    .onGestureSwipe(() => {
148      if (!this.isOnSwiperAnimation) {
149        this.isOnSwiperAnimation = true;
150      }
151    })
152    .index(this.currentIndex)
153    .indicator(false)
154    .loop(false)
155    .onChange((index: number) => {
156      if (this.currentIndex - index == 1) {
157        this.isLeftSwiper = true;
158      } else if (this.currentIndex - index == -1) {
159        this.isLeftSwiper = false;
160      }
161      if (this.mDuration != 0) {
162        this.onPhotoChanged(index);
163
164        if (!!this.verifyPhotoScaledFunc) {
165          this.verifyPhotoScaledFunc(undefined)
166        }
167      }
168    })
169    .disableSwipe(this.canSwipe)
170    .onAnimationStart((index: number) => {
171      this.isOnSwiperAnimation = true;
172    })
173    .onAnimationEnd(() => {
174      this.isOnSwiperAnimation = false;
175    })
176  }
177}