@matechat/core
Version:
前端智能化场景解决方案UI库,轻松构建你的AI应用。
288 lines (287 loc) • 9 kB
JavaScript
import "./index.css";
import { computed as P, defineComponent as E, inject as U, ref as b, watch as N, onMounted as S, onBeforeUnmount as R, createBlock as k, openBlock as T, Teleport as V, withDirectives as M, createElementVNode as w, renderSlot as A, vShow as O, mergeModels as x, useSlots as B, useModel as $, provide as j, createElementBlock as z, unref as g, normalizeClass as _, createCommentVNode as H, withCtx as L, createTextVNode as W, toDisplayString as q } from "vue";
import { useMcI18n as Y } from "@matechat/core/Locale";
const K = {
uploadOptions: {
type: Object,
default: () => ({})
},
disabled: {
type: Boolean,
default: !1
},
accept: {
type: String,
default: ""
},
dropPlaceholder: {
type: String
},
maxCount: {
type: Number,
default: Number.POSITIVE_INFINITY
},
maxSize: {
type: Number,
default: Number.POSITIVE_INFINITY
},
multiple: {
type: Boolean,
default: !0
},
draggable: {
type: Boolean,
default: !0
},
beforeUpload: {
type: Function,
default: null
},
getDropContainer: {
type: Function
}
}, X = {
change: (a, s) => a instanceof File && Array.isArray(s),
success: (a, s, o) => a instanceof File && Array.isArray(o),
error: (a, s, o) => a instanceof File && Array.isArray(o),
progress: (a, s) => a instanceof File && Array.isArray(s),
drop: (a) => Array.isArray(a),
validChange: (a) => Array.isArray(a)
}, I = "mc-attachment";
function G(a) {
const { file: s, options: o, onProgress: i, onSuccess: h, onError: p } = a, t = new XMLHttpRequest();
t.upload.onprogress = (l) => {
if (l.lengthComputable) {
const r = Math.round(l.loaded * 100 / l.total);
i(r);
}
}, t.onerror = () => {
p({
message: "Upload failed due to a network error.",
status: t.status,
statusText: t.statusText
});
}, t.onload = () => {
if (t.status >= 200 && t.status < 300) {
const l = o.responseType === "text" || !t.response ? t.responseText : t.response;
h(l);
} else
p({
message: `Upload failed with status: ${t.status}`,
status: t.status,
statusText: t.statusText,
response: t.response
});
};
const c = new FormData(), m = o.fileFieldName || "file";
if (c.append(m, s, s.name), o.additionalParameter)
for (const l of Object.keys(o.additionalParameter))
c.append(l, o.additionalParameter[l]);
if (t.open(o.method || "POST", o.uri, !0), o.withCredentials && (t.withCredentials = !0), o.responseType && (t.responseType = o.responseType), o.headers)
for (const l of Object.keys(o.headers))
t.setRequestHeader(l, o.headers[l]);
if (o.authToken) {
const l = o.authTokenHeader || "Authorization";
t.setRequestHeader(l, o.authToken);
}
t.send(c);
}
let J = Date.now();
function Q(a, s, o, i) {
const h = P(() => a.disabled || i.value.length >= a.maxCount), p = (r) => {
const d = URL.createObjectURL(r);
return {
uid: J++,
name: r.name,
size: r.size,
type: r.type,
status: "uploading",
percentage: 0,
url: d,
thumbUrl: d
};
}, t = async (r) => {
if (r.length === 0) return;
if (i.value.length + r.length > a.maxCount) {
s("validChange", [{ type: "exceedCount" }]);
return;
}
const d = [], u = [];
for (const n of r) {
let e = !0;
if (a.accept && a.accept !== "*") {
const f = a.accept.split(",").map((y) => y.trim().toLowerCase()), v = n.type.toLowerCase(), C = n.name.toLowerCase();
f.some((y) => y.endsWith("/*") ? v.startsWith(y.slice(0, -1)) : y.startsWith(".") ? C.endsWith(y) : v === y) || (u.push({ type: "unsupportedFileType", file: n }), e = !1);
}
if (e && n.size / 1024 / 1024 > a.maxSize && (u.push({ type: "exceedSizeLimit", file: n }), e = !1), e && a.beforeUpload)
try {
await Promise.resolve(a.beforeUpload(n)) === !1 && (u.push({ type: "beforeUploadRejected", file: n }), e = !1);
} catch {
u.push({ type: "beforeUploadRejected", file: n }), e = !1;
}
e && d.push(n);
}
if (u.length > 0 && s("validChange", u), d.length !== 0)
for (const n of d) {
const e = p(n);
i.value.push(e), s("change", n, [...i.value]), c(n, e);
}
}, c = (r, d) => {
const u = () => i.value.findIndex((n) => n.uid === d.uid);
G({
file: r,
options: a.uploadOptions,
onProgress: (n) => {
const e = u();
e > -1 && (i.value[e].percentage = n, s("progress", r, [...i.value]));
},
onSuccess: (n) => {
const e = u();
e > -1 && (i.value[e].status = "success", i.value[e].response = n, s("success", r, n, [...i.value]));
},
onError: (n) => {
const e = u();
e > -1 && (i.value[e].status = "uploadError", i.value[e].error = n, s("error", r, n, [...i.value]));
}
});
};
return {
isDisabled: h,
handleClick: () => {
var r;
h.value || (r = o.value) == null || r.click();
},
handleFileChange: (r) => {
const d = r.target.files;
d && t(Array.from(d));
},
uploadFiles: t
};
}
const Z = /* @__PURE__ */ E({
__name: "drop-area",
setup(a) {
const { rootProps: s, rootEmits: o, isDisabled: i, uploadFiles: h } = U(
I
), p = b(), t = b(), c = b(!1);
let m = 0;
N(
() => s.getDropContainer,
(e) => {
if (e) {
const f = e();
p.value !== f && (p.value = f);
}
}
);
const l = (e) => {
if (e.preventDefault(), m++, m === 1 && (c.value = !0), p.value && t.value)
if (p.value === document.body)
t.value.style.inset = "0";
else {
const { x: f, y: v, width: C, height: D } = p.value.getBoundingClientRect();
t.value.style.width = `${C}px`, t.value.style.height = `${D}px`, t.value.style.top = `${v}px`, t.value.style.left = `${f}px`;
}
}, r = (e) => {
e.preventDefault();
}, d = (e) => {
e.preventDefault(), m--, m === 0 && (c.value = !1);
}, u = (e) => {
var v;
if (e.preventDefault(), c.value = !1, m = 0, i.value) return;
const f = Array.from(((v = e.dataTransfer) == null ? void 0 : v.files) || []);
f.length > 0 && (o("drop", f), h(f));
};
function n(e) {
e.preventDefault(), c.value = !1, m = 0;
}
return S(() => {
s.getDropContainer && (p.value = s.getDropContainer()), document.body.addEventListener("dragenter", l), document.body.addEventListener("dragover", r), document.body.addEventListener("dragleave", d), document.body.addEventListener("drop", n);
}), R(() => {
document.body.removeEventListener("dragenter", l), document.body.removeEventListener("dragover", r), document.body.removeEventListener("dragleave", d), document.body.removeEventListener("drop", n);
}), (e, f) => (T(), k(V, { to: "body" }, [
M(w(
"div",
{
ref_key: "dropAreaEl",
ref: t,
class: "mc-attachment-drop-area",
onDrop: u
},
[
A(e.$slots, "default")
],
544
/* NEED_HYDRATION, NEED_PATCH */
), [
[O, c.value]
])
]));
}
}), ee = ["accept", "multiple", "disabled"], F = /* @__PURE__ */ E({
name: "McAttachment",
__name: "Attachment",
props: /* @__PURE__ */ x(K, {
modelValue: { default: [] },
modelModifiers: {}
}),
emits: /* @__PURE__ */ x(X, ["update:modelValue"]),
setup(a, { emit: s }) {
const o = a, i = s;
B();
const h = $(a, "modelValue"), { t: p } = Y(), t = b(), { handleClick: c, handleFileChange: m, isDisabled: l, uploadFiles: r } = Q(
o,
i,
t,
h
);
return j(I, {
rootProps: o,
rootEmits: i,
isDisabled: l,
uploadFiles: r
}), (d, u) => (T(), z(
"div",
{
class: _(["mc-attachment", { "is-disabled": g(l) }]),
onClick: u[1] || (u[1] = //@ts-ignore
(...n) => g(c) && g(c)(...n))
},
[
A(d.$slots, "default"),
w("input", {
ref_key: "inputRef",
ref: t,
type: "file",
class: "mc-attachment-file",
accept: d.accept,
multiple: d.multiple,
disabled: g(l),
onChange: u[0] || (u[0] = //@ts-ignore
(...n) => g(m) && g(m)(...n))
}, null, 40, ee),
d.draggable ? (T(), k(Z, { key: 0 }, {
default: L(() => [
A(d.$slots, "dropPlaceholder", {}, () => [
W(
q(d.dropPlaceholder ?? g(p)("Attachment.dragToUpload")),
1
/* TEXT */
)
])
]),
_: 3
/* FORWARDED */
})) : H("v-if", !0)
],
2
/* CLASS */
));
}
});
F.install = (a) => {
a.component("McAttachment", F);
};
export {
F as McAttachment
};