Skip to content

Commit

Permalink
Added bunch of tags, bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Haxxer committed Jul 23, 2024
1 parent 6b8e542 commit c6edad1
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 74 deletions.
13 changes: 12 additions & 1 deletion src/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ CONSTANTS.FLAG_KEYS = {
STATES: "states",
NUMBER_TYPE: "numberType",
FPS: "fps",
ASSET_TYPES: "asset_types",
TIME_PERIODS: "time_periods",
CATEGORIES: "categories",
TAGS: "tags",
DELEGATED_STATEFUL_VIDEOS: "delegatedStatefulVideos",
}

Expand All @@ -65,7 +69,10 @@ CONSTANTS.STATE_FLAGS = {
nextState: null,
randomState: null,
randomStart: null,
randomEnd: null
randomEnd: null,
asset_types: null,
time_periods: null,
categories: null,
}

CONSTANTS.FLAGS = `flags.${CONSTANTS.MODULE_NAME}`;
Expand All @@ -79,6 +86,10 @@ CONSTANTS.UPDATED_FLAG = `flags.${CONSTANTS.MODULE_NAME}.${CONSTANTS.FLAG_KEYS.U
CONSTANTS.STATES_FLAG = `flags.${CONSTANTS.MODULE_NAME}.${CONSTANTS.FLAG_KEYS.STATES}`;
CONSTANTS.NUMBER_TYPE_FLAG = `flags.${CONSTANTS.MODULE_NAME}.${CONSTANTS.FLAG_KEYS.NUMBER_TYPE}`;
CONSTANTS.FPS_FLAG = `flags.${CONSTANTS.MODULE_NAME}.${CONSTANTS.FLAG_KEYS.FPS}`;
CONSTANTS.ASSET_TYPES_FLAG = `flags.${CONSTANTS.MODULE_NAME}.${CONSTANTS.FLAG_KEYS.ASSET_TYPES}`;
CONSTANTS.TIME_PERIODS_FLAG = `flags.${CONSTANTS.MODULE_NAME}.${CONSTANTS.FLAG_KEYS.TIME_PERIODS}`;
CONSTANTS.CATEGORIES_FLAG = `flags.${CONSTANTS.MODULE_NAME}.${CONSTANTS.FLAG_KEYS.CATEGORIES}`;
CONSTANTS.TAGS_FLAG = `flags.${CONSTANTS.MODULE_NAME}.${CONSTANTS.FLAG_KEYS.TAGS}`;
CONSTANTS.DELEGATED_STATEFUL_VIDEOS_FLAG = `flags.${CONSTANTS.MODULE_NAME}.${CONSTANTS.FLAG_KEYS.DELEGATED_STATEFUL_VIDEOS}`;

CONSTANTS.TRANSLATED_BEHAVIORS = {
Expand Down
131 changes: 75 additions & 56 deletions src/filepicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,22 @@ class KinemancerFilePicker extends FilePicker {

filesWithColorVariants = {};
filesWithWebmThumbnails = {};
tags = {};
deepSearch = "";
filtersActive = false;
tags = {};
filters = {};

dirMatchesFilter(dir) {
return Object.entries(this.filters).every(([settingsKey, filters]) => {
const setting = game.settings.get(CONSTANTS.MODULE_NAME, settingsKey);
return setting[dir] && Object.entries(filters).every(([tag, value]) => {
const found = setting[dir].includes(tag);
return found === value;
});
})
}

async searchDir(dir, data, validPacks) {
async searchDir(dir, data) {

const results = await FilePicker.browse("data", `${dir}/*`, { wildcard: true });

Expand All @@ -36,7 +48,9 @@ class KinemancerFilePicker extends FilePicker {
dir.pop();
dir = dir.join("/")

if (validPacks && !validPacks.has(dir)) continue;
if (this.filtersActive) {
if (!this.dirMatchesFilter(dir)) continue;
}

// Find the color variants
const colorVariants = results.files.filter(variantFile => {
Expand All @@ -48,12 +62,19 @@ class KinemancerFilePicker extends FilePicker {
if (this.deepSearch) {
const parts = file.split("/");
const fileName = parts.pop().split(".")[0].toLowerCase();
const basePath = parts.join("/")

const searchParts = this.deepSearch.split(" ").map(str => str.toLowerCase());
const additionalValidSearchParts = this.filters[basePath]?.length
? this.filters[basePath].map(str => str.toLowerCase())
: [];

if (!searchParts.every(part => {
if (part.startsWith("color:")) {
return colorVariants.some(color => color.colorName.includes(part.split(":")[1]))
const colorToFind = part.split(":")[1];
return colorVariants.some(color => color.colorName.includes(colorToFind))
}
return fileName.includes(part)
return fileName.includes(part) || additionalValidSearchParts.includes(part)
})) continue;
}

Expand All @@ -77,9 +98,9 @@ class KinemancerFilePicker extends FilePicker {

}

if (this.deepSearch || validPacks) {
if (this.deepSearch || this.filtersActive) {
for (const subDir of results.dirs) {
await this.searchDir(subDir, data, validPacks);
await this.searchDir(subDir, data);
}
}

Expand All @@ -94,41 +115,29 @@ class KinemancerFilePicker extends FilePicker {

const data = await super.getData(options);

this.filtersActive = false;

if (!data.target.startsWith(CONSTANTS.MODULE_NAME)) return data;

const validPacks = foundry.utils.isEmpty(this.tags) ? false : new Set();
const blackListed = new Set();
if (validPacks) {
const packTags = Object.entries(GameSettings.PACK_TAGS.get());
Object.entries(this.tags).forEach(([tag, filter]) => {
for (const [dir, tags] of packTags) {
if (filter) {
const packHasTag = tags.some(packTag => packTag === tag);
if (!packHasTag) continue;
if (!blackListed.has(dir)) validPacks.add(dir);
} else {
blackListed.add(dir);
validPacks.delete(dir);
}
}
})
}
this.tags = GameSettings.TAGS.get();

this.filtersActive = !foundry.utils.isEmpty(this.filters);

if (this.deepSearch || validPacks) {
if (this.deepSearch || this.filtersActive) {
data.files = [];
}

for (const [index, dir] of foundry.utils.deepClone(data.dirs).entries()) {

const foundMatches = await this.searchDir(dir.path, data, validPacks);
const foundMatches = await this.searchDir(dir.path, data);

if (foundMatches) {
data.dirs.splice(index, 1);
}

}

if (this.deepSearch || validPacks) {
if (this.deepSearch || this.filtersActive) {
data.dirs = [];
}

Expand Down Expand Up @@ -160,52 +169,62 @@ class KinemancerFilePicker extends FilePicker {
searchElem.val(value);
}

const tags = GameSettings.getUniquePackTags();
this.addTagRegion("Asset Types", GameSettings.SETTINGS.ASSET_TYPES);
this.addTagRegion("Time Periods", GameSettings.SETTINGS.TIME_PERIODS);
this.addTagRegion("Categories", GameSettings.SETTINGS.CATEGORIES);

if (tags.length) {
this.position.height = null;
this.element.css({ height: "" });

const tagsParent = $(`<div class="form-group favorites"><label><span>Tags</span></label><div class="form-fields paths tags"></div></div>`);
}

tags.forEach(tag => {
return result;
}

const tagElem = $(`<span class="path tag"><a class="link">${tag}</a></span>`);
addTagRegion(title, setting_key) {

const fp = this;
const aElem = tagElem.find("a");
const tags = GameSettings.getUniqueTags(setting_key);

tagElem.attr("class", "path tag " + this.getTagClass(tag));
aElem.on("click", function () {
fp.toggleTag(tag);
fp.render(true);
})
tagsParent.find(".form-fields").append(tagElem);
});
if (!tags.length) return;

tagsParent.insertAfter(this.element.find("div.filter-dir"));
const tagsParent = $(`<div class="form-group favorites"><label><span>${title}</span></label><div class="form-fields paths tags"></div></div>`);

this.position.height = null;
this.element.css({ height: "" });
tags.forEach(tag => {

}
const tagElem = $(`<span class="path tag"><a class="link">${tag}</a></span>`);

}
const fp = this;
const aElem = tagElem.find("a");

tagElem.attr("class", "path tag " + this.getTagClass(setting_key, tag));
aElem.on("click", function () {
fp.toggleFilter(setting_key, tag);
fp.render(true);
})
tagsParent.find(".form-fields").append(tagElem);
});

tagsParent.insertBefore(this.element.find("div.form-fields.display-modes").parent());

return result;
}

toggleTag(tag) {
if (this.tags[tag] === undefined) {
this.tags[tag] = true;
} else if (this.tags[tag]) {
this.tags[tag] = false;
toggleFilter(filterKey, tag) {
if (this.filters[filterKey]?.[tag] === undefined) {
if (!this.filters[filterKey]) this.filters[filterKey] = {}
this.filters[filterKey][tag] = true;
} else if (this.filters[filterKey]?.[tag]) {
this.filters[filterKey][tag] = false;
} else {
delete this.tags[tag];
delete this.filters[filterKey][tag];
if (foundry.utils.isEmpty(this.filters[filterKey])) {
delete this.filters[filterKey];
}
}
}

getTagClass(tag) {
if (this.tags[tag] === undefined) return "";
if (this.tags[tag]) return "ats-tag-selected";
getTagClass(filterKey, tag) {
if (this.filters[filterKey]?.[tag] === undefined) return "";
if (this.filters[filterKey]?.[tag]) return "ats-tag-selected";
return "ats-tag-deselected";
}

Expand Down
35 changes: 25 additions & 10 deletions src/lib/downloader.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ProgressBar from "./ProgressBarStore.js";
import * as lib from "./lib.js";
import { writable } from "svelte/store";
import GameSettings from "../settings.js";
import CONSTANTS from "../constants.js";

class Downloader {

Expand Down Expand Up @@ -87,15 +88,31 @@ class Downloader {
const filesToCheck = Object.values(zip.files).filter(f => !f.dir && zip.file(f.name));

const filesToCreate = [];
let tags = {};
let tags = {
[GameSettings.SETTINGS.ASSET_TYPES]: {},
[GameSettings.SETTINGS.TIME_PERIODS]: {},
[GameSettings.SETTINGS.CATEGORIES]: {},
[GameSettings.SETTINGS.TAGS]: {}
};
for (const zipFile of filesToCheck) {
let path = zipFile.name.split("/")
const fileName = path.pop();
path = path.join("/")
if (zipFile.name.endsWith("tags.json")) {
const jsonData = await zip.file(zipFile.name).async("string");
tags[path] = JSON.parse(jsonData);
continue;
if (zipFile.name.endsWith(".json")) {
const jsonString = await zip.file(zipFile.name).async("string");
const jsonData = JSON.parse(jsonString);
if (foundry.utils.getProperty(jsonData, CONSTANTS.ASSET_TYPES_FLAG)?.length) {
tags[GameSettings.SETTINGS.ASSET_TYPES][path] = foundry.utils.getProperty(jsonData, CONSTANTS.ASSET_TYPES_FLAG);
}
if (foundry.utils.getProperty(jsonData, CONSTANTS.TIME_PERIODS_FLAG)?.length) {
tags[GameSettings.SETTINGS.TIME_PERIODS][path] = foundry.utils.getProperty(jsonData, CONSTANTS.TIME_PERIODS_FLAG);
}
if (foundry.utils.getProperty(jsonData, CONSTANTS.CATEGORIES_FLAG)?.length) {
tags[GameSettings.SETTINGS.CATEGORIES][path] = foundry.utils.getProperty(jsonData, CONSTANTS.CATEGORIES_FLAG);
}
if (foundry.utils.getProperty(jsonData, CONSTANTS.TAGS_FLAG)?.length) {
tags[GameSettings.SETTINGS.TAGS][path] = foundry.utils.getProperty(jsonData, CONSTANTS.TAGS_FLAG);
}
}
const fileData = zip.file(zipFile.name);
filesToCreate.push({ path, fileName, fileData, fullPath: zipFile.name });
Expand All @@ -117,13 +134,11 @@ class Downloader {
})
}

async createFiles({ dirsToCreate = [], filesToCreate = [], tags = [] } = {}) {
async createFiles({ dirsToCreate = [], filesToCreate = [], tags = {} } = {}) {

const newTags = GameSettings.PACK_TAGS.get();
for (const [path, name] of Object.entries(tags)) {
newTags[path] = name;
for (const [settingsKey, values] of Object.entries(tags)) {
await lib.updateFilters(settingsKey, values);
}
await GameSettings.PACK_TAGS.set(newTags);

if (dirsToCreate.length) {

Expand Down
21 changes: 18 additions & 3 deletions src/lib/lib.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,18 @@ export function getThumbnailVariations(url) {
return Object.keys(CONST.IMAGE_FILE_EXTENSIONS).map(ext => url.replace(".webm", "." + ext));
}

export function getVideoJsonPath(placeableDocument) {
return decodeURI(placeableDocument.texture.src).split(" ")[0]
export function getCleanWebmPath(placeableDocument) {
return decodeURI(placeableDocument.texture.src)
.split(" ")[0]
.split("_(")[0]
.split("__")[0]
+ ".json";
+ ".webm";
}

export function getVideoJsonPath(placeableDocument) {
return getCleanWebmPath(placeableDocument)
.replace(".webm", "")
+ ".json"
}

export function createJsonFile(placeableDocument, inData) {
Expand All @@ -210,6 +217,14 @@ export function createJsonFile(placeableDocument, inData) {
return FilePicker.upload("data", splitPath.join('/'), file, {}, { notify: false });
}

export function updateFilters(settingsKey, values) {
const newTags = game.settings.get(CONSTANTS.MODULE_NAME, settingsKey);
for (const [path, tags] of Object.entries(values)) {
newTags[path] = tags;
}
return game.settings.set(CONSTANTS.MODULE_NAME, settingsKey, newTags);
}


export function getFolder(path) {
const folderParts = path.split("/");
Expand Down
Loading

0 comments on commit c6edad1

Please sign in to comment.