Fix issues with asset upload

It didn't work when creating a new project or editing personal projects,
due to routing issues. I also took this opportunity to make the script
support multiple form submit buttons, since in some cases we will have a
submit button on each tab, and I figured they all should respect the
fact that you have an upload in progress.
This commit is contained in:
Ben Visness 2022-08-01 21:59:42 -05:00
parent a295d0ed52
commit d164a58ba0
5 changed files with 42 additions and 42 deletions

View File

@ -1,28 +1,31 @@
/* Requires base64.js // Requires base64.js
Usage: setupMarkdownUpload(eSubmit, eFileInput, eUploadBar, eText, doMarkdown, maxFileSize, uploadUrl) /**
eSubmit is the element of the button to submit/save the markdown changes. It * Sets up file / image uploading for Markdown content.
will be disabled and tell users files are uploading while uploading is *
happening. * @param eSubmits A list of elements of buttons to submit/save the page you're on. They
eFileInput is the <input type="file"> * will be disabled and tell users files are uploading while uploading is
eUploadBar usually looks like * happening.
<div class="upload_bar flex-grow-1"> * @param eFileInput The `<input type="file">`
<div class="instructions"> * @param eUploadBar Usually looks like
Upload files by dragging & dropping, pasting, or <label class="pointer link" for="file_input">selecting</label> them. * ```
</div> * <div class="upload_bar flex-grow-1">
<div class="progress flex"> * <div class="instructions">
<div class="progress_text mr3"></div> * Upload files by dragging & dropping, pasting, or <label class="pointer link" for="file_input">selecting</label> them.
<div class="progress_bar flex-grow-1 flex-shrink-1 pa1"><div class=""></div></div> * </div>
</div> * <div class="progress flex">
</div> * <div class="progress_text mr3"></div>
eText is the text field that can be dropped into and is editing the markdown. * <div class="progress_bar flex-grow-1 flex-shrink-1 pa1"><div class=""></div></div>
doMarkdown is the function returned by initLiveMarkdown. * </div>
maxFileSize * </div>
uploadUrl * ```
*/ * @param eText The text field that can be dropped into and is editing the markdown.
* @param doMarkdown The function returned by `initLiveMarkdown`.
function setupMarkdownUpload(eSubmit, eFileInput, eUploadBar, eText, doMarkdown, maxFileSize, uploadUrl) { * @param maxFileSize The max allowed file size in bytes.
const submitText = eSubmit.value; * @param uploadUrl The URL to POST assets to (unique per project to avoid CORS issues).
*/
function setupMarkdownUpload(eSubmits, eFileInput, eUploadBar, eText, doMarkdown, maxFileSize, uploadUrl) {
const submitTexts = Array.from(eSubmits).map(e => e.value);
const uploadProgress = eUploadBar.querySelector('.progress'); const uploadProgress = eUploadBar.querySelector('.progress');
const uploadProgressText = eUploadBar.querySelector('.progress_text'); const uploadProgressText = eUploadBar.querySelector('.progress_text');
const uploadProgressBar = eUploadBar.querySelector('.progress_bar'); const uploadProgressBar = eUploadBar.querySelector('.progress_bar');
@ -207,8 +210,10 @@ function setupMarkdownUpload(eSubmit, eFileInput, eUploadBar, eText, doMarkdown,
uploadProgressText.textContent = `Uploading files ${currentBatchDone+1}/${currentBatchSize}`; uploadProgressText.textContent = `Uploading files ${currentBatchDone+1}/${currentBatchSize}`;
eUploadBar.classList.add("uploading"); eUploadBar.classList.add("uploading");
uploadProgressBarFill.style.width = "0%"; uploadProgressBarFill.style.width = "0%";
eSubmit.disabled = true; for (const e of eSubmits) {
eSubmit.value = "Uploading files..."; e.disabled = true;
e.value = "Uploading files...";
}
try { try {
let utf8Filename = strToUTF8Arr(next.file.name); let utf8Filename = strToUTF8Arr(next.file.name);
@ -228,8 +233,10 @@ function setupMarkdownUpload(eSubmit, eFileInput, eUploadBar, eText, doMarkdown,
uploadNext(); uploadNext();
} }
} else { } else {
eSubmit.disabled = false; for (const [i, e] of eSubmits.entries()) {
eSubmit.value = submitText; e.disabled = false;
e.value = submitTexts[i];
}
eUploadBar.classList.remove("uploading"); eUploadBar.classList.remove("uploading");
currentBatchSize = 0; currentBatchSize = 0;
currentBatchDone = 0; currentBatchDone = 0;

View File

@ -163,16 +163,8 @@ func SampleSeed() {
} }
} }
// admin := CreateAdminUser("admin", "12345678") // Finally, set sequence numbers to things that won't conflict
// user := CreateUser("regular_user", "12345678") utils.Must1(tx.Exec(ctx, "SELECT setval('project_id_seq', 100, true);"))
// hmnProject := CreateProject("hmn", "Handmade Network")
// Create category
// Create thread
// Create accepted user project
// Create pending user project
// Create showcase items
// Create codelanguages
// Create library and library resources
utils.Must0(tx.Commit(ctx)) utils.Must0(tx.Commit(ctx))
} }

View File

@ -123,7 +123,7 @@
/ Asset upload / Asset upload
*/ */
setupMarkdownUpload( setupMarkdownUpload(
document.querySelector("#form input[type=submit]"), document.querySelectorAll("#form input[type=submit]"),
document.querySelector('#file_input'), document.querySelector('#file_input'),
document.querySelector('.upload_bar'), document.querySelector('.upload_bar'),
textField, textField,

View File

@ -389,7 +389,7 @@
// Asset upload // // Asset upload //
////////////////// //////////////////
setupMarkdownUpload( setupMarkdownUpload(
document.querySelector("#project_form [data-name=Description] input[type=submit]"), document.querySelectorAll("#project_form input[type=submit]"),
document.querySelector('#file_input'), document.querySelector('#file_input'),
document.querySelector('.upload_bar'), document.querySelector('.upload_bar'),
description, description,

View File

@ -186,14 +186,15 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler {
fmt.Sprintf("blog%s", c.PathParams["remainder"]), nil, fmt.Sprintf("blog%s", c.PathParams["remainder"]), nil,
), http.StatusMovedPermanently) ), http.StatusMovedPermanently)
}) })
rb.POST(hmnurl.RegexAssetUpload, AssetUpload)
} }
officialProjectRoutes := anyProject.WithMiddleware(officialProjectMiddleware) officialProjectRoutes := anyProject.WithMiddleware(officialProjectMiddleware)
personalProjectRoutes := hmnOnly.Group(hmnurl.RegexPersonalProject, personalProjectMiddleware) personalProjectRoutes := hmnOnly.Group(hmnurl.RegexPersonalProject, personalProjectMiddleware)
attachProjectRoutes(&officialProjectRoutes) attachProjectRoutes(&officialProjectRoutes)
attachProjectRoutes(&personalProjectRoutes) attachProjectRoutes(&personalProjectRoutes)
anyProject.POST(hmnurl.RegexAssetUpload, AssetUpload) // TODO(ben): Uh, should these all be pulled into the project route group above...?
anyProject.GET(hmnurl.RegexEpisodeList, EpisodeList) anyProject.GET(hmnurl.RegexEpisodeList, EpisodeList)
anyProject.GET(hmnurl.RegexEpisode, Episode) anyProject.GET(hmnurl.RegexEpisode, Episode)
anyProject.GET(hmnurl.RegexCineraIndex, CineraIndex) anyProject.GET(hmnurl.RegexCineraIndex, CineraIndex)