Added settings UI for template creation trans skip
Some checks failed
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled

This commit is contained in:
SwingTheVine 2026-03-05 23:03:25 -05:00
parent 077131d07b
commit faeb67717f
13 changed files with 113 additions and 39 deletions

View file

@ -390,9 +390,14 @@ input[type=file] {
}
/* src/WindowSettings.css */
#bm-window-settings div:has(> .bm-highlight-preset-container) {
width: fit-content;
justify-content: flex-start;
}
#bm-window-settings .bm-highlight-preset-container {
display: flex;
flex-direction: column;
width: 13%;
}
#bm-window-settings .bm-highlight-preset-container span {
width: fit-content;
@ -408,8 +413,8 @@ input[type=file] {
stroke: #333;
stroke-width: 0.02px;
width: 100%;
min-width: 1ch;
max-width: 10ch;
min-width: 1.5ch;
max-width: 14.5ch;
}
#bm-window-settings .bm-highlight-preset-container button:hover svg,
#bm-window-settings .bm-highlight-preset-container button:focus svg {
@ -420,7 +425,7 @@ input[type=file] {
grid-template-columns: 1fr 1fr 1fr;
width: 25%;
min-width: 3ch;
max-width: 30ch;
max-width: 15ch;
}
#bm-window-settings .bm-highlight-grid > button {
width: 100%;

View file

