{"version":3,"file":"video-progress.mjs","sources":["../../../../../../packages/components/video/src/video-progress.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { computed, ref } from 'vue'\nimport { useSetTimeout } from '@lit-element/components/captcha/src/hooks/useSetTimeout'\nimport { useNamespace } from '@lit-element/hooks'\nimport { throttle } from '@lit-element/components/resize-observer/src/performance'\nimport Slider from '@lit-element/components/slider'\nimport ResizeObserver from '../../resize-box/src/resize-observer'\nimport { useListener } from './hooks/listener'\nimport { boundRange, formatSeconds, getStepByWord } from './hooks/utils'\nimport { localeVideo } from './symbol'\nimport type { PropType } from 'vue'\nimport type { VideoSegment } from './symbol'\n\ninterface PointState {\n  start: number\n  startPercent: number\n  end: number\n  endPercent: number\n  duration: number\n  durationPercent: number\n  width: number\n}\n\ndefineOptions({ name: 'VideoProgress' })\n\nconst props = defineProps({\n  time: {\n    type: Number,\n    default: 0,\n  },\n  duration: {\n    type: Number,\n    default: 0,\n  },\n  segments: {\n    type: Array as PropType<VideoSegment[]>,\n    default: () => [],\n  },\n  noPreview: {\n    type: Boolean,\n    default: false,\n  },\n  previewSrc: {\n    type: String,\n    default: '',\n  },\n})\n\nconst emit = defineEmits(['change'])\n\nconst ns = useNamespace('video')\n\nconst { timer } = useSetTimeout()\n\nconst slidTime = ref(0)\nconst hovered = ref(false)\nconst hoveredTime = ref(0)\nconst indicatorLeft = ref(0)\nconst previewLeft = ref(0)\n\nlet paddingX = [0, 0]\nlet sliderWidth = 100\nlet previewWidth = 60\n\nconst wrapper = ref<HTMLElement>()\nconst slider = ref()\nconst sliderEl = computed(() => slider.value?.$el as HTMLElement | undefined)\nconst preview = ref<HTMLElement>()\n\nconst sliderVal = ref(0)\nconst sliding = computed(() => {\n  return !!slider.value?.firstButton?.dragging\n})\n// const percent = computed(() => {\n//   return props.duration\n//     ? ((sliding.value ? slidTime.value : props.time) / props.duration) * 100\n//     : 0\n// })\nconst className = computed(() => {\n  return {\n    [ns.e('progress')]: true,\n    [ns.em('progress', 'sliding')]: sliding.value,\n    [ns.em('progress', 'disabled')]: props.duration <= 0,\n  }\n})\nconst points = computed<PointState[]>(() => {\n  const duration = Math.max(1, props.duration)\n\n  let times = props.segments.map((segment) => segment.time)\n\n  if (!times.length) times = [0, duration]\n\n  times = times.at(-1) === duration ? times : [...times, duration]\n  times = times[0] === 0 ? times : [0, ...times]\n\n  const points: PointState[] = []\n\n  for (let i = 0, len = times.length - 1; i < len; ++i) {\n    const start = times[i]\n    const end = times[i + 1]\n    const pointDuration = end - start\n\n    points.push({\n      start,\n      startPercent: (start / duration) * 100,\n      end,\n      endPercent: (end / duration) * 100,\n      duration: pointDuration,\n      durationPercent: (pointDuration / duration) * 100,\n      width: ((end - start) / duration) * 100,\n    })\n  }\n\n  return points\n})\nconst segmentLabel = computed(() => {\n  const time = hoveredTime.value\n\n  const segments = props.segments\n\n  if (!segments.length) return ''\n\n  let index = -1\n\n  if (time <= 0) {\n    index = 0\n  } else {\n    for (let i = 1, len = segments.length; i < len; ++i) {\n      if (segments[i].time > time) {\n        index = i - 1\n        break\n      }\n    }\n  }\n\n  if (index < 0) {\n    index = segments.length - 1\n  }\n\n  const title =\n    segments[index]?.title || getStepByWord(localeVideo.chapterCount, index + 1)\n\n  return title && ` (${title})`\n})\n\nuseListener(sliderEl, 'pointerenter', () => {\n  clearTimeout(timer.hover)\n\n  timer.hover = setTimeout(() => {\n    hovered.value = true\n  }, 100)\n})\nuseListener(sliderEl, 'pointerleave', () => {\n  clearTimeout(timer.hover)\n\n  timer.hover = setTimeout(() => {\n    hovered.value = false\n  }, 100)\n})\nuseListener(\n  sliderEl,\n  'pointermove',\n  throttle((event: PointerEvent) => {\n    if (!sliding.value) {\n      processMoveOnTrack(event)\n    }\n  })\n)\n\nfunction processMoveOnTrack(event: PointerEvent) {\n  if (!sliderEl.value) return\n\n  const offsetX = boundRange(\n    event.clientX - sliderEl.value.getBoundingClientRect().left,\n    0,\n    sliderWidth\n  )\n\n  hoveredTime.value = (offsetX / sliderWidth) * props.duration\n  indicatorLeft.value = offsetX + paddingX[0]\n  previewLeft.value = boundRange(\n    offsetX - previewWidth * 0.5 + paddingX[0],\n    0,\n    sliderWidth - previewWidth + paddingX[0] + paddingX[1]\n  )\n}\n\nfunction onSliderResize(entry: ResizeObserverEntry) {\n  console.log('onSliderResize')\n  if (!wrapper.value) return\n\n  const style = getComputedStyle(wrapper.value)\n\n  paddingX = [\n    Number.parseFloat(style.paddingLeft),\n    Number.parseFloat(style.paddingRight),\n  ]\n  sliderWidth = entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width\n}\n\nfunction onPreviewResize(entry: ResizeObserverEntry) {\n  previewWidth = entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width\n}\n\nfunction handleChange(permillage: any) {\n  emit('change', (permillage / 1000) * props.duration)\n}\n\nconst onSlideMove = throttle(processMoveOnTrack)\n\nfunction onSlideStart() {\n  slidTime.value = props.time\n  document.addEventListener('pointermove', onSlideMove)\n  document.addEventListener('pointerup', onSlideEnd)\n}\n\nfunction onSlideEnd() {\n  document.removeEventListener('pointermove', onSlideMove)\n  document.removeEventListener('pointerup', onSlideEnd)\n}\n</script>\n<template>\n  <!-- :model-value=\"percent * 10\" -->\n  <div ref=\"wrapper\" :class=\"className\">\n    <ResizeObserver @resize=\"onSliderResize\">\n      <Slider\n        ref=\"slider\"\n        v-model=\"sliderVal\"\n        style=\"height: 14px\"\n        :class=\"ns.e('progress-slider')\"\n        :max=\"1000\"\n        :vertical=\"false\"\n        :range=\"false\"\n        :show-tooltip=\"false\"\n        :disabled=\"duration <= 0\"\n        @change=\"handleChange\"\n        @pointerdown=\"onSlideStart\"\n      >\n        <template #filler=\"state\">\n          <div\n            v-for=\"(point, index) in points\"\n            :key=\"index\"\n            :class=\"ns.e('progress-segment')\"\n            :style=\"{ width: `${point.width}%` }\"\n          >\n            <div :class=\"ns.e('progress-track')\">\n              <div\n                :class=\"ns.e('progress-filler')\"\n                :style=\"{\n                  visibility:\n                    state.percent[1] < point.startPercent\n                      ? 'hidden'\n                      : undefined,\n                  transform: `translateX(${Math.min(\n                    (Math.max(state.percent[1] - point.startPercent, 0) /\n                      point.durationPercent) *\n                      100 -\n                      100,\n                    0\n                  )}%) translateZ(0)`,\n                }\"\n              />\n            </div>\n          </div>\n        </template>\n        <template #trigger>\n          <slot name=\"trigger\">\n            <div :class=\"ns.e('progress-trigger')\" />\n          </slot>\n        </template>\n      </Slider>\n    </ResizeObserver>\n    <div\n      :class=\"{\n        [ns.e('progress-indicator')]: true,\n        [ns.em('progress-indicator', 'active')]: hovered && !sliding,\n      }\"\n      :style=\"{ transform: `translateX(${indicatorLeft}px) translateZ(0)` }\"\n    />\n    <ResizeObserver v-if=\"!noPreview\" @resize=\"onPreviewResize\">\n      <div\n        ref=\"preview\"\n        :class=\"{\n          [ns.e('preview')]: true,\n          [ns.em('preview', 'has-image')]: previewSrc,\n          [ns.em('preview', 'active')]: hovered || sliding,\n        }\"\n        :style=\"{ transform: `translateX(${previewLeft}px) translateZ(0)` }\"\n      >\n        <slot name=\"preview\">\n          <div v-if=\"previewSrc\" :class=\"ns.e('preview-image')\">\n            <img :src=\"previewSrc\" />\n          </div>\n          <div :class=\"ns.e('preview-time')\">\n            {{ formatSeconds(hoveredTime) + segmentLabel }}\n          </div>\n        </slot>\n      </div>\n    </ResizeObserver>\n  </div>\n</template>\n"],"names":["points"],"mappings":"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"}