Добавить копирование текста и двухосевую прокрутку в превью unwrap.
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
- одноразовая расшифровка — ciphertext удаляется с сервера после открытия
|
||||
- опциональный пароль: Argon2-проверка до выдачи ciphertext, лимит попыток (по умолчанию 3), пустой пароль попытку не тратит
|
||||
- подсветка синтаксиса (highlight.js), ручной выбор языка
|
||||
- после расшифровки: прокрутка текста по вертикали и горизонтали, копирование в буфер обмена
|
||||
- вложения: drag-and-drop, выбор файлов, вставка скриншота из буфера
|
||||
- спиннер с логотипом при создании и расшифровке
|
||||
- RU / EN, светлая и тёмная тема
|
||||
@@ -45,7 +46,7 @@
|
||||
|
||||
### Расшифровка
|
||||
|
||||
Одноразовое открытие: ciphertext удаляется на сервере, превью — только в текущей сессии браузера.
|
||||
Одноразовое открытие: ciphertext удаляется на сервере, превью — только в текущей сессии браузера. Текст с подсветкой прокручивается по обеим осям; рядом — кнопки копирования и скачивания.
|
||||
|
||||
| Светлая тема | Тёмная тема |
|
||||
|:------------:|:-----------:|
|
||||
|
||||
+38
-6
@@ -553,7 +553,15 @@ body.busy-open { overflow: hidden; }
|
||||
min-width: 0;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.btn.download-btn {
|
||||
.item-card-actions {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
.btn.download-btn,
|
||||
.btn.copy-btn {
|
||||
flex-shrink: 0;
|
||||
gap: 0.35rem;
|
||||
padding: 0.35rem 0.65rem;
|
||||
@@ -561,7 +569,8 @@ body.busy-open { overflow: hidden; }
|
||||
font-size: 0.78rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
.btn.download-btn i {
|
||||
.btn.download-btn i,
|
||||
.btn.copy-btn i {
|
||||
font-size: 0.72rem;
|
||||
opacity: 0.9;
|
||||
}
|
||||
@@ -961,15 +970,38 @@ html[data-theme="light"] .footer-pillars li {
|
||||
padding: 1rem;
|
||||
background: var(--input);
|
||||
}
|
||||
.item-card pre {
|
||||
.item-card pre,
|
||||
.item-card .item-text-pre {
|
||||
margin: 0.6rem 0 0;
|
||||
overflow: auto;
|
||||
max-height: 420px;
|
||||
max-height: min(60vh, 28rem);
|
||||
padding: 0.8rem;
|
||||
border-radius: 8px;
|
||||
background: rgba(0,0,0,0.25);
|
||||
overflow-x: auto;
|
||||
overflow-y: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
overscroll-behavior: contain;
|
||||
tab-size: 2;
|
||||
}
|
||||
.item-card pre code,
|
||||
.item-card .item-text-pre code {
|
||||
display: block;
|
||||
width: max-content;
|
||||
min-width: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: transparent !important;
|
||||
white-space: pre;
|
||||
word-break: normal;
|
||||
overflow-wrap: normal;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.45;
|
||||
}
|
||||
html[data-theme="light"] .item-card pre,
|
||||
html[data-theme="light"] .item-card .item-text-pre {
|
||||
background: rgba(16, 32, 56, 0.05);
|
||||
}
|
||||
html[data-theme="light"] .item-card pre { background: rgba(16, 32, 56, 0.05); }
|
||||
.item-card img {
|
||||
max-width: 100%;
|
||||
border-radius: 8px;
|
||||
|
||||
+30
-6
@@ -120,6 +120,27 @@
|
||||
return btn;
|
||||
}
|
||||
|
||||
function makeCopyBtn(getText) {
|
||||
const btn = document.createElement("button");
|
||||
btn.className = "btn copy-btn";
|
||||
btn.type = "button";
|
||||
const label = () =>
|
||||
`<i class="fa-solid fa-copy" aria-hidden="true"></i><span>${t("common.copy")}</span>`;
|
||||
btn.innerHTML = label();
|
||||
btn.addEventListener("click", async () => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(getText() || "");
|
||||
btn.innerHTML = `<i class="fa-solid fa-check" aria-hidden="true"></i><span>${t("common.copied")}</span>`;
|
||||
setTimeout(() => {
|
||||
btn.innerHTML = label();
|
||||
}, 1200);
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
});
|
||||
return btn;
|
||||
}
|
||||
|
||||
function renderPackage(pack) {
|
||||
els.items.innerHTML = "";
|
||||
for (const item of pack.items || []) {
|
||||
@@ -127,23 +148,26 @@
|
||||
card.className = "item-card";
|
||||
if (item.type === "text") {
|
||||
const lang = item.language || "plaintext";
|
||||
const text = item.content || "";
|
||||
const head = document.createElement("div");
|
||||
head.className = "item-card-head";
|
||||
head.innerHTML = `<div><strong>text</strong> · <span class="mono">${lang}</span></div>`;
|
||||
head.appendChild(
|
||||
const actions = document.createElement("div");
|
||||
actions.className = "item-card-actions";
|
||||
actions.appendChild(makeCopyBtn(() => text));
|
||||
actions.appendChild(
|
||||
makeDownloadBtn(() => {
|
||||
downloadBlob(
|
||||
`wrapped-${lang}.txt`,
|
||||
new Blob([item.content || ""], { type: "text/plain" })
|
||||
);
|
||||
downloadBlob(`wrapped-${lang}.txt`, new Blob([text], { type: "text/plain" }));
|
||||
})
|
||||
);
|
||||
head.appendChild(actions);
|
||||
card.appendChild(head);
|
||||
const pre = document.createElement("pre");
|
||||
pre.className = "item-text-pre";
|
||||
const code = document.createElement("code");
|
||||
pre.appendChild(code);
|
||||
card.appendChild(pre);
|
||||
window.WrappedHighlight.highlightElement(code, item.content || "", lang);
|
||||
window.WrappedHighlight.highlightElement(code, text, lang);
|
||||
} else if (item.type === "file") {
|
||||
const bytes = window.WrappedCrypto.base64ToBytes(item.data_b64);
|
||||
const blob = new Blob([bytes], { type: item.mime || "application/octet-stream" });
|
||||
|
||||
Reference in New Issue
Block a user