- Add notification state management with badge counts in useAgentManager - Render exclamation badge on agent sprites (separate from status icons) - Add CEO desk document icon with click-to-open activity panel - Create DocumentPanel with unified activity feed + per-agent detail tabs - Add telegram test button to stock agent ChatPanel - Remove TaskHistory + bottom toolbar (replaced by DocumentPanel) - Add getActivityFeed API helper Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
90 lines
2.4 KiB
JavaScript
90 lines
2.4 KiB
JavaScript
import { drawAgent, getAnimSpeed } from './SpriteSheet';
|
|
|
|
export class AgentSprite {
|
|
constructor(agentId, waypoints) {
|
|
this.agentId = agentId;
|
|
this.waypoints = waypoints;
|
|
this.state = 'idle';
|
|
this.detail = '';
|
|
this.notificationCount = 0;
|
|
|
|
const deskKey = `${agentId}_desk`;
|
|
const desk = waypoints[deskKey] || { x: 5, y: 3 };
|
|
this.x = desk.x;
|
|
this.y = desk.y;
|
|
this.targetX = desk.x;
|
|
this.targetY = desk.y;
|
|
this.deskPos = { x: desk.x, y: desk.y };
|
|
|
|
this.frameIndex = 0;
|
|
this._lastFrameTime = 0;
|
|
this._moveSpeed = 0.05;
|
|
}
|
|
|
|
setNotification(count) {
|
|
this.notificationCount = count;
|
|
}
|
|
|
|
setState(newState, detail = '') {
|
|
this.state = newState;
|
|
this.detail = detail;
|
|
this.frameIndex = 0;
|
|
}
|
|
|
|
moveTo(target) {
|
|
const wp = this.waypoints[target];
|
|
if (wp) {
|
|
this.targetX = wp.x;
|
|
this.targetY = wp.y;
|
|
}
|
|
}
|
|
|
|
moveToDesk() {
|
|
this.targetX = this.deskPos.x;
|
|
this.targetY = this.deskPos.y;
|
|
}
|
|
|
|
update(now) {
|
|
const speed = getAnimSpeed(this.state);
|
|
if (now - this._lastFrameTime > speed) {
|
|
this.frameIndex++;
|
|
this._lastFrameTime = now;
|
|
}
|
|
|
|
const dx = this.targetX - this.x;
|
|
const dy = this.targetY - this.y;
|
|
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
|
|
if (dist > 0.1) {
|
|
const step = Math.min(this._moveSpeed, dist);
|
|
this.x += (dx / dist) * step;
|
|
this.y += (dy / dist) * step;
|
|
} else {
|
|
this.x = this.targetX;
|
|
this.y = this.targetY;
|
|
}
|
|
}
|
|
|
|
draw(ctx, renderInfo) {
|
|
const { scale, offsetX, offsetY, tileSize } = renderInfo;
|
|
const canvasX = offsetX + this.x * tileSize * scale + (tileSize * scale) / 2;
|
|
const canvasY = offsetY + this.y * tileSize * scale + (tileSize * scale) / 2;
|
|
|
|
const isMoving = Math.abs(this.targetX - this.x) > 0.1 || Math.abs(this.targetY - this.y) > 0.1;
|
|
const drawState = isMoving ? 'walk' : this.state;
|
|
|
|
drawAgent(ctx, this.agentId, canvasX, canvasY, drawState, this.frameIndex, scale * 1.5);
|
|
}
|
|
|
|
hitTest(canvasX, canvasY, renderInfo) {
|
|
const { scale, offsetX, offsetY, tileSize } = renderInfo;
|
|
const cx = offsetX + this.x * tileSize * scale + (tileSize * scale) / 2;
|
|
const cy = offsetY + this.y * tileSize * scale + (tileSize * scale) / 2;
|
|
const hitW = 20 * scale;
|
|
const hitH = 30 * scale;
|
|
|
|
return canvasX >= cx - hitW && canvasX <= cx + hitW &&
|
|
canvasY >= cy - hitH && canvasY <= cy + hitH;
|
|
}
|
|
}
|