First commit
This commit is contained in:
65
src/extension.ts
Normal file
65
src/extension.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { getVisitorCount } from './http';
|
||||
import { initStatusBar, refresh } from './statusBar';
|
||||
|
||||
const OPEN = 4;
|
||||
const CLOSE = 23;
|
||||
const INTERVAL_MS = 2 * 60 * 1000;
|
||||
|
||||
let timer: NodeJS.Timeout | undefined;
|
||||
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
const subscriptions = context.subscriptions;
|
||||
const commandId = 'vsc-adda.refresh';
|
||||
|
||||
const item = initStatusBar(getVisitorCount, commandId);
|
||||
subscriptions.push(item);
|
||||
|
||||
subscriptions.push(
|
||||
vscode.commands.registerCommand(commandId, async () => {
|
||||
await refresh();
|
||||
})
|
||||
);
|
||||
|
||||
await refresh();
|
||||
scheduleNext();
|
||||
|
||||
subscriptions.push({ dispose: () => timer && clearTimeout(timer) });
|
||||
}
|
||||
|
||||
export function deactivate() {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
|
||||
function isOpen(d: Date = new Date()): boolean {
|
||||
return d.getHours() >= OPEN && d.getHours() < CLOSE;
|
||||
}
|
||||
|
||||
function timeUntilOpenMs(from: Date = new Date()): number {
|
||||
const next = new Date(from);
|
||||
if (from.getHours() < OPEN) {
|
||||
next.setHours(OPEN, 0, 0, 0);
|
||||
} else {
|
||||
next.setDate(next.getDate() + 1);
|
||||
next.setHours(OPEN, 0, 0, 0);
|
||||
}
|
||||
return next.getTime() - from.getTime();
|
||||
}
|
||||
|
||||
function scheduleNext(): void {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
|
||||
if (isOpen()) {
|
||||
timer = setTimeout(() => {
|
||||
refresh().finally(scheduleNext);
|
||||
}, INTERVAL_MS);
|
||||
} else {
|
||||
timer = setTimeout(() => {
|
||||
refresh().finally(scheduleNext);
|
||||
}, timeUntilOpenMs());
|
||||
}
|
||||
}
|
||||
37
src/http.ts
Normal file
37
src/http.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import * as https from 'https';
|
||||
|
||||
export function getVisitorCount(): Promise<number> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = https.get('https://www.gymcontrol.se/global/checkedin/checkedin.php?uid=9094', (res) => {
|
||||
if (!res.statusCode || res.statusCode < 200 || res.statusCode >= 300) {
|
||||
res.resume();
|
||||
reject(new Error(`HTTP ${res.statusCode ?? '?'}`));
|
||||
return;
|
||||
}
|
||||
|
||||
res.setEncoding('utf8');
|
||||
|
||||
let raw = '';
|
||||
res.on('data', (chunk) => {
|
||||
raw += chunk;
|
||||
});
|
||||
|
||||
res.on('end', () => {
|
||||
const text = raw.trim();
|
||||
const n = Number.parseInt(text, 10);
|
||||
|
||||
if (Number.isFinite(n)) {
|
||||
resolve(n);
|
||||
} else {
|
||||
reject(new Error(`Invalid response: "${text}"`));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
req.on('error', reject);
|
||||
|
||||
req.setTimeout(5000, () => {
|
||||
req.destroy(new Error('Timeout after 5000 ms'));
|
||||
});
|
||||
});
|
||||
}
|
||||
42
src/statusBar.ts
Normal file
42
src/statusBar.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
const TOOLTIP_TEXT = 'Current Gym Visitors';
|
||||
|
||||
let item: vscode.StatusBarItem;
|
||||
let getCount: (() => Promise<number>) | undefined;
|
||||
|
||||
export function initStatusBar(getVisitorCount: () => Promise<number>, commandId: string): vscode.StatusBarItem {
|
||||
getCount = getVisitorCount;
|
||||
|
||||
item = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, 1000);
|
||||
item.command = commandId;
|
||||
item.text = '$(adda-fitness) 0';
|
||||
item.tooltip = TOOLTIP_TEXT;
|
||||
item.show();
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
export async function refresh(): Promise<void> {
|
||||
if (!item || !getCount) {
|
||||
return;
|
||||
}
|
||||
|
||||
item.text = '$(adda-fitness) $(sync~spin)';
|
||||
|
||||
try {
|
||||
const [count] = await Promise.all([getCount(), sleep(1500)]);
|
||||
|
||||
item.text = `$(adda-fitness) ${count}`;
|
||||
item.tooltip = TOOLTIP_TEXT;
|
||||
} catch (e: any) {
|
||||
item.text = '$(warning) Adda';
|
||||
item.tooltip = e?.message ?? 'Unknown error';
|
||||
} finally {
|
||||
item.show();
|
||||
}
|
||||
}
|
||||
|
||||
function sleep(ms: number): Promise<void> {
|
||||
return new Promise((resolve) => setTimeout(resolve, ms));
|
||||
}
|
||||
Reference in New Issue
Block a user