Skip to content

Ekran — Mapa Kraju

Przegląd

Mapa kraju to ilustrowany widok 2D z pinezkami reprezentującymi lokacje w danym świecie (kraju). Pinezki mają trzy stany: zablokowana (szara), odblokowana (kolorowa), ukończona (złota gwiazdka). Dziecko tapuje pinezkę, żeby przejść do ekranu lokacji.

Routing (GoRouter)

dart
GoRoute(
  path: '/world/:worldId',
  builder: (context, state) => MapScreen(
    worldId: state.pathParameters['worldId']!,
  ),
),

Riverpod Providers

dart
// Szczegóły świata (nazwa, opis, tło mapy)
final worldDetailProvider = FutureProvider.family<World, String>((ref, worldId) {
  return ref.watch(worldRepositoryProvider).getWorld(worldId);
});

// Lista lokacji na mapie
final worldLocationsProvider = FutureProvider.family<List<Location>, String>((ref, worldId) {
  return ref.watch(worldRepositoryProvider).getLocations(worldId);
});

// Aktualnie wybrana lokacja (po tapnięciu pinu)
final selectedLocationProvider = StateProvider<Location?>((ref) => null);

ASCII Wireframe

┌──────────────────────────────────┐
│  ← Polska                  🇵🇱  │
├──────────────────────────────────┤
│                                  │
│  ┌────────────────────────────┐  │
│  │                            │  │
│  │   (ilustrowana mapa)       │  │
│  │                            │  │
│  │      🔒          ⭐        │  │
│  │    Fabryka     Biblioteka   │  │
│  │                            │  │
│  │           📍               │  │
│  │         Camp               │  │
│  │                            │  │
│  │     📍            🔒      │  │
│  │   Boisko        Muzeum     │  │
│  │                            │  │
│  │              📍            │  │
│  │           Park             │  │
│  │                            │  │
│  └────────────────────────────┘  │
│                                  │
│  Legenda:                        │
│  📍 Odblokowana  ⭐ Ukończona   │
│  🔒 Zablokowana                 │
│                                  │
│  Lokacje: 3/5 odblokowane       │
│  Postęp: ████████░░ 60%         │
│                                  │
└──────────────────────────────────┘

Stan po tapnięciu pinezki

┌──────────────────────────────────┐
│  ← Polska                  🇵🇱  │
├──────────────────────────────────┤
│                                  │
│  ┌────────────────────────────┐  │
│  │                            │  │
│  │   (mapa przygaszona)       │  │
│  │                            │  │
│  │           [📍]             │  │
│  │          (pulsuje)         │  │
│  │                            │  │
│  └────────────────────────────┘  │
│                                  │
│  ┌────────────────────────────┐  │
│  │                            │  │
│  │  📍 Camp Odkrywców         │  │
│  │                            │  │
│  │  🎬 3 video  📝 5 quizów   │  │
│  │  🎧 2 podcasty  🎮 1 gra   │  │
│  │                            │  │
│  │  Postęp: ████░░░░ 40%     │  │
│  │  XP do zdobycia: 450      │  │
│  │                            │  │
│  │  [ WEJDŹ → ]              │  │
│  │                            │  │
│  └────────────────────────────┘  │
│                                  │
└──────────────────────────────────┘

Pinezka zablokowana — tap

┌────────────────────────────────┐
│                                │
│  🔒 Fabryka Wynalazków         │
│                                │
│  Żeby odblokować tę lokację,  │
│  ukończ 3 zadania w Camp       │
│  Odkrywców.                    │
│                                │
│  Postęp: ██░░░░ 1/3           │
│                                │
│  [ OK ]                        │
│                                │
└────────────────────────────────┘

Komponenty

KomponentOpis
MapViewWidok mapy: ilustrowane tło + pinezki. Obsługuje pan i zoom
LocationPinPinezka na mapie — 3 warianty wizualne
LocationPin.lockedSzara pinezka z ikoną kłódki
LocationPin.unlockedKolorowa pinezka (kolor zależny od typu lokacji)
LocationPin.completedZłota pinezka z gwiazdką
LocationInfoCardBottom sheet z informacjami o lokacji po tapnięciu pinu
LockedInfoDialogDialog wyjaśniający warunki odblokowania
MapAppBarApp bar z przyciskiem back, nazwą kraju i flagą
ProgressBarPasek postępu świata (% ukończonych lokacji)
MapLegendLegenda stanów pinezek

