Skip to content

Commit

Permalink
Merge pull request projectstorm#32 from projectstorm/more_fixes_2
Browse files Browse the repository at this point in the history
fixed a lot of initial rendering buffer issues
  • Loading branch information
dylanvorster committed Jan 20, 2023
2 parents 3bda2d3 + 3945d18 commit 49a0dc7
Show file tree
Hide file tree
Showing 9 changed files with 105 additions and 39 deletions.
11 changes: 11 additions & 0 deletions .changeset/yellow-schools-fail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@projectstorm/react-workspaces-core': minor
'@projectstorm/react-workspaces-model-tray': minor
---

- new method to waiting for initial rendering of any model
- new parameter to immediately run DimensionContainer invalidation
- fixed bug with determining if something left aligned by now checking parent container
- useResizeObserver now invalidates its hooks based off the dimension container
- trays now use their children and how they render to determine initial expand width
- tray icons now set their positioning correctly on boot (immediately)
25 changes: 23 additions & 2 deletions packages/core/src/core-models/WorkspaceModel.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { WorkspaceEngineInterface } from '../core/WorkspaceEngineInterface';
import { WorkspaceCollectionInterface } from './WorkspaceCollectionInterface';
import { BaseListener, BaseObserver } from '../core/BaseObserver';
import { Alignment } from '../core/tools';
import { v4 } from 'uuid';
import { ISize, Size } from '../core/dimensions/Size';
import { DimensionContainer } from '../core/dimensions/DimensionContainer';
import { DimensionContainer, IDimension } from '../core/dimensions/DimensionContainer';
import { WorkspaceCollectionModel } from './WorkspaceCollectionModel';

export interface SerializedModel {
Expand Down Expand Up @@ -98,6 +97,28 @@ export class WorkspaceModel<
this._expandVertical = value;
}

async waitForInitialRenderedSize(): Promise<IDimension> {
return new Promise((resolve) => {
let l1, l2;
l1 = this.r_dimensions.registerListener({
updated: () => {
if (this.r_dimensions.size.width > 0) {
resolve(this.r_dimensions.dimensions);
l1?.();
l2?.();
}
}
});
l2 = this.registerListener({
visibilityChanged: () => {
if (this.r_visible) {
this.r_dimensions.invalidate(true);
}
}
} as Partial<L>);
});
}

private normalizeSize() {
if (this.size.width < this.minimumSize.width) {
this.size.width = this.minimumSize.width;
Expand Down
14 changes: 7 additions & 7 deletions packages/core/src/core/dimensions/DimensionContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Alignment, MousePosition } from '../tools';

export interface DimensionContainerListener extends BaseListener {
updated: () => any;
invalidate: () => any;
invalidate: (immediate?: boolean) => any;
}

export type IDimension = IPosition & ISize;
Expand Down Expand Up @@ -62,8 +62,8 @@ export class DimensionContainer extends BaseObserver<DimensionContainerListener>
return this.size.getVolume();
}

invalidate() {
this.iterateListeners((cb) => cb.invalidate?.());
invalidate(immediate?: boolean) {
this.iterateListeners((cb) => cb.invalidate?.(immediate));
}

update(dim: Partial<IDimension>) {
Expand All @@ -82,16 +82,16 @@ export class DimensionContainer extends BaseObserver<DimensionContainerListener>
isAligned(parent: DimensionContainer, alignment: Alignment) {
const rel = this.getRelativeToPosition(parent.position)[alignment];
if (alignment === Alignment.LEFT) {
return rel <= this.dimensions.width / 2;
return rel <= parent.dimensions.width / 2;
}
if (alignment === Alignment.RIGHT) {
return rel > this.dimensions.width / 2;
return rel > parent.dimensions.width / 2;
}
if (alignment === Alignment.TOP) {
return rel <= this.dimensions.height / 2;
return rel <= parent.dimensions.height / 2;
}
if (alignment === Alignment.BOTTOM) {
return rel > this.dimensions.height / 2;
return rel > parent.dimensions.height / 2;
}
}
}
20 changes: 12 additions & 8 deletions packages/core/src/widgets/hooks/useBaseResizeObserver.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ export const useBaseResizeObserver = (props: UseBaseBaseResizeObserverProps) =>
};

