|
@@ -1,313 +0,0 @@
|
|
-<template>
|
|
|
|
- <div class="uploader-file" :status="status">
|
|
|
|
- <slot
|
|
|
|
- :file="file"
|
|
|
|
- :list="list"
|
|
|
|
- :status="status"
|
|
|
|
- :paused="paused"
|
|
|
|
- :error="error"
|
|
|
|
- :response="response"
|
|
|
|
- :average-speed="averageSpeed"
|
|
|
|
- :formated-average-speed="formatedAverageSpeed"
|
|
|
|
- :current-speed="currentSpeed"
|
|
|
|
- :is-complete="isComplete"
|
|
|
|
- :is-uploading="isUploading"
|
|
|
|
- :size="size"
|
|
|
|
- :formated-size="formatedSize"
|
|
|
|
- :uploaded-size="uploadedSize"
|
|
|
|
- :progress="progress"
|
|
|
|
- :progress-style="progressStyle"
|
|
|
|
- :progressing-class="progressingClass"
|
|
|
|
- :time-remaining="timeRemaining"
|
|
|
|
- :formated-time-remaining="formatedTimeRemaining"
|
|
|
|
- :type="type"
|
|
|
|
- :extension="extension"
|
|
|
|
- :file-category="fileCategory"
|
|
|
|
- >
|
|
|
|
- <div class="uploader-file-progress" :class="progressingClass" :style="progressStyle"></div>
|
|
|
|
- <div class="uploader-file-info">
|
|
|
|
- <div class="uploader-file-name">
|
|
|
|
- <i class="uploader-file-icon" :icon="fileCategory"/>
|
|
|
|
- <span>{{ file.name }}</span>
|
|
|
|
- </div>
|
|
|
|
- <div class="uploader-file-size">{{ formatedSize }}</div>
|
|
|
|
- <div class="uploader-file-status" v-show="status === 'uploading'">
|
|
|
|
- {{ progressStyle.progress }} / {{ formatedAverageSpeed}} / {{ formatedTimeRemaining}}
|
|
|
|
- </div>
|
|
|
|
- <div class="uploader-file-status text" :class="'hc-custom-status-' + file.id" v-show="status !== 'uploading'">{{ statusText }}</div>
|
|
|
|
- <div class="uploader-file-actions">
|
|
|
|
- <span class="uploader-file-pause" @click="pause"></span>
|
|
|
|
- <span class="uploader-file-resume" @click="resume">️</span>
|
|
|
|
- <span class="uploader-file-retry" @click="retry"></span>
|
|
|
|
- <span class="uploader-file-remove" @click="remove"></span>
|
|
|
|
- </div>
|
|
|
|
- </div>
|
|
|
|
- </slot>
|
|
|
|
- </div>
|
|
|
|
-</template>
|
|
|
|
-
|
|
|
|
-<script>
|
|
|
|
-import {computed, ref, toRaw, watch, onMounted, onUnmounted, getCurrentInstance} from 'vue'
|
|
|
|
-import Uploader from 'simple-uploader.js'
|
|
|
|
-import {secondsToStr} from '../common/utils'
|
|
|
|
-import events from '../common/file-events'
|
|
|
|
-
|
|
|
|
-const COMPONENT_NAME = 'uploader-file'
|
|
|
|
-
|
|
|
|
-export default {
|
|
|
|
- name: COMPONENT_NAME,
|
|
|
|
- props: {
|
|
|
|
- file: {
|
|
|
|
- type: Object,
|
|
|
|
- default() {
|
|
|
|
- return {}
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- list: {
|
|
|
|
- type: Boolean,
|
|
|
|
- default: false
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- setup(props) {
|
|
|
|
- const instance = getCurrentInstance()
|
|
|
|
- let handlers = {}
|
|
|
|
- let tid = 0
|
|
|
|
- const response = ref(null)
|
|
|
|
- const paused = ref(false)
|
|
|
|
- const error = ref(false)
|
|
|
|
- const averageSpeed = ref(0)
|
|
|
|
- const currentSpeed = ref(0)
|
|
|
|
- const isComplete = ref(false)
|
|
|
|
- const isUploading = ref(false)
|
|
|
|
- const size = ref(0)
|
|
|
|
- const formatedSize = ref('')
|
|
|
|
- const uploadedSize = ref(0)
|
|
|
|
- const progress = ref(0)
|
|
|
|
- const timeRemaining = ref(0)
|
|
|
|
- const type = ref('')
|
|
|
|
- const extension = ref('')
|
|
|
|
- const progressingClass = ref('')
|
|
|
|
- const fileCategory = computed(() => {
|
|
|
|
- const isFolder = props.file.isFolder
|
|
|
|
- let type = isFolder ? 'folder' : 'unknown'
|
|
|
|
- const categoryMap = props.file.uploader.opts.categoryMap
|
|
|
|
- const typeMap = categoryMap || {
|
|
|
|
- image: ['gif', 'jpg', 'jpeg', 'png', 'bmp', 'webp'],
|
|
|
|
- video: ['mp4', 'm3u8', 'rmvb', 'avi', 'swf', '3gp', 'mkv', 'flv'],
|
|
|
|
- audio: ['mp3', 'wav', 'wma', 'ogg', 'aac', 'flac'],
|
|
|
|
- document: ['doc', 'txt', 'docx', 'pages', 'epub', 'pdf', 'numbers', 'csv', 'xls', 'xlsx', 'keynote', 'ppt', 'pptx']
|
|
|
|
- }
|
|
|
|
- Object.keys(typeMap).forEach((_type) => {
|
|
|
|
- const extensions = typeMap[_type]
|
|
|
|
- if (extensions.indexOf(extension.value) > -1) {
|
|
|
|
- type = _type
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- return type
|
|
|
|
- })
|
|
|
|
- const progressStyle = computed(() => {
|
|
|
|
- progress.value = Math.floor(progress.value * 100)
|
|
|
|
- const style = `translateX(${Math.floor(progress.value - 100)}%)`
|
|
|
|
- return {
|
|
|
|
- progress: `${progress.value}%`,
|
|
|
|
- webkitTransform: style,
|
|
|
|
- mozTransform: style,
|
|
|
|
- msTransform: style,
|
|
|
|
- transform: style
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- const formatedAverageSpeed = computed(() => {
|
|
|
|
- return `${Uploader.utils.formatSize(averageSpeed.value)}/s`
|
|
|
|
- })
|
|
|
|
- const status = computed(() => {
|
|
|
|
- let isError = error
|
|
|
|
- if (isComplete.value) {
|
|
|
|
- return 'success'
|
|
|
|
- } else if (isError.value) {
|
|
|
|
- return 'error'
|
|
|
|
- } else if (isUploading.value) {
|
|
|
|
- return 'uploading'
|
|
|
|
- } else if (paused.value) {
|
|
|
|
- return 'paused'
|
|
|
|
- } else {
|
|
|
|
- return 'waiting'
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- const statusText = computed(() => {
|
|
|
|
- const fileStatusText = props.file.uploader.fileStatusText
|
|
|
|
- let txt = status.value
|
|
|
|
- if (typeof fileStatusText === 'function') {
|
|
|
|
- txt = fileStatusText(status.value, response.value)
|
|
|
|
- } else {
|
|
|
|
- txt = fileStatusText[status.value]
|
|
|
|
- }
|
|
|
|
- return txt || status
|
|
|
|
- })
|
|
|
|
- const formatedTimeRemaining = computed(() => {
|
|
|
|
- const file = props.file
|
|
|
|
- if (timeRemaining.value === Number.POSITIVE_INFINITY || timeRemaining.value === 0) {
|
|
|
|
- return ''
|
|
|
|
- }
|
|
|
|
- let parsedTimeRemaining = secondsToStr(timeRemaining.value)
|
|
|
|
- const parseTimeRemaining = file.uploader.opts.parseTimeRemaining
|
|
|
|
- if (parseTimeRemaining) {
|
|
|
|
- parsedTimeRemaining = parseTimeRemaining(timeRemaining.value, parsedTimeRemaining)
|
|
|
|
- }
|
|
|
|
- return parsedTimeRemaining
|
|
|
|
- })
|
|
|
|
- const actionCheck = () => {
|
|
|
|
- paused.value = props.file.paused
|
|
|
|
- error.value = props.file.error
|
|
|
|
- isUploading.value = props.file.isUploading()
|
|
|
|
- }
|
|
|
|
- const pause = () => {
|
|
|
|
- props.file.pause()
|
|
|
|
- actionCheck()
|
|
|
|
- fileProgress()
|
|
|
|
- }
|
|
|
|
- const resume = () => {
|
|
|
|
- props.file.resume()
|
|
|
|
- actionCheck()
|
|
|
|
- }
|
|
|
|
- const remove = () => {
|
|
|
|
- props.file.cancel()
|
|
|
|
- }
|
|
|
|
- const retry = () => {
|
|
|
|
- props.file.retry()
|
|
|
|
- actionCheck()
|
|
|
|
- }
|
|
|
|
- const processResponse = (message) => {
|
|
|
|
- let res = message
|
|
|
|
- try {
|
|
|
|
- res = JSON.parse(message)
|
|
|
|
- } catch (e) {
|
|
|
|
- }
|
|
|
|
- response.value = res
|
|
|
|
- }
|
|
|
|
- const fileEventsHandler = (event, args) => {
|
|
|
|
- const rootFile = args[0]
|
|
|
|
- const file = args[1]
|
|
|
|
- const target = props.list ? rootFile : file
|
|
|
|
- if (toRaw(props.file) === toRaw(target)) {
|
|
|
|
- if (props.list && event === 'fileSuccess') {
|
|
|
|
- processResponse(args[2])
|
|
|
|
- return
|
|
|
|
- }
|
|
|
|
- instance.setupState[event](...args)
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- const fileProgress = () => {
|
|
|
|
- progress.value = props.file.progress()
|
|
|
|
- averageSpeed.value = props.file.averageSpeed
|
|
|
|
- currentSpeed.value = props.file.currentSpeed
|
|
|
|
- timeRemaining.value = props.file.timeRemaining()
|
|
|
|
- uploadedSize.value = props.file.sizeUploaded()
|
|
|
|
- actionCheck()
|
|
|
|
- }
|
|
|
|
- const fileSuccess = (rootFile, file, message) => {
|
|
|
|
- if (rootFile) {
|
|
|
|
- processResponse(message)
|
|
|
|
- }
|
|
|
|
- fileProgress()
|
|
|
|
- error.value = false
|
|
|
|
- isComplete.value = true
|
|
|
|
- isUploading.value = false
|
|
|
|
- }
|
|
|
|
- const fileComplete = () => {
|
|
|
|
- fileSuccess()
|
|
|
|
- }
|
|
|
|
- const fileError = (rootFile, file, message) => {
|
|
|
|
- fileProgress()
|
|
|
|
- processResponse(message)
|
|
|
|
- error.value = true
|
|
|
|
- isComplete.value = false
|
|
|
|
- isUploading.value = false
|
|
|
|
- }
|
|
|
|
- watch(status, (newStatus, oldStatus) => {
|
|
|
|
- if (oldStatus && newStatus === 'uploading' && oldStatus !== 'uploading') {
|
|
|
|
- tid = setTimeout(() => {
|
|
|
|
- progressingClass.value = 'uploader-file-progressing'
|
|
|
|
- }, 200)
|
|
|
|
- } else {
|
|
|
|
- clearTimeout(tid)
|
|
|
|
- progressingClass.value = ''
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- onMounted(() => {
|
|
|
|
- paused.value = props.file['paused']
|
|
|
|
- error.value = props.file['error']
|
|
|
|
- averageSpeed.value = props.file['averageSpeed']
|
|
|
|
- currentSpeed.value = props.file['currentSpeed']
|
|
|
|
- isComplete.value = props.file.isComplete()
|
|
|
|
- isUploading.value = props.file.isUploading()
|
|
|
|
- size.value = props.file.getSize()
|
|
|
|
- formatedSize.value = props.file.getFormatSize()
|
|
|
|
- uploadedSize.value = props.file.sizeUploaded()
|
|
|
|
- progress.value = props.file.progress()
|
|
|
|
- timeRemaining.value = props.file.timeRemaining()
|
|
|
|
- type.value = props.file.getType()
|
|
|
|
- extension.value = props.file.getExtension()
|
|
|
|
- const eventHandler = (event) => {
|
|
|
|
- handlers[event] = (...args) => {
|
|
|
|
- fileEventsHandler(event, args)
|
|
|
|
- }
|
|
|
|
- return handlers[event]
|
|
|
|
- }
|
|
|
|
- events.forEach((event) => {
|
|
|
|
- props.file.uploader.on(event, eventHandler(event))
|
|
|
|
- })
|
|
|
|
- })
|
|
|
|
- onUnmounted(() => {
|
|
|
|
- events.forEach((event) => {
|
|
|
|
- props.file.uploader.off(event, handlers[event])
|
|
|
|
- })
|
|
|
|
- handlers = null
|
|
|
|
- })
|
|
|
|
- return {
|
|
|
|
- response,
|
|
|
|
- paused,
|
|
|
|
- error,
|
|
|
|
- averageSpeed,
|
|
|
|
- currentSpeed,
|
|
|
|
- isComplete,
|
|
|
|
- isUploading,
|
|
|
|
- size,
|
|
|
|
- formatedSize,
|
|
|
|
- uploadedSize,
|
|
|
|
- progress,
|
|
|
|
- timeRemaining,
|
|
|
|
- type,
|
|
|
|
- extension,
|
|
|
|
- progressingClass,
|
|
|
|
- fileCategory,
|
|
|
|
- progressStyle,
|
|
|
|
- formatedAverageSpeed,
|
|
|
|
- status,
|
|
|
|
- statusText,
|
|
|
|
- formatedTimeRemaining,
|
|
|
|
- actionCheck,
|
|
|
|
- pause,
|
|
|
|
- resume,
|
|
|
|
- remove,
|
|
|
|
- retry,
|
|
|
|
- processResponse,
|
|
|
|
- fileEventsHandler,
|
|
|
|
- fileProgress,
|
|
|
|
- fileSuccess,
|
|
|
|
- fileComplete,
|
|
|
|
- fileError
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-</script>
|
|
|
|
-
|
|
|
|
-<style lang="scss" scoped>
|
|
|
|
-.uploader-file-info {
|
|
|
|
- i, em {
|
|
|
|
- font-style: normal;
|
|
|
|
- }
|
|
|
|
- &:hover {
|
|
|
|
- background-color: #e9faf4;
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-</style>
|
|
|