mirror of
https://github.com/invoke-ai/InvokeAI
synced 2024-08-30 20:32:17 +00:00
feat(ui): fix a few things that didn't unsubscribe correctly, add helper to manage subscriptions
This commit is contained in:
parent
b9746a6c2c
commit
14f249a2f0
@ -254,12 +254,6 @@ export class CanvasManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
syncStageScale() {
|
|
||||||
for (const layer of this.layers.values()) {
|
|
||||||
layer.syncStageScale();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
arrangeEntities() {
|
arrangeEntities() {
|
||||||
const { getLayersState, getControlAdaptersState, getRegionsState } = this.stateApi;
|
const { getLayersState, getControlAdaptersState, getRegionsState } = this.stateApi;
|
||||||
const layers = getLayersState().entities;
|
const layers = getLayersState().entities;
|
||||||
@ -462,7 +456,7 @@ export class CanvasManager {
|
|||||||
this.log.debug('Initializing renderer');
|
this.log.debug('Initializing renderer');
|
||||||
this.stage.container(this.container);
|
this.stage.container(this.container);
|
||||||
|
|
||||||
const cleanupListeners = setStageEventHandlers(this);
|
const unsubscribeListeners = setStageEventHandlers(this);
|
||||||
|
|
||||||
// We can use a resize observer to ensure the stage always fits the container. We also need to re-render the bg and
|
// We can use a resize observer to ensure the stage always fits the container. We also need to re-render the bg and
|
||||||
// document bounds overlay when the stage is resized.
|
// document bounds overlay when the stage is resized.
|
||||||
@ -473,19 +467,23 @@ export class CanvasManager {
|
|||||||
const unsubscribeRenderer = this._store.subscribe(this.render);
|
const unsubscribeRenderer = this._store.subscribe(this.render);
|
||||||
|
|
||||||
// When we this flag, we need to render the staging area
|
// When we this flag, we need to render the staging area
|
||||||
$shouldShowStagedImage.subscribe(async (shouldShowStagedImage, prevShouldShowStagedImage) => {
|
const unsubscribeShouldShowStagedImage = $shouldShowStagedImage.subscribe(
|
||||||
if (shouldShowStagedImage !== prevShouldShowStagedImage) {
|
async (shouldShowStagedImage, prevShouldShowStagedImage) => {
|
||||||
this.log.debug('Rendering staging area');
|
if (shouldShowStagedImage !== prevShouldShowStagedImage) {
|
||||||
await this.preview.stagingArea.render();
|
this.log.debug('Rendering staging area');
|
||||||
|
await this.preview.stagingArea.render();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
|
||||||
$lastProgressEvent.subscribe(async (lastProgressEvent, prevLastProgressEvent) => {
|
const unsubscribeLastProgressEvent = $lastProgressEvent.subscribe(
|
||||||
if (lastProgressEvent !== prevLastProgressEvent) {
|
async (lastProgressEvent, prevLastProgressEvent) => {
|
||||||
this.log.debug('Rendering progress image');
|
if (lastProgressEvent !== prevLastProgressEvent) {
|
||||||
await this.preview.progressPreview.render(lastProgressEvent);
|
this.log.debug('Rendering progress image');
|
||||||
|
await this.preview.progressPreview.render(lastProgressEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
);
|
||||||
|
|
||||||
this.log.debug('First render of konva stage');
|
this.log.debug('First render of konva stage');
|
||||||
this.preview.tool.render();
|
this.preview.tool.render();
|
||||||
@ -494,8 +492,9 @@ export class CanvasManager {
|
|||||||
return () => {
|
return () => {
|
||||||
this.log.debug('Cleaning up konva renderer');
|
this.log.debug('Cleaning up konva renderer');
|
||||||
unsubscribeRenderer();
|
unsubscribeRenderer();
|
||||||
cleanupListeners();
|
unsubscribeListeners();
|
||||||
$shouldShowStagedImage.off();
|
unsubscribeShouldShowStagedImage();
|
||||||
|
unsubscribeLastProgressEvent();
|
||||||
resizeObserver.disconnect();
|
resizeObserver.disconnect();
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -2,6 +2,7 @@ import { $alt, $ctrl, $meta, $shift } from '@invoke-ai/ui-library';
|
|||||||
import type { Store } from '@reduxjs/toolkit';
|
import type { Store } from '@reduxjs/toolkit';
|
||||||
import { logger } from 'app/logging/logger';
|
import { logger } from 'app/logging/logger';
|
||||||
import type { RootState } from 'app/store/store';
|
import type { RootState } from 'app/store/store';
|
||||||
|
import { buildSubscribe } from 'features/controlLayers/konva/util';
|
||||||
import {
|
import {
|
||||||
$isDrawing,
|
$isDrawing,
|
||||||
$isMouseDown,
|
$isMouseDown,
|
||||||
@ -293,11 +294,11 @@ export class CanvasStateApi {
|
|||||||
onMetaChanged = $meta.subscribe;
|
onMetaChanged = $meta.subscribe;
|
||||||
|
|
||||||
getShiftKey = $shift.get;
|
getShiftKey = $shift.get;
|
||||||
onShiftChanged = $shift.subscribe;
|
onShiftChanged = buildSubscribe($shift.subscribe, 'onShiftChanged');
|
||||||
|
|
||||||
getShouldShowStagedImage = $shouldShowStagedImage.get;
|
getShouldShowStagedImage = $shouldShowStagedImage.get;
|
||||||
onGetShouldShowStagedImageChanged = $shouldShowStagedImage.subscribe;
|
onGetShouldShowStagedImageChanged = $shouldShowStagedImage.subscribe;
|
||||||
|
|
||||||
setStageAttrs = $stageAttrs.set;
|
setStageAttrs = $stageAttrs.set;
|
||||||
onStageAttrsChanged = $stageAttrs.subscribe;
|
onStageAttrsChanged = buildSubscribe($stageAttrs.subscribe, 'onStageAttrsChanged');
|
||||||
}
|
}
|
||||||
|
@ -494,7 +494,6 @@ export const setStageEventHandlers = (manager: CanvasManager): (() => void) => {
|
|||||||
scale: newScale,
|
scale: newScale,
|
||||||
});
|
});
|
||||||
manager.background.render();
|
manager.background.render();
|
||||||
manager.syncStageScale();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
manager.preview.tool.render();
|
manager.preview.tool.render();
|
||||||
|
@ -7,6 +7,7 @@ import Konva from 'konva';
|
|||||||
import type { KonvaEventObject } from 'konva/lib/Node';
|
import type { KonvaEventObject } from 'konva/lib/Node';
|
||||||
import type { Vector2d } from 'konva/lib/types';
|
import type { Vector2d } from 'konva/lib/types';
|
||||||
import { customAlphabet } from 'nanoid';
|
import { customAlphabet } from 'nanoid';
|
||||||
|
import type { WritableAtom } from 'nanostores';
|
||||||
import type { ImageDTO } from 'services/api/types';
|
import type { ImageDTO } from 'services/api/types';
|
||||||
import { assert } from 'tsafe';
|
import { assert } from 'tsafe';
|
||||||
|
|
||||||
@ -591,3 +592,23 @@ export function getObjectId(type: RenderableObject['type'], isBuffer?: boolean):
|
|||||||
return getPrefixedId(type);
|
return getPrefixedId(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type Subscription = {
|
||||||
|
name: string;
|
||||||
|
unsubscribe: () => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds a subscribe function for a nanostores atom.
|
||||||
|
* @param subscribe The subscribe function of the atom
|
||||||
|
* @param name The name of the atom
|
||||||
|
* @returns A subscribe function that returns an object with the name and unsubscribe function
|
||||||
|
*/
|
||||||
|
export const buildSubscribe = <T>(subscribe: WritableAtom<T>['subscribe'], name: string) => {
|
||||||
|
return (cb: Parameters<WritableAtom<T>['subscribe']>[0]): Subscription => {
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
unsubscribe: subscribe(cb),
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user