feat(SearchCommoServe): add CORS handling and loading state for search errors
This commit is contained in:
parent
c3af4406bf
commit
8957254471
|
|
@ -231,6 +231,7 @@ export default function SearchAssembly64({ config, setConfig, onClose }: SearchA
|
|||
};
|
||||
|
||||
const handleSearch = () => doSearch(query, categoryFilter, 0);
|
||||
const handleLoadMore = () => doSearch(query, categoryFilter, offset, true);
|
||||
|
||||
// Build an AQL token for a preset value and append/replace it in the query.
|
||||
// Tokens that already contain a colon (e.g. 'subcat:c64comdemos') are
|
||||
|
|
|
|||
|
|
@ -158,6 +158,7 @@ export default function SearchCommoServe({ config, setConfig, onClose }: SearchC
|
|||
const [isSearching, setIsSearching] = useState(false);
|
||||
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
||||
const [searchError, setSearchError] = useState<string | null>(null);
|
||||
const [corsBlocked, setCorsBlocked] = useState(false);
|
||||
const [categoryFilter, setCategoryFilter] = useState<number | null>(() => _store.categoryFilter);
|
||||
|
||||
const [categories, setCategories] = useState<CategoryMapping[]>([]);
|
||||
|
|
@ -186,8 +187,9 @@ export default function SearchCommoServe({ config, setConfig, onClose }: SearchC
|
|||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
leetJson<CategoryMapping[]>('/search/categories').then(setCategories).catch(() => {});
|
||||
leetJson<PresetGroup[]>('/search/aql/presets').then(setPresets).catch(() => {});
|
||||
const isCors = (e: any) => /failed to fetch|networkerror/i.test(e?.message ?? '');
|
||||
leetJson<CategoryMapping[]>('/search/categories').then(setCategories).catch(e => { if (isCors(e)) setCorsBlocked(true); });
|
||||
leetJson<PresetGroup[]>('/search/aql/presets').then(setPresets).catch(e => { if (isCors(e)) setCorsBlocked(true); });
|
||||
}, []);
|
||||
|
||||
const categoryName = useMemo(() => {
|
||||
|
|
@ -215,7 +217,8 @@ export default function SearchCommoServe({ config, setConfig, onClose }: SearchC
|
|||
setHasMore(data.length === PAGE_SIZE);
|
||||
setHasSearched(true);
|
||||
} catch (e: any) {
|
||||
setSearchError(e?.message ?? 'Search failed');
|
||||
if (/failed to fetch|networkerror/i.test(e?.message ?? '')) setCorsBlocked(true);
|
||||
else setSearchError(e?.message ?? 'Search failed');
|
||||
} finally {
|
||||
setIsSearching(false);
|
||||
setIsLoadingMore(false);
|
||||
|
|
@ -397,14 +400,25 @@ export default function SearchCommoServe({ config, setConfig, onClose }: SearchC
|
|||
className="flex-1 overflow-y-auto"
|
||||
onScroll={e => { _store.scrollTop = (e.currentTarget as HTMLDivElement).scrollTop; }}
|
||||
>
|
||||
{isSearching && !hasSearched && (
|
||||
{corsBlocked && (
|
||||
<div className="flex flex-col items-center justify-center py-16 px-8 gap-3 text-center">
|
||||
<span className="text-3xl">🚫</span>
|
||||
<p className="text-sm font-medium text-neutral-700">CommoServe is not accessible</p>
|
||||
<p className="text-xs text-neutral-400 leading-relaxed">
|
||||
The CommoServe server does not allow requests from this browser origin (CORS policy).
|
||||
This service may only be reachable directly from your Meatloaf device.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!corsBlocked && isSearching && !hasSearched && (
|
||||
<div className="flex flex-col items-center justify-center py-16 gap-3">
|
||||
<Loader2 className="w-8 h-8 text-blue-500 animate-spin" />
|
||||
<p className="text-sm text-neutral-500">Searching…</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{searchError && (
|
||||
{!corsBlocked && searchError && (
|
||||
<div className="p-6 text-center">
|
||||
<p className="text-sm text-red-500">{searchError}</p>
|
||||
<button onClick={handleSearch} className="mt-2 inline-flex items-center gap-1 text-xs text-blue-600">
|
||||
|
|
@ -413,7 +427,7 @@ export default function SearchCommoServe({ config, setConfig, onClose }: SearchC
|
|||
</div>
|
||||
)}
|
||||
|
||||
{!searchError && hasSearched && (
|
||||
{!corsBlocked && !searchError && hasSearched && (
|
||||
<>
|
||||
{results.length > 0 ? (
|
||||
<>
|
||||
|
|
@ -487,7 +501,7 @@ export default function SearchCommoServe({ config, setConfig, onClose }: SearchC
|
|||
</>
|
||||
)}
|
||||
|
||||
{!hasSearched && !isSearching && (
|
||||
{!corsBlocked && !hasSearched && !isSearching && (
|
||||
<div className="py-16 text-center px-6">
|
||||
<Search className="w-10 h-10 mx-auto mb-3 text-neutral-300" />
|
||||
<p className="text-sm font-medium text-neutral-600 mb-1">Search the CommoServe database</p>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user