Change klippy window behavour, Fix user management behavour, clean up search server page

This commit is contained in:
2026-03-08 00:00:17 +01:00
parent 90f067e662
commit d20509566d
56 changed files with 1783 additions and 489 deletions

View File

@@ -289,7 +289,7 @@ export class ServerDirectoryService {
return this.searchAllEndpoints(query);
}
return this.searchSingleEndpoint(query, this.buildApiBaseUrl());
return this.searchSingleEndpoint(query, this.buildApiBaseUrl(), this.activeServer());
}
/** Retrieve the full list of public servers. */
@@ -301,7 +301,7 @@ export class ServerDirectoryService {
return this.http
.get<{ servers: ServerInfo[]; total: number }>(`${this.buildApiBaseUrl()}/servers`)
.pipe(
map((response) => this.unwrapServersResponse(response)),
map((response) => this.normalizeServerList(response, this.activeServer())),
catchError((error) => {
console.error('Failed to get servers:', error);
return of([]);
@@ -314,6 +314,7 @@ export class ServerDirectoryService {
return this.http
.get<ServerInfo>(`${this.buildApiBaseUrl()}/servers/${serverId}`)
.pipe(
map((server) => this.normalizeServerInfo(server, this.activeServer())),
catchError((error) => {
console.error('Failed to get server:', error);
return of(null);
@@ -471,14 +472,15 @@ export class ServerDirectoryService {
/** Search a single endpoint for servers matching a query. */
private searchSingleEndpoint(
query: string,
apiBaseUrl: string
apiBaseUrl: string,
source?: ServerEndpoint | null
): Observable<ServerInfo[]> {
const params = new HttpParams().set('q', query);
return this.http
.get<{ servers: ServerInfo[]; total: number }>(`${apiBaseUrl}/servers`, { params })
.pipe(
map((response) => this.unwrapServersResponse(response)),
map((response) => this.normalizeServerList(response, source)),
catchError((error) => {
console.error('Failed to search servers:', error);
return of([]);
@@ -493,19 +495,11 @@ export class ServerDirectoryService {
);
if (onlineEndpoints.length === 0) {
return this.searchSingleEndpoint(query, this.buildApiBaseUrl());
return this.searchSingleEndpoint(query, this.buildApiBaseUrl(), this.activeServer());
}
const requests = onlineEndpoints.map((endpoint) =>
this.searchSingleEndpoint(query, `${endpoint.url}/api`).pipe(
map((results) =>
results.map((server) => ({
...server,
sourceId: endpoint.id,
sourceName: endpoint.name
}))
)
)
this.searchSingleEndpoint(query, `${endpoint.url}/api`, endpoint)
);
return forkJoin(requests).pipe(
@@ -524,7 +518,7 @@ export class ServerDirectoryService {
return this.http
.get<{ servers: ServerInfo[]; total: number }>(`${this.buildApiBaseUrl()}/servers`)
.pipe(
map((response) => this.unwrapServersResponse(response)),
map((response) => this.normalizeServerList(response, this.activeServer())),
catchError(() => of([]))
);
}
@@ -533,15 +527,7 @@ export class ServerDirectoryService {
this.http
.get<{ servers: ServerInfo[]; total: number }>(`${endpoint.url}/api/servers`)
.pipe(
map((response) => {
const results = this.unwrapServersResponse(response);
return results.map((server) => ({
...server,
sourceId: endpoint.id,
sourceName: endpoint.name
}));
}),
map((response) => this.normalizeServerList(response, endpoint)),
catchError(() => of([] as ServerInfo[]))
)
);
@@ -562,6 +548,57 @@ export class ServerDirectoryService {
});
}
private normalizeServerList(
response: { servers: ServerInfo[]; total: number } | ServerInfo[],
source?: ServerEndpoint | null
): ServerInfo[] {
return this.unwrapServersResponse(response).map((server) => this.normalizeServerInfo(server, source));
}
private normalizeServerInfo(
server: ServerInfo | Record<string, unknown>,
source?: ServerEndpoint | null
): ServerInfo {
const candidate = server as Record<string, unknown>;
const userCount = typeof candidate['userCount'] === 'number'
? candidate['userCount']
: (typeof candidate['currentUsers'] === 'number' ? candidate['currentUsers'] : 0);
const maxUsers = typeof candidate['maxUsers'] === 'number' ? candidate['maxUsers'] : 0;
const isPrivate = typeof candidate['isPrivate'] === 'boolean'
? candidate['isPrivate']
: candidate['isPrivate'] === 1;
return {
id: typeof candidate['id'] === 'string' ? candidate['id'] : '',
name: typeof candidate['name'] === 'string' ? candidate['name'] : 'Unnamed server',
description: typeof candidate['description'] === 'string' ? candidate['description'] : undefined,
topic: typeof candidate['topic'] === 'string' ? candidate['topic'] : undefined,
hostName:
typeof candidate['hostName'] === 'string'
? candidate['hostName']
: (typeof candidate['sourceName'] === 'string'
? candidate['sourceName']
: (source?.name ?? 'Unknown API')),
ownerId: typeof candidate['ownerId'] === 'string' ? candidate['ownerId'] : undefined,
ownerName: typeof candidate['ownerName'] === 'string' ? candidate['ownerName'] : undefined,
ownerPublicKey:
typeof candidate['ownerPublicKey'] === 'string' ? candidate['ownerPublicKey'] : undefined,
userCount,
maxUsers,
isPrivate,
tags: Array.isArray(candidate['tags']) ? candidate['tags'] as string[] : [],
createdAt: typeof candidate['createdAt'] === 'number' ? candidate['createdAt'] : Date.now(),
sourceId:
typeof candidate['sourceId'] === 'string'
? candidate['sourceId']
: source?.id,
sourceName:
typeof candidate['sourceName'] === 'string'
? candidate['sourceName']
: source?.name
};
}
/** Load endpoints from localStorage, syncing the built-in default endpoint if needed. */
private loadEndpoints(): void {
const stored = localStorage.getItem(ENDPOINTS_STORAGE_KEY);