Files
asc-asset-manager/src/main.js
Anthony Correa 729a711ab3 diff --git a/src/assets/download-solid.svg b/src/assets/download-solid.svg
new file mode 100644
index 0000000..7b84625
--- /dev/null
+++ b/src/assets/download-solid.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path fill="white" d="M288 32c0-17.7-14.3-32-32-32s-32 14.3-32 32l0 242.7-73.4-73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l128 128c12.5 12.5 32.8 12.5 45.3 0l128-128c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L288 274.7 288 32zM64 352c-35.3 0-64 28.7-64 64l0 32c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-32c0-35.3-28.7-64-64-64l-101.5 0-45.3 45.3c-25 25-65.5 25-90.5 0L165.5 352 64 352zm368 56a24 24 0 1 1 0 48 24 24 0 1 1 0-48z"/></svg>
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index 5940532..2277bc3 100644
--- a/src/main.js
+++ b/src/main.js
@@ -7,7 +7,8 @@ export class AscAssetManager {
   static ID = 'asc-asset-manager'
   static TEMPLATES = {
     UPLOAD_CHOOSE:`modules/${this.ID}/templates/upload-choose.hbs`,
-    UPLOAD_FORM:`modules/${this.ID}/templates/upload-form.hbs`
+    UPLOAD_FORM:`modules/${this.ID}/templates/upload-form.hbs`,
+    SETTINGS_MENU_MACRO:`modules/${this.ID}/templates/settings-menu-macro.hbs`
   }

   static getDirectory () {
@@ -34,14 +35,17 @@ export class AscAssetManager {
   }
 }

+Hooks.on('init', ()=>CONFIG.debug.hooks = true)
+
 Hooks.on("ready", function() {
   AscAssetManager.log(false, "Deno nodule reody")
-  registerSettings(AscAssetManager.ID);
+  registerSettings(AscAssetManager);
 });

-Hooks.on("ascAssetManager.renderUploadChoose", () => {
-  renderTemplate(AscAssetManager.TEMPLATES.UPLOAD_CHOOSE).then((content)=>{
-    new Dialog({
+Hooks.on("ascAssetManager.renderUploadChoose", (data={}) => {
+  let {files} = data
+  renderTemplate(AscAssetManager.TEMPLATES.UPLOAD_CHOOSE, {moduleId: AscAssetManager.ID}).then((content)=>{
+    const dialog = new Dialog({
       title: "Choose",
       content: content,
       buttons: [],
@@ -51,19 +55,23 @@ Hooks.on("ascAssetManager.renderUploadChoose", () => {
         const fileInput = html.find("#file-input");
         const form = html.find("form")

+        if (files) {
+          fileInput.val(files)
+        }
+
          // Handle drag-and-drop events
          uploadArea.on("dragover", (event) => {
           event.preventDefault();
-          uploadArea.css("background-color", "#e0f7fa");
+          uploadArea.addClass('dragover')
         });

         uploadArea.on("dragleave", () => {
-          uploadArea.css("background-color", "");
+          uploadArea.removeClass('dragover')
         });

         uploadArea.on("drop", (event) => {
           event.preventDefault();
-          uploadArea.css("background-color", "");
+          // uploadArea.css("background-color", "");
           const files = event.originalEvent.dataTransfer.files;
           if (files.length > 0) {
             AscAssetManager.log(false, 'file dropped change')
@@ -73,7 +81,9 @@ Hooks.on("ascAssetManager.renderUploadChoose", () => {
               dataTransfer.items.add(file); // Add the first dropped file
             }
             fileInput.files = dataTransfer.files;
-            fileInput.trigger('change')
+            for (let file of fileInput.files) {
+              Hooks.callAll("ascAssetManager.renderUploadForm", {file})
+            }
           }
         });

@@ -83,22 +93,56 @@ Hooks.on("ascAssetManager.renderUploadChoose", () => {
            uploadArea.find("p").text(`Selected file: ${Array.from(files).map(f=>f.name).join(', ')}`);

         })
-        form.on('submit', (event) => {
-          for (let file of fileInput.files) {
-            Hooks.callAll("ascAssetManager.renderUploadForm", {file})
-          }
-        })
-
       }
     }).render(true)
   })
 })

-Hooks.on("ascAssetManager.renderUploadForm", (data)=>{
-  const templateData = {fileCategories: AscAssetManager.fileCategories, fileTags: AscAssetManager.fileTags}
+Hooks.on("renderHotbar", ({macros}, html) => {
+  // Find macro on the hotbar
+  for (let macro_item of macros) {
+    const {macro} = macro_item
+    if (macro?.command?.includes("ascAssetManager.renderUploadChoose")) {
+      AscAssetManager.log(false, `Found macro with command: ${macro.name}`);
+
+      // Find the corresponding button in the hotbar
+      const macroButton = html.find(`.macro[data-macro-id='${macro.id}']`);
+
+      if (macroButton.length > 0) {
+        AscAssetManager.log(false, `Adding custom drop event to macro: ${macro.name}`, {macro, macroButton});
+        macroButton.addClass(AscAssetManager.ID)
+
+        macroButton.on('dragover', (event)=>{
+          AscAssetManager.log(false, {event});
+          $(event.currentTarget).addClass('dragover');
+          AscAssetManager.log(false, {classlist: event.currentTarget.classList});
+        })
+        macroButton.on('dragleave', (event)=>$(event.currentTarget).removeClass('dragover'))
+
+        // Add a custom drop event to the macro
+        macroButton.on("drop", (event) => {
+          event.preventDefault();
+          $(event.currentTarget).removeClass('dragover')
+          const files = event.originalEvent.dataTransfer.files;
+          AscAssetManager.log(false, "Dropped file on macro.", {files});
+
+          for (let file of files) {
+            Hooks.callAll("ascAssetManager.renderUploadForm", {file})
+          }
+
+          // Perform your custom logic with the dropped data
+          // handleCustomDrop(droppedData, macro);
+        });
+      }
+    }
+  }
+});
+
+Hooks.on("ascAssetManager.renderUploadForm", (data={})=>{
+  const templateData = {moduleId: AscAssetManager.ID, fileCategories: AscAssetManager.fileCategories, fileTags: AscAssetManager.fileTags}
   renderTemplate(AscAssetManager.TEMPLATES.UPLOAD_FORM, templateData).then(content => {
     let {file} = data
-    new Dialog({
+    const dialog = new Dialog({
       title: "Simple Popup",
       content: content,
       buttons: [],
@@ -153,7 +197,10 @@ Hooks.on("ascAssetManager.renderUploadForm", (data)=>{
                 notify: true
               }
           )
-          .then((res)=>AscAssetManager.log(false, 'Uploaded!', res))
+          .then((res)=>{
+            AscAssetManager.log(false, 'Uploaded!', res);
+            dialog.close()
+          })
           .catch((e)=>ui.notifications.error('Error uploading', e))
         })
       }
diff --git a/src/module.json b/src/module.json
index c63a0cb..1f48002 100644
--- a/src/module.json
+++ b/src/module.json
@@ -13,9 +13,21 @@
     }
   ],
   "esmodules": [
-    "./main.js"
+    "main.js"
   ],
   "styles": [
-    "./styles/style.css"
+    "styles/style.css"
+  ],
+  "packs": [
+    {
+      "name": "asc-asset-manager-macros",
+      "label": "Asset Manager Macros",
+      "path": "packs/asc-asset-manager-macros",
+      "type": "Macro",
+      "ownership": {
+        "PLAYER": "OBSERVER",
+        "ASSISTANT": "OWNER"
+      }
+    }
   ]
 }
\ No newline at end of file
diff --git a/src/packs/asc-asset-manager-macros/000005.ldb b/src/packs/asc-asset-manager-macros/000005.ldb
new file mode 100644
index 0000000..483e9e9
Binary files /dev/null and b/src/packs/asc-asset-manager-macros/000005.ldb differ
diff --git a/src/packs/asc-asset-manager-macros/000008.ldb b/src/packs/asc-asset-manager-macros/000008.ldb
new file mode 100644
index 0000000..c3a5f47
Binary files /dev/null and b/src/packs/asc-asset-manager-macros/000008.ldb differ
diff --git a/src/packs/asc-asset-manager-macros/000011.log b/src/packs/asc-asset-manager-macros/000011.log
new file mode 100644
index 0000000..e69de29
diff --git a/src/packs/asc-asset-manager-macros/CURRENT b/src/packs/asc-asset-manager-macros/CURRENT
new file mode 100644
index 0000000..3051f81
--- /dev/null
+++ b/src/packs/asc-asset-manager-macros/CURRENT
@@ -0,0 +1 @@
+MANIFEST-000010
diff --git a/src/packs/asc-asset-manager-macros/LOCK b/src/packs/asc-asset-manager-macros/LOCK
new file mode 100644
index 0000000..e69de29
diff --git a/src/packs/asc-asset-manager-macros/LOG b/src/packs/asc-asset-manager-macros/LOG
new file mode 100644
index 0000000..f2fe778
--- /dev/null
+++ b/src/packs/asc-asset-manager-macros/LOG
@@ -0,0 +1,3 @@
+2025/01/19-15:09:29.737471 17359b000 Recovering log #9
+2025/01/19-15:09:29.737887 17359b000 Delete type=3 #7
+2025/01/19-15:09:29.737973 17359b000 Delete type=0 #9
diff --git a/src/packs/asc-asset-manager-macros/LOG.old b/src/packs/asc-asset-manager-macros/LOG.old
new file mode 100644
index 0000000..65b43b2
--- /dev/null
+++ b/src/packs/asc-asset-manager-macros/LOG.old
@@ -0,0 +1,5 @@
+2025/01/19-15:04:17.219781 17397b000 Recovering log #6
+2025/01/19-15:04:17.219809 17397b000 Level-0 table #8: started
+2025/01/19-15:04:17.219961 17397b000 Level-0 table #8: 634 bytes OK
+2025/01/19-15:04:17.220279 17397b000 Delete type=0 #6
+2025/01/19-15:04:17.220330 17397b000 Delete type=3 #4
diff --git a/src/packs/asc-asset-manager-macros/MANIFEST-000010 b/src/packs/asc-asset-manager-macros/MANIFEST-000010
new file mode 100644
index 0000000..9767b8e
Binary files /dev/null and b/src/packs/asc-asset-manager-macros/MANIFEST-000010 differ
diff --git a/src/settings.js b/src/settings.js
index d8fdb69..d8d9533 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -1,6 +1,7 @@
-export function registerSettings(ID) {
+export function registerSettings(AscAssetManager) {
   console.log("Registering settings for My Module...");
-
+  const ID = AscAssetManager.ID
+  //<a class="content-link" draggable="true" data-link="" data-uuid="Item.VF90ijwtDojmEQE5" data-id="VF90ijwtDojmEQE5" data-type="Item" data-tooltip="Ability Item"><i class="fas fa-suitcase"></i>Ability</a>
   // Register the "enableFeature" setting
   game.settings.register(ID, "enableFeature", {
     name: "Enable Feature",
@@ -45,4 +46,30 @@ export function registerSettings(ID) {
       console.log(`Theme changed to: ${value}`);
     }
   });
+
+  game.settings.registerMenu(ID, "instructions", {
+    name: "Add macro to hotbar",
+    label: "Get Macro",
+    scope: "world",
+    icon: "fas fa-code",
+    config: true,
+    type: class extends FormApplication {
+      static get defaultOptions() {
+        return mergeObject(super.defaultOptions, {
+          id: ID, // Unique ID for the application
+          title: "Simple Form Application", // Title of the window
+          template: AscAssetManager.TEMPLATES.SETTINGS_MENU_MACRO, // Path to your Handlebars template
+          width: 300, // Width of the form
+          height: "auto", // Adjust height automatically
+        });
+      }
+      async getData() {
+        const macros = game.packs.get("asc-asset-manager.asc-asset-manager-macros").getDocuments()
+        return {
+          moduleId: ID,
+          macros: await macros
+        }
+      }
+    },
+  });
 }
\ No newline at end of file
diff --git a/src/styles/style.css b/src/styles/style.css
index 30dbf29..36e4e46 100644
--- a/src/styles/style.css
+++ b/src/styles/style.css
@@ -1,7 +1,17 @@
-#upload-area {
-  border: 2px dashed #ccc;
-  padding: 20px;
-  text-align: center;
-  cursor: pointer;
-  background-color: #f9f9f9;
-}
\ No newline at end of file
+.asc-asset-manager {
+  /* --dragover-border-color: #e0f7fa; */
+  --dragover-border-color: var(--color-border-highlight);
+
+  &#upload-area {
+    border: 2px dashed #ccc;
+    padding: 20px;
+    text-align: center;
+    cursor: pointer;
+    background-color: #f9f9f9;
+  }
+
+  &.dragover {
+    border: 2px solid var(--dragover-border-color) !important;
+  }
+}
+
diff --git a/src/templates/settings-menu-macro.hbs b/src/templates/settings-menu-macro.hbs
new file mode 100644
index 0000000..ace76de
--- /dev/null
+++ b/src/templates/settings-menu-macro.hbs
@@ -0,0 +1,20 @@
+<div class="{{moduleId}}">
+  <div style="display:flex;justify-items:center;">
+    {{#each macros}}
+      <a
+      class="content-link"
+      draggable="true"
+      data-link=""
+      data-pack="asc-asset-manager.asc-asset-manager-macros" data-tooltip="Script Macro"
+      data-type="Macro"
+      data-uuid="{{uuid}}"
+      data-id="{{id}}"
+      data-tooltip="Script Macro">
+      <i class="fas fa-code"></i>{{name}}</a>
+    {{/each}}
+    </div>
+  <div>
+    <p>Drag this macro to your hotbar to make it easily accessible during gameplay!</p>
+    <p>You can drag the macro by clicking and holding the macro icon, then dropping it onto the hotbar at the bottom of your screen.</p>
+  </div>
+</div>
\ No newline at end of file
diff --git a/src/templates/upload-choose.hbs b/src/templates/upload-choose.hbs
index 0605c88..111a738 100644
--- a/src/templates/upload-choose.hbs
+++ b/src/templates/upload-choose.hbs
@@ -1,7 +1,6 @@
   <form action="">
-    <div id="upload-area">
+    <div id="upload-area" class="{{moduleId}}">
       <p>Drag files here to upload</p>
       <input type="file" id="file-input" style="display:none;">
     </div>
-    <button type="submit">Submit</button>
   </form>
\ No newline at end of file
diff --git a/src/templates/upload-form.hbs b/src/templates/upload-form.hbs
index 0027133..ee2c541 100644
--- a/src/templates/upload-form.hbs
+++ b/src/templates/upload-form.hbs
@@ -1,6 +1,6 @@
-<form id="upload-form">
+<form id="upload-form" class="{{moduleId}}">
   <input type="text" id="file-input" style="" readonly>
-  <img height=100px>
+  <div class="image-preview"><img height=100px></div>

   <div class="form-group">
       <label>Category</label>
2025-01-19 15:47:17 -06:00

212 lines
7.1 KiB
JavaScript

const LOG_PREFIX = "asc-asset-manager | "
import { registerSettings } from "./settings.js";
import { parseFileName, createMetaFileName } from "./utils.js";
export class AscAssetManager {
static ID = 'asc-asset-manager'
static TEMPLATES = {
UPLOAD_CHOOSE:`modules/${this.ID}/templates/upload-choose.hbs`,
UPLOAD_FORM:`modules/${this.ID}/templates/upload-form.hbs`,
SETTINGS_MENU_MACRO:`modules/${this.ID}/templates/settings-menu-macro.hbs`
}
static getDirectory () {
return game.settings.get(this.ID, "rootDirectory")
}
static fileCategories = [
{id: "npcn", label: "NPC (Named)"},
{id: "npcu", label: "NPC (Unnamed)"},
{id: "scene", label: "Scene Background"},
{id: "pc", label: "PC"},
{id: "inset", label: "Inset"},
{id: "vehicle", label: "Vehicle"},
{id: "weapon", label: "Weapon"}
]
static fileTags = [
{id:"tk", label: "Token"},
{id:"sq", label: "Square"}
]
static log(force, ...args) {
console.log(this.ID, '|', ...args);
}
}
Hooks.on('init', ()=>CONFIG.debug.hooks = true)
Hooks.on("ready", function() {
AscAssetManager.log(false, "Deno nodule reody")
registerSettings(AscAssetManager);
});
Hooks.on("ascAssetManager.renderUploadChoose", (data={}) => {
let {files} = data
renderTemplate(AscAssetManager.TEMPLATES.UPLOAD_CHOOSE, {moduleId: AscAssetManager.ID}).then((content)=>{
const dialog = new Dialog({
title: "Choose",
content: content,
buttons: [],
render: (html)=> {
AscAssetManager.log(false, 'Rendering choose window')
const uploadArea = html.find("#upload-area");
const fileInput = html.find("#file-input");
const form = html.find("form")
if (files) {
fileInput.val(files)
}
// Handle drag-and-drop events
uploadArea.on("dragover", (event) => {
event.preventDefault();
uploadArea.addClass('dragover')
});
uploadArea.on("dragleave", () => {
uploadArea.removeClass('dragover')
});
uploadArea.on("drop", (event) => {
event.preventDefault();
// uploadArea.css("background-color", "");
const files = event.originalEvent.dataTransfer.files;
if (files.length > 0) {
AscAssetManager.log(false, 'file dropped change')
// Update the file input with the dropped file
const dataTransfer = new DataTransfer();
for (let file of files) {
dataTransfer.items.add(file); // Add the first dropped file
}
fileInput.files = dataTransfer.files;
for (let file of fileInput.files) {
Hooks.callAll("ascAssetManager.renderUploadForm", {file})
}
}
});
fileInput.on("change", (event)=> {
const files = fileInput.files
// Show feedback to the user
uploadArea.find("p").text(`Selected file: ${Array.from(files).map(f=>f.name).join(', ')}`);
})
}
}).render(true)
})
})
Hooks.on("renderHotbar", ({macros}, html) => {
// Find macro on the hotbar
for (let macro_item of macros) {
const {macro} = macro_item
if (macro?.command?.includes("ascAssetManager.renderUploadChoose")) {
AscAssetManager.log(false, `Found macro with command: ${macro.name}`);
// Find the corresponding button in the hotbar
const macroButton = html.find(`.macro[data-macro-id='${macro.id}']`);
if (macroButton.length > 0) {
AscAssetManager.log(false, `Adding custom drop event to macro: ${macro.name}`, {macro, macroButton});
macroButton.addClass(AscAssetManager.ID)
macroButton.on('dragover', (event)=>{
AscAssetManager.log(false, {event});
$(event.currentTarget).addClass('dragover');
AscAssetManager.log(false, {classlist: event.currentTarget.classList});
})
macroButton.on('dragleave', (event)=>$(event.currentTarget).removeClass('dragover'))
// Add a custom drop event to the macro
macroButton.on("drop", (event) => {
event.preventDefault();
$(event.currentTarget).removeClass('dragover')
const files = event.originalEvent.dataTransfer.files;
AscAssetManager.log(false, "Dropped file on macro.", {files});
for (let file of files) {
Hooks.callAll("ascAssetManager.renderUploadForm", {file})
}
// Perform your custom logic with the dropped data
// handleCustomDrop(droppedData, macro);
});
}
}
}
});
Hooks.on("ascAssetManager.renderUploadForm", (data={})=>{
const templateData = {moduleId: AscAssetManager.ID, fileCategories: AscAssetManager.fileCategories, fileTags: AscAssetManager.fileTags}
renderTemplate(AscAssetManager.TEMPLATES.UPLOAD_FORM, templateData).then(content => {
let {file} = data
const dialog = new Dialog({
title: "Simple Popup",
content: content,
buttons: [],
render: (html) =>{
AscAssetManager.log('file', file)
const uploadArea = html.find("#upload-area");
const fileInput = html.find("#file-input");
const form = html.find('#upload-form');
const namePreview = html.find('#name-preview')
const baseName = form.find("input[id='baseName']")
fileInput.val(file.name)
const reader = new FileReader();
reader.onload = (e) => {
const img = form.find("img");
const blob = new Blob([e.target.result], { type: file.type });
const blobUrl = URL.createObjectURL(blob)
AscAssetManager.log(false, blobUrl,img)
img.attr("src", blobUrl)
};
reader.readAsArrayBuffer(file)
baseName.val(parseFileName(file.name).fileName)
// Handle click to open file selector
// uploadArea.on("click", () => fileInput.click());
form.on('change', (event)=>{
const fileExtension = parseFileName(fileInput.val()).fileExtension
const fileCategory = form.find("select[name='file-category'] option:checked").val()
const fileTags = form.find("input[name='file-tags']:checked").map(function(){
return $(this).val()
}).get()
AscAssetManager.log(false, 'form changed', {fileCategory, fileTags, baseName})
const new_filename = createMetaFileName(`${baseName.val()}.${fileExtension}`,{
category: fileCategory,
tags: fileTags
})
namePreview.val(new_filename)
})
form.on('submit', (event) => {
AscAssetManager.log(false, "Form Submitted");
event.preventDefault();
const renamedFile = new File([file], namePreview.val(), {type:file.type})
FilePicker.upload(
"data",
AscAssetManager.getDirectory(),
renamedFile,
{
notify: true
}
)
.then((res)=>{
AscAssetManager.log(false, 'Uploaded!', res);
dialog.close()
})
.catch((e)=>ui.notifications.error('Error uploading', e))
})
}
}).render(true);
})
})