/**
 * tdesign v0.32.0
 * (c) 2021 tdesign
 * @license MIT
 */

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var _regeneratorRuntime = require('@babel/runtime/regenerator');
var findIndex = require('lodash/findIndex');
var isFunction = require('lodash/isFunction');
var tdesignIconsVue = require('tdesign-icons-vue');
var utils_mixins = require('../utils/mixins.js');
var configProvider_configReceiver = require('../config-provider/config-receiver.js');
var config = require('../config.js');
var upload_dragger = require('./dragger.js');
var upload_image = require('./image.js');
var upload_flowList = require('./flow-list.js');
var _common_js_upload_xhr = require('../_common/js/upload/xhr.js');
var button_index = require('../button/index.js');
var dialog_index = require('../dialog/index.js');
var upload_singleFile = require('./single-file.js');
var utils_renderTnode = require('../utils/render-tnode.js');
var upload_props = require('./props.js');
var utils_event = require('../utils/event.js');
require('vue');
require('../config-provider/zh_CN_config.js');
require('../loading/index.js');
require('../loading/loading.js');
require('../loading/icon/gradient.js');
require('../utils/set-style.js');
require('../utils/classnames.js');
require('../utils/dom.js');
require('raf');
require('lodash/isString');
require('../utils/easing.js');
require('../utils/transfer-dom.js');
require('../loading/props.js');
require('@babel/runtime/helpers/typeof');
require('../utils/withInstall.js');
require('lodash/capitalize');
require('../loading/plugin.js');
require('./util.js');
require('../button/button.js');
require('../button/props.js');
require('../utils/ripple.js');
require('../dialog/dialog.js');
require('../dialog/actions.js');
require('../_chunks/dep-44e6bdf6.js');
require('lodash/isObject');
require('../dialog/props.js');
require('../utils/helper.js');
require('@babel/runtime/helpers/objectWithoutProperties');
require('@babel/runtime/helpers/slicedToArray');
require('lodash/camelCase');
require('../dialog/plugin.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var _asyncToGenerator__default = /*#__PURE__*/_interopDefaultLegacy(_asyncToGenerator);
var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
var _regeneratorRuntime__default = /*#__PURE__*/_interopDefaultLegacy(_regeneratorRuntime);
var findIndex__default = /*#__PURE__*/_interopDefaultLegacy(findIndex);
var isFunction__default = /*#__PURE__*/_interopDefaultLegacy(isFunction);

function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }

