Fix indentation, tweak newlines
This commit is contained in:
parent
7063fd5604
commit
a38727ed69
|
@ -12,9 +12,9 @@
|
|||
resize: vertical;
|
||||
}
|
||||
|
||||
#editor.drop {
|
||||
box-shadow: inset 0px 0px 5px yellow;
|
||||
}
|
||||
#editor.drop {
|
||||
box-shadow: inset 0px 0px 5px yellow;
|
||||
}
|
||||
</style>
|
||||
{{ end }}
|
||||
|
||||
|
@ -54,16 +54,16 @@
|
|||
*/}}
|
||||
<textarea id="editor" class="w-100 h6 minh-6 pa2 mono lh-copy" name="body">{{ .EditInitialContents }}</textarea>
|
||||
|
||||
<div class="flex justify-end items-center mt2">
|
||||
<div class="upload_bar flex-grow-1">
|
||||
<div class="instructions">
|
||||
Upload files by dragging & dropping, pasting, or <label class="pointer link" for="file_input">selecting</label> them.
|
||||
</div>
|
||||
<div class="progress flex">
|
||||
<div class="progress_text mr3"></div>
|
||||
<div class="progress_bar flex-grow-1 flex-shrink-1 pa1"><div class=""></div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end items-center mt2">
|
||||
<div class="upload_bar flex-grow-1">
|
||||
<div class="instructions">
|
||||
Upload files by dragging & dropping, pasting, or <label class="pointer link" for="file_input">selecting</label> them.
|
||||
</div>
|
||||
<div class="progress flex">
|
||||
<div class="progress_text mr3"></div>
|
||||
<div class="progress_bar flex-grow-1 flex-shrink-1 pa1"><div class=""></div></div>
|
||||
</div>
|
||||
</div>
|
||||
<input type="submit" class="button ml2 flex-grow-0 flex-shrink-0" name="submit" value="{{ .SubmitLabel }}" />
|
||||
</div>
|
||||
|
||||
|
@ -114,13 +114,13 @@
|
|||
<div id="preview-container" class="post post-preview mathjax flex-fair-ns overflow-auto mv3 mv0-ns ml3-ns pa3 br3 bg--dim">
|
||||
<div id="preview" class="post-content"></div>
|
||||
</div>
|
||||
<input type="file" multiple name="file_input" id="file_input" class="dn" />{{/* NOTE(asaf): Placing this outside the form to avoid submitting it to the server by accident */}}
|
||||
<input type="file" multiple name="file_input" id="file_input" class="dn" />{{/* NOTE(asaf): Placing this outside the form to avoid submitting it to the server by accident */}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const maxFileSize = {{ .MaxFileSize }};
|
||||
const uploadUrl = {{ .UploadUrl }};
|
||||
const maxFileSize = {{ .MaxFileSize }};
|
||||
const uploadUrl = {{ .UploadUrl }};
|
||||
|
||||
const form = document.querySelector('#form');
|
||||
const titleField = document.querySelector('#title'); // may be undefined, be careful!
|
||||
|
@ -196,224 +196,224 @@
|
|||
window.localStorage.removeItem(storageKey);
|
||||
});
|
||||
|
||||
/*
|
||||
/ Asset upload
|
||||
*/
|
||||
const submitButton = document.querySelector("#form input[type=submit]");
|
||||
const submitText = submitButton.value;
|
||||
const fileInput = document.querySelector('#file_input');
|
||||
const uploadBar = document.querySelector('.upload_bar');
|
||||
const uploadProgress = document.querySelector('.upload_bar .progress');
|
||||
const uploadProgressText = document.querySelector('.upload_bar .progress_text');
|
||||
const uploadProgressBar = document.querySelector('.upload_bar .progress_bar');
|
||||
const uploadProgressBarFill = document.querySelector('.upload_bar .progress_bar > div');
|
||||
let fileCounter = 0;
|
||||
let enterCounter = 0;
|
||||
let uploadQueue = [];
|
||||
let currentUpload = null;
|
||||
let currentXhr = null;
|
||||
let currentBatchSize = 0;
|
||||
let currentBatchDone = 0;
|
||||
/*
|
||||
/ Asset upload
|
||||
*/
|
||||
const submitButton = document.querySelector("#form input[type=submit]");
|
||||
const submitText = submitButton.value;
|
||||
const fileInput = document.querySelector('#file_input');
|
||||
const uploadBar = document.querySelector('.upload_bar');
|
||||
const uploadProgress = document.querySelector('.upload_bar .progress');
|
||||
const uploadProgressText = document.querySelector('.upload_bar .progress_text');
|
||||
const uploadProgressBar = document.querySelector('.upload_bar .progress_bar');
|
||||
const uploadProgressBarFill = document.querySelector('.upload_bar .progress_bar > div');
|
||||
let fileCounter = 0;
|
||||
let enterCounter = 0;
|
||||
let uploadQueue = [];
|
||||
let currentUpload = null;
|
||||
let currentXhr = null;
|
||||
let currentBatchSize = 0;
|
||||
let currentBatchDone = 0;
|
||||
|
||||
fileInput.addEventListener("change", function(ev) {
|
||||
if (fileInput.files.length > 0) {
|
||||
importUserFiles(fileInput.files);
|
||||
}
|
||||
});
|
||||
fileInput.addEventListener("change", function(ev) {
|
||||
if (fileInput.files.length > 0) {
|
||||
importUserFiles(fileInput.files);
|
||||
}
|
||||
});
|
||||
|
||||
textField.addEventListener("dragover", function(ev) {
|
||||
let effect = "none";
|
||||
for (let i = 0; i < ev.dataTransfer.items.length; ++i) {
|
||||
if (ev.dataTransfer.items[i].kind.toLowerCase() == "file") {
|
||||
effect = "copy";
|
||||
break;
|
||||
}
|
||||
}
|
||||
ev.dataTransfer.dropEffect = effect;
|
||||
ev.preventDefault();
|
||||
});
|
||||
textField.addEventListener("dragover", function(ev) {
|
||||
let effect = "none";
|
||||
for (let i = 0; i < ev.dataTransfer.items.length; ++i) {
|
||||
if (ev.dataTransfer.items[i].kind.toLowerCase() == "file") {
|
||||
effect = "copy";
|
||||
break;
|
||||
}
|
||||
}
|
||||
ev.dataTransfer.dropEffect = effect;
|
||||
ev.preventDefault();
|
||||
});
|
||||
|
||||
textField.addEventListener("dragenter", function(ev) {
|
||||
enterCounter++;
|
||||
let droppable = false;
|
||||
for (let i = 0; i < ev.dataTransfer.items.length; ++i) {
|
||||
if (ev.dataTransfer.items[i].kind.toLowerCase() == "file") {
|
||||
droppable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (droppable) {
|
||||
textField.classList.add("drop");
|
||||
}
|
||||
});
|
||||
textField.addEventListener("dragenter", function(ev) {
|
||||
enterCounter++;
|
||||
let droppable = false;
|
||||
for (let i = 0; i < ev.dataTransfer.items.length; ++i) {
|
||||
if (ev.dataTransfer.items[i].kind.toLowerCase() == "file") {
|
||||
droppable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (droppable) {
|
||||
textField.classList.add("drop");
|
||||
}
|
||||
});
|
||||
|
||||
textField.addEventListener("dragleave", function(ev) {
|
||||
enterCounter--;
|
||||
if (enterCounter == 0) {
|
||||
textField.classList.remove("drop");
|
||||
}
|
||||
});
|
||||
textField.addEventListener("dragleave", function(ev) {
|
||||
enterCounter--;
|
||||
if (enterCounter == 0) {
|
||||
textField.classList.remove("drop");
|
||||
}
|
||||
});
|
||||
|
||||
function makeUploadString(uploadNumber, filename) {
|
||||
return `Uploading file #${uploadNumber}: \`${filename}\`...`;
|
||||
}
|
||||
function makeUploadString(uploadNumber, filename) {
|
||||
return `Uploading file #${uploadNumber}: \`${filename}\`...`;
|
||||
}
|
||||
|
||||
textField.addEventListener("drop", function(ev) {
|
||||
enterCounter = 0;
|
||||
textField.classList.remove("drop");
|
||||
textField.addEventListener("drop", function(ev) {
|
||||
enterCounter = 0;
|
||||
textField.classList.remove("drop");
|
||||
|
||||
if (ev.dataTransfer && ev.dataTransfer.files) {
|
||||
importUserFiles(ev.dataTransfer.files)
|
||||
}
|
||||
if (ev.dataTransfer && ev.dataTransfer.files) {
|
||||
importUserFiles(ev.dataTransfer.files)
|
||||
}
|
||||
|
||||
ev.preventDefault();
|
||||
});
|
||||
ev.preventDefault();
|
||||
});
|
||||
|
||||
textField.addEventListener("paste", function(ev) {
|
||||
if (ev.clipboardData && ev.clipboardData.files) {
|
||||
importUserFiles(ev.clipboardData.files)
|
||||
}
|
||||
});
|
||||
textField.addEventListener("paste", function(ev) {
|
||||
if (ev.clipboardData && ev.clipboardData.files) {
|
||||
importUserFiles(ev.clipboardData.files)
|
||||
}
|
||||
});
|
||||
|
||||
function importUserFiles(files) {
|
||||
let items = [];
|
||||
for (let i = 0; i < files.length; ++i) {
|
||||
let f = files[i];
|
||||
if (f.size < maxFileSize) {
|
||||
items.push({ file: f, error: null });
|
||||
} else {
|
||||
items.push({ file: null, error: `\`${f.name}\` is too big! Max size is ${maxFileSize} but the file is ${f.size}.` });
|
||||
}
|
||||
}
|
||||
function importUserFiles(files) {
|
||||
let items = [];
|
||||
for (let i = 0; i < files.length; ++i) {
|
||||
let f = files[i];
|
||||
if (f.size < maxFileSize) {
|
||||
items.push({ file: f, error: null });
|
||||
} else {
|
||||
items.push({ file: null, error: `\`${f.name}\` is too big! Max size is ${maxFileSize} but the file is ${f.size}.` });
|
||||
}
|
||||
}
|
||||
|
||||
let cursorStart = textField.selectionStart;
|
||||
let cursorEnd = textField.selectionEnd;
|
||||
let cursorStart = textField.selectionStart;
|
||||
let cursorEnd = textField.selectionEnd;
|
||||
|
||||
let toInsert = "";
|
||||
let linesToCursor = textField.value.substr(0, cursorStart).split("\n");
|
||||
let cursorLine = linesToCursor[linesToCursor.length-1].trim();
|
||||
if (cursorLine.length > 0) {
|
||||
toInsert = "\n";
|
||||
}
|
||||
for (let i = 0; i < items.length; ++i) {
|
||||
if (items[i].file) {
|
||||
fileCounter++;
|
||||
toInsert += makeUploadString(fileCounter, items[i].file.name) + "\n";
|
||||
queueUpload(fileCounter, items[i].file);
|
||||
} else {
|
||||
toInsert += `${items[i].error}\n`;
|
||||
}
|
||||
}
|
||||
let toInsert = "";
|
||||
let linesToCursor = textField.value.substr(0, cursorStart).split("\n");
|
||||
let cursorLine = linesToCursor[linesToCursor.length-1].trim();
|
||||
if (cursorLine.length > 0) {
|
||||
toInsert = "\n\n";
|
||||
}
|
||||
for (let i = 0; i < items.length; ++i) {
|
||||
if (items[i].file) {
|
||||
fileCounter++;
|
||||
toInsert += makeUploadString(fileCounter, items[i].file.name) + "\n\n";
|
||||
queueUpload(fileCounter, items[i].file);
|
||||
} else {
|
||||
toInsert += `${items[i].error}\n\n`;
|
||||
}
|
||||
}
|
||||
|
||||
textField.value = textField.value.substring(0, cursorStart) + toInsert + textField.value.substring(cursorEnd, textField.value.length);
|
||||
doMarkdown();
|
||||
uploadNext();
|
||||
}
|
||||
textField.value = textField.value.substring(0, cursorStart) + toInsert + textField.value.substring(cursorEnd, textField.value.length);
|
||||
doMarkdown();
|
||||
uploadNext();
|
||||
}
|
||||
|
||||
function replaceUploadString(upload, newString) {
|
||||
let cursorStart = textField.selectionStart;
|
||||
let cursorEnd = textField.selectionEnd;
|
||||
let uploadString = makeUploadString(upload.uploadNumber, upload.file.name);
|
||||
let insertIndex = textField.value.indexOf(uploadString)
|
||||
textField.value = textField.value.replace(uploadString, newString);
|
||||
if (cursorStart <= insertIndex + uploadString.length) {
|
||||
textField.selectionStart = cursorStart;
|
||||
} else {
|
||||
textField.selectionStart = cursorStart - uploadString.length + newString.length;
|
||||
}
|
||||
if (cursorEnd <= insertIndex + uploadString.length) {
|
||||
textField.selectionEnd = cursorEnd;
|
||||
} else {
|
||||
textField.selectionEnd = cursorEnd - uploadString.length + newString.length;
|
||||
}
|
||||
doMarkdown();
|
||||
}
|
||||
function replaceUploadString(upload, newString) {
|
||||
let cursorStart = textField.selectionStart;
|
||||
let cursorEnd = textField.selectionEnd;
|
||||
let uploadString = makeUploadString(upload.uploadNumber, upload.file.name);
|
||||
let insertIndex = textField.value.indexOf(uploadString)
|
||||
textField.value = textField.value.replace(uploadString, newString);
|
||||
if (cursorStart <= insertIndex + uploadString.length) {
|
||||
textField.selectionStart = cursorStart;
|
||||
} else {
|
||||
textField.selectionStart = cursorStart - uploadString.length + newString.length;
|
||||
}
|
||||
if (cursorEnd <= insertIndex + uploadString.length) {
|
||||
textField.selectionEnd = cursorEnd;
|
||||
} else {
|
||||
textField.selectionEnd = cursorEnd - uploadString.length + newString.length;
|
||||
}
|
||||
doMarkdown();
|
||||
}
|
||||
|
||||
function replaceUploadStringError(upload) {
|
||||
replaceUploadString(upload, `There was a problem uploading your file \`${upload.file.name}\`.`);
|
||||
}
|
||||
function replaceUploadStringError(upload) {
|
||||
replaceUploadString(upload, `There was a problem uploading your file \`${upload.file.name}\`.`);
|
||||
}
|
||||
|
||||
function queueUpload(uploadNumber, file) {
|
||||
uploadQueue.push({
|
||||
uploadNumber: uploadNumber,
|
||||
file: file
|
||||
});
|
||||
function queueUpload(uploadNumber, file) {
|
||||
uploadQueue.push({
|
||||
uploadNumber: uploadNumber,
|
||||
file: file
|
||||
});
|
||||
|
||||
currentBatchSize++;
|
||||
uploadProgressText.textContent = `Uploading files ${currentBatchDone+1}/${currentBatchSize}`;
|
||||
}
|
||||
currentBatchSize++;
|
||||
uploadProgressText.textContent = `Uploading files ${currentBatchDone+1}/${currentBatchSize}`;
|
||||
}
|
||||
|
||||
function uploadDone(ev) {
|
||||
try {
|
||||
if (currentXhr.status == 200 && currentXhr.response) {
|
||||
if (currentXhr.response.url) {
|
||||
let url = currentXhr.response.url;
|
||||
let newString = `[${currentUpload.file.name}](${url})`;
|
||||
if (currentXhr.response.mime.startsWith("image")) {
|
||||
newString = "!" + newString;
|
||||
}
|
||||
function uploadDone(ev) {
|
||||
try {
|
||||
if (currentXhr.status == 200 && currentXhr.response) {
|
||||
if (currentXhr.response.url) {
|
||||
let url = currentXhr.response.url;
|
||||
let newString = `[${currentUpload.file.name}](${url})`;
|
||||
if (currentXhr.response.mime.startsWith("image")) {
|
||||
newString = "!" + newString;
|
||||
}
|
||||
|
||||
replaceUploadString(currentUpload, newString);
|
||||
} else if (currentXhr.response.error) {
|
||||
replaceUploadString(currentUpload, `Upload failed for \`${currentUpload.file.name}\`: ${currentXhr.response.error}.`);
|
||||
} else {
|
||||
replaceUploadStringError(currentUpload);
|
||||
}
|
||||
} else {
|
||||
replaceUploadStringError(currentUpload);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
replaceUploadStringError(currentUpload);
|
||||
}
|
||||
currentUpload = null;
|
||||
currentXhr = null;
|
||||
currentBatchDone++;
|
||||
uploadNext();
|
||||
}
|
||||
replaceUploadString(currentUpload, newString);
|
||||
} else if (currentXhr.response.error) {
|
||||
replaceUploadString(currentUpload, `Upload failed for \`${currentUpload.file.name}\`: ${currentXhr.response.error}.`);
|
||||
} else {
|
||||
replaceUploadStringError(currentUpload);
|
||||
}
|
||||
} else {
|
||||
replaceUploadStringError(currentUpload);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
replaceUploadStringError(currentUpload);
|
||||
}
|
||||
currentUpload = null;
|
||||
currentXhr = null;
|
||||
currentBatchDone++;
|
||||
uploadNext();
|
||||
}
|
||||
|
||||
function updateUploadProgress(ev) {
|
||||
if (ev.lengthComputable) {
|
||||
let progress = ev.loaded / ev.total;
|
||||
uploadProgressBarFill.style.width = Math.floor(progress * 100) + "%";
|
||||
}
|
||||
}
|
||||
function updateUploadProgress(ev) {
|
||||
if (ev.lengthComputable) {
|
||||
let progress = ev.loaded / ev.total;
|
||||
uploadProgressBarFill.style.width = Math.floor(progress * 100) + "%";
|
||||
}
|
||||
}
|
||||
|
||||
function uploadNext() {
|
||||
if (currentUpload == null) {
|
||||
next = uploadQueue.shift();
|
||||
if (next) {
|
||||
uploadProgressText.textContent = `Uploading files ${currentBatchDone+1}/${currentBatchSize}`;
|
||||
uploadBar.classList.add("uploading");
|
||||
uploadProgressBarFill.style.width = "0%";
|
||||
submitButton.disabled = true;
|
||||
submitButton.value = "Uploading files...";
|
||||
function uploadNext() {
|
||||
if (currentUpload == null) {
|
||||
next = uploadQueue.shift();
|
||||
if (next) {
|
||||
uploadProgressText.textContent = `Uploading files ${currentBatchDone+1}/${currentBatchSize}`;
|
||||
uploadBar.classList.add("uploading");
|
||||
uploadProgressBarFill.style.width = "0%";
|
||||
submitButton.disabled = true;
|
||||
submitButton.value = "Uploading files...";
|
||||
|
||||
try {
|
||||
let utf8Filename = strToUTF8Arr(next.file.name);
|
||||
let base64Filename = base64EncArr(utf8Filename);
|
||||
// NOTE(asaf): We use XHR because fetch can't do upload progress reports. Womp womp. https://youtu.be/Pubd-spHN-0?t=2
|
||||
currentXhr = new XMLHttpRequest();
|
||||
currentXhr.upload.addEventListener("progress", updateUploadProgress);
|
||||
currentXhr.open("POST", uploadUrl, true);
|
||||
currentXhr.setRequestHeader("Hmn-Upload-Filename", base64Filename);
|
||||
currentXhr.responseType = "json";
|
||||
currentXhr.addEventListener("loadend", uploadDone);
|
||||
currentXhr.send(next.file);
|
||||
currentUpload = next;
|
||||
} catch (err) {
|
||||
replaceUploadStringError(next);
|
||||
console.error(err);
|
||||
uploadNext();
|
||||
}
|
||||
} else {
|
||||
submitButton.disabled = false;
|
||||
submitButton.value = submitText;
|
||||
uploadBar.classList.remove("uploading");
|
||||
currentBatchSize = 0;
|
||||
currentBatchDone = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
let utf8Filename = strToUTF8Arr(next.file.name);
|
||||
let base64Filename = base64EncArr(utf8Filename);
|
||||
// NOTE(asaf): We use XHR because fetch can't do upload progress reports. Womp womp. https://youtu.be/Pubd-spHN-0?t=2
|
||||
currentXhr = new XMLHttpRequest();
|
||||
currentXhr.upload.addEventListener("progress", updateUploadProgress);
|
||||
currentXhr.open("POST", uploadUrl, true);
|
||||
currentXhr.setRequestHeader("Hmn-Upload-Filename", base64Filename);
|
||||
currentXhr.responseType = "json";
|
||||
currentXhr.addEventListener("loadend", uploadDone);
|
||||
currentXhr.send(next.file);
|
||||
currentUpload = next;
|
||||
} catch (err) {
|
||||
replaceUploadStringError(next);
|
||||
console.error(err);
|
||||
uploadNext();
|
||||
}
|
||||
} else {
|
||||
submitButton.disabled = false;
|
||||
submitButton.value = submitText;
|
||||
uploadBar.classList.remove("uploading");
|
||||
currentBatchSize = 0;
|
||||
currentBatchDone = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{{ end }}
|
||||
|
|
Loading…
Reference in New Issue