mirror of
https://github.com/BigBodyCobain/Shadowbroker.git
synced 2026-07-08 05:17:49 +02:00
cfbeabda1e
* feat(telegram): auto-translate OSINT channel posts to English Cherry-picked from @Bobpick PR #391 (telegram-only slice): server-side translation during fetch, SHOW ORIGINAL toggle in TelegramOsintPopup, and on-demand /api/telegram-feed?lang=. Co-authored-by: Robert Pickett <bobpickettsr@yahoo.com> Co-authored-by: Cursor <cursoragent@cursor.com> * feat(gt): experimental Derived OSINT analytics with lean-node safeguards Cherry-picked from @Bobpick PR #391 (GT + OpenClaw slice): Bayesian strategic-risk engine, map overlay, OpenClaw commands, and telegram_rhetoric watchdog. Off by default (GT_ANALYTICS_ENABLED=false, gt_risk layer false). 1 vCPU nodes get cgroup detection, UI warning on layer toggle, and lean profile that skips scheduled ingest/Louvain unless GT_ANALYTICS_ACK_LOW_CPU=true. Backtest HUD removed from dashboard (OpenClaw/API regression only). Co-authored-by: Robert Pickett <bobpickettsr@yahoo.com> Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Robert Pickett <bobpickettsr@yahoo.com> Co-authored-by: Cursor <cursoragent@cursor.com>
58 lines
1.6 KiB
TypeScript
58 lines
1.6 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import type { GtDossier } from '@/types/dashboard';
|
|
import { API_BASE } from '@/lib/api';
|
|
|
|
export function useGtDossier(
|
|
lat: number | undefined,
|
|
lng: number | undefined,
|
|
countryName?: string,
|
|
enabled = true,
|
|
) {
|
|
const [gtDossier, setGtDossier] = useState<GtDossier | null>(null);
|
|
const [gtDossierLoading, setGtDossierLoading] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (!enabled || lat == null || lng == null) {
|
|
setGtDossier(null);
|
|
setGtDossierLoading(false);
|
|
return;
|
|
}
|
|
|
|
let cancelled = false;
|
|
const regions = [
|
|
`${lat.toFixed(2)},${lng.toFixed(2)}`,
|
|
countryName?.trim().toLowerCase(),
|
|
].filter((value): value is string => Boolean(value));
|
|
|
|
const load = async () => {
|
|
setGtDossierLoading(true);
|
|
let best: GtDossier | null = null;
|
|
for (const region of regions) {
|
|
try {
|
|
const response = await fetch(
|
|
`${API_BASE}/api/analytics/dossier/${encodeURIComponent(region)}`,
|
|
);
|
|
if (!response.ok) continue;
|
|
const payload = (await response.json()) as GtDossier;
|
|
if (!payload.enabled) continue;
|
|
if (!best || (payload.current_risk ?? 0) > (best.current_risk ?? 0)) {
|
|
best = { ...payload, region };
|
|
}
|
|
} catch {
|
|
// GT analytics optional — ignore fetch errors
|
|
}
|
|
}
|
|
if (!cancelled) {
|
|
setGtDossier(best);
|
|
setGtDossierLoading(false);
|
|
}
|
|
};
|
|
|
|
void load();
|
|
return () => {
|
|
cancelled = true;
|
|
};
|
|
}, [lat, lng, countryName, enabled]);
|
|
|
|
return { gtDossier, gtDossierLoading };
|
|
} |