props.dimension.update(props.transformer?.(dimObject) || dimObject);
}, []);
}, [props.dimension]);

const updateDebounced = useCallback(
_.debounce(() => {
updateLogic();
}, 500),
[]
[props.dimension]
);

const update = useCallback(() => {
Expand All @@ -46,16 +46,20 @@ export const useBaseResizeObserver = (props: UseBaseBaseResizeObserverProps) =>
} else {
updateDebounced();
}
}, [props.ignoreDebounce]);
}, [props.dimension, props.ignoreDebounce]);

// listen to invalidate directives
useEffect(() => {
return props.dimension.registerListener({
invalidate: () => {
update();
invalidate: (immediate) => {
if (immediate) {
updateLogic();
} else {
update();
}
}
});
}, []);
}, [props.dimension]);

// window resized
useWindowResize({
Expand All @@ -81,7 +85,7 @@ export const useBaseResizeObserver = (props: UseBaseBaseResizeObserverProps) =>
}
intersectionObserver.disconnect();
};
}, []);
}, [props.dimension]);

// native resize
useEffect(() => {
Expand All @@ -96,5 +100,5 @@ export const useBaseResizeObserver = (props: UseBaseBaseResizeObserverProps) =>
}
resizeObserver.disconnect();
};
}, []);
}, [props.dimension]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ export const useDimensionLayoutInvalidator = (props: UseDimensionLayoutInvalidat
l1();
l2?.();
};
}, []);
}, [props.dimension]);
};
2 changes: 1 addition & 1 deletion packages/core/src/widgets/hooks/useModelElement.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ export const useModelElement = (props: UseModelElementProps) => {
return () => {
props.model.setVisible(false);
};
}, []);
}, [props.model]);
return ref;
};
1 change: 0 additions & 1 deletion packages/model-tray/src/WorkspaceTrayFactory.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export class WorkspaceTrayFactory<T extends WorkspaceTrayModel = WorkspaceTrayMo
generateModel(): T {
const model = new WorkspaceTrayModel({
iconWidth: 50,
expandedWidth: 200,
factory: this.options.windowFactory
}) as T;
if (this.options.installIconPositionListener) {
Expand Down
41 changes: 32 additions & 9 deletions packages/model-tray/src/WorkspaceTrayModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export enum TrayIconPosition {

export interface WorkspaceTrayModelOptions {
iconWidth: number;
expandedWidth: number;
factory: FloatingWindowFactory;
}

Expand All @@ -37,6 +36,7 @@ export interface SerializedWorkspaceTrayModel extends WorkspaceNodeModelSerializ
selected: string;
iconPosition: TrayIconPosition;
mode: WorkspaceTrayMode;
sizeExpanded: number;
}

export class WorkspaceTrayModel extends WorkspaceNodeModel<SerializedWorkspaceTrayModel, WorkspaceTrayModelListener> {
Expand All @@ -45,7 +45,7 @@ export class WorkspaceTrayModel extends WorkspaceNodeModel<SerializedWorkspaceTr
selectedModel: WorkspaceModel;
floatingWindow: FloatingWindowModel;

private normalSize: number;
private sizeExpanded: number;
private childListener: () => any;

static NAME = 'srw-tray';
Expand Down Expand Up @@ -80,15 +80,23 @@ export class WorkspaceTrayModel extends WorkspaceNodeModel<SerializedWorkspaceTr
});
}
});
this.normalSize = options.expandedWidth;
this.setMode(WorkspaceTrayMode.NORMAL);
this.size.registerListener({
updated: () => {
if (this.mode === WorkspaceTrayMode.NORMAL) {
this.normalSize = this.size.width;
if (this.mode === WorkspaceTrayMode.NORMAL && this.r_visible) {
this.setExpandedSize(this.size.width);
}
}
});
this.setMode(WorkspaceTrayMode.NORMAL);
}

