Compare commits
9 Commits
c25715c8d0
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
8fbbb4f788
|
|||
|
e6e8ae4f3f
|
|||
|
fb9eeba103
|
|||
|
04aee6e44c
|
|||
|
3fdaadf7e0
|
|||
|
4cd01570f7
|
|||
|
a9ba4f27ff
|
|||
|
1d698c0ef1
|
|||
|
07db5da750
|
1
.gitattributes
vendored
Normal file
1
.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
src/packs/** binary
|
||||
22
src/main.js
22
src/main.js
@@ -8,7 +8,8 @@ export class AscAssetManager {
|
||||
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`
|
||||
SETTINGS_MENU_MACRO:`modules/${this.ID}/templates/settings-menu-macro.hbs`,
|
||||
SETTINGS_TAGS_AND_CATEGORIES:`modules/${this.ID}/templates/settings-tags-and-categories.hbs`
|
||||
}
|
||||
|
||||
static getDirectory () {
|
||||
@@ -35,11 +36,20 @@ export class AscAssetManager {
|
||||
}
|
||||
}
|
||||
|
||||
Hooks.on('init', ()=>CONFIG.debug.hooks = true)
|
||||
Hooks.on('init', ()=>{
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
Hooks.on("ready", function() {
|
||||
AscAssetManager.log(false, "Deno nodule reody")
|
||||
registerSettings(AscAssetManager);
|
||||
const DEBUG = game.settings.get(AscAssetManager.ID, "enableDebugMode")
|
||||
if (DEBUG) {
|
||||
AscAssetManager.log(false, "Debug Mode Enabled")
|
||||
CONFIG.debug.hooks = true
|
||||
}
|
||||
AscAssetManager.log(false, "Deno nodule reody")
|
||||
|
||||
});
|
||||
|
||||
Hooks.on("ascAssetManager.renderUploadChoose", (data={}) => {
|
||||
@@ -139,7 +149,11 @@ Hooks.on("renderHotbar", ({macros}, html) => {
|
||||
});
|
||||
|
||||
Hooks.on("ascAssetManager.renderUploadForm", (data={})=>{
|
||||
const templateData = {moduleId: AscAssetManager.ID, fileCategories: AscAssetManager.fileCategories, fileTags: AscAssetManager.fileTags}
|
||||
const templateData = {
|
||||
moduleId: AscAssetManager.ID,
|
||||
fileCategories: game.settings.get(AscAssetManager.ID, "categories"),
|
||||
fileTags: game.settings.get(AscAssetManager.ID, "tags")
|
||||
}
|
||||
renderTemplate(AscAssetManager.TEMPLATES.UPLOAD_FORM, templateData).then(content => {
|
||||
let {file} = data
|
||||
const dialog = new Dialog({
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
{
|
||||
"id": "asc-asset-manager",
|
||||
"title": "asc-asset-manager",
|
||||
"version": "0.1.0",
|
||||
"title": "Asset Manager",
|
||||
"version": "0.2.1",
|
||||
"download": "https://gitea.ascorrea.com/asc/asc-asset-manager/releases/download/0.2.1/module.zip",
|
||||
"manifest": "https://gitea.ascorrea.com/asc/asc-asset-manager/releases/download/latest/module.json",
|
||||
"compatibility": {
|
||||
"minimum": "12",
|
||||
"verified": "12"
|
||||
"verified": "12.331"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
|
||||
Binary file not shown.
@@ -1 +1 @@
|
||||
MANIFEST-000010
|
||||
MANIFEST-000039
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
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
|
||||
2025/01/29-15:45:18.681004 30ad38000 Recovering log #38
|
||||
2025/01/29-15:45:18.681277 30ad38000 Delete type=0 #38
|
||||
2025/01/29-15:45:18.681298 30ad38000 Delete type=3 #37
|
||||
2025/01/29-15:46:39.436862 310dbb000 Level-0 table #42: started
|
||||
2025/01/29-15:46:39.436930 310dbb000 Level-0 table #42: 0 bytes OK
|
||||
2025/01/29-15:46:39.437031 310dbb000 Delete type=0 #40
|
||||
2025/01/29-15:46:39.437558 310dbb000 Manual compaction at level-0 from '!macros!rdl3Dw3jRkibnQQC' @ 72057594037927935 : 1 .. '!macros!rdl3Dw3jRkibnQQC' @ 0 : 0; will stop at (end)
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
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
|
||||
2025/01/27-20:40:12.716406 16fa73000 Recovering log #35
|
||||
2025/01/27-20:40:12.716718 16fa73000 Delete type=3 #33
|
||||
2025/01/27-20:40:12.716753 16fa73000 Delete type=0 #35
|
||||
|
||||
Binary file not shown.
BIN
src/packs/asc-asset-manager-macros/MANIFEST-000039
Normal file
BIN
src/packs/asc-asset-manager-macros/MANIFEST-000039
Normal file
Binary file not shown.
210
src/settings.js
210
src/settings.js
@@ -3,18 +3,54 @@ export function registerSettings(AscAssetManager) {
|
||||
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",
|
||||
hint: "Enable or disable the special feature of this module.",
|
||||
game.settings.register(ID, "enableDebugMode", {
|
||||
name: "Enable Debug Mode",
|
||||
hint: "Enable or disable debug mode for this module. When enabled, additional debugging information will be logged to the console.",
|
||||
scope: "world",
|
||||
config: true,
|
||||
type: Boolean,
|
||||
default: true,
|
||||
requiresReload: true,
|
||||
default: false,
|
||||
onChange: value => {
|
||||
console.log(`Enable Feature setting changed to: ${value}`);
|
||||
console.log(`Debug Mode setting changed to: ${value}`);
|
||||
}
|
||||
});
|
||||
|
||||
// Register default tags setting
|
||||
game.settings.register(ID, "tags", {
|
||||
name: "Tags",
|
||||
hint: "A list of tags to use in the module.",
|
||||
scope: "world", // "world" means the setting is shared across all users; "client" means it's per-user
|
||||
config: false, // Whether the setting shows up in the settings menu
|
||||
type: Object, // Data type
|
||||
default: [
|
||||
{id:"tk", label: "Token"},
|
||||
{id:"sq", label: "Square"}
|
||||
], // Default tags
|
||||
onChange: (value) => console.log("Tags updated to:", value) // Optional: Triggered when setting is updated
|
||||
});
|
||||
|
||||
// Register default categories setting
|
||||
game.settings.register(ID, "categories", {
|
||||
name: "Categories",
|
||||
hint: "A list of categories to use in the module.",
|
||||
scope: "world",
|
||||
config: false,
|
||||
type: Object,
|
||||
default: [
|
||||
{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"},
|
||||
{id: "icon", label: "Icon"},
|
||||
{id: "map", label: "Map"}
|
||||
],
|
||||
onChange: (value) => console.log("Categories updated to:", value)
|
||||
});
|
||||
|
||||
// Register the "customMessage" setting
|
||||
game.settings.register(ID, "rootDirectory", {
|
||||
name: "Root Directory",
|
||||
@@ -29,24 +65,6 @@ export function registerSettings(AscAssetManager) {
|
||||
}
|
||||
});
|
||||
|
||||
// Register a dropdown setting
|
||||
game.settings.register(ID, "theme", {
|
||||
name: "Select Theme",
|
||||
hint: "Choose a theme for the module.",
|
||||
scope: "world",
|
||||
config: true,
|
||||
type: String,
|
||||
choices: {
|
||||
light: "Light Theme",
|
||||
dark: "Dark Theme",
|
||||
system: "Use System Default"
|
||||
},
|
||||
default: "system",
|
||||
onChange: value => {
|
||||
console.log(`Theme changed to: ${value}`);
|
||||
}
|
||||
});
|
||||
|
||||
game.settings.registerMenu(ID, "instructions", {
|
||||
name: "Add macro to hotbar",
|
||||
label: "Get Macro",
|
||||
@@ -55,7 +73,7 @@ export function registerSettings(AscAssetManager) {
|
||||
config: true,
|
||||
type: class extends FormApplication {
|
||||
static get defaultOptions() {
|
||||
return mergeObject(super.defaultOptions, {
|
||||
return foundry.utils.FormApplicationmergeObject(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
|
||||
@@ -72,4 +90,148 @@ export function registerSettings(AscAssetManager) {
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
game.settings.registerMenu(ID, "categories", {
|
||||
name: "Set Tags and Categories",
|
||||
label: "Set Tags and Categories",
|
||||
scope: "world",
|
||||
icon: "fas fa-list",
|
||||
config: true,
|
||||
type: class extends FormApplication {
|
||||
static get defaultOptions() {
|
||||
return foundry.utils.mergeObject(super.defaultOptions, {
|
||||
id: ID, // Unique ID for the application
|
||||
title: "Simple Form Application", // Title of the window
|
||||
template: AscAssetManager.TEMPLATES.SETTINGS_TAGS_AND_CATEGORIES, // Path to your Handlebars template
|
||||
width: 300, // Width of the form
|
||||
height: "auto", // Adjust height automatically
|
||||
});
|
||||
}
|
||||
getData() {
|
||||
return {
|
||||
moduleId: ID,
|
||||
categories: game.settings.get(ID, "categories"),
|
||||
tags: game.settings.get(ID, "tags")
|
||||
}
|
||||
}
|
||||
activateListeners(html) {
|
||||
super.activateListeners(html);
|
||||
|
||||
function addRow (html) {
|
||||
// Find the nearest parent div
|
||||
const parentDiv = html.closest("div:has(table)");
|
||||
|
||||
// Find the last row in the body
|
||||
const lastRow = parentDiv.find("tbody tr:last");
|
||||
|
||||
// Clone the last row
|
||||
const newRow = lastRow.clone();
|
||||
|
||||
// Loop through each input in the new row to reset values and update names/ids
|
||||
newRow.find("input").each(function () {
|
||||
const input = $(this);
|
||||
|
||||
// Reset the input value
|
||||
input.val("");
|
||||
|
||||
// Update the name and id to n+1
|
||||
const name = input.attr("name");
|
||||
const id = input.attr("id");
|
||||
|
||||
if (name) {
|
||||
const match = name.match(/(\d+)/); // Find the index in the name
|
||||
if (match) {
|
||||
const index = parseInt(match[1], 10) + 1;
|
||||
input.attr("name", name.replace(/\d+/, index));
|
||||
}
|
||||
}
|
||||
|
||||
if (id) {
|
||||
const match = id.match(/(\d+)/); // Find the index in the id
|
||||
if (match) {
|
||||
const index = parseInt(match[1], 10) + 1;
|
||||
input.attr("id", id.replace(/\d+/, index));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Append the new row to the table
|
||||
parentDiv.find("tbody").append(newRow);
|
||||
}
|
||||
|
||||
html.find('#add-category, #add-tag').click((evt)=>{
|
||||
evt.preventDefault()
|
||||
addRow($(evt.currentTarget));
|
||||
})
|
||||
html.find('#reset-category, #reset-tag').click((evt)=>{
|
||||
evt.preventDefault()
|
||||
let data
|
||||
let item_id
|
||||
if (evt.currentTarget.id == "reset-category"){
|
||||
item_id = "category"
|
||||
data = game.settings.settings.get(`${ID}.categories`).default
|
||||
} else if (evt.currentTarget.id == "reset-tag") {
|
||||
item_id = "tag"
|
||||
data = game.settings.settings.get(`${ID}.tags`).default
|
||||
}
|
||||
const tbody = $(evt.currentTarget).closest('div:has(table)').find("tbody")
|
||||
tbody.empty();
|
||||
for (let [idx, {id, label}] of data.entries()){
|
||||
const newRow = $(`<tr></tr>`)
|
||||
newRow.append(`<td><input type="text" name="${item_id}-id-${idx}" value="${id}"></input></td>`)
|
||||
newRow.append(`<td><input type="text" name="${item_id}-label-${idx}" value="${label}"></input></td>`)
|
||||
newRow.append(`<td><button id="delete-row-${idx}" class="delete-row"><i class="delete-row fa-solid fa-trash-can"></i></button></td>`)
|
||||
tbody.append(newRow)
|
||||
}
|
||||
})
|
||||
html.find('.delete-row').click((evt)=>{
|
||||
evt.preventDefault();
|
||||
const button = $(evt.currentTarget)
|
||||
button.closest('tr').remove()
|
||||
})
|
||||
}
|
||||
|
||||
async _updateObject(event, formData) {
|
||||
// Save updates when the form is submitted
|
||||
|
||||
const categories = [];
|
||||
const tags = [];
|
||||
|
||||
// Dynamically group rows for categories and tags
|
||||
for (const [key, value] of Object.entries(formData)) {
|
||||
// Match category rows
|
||||
const categoryMatch = key.match(/^category-(id|label)-(\d+)$/);
|
||||
if (categoryMatch) {
|
||||
const [_, field, index] = categoryMatch; // Extract field (id/label) and index
|
||||
const i = parseInt(index);
|
||||
|
||||
// Ensure the index exists in the categories array
|
||||
if (!categories[i]) categories[i] = { id: "", label: "" };
|
||||
categories[i][field] = value;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Match tag rows
|
||||
const tagMatch = key.match(/^tag-(id|label)-(\d+)$/);
|
||||
if (tagMatch) {
|
||||
const [_, field, index] = tagMatch; // Extract field (id/label) and index
|
||||
const i = parseInt(index);
|
||||
|
||||
// Ensure the index exists in the tags array
|
||||
if (!tags[i]) tags[i] = { id: "", label: "" };
|
||||
tags[i][field] = value;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
await game.settings.set(ID, "tags", tags);
|
||||
await game.settings.set(ID, "categories", categories);
|
||||
|
||||
ui.notifications.info("Settings updated!");
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
game
|
||||
|
||||
}
|
||||
44
src/templates/settings-tags-and-categories.hbs
Normal file
44
src/templates/settings-tags-and-categories.hbs
Normal file
@@ -0,0 +1,44 @@
|
||||
{{#*inline "table"}}
|
||||
<table>
|
||||
<thead>
|
||||
<tr><th colspan=3>{{collection_title}}</th></tr>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Label</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each collection}}
|
||||
<tr>
|
||||
<td><input type="text" name="{{../item_id}}-id-{{@index}}" value="{{id}}"></input></td>
|
||||
<td><input type="text" name="{{../item_id}}-label-{{@index}}" value="{{label}}"></input></td>
|
||||
<td><button id="delete-row-{{@index}}" class="delete-row"><i class="delete-row fa-solid fa-trash-can"></i></button></td>
|
||||
</tr>
|
||||
{{else}}
|
||||
<tr>
|
||||
<td><input type="text" name="{{../item_id}}-id-0" value="" placeholder="id"></input></td>
|
||||
<td><input type="text" name="{{../item_id}}-label-0" value="" placeholder="label"></input></td>
|
||||
<td><button id="delete-row-0" class="delete-row"><i class="delete-row fa-solid fa-trash-can"></i></button></td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="dialog-buttons">
|
||||
<button id="add-{{item_id}}" class="dialog-button"><i class="fa-solid fa-plus"></i>Add {{item_title}}</button>
|
||||
<button id="reset-{{item_id}}" class="dialog-button"><i class="fa-solid fa-arrow-rotate-left"></i>Reset {{collection_ttitle}}</button>
|
||||
</div>
|
||||
{{/inline}}
|
||||
<div class="{{moduleId}}">
|
||||
<form id="form-categories-and-tags">
|
||||
<div>
|
||||
{{> table collection_title="Categories" item_title="Category" collection=categories item_id="category"}}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{{> table collection_title="Tags" item_title="Tag" collection=tags item_id="tag"}}
|
||||
</div>
|
||||
<hr>
|
||||
<button id="save" class="dialog-button"><i class="fa-solid fa-check"></i> Save</button>
|
||||
</form>
|
||||
</div>
|
||||
Reference in New Issue
Block a user