Compare commits

9 Commits

Author SHA1 Message Date
8fbbb4f788 Bump version to 0.2.1 and update download URL
Incremented the module version from 0.2.0 to 0.2.1 and updated the corresponding download URL to reflect the new release. This ensures proper version tracking and correct download linkage for the updated module.
2025-02-03 07:57:27 -06:00
e6e8ae4f3f Fix incorrect Handlebars context reference in input names
Updated the Handlebars template to correctly reference the parent context for `item_id` using `../item_id` instead of `item_id`. This ensures the input field names are properly constructed within nested loops, avoiding potential data binding issues.
2025-02-03 07:55:52 -06:00
fb9eeba103 Rename log and manifest files in asset manager macros
- Renamed `000028.log` to `000041.log`
- Renamed `MANIFEST-000027` to `MANIFEST-000039`
- Updated binary files `CURRENT`, `LOG`, and `LOG.old`
2025-01-31 09:57:34 -06:00
04aee6e44c Bump version to 0.2.0 and update download URL
- Updated the module version in `module.json` from `0.1.1` to `0.2.0`.
- Adjusted the `download` URL to point to the `0.2.0` release ZIP file.

This change reflects the addition of new features and improvements in the latest release.
2025-01-23 10:26:17 -06:00
3fdaadf7e0 Add customizable tags and categories with UI management
- Introduced settings for tags and categories in `settings.js`:
  - Added `tags` and `categories` settings with default values and support for customization.
  - Registered a new settings menu for managing tags and categories dynamically.
- Enhanced `main.js` to use the customizable tags and categories in templates.
  - Adjusted `AscAssetManager.TEMPLATES` to include a new `SETTINGS_TAGS_AND_CATEGORIES` template.
  - Updated the `renderUploadForm` hook to fetch tags and categories dynamically from settings.
- Added a new Handlebars template `settings-tags-and-categories.hbs`:
  - Provides a user interface for managing tags and categories.
  - Includes functionality to add, reset, and delete rows dynamically.

These updates allow users to define and manage tags and categories via the module's settings menu, improving flexibility and user experience.
2025-01-23 10:24:54 -06:00
4cd01570f7 Update and rename binary files in asset manager macros
- Renamed `000024.log` to `000028.log`.
- Renamed `MANIFEST-000023` to `MANIFEST-000027` with updated binary content.
- Updated binary content for `CURRENT`, `LOG`, and `LOG.old`.

These changes reorganize and modify the binary files in the `asc-asset-manager-macros` directory to reflect the latest updates.
2025-01-23 10:24:14 -06:00
a9ba4f27ff Refactor debug mode initialization and settings management
- Replaced the "enableFeature" setting with "enableDebugMode" for clarity.
  - Added a new `requiresReload` property for the debug mode setting.
  - Updated the default value to `false` and refined the hint text.
- Removed unused "theme" setting from `settings.js`.
- Enhanced the `init` hook in `main.js` to properly configure debug mode:
  - Logs a message when debug mode is enabled.
  - Sets `CONFIG.debug.hooks` conditionally based on the debug mode setting.
- Minor adjustments for consistency in code formatting and logging.

These changes improve the debugging experience and streamline module settings.

Update module title and bump version to 0.1.1

- Changed module title from "asc-asset-manager" to "Asset Manager" for a more user-friendly name.
- Updated the version in `module.json` from `0.1.0` to `0.1.1` to reflect the update.

Add download and manifest URLs and update compatibility version

- Added `download` and `manifest` URLs to `module.json`:
  - `download`: Points to the module's ZIP file for version `0.1.1`.
  - `manifest`: Points to the latest release manifest file.
- Updated the `verified` compatibility version from `12` to `12.331` to ensure compatibility with the latest framework version.

Fix download URL in module.json

Updated the `download` URL in `module.json` to correctly point to the `0.1.1` release ZIP file under the `/releases/download/0.1.1/` path.
2025-01-23 08:16:11 -06:00
1d698c0ef1 Update and reorganize binary files in asset manager macros
- Deleted `000005.ldb` and `MANIFEST-000010` binary files.
- Renamed:
  - `000008.ldb` to `000020.ldb`.
  - `000011.log` to `000024.log`.
- Updated binary content for `CURRENT`, `LOG`, and `LOG.old`.
- Added new binary file `MANIFEST-000023`.

These changes reflect a reorganization and update of the binary files within the `asc-asset-manager-macros` directory.
2025-01-23 07:49:31 -06:00
07db5da750 Add .gitattributes file to manage binary files
Introduced a new `.gitattributes` file to mark all files under `src/packs/` as binary. This ensures proper handling of binary files in the specified directory during Git operations.
2025-01-23 07:48:31 -06:00
13 changed files with 265 additions and 40 deletions

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
src/packs/** binary

View File

@@ -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({

View File

@@ -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": [
{

View File

@@ -1 +1 @@
MANIFEST-000010
MANIFEST-000039

View File

@@ -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)

View File

@@ -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.

View File

@@ -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
}

View 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>