SkateSpots/src/hooks/useAutoHiddenSpots.ts
SkateSpots ee97a1c5ca feat(spots): make reports act, add a publish floor, stop junk looking endorsed
The 'test of secret island airport' case: a no-photo, one-line, reported pin sat
on the map looking legit. Four fixes:

- A) Report has a visible effect: a 'Reported as not a skate spot by N — under
     review' banner on the spot page, for everyone.
- B) Publish floor: a spot needs a photo OR a non-empty description. Photo stays
     optional (per the earlier decision); title + type alone no longer publishes.
- C) Auto-hide from the map when >=3 DISTINCT accounts report it AND it has no
     community signals (no community photo, no status report). The 'no signals'
     clause is the anti-brigade guard; reversible. useSpotReports now exposes
     distinct .
- D) The flattering 'Conditions ... NN/100' block is hidden until the spot is
     confirmed (community or staff) — on an unconfirmed pin it read as the app
     endorsing the spot itself.
2026-09-28 19:32:01 +07:00

41 lines
1.5 KiB
TypeScript

import { useMemo } from 'react';
import { useSpotReports } from '@/hooks/useSpotReports';
import { useBatchSpotPhotos } from '@/hooks/useSpotContributions';
import { useBatchSpotStatus } from '@/hooks/useSpotStatus';
/**
* A spot is auto-hidden pending human review when this many DISTINCT accounts
* have reported it "not a skate spot" AND it has NO community signals at all
* (no community photo, no status report).
*
* The "no community signals" clause is the anti-brigade guard: any real spot
* that a skater has engaged with is left to a human instead. It is fully
* reversible — a community photo/status (or an admin `cleared`/`verified`
* verdict) brings it straight back.
*/
export const AUTO_HIDE_REPORT_THRESHOLD = 3;
export function useAutoHiddenSpots(
spots: Array<{ id: string; pubkey: string; identifier: string }>,
) {
const reports = useSpotReports(spots);
const photos = useBatchSpotPhotos(spots);
const status = useBatchSpotStatus(spots);
const autoHiddenIds = useMemo(() => {
const set = new Set<string>();
for (const s of spots) {
if (reports.getCounts(s.id).reporters < AUTO_HIDE_REPORT_THRESHOLD) continue;
const hasPhoto = photos.getCommunityPhotoCount(s.pubkey, s.identifier) > 0;
const hasStatus = (status.getStatus(s.pubkey, s.identifier)?.reporterCount ?? 0) > 0;
if (hasPhoto || hasStatus) continue;
set.add(s.id);
}
return set;
}, [spots, reports, photos, status]);
return {
autoHiddenIds,
isAutoHidden: (id: string) => autoHiddenIds.has(id),
};
}