Streamline admin reply composer
This commit is contained in:
+33
-13
@@ -487,24 +487,44 @@ label { display: grid; gap: 6px; color: var(--muted); font-size: 13px; }
|
||||
background: white;
|
||||
border-top: 1px solid var(--line);
|
||||
}
|
||||
.reply.dragging {
|
||||
box-shadow: inset 0 0 0 2px var(--brand);
|
||||
background: #edf8f3;
|
||||
}
|
||||
.reply-composer {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
gap: 10px;
|
||||
grid-template-columns: minmax(0, 1fr) 44px 48px;
|
||||
gap: 8px;
|
||||
align-items: stretch;
|
||||
}
|
||||
.admin-dropzone {
|
||||
min-height: 38px;
|
||||
border: 1px dashed var(--line);
|
||||
border-radius: 8px;
|
||||
padding: 8px 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: var(--muted);
|
||||
background: #f8fbf9;
|
||||
.reply-composer textarea { min-height: 72px; resize: vertical; }
|
||||
.reply-icon-button {
|
||||
min-height: 72px;
|
||||
width: 100%;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
border-radius: 6px;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.admin-dropzone.dragging { border-color: var(--brand); background: #edf8f3; color: var(--ink); }
|
||||
.admin-dropzone input { display: none; }
|
||||
.reply-icon-button svg {
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
fill: currentColor;
|
||||
}
|
||||
.attach-button {
|
||||
border: 1px solid var(--line);
|
||||
background: #f8fbf9;
|
||||
color: var(--muted);
|
||||
}
|
||||
.attach-button:hover { background: #edf3ef; color: var(--ink); }
|
||||
.attach-button input { display: none; }
|
||||
.send-button {
|
||||
border: 0;
|
||||
background: var(--brand);
|
||||
color: white;
|
||||
}
|
||||
.send-button svg { transform: translateX(1px); }
|
||||
.reply-attachments {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
+11
-5
@@ -58,12 +58,18 @@
|
||||
<form id="replyForm" class="reply hidden">
|
||||
<div class="reply-composer">
|
||||
<textarea name="message" rows="3" placeholder="Napsat odpoved..."></textarea>
|
||||
<button type="submit" title="Odeslat">Odeslat</button>
|
||||
<label class="reply-icon-button attach-button" title="Pridat fotku" aria-label="Pridat fotku">
|
||||
<input name="attachments" type="file" accept=".jpg,.jpeg,.png,.webp,.gif,.avif,image/jpeg,image/png,image/webp,image/gif,image/avif" multiple>
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M7.5 18.5a5 5 0 0 1 0-7.1l7.7-7.7a3.5 3.5 0 0 1 5 5l-8.4 8.4a2.1 2.1 0 0 1-3-3l7.8-7.8 1.4 1.4-7.8 7.8a.1.1 0 0 0 .1.1l8.4-8.4a1.5 1.5 0 0 0-2.1-2.1l-7.7 7.7a3 3 0 0 0 4.2 4.2l7.5-7.5 1.4 1.4-7.5 7.5a5 5 0 0 1-7 0Z"></path>
|
||||
</svg>
|
||||
</label>
|
||||
<button class="reply-icon-button send-button" type="submit" title="Odeslat" aria-label="Odeslat">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<path d="M3.7 20.3 21 12 3.7 3.7l2.5 7.1L14 12l-7.8 1.2-2.5 7.1Z"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<label class="admin-dropzone" tabindex="0">
|
||||
<input name="attachments" type="file" accept=".jpg,.jpeg,.png,.webp,.gif,.avif,image/jpeg,image/png,image/webp,image/gif,image/avif" multiple>
|
||||
<span>Pridat fotky nebo pretahnout</span>
|
||||
</label>
|
||||
<div id="replyAttachments" class="reply-attachments"></div>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
+25
-16
@@ -119,35 +119,39 @@ $("#replyForm textarea").addEventListener("input", debounce(() => {
|
||||
}, 600));
|
||||
|
||||
$("#replyForm input[name='attachments']").addEventListener("change", (event) => {
|
||||
state.replyFiles = mergeImageFiles(state.replyFiles, [...event.target.files]);
|
||||
addReplyFiles([...event.target.files]);
|
||||
event.target.value = "";
|
||||
renderReplyAttachments();
|
||||
});
|
||||
|
||||
$(".admin-dropzone").addEventListener("keydown", (event) => {
|
||||
if (event.key === "Enter" || event.key === " ") {
|
||||
event.preventDefault();
|
||||
$("#replyForm input[name='attachments']").click();
|
||||
}
|
||||
});
|
||||
|
||||
for (const eventName of ["dragenter", "dragover"]) {
|
||||
$(".admin-dropzone").addEventListener(eventName, (event) => {
|
||||
$(".conversation").addEventListener(eventName, (event) => {
|
||||
event.preventDefault();
|
||||
$(".admin-dropzone").classList.add("dragging");
|
||||
if (!state.activeId) return;
|
||||
$("#replyForm").classList.add("dragging");
|
||||
});
|
||||
}
|
||||
|
||||
for (const eventName of ["dragleave", "drop"]) {
|
||||
$(".admin-dropzone").addEventListener(eventName, (event) => {
|
||||
$(".conversation").addEventListener(eventName, (event) => {
|
||||
event.preventDefault();
|
||||
$(".admin-dropzone").classList.remove("dragging");
|
||||
$("#replyForm").classList.remove("dragging");
|
||||
});
|
||||
}
|
||||
|
||||
$(".admin-dropzone").addEventListener("drop", (event) => {
|
||||
state.replyFiles = mergeImageFiles(state.replyFiles, [...event.dataTransfer.files]);
|
||||
renderReplyAttachments();
|
||||
$(".conversation").addEventListener("drop", (event) => {
|
||||
if (!state.activeId) return;
|
||||
addReplyFiles([...event.dataTransfer.files]);
|
||||
});
|
||||
|
||||
$(".conversation").addEventListener("paste", (event) => {
|
||||
if (!state.activeId) return;
|
||||
const files = [...event.clipboardData?.items || []]
|
||||
.filter((item) => item.kind === "file")
|
||||
.map((item) => item.getAsFile())
|
||||
.filter(Boolean);
|
||||
if (!files.length) return;
|
||||
event.preventDefault();
|
||||
addReplyFiles(files);
|
||||
});
|
||||
|
||||
$("#replyAttachments").addEventListener("click", (event) => {
|
||||
@@ -458,6 +462,11 @@ function renderReplyAttachments() {
|
||||
`).join("");
|
||||
}
|
||||
|
||||
function addReplyFiles(files) {
|
||||
state.replyFiles = mergeImageFiles(state.replyFiles, files);
|
||||
renderReplyAttachments();
|
||||
}
|
||||
|
||||
function clearReplyComposer(form = $("#replyForm")) {
|
||||
const textarea = form?.querySelector("textarea[name='message']");
|
||||
if (!textarea) return;
|
||||
|
||||
Reference in New Issue
Block a user