Add initial implementation for AscAssetManager module
This commit introduces the following key features: - **New `.gitignore`**: - Ignores `.vscode`, `.eslintrc.js`, and `dist/module.zip`. - **Core functionality**: - Created `src/main.js` to implement the `AscAssetManager` class with methods to manage file uploads, categories, tags, and settings registration. - Introduced hooks for rendering and managing custom upload dialogs and forms. - **Configuration and settings**: - Added `src/settings.js` to register settings for features like enabling/disabling, root directory configuration, and theme selection. - **Templates**: - Added `upload-choose.hbs` for the file selection dialog. - Added `upload-form.hbs` for the file metadata customization dialog. - **Utilities**: - Added `src/utils.js` with helper functions for file parsing, metadata handling, and filename creation. - **Styling**: - Added `style.css` for styling upload areas. - **Module metadata**: - Added `module.json` with module details, compatibility, and dependencies. This commit establishes the foundational structure and functionality for the AscAssetManager module.
This commit is contained in:
164
src/main.js
Normal file
164
src/main.js
Normal file
@@ -0,0 +1,164 @@
|
||||
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`
|
||||
}
|
||||
|
||||
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("ready", function() {
|
||||
AscAssetManager.log(false, "Deno nodule reody")
|
||||
registerSettings(AscAssetManager.ID);
|
||||
});
|
||||
|
||||
Hooks.on("ascAssetManager.renderUploadChoose", () => {
|
||||
renderTemplate(AscAssetManager.TEMPLATES.UPLOAD_CHOOSE).then((content)=>{
|
||||
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")
|
||||
|
||||
// Handle drag-and-drop events
|
||||
uploadArea.on("dragover", (event) => {
|
||||
event.preventDefault();
|
||||
uploadArea.css("background-color", "#e0f7fa");
|
||||
});
|
||||
|
||||
uploadArea.on("dragleave", () => {
|
||||
uploadArea.css("background-color", "");
|
||||
});
|
||||
|
||||
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;
|
||||
fileInput.trigger('change')
|
||||
}
|
||||
});
|
||||
|
||||
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(', ')}`);
|
||||
|
||||
})
|
||||
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}
|
||||
renderTemplate(AscAssetManager.TEMPLATES.UPLOAD_FORM, templateData).then(content => {
|
||||
let {file} = data
|
||||
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))
|
||||
.catch((e)=>ui.notifications.error('Error uploading', e))
|
||||
})
|
||||
}
|
||||
}).render(true);
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user