From 482fd7adee5e9e0990bf5904ed7d754d315de649 Mon Sep 17 00:00:00 2001 From: Arno Richter Date: Wed, 21 Dec 2022 15:05:28 +0100 Subject: first attempt at image attachments! --- js/microblog.js | 193 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 js/microblog.js (limited to 'js/microblog.js') diff --git a/js/microblog.js b/js/microblog.js new file mode 100644 index 0000000..f7963e3 --- /dev/null +++ b/js/microblog.js @@ -0,0 +1,193 @@ +'use strict'; + +document.documentElement.classList.remove('no-js'); + +const textarea = document.querySelector('textarea[name="content"]'); +const charCount = document.querySelector('#count'); + +if (textarea) { + const maxCount = parseInt(textarea.getAttribute('maxlength')); + + if (textarea.value.length > 0) { + const textLength = [...textarea.value].length; + charCount.textContent = maxCount - textLength; + } else { + charCount.textContent = maxCount; + } + + textarea.addEventListener('input', function () { + const textLength = [...this.value].length; + + charCount.textContent = maxCount - textLength; + }, false); +} + +const postForm = document.querySelector('#post-new-form'); +let useDragDrop = (!!window.FileReader && 'draggable' in document.createElement('div')); +useDragDrop = true; +if (postForm) { + const droparea = postForm.querySelector('#post-droparea'); + const attachmentsInput = postForm.querySelector('#post-attachments'); + const data = { + 'attachments': [] + }; + + + if (droparea && attachmentsInput) { + if (useDragDrop) { + console.log('init with modern file attachments'); + + const list = postForm.querySelector('#post-attachments-list'); + list.addEventListener('click', function (e) { + e.preventDefault(); + + // remove attachment + if (e.target.nodeName.toLowerCase() == 'li') { + const filename = e.target.textContent; + + data.attachments = data.attachments.filter(function (ele) { + return ele.name !== filename; + }); + + e.target.remove(); + } + }); + + droparea.classList.remove('hidden'); + document.querySelector('#post-attachments-label').classList.add('hidden'); + + droparea.ondragover = droparea.ondragenter = function (e) { + e.stopPropagation(); + e.preventDefault(); + + e.dataTransfer.dropEffect = 'copy'; + e.target.classList.add('drag'); + }; + + droparea.ondragleave = function (e) { + e.target.classList.remove('drag'); + }; + + droparea.onclick = function (e) { + e.preventDefault(); + + // make a virtual file upload + const input = document.createElement('input'); + input.type = 'file'; + input.setAttribute('multiple', ''); + input.setAttribute('accept', 'image/*'); // only images for now + + input.onchange = e => { + processSelectedFiles(e.target.files); + } + + input.click(); + }; + + function processSelectedFiles(files) { + if (!files || files.length < 1) return; + + for (const file of files) { + const found = data.attachments.find(ele => ele.name === file.name); + if(found) continue; // skip existing attachments + + data.attachments.push({ + 'name': file.name, + // todo: maybe some better form of dupe detection here? + 'file': file + }); + + const li = document.createElement('li'); + li.textContent = file.name; + + const reader = new FileReader(); + + if(file.type.startsWith('image/')) { + reader.onload = function (e) { + var dataURL = e.target.result; + + const preview = document.createElement('img'); + preview.classList.add('file-preview'); + preview.setAttribute('src', dataURL); + + li.prepend(preview); + }; + reader.onerror = function (e) { + console.log('An error occurred during file input: '+e.target.error.code); + }; + + reader.readAsDataURL(file); + } + + list.append(li); + } + } + + droparea.ondrop = function (e) { + if (e.dataTransfer) { + e.preventDefault(); + e.stopPropagation(); + + processSelectedFiles(e.dataTransfer.files); + } + + e.target.classList.remove('drag'); + }; + + postForm.addEventListener('submit', async function (e) { + e.preventDefault(); + + const postFormData = new FormData(); + + postFormData.append('content', postForm.querySelector('[name="content"]').value); + + for (const attachment of data.attachments) { + postFormData.append('attachments[]', attachment.file); + } + + /* + for (const pair of postFormData.entries()) { + console.log(`${pair[0]}, ${pair[1]}`); + } + */ + + const response = await fetch(postForm.getAttribute('action'), { + body: postFormData, + method: 'POST' + }); + + if (response.ok && response.status == 200) { + const txt = await response.text(); + // console.log(response, txt); + window.location.href = postForm.dataset.redirect; + } else { + console.warn('error during post submission!', response); + } + }); + } else { + // use the native file input dialog + // but enhanced + if (attachmentsInput) { + console.log('init with classic file attachments'); + + attachmentsInput.addEventListener('change', function (e) { + console.log(e.target.files); + + const list = postForm.querySelector('#post-attachments-list'); + list.replaceChildren(); + + for (const file of e.target.files) { + const li = document.createElement('li'); + li.textContent = file.name; + list.append(li); + } + }); + } + } + } +} + +// better rounded corners +if ('paintWorklet' in CSS) { + // CSS.paintWorklet.addModule('./js/squircle.js'); +} -- cgit v1.2.3