Files
Battle-for-Tismo/client/js/feed.js
T

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();
}
}