Add File Upload Support
还没有人认领这个 Issue。
评估
- 难度
- 5/5
- 预计耗时
- 一周以上
- 新手友好度
- 30/100
- Issue 类型
- 功能
- 描述清晰度
- 基本清楚
- 活跃度
- 停滞
- 技术栈
- react, typescript
- 领域
- frontend
调研方向
首先定位现有的 useStacValue hook 及其当前的 URL 获取路径;该 issue 未指定源文件或测试路径。比较提议的 file、URL 和 JSON 输入,然后为加载、无效 file、验证、并发输入和 file 大小添加有针对性的覆盖,并补充关于 upload 和拖放用法的文档。
由索引模型根据 Issue 内容生成。
描述
Problem
stac-react currently only supports fetching STAC resources from URLs. There's no support for:
- Loading STAC JSON from uploaded files
- Exploring local STAC catalogs
- Working with STAC files without hosting them
- Development and testing with local files
Projects like stac-map need to allow users to drag-and-drop or upload STAC JSON files for immediate visualization without requiring the files to be hosted.
Current Behavior
// Only URL-based fetching is supported
const { collection } = useCollection('collection-id'); // Requires API
const { item } = useItem('https://example.com/item.json'); // Requires URL
No way to load from File objects or FileList.
Desired Behavior
import { useStacValue } from '@developmentseed/stac-react';
function StacFileUploader() {
const [file, setFile] = useState<File | null>(null);
const { value, isLoading, error } = useStacValue({
file: file,
});
return (
<div>
<input
type="file"
accept=".json,application/json"
onChange={(e) => setFile(e.target.files?.[0])}
/>
{value && <StacViewer value={value} />}
</div>
);
}
Use Cases from stac-map
stac-map supports file uploads via:
const fileUpload = useFileUpload({ maxFiles: 1 });
const { value, error } = useStacValue({
href,
fileUpload, // Handles uploaded files
});
// In the UI:
<FileUpload.Dropzone>
<Map value={value} />
</FileUpload.Dropzone>
Proposed Solution
Enhanced Hook Signature
type UseStacValueOptions = {
// URL-based
url?: string;
// File-based
file?: File;
// Raw JSON
json?: object;
// Fetch options (for URL)
headers?: Record<string, string>;
method?: 'GET' | 'POST';
body?: unknown;
};
function useStacValue(options: UseStacValueOptions): UseStacValueResult;
Implementation
import { useQuery } from '@tanstack/react-query';
function useStacValue(options: UseStacValueOptions): UseStacValueResult {
const { url, file, json, headers, method, body } = options;
const { data, error, isLoading, isFetching, refetch } = useQuery({
queryKey: ['stac-value', url, file?.name, json, method],
queryFn: async () => {
let value: any;
if (json) {
// Direct JSON object
value = json;
} else if (file) {
// File upload
const text = await file.text();
value = JSON.parse(text);
} else if (url) {
// URL fetch
const response = await fetch(url, {
method: method || 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
...headers,
},
body: body ? JSON.stringify(body) : undefined,
});
if (!response.ok) {
throw new ApiError(
response.statusText,
response.status,
await response.text(),
response.url
);
}
value = await response.json();
} else {
throw new Error('Must provide url, file, or json');
}
return {
value,
type: determineStacType(value),
};
},
enabled: !!(url || file || json),
retry: false,
});
return {
value: data?.value,
type: data?.type,
isLoading,
isFetching,
error,
refetch,
};
}
Example Usage Patterns
1. File Input
function FileUploadExample() {
const [file, setFile] = useState<File | null>(null);
const { value, isLoading, error } = useStacValue({ file });
return (
<div>
<input
type="file"
onChange={(e) => setFile(e.target.files?.[0] || null)}
/>
{isLoading && <p>Loading...</p>}
{error && <p>Error: {error.message}</p>}
{value && <pre>{JSON.stringify(value, null, 2)}</pre>}
</div>
);
}
2. Drag and Drop
function DragDropExample() {
const [file, setFile] = useState<File | null>(null);
const { value } = useStacValue({ file });
const handleDrop = (e: React.DragEvent) => {
e.preventDefault();
const droppedFile = e.dataTransfer.files[0];
if (droppedFile?.type === 'application/json') {
setFile(droppedFile);
}
};
return (
<div
onDrop={handleDrop}
onDragOver={(e) => e.preventDefault()}
>
Drop STAC JSON file here
{value && <StacViewer value={value} />}
</div>
);
}
3. Combined URL and File
function FlexibleLoader({ url, file }) {
// Automatically uses file if provided, otherwise URL
const { value, isLoading } = useStacValue({
url: !file ? url : undefined,
file: file,
});
return <div>{/* ... */}</div>;
}
File Validation
Add optional validation:
function validateStacFile(file: File): Promise<boolean> {
return new Promise((resolve) => {
if (!file.name.endsWith('.json')) {
resolve(false);
return;
}
const reader = new FileReader();
reader.onload = (e) => {
try {
const json = JSON.parse(e.target?.result as string);
// Check for STAC required fields
resolve(
json.type &&
json.stac_version &&
json.links
);
} catch {
resolve(false);
}
};
reader.readAsText(file);
});
}
Benefits
- ✅ Load STAC from uploaded files
- ✅ Support drag-and-drop workflows
- ✅ Enable offline/local STAC exploration
- ✅ Simplify development and testing
- ✅ Support in-memory STAC objects
- ✅ Maintain URL-based fetching
Breaking Changes
None - this extends existing functionality with backward compatibility.
Testing Requirements
- Test loading from File objects
- Test loading from URL
- Test loading from JSON objects
- Test error handling for invalid files
- Test file validation
- Test with different file sizes
- Test concurrent file and URL loading
Documentation Requirements
- Document file upload patterns
- Provide drag-and-drop examples
- Document file validation
- Show integration with file input libraries
- Document security considerations
- 主要语言
- TypeScript
- 星标
- 35
- 派生
- 4
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
developmentseed/stac-react 的其他 Issue
-
难度 3/5 1-2 天 新手友好度 55/100
-
难度 5/5 一周以上 新手友好度 35/100
-
难度 5/5 一周以上 新手友好度 30/100
-
难度 5/5 一周以上 新手友好度 35/100
-
难度 5/5 一周以上 新手友好度 42/100
查看 developmentseed/stac-react 的全部 Issue
相似的 Issue
-
docs(api): openapi.yaml still documents gif-tools optimize colors as 2-256 instead of 2, 4, 16, 256未关闭area: backend documentation priority: low
难度 2/5 1-3 小时 新手友好度 84/100
snapotter-hq/SnapOtter#2919 ·
维护者通常 1 天内回复
-
accepted :+1: bug db/redis
难度 2/5 1-3 小时 新手友好度 76/100
beekeeper-studio/beekeeper-studio#4882 · 1 条评论 ·
维护者通常 1 天内回复
-
ready-for-triage
难度 2/5 1-3 小时 新手友好度 72/100
konflux-ci/konflux-ui#1630 · 1 条评论 ·
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 67/100
ahmedkhaleel2004/gitdiagram#233 ·
-
难度 2/5 1-3 小时 新手友好度 72/100
simkimsia/netlify-axi#19 ·
维护者通常 1 天内回复