feat(reports): add server-driven report flows (#3330)

This commit is contained in:
Hampus authored and GitHub committed 2026-10-09 01:38:00 +02:00
1 parent bc17922b02
commit ece622e800
471 files changed
+56262 -35932

No files matched your search

@@ -212,7 +212,7 @@ function useGuildNavigationVisibility(): GuildNavigationVisibility {
const fluxerVisible = !RuntimeConfig.directMessagesDisabled;
const favoritesVisible = Accessibility.showFavorites;
const downloadVisible = !Platform.isElectron && !Platform.isPWA && !HiddenGuildListButtons.downloadButtonHidden;
const helpVisible = !HiddenGuildListButtons.helpButtonHidden;
const helpVisible = !HiddenGuildListButtons.helpButtonHidden && Routes.help() != null;
return useMemo(
() =>
Object.freeze({
@@ -256,9 +256,8 @@ export const Endpoints = {
USER_PUSH_SUBSCRIPTIONS: '/users/@me/push/subscriptions',
USER_PUSH_SUBSCRIPTION: (subscriptionId: string) => `/users/@me/push/subscriptions/${subscriptionId}`,
WEBHOOK: (webhookId: string) => `/webhooks/${webhookId}`,
REPORT_MESSAGE: '/reports/message',
REPORT_USER: '/reports/user',
REPORT_GUILD: '/reports/guild',
REPORT_FLOW: (targetType: string) => `/reports/flows/${targetType}`,
REPORT_FLOW_SUBMISSIONS: (targetType: string) => `/reports/flows/${targetType}/submissions`,
DISCOVERY_GUILDS: '/discovery/guilds',
DISCOVERY_CATEGORIES: '/discovery/categories',
DISCOVERY_JOIN: (guildId: string) => `/discovery/guilds/${guildId}/join`,
@@ -162,6 +162,10 @@ export function describeAPIEndpoint(endpoint: string): string {
return withoutScheme;
}
const DISCOVERY_REVALIDATION_TIMEOUT_MS = 5000;
let pendingDiscoveryRevalidation: Promise<void> | null = null;
class RuntimeConfig {
private lifecycleGeneration = 0;
private activeRuntime: ActiveRuntime | null = null;
@@ -659,13 +663,29 @@ class RuntimeConfig {
});
}
async refreshDiscovery(): Promise<void> {
async refreshDiscovery(signal?: AbortSignal): Promise<void> {
const current = this.requireActiveSnapshot();
const resolution = await InstanceSnapshotStore.refresh({input: current.apiEndpoint, signal: null});
const resolution = await InstanceSnapshotStore.refresh({input: current.apiEndpoint, signal: signal ?? null});
if (runtimeInstanceKey(resolution.snapshot) !== runtimeInstanceKey(this.requireActiveSnapshot())) {
return;
}
this.replaceActiveFeatures(resolution.snapshot.features);
const runtime = this.requireActiveRuntime();
const usable = this.requireUsableSnapshot({
...runtime.snapshot,
features: resolution.snapshot.features,
appPublic: resolution.snapshot.appPublic,
});
this.activeRuntime = {...runtime, snapshot: usable};
this.lifecycleGeneration = nextLifecycleGeneration(this.lifecycleGeneration);
}
revalidateDiscovery(): Promise<void> {
if (pendingDiscoveryRevalidation !== null) return pendingDiscoveryRevalidation;
const request = this.refreshDiscovery(AbortSignal.timeout(DISCOVERY_REVALIDATION_TIMEOUT_MS)).finally(() => {
if (pendingDiscoveryRevalidation === request) pendingDiscoveryRevalidation = null;
});
pendingDiscoveryRevalidation = request;
return request;
}
private replaceActiveFeatures(features: InstanceFeatures): void {