function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty__default["default"](target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
var name = "".concat(config.prefix, "-upload");
var SIZE_MAP = {
  B: 1024,
  KB: 1,
  MB: 1048576,
  GB: 1073741824
};

function isOverSizeLimit(fileSize, sizeLimit, unit) {
  var units = ["B", "KB", "MB", "GB"];
  var KBIndex = 1;
  var index = units.indexOf(unit);

  if (index === -1) {
    console.warn("TDesign Upload Warn: `sizeLimit.unit` can only be one of ".concat(units.join()));
    index = KBIndex;
  }

  var num = SIZE_MAP[unit];
  var limit = index < KBIndex ? sizeLimit / num : sizeLimit * num;
  return fileSize <= limit;
}

var _Upload = utils_mixins["default"](configProvider_configReceiver["default"]("upload")).extend({
  name: "TUpload",
  components: {
    Dragger: upload_dragger["default"],
    SingleFile: upload_singleFile["default"],
    ImageCard: upload_image["default"],
    FlowList: upload_flowList["default"],
    TDialog: dialog_index.Dialog
  },
  model: {
    prop: "files",
    event: "change"
  },
  props: _objectSpread({}, upload_props["default"]),
  data: function data() {
    return {
      dragActive: false,
      loadingFile: null,
      toUploadFiles: [],
      errorMsg: "",
      showImageViewDialog: false,
      showImageViewUrl: "",
      xhrReq: null
    };
  },
  computed: {
    showTips: function showTips() {
      if (this.theme === "file") {
        var hasNoFile = (!this.files || !this.files.length) && !this.loadingFile;
        return this.tips && hasNoFile;
      }

      return Boolean(this.tips);
    },
    showCustomDisplay: function showCustomDisplay() {
      return this.theme === "custom";
    },
    showSingleDisplay: function showSingleDisplay() {
      return !this.draggable && ["file", "file-input"].includes(this.theme);
    },
    showImgCard: function showImgCard() {
      return !this.draggable && this.theme === "image";
    },
    singleDraggable: function singleDraggable() {
      return !this.multiple && this.draggable && ["file", "file-input", "image"].includes(this.theme);
    },
    showUploadList: function showUploadList() {
      return this.multiple && ["file-flow", "image-flow"].includes(this.theme);
    },
    showImgDialog: function showImgDialog() {
      return ["image", "image-flow", "custom"].includes(this.theme);
    },
    showErrorMsg: function showErrorMsg() {
      return !this.showUploadList && !!this.errorMsg;
    },
    tipsClasses: function tipsClasses() {
      return ["".concat(name, "__tips ").concat(config.prefix, "-size-s")];
    },
    errorClasses: function errorClasses() {
      return this.tipsClasses.concat("".concat(name, "__tips-error"));
    }
  },
  methods: {
    emitChangeEvent: function emitChangeEvent(files, ctx) {
      utils_event.emitEvent(this, "change", files, ctx);
    },
    emitRemoveEvent: function emitRemoveEvent(ctx) {
      utils_event.emitEvent(this, "remove", ctx);
    },
    handlePreviewImg: function handlePreviewImg(event, file) {
      if (!file.url) throw new Error("Error file");
      this.showImageViewUrl = file.url;
      this.showImageViewDialog = true;
      var previewCtx = {
        file: file,
        e: event
      };
      utils_event.emitEvent(this, "preview", previewCtx);
    },
    handleChange: function handleChange(event) {
      var files = event.target.files;
      if (this.disabled) return;
      this.uploadFiles(files);
      this.$refs.input.value = "";
    },
    handleDragChange: function handleDragChange(files) {
      if (this.disabled) return;
      this.uploadFiles(files);
    },
    handleSingleRemove: function handleSingleRemove(e) {
      var changeCtx = {
        trigger: "remove"
      };
      if (this.loadingFile) this.loadingFile = null;
      this.errorMsg = "";
      this.emitChangeEvent([], changeCtx);
      this.emitRemoveEvent({
        e: e
      });
    },
    handleFileInputRemove: function handleFileInputRemove(e) {
      e === null || e === void 0 ? void 0 : e.stopPropagation();
      this.handleSingleRemove(e);
    },
    handleMultipleRemove: function handleMultipleRemove(options) {
      var changeCtx = _objectSpread({
        trigger: "remove"
      }, options);

      var files = this.files.concat();
      files.splice(options.index, 1);
      this.emitChangeEvent(files, changeCtx);
      this.emitRemoveEvent(options);
    },
    handleListRemove: function handleListRemove(context) {
      var file = context.file;
      var index = findIndex__default["default"](this.toUploadFiles, function (o) {
        return o.name === file.name;
      });

      if (index >= 0) {
        this.toUploadFiles.splice(index, 1);
      } else {
        var index2 = findIndex__default["default"](this.files, function (o) {
          return o.name === file.name;
        });
        this.handleMultipleRemove({
          e: context.e,
          index: index2
        });
      }
    },
    uploadFiles: function uploadFiles(files) {
      var _this = this;

      var tmpFiles = _toConsumableArray__default["default"](files);

      if (this.max) {
        tmpFiles = tmpFiles.slice(0, this.max - this.files.length);

        if (tmpFiles.length !== files.length) {
          console.warn("TDesign Upload Warn: you can only upload ".concat(this.max, " files"));
        }
      }

      tmpFiles.forEach(function (fileRaw) {
        var file = fileRaw;

        if (typeof _this.format === "function") {
          file = _this.format(fileRaw);
        }

        var uploadFile = _objectSpread({
          raw: fileRaw,
          lastModified: fileRaw.lastModified,
          name: fileRaw.name,
          size: fileRaw.size,
          type: fileRaw.type,
          percent: 0,
          status: "waiting"
        }, file);

        var reader = new FileReader();
        reader.readAsDataURL(fileRaw);

        reader.onload = function (event) {
          uploadFile.url = event.target.result;
        };

        _this.handleBeforeUpload(file).then(function (canUpload) {
          if (!canUpload) return;

          var newFiles = _this.toUploadFiles.concat();

          newFiles.push(uploadFile);
          _this.toUploadFiles = _toConsumableArray__default["default"](new Set(newFiles));
          _this.loadingFile = uploadFile;

          if (_this.autoUpload) {
            _this.upload(uploadFile);
          }
        });
      });
    },
    upload: function upload(file) {
      var _this2 = this;

      return _asyncToGenerator__default["default"]( /*#__PURE__*/_regeneratorRuntime__default["default"].mark(function _callee() {
        var request;
        return _regeneratorRuntime__default["default"].wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                if (!(!_this2.action && !_this2.requestMethod)) {
                  _context.next = 3;
                  break;
                }

                console.error("TDesign Upload Error: one of action and requestMethod must be exist.");
                return _context.abrupt("return");

              case 3:
                _this2.errorMsg = "";
                file.status = "progress";
                _this2.loadingFile = file;

                if (_this2.requestMethod) {
                  _this2.handleRequestMethod(file);
                } else {
                  if (_this2.useMockProgress) {
                    _this2.handleMockProgress(file);
                  }

                  request = _common_js_upload_xhr["default"];
                  _this2.xhrReq = request({
                    action: _this2.action,
                    data: _this2.data,
                    file: file,
                    name: _this2.name,
                    headers: _this2.headers,
                    withCredentials: _this2.withCredentials,
                    onError: _this2.onError,
                    onProgress: _this2.handleProgress,
                    onSuccess: _this2.handleSuccess
                  });
                }

              case 7:
              case "end":
                return _context.stop();
            }
          }
        }, _callee);
      }))();
    },
    handleMockProgress: function handleMockProgress(file) {
      var _this3 = this;

      var timer = setInterval(function () {
        if (file.status === "success" || file.percent >= 99) {
          clearInterval(timer);
          return;
        }

        file.percent += 1;

        _this3.handleProgress({
          file: file,
          percent: file.percent,
          type: "mock"
        });
      }, 10);
    },
    handleRequestMethod: function handleRequestMethod(file) {
      var _this4 = this;

      if (!isFunction__default["default"](this.requestMethod)) {
        console.warn("TDesign Upload Warn: `requestMethod` must be a function.");
        return;
      }

      this.requestMethod(file).then(function (res) {
        if (!_this4.handleRequestMethodResponse(res)) return;

        if (res.status === "success") {
          _this4.handleSuccess({
            file: file,
            response: res.response
          });
        } else if (res.status === "fail") {
          var r = res.response || {};

          _this4.onError({
            file: file,
            response: _objectSpread(_objectSpread({}, r), {}, {
              error: res.error
            })
          });
        }
      });
    },
    handleRequestMethodResponse: function handleRequestMethodResponse(res) {
      if (!res) {
        console.error("TDesign Upoad Error: `requestMethodResponse` is required.");
        return false;
      }

      if (!res.status) {
        console.error("TDesign Upoad Error: `requestMethodResponse.status` is missing, which value is `success` or `fail`");
        return false;
      }

      if (!["success", "fail"].includes(res.status)) {
        console.error("TDesign Upoad Error: `requestMethodResponse.status` must be `success` or `fail`");
        return false;
      }

      if (res.status === "success" && (!res.response || !res.response.url)) {
        console.warn("TDesign Upoad Warn: `requestMethodResponse.response.url` is required, when `status` is `success`");
      }

      return true;
    },
    multipleUpload: function multipleUpload(files) {
      var _this5 = this;

      files.forEach(function (file) {
        _this5.upload(file);
      });
    },
    onError: function onError(options) {
      var _res;

      var event = options.event,
          file = options.file,
          response = options.response,
          resFormatted = options.resFormatted;
      file.status = "fail";
      this.loadingFile = file;
      var res = response;

      if (!resFormatted && typeof this.formatResponse === "function") {
        res = this.formatResponse(response, {
          file: file
        });
      }

      this.errorMsg = (_res = res) === null || _res === void 0 ? void 0 : _res.error;
      var context = {
        e: event,
        file: file
      };
      utils_event.emitEvent(this, "fail", context);
    },
    handleProgress: function handleProgress(_ref) {
      var event = _ref.event,
          file = _ref.file,
          percent = _ref.percent,
          _ref$type = _ref.type,
          type = _ref$type === void 0 ? "real" : _ref$type;
      file.percent = Math.min(percent, 100);
      this.loadingFile = file;
      var progressCtx = {
        percent: percent,
        e: event,
        file: file,
        type: type
      };
      utils_event.emitEvent(this, "progress", progressCtx);
    },
    handleSuccess: function handleSuccess(_ref2) {
      var _res2;

      var event = _ref2.event,
          file = _ref2.file,
          response = _ref2.response;
      file.status = "success";
      var res = response;

      if (typeof this.formatResponse === "function") {
        res = this.formatResponse(response, {
          file: file
        });
      }

      if ((_res2 = res) !== null && _res2 !== void 0 && _res2.error) {
        this.onError({
          event: event,
          file: file,
          response: res,
          resFormatted: true
        });
        return;
      }

      file.url = res.url || file.url;
      var index = findIndex__default["default"](this.toUploadFiles, function (o) {
        return o.name === file.name;
      });
      this.toUploadFiles.splice(index, 1);

      var newFile = _objectSpread(_objectSpread({}, file), {}, {
        response: res
      });

      var files = this.multiple ? this.files.concat(newFile) : [newFile];
      var context = {
        e: event,
        response: res,
        trigger: "upload-success"
      };
      this.emitChangeEvent(files, context);
      var sContext = {
        file: file,
        fileList: files,
        e: event,
        response: res
      };
      utils_event.emitEvent(this, "success", sContext);
      this.loadingFile = null;
    },
    handlePreview: function handlePreview(_ref3) {
      var file = _ref3.file,
          event = _ref3.event;
      return {
        file: file,
        event: event
      };
    },
    triggerUpload: function triggerUpload() {
      if (this.disabled) return;
      this.$refs.input.click();
    },
    handleDragenter: function handleDragenter(e) {
      if (this.disabled) return;
      this.dragActive = true;
      utils_event.emitEvent(this, "dragenter", {
        e: e
      });
    },
    handleDragleave: function handleDragleave(e) {
      if (this.disabled) return;
      this.dragActive = false;
      utils_event.emitEvent(this, "dragleave", {
        e: e
      });
    },
    handleBeforeUpload: function handleBeforeUpload(file) {
      var _this6 = this;

      if (typeof this.beforeUpload === "function") {
        var r = this.beforeUpload(file);
        if (r instanceof Promise) return r;
        return new Promise(function (resolve) {
          return resolve(r);
        });
      }

      return new Promise(function (resolve) {
        if (_this6.sizeLimit) {
          resolve(_this6.handleSizeLimit(file.size));
        }

        resolve(true);
      });
    },
    handleSizeLimit: function handleSizeLimit(fileSize) {
      var sizeLimit = typeof this.sizeLimit === "number" ? {
        size: this.sizeLimit,
        unit: "KB"
      } : this.sizeLimit;
      var rSize = isOverSizeLimit(fileSize, sizeLimit.size, sizeLimit.unit);

      if (!rSize) {
        this.errorMsg = sizeLimit.message ? this.t(sizeLimit.message, {
          sizeLimit: sizeLimit.size
        }) : "".concat(this.t(this.global.sizeLimitMessage, {
          sizeLimit: sizeLimit.size
        }), " ").concat(sizeLimit.unit);
      }

      return rSize;
    },
    cancelUpload: function cancelUpload() {
      if (this.loadingFile) {
        if (this.requestMethod) {
          utils_event.emitEvent(this, "cancel-upload");
        } else {
          this.xhrReq && this.xhrReq.abort();
        }

        this.loadingFile = null;
      }

      this.$refs.input.value = "";
    },
    cancelPreviewImgDialog: function cancelPreviewImgDialog() {
      var _this7 = this;

      this.showImageViewDialog = false;
      var timer = setTimeout(function () {
        _this7.showImageViewUrl = "";
        clearTimeout(timer);
        timer = null;
      }, 500);
    },
    getDefaultTrigger: function getDefaultTrigger() {
      var _this$files2;

      var h = this.$createElement;

      if (this.theme === "file-input" || this.showUploadList) {
        var _this$files;

        return h(button_index.Button, {
          "attrs": {
            "variant": "outline"
          }
        }, [(_this$files = this.files) !== null && _this$files !== void 0 && _this$files.length ? "\u91CD\u65B0\u4E0A\u4F20" : "\u9009\u62E9\u6587\u4EF6"]);
      }

      return h(button_index.Button, {
        "attrs": {
          "variant": "outline"
        }
      }, [h(tdesignIconsVue.UploadIcon, {
        "slot": "icon"
      }), (_this$files2 = this.files) !== null && _this$files2 !== void 0 && _this$files2.length ? "\u91CD\u65B0\u4E0A\u4F20" : "\u70B9\u51FB\u4E0A\u4F20"]);
    },
    renderInput: function renderInput() {
      var h = this.$createElement;
      return h("input", {
        "ref": "input",
        "attrs": {
          "type": "file",
          "disabled": this.disabled,
          "multiple": this.multiple,
          "accept": this.accept,
          "hidden": true
        },
        "on": {
          "change": this.handleChange
        }
      });
    },
    renderSingleDisplay: function renderSingleDisplay(triggerElement) {
      var h = this.$createElement;
      return h(upload_singleFile["default"], {
        "attrs": {
          "file": this.files && this.files[0],
          "loadingFile": this.loadingFile,
          "display": this.theme,
          "remove": this.handleSingleRemove,
          "showUploadProgress": this.showUploadProgress,
          "placeholder": this.placeholder
        }
      }, [h("div", {
        "class": "".concat(name, "__trigger"),
        "on": {
          "click": this.triggerUpload
        }
      }, [triggerElement])]);
    },
    renderDraggerTrigger: function renderDraggerTrigger() {
      var h = this.$createElement;
      var params = {
        dragActive: this.dragActive,
        uploadingFile: this.multiple ? this.toUploadFiles : this.loadingFile
      };
      var triggerElement = utils_renderTnode.renderContent(this, "default", "trigger", {
        params: params
      });
      return h(upload_dragger["default"], {
        "attrs": {
          "showUploadProgress": this.showUploadProgress,
          "loadingFile": this.loadingFile,
          "file": this.files && this.files[0],
          "display": this.theme,
          "cancel": this.cancelUpload,
          "trigger": this.triggerUpload,
          "remove": this.handleSingleRemove,
          "upload": this.upload,
          "autoUpload": this.autoUpload
        },
        "on": {
          "change": this.handleDragChange,
          "dragenter": this.handleDragenter,
          "dragleave": this.handleDragleave
        }
      }, [triggerElement]);
    },
    renderTrigger: function renderTrigger() {
      var defaultNode = this.getDefaultTrigger();
      return utils_renderTnode.renderContent(this, "default", "trigger", defaultNode);
    },
    renderCustom: function renderCustom(triggerElement) {
      var h = this.$createElement;
      return this.draggable ? this.renderDraggerTrigger() : h("div", {
        "class": "".concat(name, "__trigger"),
        "on": {
          "click": this.triggerUpload
        }
      }, [triggerElement]);
    }
  },
  render: function render() {
    var h = arguments[0];
    var triggerElement = this.renderTrigger();
    return h("div", {
      "class": "".concat(name)
    }, [this.renderInput(), this.showCustomDisplay && this.renderCustom(triggerElement), this.showSingleDisplay && this.renderSingleDisplay(triggerElement), this.singleDraggable && this.renderDraggerTrigger(), this.showImgCard && h(upload_image["default"], {
      "attrs": {
        "files": this.files,
        "multiple": this.multiple,
        "remove": this.handleMultipleRemove,
        "trigger": this.triggerUpload,
        "loadingFile": this.loadingFile,
        "toUploadFiles": this.toUploadFiles,
        "max": this.max,
        "disabled": this.disabled
      },
      "on": {
        "imgPreview": this.handlePreviewImg
      }
    }), this.showUploadList && h(upload_flowList["default"], {
      "attrs": {
        "files": this.files,
        "placeholder": this.placeholder,
        "autoUpload": this.autoUpload,
        "toUploadFiles": this.toUploadFiles,
        "remove": this.handleListRemove,
        "showUploadProgress": this.showUploadProgress,
        "upload": this.multipleUpload,
        "cancel": this.cancelUpload,
        "display": this.theme
      },
      "on": {
        "imgPreview": this.handlePreviewImg,
        "change": this.handleDragChange,
        "dragenter": this.handleDragenter,
        "dragleave": this.handleDragleave
      }
    }, [h("div", {
      "class": "".concat(name, "__trigger"),
      "on": {
        "click": this.triggerUpload
      }
    }, [triggerElement])]), this.showImgDialog && h(dialog_index.Dialog, {
      "attrs": {
        "visible": this.showImageViewDialog,
        "showOverlay": true,
        "width": "auto",
        "top": "10%",
        "footer": false,
        "header": false
      },
      "class": "".concat(name, "__dialog"),
      "on": {
        "close": this.cancelPreviewImgDialog
      }
    }, [h("div", {
      "class": "".concat(config.prefix, "__dialog-body-img-box")
    }, [h("img", {
      "attrs": {
        "src": this.showImageViewUrl,
        "alt": ""
      }
    })])]), !this.errorMsg && this.showTips && h("small", {
      "class": this.tipsClasses
    }, [this.tips]), this.showErrorMsg && h("small", {
      "class": this.errorClasses
    }, [this.errorMsg])]);
  }
});

exports["default"] = _Upload;
//# sourceMappingURL=upload.js.map
