60 lines
1.9 KiB
JavaScript
60 lines
1.9 KiB
JavaScript
// The game feed: a chat-like column of short-lived messages pinned to the
|
|
// lower-left corner of the map. Newest lines sit at the bottom and each line
|
|
// retires on its own, so the map is never permanently obstructed.
|
|
|
|
export const FEED_TTL_MS = 4500;
|
|
export const FEED_ALERT_TTL_MS = 8000;
|
|
const FEED_FADE_MS = 400;
|
|
|
|
export class GameFeed {
|
|
constructor($container, options = {}) {
|
|
this.$container = $container;
|
|
this.ttl = options.ttl !== undefined ? options.ttl : FEED_TTL_MS;
|
|
this.alertTtl = options.alertTtl !== undefined ? options.alertTtl : FEED_ALERT_TTL_MS;
|
|
this.fade = options.fade !== undefined ? options.fade : FEED_FADE_MS;
|
|
this._timers = new Set();
|
|
}
|
|
|
|
// Appends one line at the bottom of the feed. `alert` marks a message the
|
|
// player must not miss (being declared war on) and lets it linger longer.
|
|
// A negative `ttl` keeps the line until `clear` or a later retirement.
|
|
push(text, { alert = false, ttl } = {}) {
|
|
if (!this.$container || !this.$container.length) return null;
|
|
const life = ttl !== undefined ? ttl : alert ? this.alertTtl : this.ttl;
|
|
const $line = $("<div class='feed-line'></div>").text(text);
|
|
if (alert) $line.addClass("feed-alert");
|
|
this.$container.append($line);
|
|
if (life >= 0) {
|
|
const timer = setTimeout(() => {
|
|
this._timers.delete(timer);
|
|
this._retire($line);
|
|
}, life);
|
|
this._timers.add(timer);
|
|
}
|
|
return $line;
|
|
}
|
|
|
|
lineCount() {
|
|
return this.$container ? this.$container.children(".feed-line").length : 0;
|
|
}
|
|
|
|
_retire($line) {
|
|
$line.addClass("leaving");
|
|
if (this.fade <= 0) {
|
|
$line.remove();
|
|
return;
|
|
}
|
|
const timer = setTimeout(() => {
|
|
this._timers.delete(timer);
|
|
$line.remove();
|
|
}, this.fade);
|
|
this._timers.add(timer);
|
|
}
|
|
|
|
clear() {
|
|
for (const timer of this._timers) clearTimeout(timer);
|
|
this._timers.clear();
|
|
if (this.$container) this.$container.empty();
|
|
}
|
|
}
|