journal-to-canvas-slideshow/scripts/classes/JTCSSettingsApplication.js

322 lines
12 KiB
JavaScript
Raw Permalink Normal View History

2024-01-28 15:59:53 -06:00
import { log, MODULE_ID } from "../debug-mode.js";
import { artGalleryDefaultSettings, colorThemes } from "../settings.js";
import { universalInterfaceActions as UIA } from "../data/Universal-Actions.js";
import { HelperFunctions, HelperFunctions as HF } from "./HelperFunctions.js";
import { ArtTileManager } from "./ArtTileManager.js";
const settingsActions = {
global: {
resetColors: {
onClick: () => {},
},
},
item: {},
};
/**
* Form app to handle JTCS settings
*/
export class JTCSSettingsApplication extends FormApplication {
constructor(data = {}) {
super();
// this.data = data;
this.data = game.JTCS.utils.getSettingValue("artGallerySettings");
}
static get defaultOptions() {
return mergeObject(super.defaultOptions, {
classes: ["form"],
width: 600,
popOut: true,
resizable: true,
minimizable: true,
submitOnClose: false,
closeOnSubmit: true,
submitOnChange: false,
template: `modules/${MODULE_ID}/templates/JTCS-settings-app.hbs`,
id: "JTCSSettingsApplication",
title: " JTCSSettings Application",
scrollY: [".form-content"],
onsubmit: (event) => {},
});
}
async addArtSceneAndJournalData(dedicatedDisplayData) {
const { journal, scene } = dedicatedDisplayData;
function mapNameAndId(contents) {
const newData = {};
contents.forEach((c) => {
newData[c.id] = c.name;
});
return newData;
}
const allJournals = mapNameAndId(game.journal.contents);
const artJournalID = journal.value;
const artJournalData = {
options: allJournals,
value: artJournalID,
};
const allScenes = mapNameAndId(
await ArtTileManager.getAllScenesWithSlideshowData()
);
const artSceneID = scene.value;
const artSceneData = {
options: allScenes,
value: artSceneID,
};
return {
...dedicatedDisplayData,
journal: {
...journal,
artJournalData,
},
scene: {
...scene,
artSceneData,
},
};
}
async getData() {
// Send data to the template
// let data = game.JTCS.utils.getSettingValue("artGallerySettings");
this.data = await game.JTCS.utils.getSettingValue("artGallerySettings");
let data = { ...this.data };
let newDisplayData = await this.addArtSceneAndJournalData(
data.dedicatedDisplayData
);
setProperty(data, "dedicatedDisplayData", newDisplayData);
return data;
}
activateListeners(html) {
super.activateListeners(html);
html.off("click").on(
"click",
"[data-action]",
this._handleButtonClick.bind(this)
);
this._handleChange();
}
async handleAction(event, actionType) {}
async _handleChange() {
$(`select, input[type='checkbox'], input[type='radio'], input[type='text']`).on(
"change",
async function (event) {
let { value, name, checked, type } = event.currentTarget;
let propertyString = "";
switch (type) {
case "select":
case "radio":
//the radio or select data is nested in a parent object that holds both its choices and the chosen value
//so we will want to get that parent object instead of the object itself
propertyString = name.split(".").splice(0, 2).join(".");
break;
case "checkbox":
value = checked; //if its a checkbox, set its value to whether or not it is checked
break;
case "text":
propertyString = name.split(".").splice(0, 1).join(".");
break;
default:
propertyString = name;
break;
}
let settingsObject = getProperty(
artGalleryDefaultSettings,
propertyString
);
if (settingsObject && settingsObject.hasOwnProperty("onChange")) {
let ourApp = game.JTCSSettingsApp;
settingsObject.onChange(event, {
value: value,
app: ourApp,
html: ourApp.element,
});
}
}
);
}
async _handleButtonClick(event) {
let clickedElement = $(event.currentTarget);
let action = clickedElement.data().action;
let type = clickedElement[0].type;
if (type === "submit") {
this.element.find("form").on("submit", (e) => {
if (action === "closeOnSubmit") {
this.close();
}
});
return;
}
event.stopPropagation();
event.preventDefault();
let backgroundColor = this.element.find("#backgroundColor").val();
let outerWrapper = clickedElement.closest(".outer-wrapper");
const accentElement = outerWrapper.find("[data-responsive-color]");
let accentColor = accentElement.val();
let contrastNotification = outerWrapper.find(".inline-notification");
if (action === "checkContrast") {
let hasEnoughContrast = HF.checkIfColorsContrastEnough(
backgroundColor,
accentColor
);
if (!hasEnoughContrast && contrastNotification.length === 0) {
await UIA.renderInlineNotification(event, "outer-wrapper", {
message:
"This color does not have enough contrast with the background color you've chosen. Text and buttons might be unreadable.",
notificationType: "warning",
});
} else if (hasEnoughContrast && contrastNotification.length > 0) {
contrastNotification.remove();
}
} else if (action === "toggleAutoContrastOff") {
const templatePath = game.JTCS.templates["delete-confirmation-prompt"];
const buttons = {
cancel: {
label: "Cancel",
icon: "<i class='fas fa-undo'></i>",
},
delete: {
label: "Turn Off Auto-Contrast",
icon: "<i class='fas fa-power-off'></i>",
callback: async () => {
await HF.setSettingValue(
"artGallerySettings",
false,
"colorSchemeData.autoContrast"
);
this.render(true);
},
},
};
const data = {
icon: "fas fa-exclamation",
heading: "Turn off Auto-Contrast?",
destructiveActionText: `Turn off auto contrast`,
explanation: `This will make it so your chosen colors aren't automatically adjusted to contrast with your background color;
<br/> However you risk choosing colors that make text illegible`,
buttons,
};
await HF.createDialog("Turn Off Auto Contrast", templatePath, data);
} else if (action === "toggleAutoContrastOn") {
await HF.setSettingValue(
"artGallerySettings",
true,
"colorSchemeData.autoContrast"
);
this.render(true);
} else if (action === "resetColor") {
let key = accentElement.attr("name");
let theme = await HF.getSettingValue(
"artGallerySettings",
"colorSchemeData.theme"
);
// const newScheme = mergeObject(currentSettings, colorThemes[theme]);
const defaultValue = getProperty(colorThemes[theme], key);
await HF.setSettingValue("artGallerySettings", defaultValue, key);
this.render(true);
// accentElement.val(defaultValue);
} else if (action === "scrollTo") {
const parentItem = clickedElement.closest("form");
UIA.scrollOtherElementIntoView(event, { parentItem });
} else if (action === "applyChanges") {
const form = event.currentTarget.closest("form");
const formData = {};
Array.from(form.querySelectorAll("input, select")).forEach((input) => {
let value = input.value;
if (input.type === "checkbox") {
value = input.checked;
}
formData[input.name] = value;
});
await HF.setSettingValue("artGallerySettings", formData, "", true);
this.render(true);
} else if (action === "setDarkTheme" || action === "setLightTheme") {
const theme = action === "setDarkTheme" ? "dark" : "light";
const templatePath = game.JTCS.templates["delete-confirmation-prompt"];
const buttons = {
cancel: {
label: "Cancel",
icon: "<i class='fas fa-undo'></i>",
},
reset: {
label: `Apply Default ${HF.capitalizeEachWord(theme)} Theme`,
icon: "<i class='fas fa-power-off'></i>",
callback: async () => {
//store the chosen theme as a setting
await HF.setSettingValue(
"artGallerySettings",
theme,
"colorSchemeData.theme"
);
const currentSettings = await HF.getSettingValue(
"artGallerySettings"
);
const newScheme = mergeObject(
currentSettings,
colorThemes[theme]
);
await HF.setSettingValue("artGallerySettings", newScheme);
this.render(true);
},
},
};
const data = {
icon: "fas fa-exclamation",
heading: `Apply Default ${HF.capitalizeEachWord(theme)} Theme?`,
destructiveActionText: `Apply Default ${HF.capitalizeEachWord(
theme
)} Theme`,
explanation: `This will overwrite any custom colors you've picked out`,
buttons,
};
await HF.createDialog("Apply Default Theme", templatePath, data);
}
}
async _updateObject(event, formData) {
const autoContrast = await HF.getSettingValue(
"artGallerySettings",
"colorSchemeData.autoContrast"
);
if (autoContrast) {
//if auto-contrast is turned on
const bgColorKey = "colorSchemeData.colors.backgroundColor";
for (const key in formData) {
if (key.includes(".colors.") && !key.includes(bgColorKey)) {
//for all the colors, convert the colors
const bgColor = formData[bgColorKey];
const fgColor = formData[key];
const hasEnoughContrast = HF.checkIfColorsContrastEnough(
bgColor,
fgColor
);
//only alter the contrast if there isn't enough already
if (!hasEnoughContrast) {
formData[key] = HF.getColorWithContrast(bgColor, fgColor);
}
}
}
}
await game.JTCS.utils.setSettingValue("artGallerySettings", formData, "", true);
await game.JTCSSettingsApp.render(true);
}
}
window.JTCSSettingsApplication = JTCSSettingsApplication;