{"version":3,"file":"video-progress.vue2.cjs","sources":["../../../components/video/video-progress.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { ResizeObserver } from '@/components/resize-observer'\nimport { Slider } from '@/components/slider'\n\nimport { computed, ref } from 'vue'\n\nimport { getStepByWord, useLocale, useNameHelper } from '@vexip-ui/config'\nimport { useListener, useSetTimeout } from '@vexip-ui/hooks'\nimport { boundRange, throttle } from '@vexip-ui/utils'\nimport { formatSeconds } from './helper'\n\nimport type { PropType } from 'vue'\nimport type { SliderExposed } from '@/components/slider'\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 nh = useNameHelper('video')\nconst locale = useLocale('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<SliderExposed>()\nconst sliderEl = computed(() => slider.value?.$el as HTMLElement | undefined)\nconst preview = ref<HTMLElement>()\n\nconst sliding = computed(() => !!slider.value?.sliding[1])\nconst percent = computed(() => {\n  return props.duration ? ((sliding.value ? slidTime.value : props.time) / props.duration) * 100 : 0\n})\nconst className = computed(() => {\n  return {\n    [nh.be('progress')]: true,\n    [nh.bem('progress', 'sliding')]: sliding.value,\n    [nh.bem('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  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 = segments[index]?.title || getStepByWord(locale.value.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  if (!wrapper.value) return\n\n  const style = getComputedStyle(wrapper.value)\n\n  paddingX = [parseFloat(style.paddingLeft), parseFloat(style.paddingRight)]\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: number) {\n  emit('change', (permillage / 1000) * props.duration)\n}\n\nconst onSlideMove = throttle(processMoveOnTrack)\n\nfunction onSlideStart() {\n  slidTime.value = props.time\n\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\n<template>\n  <div ref=\"wrapper\" :class=\"className\">\n    <ResizeObserver :on-resize=\"onSliderResize\">\n      <Slider\n        ref=\"slider\"\n        :class=\"nh.be('progress-slider')\"\n        :value=\"percent * 10\"\n        :max=\"1000\"\n        :vertical=\"false\"\n        :range=\"false\"\n        hide-tip\n        trigger-fade\n        flip-marker\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=\"nh.be('progress-segment')\"\n            :style=\"{ width: `${point.width}%` }\"\n          >\n            <div :class=\"nh.be('progress-track')\">\n              <div\n                :class=\"nh.be('progress-filler')\"\n                :style=\"{\n                  visibility: state.percent[1] < point.startPercent ? 'hidden' : undefined,\n                  transform: `translateX(${Math.min(\n                    (Math.max(state.percent[1] - point.startPercent, 0) / point.durationPercent) *\n                      100 -\n                      100,\n                    0\n                  )}%) translateZ(0)`\n                }\"\n              ></div>\n            </div>\n          </div>\n        </template>\n        <template #trigger>\n          <slot name=\"trigger\">\n            <div :class=\"nh.be('progress-trigger')\"></div>\n          </slot>\n        </template>\n      </Slider>\n    </ResizeObserver>\n    <div\n      :class=\"{\n        [nh.be('progress-indicator')]: true,\n        [nh.bem('progress-indicator', 'active')]: hovered && !sliding\n      }\"\n      :style=\"{ transform: `translateX(${indicatorLeft}px) translateZ(0)` }\"\n    ></div>\n    <ResizeObserver v-if=\"!noPreview\" :on-resize=\"onPreviewResize\">\n      <div\n        ref=\"preview\"\n        :class=\"{\n          [nh.be('preview')]: true,\n          [nh.bem('preview', 'has-image')]: previewSrc,\n          [nh.bem('preview', 'active')]: hovered || sliding\n        }\"\n        :style=\"{ transform: `translateX(${previewLeft}px) translateZ(0)` }\"\n      >\n        <slot name=\"preview\">\n          <div v-if=\"previewSrc\" :class=\"nh.be('preview-image')\">\n            <img :src=\"previewSrc\" />\n          </div>\n          <div :class=\"nh.be('preview-time')\">\n            {{ formatSeconds(hoveredTime) + segmentLabel }}\n          </div>\n        </slot>\n      </div>\n    </ResizeObserver>\n  </div>\n</template>\n"],"names":["props","__props","emit","__emit","nh","useNameHelper","locale","useLocale","timer","useSetTimeout","slidTime","ref","hovered","hoveredTime","indicatorLeft","previewLeft","paddingX","sliderWidth","previewWidth","wrapper","slider","sliderEl","computed","_a","preview","sliding","percent","className","points","duration","times","segment","len","start","end","pointDuration","segmentLabel","time","segments","index","i","title","getStepByWord","useListener","throttle","event","processMoveOnTrack","offsetX","boundRange","onSliderResize","entry","style","_b","onPreviewResize","handleChange","permillage","onSlideMove","onSlideStart","onSlideEnd","_createElementBlock","_createVNode","_unref","ResizeObserver","Slider","_normalizeClass","_withCtx","state","_openBlock","_Fragment","_renderList","point","_normalizeStyle","_createElementVNode","_renderSlot","_ctx","_createBlock","_hoisted_1","formatSeconds"],"mappings":"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"}