mirror of
https://github.com/block/buzz.git
synced 2026-11-02 15:31:27 +00:00
## Summary Project channels previously appeared as ordinary channels until the community-wide project enumeration completed, delaying the contextual right rail most noticeably on larger relays. - Restore the last fully validated, relay-and-identity-scoped project collection immediately while keeping live relay data authoritative. - Resolve the active channel's project home through scoped `#buzz-channel` queries instead of waiting for the complete project scan. - Keep snapshots aligned with community removal and relay reconnect invalidation. ### Related issue None found. ### Testing - Pre-push `file-size-check`, `desktop-check`, `desktop-typecheck`, and `desktop-test` - Project enumeration, snapshot persistence, and relay invalidation unit coverage - Targeted Playwright scenario: project sidebar rows open the home channel and nest extra channels No numeric startup benchmark was captured; this draft validates the cache and scoped-query behavior while leaving timing measurement for review. --------- Signed-off-by: Thomas Petersen <thomasp@squareup.com>
76 lines
2.5 KiB
TypeScript
76 lines
2.5 KiB
TypeScript
import { getCachedRelayOrigin } from "@/shared/lib/mediaUrl";
|
|
import { getIdentity } from "@/shared/api/tauriIdentity";
|
|
import {
|
|
buildProjectHomeFromFetcher,
|
|
buildProjectsFromFetcher,
|
|
type FetchProjectEventsExhaustively,
|
|
fetchProjectEventsExhaustively,
|
|
} from "./projectEnumeration";
|
|
import type { Project } from "./projectModels";
|
|
import { markProjectDataAuthoritative } from "./projectSnapshot";
|
|
|
|
const HIDDEN_PROJECT_CARDS_KEY = "buzz.projects.hidden-cards.v1";
|
|
|
|
function readHiddenProjectCards(): string[] {
|
|
if (typeof window === "undefined") {
|
|
return [];
|
|
}
|
|
|
|
try {
|
|
const parsed = JSON.parse(
|
|
window.localStorage.getItem(HIDDEN_PROJECT_CARDS_KEY) ?? "[]",
|
|
);
|
|
return Array.isArray(parsed)
|
|
? parsed.filter((item): item is string => typeof item === "string")
|
|
: [];
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
/** Enumerates the projects visible to the current relay identity. */
|
|
export async function fetchProjects(
|
|
fetchExhaustively?: FetchProjectEventsExhaustively,
|
|
signal?: AbortSignal,
|
|
): Promise<Project[]> {
|
|
// Delegates to `buildProjectsFromFetcher` in `projectEnumeration.ts`, which
|
|
// is the pure, Tauri-free core of this operation. Its javadoc explains
|
|
// fail-closed tombstones and NIP-OA owner-deletion suppression.
|
|
const viewerPubkey = await getIdentity()
|
|
.then((identity) => identity.pubkey)
|
|
.catch(() => undefined);
|
|
const fetcher: FetchProjectEventsExhaustively =
|
|
fetchExhaustively ??
|
|
((kinds, extraFilter) =>
|
|
fetchProjectEventsExhaustively(kinds, extraFilter, undefined, signal));
|
|
const projects = await buildProjectsFromFetcher(fetcher, {
|
|
relayOrigin: getCachedRelayOrigin(),
|
|
hiddenAddresses: new Set(readHiddenProjectCards()),
|
|
viewerPubkey,
|
|
});
|
|
return projects.map((project) =>
|
|
markProjectDataAuthoritative(project, "relay"),
|
|
);
|
|
}
|
|
|
|
/** Resolves the active channel's project home with a scoped relay query. */
|
|
export async function fetchProjectHomeForChannel(
|
|
channelId: string,
|
|
signal?: AbortSignal,
|
|
): Promise<Project | null> {
|
|
const viewerPubkey = await getIdentity()
|
|
.then((identity) => identity.pubkey)
|
|
.catch(() => undefined);
|
|
const project = await buildProjectHomeFromFetcher(
|
|
(kinds, extraFilter) =>
|
|
fetchProjectEventsExhaustively(kinds, extraFilter, undefined, signal),
|
|
channelId,
|
|
{
|
|
relayOrigin: getCachedRelayOrigin(),
|
|
hiddenAddresses: new Set(readHiddenProjectCards()),
|
|
viewerPubkey,
|
|
},
|
|
);
|
|
return project ? markProjectDataAuthoritative(project, "relay") : null;
|
|
}
|