feat: Add browser documentation
This commit is contained in:
@@ -4,8 +4,8 @@
|
||||
<div>
|
||||
<h4 class="text-base font-semibold text-foreground">Local HTTP API</h4>
|
||||
<p class="mt-1 text-sm text-muted-foreground">
|
||||
Expose your client to local automation tools and scripts. Authentication is verified against your signaling server,
|
||||
and access is off by default.
|
||||
Expose your client to local automation tools and scripts. Authentication is verified against your signaling server, and access is off by
|
||||
default.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -23,9 +23,7 @@
|
||||
<section class="space-y-4 rounded-lg border border-border bg-card/60 p-5">
|
||||
<div>
|
||||
<h5 class="text-sm font-semibold text-foreground">Server</h5>
|
||||
<p class="mt-1 text-sm text-muted-foreground">
|
||||
Enable to start a local HTTP server. By default it only listens on the loopback interface.
|
||||
</p>
|
||||
<p class="mt-1 text-sm text-muted-foreground">Enable to start a local HTTP server. By default it only listens on the loopback interface.</p>
|
||||
</div>
|
||||
|
||||
<label class="flex items-start gap-3">
|
||||
@@ -42,6 +40,20 @@
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<label class="flex items-start gap-3">
|
||||
<input
|
||||
type="checkbox"
|
||||
class="mt-1 h-4 w-4 rounded border-border text-primary focus:ring-primary"
|
||||
[checked]="settings().docusaurusEnabled"
|
||||
[disabled]="busy() || !settings().enabled"
|
||||
(change)="toggleDocusaurus($event)"
|
||||
/>
|
||||
<span class="text-sm text-foreground">
|
||||
<span class="font-medium">Serve Docusaurus documentation at <code>/docusaurus</code></span>
|
||||
<span class="mt-1 block text-xs text-muted-foreground"> Hosts the built app and plugin documentation from local desktop resources. </span>
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<label class="flex items-start gap-3">
|
||||
<input
|
||||
type="checkbox"
|
||||
@@ -53,8 +65,7 @@
|
||||
<span class="text-sm text-foreground">
|
||||
<span class="font-medium">Allow connections from your network</span>
|
||||
<span class="mt-1 block text-xs text-muted-foreground">
|
||||
Bind to all interfaces (0.0.0.0). Other devices on your LAN will be able to reach the API. Only enable this on
|
||||
networks you trust.
|
||||
Bind to all interfaces (0.0.0.0). Other devices on your LAN will be able to reach the API. Only enable this on networks you trust.
|
||||
</span>
|
||||
</span>
|
||||
</label>
|
||||
@@ -73,9 +84,7 @@
|
||||
/>
|
||||
</label>
|
||||
|
||||
<p class="text-xs text-muted-foreground">
|
||||
Change the listening port if 17878 is in use. Press save to apply.
|
||||
</p>
|
||||
<p class="text-xs text-muted-foreground">Change the listening port if 17878 is in use. Press save to apply.</p>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
@@ -92,8 +101,8 @@
|
||||
<div>
|
||||
<h5 class="text-sm font-semibold text-foreground">Authentication</h5>
|
||||
<p class="mt-1 text-sm text-muted-foreground">
|
||||
Bearer tokens are issued only after a username/password is verified against one of the signaling servers below.
|
||||
Add the full URL (including <code>https://</code>) of every signaling server you trust.
|
||||
Bearer tokens are issued only after a username/password is verified against one of the signaling servers below. Add the full URL (including
|
||||
<code>https://</code>) of every signaling server you trust.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -153,6 +162,15 @@
|
||||
Open API docs in browser
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center rounded-lg border border-primary/40 bg-primary/10 px-4 py-2 text-sm font-medium text-primary transition-colors hover:bg-primary/20 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
[disabled]="busy()"
|
||||
(click)="openDocusaurusDocs()"
|
||||
>
|
||||
Open app docs in browser
|
||||
</button>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center rounded-lg border border-border bg-secondary px-4 py-2 text-sm font-medium text-foreground transition-colors hover:bg-secondary/80 disabled:cursor-not-allowed disabled:opacity-60"
|
||||
|
||||
@@ -25,6 +25,7 @@ export class LocalApiSettingsComponent implements OnInit, OnDestroy {
|
||||
port: 17878,
|
||||
exposeOnLan: false,
|
||||
scalarEnabled: false,
|
||||
docusaurusEnabled: false,
|
||||
allowedSignalingServers: []
|
||||
});
|
||||
|
||||
@@ -35,7 +36,8 @@ export class LocalApiSettingsComponent implements OnInit, OnDestroy {
|
||||
baseUrl: null,
|
||||
error: null,
|
||||
exposeOnLan: false,
|
||||
scalarEnabled: false
|
||||
scalarEnabled: false,
|
||||
docusaurusEnabled: false
|
||||
});
|
||||
|
||||
readonly allowedServersText = signal('');
|
||||
@@ -94,6 +96,7 @@ export class LocalApiSettingsComponent implements OnInit, OnDestroy {
|
||||
port: desktop.localApi.port,
|
||||
exposeOnLan: desktop.localApi.exposeOnLan,
|
||||
scalarEnabled: desktop.localApi.scalarEnabled,
|
||||
docusaurusEnabled: desktop.localApi.docusaurusEnabled,
|
||||
allowedSignalingServers: [...desktop.localApi.allowedSignalingServers]
|
||||
});
|
||||
|
||||
@@ -135,6 +138,12 @@ export class LocalApiSettingsComponent implements OnInit, OnDestroy {
|
||||
await this.savePatch({ scalarEnabled: checkbox.checked });
|
||||
}
|
||||
|
||||
async toggleDocusaurus(event: Event): Promise<void> {
|
||||
const checkbox = event.target as HTMLInputElement;
|
||||
|
||||
await this.savePatch({ docusaurusEnabled: checkbox.checked });
|
||||
}
|
||||
|
||||
onPortInput(event: Event): void {
|
||||
const input = event.target as HTMLInputElement;
|
||||
|
||||
@@ -187,6 +196,22 @@ export class LocalApiSettingsComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
}
|
||||
|
||||
async openDocusaurusDocs(): Promise<void> {
|
||||
const api = this.bridge.getApi();
|
||||
|
||||
if (!api)
|
||||
return;
|
||||
|
||||
const result = await api.openDocusaurusDocs();
|
||||
|
||||
if (result && !result.opened) {
|
||||
this.errorMessage.set(result.reason ?? 'Could not open documentation');
|
||||
} else {
|
||||
this.errorMessage.set(null);
|
||||
await this.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
async copyBaseUrl(): Promise<void> {
|
||||
const baseUrl = this.status().baseUrl;
|
||||
|
||||
@@ -221,6 +246,7 @@ export class LocalApiSettingsComponent implements OnInit, OnDestroy {
|
||||
port: updated.localApi.port,
|
||||
exposeOnLan: updated.localApi.exposeOnLan,
|
||||
scalarEnabled: updated.localApi.scalarEnabled,
|
||||
docusaurusEnabled: updated.localApi.docusaurusEnabled,
|
||||
allowedSignalingServers: [...updated.localApi.allowedSignalingServers]
|
||||
});
|
||||
|
||||
|
||||
@@ -98,6 +98,20 @@
|
||||
/>
|
||||
</button>
|
||||
|
||||
@if (isElectron()) {
|
||||
<button
|
||||
type="button"
|
||||
class="grid h-8 w-8 place-items-center rounded-md transition-colors hover:bg-secondary"
|
||||
title="Open Documentation"
|
||||
(click)="openDocumentation()"
|
||||
>
|
||||
<ng-icon
|
||||
name="lucideBookOpen"
|
||||
class="h-4 w-4 text-muted-foreground"
|
||||
/>
|
||||
</button>
|
||||
}
|
||||
|
||||
<div class="relative">
|
||||
<button
|
||||
type="button"
|
||||
@@ -151,6 +165,20 @@
|
||||
>
|
||||
Plugin Store
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
(click)="openSettings()"
|
||||
class="w-full rounded-md px-3 py-2 text-left text-sm text-foreground transition-colors hover:bg-secondary"
|
||||
>
|
||||
Settings
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
(click)="openDocumentation()"
|
||||
class="w-full rounded-md px-3 py-2 text-left text-sm text-foreground transition-colors hover:bg-secondary"
|
||||
>
|
||||
Documentation
|
||||
</button>
|
||||
<div class="mx-2 my-1 h-px bg-border"></div>
|
||||
<button
|
||||
type="button"
|
||||
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
lucideSquare,
|
||||
lucideX,
|
||||
lucideChevronLeft,
|
||||
lucideBookOpen,
|
||||
lucideHash,
|
||||
lucideMenu,
|
||||
lucidePackage,
|
||||
@@ -39,6 +40,7 @@ import { RealtimeSessionFacade } from '../../../core/realtime';
|
||||
import { ServerDirectoryFacade } from '../../../domains/server-directory';
|
||||
import { PlatformService } from '../../../core/platform';
|
||||
import { clearStoredCurrentUserId } from '../../../core/storage/current-user-storage';
|
||||
import { SettingsModalService } from '../../../core/services/settings-modal.service';
|
||||
import { LeaveServerDialogComponent } from '../../../shared';
|
||||
import { Room } from '../../../shared-kernel';
|
||||
import { VoiceWorkspaceService } from '../../../domains/voice-session';
|
||||
@@ -58,6 +60,7 @@ import { ThemeNodeDirective } from '../../../domains/theme';
|
||||
lucideSquare,
|
||||
lucideX,
|
||||
lucideChevronLeft,
|
||||
lucideBookOpen,
|
||||
lucideHash,
|
||||
lucideMenu,
|
||||
lucidePackage,
|
||||
@@ -76,6 +79,7 @@ export class TitleBarComponent {
|
||||
private webrtc = inject(RealtimeSessionFacade);
|
||||
private platform = inject(PlatformService);
|
||||
private voiceWorkspace = inject(VoiceWorkspaceService);
|
||||
private settingsModal = inject(SettingsModalService);
|
||||
|
||||
private getWindowControlsApi() {
|
||||
return this.electronBridge.getApi();
|
||||
@@ -188,6 +192,27 @@ export class TitleBarComponent {
|
||||
void this.router.navigate(['/plugin-store'], { queryParams: { returnUrl } });
|
||||
}
|
||||
|
||||
openSettings(): void {
|
||||
this._showMenu.set(false);
|
||||
this.settingsModal.open('general');
|
||||
}
|
||||
|
||||
async openDocumentation(): Promise<void> {
|
||||
const api = this.electronBridge.getApi();
|
||||
|
||||
this._showMenu.set(false);
|
||||
|
||||
if (!api) {
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await api.openDocusaurusDocs();
|
||||
|
||||
if (result && !result.opened) {
|
||||
this.inviteStatus.set(result.reason ?? 'Unable to open documentation.');
|
||||
}
|
||||
}
|
||||
|
||||
/** Open the unified leave-server confirmation dialog. */
|
||||
private openLeaveConfirm() {
|
||||
this._showMenu.set(false);
|
||||
|
||||
Reference in New Issue
Block a user