@ -2,7 +2,7 @@
// @name Blue Marble
// @name:en Blue Marble
// @namespace https://github.com/SwingTheVine/
// @version 0.91.67
// @version 0.91.74
// @description A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features.
// @description:en A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features.
// @author SwingTheVine
@ -713,8 +713,15 @@
addCheckbox(additionalProperties = {}, callback = () => {
}) {
const properties = { "type": "checkbox" };
const label = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "label", { "textContent": additionalProperties["textContent"] ?? "" });
delete additionalProperties["textContent"];
const labelContent = {};
if (!!additionalProperties["textContent"]) {
labelContent["textContent"] = additionalProperties["textContent"];
delete additionalProperties["textContent"];
} else if (!!additionalProperties["innerHTML"]) {
labelContent["innerHTML"] = additionalProperties["innerHTML"];
delete additionalProperties["textContent"];
}
const label = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "label", labelContent);
const checkbox = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "input", properties, additionalProperties);
label.insertBefore(checkbox, label.firstChild);
this.buildElement();
@ -1577,6 +1584,7 @@
};
}).buildElement().buildElement().buildElement().addDiv({ "class": "bm-window-content" }).addDiv({ "class": "bm-container bm-center-vertically" }).addHeader(1, { "textContent": "Settings" }).buildElement().buildElement().addHr().buildElement().addP({ "textContent": "Settings take 5 seconds to save." }).buildElement().addDiv({ "class": "bm-container bm-scrollable" }, (instance, div) => {
this.buildHighlight();
this.buildTemplate();
}).buildElement().buildElement().buildElement().buildOverlay(this.windowParent);
this.handleDrag(`#${this.windowID}.bm-window`, `#${this.windowID} .bm-dragbar`);
}
@ -1587,10 +1595,18 @@
buildHighlight() {
__privateMethod(this, _WindowSettings_instances, errorOverrideFailure_fn).call(this, "Pixel Highlight");
}
/** Builds the template section of the window.
* This should be overriden by {@link SettingsManager}
* @since 0.91.68
*/
buildTemplate() {
__privateMethod(this, _WindowSettings_instances, errorOverrideFailure_fn).call(this, "Template");
}
};
_WindowSettings_instances = new WeakSet();
/** Displays an error when a settings category fails to load.
* @param {string} name - The name of the category
* @since 0.91.11
*/
errorOverrideFailure_fn = function(name2) {
this.window = this.addDiv({ "class": "bm-container" }).addHeader(2, { "textContent": name2 }).buildElement().addHr().buildElement().addP({ "innerHTML": `An error occured loading the ${name2} category. <code>SettingsManager</code> failed to override the ${name2} function inside <code>WindowSettings</code>.` }).buildElement().buildElement();
@ -1657,7 +1673,7 @@
this.window = this.addDiv({ "class": "bm-container" }).addHeader(2, { "textContent": "Pixel Highlight" }).buildElement().addHr().buildElement().addDiv({ "class": "bm-container", "style": "margin-left: 1.5ch;" }).addCheckbox({ "textContent": "Highlight transparent pixels" }, (instance, label, checkbox) => {
checkbox.checked = !this.userSettings?.flags?.includes("hl-noTrans");
checkbox.onchange = (event) => this.toggleFlag("hl-noTrans", !event.target.checked);
}).buildElement().addP({ "id": "bm-highlight-preset-label", "textContent": "Choose a preset:", "style": "font-weight: 700;" }).buildElement().addDiv({ "class": "bm-flex-center", "style": "width: 50%;", "role": "group", "aria-labelledby": "bm-highlight-preset-label" }).addDiv({ "class": "bm-highlight-preset-container" }).addSpan({ "textContent": "None" }).buildElement().addButton({ "innerHTML": highlightPresetOff, "aria-label": 'Preset "None"' }, (instance, button) => {
}).buildElement().addP({ "id": "bm-highlight-preset-label", "textContent": "Choose a preset:", "style": "font-weight: 700;" }).buildElement().addDiv({ "class": "bm-flex-center", "role": "group", "aria-labelledby": "bm-highlight-preset-label" }).addDiv({ "class": "bm-highlight-preset-container" }).addSpan({ "textContent": "None" }).buildElement().addButton({ "innerHTML": highlightPresetOff, "aria-label": 'Preset "None"' }, (instance, button) => {
button.onclick = () => __privateMethod(this, _SettingsManager_instances, updateHighlightToPreset_fn).call(this, "None");
}).buildElement().buildElement().addDiv({ "class": "bm-highlight-preset-container" }).addSpan({ "textContent": "Cross" }).buildElement().addButton({ "innerHTML": highlightPresetCross, "aria-label": 'Preset "Cross Shape"' }, (instance, button) => {
button.onclick = () => __privateMethod(this, _SettingsManager_instances, updateHighlightToPreset_fn).call(this, "Cross");
@ -1685,6 +1701,19 @@
}
this.window = this.buildElement().buildElement().buildElement();
}
/** Build the "template" category of settings window
* @since 0.91.68
* @see WindowSettings#buildTemplate
*/
buildTemplate() {
this.window = this.addDiv({ "class": "bm-container" }).addHeader(2, { "textContent": "Pixel Highlight" }).buildElement().addHr().buildElement().addDiv({ "class": "bm-container", "style": "margin-left: 1.5ch;" }).addCheckbox({ "textContent": "Template creation should skip transparent tiles" }, (instance, label, checkbox) => {
checkbox.checked = !this.userSettings?.flags?.includes("hl-noSkip");
checkbox.onchange = (event) => this.toggleFlag("hl-noSkip", !event.target.checked);
}).buildElement().addCheckbox({ "innerHTML": "Experimental: Template creation should <em>aggressively</em> skip transparent tiles" }, (instance, label, checkbox) => {
checkbox.checked = this.userSettings?.flags?.includes("hl-agSkip");
checkbox.onchange = (event) => this.toggleFlag("hl-agSkip", event.target.checked);
}).buildElement().buildElement().buildElement();
}
};
_SettingsManager_instances = new WeakSet();
/** Updates the display of the highlight buttons in the settings window.
@ -1694,13 +1723,11 @@
* @since 0.91.46
*/
updateHighlightSettings_fn = function(button, coords2) {
console.log(coords2);
button.disabled = true;
const status = button.dataset["status"];
const userStorageOld = this.userSettings?.highlight ?? [[1, 0, 1], [2, 0, 0], [1, -1, 0], [1, 1, 0], [1, 0, -1]];
let userStorageChange = [2, 0, 0];
const userStorageNew = userStorageOld;
console.log(userStorageOld);
switch (status) {
// If the button was in the "Disabled" state
case "Disabled":
@ -1721,9 +1748,7 @@
userStorageChange = [0, ...coords2];
break;
}
console.log(userStorageChange);
const indexOfChange = userStorageOld.findIndex(([, x, y]) => x == userStorageChange[1] && y == userStorageChange[2]);
console.log(indexOfChange);
if (userStorageChange[0] != 0) {
if (indexOfChange != -1) {
userStorageNew[indexOfChange] = userStorageChange;
@ -1733,7 +1758,6 @@
} else if (indexOfChange != -1) {
userStorageNew.splice(indexOfChange, 1);
}
console.log(userStorageNew);
this.userSettings["highlight"] = userStorageNew;
button.disabled = false;
};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -51,7 +51,7 @@
<a href="https://discord.gg/tpeBPy46hf" target="_blank" rel="noopener noreferrer"><img alt="Contact Me" src="https://img.shields.io/badge/Contact_Me-gray?style=flat&logo=Discord&logoColor=white&logoSize=auto&labelColor=cornflowerblue"></a>
<a href="https://bluemarble.lol/" target="_blank" rel="noopener noreferrer"><img alt="Blue Marble Website" src="https://img.shields.io/badge/Blue_Marble_Website-crqch-blue?style=flat&logo=globe&logoColor=white"></a>
<a href="" target="_blank" rel="noopener noreferrer"><img alt="WakaTime" src="https://img.shields.io/badge/Coding_Time-212hrs_17mins-blue?style=flat&logo=wakatime&logoColor=black&logoSize=auto&labelColor=white"></a>
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-1182-black?style=flat"></a>
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-1189-black?style=flat"></a>
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Lines of Code" src="https://img.shields.io/badge/Lines_Of_Code-6620-blue?style=flat"></a>
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Comments" src="https://img.shields.io/badge/Lines_Of_Comments-5414-blue?style=flat"></a>
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Compression" src="https://img.shields.io/badge/Compression-71.85%25-blue"></a>

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "wplace-bluemarble",
"version": "0.91.67",
"version": "0.91.74",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "wplace-bluemarble",
"version": "0.91.67",
"version": "0.91.74",
"devDependencies": {
"esbuild": "^0.25.0",
"jsdoc": "^4.0.5",

View file

@ -1,6 +1,6 @@
{
"name": "wplace-bluemarble",
"version": "0.91.67",
"version": "0.91.74",
"type": "module",
"homepage": "https://bluemarble.lol/",
"repository": {

View file

@ -2,7 +2,7 @@
// @name Blue Marble
// @name:en Blue Marble
// @namespace https://github.com/SwingTheVine/
// @version 0.91.67
// @version 0.91.74
// @description A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features.
// @description:en A userscript to enhance the user experience on Wplace.live. This includes, but is not limited to: uploading images to display locally on a canvas, adding a button to move the Wplace color palette menu, and other QoL features.
// @author SwingTheVine

View file

@ -517,8 +517,24 @@ export default class Overlay {
const properties = {'type': 'checkbox'}; // Shared checkbox DOM properties
const label = this.#createElement('label', {'textContent': additionalProperties['textContent'] ?? ''}); // Creates the label element
delete additionalProperties['textContent']; // Deletes 'textContent' DOM property before adding the properties to the checkbox
// Stores the label content from the additional property
const labelContent = {};
// If the label content was passed in as 'textContent'...
if (!!additionalProperties['textContent']) {
// Store the information, then delete it from additionalProperties
labelContent['textContent'] = additionalProperties['textContent'];
delete additionalProperties['textContent']; // Deletes 'textContent' DOM property before adding the properties to the checkbox
} else if (!!additionalProperties['innerHTML']) {
// Else if the label content was passed in as 'innerHTML'...
// Store the information, then delete it from additionalProperties
labelContent['innerHTML'] = additionalProperties['innerHTML'];
delete additionalProperties['textContent'];
}
const label = this.#createElement('label', labelContent); // Creates the label element
const checkbox = this.#createElement('input', properties, additionalProperties); // Creates the checkbox element
label.insertBefore(checkbox, label.firstChild); // Makes the checkbox the first child of the label (before the text content)
this.buildElement(); // Signifies that we are done adding children to the checkbox

View file

@ -1,9 +1,16 @@
/* @since 0.91.22 */
/* Highlight preset group container */
#bm-window-settings div:has(> .bm-highlight-preset-container) {
width: fit-content;
justify-content: flex-start;
}
/* Highlight preset container */
#bm-window-settings .bm-highlight-preset-container {
display: flex;
flex-direction: column;
width: 13%;
}
/* Highlight preset title */
@ -25,8 +32,8 @@
stroke: #333;
stroke-width: 0.02px;
width: 100%;
min-width: 1ch;
max-width: 10ch;
min-width: 1.5ch;
max-width: 14.5ch;
}
/* Highlight preset SVG on hover/focus */
@ -41,7 +48,7 @@
grid-template-columns: 1fr 1fr 1fr;
width: 25%;
min-width: 3ch;
max-width: 30ch;
max-width: 15ch;
}
/* Highlight pattern button */

View file

@ -58,6 +58,7 @@ export default class WindowSettings extends Overlay {
.addDiv({'class': 'bm-container bm-scrollable'}, (instance, div) => {
// Each category in the settings window
this.buildHighlight();
this.buildTemplate();
}).buildElement()
.buildElement()
.buildElement().buildOverlay(this.windowParent);
@ -68,6 +69,7 @@ export default class WindowSettings extends Overlay {
/** Displays an error when a settings category fails to load.
* @param {string} name - The name of the category
* @since 0.91.11
*/
#errorOverrideFailure(name) {
this.window = this.addDiv({'class': 'bm-container'})
@ -84,4 +86,12 @@ export default class WindowSettings extends Overlay {
buildHighlight() {
this.#errorOverrideFailure('Pixel Highlight');
}
/** Builds the template section of the window.
* This should be overriden by {@link SettingsManager}
* @since 0.91.68
*/
buildTemplate() {
this.#errorOverrideFailure('Template');
}
}

View file

@ -14,7 +14,7 @@ import WindowSettings from "./WindowSettings";
* {
* "uuid": "497dcba3-ecbf-4587-a2dd-5eb0665e6880",
* "telemetry": 1,
* "flags": ["hl-noTrans", "ftr-oWin"],
* "flags": ["hl-noTrans", "ftr-oWin", "te-noSkip"],
* "highlight": [[1,0,-1],[1,-1,0],[2,1,0],[1,0,1]],
* "filter": [-2,0,4,5,6,29,63]
* }
@ -104,7 +104,7 @@ export default class SettingsManager extends WindowSettings {
checkbox.onchange = (event) => this.toggleFlag('hl-noTrans', !event.target.checked); // Forces the flag to be the opposite state as the checkbox. E.g. "Checked" means 'hl-noTrans' is false (does not exist).
}).buildElement()
.addP({'id': 'bm-highlight-preset-label', 'textContent': 'Choose a preset:', 'style': 'font-weight: 700;'}).buildElement()
.addDiv({'class': 'bm-flex-center', 'style': 'width: 50%;', 'role': 'group', 'aria-labelledby': 'bm-highlight-preset-label'})
.addDiv({'class': 'bm-flex-center', 'role': 'group', 'aria-labelledby': 'bm-highlight-preset-label'})
.addDiv({'class': 'bm-highlight-preset-container'})
.addSpan({'textContent': 'None'}).buildElement()
.addButton({'innerHTML': highlightPresetOff, 'aria-label': 'Preset "None"'}, (instance, button) => {button.onclick = () => this.#updateHighlightToPreset('None')}).buildElement()
@ -159,8 +159,6 @@ export default class SettingsManager extends WindowSettings {
*/
#updateHighlightSettings(button, coords) {
console.log(coords);
button.disabled = true; // Disabled the button until we are done
const status = button.dataset['status']; // Obtains the current status of the button
@ -172,8 +170,6 @@ export default class SettingsManager extends WindowSettings {
const userStorageNew = userStorageOld; // The old storage with the new change
console.log(userStorageOld);
// For each different type of status...
switch (status) {
@ -205,13 +201,9 @@ export default class SettingsManager extends WindowSettings {
break;
}
console.log(userStorageChange);
// Finds the index of the pixel to change
const indexOfChange = userStorageOld.findIndex(([, x, y]) => ((x == userStorageChange[1]) && (y == userStorageChange[2])));
console.log(indexOfChange);
// If the new sub-pixel state is NOT disabled
if (userStorageChange[0] != 0) {
@ -226,8 +218,6 @@ export default class SettingsManager extends WindowSettings {
userStorageNew.splice(indexOfChange, 1); // Removes 1 index from the array at the index of the pixel change
}
console.log(userStorageNew);
this.userSettings['highlight'] = userStorageNew;
// TODO: Add timer update here
@ -316,4 +306,26 @@ export default class SettingsManager extends WindowSettings {
button.disabled = false; // Re-enables the button
}
}
/** Build the "template" category of settings window
* @since 0.91.68
* @see WindowSettings#buildTemplate
*/
buildTemplate() {
this.window = this.addDiv({'class': 'bm-container'})
.addHeader(2, {'textContent': 'Pixel Highlight'}).buildElement()
.addHr().buildElement()
.addDiv({'class': 'bm-container', 'style': 'margin-left: 1.5ch;'})
.addCheckbox({'textContent': 'Template creation should skip transparent tiles'}, (instance, label, checkbox) => {
checkbox.checked = !this.userSettings?.flags?.includes('hl-noSkip'); // Makes the checkbox match the last stored user setting
checkbox.onchange = (event) => this.toggleFlag('hl-noSkip', !event.target.checked); // If the user wants to skip, then the checkbox is NOT checked
}).buildElement()
.addCheckbox({'innerHTML': 'Experimental: Template creation should <em>aggressively</em> skip transparent tiles'}, (instance, label, checkbox) => {
checkbox.checked = this.userSettings?.flags?.includes('hl-agSkip'); // Makes the checkbox match the last stored user setting
checkbox.onchange = (event) => this.toggleFlag('hl-agSkip', event.target.checked); // If the user wants to aggressively skip, then the checkbox is checked
}).buildElement()
.buildElement()
.buildElement()
}
}