Skip to content

Ekran — Kosmos

Przegląd

Kosmos to ekran planet (custom worlds) tworzonych przez rodziców, szkoły lub moderatorów. Dziecko może przeglądać otwarte planety i do nich dołączać. Ekran ma dwie zakładki: "Otwarte" (public planets) i "Moje" (joined planets). Tap na planetę otwiera jej mapę (reuse ekranu Mapa Kraju).

Routing (GoRouter)

dart
// Kosmos jest częścią ShellRoute (bottom nav)
GoRoute(path: '/cosmos', builder: (_, __) => CosmosScreen()),

// Mapa planety reużywa MapScreen z parametrem "planet"
GoRoute(
  path: '/planet/:planetId',
  builder: (context, state) => MapScreen(
    worldId: state.pathParameters['planetId']!,
    isPlanet: true,
  ),
),

Riverpod Providers

dart
// Otwarte planety (public, z paginacją)
final openPlanetsProvider = StateNotifierProvider<PlanetListNotifier, PaginatedList<Planet>>(
  (ref) => PlanetListNotifier(
    ref.watch(planetRepositoryProvider),
    type: PlanetListType.open,
  ),
);

// Moje planety (joined, z paginacją)
final myPlanetsProvider = StateNotifierProvider<PlanetListNotifier, PaginatedList<Planet>>(
  (ref) => PlanetListNotifier(
    ref.watch(planetRepositoryProvider),
    type: PlanetListType.mine,
  ),
);

// Aktywna zakładka (0 = Otwarte, 1 = Moje)
final cosmosTabProvider = StateProvider<int>((ref) => 0);

// Stan join/leave (loading per planet)
final planetActionProvider = StateProvider.family<AsyncValue<void>, String>(
  (ref, planetId) => const AsyncValue.data(null),
);

ASCII Wireframe

┌──────────────────────────────────┐
│  Kosmos                     🔍  │
├──────────────────────────────────┤
│  ┌──────────────┬───────────────┐│
│  │   Otwarte    │     Moje      ││
│  │   (aktywna)  │               ││
│  └──────────────┴───────────────┘│
│                                  │
│  ┌────────────────────────────┐  │
│  │  ┌────────┐                │  │
│  │  │ 🪐     │  Planeta Nauki │  │
│  │  │ (img)  │                │  │
│  │  │        │  👥 42 uczniów  │  │
│  │  └────────┘  📍 8 lokacji   │  │
│  │                            │  │
│  │  Planeta z zadaniami z     │  │
│  │  matematyki i fizyki.      │  │
│  │                            │  │
│  │  [ DOŁĄCZ ]                │  │
│  └────────────────────────────┘  │
│                                  │
│  ┌────────────────────────────┐  │
│  │  ┌────────┐                │  │
│  │  │ 🌍     │  Szkoła ABC    │  │
│  │  │ (img)  │                │  │
│  │  │        │  👥 128 uczniów │  │
│  │  └────────┘  📍 12 lokacji  │  │
│  │                            │  │
│  │  Planeta klasy 3a z SP 12. │  │
│  │                            │  │
│  │  [ DOŁĄCZ ]                │  │
│  └────────────────────────────┘  │
│                                  │
│  ┌────────────────────────────┐  │
│  │  ┌────────┐                │  │
│  │  │ 🔬     │  Lab Przyrody  │  │
│  │  │ (img)  │                │  │
│  │  │        │  👥 67 uczniów  │  │
│  │  └────────┘  📍 5 lokacji   │  │
│  │                            │  │
│  │  Eksperymenty i odkrycia.  │  │
│  │                            │  │
│  │  [ DOŁĄCZ ]                │  │
│  └────────────────────────────┘  │
│                                  │
│  (ładowanie kolejnych...)        │
│                                  │
├──────────────────────────────────┤
│  🌍        🪐        🚀     👤  │
│ Globus    Kosmos    Statek  Profil│
└──────────────────────────────────┘

Zakładka "Moje"

┌──────────────────────────────────┐
│  Kosmos                     🔍  │
├──────────────────────────────────┤
│  ┌──────────────┬───────────────┐│
│  │   Otwarte    │     Moje      ││
│  │              │   (aktywna)   ││
│  └──────────────┴───────────────┘│
│                                  │
│  ┌────────────────────────────┐  │
│  │  ┌────────┐                │  │
│  │  │ 🪐     │  Planeta Nauki │  │
│  │  │ (img)  │                │  │
│  │  │        │  👥 42 uczniów  │  │
│  │  └────────┘  📍 8 lokacji   │  │
│  │                            │  │
│  │  Postęp: ████████░░ 75%   │  │
│  │                            │  │
│  │  [ ODKRYWAJ ]   [ OPUŚĆ ] │  │
│  └────────────────────────────┘  │
│                                  │
│  ┌────────────────────────────┐  │
│  │  ┌────────┐                │  │
│  │  │ 📚     │  Klub Książki  │  │
│  │  │ (img)  │                │  │
│  │  │        │  👥 15 uczniów  │  │
│  │  └────────┘  📍 3 lokacji   │  │
│  │                            │  │
│  │  Postęp: ██░░░░░░░░ 20%   │  │
│  │                            │  │
│  │  [ ODKRYWAJ ]   [ OPUŚĆ ] │  │
│  └────────────────────────────┘  │
│                                  │
│  ── Koniec listy ──              │
│                                  │
├──────────────────────────────────┤
│  🌍        🪐        🚀     👤  │
│ Globus    Kosmos    Statek  Profil│
└──────────────────────────────────┘

