### Changes Made - Added a new SVG asset (`download-solid.svg`) to `src/assets`. - Updated `main.js`: - Added a new template `SETTINGS_MENU_MACRO`. - Improved drag-and-drop file upload handling with visual feedback. - Enhanced macro functionality with custom drag-and-drop events on hotbar macros. - Adjusted `registerSettings` function to include macro menu registration. - Updated `module.json`: - Added macro pack support under `packs` for "asc-asset-manager-macros." - Created new binary files for macro pack (`asc-asset-manager-macros`). - Improved CSS styling: - Added `.dragover` class for better drag-and-drop UI feedback. - Updated styles to include `asc-asset-manager` context. - Updated `upload-choose.hbs` and `upload-form.hbs`: - Added `moduleId` class context. - Enhanced `upload-form` with an image preview section. - Added a new template (`settings-menu-macro.hbs`) for macro-related UI. - Improved logging and hooks for better event tracking and debugging. This commit enhances functionality, user experience, and modularity for managing assets.
212 lines
7.1 KiB
JavaScript
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);
|
|
})
|
|
})
|
|
|
|
|