fix territory modal performance (#1600)

## Description:

The territory patterns modal was listening for keypresses, and would
regenerate all patterns on each render().

So do:
1. Cache territory patterns to prevent regeneration
2. disable handler on close

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I have read and accepted the CLA agreement (only required once).

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
This commit is contained in:
evanpelle
2025-07-28 13:08:07 -07:00
committed by GitHub
parent 1db9b93950
commit bf13c65657
+20 -8
View File
@@ -37,6 +37,8 @@ export class TerritoryPatternsModal extends LitElement {
private userSettings: UserSettings = new UserSettings();
private isActive = false;
constructor() {
super();
}
@@ -44,7 +46,6 @@ export class TerritoryPatternsModal extends LitElement {
connectedCallback() {
super.connectedCallback();
this.selectedPattern = this.userSettings.getSelectedPattern();
window.addEventListener("keydown", this.handleKeyDown);
this.updateComplete.then(() => {
const containers = this.renderRoot.querySelectorAll(".preview-container");
if (this.resizeObserver) {
@@ -54,12 +55,11 @@ export class TerritoryPatternsModal extends LitElement {
}
this.updatePreview();
});
this.open();
}
disconnectedCallback() {
super.disconnectedCallback();
window.removeEventListener("keydown", this.handleKeyDown);
this.resizeObserver.disconnect();
}
async onUserMe(userMeResponse: UserMeResponse | null) {
@@ -220,6 +220,7 @@ export class TerritoryPatternsModal extends LitElement {
}
render() {
if (!this.isActive) return html``;
return html`
${this.renderTooltip()}
<o-modal
@@ -233,10 +234,15 @@ export class TerritoryPatternsModal extends LitElement {
public open() {
this.modalEl?.open();
window.addEventListener("keydown", this.handleKeyDown);
this.isActive = true;
}
public close() {
this.modalEl?.close();
window.removeEventListener("keydown", this.handleKeyDown);
this.resizeObserver?.disconnect();
this.isActive = false;
}
private selectPattern(pattern: string | undefined) {
@@ -336,6 +342,7 @@ export class TerritoryPatternsModal extends LitElement {
}
}
const patternCache = new Map<string, string>();
const DEFAULT_PATTERN_B64 = "AAAAAA"; // Empty 2x2 pattern
const COLOR_SET = [0, 0, 0, 255]; // Black
const COLOR_UNSET = [255, 255, 255, 255]; // White
@@ -344,11 +351,14 @@ export function generatePreviewDataUrl(
width?: number,
height?: number,
): string {
pattern ??= DEFAULT_PATTERN_B64;
if (patternCache.has(pattern)) {
return patternCache.get(pattern)!;
}
// Calculate canvas size
const decoder = new PatternDecoder(
pattern ?? DEFAULT_PATTERN_B64,
base64url.decode,
);
const decoder = new PatternDecoder(pattern, base64url.decode);
const scaledWidth = decoder.scaledWidth();
const scaledHeight = decoder.scaledHeight();
@@ -384,5 +394,7 @@ export function generatePreviewDataUrl(
// Create a data URL
ctx.putImageData(imageData, 0, 0);
return canvas.toDataURL("image/png");
const dataUrl = canvas.toDataURL("image/png");
patternCache.set(pattern, dataUrl);
return dataUrl;
}