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.
41 lines
1.5 KiB
TypeScript
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),
|
|
};
|
|
}
|