PlayerFullScreenView.ets 10.6 KB
import { ContentDetailDTO } from 'wdBean/Index'
import { WDShare } from 'wdShare/Index'
import { PlayerProgressFullScreenView } from './PlayerProgressFullScreenView'
import { PlayerConstants, WDPlayerController } from 'wdPlayer/Index'
import { DateTimeUtils, Logger, WindowModel } from 'wdKit/Index'
import { DisplayDirection } from 'wdConstant/Index'
import { window } from '@kit.ArkUI'

@Component
export struct PlayerFullScreenView {
  private playerController?: WDPlayerController;
  @Consume contentDetailData: ContentDetailDTO
  @Consume @Watch("updateProgress") progressVal: number;
  @Consume status: number
  @Consume displayDirection: DisplayDirection
  @Consume isDragging: boolean
  @State videoDuration: number = this.contentDetailData?.videoInfo?.[0]?.videoDuration || 1
  @State showOperator: boolean = true
  private timer: number = -1
  @State upProVal: string = ''
  @State duration: string = DateTimeUtils.secondToTime(this.videoDuration)
  @State startX: number = 0
  @State endX: number = 0
  @State panDirection: number = 1 //1左滑 2右滑
  private panDistance: number = 0
  private touchDownX: number = 0
  private touchUpX: number = 0
  @State isTouched: boolean = false

  getTitle() {
    return this.contentDetailData?.newsTitle
    // || this.contentDetailData?.newsSummary || ''
  }

  share() {
    WDShare.shareContent(this.contentDetailData)
  }

  updateProgress() {
    this.upProVal = DateTimeUtils.secondToTime(Math.floor((this.progressVal / 100 * this.videoDuration)))
  }

  aboutToAppear(): void {
    WindowModel.shared.setWindowSystemBarEnable([])
    this.timer = setInterval(() => {
      this.showOperator = false
    }, 5000)
    // 初始显示
    this.updateProgress()
  }

  aboutToDisappear(): void {
    WindowModel.shared.setWindowSystemBarEnable(['status', 'navigation'])
    clearInterval(this.timer)
  }

  restartTimer() {
    clearInterval(this.timer)
    this.showOperator = true
    this.timer = setInterval(() => {
      this.showOperator = false
    }, 5000)
  }

  build() {
    Stack() {
      Row() {
      }.height('100%').width('100%')
      .onClick(() => {
        this.restartTimer()
      })

      this.headerBuilder()
      this.middleSlideBuilder()
      // this.middleContainerBuilder()
      this.bottomBuilder()
    }
    .zIndex(99999)
    .height('100%')
    .width('100%')

  }

  @Builder
  headerBuilder() {
    Row() {
      Row() {
        Image($r(`app.media.ic_back`)).height(24).width(24)
          .onClick(() => {
            this.displayDirection = this.displayDirection == DisplayDirection.VERTICAL ?
            DisplayDirection.VIDEO_HORIZONTAL :
            DisplayDirection.VERTICAL
            WindowModel.shared.setPreferredOrientation(this.displayDirection == DisplayDirection.VERTICAL ?
            window.Orientation.PORTRAIT :
            window.Orientation.LANDSCAPE)
          })
        Text(this.getTitle())
          .fontSize(18)
          .fontColor(Color.White)
          .maxLines(1)
          .textOverflow({ overflow: TextOverflow.Ellipsis })
          .margin({ left: 10 })
      }

      Image($r(`app.media.ic_share_empty`)).height(24).width(24)
        .onClick(() => {
          this.share()
        })

    }
    .width('100%')
    .position({ x: 0, y: 0 })
    .align(Alignment.Top)
    .height(73)
    .alignItems(VerticalAlign.Center)
    .justifyContent(FlexAlign.SpaceBetween)
    .padding({ left: 40, right: 40 })
    .animation({ duration: 2000 })
    .visibility(this.showOperator ? Visibility.Visible : Visibility.Hidden)
    .linearGradient({
      direction: GradientDirection.Bottom, // 渐变方向
      colors: [['rgba(0,0,0,0.5)', 0],
        ['rgba(1,1,1,0)', 1.0]] // 数组末尾元素占比小于1时满足重复着色效果
    })
  }

  @Builder
  bottomBuilder() {

    Column() {
      Text() {
        Span(this.upProVal)
          .fontColor(Color.White)
        Span(' / ')
          .fontColor(Color.White)
        Span(this.duration)
          .fontColor('#888888')

      }
      .fontSize(24)

      .fontWeight(600)
      .margin({ bottom: 30 })
      .visibility(this.isDragging ? Visibility.Visible : Visibility.None)

      Row() {
        Image($r(`app.media.ic_play`)).height(24).width(24)
          .visibility(this.status === PlayerConstants.STATUS_START ? Visibility.None : Visibility.Visible)
          .onClick(() => {
            this.playerController?.switchPlayOrPause()
          })
        Image($r(`app.media.ic_pause`)).height(24).width(24)
          .visibility(this.status === PlayerConstants.STATUS_PAUSE ? Visibility.None : Visibility.Visible)
          .onClick(() => {
            this.playerController?.switchPlayOrPause()
          })

        Text(this.upProVal)
          .fontSize(12)
          .fontWeight(600)
          .fontColor(Color.White)
          .margin({ left: 16, right: 8 })

        PlayerProgressFullScreenView({ playerController: this.playerController }).layoutWeight(1)
          .onTouch((event?: TouchEvent) => {

            if (event) {
              if (event.type === TouchType.Down) {
                // console.info(`cj2024 onTouch Down x=${event?.tiltX}`)
                clearInterval(this.timer)
              }
              if (event.type === TouchType.Up) {
                // console.info(`cj2024 onTouch Up x=${event?.tiltX}`)
                this.restartTimer();
              }
            }
          })

        Text(this.duration)
          .fontSize(12)
          .fontWeight(600)
          .fontColor(Color.White)
          .margin({ left: 16 })
      }
      .width('100%')
      .height(73)
      .alignItems(VerticalAlign.Center)
      .justifyContent(FlexAlign.SpaceBetween)
    }
    .width('100%')
    .position({ x: 0, y: '100%' })
    .markAnchor({ y: '100%' })
    .align(Alignment.Bottom)
    .padding({ left: 40, right: 40 })
    .animation({ duration: 2000 })
    .visibility(this.showOperator ? Visibility.Visible : Visibility.Hidden)
    .linearGradient({
      direction: GradientDirection.Bottom, // 渐变方向
      colors: [['rgba(0,0,0,0.5)', 0],
        ['rgba(1,1,1,0)', 1.0]] // 数组末尾元素占比小于1时满足重复着色效果
    })

  }

