mirror of
https://github.com/sune-org/sune.git
synced 2026-10-16 15:27:52 +00:00
This build was committed by a bot.
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
import { t as require___vite_browser_external } from "./src-Bv2YeDx1.js";
|
||||||
|
export default require___vite_browser_external();
|
||||||
+257
-78
@@ -1,3 +1,4 @@
|
|||||||
|
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/mediabunny-aac-encoder-CtuZhjiD.js","assets/src-Bv2YeDx1.js"])))=>i.map(i=>d[i]);
|
||||||
import mathjax3 from "https://esm.sh/markdown-it-mathjax3";
|
import mathjax3 from "https://esm.sh/markdown-it-mathjax3";
|
||||||
//#region \0vite/modulepreload-polyfill.js
|
//#region \0vite/modulepreload-polyfill.js
|
||||||
(function polyfill() {
|
(function polyfill() {
|
||||||
@@ -664,11 +665,213 @@ function kbBind() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
//#endregion
|
//#endregion
|
||||||
|
//#region \0vite/preload-helper.js
|
||||||
|
var scriptRel = "modulepreload";
|
||||||
|
var assetsURL = function(dep) {
|
||||||
|
return "/" + dep;
|
||||||
|
};
|
||||||
|
var seen = {};
|
||||||
|
var __vitePreload = function preload(baseModule, deps, importerUrl) {
|
||||||
|
let promise = Promise.resolve();
|
||||||
|
if (deps && deps.length > 0) {
|
||||||
|
const links = document.getElementsByTagName("link");
|
||||||
|
const cspNonceMeta = document.querySelector("meta[property=csp-nonce]");
|
||||||
|
const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
|
||||||
|
function allSettled(promises) {
|
||||||
|
return Promise.all(promises.map((p) => Promise.resolve(p).then((value) => ({
|
||||||
|
status: "fulfilled",
|
||||||
|
value
|
||||||
|
}), (reason) => ({
|
||||||
|
status: "rejected",
|
||||||
|
reason
|
||||||
|
}))));
|
||||||
|
}
|
||||||
|
promise = allSettled(deps.map((dep) => {
|
||||||
|
dep = assetsURL(dep, importerUrl);
|
||||||
|
if (dep in seen) return;
|
||||||
|
seen[dep] = true;
|
||||||
|
const isCss = dep.endsWith(".css");
|
||||||
|
const cssSelector = isCss ? "[rel=\"stylesheet\"]" : "";
|
||||||
|
if (!!importerUrl) for (let i = links.length - 1; i >= 0; i--) {
|
||||||
|
const link = links[i];
|
||||||
|
if (link.href === dep && (!isCss || link.rel === "stylesheet")) return;
|
||||||
|
}
|
||||||
|
else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) return;
|
||||||
|
const link = document.createElement("link");
|
||||||
|
link.rel = isCss ? "stylesheet" : scriptRel;
|
||||||
|
if (!isCss) link.as = "script";
|
||||||
|
link.crossOrigin = "";
|
||||||
|
link.href = dep;
|
||||||
|
if (cspNonce) link.setAttribute("nonce", cspNonce);
|
||||||
|
document.head.appendChild(link);
|
||||||
|
if (isCss) return new Promise((res, rej) => {
|
||||||
|
link.addEventListener("load", res);
|
||||||
|
link.addEventListener("error", () => rej(/* @__PURE__ */ new Error(`Unable to preload CSS for ${dep}`)));
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
function handlePreloadError(err) {
|
||||||
|
const e = new Event("vite:preloadError", { cancelable: true });
|
||||||
|
e.payload = err;
|
||||||
|
window.dispatchEvent(e);
|
||||||
|
if (!e.defaultPrevented) throw err;
|
||||||
|
}
|
||||||
|
return promise.then((res) => {
|
||||||
|
for (const item of res || []) {
|
||||||
|
if (item.status !== "rejected") continue;
|
||||||
|
handlePreloadError(item.reason);
|
||||||
|
}
|
||||||
|
return baseModule().catch(handlePreloadError);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//#endregion
|
||||||
|
//#region src/video.js
|
||||||
|
var SHORT_SIDE = 360, FPS = 4, VIDEO_BPS = {
|
||||||
|
hevc: 13e4,
|
||||||
|
avc: 16e4
|
||||||
|
}, AUDIO_BPS = 32e3;
|
||||||
|
var even = (n) => Math.max(2, Math.round(n / 2) * 2);
|
||||||
|
var mb;
|
||||||
|
var loadMb = async () => {
|
||||||
|
if (mb) return mb;
|
||||||
|
const m = await __vitePreload(() => import("./src-Bv2YeDx1.js"), []);
|
||||||
|
if (!await m.canEncodeAudio("aac", {
|
||||||
|
numberOfChannels: 1,
|
||||||
|
sampleRate: 48e3,
|
||||||
|
bitrate: AUDIO_BPS
|
||||||
|
})) (await __vitePreload(async () => {
|
||||||
|
const { registerAacEncoder } = await import("./mediabunny-aac-encoder-CtuZhjiD.js");
|
||||||
|
return { registerAacEncoder };
|
||||||
|
}, __vite__mapDeps([0,1]))).registerAacEncoder();
|
||||||
|
return mb = m;
|
||||||
|
};
|
||||||
|
var isVideo = (name, mime) => /^video\//.test(mime) || /\.(mp4|m4v|mov|webm|mkv|3gp)$/i.test(name);
|
||||||
|
async function compressVideo(file, { onProgress, signal } = {}) {
|
||||||
|
const { Input, Output, Conversion, ALL_FORMATS, BlobSource, BufferTarget, Mp4OutputFormat, Quality, canEncodeVideo } = await loadMb();
|
||||||
|
const input = new Input({
|
||||||
|
source: new BlobSource(file),
|
||||||
|
formats: ALL_FORMATS
|
||||||
|
}), track = await input.getPrimaryVideoTrack();
|
||||||
|
if (!track) throw new Error("no video track");
|
||||||
|
const w = await track.getDisplayWidth(), h = await track.getDisplayHeight(), s = Math.min(1, SHORT_SIDE / Math.min(w, h)), width = even(w * s), height = even(h * s);
|
||||||
|
let codec = null;
|
||||||
|
for (const c of ["hevc", "avc"]) if (await canEncodeVideo(c, {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
frameRate: FPS,
|
||||||
|
bitrate: VIDEO_BPS[c]
|
||||||
|
})) {
|
||||||
|
codec = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!codec) throw new Error("this device cannot encode HEVC or H.264");
|
||||||
|
const output = new Output({
|
||||||
|
format: new Mp4OutputFormat({ fastStart: "in-memory" }),
|
||||||
|
target: new BufferTarget()
|
||||||
|
});
|
||||||
|
const video = {
|
||||||
|
frameRate: FPS,
|
||||||
|
codec,
|
||||||
|
quality: new Quality({ bitrate: VIDEO_BPS[codec] }),
|
||||||
|
forceTranscode: true
|
||||||
|
};
|
||||||
|
if (await track.getFlip()) Object.assign(video, {
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
fit: "fill"
|
||||||
|
});
|
||||||
|
else {
|
||||||
|
const cx = new OffscreenCanvas(width, height).getContext("2d"), rot = await track.getRotation();
|
||||||
|
cx.imageSmoothingQuality = "high";
|
||||||
|
Object.assign(video, {
|
||||||
|
process: (f) => (f.draw(cx, 0, 0, width, height), cx.canvas),
|
||||||
|
processedWidth: width,
|
||||||
|
processedHeight: height,
|
||||||
|
rotate: (360 - rot) % 360
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const conv = await Conversion.init({
|
||||||
|
input,
|
||||||
|
output,
|
||||||
|
tracks: "primary",
|
||||||
|
video,
|
||||||
|
audio: {
|
||||||
|
numberOfChannels: 1,
|
||||||
|
codec: "aac",
|
||||||
|
quality: new Quality({ bitrate: AUDIO_BPS }),
|
||||||
|
forceTranscode: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (!conv.isValid) throw new Error(conv.discardedTracks.map((t) => t.reason).join(", ") || "unsupported video");
|
||||||
|
if (signal) {
|
||||||
|
if (signal.aborted) return null;
|
||||||
|
signal.addEventListener("abort", () => conv.cancel(), { once: true });
|
||||||
|
}
|
||||||
|
conv.onProgress = (p) => onProgress?.(p);
|
||||||
|
try {
|
||||||
|
await conv.execute();
|
||||||
|
} catch (e) {
|
||||||
|
if (signal?.aborted) return null;
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: "video_url",
|
||||||
|
video_url: { url: await asDataURL(new Blob([output.target.buffer], { type: "video/mp4" })) }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var blobUrls = /* @__PURE__ */ new Set();
|
||||||
|
var toBlobUrl = async (u) => {
|
||||||
|
const o = URL.createObjectURL(await (await fetch(u)).blob());
|
||||||
|
blobUrls.add(o);
|
||||||
|
return o;
|
||||||
|
};
|
||||||
|
var revokeVideoUrls = () => {
|
||||||
|
blobUrls.forEach((u) => URL.revokeObjectURL(u));
|
||||||
|
blobUrls.clear();
|
||||||
|
};
|
||||||
|
function openPlayer(src) {
|
||||||
|
const o = document.createElement("div");
|
||||||
|
o.className = "fixed inset-0 z-[70] bg-black flex items-center justify-center";
|
||||||
|
o.innerHTML = "<video controls autoplay playsinline class=\"h-full w-full object-contain\"></video><button type=\"button\" aria-label=\"Close\" class=\"absolute top-3 right-3 h-10 w-10 rounded-full bg-white/15 text-white inline-flex items-center justify-center\"><i data-lucide=\"x\" class=\"h-6 w-6\"></i></button>";
|
||||||
|
const v = o.querySelector("video"), done = () => {
|
||||||
|
v.pause();
|
||||||
|
o.remove();
|
||||||
|
removeEventListener("keydown", esc);
|
||||||
|
document.fullscreenElement && document.exitFullscreen().catch(() => {});
|
||||||
|
}, esc = (e) => e.key === "Escape" && history.back();
|
||||||
|
v.src = src;
|
||||||
|
history.pushState({ video: 1 }, "");
|
||||||
|
addEventListener("popstate", done, { once: true });
|
||||||
|
addEventListener("keydown", esc);
|
||||||
|
o.querySelector("button").onclick = () => history.back();
|
||||||
|
o.addEventListener("fullscreenchange", () => !document.fullscreenElement && o.isConnected && history.back());
|
||||||
|
document.body.append(o);
|
||||||
|
window.lucide?.createIcons();
|
||||||
|
o.requestFullscreen?.().catch(() => {});
|
||||||
|
}
|
||||||
|
function videoStrip(parts) {
|
||||||
|
const wrap = document.createElement("div");
|
||||||
|
wrap.className = "flex gap-2 overflow-x-auto no-scrollbar px-4";
|
||||||
|
for (const p of parts) {
|
||||||
|
const b = document.createElement("button");
|
||||||
|
b.type = "button";
|
||||||
|
b.setAttribute("aria-label", "Play video");
|
||||||
|
b.className = "relative shrink-0 h-40 rounded-xl overflow-hidden bg-black";
|
||||||
|
b.innerHTML = "<video muted playsinline preload=\"metadata\" class=\"h-full w-auto min-w-24 object-cover pointer-events-none\"></video><span class=\"absolute inset-0 flex items-center justify-center\"><span class=\"h-10 w-10 rounded-full bg-black/60 text-white inline-flex items-center justify-center\"><i data-lucide=\"play\" class=\"h-5 w-5\"></i></span></span>";
|
||||||
|
const src = toBlobUrl(p.video_url?.url || "");
|
||||||
|
src.then((u) => b.querySelector("video").src = u + "#t=0.1").catch(() => {});
|
||||||
|
b.onclick = async () => openPlayer(await src);
|
||||||
|
wrap.append(b);
|
||||||
|
}
|
||||||
|
return wrap;
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
//#region src/attachments.js
|
//#region src/attachments.js
|
||||||
async function toAttach(file) {
|
async function toAttach(file, opts) {
|
||||||
if (!file) return null;
|
if (!file) return null;
|
||||||
if (file instanceof File) {
|
if (file instanceof File) {
|
||||||
const name = file.name || "file", mime = (file.type || "application/octet-stream").toLowerCase();
|
const name = file.name || "file", mime = (file.type || "application/octet-stream").toLowerCase();
|
||||||
|
if (isVideo(name, mime)) return compressVideo(file, opts);
|
||||||
if (/^image\//.test(mime) || /\.(png|jpe?g|webp|gif)$/i.test(name)) return {
|
if (/^image\//.test(mime) || /\.(png|jpe?g|webp|gif)$/i.test(name)) return {
|
||||||
type: "image_url",
|
type: "image_url",
|
||||||
image_url: { url: mime === "image/webp" || /\.webp$/i.test(name) ? await asDataURL(file) : await imgToWebp(file, 2048, 94) }
|
image_url: { url: mime === "image/webp" || /\.webp$/i.test(name) ? await asDataURL(file) : await imgToWebp(file, 2048, 94) }
|
||||||
@@ -711,6 +914,10 @@ async function toAttach(file) {
|
|||||||
file_data: file.data
|
file_data: file.data
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
if (/^video\//.test(mime)) return {
|
||||||
|
type: "video_url",
|
||||||
|
video_url: { url: `data:${mime};base64,${file.data}` }
|
||||||
|
};
|
||||||
if (/^audio\//.test(mime)) {
|
if (/^audio\//.test(mime)) {
|
||||||
const fmt = /mp3/.test(mime) ? "mp3" : "wav";
|
const fmt = /mp3/.test(mime) ? "mp3" : "wav";
|
||||||
return {
|
return {
|
||||||
@@ -813,66 +1020,6 @@ var renderSuneHTML = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
//#endregion
|
//#endregion
|
||||||
//#region \0vite/preload-helper.js
|
|
||||||
var scriptRel = "modulepreload";
|
|
||||||
var assetsURL = function(dep) {
|
|
||||||
return "/" + dep;
|
|
||||||
};
|
|
||||||
var seen = {};
|
|
||||||
var __vitePreload = function preload(baseModule, deps, importerUrl) {
|
|
||||||
let promise = Promise.resolve();
|
|
||||||
if (deps && deps.length > 0) {
|
|
||||||
const links = document.getElementsByTagName("link");
|
|
||||||
const cspNonceMeta = document.querySelector("meta[property=csp-nonce]");
|
|
||||||
const cspNonce = cspNonceMeta?.nonce || cspNonceMeta?.getAttribute("nonce");
|
|
||||||
function allSettled(promises) {
|
|
||||||
return Promise.all(promises.map((p) => Promise.resolve(p).then((value) => ({
|
|
||||||
status: "fulfilled",
|
|
||||||
value
|
|
||||||
}), (reason) => ({
|
|
||||||
status: "rejected",
|
|
||||||
reason
|
|
||||||
}))));
|
|
||||||
}
|
|
||||||
promise = allSettled(deps.map((dep) => {
|
|
||||||
dep = assetsURL(dep, importerUrl);
|
|
||||||
if (dep in seen) return;
|
|
||||||
seen[dep] = true;
|
|
||||||
const isCss = dep.endsWith(".css");
|
|
||||||
const cssSelector = isCss ? "[rel=\"stylesheet\"]" : "";
|
|
||||||
if (!!importerUrl) for (let i = links.length - 1; i >= 0; i--) {
|
|
||||||
const link = links[i];
|
|
||||||
if (link.href === dep && (!isCss || link.rel === "stylesheet")) return;
|
|
||||||
}
|
|
||||||
else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) return;
|
|
||||||
const link = document.createElement("link");
|
|
||||||
link.rel = isCss ? "stylesheet" : scriptRel;
|
|
||||||
if (!isCss) link.as = "script";
|
|
||||||
link.crossOrigin = "";
|
|
||||||
link.href = dep;
|
|
||||||
if (cspNonce) link.setAttribute("nonce", cspNonce);
|
|
||||||
document.head.appendChild(link);
|
|
||||||
if (isCss) return new Promise((res, rej) => {
|
|
||||||
link.addEventListener("load", res);
|
|
||||||
link.addEventListener("error", () => rej(/* @__PURE__ */ new Error(`Unable to preload CSS for ${dep}`)));
|
|
||||||
});
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
function handlePreloadError(err) {
|
|
||||||
const e = new Event("vite:preloadError", { cancelable: true });
|
|
||||||
e.payload = err;
|
|
||||||
window.dispatchEvent(e);
|
|
||||||
if (!e.defaultPrevented) throw err;
|
|
||||||
}
|
|
||||||
return promise.then((res) => {
|
|
||||||
for (const item of res || []) {
|
|
||||||
if (item.status !== "rejected") continue;
|
|
||||||
handlePreloadError(item.reason);
|
|
||||||
}
|
|
||||||
return baseModule().catch(handlePreloadError);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
//#endregion
|
|
||||||
//#region src/main.js
|
//#region src/main.js
|
||||||
(() => {
|
(() => {
|
||||||
let k, v = visualViewport;
|
let k, v = visualViewport;
|
||||||
@@ -1299,6 +1446,8 @@ function _createMessageRow(m) {
|
|||||||
$head.append($avatar, $name, $copyBtn, $deleteBtn);
|
$head.append($avatar, $name, $copyBtn, $deleteBtn);
|
||||||
const $bubble = $(`<div class="${(isUser ? "bg-gray-50 border border-gray-200" : "bg-gray-100") + " msg-bubble markdown-body rounded-none px-4 py-3 w-full"}"></div>`);
|
const $bubble = $(`<div class="${(isUser ? "bg-gray-50 border border-gray-200" : "bg-gray-100") + " msg-bubble markdown-body rounded-none px-4 py-3 w-full"}"></div>`);
|
||||||
$row.append($head, $bubble);
|
$row.append($head, $bubble);
|
||||||
|
const vids = (Array.isArray(meta.content) ? meta.content : []).filter((p) => p?.type === "video_url");
|
||||||
|
if (vids.length) $row.append(videoStrip(vids));
|
||||||
return $row;
|
return $row;
|
||||||
}
|
}
|
||||||
function msgRow(m) {
|
function msgRow(m) {
|
||||||
@@ -1334,9 +1483,8 @@ var clearChat = () => {
|
|||||||
el.suneHtml.dispatchEvent(new CustomEvent("sune:unmount"));
|
el.suneHtml.dispatchEvent(new CustomEvent("sune:unmount"));
|
||||||
state.messages = [];
|
state.messages = [];
|
||||||
el.messages.innerHTML = "";
|
el.messages.innerHTML = "";
|
||||||
state.attachments = [];
|
clearAttachments();
|
||||||
updateAttachBadge();
|
revokeVideoUrls();
|
||||||
el.fileInput.value = "";
|
|
||||||
};
|
};
|
||||||
var payloadWithSampling = (b) => {
|
var payloadWithSampling = (b) => {
|
||||||
const o = Object.assign({}, b), s = SUNE, p = {
|
const o = Object.assign({}, b), s = SUNE, p = {
|
||||||
@@ -1736,21 +1884,49 @@ $(el.sunesSyncDownloadBtn).on("click", () => {
|
|||||||
hideSunesSyncPopover();
|
hideSunesSyncPopover();
|
||||||
performSuneDownload(false);
|
performSuneDownload(false);
|
||||||
});
|
});
|
||||||
|
var attachGen = 0, attachJob = null, attachQueue = Promise.resolve(), attachWait = false;
|
||||||
function updateAttachBadge() {
|
function updateAttachBadge() {
|
||||||
const n = state.attachments.length;
|
const n = state.attachments.length;
|
||||||
el.attachBadge.textContent = String(n);
|
el.attachBadge.textContent = attachJob ? Math.floor(attachJob.p * 100) + "%" : String(n);
|
||||||
el.attachBadge.classList.toggle("hidden", n === 0);
|
el.attachBadge.classList.toggle("hidden", !n && !attachJob);
|
||||||
}
|
}
|
||||||
var addAttachments = async (files) => {
|
function clearAttachments() {
|
||||||
for (const f of files) {
|
attachGen++;
|
||||||
const at = await toAttach(f).catch(() => null);
|
attachJob?.ac.abort();
|
||||||
if (at) state.attachments.push(at);
|
attachJob = null;
|
||||||
}
|
state.attachments = [];
|
||||||
updateAttachBadge();
|
updateAttachBadge();
|
||||||
|
el.fileInput.value = "";
|
||||||
|
}
|
||||||
|
var addAttachments = (files) => {
|
||||||
|
const g = attachGen;
|
||||||
|
attachQueue = attachQueue.then(async () => {
|
||||||
|
for (const f of files) {
|
||||||
|
if (g !== attachGen) return;
|
||||||
|
const job = attachJob = {
|
||||||
|
ac: new AbortController(),
|
||||||
|
p: 0
|
||||||
|
};
|
||||||
|
updateAttachBadge();
|
||||||
|
const at = await toAttach(f, {
|
||||||
|
signal: job.ac.signal,
|
||||||
|
onProgress: (p) => {
|
||||||
|
job.p = p;
|
||||||
|
updateAttachBadge();
|
||||||
|
}
|
||||||
|
}).catch((e) => {
|
||||||
|
if (g === attachGen) alert(`Couldn't attach ${f.name || "file"}: ${e?.message || e}`);
|
||||||
|
});
|
||||||
|
if (g !== attachGen) return;
|
||||||
|
attachJob = null;
|
||||||
|
if (at) state.attachments.push(at);
|
||||||
|
updateAttachBadge();
|
||||||
|
}
|
||||||
|
}).catch(() => {});
|
||||||
};
|
};
|
||||||
var hideAttachPopover = () => el.attachPopover.classList.add("hidden");
|
var hideAttachPopover = () => el.attachPopover.classList.add("hidden");
|
||||||
function showAttachPopover() {
|
function showAttachPopover() {
|
||||||
if (!state.attachments.length || !el.attachPopover.classList.contains("hidden")) return;
|
if (!state.attachments.length && !attachJob || !el.attachPopover.classList.contains("hidden")) return;
|
||||||
haptic();
|
haptic();
|
||||||
el.attachPopover.classList.remove("hidden");
|
el.attachPopover.classList.remove("hidden");
|
||||||
positionPopover(el.attachBtn, el.attachPopover);
|
positionPopover(el.attachBtn, el.attachPopover);
|
||||||
@@ -1774,8 +1950,7 @@ $(el.attachBtn).on("pointerdown", (e) => {
|
|||||||
});
|
});
|
||||||
$(el.attachPopover).on("click", (e) => {
|
$(el.attachPopover).on("click", (e) => {
|
||||||
if (!e.target.closest("[data-action=\"clear\"]")) return;
|
if (!e.target.closest("[data-action=\"clear\"]")) return;
|
||||||
state.attachments = [];
|
clearAttachments();
|
||||||
updateAttachBadge();
|
|
||||||
hideAttachPopover();
|
hideAttachPopover();
|
||||||
});
|
});
|
||||||
$(document).on("click", (e) => {
|
$(document).on("click", (e) => {
|
||||||
@@ -1784,20 +1959,23 @@ $(document).on("click", (e) => {
|
|||||||
$(window).on("resize", () => {
|
$(window).on("resize", () => {
|
||||||
if (!el.attachPopover.classList.contains("hidden")) positionPopover(el.attachBtn, el.attachPopover);
|
if (!el.attachPopover.classList.contains("hidden")) positionPopover(el.attachBtn, el.attachPopover);
|
||||||
});
|
});
|
||||||
$(el.fileInput).on("change", async () => {
|
$(el.fileInput).on("change", () => {
|
||||||
const files = [...el.fileInput.files || []];
|
const files = [...el.fileInput.files || []];
|
||||||
el.fileInput.value = "";
|
el.fileInput.value = "";
|
||||||
await addAttachments(files);
|
addAttachments(files);
|
||||||
});
|
});
|
||||||
$(el.composer).on("paste", async (e) => {
|
$(el.composer).on("paste", async (e) => {
|
||||||
const files = [...(e.clipboardData || e.originalEvent?.clipboardData)?.files || []];
|
const files = [...(e.clipboardData || e.originalEvent?.clipboardData)?.files || []];
|
||||||
if (!files.length) return;
|
if (!files.length) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await addAttachments(files);
|
addAttachments(files);
|
||||||
});
|
});
|
||||||
$(el.composer).on("submit", async (e) => {
|
$(el.composer).on("submit", async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (state.busy) return;
|
if (state.busy || attachWait) return;
|
||||||
|
attachWait = true;
|
||||||
|
await attachQueue;
|
||||||
|
attachWait = false;
|
||||||
const text = el.input.value.trim();
|
const text = el.input.value.trim();
|
||||||
if (!text && !state.attachments.length) return SUNE.infer();
|
if (!text && !state.attachments.length) return SUNE.infer();
|
||||||
await ensureThreadOnFirstUser(text || "(attachments)");
|
await ensureThreadOnFirstUser(text || "(attachments)");
|
||||||
@@ -2829,3 +3007,4 @@ Object.assign(window, {
|
|||||||
cleanSuneStorage
|
cleanSuneStorage
|
||||||
});
|
});
|
||||||
//#endregion
|
//#endregion
|
||||||
|
export { __vitePreload as t };
|
||||||
+3493
File diff suppressed because one or more lines are too long
Vendored
+35044
File diff suppressed because one or more lines are too long
Vendored
+2
-2
@@ -13,7 +13,7 @@
|
|||||||
<script defer src="//unpkg.com/alpinejs"></script>
|
<script defer src="//unpkg.com/alpinejs"></script>
|
||||||
|
|
||||||
|
|
||||||
<script type="module" crossorigin src="/assets/index-DCxWcq5K.js"></script>
|
<script type="module" crossorigin src="/assets/index-BUD8Xh0Q.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-DDqI2rlK.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-DDqI2rlK.css">
|
||||||
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
||||||
<body class="bg-white text-gray-900 selection:bg-black/10" x-data @click.window="if($event.target.closest('button')) haptic(); if(!document.getElementById('threadPopover').contains($event.target)&&!$event.target.closest('[data-thread-menu]')) hideThreadPopover(); if(!document.getElementById('sunePopover').contains($event.target)&&!$event.target.closest('[data-sune-menu]')) hideSunePopover(); if(!document.getElementById('userMenu').contains($event.target)&&!document.getElementById('userMenuBtn').contains($event.target)) document.getElementById('userMenu').classList.add('hidden')">
|
<body class="bg-white text-gray-900 selection:bg-black/10" x-data @click.window="if($event.target.closest('button')) haptic(); if(!document.getElementById('threadPopover').contains($event.target)&&!$event.target.closest('[data-thread-menu]')) hideThreadPopover(); if(!document.getElementById('sunePopover').contains($event.target)&&!$event.target.closest('[data-sune-menu]')) hideSunePopover(); if(!document.getElementById('userMenu').contains($event.target)&&!document.getElementById('userMenuBtn').contains($event.target)) document.getElementById('userMenu').classList.add('hidden')">
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
<button id="sendBtn" type="submit" aria-label="Send" class="shrink-0 rounded-2xl bg-black text-white h-10 w-10 inline-flex items-center justify-center shadow-sm hover:bg-black/90 active:scale-[.98] transition"><i data-lucide="sparkles" class="h-5 w-5"></i></button>
|
<button id="sendBtn" type="submit" aria-label="Send" class="shrink-0 rounded-2xl bg-black text-white h-10 w-10 inline-flex items-center justify-center shadow-sm hover:bg-black/90 active:scale-[.98] transition"><i data-lucide="sparkles" class="h-5 w-5"></i></button>
|
||||||
<button id="attachBtn" type="button" aria-label="Attach" class="relative shrink-0 rounded-2xl bg-gray-100 text-gray-900 h-10 w-10 inline-flex items-center justify-center shadow-sm hover:bg-gray-200 active:scale-[.98] transition"><i data-lucide="paperclip" class="h-5 w-5"></i><span id="attachBadge" class="hidden absolute -top-1 -right-1 h-4 min-w-4 px-1 rounded-full bg-black text-white text-[10px] leading-4 text-center"></span></button>
|
<button id="attachBtn" type="button" aria-label="Attach" class="relative shrink-0 rounded-2xl bg-gray-100 text-gray-900 h-10 w-10 inline-flex items-center justify-center shadow-sm hover:bg-gray-200 active:scale-[.98] transition"><i data-lucide="paperclip" class="h-5 w-5"></i><span id="attachBadge" class="hidden absolute -top-1 -right-1 h-4 min-w-4 px-1 rounded-full bg-black text-white text-[10px] leading-4 text-center"></span></button>
|
||||||
</div>
|
</div>
|
||||||
<input id="fileInput" type="file" class="hidden" multiple accept="image/png,image/jpeg,image/webp,image/gif,application/pdf,audio/wav,audio/x-wav,audio/mpeg,audio/mp3"/>
|
<input id="fileInput" type="file" class="hidden" multiple accept="image/png,image/jpeg,image/webp,image/gif,application/pdf,audio/wav,audio/x-wav,audio/mpeg,audio/mp3,video/*"/>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1 +1 @@
|
|||||||
if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let o={};const d=e=>i(e,t),c={module:{uri:t},exports:o,require:d};s[t]=Promise.all(n.map(e=>c[e]||d(e))).then(e=>(r(...e),o))}}define(["./workbox-9c191d2f"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"index.html",revision:"c3f11cd6433cb8fbfa5ba522a8abdaca"},{url:"assets/index-DDqI2rlK.css",revision:null},{url:"assets/index-DCxWcq5K.js",revision:null},{url:"appstore_content/✺.png",revision:"06dd8ca13016278fc47e9a226acdb7f9"},{url:"manifest.webmanifest",revision:"70d853d7dcb45ddd8488db46950b4b33"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))});
|
if(!self.define){let e,s={};const n=(n,i)=>(n=new URL(n+".js",i).href,s[n]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=s,document.head.appendChild(e)}else e=n,importScripts(n),s()}).then(()=>{let e=s[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(i,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let l={};const o=e=>n(e,t),d={module:{uri:t},exports:l,require:o};s[t]=Promise.all(i.map(e=>d[e]||o(e))).then(e=>(r(...e),l))}}define(["./workbox-9c191d2f"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"index.html",revision:"83d384dc5870ba8fbe678bc7c224f429"},{url:"assets/src-Bv2YeDx1.js",revision:null},{url:"assets/mediabunny-aac-encoder-CtuZhjiD.js",revision:null},{url:"assets/index-DDqI2rlK.css",revision:null},{url:"assets/index-BUD8Xh0Q.js",revision:null},{url:"assets/__vite-browser-external-BU5UGKjj.js",revision:null},{url:"appstore_content/✺.png",revision:"06dd8ca13016278fc47e9a226acdb7f9"},{url:"manifest.webmanifest",revision:"70d853d7dcb45ddd8488db46950b4b33"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))});
|
||||||
|
|||||||
Reference in New Issue
Block a user