Logika

  1. Przy wejściu — pobranie danych świata (GET /app/worlds/:id) i lokacji (GET /app/worlds/:id/locations)
  2. Pinezki rozmieszczone na mapie na podstawie współrzędnych x, y (0.0 - 1.0, relatywne do tła)
  3. Tap na odblokowaną pinezkę → LocationInfoCard (bottom sheet)
  4. Tap na zablokowaną pinezkę → LockedInfoDialog z warunkami odblokowania
  5. Przycisk "WEJDŹ" → nawigacja do /location/:locationId
  6. Przycisk back → powrót na globus (context.pop())

Warunki odblokowania lokacji

Lokacje mogą być blokowane na podstawie:

  • Ukończenia N zadań w innej lokacji
  • Osiągnięcia określonego poziomu XP
  • Ukończenia konkretnego zadania (quest chain)

Warunki przychodzą z API w polu unlock_conditions.

Endpointy

MetodaEndpointOpis
GET/app/worlds/:idSzczegóły świata (nazwa, opis, mapa)
GET/app/worlds/:id/locationsLista lokacji na mapie

World Response:

json
{
  "data": {
    "id": "world-pl",
    "name": "Polska",
    "flag_emoji": "🇵🇱",
    "description": "Odkryj najpiękniejsze miejsca w Polsce!",
    "map_background_url": "https://...",
    "location_count": 5,
    "completed_count": 2,
    "progress_percent": 40
  }
}

Locations Response:

json
{
  "data": [
    {
      "id": "loc-camp",
      "name": "Camp Odkrywców",
      "type": "camp",
      "status": "unlocked",
      "x": 0.45,
      "y": 0.55,
      "task_summary": {
        "video": 3,
        "quiz": 5,
        "podcast": 2,
        "game": 1,
        "creative": 0
      },
      "progress_percent": 40,
      "xp_available": 450,
      "thumbnail_url": "https://..."
    },
    {
      "id": "loc-factory",
      "name": "Fabryka Wynalazków",
      "type": "factory",
      "status": "locked",
      "x": 0.20,
      "y": 0.25,
      "unlock_conditions": {
        "type": "tasks_completed",
        "location_id": "loc-camp",
        "required": 3,
        "current": 1
      },
      "thumbnail_url": "https://..."
    },
    {
      "id": "loc-library",
      "name": "Biblioteka",
      "type": "library",
      "status": "completed",
      "x": 0.75,
      "y": 0.20,
      "task_summary": {
        "video": 2,
        "quiz": 4,
        "podcast": 1,
        "game": 0,
        "creative": 1
      },
      "progress_percent": 100,
      "xp_available": 0,
      "thumbnail_url": "https://..."
    }
  ]
}

Stany Pinezek

StatusWyglądInterakcja
lockedSzara ikona z kłódką, cień minimalnyTap → LockedInfoDialog
unlockedKolorowa ikona (brand-primary), cień, lekka animacja pulsowaniaTap → LocationInfoCard
completedZłota ikona z gwiazdką, efekt shimmerTap → LocationInfoCard (z odznaką ukończenia)

Stany Ekranu

StanWidok
ŁadowanieMapa z skeleton pinezkami (pulsujące kółka)
DanePełna mapa z pinezkami w odpowiednich stanach
BłądMapa bez pinezek + ErrorView z przyciskiem retry

Uwagi Techniczne

  • Tło mapy to ilustracja (PNG/SVG) dostarczona przez API (map_background_url)
  • Pinezki pozycjonowane za pomocą Stack + Positioned (fractional coordinates)
  • Pan i zoom obsługiwane przez InteractiveViewer
  • Animacja wejścia pinezek — pojawiają się sekwencyjnie (staggered animation, 50ms delay)
  • Cache tła mapy w pamięci (CachedNetworkImage)

Lumos Islands v2 - Dokumentacja Projektowa