  @Builder
  middleContainerBuilder() {
    Row() {

    }
    .width('100%')
    .height('100%')
    .margin({ top: 73, bottom: 73 })
    // .backgroundColor('#FF0000')
    .onClick(() => {
      Logger.warn(`cj2024 onClick showOperator=${this.showOperator}`)
      if (!this.isDragging) {
        if (this.showOperator == false) {
          this.restartTimer();
        } else {
          this.showOperator = false
        }
      }

    })
    .gesture(
      // 以下组合手势为顺序识别,当长按手势事件未正常触发时则不会触发拖动手势事件
      GestureGroup(GestureMode.Sequence,
        // TapGesture()
        //   .onAction((event?:GestureEvent) => {
        //     Logger.warn(`cj2024 TapGesture showOperator=${this.showOperator}`)
        //     if (this.showOperator == false) {
        //       this.restartTimer();
        //     } else {
        //       this.showOperator = false
        //     }
        //   }),
        PanGesture()
          .onActionStart((event?: GestureEvent) => {
            if (event) {
              this.startX = event.offsetX
            }
            Logger.warn(`cj2024 pan start`)
          })
          .onActionUpdate((event?: GestureEvent) => {
            if (event) {
            }
            Logger.warn(`cj2024 pan update`)
          })
          .onActionEnd((event?: GestureEvent) => {
            if (event) {
              this.endX = event.offsetX
            }
            this.panDirection = this.endX - this.startX > 0 ? 2 : 1
            Logger.warn(`cj2024 pan end panDirection = ${this.panDirection} this.progressVal = ${this.progressVal} dir=${this.endX -
            this.startX}`)
            if (Math.abs(this.endX - this.startX) < 100) {
              this.panDistance = 1
            } else {
              this.panDistance = Math.abs(this.endX - this.startX) / 100
            }
            if (this.panDirection == 1) { //左滑
              if (this.progressVal > 5) {
                this.progressVal -= this.panDistance
              } else {
                this.progressVal = 0
              }
            } else {
              if (this.progressVal < 100) {
                this.progressVal += this.panDistance
              } else {
                this.progressVal = 100
              }

            }
            Logger.warn(`cj2024 pan end panDistance = ${this.panDistance} this.progressVal = ${this.progressVal}`)
            this.playerController?.setSeekTime(this.progressVal, SliderChangeMode.End);
          })
      )
    )
  }

  @Builder
  middleSlideBuilder() {
    Column() {
      Slider({
        value: this.progressVal,
        step: 0.01,
        style: SliderStyle.NONE
      })
        .trackColor(Color.Transparent)// 设置轨道为透明
        .selectedColor(Color.Transparent)// 设置已选择部分为透明
        .blockColor(Color.Transparent)// 设置滑块为透明
        .trackThickness(4)
        .showSteps(false)// 不显示步进刻度
        .showTips(false)// 不显示提示
        .width('100%')
        .height('100%')
        .onChange((value: number, mode: SliderChangeMode) => {
          // if (this.isTouched) {
          //   return
          // }
          this.progressVal = value
          // console.log('cj2024 onChange slider value:', value)
          if (mode === SliderChangeMode.Moving) {
            this.isDragging = true
          }
          if (mode === SliderChangeMode.End) {
            this.isDragging = false
            this.playerController?.setSeekTime(this.progressVal, SliderChangeMode.End);
          }
        })
    }.margin({ top: 73, bottom: 73 })
    .onTouch((event?: TouchEvent) => {
      // console.log(`cj2024 onTouch isDragging = ${this.isDragging}`)
      if (this.isDragging) {
        return
      }
      if (event) {
        if (event.type === TouchType.Down) {
          // console.info(`cj2024 onTouch Down x=${event?.touches[0].x}`)
          if (event?.touches.length > 0) {
            this.touchDownX = event?.touches[0].x
          }
          clearInterval(this.timer)
        }
        if (event.type === TouchType.Up) {
          // console.info(`cj2024 onTouch Up x=${event?.touches[0].x}`)
          if (event?.touches.length > 0) {
            this.touchUpX = event?.touches[0].x
            this.isTouched = this.touchUpX == this.touchDownX ? true : false
          }
          if (this.showOperator == false) {
            this.restartTimer();
          } else {
            // if (this.isTouched) {
              this.showOperator = false
            // }
            // this.restartTimer();
          }
        }
      }
    })
  }
}