forked from cory/tildefriends
An experiment: Always show some stats as little sparklines at the top of the screen.
git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4268 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
parent
7b91a2ec37
commit
9ef3a3aca0
117
core/client.js
117
core/client.js
@ -1,7 +1,6 @@
|
|||||||
import {LitElement, html, css} from '/static/lit/lit-all.min.js';
|
import {LitElement, html, css, svg} from '/static/lit/lit-all.min.js';
|
||||||
|
|
||||||
let gSocket;
|
let gSocket;
|
||||||
let gPermissions;
|
|
||||||
|
|
||||||
let gCurrentFile;
|
let gCurrentFile;
|
||||||
let gFiles = {};
|
let gFiles = {};
|
||||||
@ -52,6 +51,7 @@ class TfNavigationElement extends LitElement {
|
|||||||
permissions: {type: Object},
|
permissions: {type: Object},
|
||||||
show_permissions: {type: Boolean},
|
show_permissions: {type: Boolean},
|
||||||
status: {type: Object},
|
status: {type: Object},
|
||||||
|
spark_lines: {type: Object},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,6 +60,7 @@ class TfNavigationElement extends LitElement {
|
|||||||
this.permissions = {};
|
this.permissions = {};
|
||||||
this.show_permissions = false;
|
this.show_permissions = false;
|
||||||
this.status = {};
|
this.status = {};
|
||||||
|
this.spark_lines = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle_edit(event) {
|
toggle_edit(event) {
|
||||||
@ -75,6 +76,21 @@ class TfNavigationElement extends LitElement {
|
|||||||
send({action: "resetPermission", permission: key});
|
send({action: "resetPermission", permission: key});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get_spark_line(key, options) {
|
||||||
|
if (!this.spark_lines[key]) {
|
||||||
|
let spark_line = document.createElement('tf-sparkline');
|
||||||
|
spark_line.title = key;
|
||||||
|
if (options) {
|
||||||
|
if (options.max) {
|
||||||
|
spark_line.max = options.max;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.spark_lines[key] = spark_line;
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
return this.spark_lines[key];
|
||||||
|
}
|
||||||
|
|
||||||
render_login() {
|
render_login() {
|
||||||
if (this?.credentials?.session?.name) {
|
if (this?.credentials?.session?.name) {
|
||||||
return html`<a href="/login/logout?return=${url() + hash()}">logout ${this.credentials.session.name}</a>`;
|
return html`<a href="/login/logout?return=${url() + hash()}">logout ${this.credentials.session.name}</a>`;
|
||||||
@ -106,22 +122,21 @@ class TfNavigationElement extends LitElement {
|
|||||||
let self = this;
|
let self = this;
|
||||||
return html`
|
return html`
|
||||||
<style>
|
<style>
|
||||||
* {
|
|
||||||
height: auto;
|
|
||||||
margin: 4px;
|
|
||||||
}
|
|
||||||
${k_global_style}
|
${k_global_style}
|
||||||
</style>
|
</style>
|
||||||
<span>😎</span>
|
<div style="margin: 4px">
|
||||||
<a accesskey="h" data-tip="Open home app." href="/" style="color: #fff">Tilde Friends</a>
|
<span>😎</span>
|
||||||
<a accesskey="a" data-tip="Open apps list." href="/~core/apps/">apps</a>
|
<a accesskey="h" data-tip="Open home app." href="/" style="color: #fff">Tilde Friends</a>
|
||||||
<a accesskey="e" data-tip="Toggle the app editor." href="#" @click=${this.toggle_edit}>edit</a>
|
<a accesskey="a" data-tip="Open apps list." href="/~core/apps/">apps</a>
|
||||||
<a accesskey="p" data-tip="View and change permissions." href="#" @click=${() => self.show_permissions = !self.show_permissions}>🎛️</a>
|
<a accesskey="e" data-tip="Toggle the app editor." href="#" @click=${this.toggle_edit}>edit</a>
|
||||||
<span style="display: inline-block; vertical-align: top; white-space: pre; color: ${this.status.color ?? kErrorColor}">${this.status.message}</span>
|
<a accesskey="p" data-tip="View and change permissions." href="#" @click=${() => self.show_permissions = !self.show_permissions}>🎛️</a>
|
||||||
<span id="requests"></span>
|
<span style="display: inline-block; vertical-align: top; white-space: pre; color: ${this.status.color ?? kErrorColor}">${this.status.message}</span>
|
||||||
${this.render_permissions()}
|
<span id="requests"></span>
|
||||||
<span id="permissions"></span>
|
${this.render_permissions()}
|
||||||
<span style="float: right">${this.render_login()}</span>
|
<span>${Object.values(this.spark_lines)}</span>
|
||||||
|
<span id="permissions"></span>
|
||||||
|
<span style="float: right">${this.render_login()}</span>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,6 +208,65 @@ class TfFilesElement extends LitElement {
|
|||||||
}
|
}
|
||||||
customElements.define('tf-files', TfFilesElement);
|
customElements.define('tf-files', TfFilesElement);
|
||||||
|
|
||||||
|
class TfSparkLineElement extends LitElement {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
lines: {type: Array},
|
||||||
|
min: {type: Number},
|
||||||
|
max: {type: Number},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.min = 0;
|
||||||
|
this.max = 1.0;
|
||||||
|
this.lines = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
append(key, value) {
|
||||||
|
let line = null;
|
||||||
|
for (let it of this.lines) {
|
||||||
|
if (it.name == key) {
|
||||||
|
line = it;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!line) {
|
||||||
|
const k_colors = ['#0f0', '#88f', '#ff0', '#f0f', '#0ff', '#f00', '#888'];
|
||||||
|
line = {
|
||||||
|
name: key,
|
||||||
|
style: k_colors[this.lines.length % k_colors.length],
|
||||||
|
values: [],
|
||||||
|
};
|
||||||
|
this.lines.push(line);
|
||||||
|
}
|
||||||
|
line.values.push(value);
|
||||||
|
if (line.values.length > 100) {
|
||||||
|
line.values.shift();
|
||||||
|
}
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
render_line(line) {
|
||||||
|
if (line?.values?.length >= 2) {
|
||||||
|
let points = [].concat(...line.values.map((x, i) => [i * 100 / (line.values.length - 1), 10 - 10 * (x - this.min) / (this.max - this.min)]));
|
||||||
|
return svg`
|
||||||
|
<polyline points=${points.join(' ')} stroke=${line.style} fill="none"/>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<svg style="width: 10em; height: 1em; vertical-align: bottom; margin: 0; padding: 0" viewPort="0 0 100 10" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
${this.lines.map(x => this.render_line(x))}
|
||||||
|
</svg>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('tf-sparkline', TfSparkLineElement);
|
||||||
|
|
||||||
window.addEventListener("keydown", function(event) {
|
window.addEventListener("keydown", function(event) {
|
||||||
if (event.keyCode == 83 && (event.altKey || event.ctrlKey)) {
|
if (event.keyCode == 83 && (event.altKey || event.ctrlKey)) {
|
||||||
if (editing()) {
|
if (editing()) {
|
||||||
@ -306,13 +380,11 @@ function trace() {
|
|||||||
function stats() {
|
function stats() {
|
||||||
window.localStorage.setItem('stats', '1');
|
window.localStorage.setItem('stats', '1');
|
||||||
document.getElementById("statsPane").style.display = 'flex';
|
document.getElementById("statsPane").style.display = 'flex';
|
||||||
send({action: 'enableStats', enabled: true});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function closeStats() {
|
function closeStats() {
|
||||||
window.localStorage.setItem('stats', '0');
|
window.localStorage.setItem('stats', '0');
|
||||||
document.getElementById("statsPane").style.display = 'none';
|
document.getElementById("statsPane").style.display = 'none';
|
||||||
send({action: 'enableStats', enabled: false});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggleStats() {
|
function toggleStats() {
|
||||||
@ -648,10 +720,7 @@ function _receive_websocket_message(message) {
|
|||||||
if (window.location.hash) {
|
if (window.location.hash) {
|
||||||
send({event: "hashChange", hash: window.location.hash});
|
send({event: "hashChange", hash: window.location.hash});
|
||||||
}
|
}
|
||||||
if (window.localStorage.getItem('stats') == '1') {
|
send({action: 'enableStats', enabled: true});
|
||||||
/* Stats were opened before we connected. */
|
|
||||||
send({action: 'enableStats', enabled: true});
|
|
||||||
}
|
|
||||||
} else if (message && message.action == "ping") {
|
} else if (message && message.action == "ping") {
|
||||||
send({action: "pong"});
|
send({action: "pong"});
|
||||||
} else if (message && message.action == "stats") {
|
} else if (message && message.action == "stats") {
|
||||||
@ -733,6 +802,10 @@ function _receive_websocket_message(message) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
timeseries.append(now, message.stats[key]);
|
timeseries.append(now, message.stats[key]);
|
||||||
|
|
||||||
|
if (graph_key == 'cpu' || graph_key == 'rpc' || graph_key == 'stored') {
|
||||||
|
document.getElementsByTagName('tf-navigation')[0].get_spark_line(graph_key, { max: 100 }).append(key, message.stats[key]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (message &&
|
} else if (message &&
|
||||||
message.message === 'tfrpc' &&
|
message.message === 'tfrpc' &&
|
||||||
|
Loading…
Reference in New Issue
Block a user