Stan pusty (Moje)

┌──────────────────────────────────┐
│  Kosmos                     🔍  │
├──────────────────────────────────┤
│  ┌──────────────┬───────────────┐│
│  │   Otwarte    │     Moje      ││
│  │              │   (aktywna)   ││
│  └──────────────┴───────────────┘│
│                                  │
│                                  │
│                                  │
│         🪐                       │
│                                  │
│    Nie masz jeszcze              │
│    żadnych planet.               │
│                                  │
│    Przejdź do "Otwarte"         │
│    i dołącz do planety!          │
│                                  │
│    [ PRZEGLĄDAJ OTWARTE ]        │
│                                  │
│                                  │
│                                  │
├──────────────────────────────────┤
│  🌍        🪐        🚀     👤  │
│ Globus    Kosmos    Statek  Profil│
└──────────────────────────────────┘

Komponenty

KomponentOpis
CosmosTabBarDwie zakładki: "Otwarte" i "Moje"
PlanetCardKarta planety: obrazek, nazwa, liczba uczniów, lokacji, opis
PlanetCard.openWariant z przyciskiem "DOŁĄCZ"
PlanetCard.joinedWariant z postępem + "ODKRYWAJ" / "OPUŚĆ"
JoinButtonPrzycisk dołączania (z loading state)
LeaveButtonPrzycisk opuszczania (z dialogiem potwierdzenia)
SearchBarPole wyszukiwania planet (ikona lupy w app bar)
EmptyStateViewWidok pustej listy z ikoną i CTA
InfiniteScrollListListView z lazy loading (cursor pagination)
PlanetCardSkeletonSkeleton loader karty planety

Logika

  1. Domyślna zakładka: "Otwarte"
  2. Lista planet — ListView.builder z infinite scroll (cursor pagination)
  3. "DOŁĄCZ" → POST /app/planets/:id/join → przeniesienie karty na "Moje"
  4. "OPUŚĆ" → dialog potwierdzenia → POST /app/planets/:id/leave → usunięcie z "Moje"
  5. "ODKRYWAJ" → nawigacja do /planet/:planetId (reuse MapScreen)
  6. Pull-to-refresh w obu zakładkach
  7. Wyszukiwarka → filtr po nazwie (lokalnie) lub API search (jeśli dostępny)

Dialog opuszczania planety

┌────────────────────────────────┐
│                                │
│  Opuścić planetę?              │
│                                │
│  Twój postęp zostanie          │
│  zachowany. Możesz wrócić      │
│  w każdej chwili.              │
│                                │
│  [ ANULUJ ]     [ OPUŚĆ ]     │
│                                │
└────────────────────────────────┘

Endpointy

MetodaEndpointOpis
GET/app/planets/openLista otwartych planet
GET/app/planets/mineLista moich planet
POST/app/planets/:id/joinDołącz do planety
POST/app/planets/:id/leaveOpuść planetę

Query params (lista):

ParamTypDomyślnieOpis
cursorstringKursor paginacji
limitint20Maks. elementów
searchstringWyszukiwanie po nazwie

Open Planets Response:

json
{
  "data": [
    {
      "id": "planet-nauka",
      "name": "Planeta Nauki",
      "description": "Planeta z zadaniami z matematyki i fizyki.",
      "image_url": "https://...",
      "member_count": 42,
      "location_count": 8,
      "created_by": "Szkoła Podstawowa nr 5"
    }
  ],
  "next_cursor": "eyJpZCI6MjB9",
  "has_more": true
}

My Planets Response:

json
{
  "data": [
    {
      "id": "planet-nauka",
      "name": "Planeta Nauki",
      "description": "Planeta z zadaniami z matematyki i fizyki.",
      "image_url": "https://...",
      "member_count": 42,
      "location_count": 8,
      "progress_percent": 75,
      "created_by": "Szkoła Podstawowa nr 5"
    }
  ],
  "next_cursor": null,
  "has_more": false
}

Join Response:

json
{
  "data": {
    "joined": true,
    "planet_id": "planet-nauka"
  }
}

Leave Response:

json
{
  "data": {
    "left": true,
    "planet_id": "planet-nauka"
  }
}

Stany Ekranu

StanWidok
ŁadowanieSkeleton karty planety (3 sztuki z shimmer)
DaneLista kart planet
Pusty (Otwarte)"Brak dostępnych planet"
Pusty (Moje)EmptyStateView z CTA do "Otwarte"
BłądErrorView z przyciskiem retry
Join loadingPrzycisk "DOŁĄCZ" z loading spinner
Leave loadingPrzycisk "OPUŚĆ" z loading spinner

Uwagi Techniczne

  • Osobne providery dla "Otwarte" i "Moje" — niezależna paginacja
  • Po join/leave → invalidacja obu list (ref.invalidate)
  • Optimistic update: po "DOŁĄCZ" karta od razu przenosi się na "Moje" (rollback przy błędzie)
  • Obrazki planet cachowane (CachedNetworkImage)
  • Tab state zachowany przy przełączaniu zakładek (scroll position per tab)

Lumos Islands v2 - Dokumentacja Projektowa