setExpandedSize(size: number) {
if (size > this.options.iconWidth && size !== this.sizeExpanded) {
this.sizeExpanded = size;
this.size.update({
width: this.sizeExpanded
});
}
}

setIconPosition(position: TrayIconPosition) {
Expand Down Expand Up @@ -150,13 +158,15 @@ export class WorkspaceTrayModel extends WorkspaceNodeModel<SerializedWorkspaceTr
...super.toArray(),
mode: this.mode,
selected: this.selectedModel?.id,
iconPosition: this.iconBarPosition
iconPosition: this.iconBarPosition,
sizeExpanded: this.sizeExpanded
};
}

fromArray(payload: SerializedWorkspaceTrayModel, engine: WorkspaceEngine) {
super.fromArray(payload, engine);
this.setIconPosition(payload['iconPosition'] || TrayIconPosition.LEFT);
this.sizeExpanded = payload.sizeExpanded;
if (payload.selected) {
this.setSelectedModel(this.children.find((m) => m.id === payload.selected) || null);
}
Expand All @@ -179,8 +189,13 @@ export class WorkspaceTrayModel extends WorkspaceNodeModel<SerializedWorkspaceTr
}

normalizeSelectedModel() {
if (this.mode === WorkspaceTrayMode.NORMAL && this.selectedModel == null) {
if (this.mode === WorkspaceTrayMode.NORMAL && this.selectedModel == null && this.children[0]) {
this.setSelectedModel(this.children[0]);

// set the default expand size
if (!this.sizeExpanded) {
this.setExpandedSize(this.children[0].size.width || this.children[0].minimumSize.width);
}
}
}

Expand All @@ -203,14 +218,22 @@ export class WorkspaceTrayModel extends WorkspaceNodeModel<SerializedWorkspaceTr
// the order of these two calls are important
this.setFloatingModel(null);
this.normalizeSelectedModel();

// if we don't have an expanded size yet, lets wait for the model to render first (asyncronously)
if (!this.sizeExpanded && this.selectedModel) {
this.selectedModel.waitForInitialRenderedSize().then((dims) => {
this.setExpandedSize(dims.width + this.options.iconWidth);
});
}

this.maximumSize.update({
width: 0
});
this.minimumSize.update({
width: 0
});
this.size.update({
width: this.normalSize
width: this.sizeExpanded
});
}
this.invalidateLayout();
Expand Down
28 changes: 18 additions & 10 deletions packages/model-tray/src/iconPositionBehavior.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,25 @@ import { Alignment } from '@projectstorm/react-workspaces-core';
* @param model
*/
export const setupIconPositionBehavior = (model: WorkspaceTrayModel) => {
return model.r_dimensions.position.registerListener({
const setupPositioning = () => {
const parent = model.getRootModel();
if (parent.r_dimensions.size.width === 0) {
return;
}
if (model.r_dimensions.isAligned(parent.r_dimensions, Alignment.LEFT)) {
model.setIconPosition(TrayIconPosition.LEFT);
} else {
model.setIconPosition(TrayIconPosition.RIGHT);
}
};
model.waitForInitialRenderedSize().then((dims) => {
const parent = model.getRootModel();
parent.r_dimensions.invalidate(true);
setupPositioning();
});
model.r_dimensions.registerListener({
updated: () => {
const parent = model.getRootModel();
if (!parent) {
return;
}
if (model.r_dimensions.isAligned(parent.r_dimensions, Alignment.LEFT)) {
model.setIconPosition(TrayIconPosition.LEFT);
} else {
model.setIconPosition(TrayIconPosition.RIGHT);
}
setupPositioning();
}
});
};

0 comments on commit 49a0dc7

Please sign in to comment.