@aurigma/design-atoms
Version:
Design Atoms is a part of Customer's Canvas SDK which allows for manipulating individual design elements through your code.
141 lines • 6.41 kB
JavaScript
import { Collection, debounce, EventObject, Item } from "@aurigma/design-atoms-model";
export class AutoPreviewContainersSource {
constructor(sourceSurface, itemsComparer) {
this._blockUpdate = false;
this._onContainerItemAdded = (data) => {
this._debounceUpdateContainers();
this._subscribeToItemChanged(data.item);
};
this._onContainerItemRemoved = (data) => {
this._debounceUpdateContainers();
this._unsubscribeFromItemChanged(data.item);
};
this._onContainerItemMoved = (data) => {
this._debounceUpdateContainers();
};
this._onItemChanged = () => {
this._debounceUpdateContainers();
};
this._sourceSurface = sourceSurface;
this._itemsComparer = itemsComparer;
this._previewContainers = new Collection();
this._previewContainersChanged = new EventObject();
this._debounceUpdateContainers = debounce(() => {
if (!this._blockUpdate) {
this._updateContainers();
}
}, 100);
this._subscribeToContainersChanged();
this._subscribeToItemCollectionsChanged();
this._updateContainers();
}
get _sourceContainers() {
return [
...this._sourceSurface.mockup.underContainers,
...this._sourceSurface.containers,
...this._sourceSurface.mockup.overContainers
];
}
getPreviewContainers() {
return this._previewContainers.toArray();
}
addPreviewContainersChanged(listener) {
this._previewContainersChanged.add(listener);
}
removePreviewContainersChanged(listener) {
this._previewContainersChanged.remove(listener);
}
async ensureUpdatedAndExecuteAsync(asyncCallback) {
this._debounceUpdateContainers.cancel();
this._blockUpdate = true;
this._updateContainers();
await asyncCallback();
this._blockUpdate = false;
}
_subscribeToContainersChanged() {
this._sourceSurface.containers.add_itemAdded(data => {
this._subscribeToContainerItemCollectionChanged(data.item);
this._debounceUpdateContainers();
this._previewContainersChanged.notify();
});
this._sourceSurface.containers.add_itemRemoved(data => {
this._unsubscribeFromContainerItemCollectionChanged(data.item);
this._debounceUpdateContainers();
this._previewContainersChanged.notify();
});
}
_subscribeToItemCollectionsChanged() {
this._sourceContainers.forEach(container => this._subscribeToContainerItemCollectionChanged(container));
}
_subscribeToContainerItemCollectionChanged(container) {
this._subscribeToItemsChanged(container);
container.items.add_itemAdded(this._onContainerItemAdded);
container.items.add_itemRemoved(this._onContainerItemRemoved);
container.items.add_itemMoved(this._onContainerItemMoved);
}
_unsubscribeFromContainerItemCollectionChanged(container) {
this._unsubscribeFromItemsChanged(container);
container.items.remove_itemAdded(this._onContainerItemAdded);
container.items.remove_itemRemoved(this._onContainerItemRemoved);
container.items.remove_itemMoved(this._onContainerItemMoved);
}
_subscribeToItemsChanged(container) {
container.items.forEach(item => this._subscribeToItemChanged(item));
}
_unsubscribeFromItemsChanged(container) {
container.items.forEach(item => this._unsubscribeFromItemChanged(item));
}
_subscribeToItemChanged(item) {
item.addPropertyChanged(this._onItemChanged);
if (item instanceof Item) {
item.getItemChangedEvent().add(this._onItemChanged);
}
}
_unsubscribeFromItemChanged(item) {
item.removePropertyChanged(this._onItemChanged);
if (item instanceof Item) {
item.getItemChangedEvent().remove(this._onItemChanged);
}
}
_updateContainers() {
this._patchCollection(this._sourceContainers, this._previewContainers);
this._previewContainers.forEach(container => container.parentComponent = { printAreas: this._sourceSurface.printAreas });
for (const sourceContainer of this._sourceContainers) {
this._updateContainer(sourceContainer, this._previewContainers.first(container => container.id === sourceContainer.id));
}
}
_updateContainer(source, destination) {
this._patchCollection(source.items, destination.items);
for (let i = 0; i < source.items.length; i++) {
const sourceItem = source.items.get(i);
const destinationItemIndex = destination.items.toArray().findIndex(item => item.id === sourceItem.id);
const destinationItem = destination.items.get(destinationItemIndex);
if (!this._itemsComparer.itemsEqual(sourceItem, destinationItem)) {
destination.items.replaceAt(sourceItem.clone(), destinationItemIndex);
}
}
}
_patchCollection(source, destination) {
const sourceArray = source instanceof Collection ? source.toArray() : source;
const resultArray = destination.toArray();
const sourceIds = sourceArray.map(item => item.id);
const destinationIds = resultArray.map(item => item.id);
const idsToAdd = sourceIds.filter((id) => !destinationIds.includes(id));
const toRemove = destinationIds.filter(id => !sourceIds.includes(id));
const toAdd = idsToAdd.map(id => {
return {
id: id,
index: sourceArray.findIndex(item => item.id === id)
};
});
toAdd.forEach(item => destination.insertAt(item.index, sourceArray.find(i => i.id === item.id).clone()));
toRemove.forEach(id => destination.removeAt(destination.indexOf(i => i.id === id)));
sourceIds.forEach((id, index) => {
const indexOld = destination.indexOf(item => item.id === id);
if (indexOld !== index) {
destination.move(indexOld, index);
}
});
}
}
//# sourceMappingURL=AutoPreviewContainersSource.js.map