diff --git a/app/javascript/application.js b/app/javascript/application.js
index b126c63..ef2a0e4 100644
--- a/app/javascript/application.js
+++ b/app/javascript/application.js
@@ -1,21 +1,23 @@
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
-import "@hotwired/turbo-rails"
-import "controllers"
+// import "@hotwired/turbo-rails"
+// import "controllers"
// Initialize the upload form.
function upload_form_init() {
// Disable the submit button if Javascript is supported.
// Upload will start right after selecting images.
- // $("#file-submit").hide();
- document.getElementById("file-submit").style.display = "none";
+ const fileSubmit = document.getElementById("file-submit");
+ if (fileSubmit)
+ {
+ fileSubmit.style.display = "none";
+ }
// Install event handler to notice when files were selected.
- // $("#file").on("change", upload_form_files_selected);
- document.getElementById("file").addEventListener("change", upload_form_files_selected);
+ document.getElementById("file")?.addEventListener("change", upload_form_files_selected);
}
function upload_form_files_selected() {
- no_files = this.files.length;
+ var no_files = this.files.length;
if (no_files > 0) {
document.getElementById("file-label").innerHTML = `${no_files} files selected - uploading…`;
document.getElementById("file-select-button").disabled = true;
@@ -28,7 +30,7 @@ function upload_form_files_selected() {
}
// Handle Ctrl-V to paste an image directly
-export function upload_paste_handler(event) {
+function upload_paste_handler(event, uploadUrl) {
console.log("paste!");
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
@@ -48,45 +50,48 @@ export function upload_paste_handler(event) {
console.log(item.type);
var file = item.getAsFile();
console.log(file);
- upload_file_with_ajax(file);
+ upload_file_with_ajax(file, uploadUrl);
}
}
-function upload_file_with_ajax(file) {
+function upload_file_with_ajax(file, uploadUrl) {
if (file == null) {
console.log("File was null. Strange.");
display_error("Maybe the image was too large.");
return;
}
+
var formData = new FormData();
formData.append("file", file);
+ console.log(formData);
- fetch(ajax_upload_url, {
+ fetch(uploadUrl, {
method: "POST",
body: formData,
headers: {
+ "X-CSRF-Token": document.querySelector('meta[name="csrf-token"]').content,
// 'Content-Type' is omitted to let the browser set it automatically
// with the proper boundary for FormData
},
})
- .then(async (response) => {
- if (!response.ok) {
- const errorData = await response.json();
- console.log(`AJAX file upload returned error: ${response.statusText}`);
- display_error(errorData);
- throw new Error("Upload failed");
- }
- return response.json();
- })
- .then((data) => {
- console.log("AJAX file upload was ok");
- window.location.replace(after_upload_url);
- })
- .catch((error) => {
- if (error.message !== "Upload failed") {
- console.log(`AJAX file upload error: ${error}`);
- }
- });
+ .then(async (response) => {
+ if (!response.ok) {
+ const errorData = await response.json();
+ console.log(`AJAX file upload returned error: ${response.statusText}`);
+ display_error(errorData);
+ throw new Error("Upload failed");
+ }
+ return response.json();
+ })
+ .then((data) => {
+ console.log("AJAX file upload was ok");
+ window.location.replace(after_upload_url);
+ })
+ .catch((error) => {
+ if (error.message !== "Upload failed") {
+ console.log(`AJAX file upload error: ${error}`);
+ }
+ });
// $.ajax(ajax_upload_url, {
// type: "POST",
@@ -107,7 +112,8 @@ function upload_file_with_ajax(file) {
// });
}
-function display_error(msg) {
+function display_error(msg) { console.log("foo");
+
// $("#messages").html(
// '
Sorry, pasting did not work. ' + msg + "
"
// );
@@ -117,3 +123,21 @@ function display_error(msg) {
`;
}
+
+
+document.addEventListener("DOMContentLoaded", () => {
+ console.log("DOM loaded");
+ // Handle uploads on specific views/pages. The DIV with ID
+ // #data-js-upload-form carries data attributes that tell us where
+ // uploads will be sent from Javascript.
+ let element = document.getElementById("data-js-upload-form");
+
+ if (element) {
+ console.log("upload_form_init");
+ // console.log(element.dataset);
+ // console.log(element.dataset.uploadUrl);
+ upload_form_init(element.dataset.uploadUrl);
+ // document.onpaste = upload_paste_handler(element.dataset.uploadUrl);
+ document.onpaste = function(event) { upload_paste_handler(event, element.dataset.uploadUrl); }
+ }
+});
diff --git a/app/views/packages/_receive_upload.slim b/app/views/packages/_receive_upload.slim
index 6b66f2c..eb564ee 100644
--- a/app/views/packages/_receive_upload.slim
+++ b/app/views/packages/_receive_upload.slim
@@ -1,5 +1,9 @@
/ Render this callout on top of the package's details page
/ if images have just been uploaded.
+
+// Make variables accessible by the JS that handles uploads
+#data-js-upload-form data-upload-url=upload_receive_json_path
+
- if (@valid_images and @valid_images.any?) or (@invalid_images and @invalid_images.any?)
.callout.warning
diff --git a/app/views/packages/details.slim b/app/views/packages/details.slim
index d0e9160..3651608 100644
--- a/app/views/packages/details.slim
+++ b/app/views/packages/details.slim
@@ -66,13 +66,8 @@
= render(partial: 'details_rightbox', locals: {pkg: @package})
javascript:
- import {upload_paste_handler} from 'aplication';
-
- // Handle Ctrl-V to paste an image directly
- document.onpaste = upload_paste_handler;
-
// Where to send POST requests for uploads
- var ajax_upload_url = '#{{upload_receive_json_path}}';
+ let ajax_upload_url = '#{{upload_receive_json_path}}';
// Where to go to after a successful image upload
- var after_upload_url = '#{{package_path(@package)}}';
+ let after_upload_url = '#{{package_path(@package)}}';
diff --git a/app/views/packages/upload.slim b/app/views/packages/upload.slim
index fb439d8..22ad9a8 100644
--- a/app/views/packages/upload.slim
+++ b/app/views/packages/upload.slim
@@ -64,18 +64,11 @@ h1 = "Upload screenshots for #{@package.name}"
' from a shell using after setting "export LANG=C".
li can be pasted here from your clipboard (Ctrl-V)
-/ javascript:
-/ // Hide the submit button unless images are selected for upload
-/ // $(document).ready(upload_form_init);
-/ import upload_form_init from '../../assets/javascripts/upload.js';
-/ document.addEventListener('DOMContentLoaded', upload_form_init);
+javascript:
+ // todo: use data attributes to pass this information to javascript
+ // https://chat.deepseek.com/a/chat/s/41a4350b-7799-42bf-aec9-3c205b22ab24
+ // Where to send POST requests for uploads
+ let ajax_upload_url = '#{{upload_receive_json_path}}';
-/ // import upload_paste_handler from '../../assets/javascripts/debshots.js';
-/ // Handle Ctrl-V to paste an image directly
-/ document.onpaste = upload_paste_handler;
-
-/ // Where to send POST requests for uploads
-/ var ajax_upload_url = '#{{upload_receive_json_path}}';
-
-/ // Where to go to after a successful image upload
-/ var after_upload_url = '#{{package_path(@package)}}';
+ // Where to go to after a successful image upload
+ let after_upload_url = '#{{package_path(@package)}}';
diff --git a/config/importmap.rb b/config/importmap.rb
new file mode 100644
index 0000000..e7724df
--- /dev/null
+++ b/config/importmap.rb
@@ -0,0 +1,7 @@
+# Pin npm packages by running ./bin/importmap
+
+pin 'application'
+pin '@hotwired/turbo-rails', to: 'turbo.min.js'
+pin '@hotwired/stimulus', to: 'stimulus.min.js'
+pin '@hotwired/stimulus-loading', to: 'stimulus-loading.js'
+pin_all_from 'app/javascript/controllers', under: 'controllers'
diff --git a/config/webpack/webpack.config.js b/config/webpack/webpack.config.js
new file mode 100644
index 0000000..1e6710b
--- /dev/null
+++ b/config/webpack/webpack.config.js
@@ -0,0 +1,21 @@
+const path = require("path")
+const webpack = require("webpack")
+
+module.exports = {
+ mode: "production",
+ devtool: "source-map",
+ entry: {
+ application: "./app/javascript/application.js"
+ },
+ output: {
+ filename: "[name].js",
+ sourceMapFilename: "[file].map",
+ chunkFormat: "module",
+ path: path.resolve(__dirname, '..', '..', 'app/assets/builds')
+ },
+ plugins: [
+ new webpack.optimize.LimitChunkCountPlugin({
+ maxChunks: 1
+ })
+ ]
+}