// package api handles launcher-specific API calls to the backend. package api import ( "context" "encoding/json" "fmt" "net/http" "time" "gitea.mrixs.me/Mrixs/MrixsCraft-launcher/internal/ui/screens" ) // ServerResponse represents the JSON response from /api/servers.json endpoint. type ServerResponse struct { Servers []ServerInfo `json:"servers"` } // ServerInfo represents a single server/modpack entry from the API. type ServerInfo struct { Slug string `json:"slug"` Name string `json:"name"` Version string `json:"version"` IP string `json:"ip"` } // FetchServerList retrieves and parses the server list from the backend API. // Returns a slice of Modpack objects suitable for UI consumption. func FetchServerList(serverURL string) ([]screens.Modpack, error) { // Create HTTP client with timeout client := &http.Client{ Timeout: 10 * time.Second, } // Create request with context for cancellation ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() req, err := http.NewRequestWithContext(ctx, "GET", fmt.Sprintf("%s/api/servers.json", serverURL), nil) if err != nil { return nil, fmt.Errorf("creating request: %w", err) } // Make the HTTP request resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("making request: %w", err) } defer resp.Body.Close() // Check HTTP status code if resp.StatusCode != http.StatusOK { return nil, fmt.Errorf("unexpected status code: %d", resp.StatusCode) } // Decode JSON response var serverResp ServerResponse if err := json.NewDecoder(resp.Body).Decode(&serverResp); err != nil { return nil, fmt.Errorf("decoding JSON: %w", err) } // Convert API server info to UI Modpack format var modpacks []screens.Modpack for _, server := range serverResp.Servers { modpacks = append(modpacks, screens.Modpack{ Slug: server.Slug, Name: server.Name, }) } return modpacks, nil }