Add WebSocket support (#12)

This commit is contained in:
Andras Schmelczer 2025-03-29 10:17:46 +00:00 • committed by GitHub
commit 1aad0fce31
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 2581 additions and 996 deletions

View file

@ -0,0 +1,32 @@
@mixin number-card {
padding: var(--size-2-1) var(--size-4-1);
border-radius: var(--radius-s);
background-color: var(--color-base-30);
font-size: var(--font-ui-small);
&.good {
background-color: rgba(var(--color-green-rgb), 0.35);
}
&.bad {
background-color: rgba(var(--color-red-rgb), 0.35);
}
}
.status-description {
margin: var(--p-spacing) 0;
.number {
@include number-card;
font-family: var(--font-monospace);
font-weight: var(--bold-weight);
}
.error {
color: rgb(var(--color-red-rgb));
}
.warning {
color: rgb(var(--color-yellow-rgb));
}
}

View file

@ -0,0 +1,148 @@
import "./status-description.scss";
import type {
HistoryStats,
NetworkConnectionStatus,
SyncClient
} from "sync-client";
export class StatusDescription {
private lastHistoryStats: HistoryStats | undefined;
private lastRemaining: number | undefined;
private lastConnectionState: NetworkConnectionStatus | undefined;
private statusChangeListeners: (() => void)[] = [];
public constructor(private readonly syncClient: SyncClient) {
void this.updateConnectionState();
syncClient.addSyncHistoryUpdateListener((status) => {
this.lastHistoryStats = status;
this.updateDescription();
});
this.syncClient.addRemainingSyncOperationsListener(
(remainingOperations) => {
this.lastRemaining = remainingOperations;
this.updateDescription();
}
);
this.syncClient.addWebSocketStatusChangeListener(
() => void this.updateConnectionState()
);
this.syncClient.addOnSettingsChangeListener(
() => void this.updateConnectionState()
);
}
public async updateConnectionState(): Promise<void> {
this.lastConnectionState = await this.syncClient.checkConnection();
this.updateDescription();
}
public addStatusChangeListener(listener: () => void): void {
this.statusChangeListeners.push(listener);
}
public removeStatusChangeListener(listener: () => void): void {
this.statusChangeListeners = this.statusChangeListeners.filter(
(l) => l !== listener
);
}
public renderStatusDescription(container: HTMLElement): void {
container.empty();
container.addClass("status-description");
if (this.lastConnectionState == undefined) {
container.createSpan({
text: "VaultLink is starting up…",
cls: "warning"
});
return;
}
if (!this.lastConnectionState.isSuccessful) {
container.createSpan({
text: `VaultLink failed to connect to the remote server with error '${this.lastConnectionState.serverMessage}'`,
cls: "error"
});
return;
}
if (!this.lastConnectionState.isWebSocketConnected) {
container.createSpan({
text: `${this.lastConnectionState.serverMessage} but the WebSocket connection could not be established.`,
cls: "error"
});
return;
}
container.createSpan({ text: "VaultLink is connected to the server " });
container.createEl("a", {
text: this.syncClient.getSettings().remoteUri,
href: this.syncClient.getSettings().remoteUri
});
container.createSpan({
text: ` and has indexed approximately `
});
container.createSpan({
text: `${this.syncClient.documentCount}`,
cls: "number"
});
container.createSpan({
text: ` documents. `
});
if (
(this.lastRemaining ?? 0) === 0 &&
(this.lastHistoryStats?.success ?? 0) === 0 &&
(this.lastHistoryStats?.error ?? 0) === 0
) {
if (this.syncClient.getSettings().isSyncEnabled) {
container.createSpan({
text: "Syncing is enabled but VaultLink hasn't found anything to sync yet."
});
} else {
container.createSpan({
text: "However, syncing is disabled right now.",
cls: "warning"
});
}
return;
}
container.createSpan({
text: "The plugin has "
});
container.createSpan({
text: `${this.lastRemaining ?? 0}`,
cls: "number"
});
container.createSpan({
text: " outstanding operations while having succeeded "
});
container.createSpan({
text: `${this.lastHistoryStats?.success ?? 0}`,
cls: ["number", "good"]
});
container.createSpan({
text: " times and failed "
});
container.createSpan({
text: `${this.lastHistoryStats?.error ?? 0}`,
cls: ["number", "bad"]
});
container.createSpan({
text: " times."
});
}
private updateDescription(): void {
this.statusChangeListeners.forEach((listener) => {
listener();
});
}
}