@infinite-canvas-tutorial/webcomponents
Version:
WebComponents UI implementation
152 lines • 5.84 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
import { css, html, LitElement } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { apiContext, appStateContext } from '../context';
import { consume } from '@lit/context';
import { Event } from '../event';
import { Cluster } from '../utils';
let Comments = class Comments extends LitElement {
constructor() {
super(...arguments);
this.clusters = [];
this.binded = false;
this.cluster = new Cluster({
maxZoom: 16,
});
this.handleCommentAdded = (e) => {
const { canvasX, canvasY } = e.detail;
const threadId = `${Date.now()}`;
const commentId = `${Date.now()}`;
this.api.setThreads([
...this.api.getThreads(),
{
type: 'thread',
id: threadId,
roomId: 'my-room-id',
createdAt: new Date(),
comments: [
{
type: 'comment',
threadId,
id: commentId,
roomId: 'my-room-id',
userId: 'alicia@example.com',
createdAt: new Date(),
editedAt: new Date(),
text: 'Hello, world!',
avatar: 'https://ui-avatars.com/api/?name=Alicia',
},
],
metadata: {
x: canvasX,
y: canvasY,
},
},
]);
this.cluster.load(this.api
.getThreads()
.map((_a) => {
var { metadata } = _a, rest = __rest(_a, ["metadata"]);
return (Object.assign({ x: metadata.x, y: metadata.y }, rest));
}));
this.updateClusters();
};
}
updateClusters() {
var _a;
if (((_a = this.cluster.points) === null || _a === void 0 ? void 0 : _a.length) > 0) {
const { cameraZoom } = this.api.getAppState();
const { minX, minY, maxX, maxY } = this.api.getViewportBounds();
// Convert [0, 4] to [0, 16]
this.clusters = this.cluster.getClusters([minX, minY, maxX, maxY], cameraZoom * 4);
}
}
shouldUpdate(changedProperties) {
// allow updates from internal state/properties
for (const prop of changedProperties.keys()) {
if (prop !== 'appState')
return true;
}
// context update: only allow if cameraZoom changed
const newZoom = this.appState.cameraZoom;
if (newZoom !== this.previousCameraZoom) {
this.previousCameraZoom = newZoom;
this.updateClusters();
return true;
}
const newX = this.appState.cameraX;
if (newX !== this.previousCameraX) {
this.previousCameraX = newX;
this.updateClusters();
return true;
}
const newY = this.appState.cameraY;
if (newY !== this.previousCameraY) {
this.previousCameraY = newY;
this.updateClusters();
return true;
}
return false;
}
render() {
if (!this.api) {
return;
}
if (this.api.element && !this.binded) {
this.api.element.addEventListener(Event.COMMENT_ADDED, this.handleCommentAdded);
this.binded = true;
this.cluster.load(this.api.getThreads().map((_a) => {
var { metadata } = _a, rest = __rest(_a, ["metadata"]);
return (Object.assign({ x: metadata.x, y: metadata.y }, rest));
}));
this.updateClusters();
}
const viewportPositions = this.clusters.map(({ x, y }) => {
return this.api.canvas2Viewport({ x, y });
});
return html `
${this.clusters.map((cluster, i) => html `
<ic-spectrum-thread
x=${viewportPositions[i].x}
y=${viewportPositions[i].y}
.cluster=${cluster}
></ic-spectrum-thread>
`)}
`;
}
};
Comments.styles = css `
:host {
position: absolute;
}
`;
__decorate([
consume({ context: appStateContext, subscribe: true })
], Comments.prototype, "appState", void 0);
__decorate([
consume({ context: apiContext, subscribe: true })
], Comments.prototype, "api", void 0);
__decorate([
state()
], Comments.prototype, "clusters", void 0);
Comments = __decorate([
customElement('ic-spectrum-comments')
], Comments);
export { Comments };
//# sourceMappingURL=comments.js.map