Download User/src/services/issueService.ts from 0xarchit/CityTrack: direct link, hf CLI and curl.
- Browser
- Download file 3.94 kB
-
https://huggingface.co/spaces/0xarchit/CityTrack/resolve/main/User/src/services/issueService.ts
- Command line
-
hf download hf://spaces/0xarchit/CityTrack/User/src/services/issueService.ts
-
curl -L -o issueService.ts https://huggingface.co/spaces/0xarchit/CityTrack/resolve/main/User/src/services/issueService.ts
3.94 kB
| import { API_BASE_URL } from "../config/supabase"; | |
| import { Issue, IssueListResponse, LocationData } from "../types"; | |
| import EventSource, { EventSourceListener } from "react-native-sse"; | |
| import { cacheService } from "./cacheService"; | |
| class IssueService { | |
| private baseUrl: string; | |
| constructor() { | |
| this.baseUrl = API_BASE_URL; | |
| } | |
| async createIssue( | |
| imageUri: string, | |
| location: LocationData, | |
| description?: string, | |
| accessToken?: string, | |
| ): Promise<{ issue_id: string; stream_url: string }> { | |
| const formData = new FormData(); | |
| const imageFile = { | |
| uri: imageUri, | |
| type: "image/jpeg", | |
| name: "issue_photo.jpg", | |
| } as any; | |
| formData.append("images", imageFile); | |
| formData.append("latitude", location.latitude.toString()); | |
| formData.append("longitude", location.longitude.toString()); | |
| formData.append("accuracy_meters", location.accuracy.toString()); | |
| formData.append("platform", "mobile_app"); | |
| formData.append("device_model", "expo_device"); | |
| if (description) { | |
| formData.append("description", description); | |
| } | |
| if (accessToken) { | |
| formData.append("authorization", `Bearer ${accessToken}`); | |
| console.log("[IssueService] Authorization token appended to form data"); | |
| } else { | |
| console.warn("[IssueService] No access token provided - issue will be created without user_id"); | |
| } | |
| const headers: Record<string, string> = { | |
| "Content-Type": "multipart/form-data", | |
| }; | |
| const response = await fetch(`${this.baseUrl}/issues/stream`, { | |
| method: "POST", | |
| headers, | |
| body: formData, | |
| }); | |
| if (!response.ok) { | |
| const error = await response.json(); | |
| throw new Error(error.detail || "Failed to create issue"); | |
| } | |
| await cacheService.clearCache(); | |
| return response.json(); | |
| } | |
| async getIssue(issueId: string): Promise<Issue> { | |
| const response = await fetch(`${this.baseUrl}/issues/${issueId}`); | |
| if (!response.ok) { | |
| throw new Error("Failed to fetch issue"); | |
| } | |
| return response.json(); | |
| } | |
| async listIssues( | |
| page: number = 1, | |
| pageSize: number = 20, | |
| state?: string, | |
| userId?: string, | |
| ): Promise<IssueListResponse> { | |
| const params = new URLSearchParams({ | |
| page: page.toString(), | |
| page_size: pageSize.toString(), | |
| }); | |
| if (state) { | |
| params.append("state", state); | |
| } | |
| if (userId) { | |
| params.append("user_id", userId); | |
| } | |
| const response = await fetch(`${this.baseUrl}/issues?${params}`); | |
| if (!response.ok) { | |
| throw new Error("Failed to fetch issues"); | |
| } | |
| return response.json(); | |
| } | |
| async connectToFlowStream( | |
| issueId: string, | |
| onMessage: (data: any) => void, | |
| onError: (error: Error) => void, | |
| ): Promise<() => void> { | |
| const eventSource = new EventSource(`${this.baseUrl}/flow/flow/${issueId}`); | |
| const listener: EventSourceListener = (event) => { | |
| if (event.type === "message") { | |
| try { | |
| const data = JSON.parse(event.data || "{}"); | |
| onMessage(data); | |
| } catch (e) { | |
| console.error("Failed to parse SSE message:", e); | |
| } | |
| } else if (event.type === "error") { | |
| onError(new Error("SSE connection error")); | |
| } | |
| }; | |
| eventSource.addEventListener("message", listener); | |
| eventSource.addEventListener("error", listener); | |
| return () => { | |
| eventSource.removeAllEventListeners(); | |
| eventSource.close(); | |
| }; | |
| } | |
| async confirmIssue(issueId: string, confirmed: boolean): Promise<Issue> { | |
| const response = await fetch(`${this.baseUrl}/issues/${issueId}/confirm`, { | |
| method: "POST", | |
| headers: { | |
| "Content-Type": "application/json", | |
| }, | |
| body: JSON.stringify({ confirmed }), | |
| }); | |
| if (!response.ok) { | |
| throw new Error("Failed to confirm issue"); | |
| } | |
| return response.json(); | |
| } | |
| } | |
| export const issueService = new IssueService(); | |