100 lines
2.7 KiB
TypeScript
100 lines
2.7 KiB
TypeScript
import { Plugin } from "obsidian";
|
|
|
|
export enum RecordingStatus {
|
|
Idle = "idle",
|
|
Recording = "recording",
|
|
Paused = "paused",
|
|
Processing = "processing",
|
|
}
|
|
|
|
export class StatusBar {
|
|
plugin: Plugin;
|
|
statusBarItem: HTMLElement | null = null;
|
|
status: RecordingStatus = RecordingStatus.Idle;
|
|
private listeners: Array<(status: RecordingStatus) => void> = [];
|
|
private meterBars: HTMLElement[] = [];
|
|
|
|
constructor(plugin: Plugin) {
|
|
this.plugin = plugin;
|
|
this.statusBarItem = this.plugin.addStatusBarItem();
|
|
this.updateStatusBarItem();
|
|
}
|
|
|
|
onChange(listener: (status: RecordingStatus) => void): void {
|
|
this.listeners.push(listener);
|
|
}
|
|
|
|
offChange(listener: (status: RecordingStatus) => void): void {
|
|
this.listeners = this.listeners.filter((fn) => fn !== listener);
|
|
}
|
|
|
|
updateStatus(status: RecordingStatus) {
|
|
this.status = status;
|
|
this.updateStatusBarItem();
|
|
this.listeners.forEach((fn) => fn(status));
|
|
}
|
|
|
|
updateInputLevel(level: number): void {
|
|
if (this.status !== RecordingStatus.Recording) return;
|
|
|
|
const clampedLevel = Math.max(0, Math.min(1, level));
|
|
const activeBars = Math.round(clampedLevel * this.meterBars.length);
|
|
|
|
this.meterBars.forEach((bar, index) => {
|
|
bar.toggleClass("nibbleai-meter-bar-active", index < activeBars);
|
|
});
|
|
}
|
|
|
|
updateStatusBarItem() {
|
|
if (!this.statusBarItem) return;
|
|
|
|
this.statusBarItem.empty();
|
|
this.statusBarItem.removeClass("nibbleai-status-recording");
|
|
this.statusBarItem.removeClass("nibbleai-status-paused");
|
|
this.statusBarItem.removeClass("nibbleai-status-processing");
|
|
this.statusBarItem.removeClass("nibbleai-status-idle");
|
|
this.meterBars = [];
|
|
|
|
switch (this.status) {
|
|
case RecordingStatus.Recording:
|
|
this.statusBarItem.addClass("nibbleai-status-recording");
|
|
this.statusBarItem.createSpan({ text: "NibbleAI " });
|
|
this.createInputMeter();
|
|
break;
|
|
case RecordingStatus.Paused:
|
|
this.statusBarItem.addClass("nibbleai-status-paused");
|
|
this.statusBarItem.setText("NibbleAI Paused");
|
|
break;
|
|
case RecordingStatus.Processing:
|
|
this.statusBarItem.addClass("nibbleai-status-processing");
|
|
this.statusBarItem.setText("NibbleAI Processing...");
|
|
break;
|
|
case RecordingStatus.Idle:
|
|
default:
|
|
this.statusBarItem.addClass("nibbleai-status-idle");
|
|
this.statusBarItem.setText("NibbleAI Idle");
|
|
break;
|
|
}
|
|
}
|
|
|
|
private createInputMeter(): void {
|
|
if (!this.statusBarItem) return;
|
|
|
|
const meter = this.statusBarItem.createSpan({
|
|
cls: "nibbleai-input-meter",
|
|
attr: { "aria-label": "Recording input level" },
|
|
});
|
|
|
|
for (let i = 0; i < 8; i++) {
|
|
this.meterBars.push(
|
|
meter.createSpan({ cls: "nibbleai-meter-bar" })
|
|
);
|
|
}
|
|
}
|
|
|
|
remove() {
|
|
if (this.statusBarItem) {
|
|
this.statusBarItem.remove();
|
|
}
|
|
}
|
|
} |