100aff185Sopenharmony_ci/*
200aff185Sopenharmony_ci * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
300aff185Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
400aff185Sopenharmony_ci * you may not use this file except in compliance with the License.
500aff185Sopenharmony_ci * You may obtain a copy of the License at
600aff185Sopenharmony_ci *
700aff185Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
800aff185Sopenharmony_ci *
900aff185Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1000aff185Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1100aff185Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1200aff185Sopenharmony_ci * See the License for the specific language governing permissions and
1300aff185Sopenharmony_ci * limitations under the License.
1400aff185Sopenharmony_ci */
1500aff185Sopenharmony_ci
1600aff185Sopenharmony_ciimport Matrix4 from '@ohos.matrix4';
1700aff185Sopenharmony_ciimport { PhotoItem } from './PhotoItem';
1800aff185Sopenharmony_ciimport { BroadCastConstants } from '../model/common/BroadCastConstants';
1900aff185Sopenharmony_ciimport { Log } from '../utils/Log';
2000aff185Sopenharmony_ciimport { BroadCast } from '../utils/BroadCast';
2100aff185Sopenharmony_ciimport Curves from '@ohos.curves';
2200aff185Sopenharmony_ciimport { Constants } from '../model/common/Constants';
2300aff185Sopenharmony_ciimport { Constants as BrowserConstants } from '../model/browser/photo/Constants';
2400aff185Sopenharmony_ciimport { PhotoDataSource } from '../model/browser/photo/PhotoDataSource';
2500aff185Sopenharmony_ciimport { MediaItem } from '../model/browser/photo/MediaItem';
2600aff185Sopenharmony_ci
2700aff185Sopenharmony_ciconst TAG: string = 'common_PhotoSwiper';
2800aff185Sopenharmony_ci
2900aff185Sopenharmony_ciexport interface Results {
3000aff185Sopenharmony_ci  data: MediaItem;
3100aff185Sopenharmony_ci  pos: number;
3200aff185Sopenharmony_ci  thumbnail: string;
3300aff185Sopenharmony_ci};
3400aff185Sopenharmony_ci
3500aff185Sopenharmony_ci@Component
3600aff185Sopenharmony_ciexport struct PhotoSwiper {
3700aff185Sopenharmony_ci  mTransition: string = '';
3800aff185Sopenharmony_ci  @Consume currentIndex: number;
3900aff185Sopenharmony_ci  @Link broadCast: BroadCast;
4000aff185Sopenharmony_ci  @State mDuration: number = 300;
4100aff185Sopenharmony_ci  onPhotoChanged: Function = (): void => {};
4200aff185Sopenharmony_ci  swiperController?: SwiperController;
4300aff185Sopenharmony_ci  isInSelectedMode: boolean = false;
4400aff185Sopenharmony_ci  @Consume canSwipe: boolean;
4500aff185Sopenharmony_ci  swiperItemSpace: number = Constants.NUMBER_8;
4600aff185Sopenharmony_ci  verifyPhotoScaledFunc: (matrix?: Matrix4.Matrix4Transit) => void = (matrix?: Matrix4.Matrix4Transit): void => {}
4700aff185Sopenharmony_ci  @Link isRunningAnimation: boolean;
4800aff185Sopenharmony_ci  isLeftSwiper: boolean = false;
4900aff185Sopenharmony_ci  @Consume isDeleting: boolean;
5000aff185Sopenharmony_ci  @State isOnSwiperAnimation: boolean = false;
5100aff185Sopenharmony_ci  private dataSource?: PhotoDataSource;
5200aff185Sopenharmony_ci  private geometryTransitionEnable: boolean = false;
5300aff185Sopenharmony_ci  private isFromFACard: boolean = false;
5400aff185Sopenharmony_ci  private SWIPE_CACHE_COUNT: number = 2;
5500aff185Sopenharmony_ci  private onDataReloadFunc: Function = (addCount: number): void => this.onDataReload(addCount);
5600aff185Sopenharmony_ci  private onChangeSwiperDurationFunc: Function = (value: number): void => this.onChangeSwiperDuration(value);
5700aff185Sopenharmony_ci
5800aff185Sopenharmony_ci  private onDataReload(addCount: number): void {
5900aff185Sopenharmony_ci    let totalCount = this.dataSource == null ? 0 : this.dataSource.totalCount();
6000aff185Sopenharmony_ci    let add = addCount;
6100aff185Sopenharmony_ci    if (add > Constants.NUMBER_0) {
6200aff185Sopenharmony_ci      if (this.dataSource != null) {
6300aff185Sopenharmony_ci        this.dataSource.onDataReloaded();
6400aff185Sopenharmony_ci      }
6500aff185Sopenharmony_ci      if (this.currentIndex + add < totalCount) {
6600aff185Sopenharmony_ci        this.currentIndex += add;
6700aff185Sopenharmony_ci      }
6800aff185Sopenharmony_ci      Log.info(TAG, `ON_DATA_RELOADED: ${this.currentIndex}, ${add}`);
6900aff185Sopenharmony_ci      return;
7000aff185Sopenharmony_ci    }
7100aff185Sopenharmony_ci    Log.debug(TAG, 'animate to data reloaded start');
7200aff185Sopenharmony_ci    animateTo({
7300aff185Sopenharmony_ci      duration: 300, // 删除动画时长
7400aff185Sopenharmony_ci      curve: Curves.cubicBezier(0.0, 0.0, 0.2, 1.0), // 减速曲线参数
7500aff185Sopenharmony_ci      onFinish: () => {
7600aff185Sopenharmony_ci        if (this.dataSource != null) {
7700aff185Sopenharmony_ci          let totalCount = this.dataSource.totalCount();
7800aff185Sopenharmony_ci          this.dataSource.onDataChanged(this.currentIndex);
7900aff185Sopenharmony_ci          // UPDATE NEXT TWO DATA FOR AVOID NOT LOADING DATA
8000aff185Sopenharmony_ci          if (this.currentIndex + 1 < totalCount) {
8100aff185Sopenharmony_ci            this.dataSource.onDataChanged(this.currentIndex + 1);
8200aff185Sopenharmony_ci          }
8300aff185Sopenharmony_ci          if (this.currentIndex + 2 < totalCount) {
8400aff185Sopenharmony_ci            this.dataSource.onDataChanged(this.currentIndex + 2);
8500aff185Sopenharmony_ci          }
8600aff185Sopenharmony_ci          this.dataSource.onDataReloaded();
8700aff185Sopenharmony_ci        }
8800aff185Sopenharmony_ci      } }, () => {
8900aff185Sopenharmony_ci      if (this.dataSource != null && this.isDeleting) {
9000aff185Sopenharmony_ci        this.dataSource.deleteData(this.currentIndex);
9100aff185Sopenharmony_ci      }
9200aff185Sopenharmony_ci      if (this.dataSource != null && this.currentIndex === this.dataSource.totalCount() ||
9300aff185Sopenharmony_ci        (this.isDeleting && this.isLeftSwiper && this.currentIndex > 0)) {
9400aff185Sopenharmony_ci        this.currentIndex--;
9500aff185Sopenharmony_ci      }
9600aff185Sopenharmony_ci      this.isDeleting = false;
9700aff185Sopenharmony_ci    })
9800aff185Sopenharmony_ci  }
9900aff185Sopenharmony_ci
10000aff185Sopenharmony_ci  private onChangeSwiperDuration(value: number): void {
10100aff185Sopenharmony_ci    Log.debug(TAG, `change duration start ${value}`);
10200aff185Sopenharmony_ci    this.mDuration = value;
10300aff185Sopenharmony_ci  }
10400aff185Sopenharmony_ci
10500aff185Sopenharmony_ci  aboutToAppear() {
10600aff185Sopenharmony_ci    this.broadCast.on(BroadCastConstants.ON_DATA_RELOADED, this.onDataReloadFunc);
10700aff185Sopenharmony_ci    this.broadCast.on(BroadCastConstants.CHANGE_SWIPER_DURATION, this.onChangeSwiperDurationFunc);
10800aff185Sopenharmony_ci  }
10900aff185Sopenharmony_ci
11000aff185Sopenharmony_ci  aboutToDisappear(): void {
11100aff185Sopenharmony_ci    this.swiperController = undefined;
11200aff185Sopenharmony_ci    this.broadCast.off(BroadCastConstants.ON_DATA_RELOADED, this.onDataReloadFunc);
11300aff185Sopenharmony_ci    this.broadCast.off(BroadCastConstants.CHANGE_SWIPER_DURATION, this.onChangeSwiperDurationFunc);
11400aff185Sopenharmony_ci  }
11500aff185Sopenharmony_ci
11600aff185Sopenharmony_ci  build() {
11700aff185Sopenharmony_ci    Swiper(this.swiperController) {
11800aff185Sopenharmony_ci      LazyForEach(this.dataSource as PhotoDataSource, (item: Results, index?: number) => {
11900aff185Sopenharmony_ci        if (!!item) {
12000aff185Sopenharmony_ci          Column() {
12100aff185Sopenharmony_ci            PhotoItem({
12200aff185Sopenharmony_ci              item: item.data,
12300aff185Sopenharmony_ci              mPosition: item.pos,
12400aff185Sopenharmony_ci              thumbnail: item.thumbnail,
12500aff185Sopenharmony_ci              transitionTag: this.mTransition ? this.mTransition : 'default_id',
12600aff185Sopenharmony_ci              verifyPhotoScaled: this.verifyPhotoScaledFunc,
12700aff185Sopenharmony_ci              albumUri: (this.dataSource == null ? '' : this.dataSource.getAlbumUri()),
12800aff185Sopenharmony_ci              geometryTransitionEnable: this.geometryTransitionEnable,
12900aff185Sopenharmony_ci              broadCast: $broadCast,
13000aff185Sopenharmony_ci              isRunningAnimation: $isRunningAnimation,
13100aff185Sopenharmony_ci              isFromFACard: this.isFromFACard,
13200aff185Sopenharmony_ci              isInSelectedMode: this.isInSelectedMode,
13300aff185Sopenharmony_ci              isOnSwiperAnimation: $isOnSwiperAnimation,
13400aff185Sopenharmony_ci              dataSource: this.dataSource
13500aff185Sopenharmony_ci            })
13600aff185Sopenharmony_ci          }.zIndex(item.pos == this.currentIndex ? 2 : 1)
13700aff185Sopenharmony_ci        }
13800aff185Sopenharmony_ci      }, (item: Results, index?: number) => {
13900aff185Sopenharmony_ci        if (item == null || item == undefined) {
14000aff185Sopenharmony_ci          return JSON.stringify(item) + index;
14100aff185Sopenharmony_ci        }
14200aff185Sopenharmony_ci        return `${item.data.path}_${item.data.size}_${item.data.orientation}_${index}`;
14300aff185Sopenharmony_ci      })
14400aff185Sopenharmony_ci    }
14500aff185Sopenharmony_ci    .cachedCount(this.SWIPE_CACHE_COUNT)
14600aff185Sopenharmony_ci    .duration(BrowserConstants.PHOTO_SWIPE_DURATION)
14700aff185Sopenharmony_ci    .itemSpace(this.swiperItemSpace)
14800aff185Sopenharmony_ci    .onGestureSwipe(() => {
14900aff185Sopenharmony_ci      if (!this.isOnSwiperAnimation) {
15000aff185Sopenharmony_ci        this.isOnSwiperAnimation = true;
15100aff185Sopenharmony_ci      }
15200aff185Sopenharmony_ci    })
15300aff185Sopenharmony_ci    .index(this.currentIndex)
15400aff185Sopenharmony_ci    .indicator(false)
15500aff185Sopenharmony_ci    .loop(false)
15600aff185Sopenharmony_ci    .onChange((index: number) => {
15700aff185Sopenharmony_ci      if (this.currentIndex - index == 1) {
15800aff185Sopenharmony_ci        this.isLeftSwiper = true;
15900aff185Sopenharmony_ci      } else if (this.currentIndex - index == -1) {
16000aff185Sopenharmony_ci        this.isLeftSwiper = false;
16100aff185Sopenharmony_ci      }
16200aff185Sopenharmony_ci      if (this.mDuration != 0) {
16300aff185Sopenharmony_ci        this.onPhotoChanged(index);
16400aff185Sopenharmony_ci
16500aff185Sopenharmony_ci        if (!!this.verifyPhotoScaledFunc) {
16600aff185Sopenharmony_ci          this.verifyPhotoScaledFunc(undefined)
16700aff185Sopenharmony_ci        }
16800aff185Sopenharmony_ci      }
16900aff185Sopenharmony_ci    })
17000aff185Sopenharmony_ci    .disableSwipe(this.canSwipe)
17100aff185Sopenharmony_ci    .onAnimationStart((index: number) => {
17200aff185Sopenharmony_ci      this.isOnSwiperAnimation = true;
17300aff185Sopenharmony_ci    })
17400aff185Sopenharmony_ci    .onAnimationEnd(() => {
17500aff185Sopenharmony_ci      this.isOnSwiperAnimation = false;
17600aff185Sopenharmony_ci    })
17700aff185Sopenharmony_ci  }
17800aff185Sopenharmony_ci}