feat: implement dynamic server list loading from API

Add internal/api package to fetch server list from /api/servers.json endpoint

Replace hardcoded server list with dynamic API call

Implement loading states, error handling, and refresh capability
This commit is contained in:
2026-06-10 20:12:03 +03:00
parent e927fff02f
commit e1371e226a
6 changed files with 303 additions and 22 deletions

72
internal/api/server.go Normal file
View File

@@ -0,0 +1,72 @@
// 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
}