Skip to content

Ekran — Wykonanie Zadania ​

Przegląd ​

Ekran wykonania zadania obsługuje 5 typow zadan, kazdy z dedykowanym layoutem: quiz, video, podcast, kreatywne, gra. Wszystkie typy dzielą wspólny progress bar, podgląd XP do zdobycia oraz animację ukończenia (confetti, XP, odznaka, level up).

Routing (GoRouter) ​

dart
GoRoute(
  path: '/task/:taskId',
  builder: (context, state) => TaskScreen(
    taskId: state.pathParameters['taskId']!,
  ),
),

Riverpod Providers ​

dart
// Pełne dane zadania
final taskDetailProvider = FutureProvider.family<TaskDetail, String>((ref, taskId) {
  return ref.watch(taskRepositoryProvider).getTask(taskId);
});

// Stan wykonania zadania (odpowiedzi, postęp)
final taskProgressProvider = StateNotifierProvider.family<TaskProgressNotifier, TaskProgress, String>(
  (ref, taskId) => TaskProgressNotifier(taskId),
);

// Aktualny krok/pytanie w zadaniu
final currentStepProvider = StateProvider.family<int, String>((ref, taskId) => 0);

// Wynik po ukończeniu (XP, badge, level up)
final taskResultProvider = StateProvider<TaskResult?>((ref) => null);

// Stan audio/video playera
final mediaPlayerProvider = StateNotifierProvider<MediaPlayerNotifier, MediaPlayerState>(
  (ref) => MediaPlayerNotifier(),
);

Layouty per Typ Zadania ​

1. Quiz ​

┌──────────────────────────────────┐
│  ← Quiz                    ✕    │
├──────────────────────────────────┤
│  ████████░░░░░░░░ 4/10          │
│                                  │
│  +50 XP                         │
│                                  │
│  ┌────────────────────────────┐  │
│  │  Pytanie 4:                │  │
│  │                            │  │
│  │  Jak nazywa się najwyższa  │  │
│  │  góra w Polsce?            │  │
│  │                            │  │
│  │  (opcjonalnie: obrazek)    │  │
│  └────────────────────────────┘  │
│                                  │
│  ┌────────────────────────────┐  │
│  │  ○  Rysy                   │  │
│  └────────────────────────────┘  │
│  ┌────────────────────────────┐  │
│  │  ○  Giewont                │  │
│  └────────────────────────────┘  │
│  ┌────────────────────────────┐  │
│  │  ●  Śnieżka        ← wyb. │  │
│  └────────────────────────────┘  │
│  ┌────────────────────────────┐  │
│  │  ○  Kasprowy Wierch        │  │
│  └────────────────────────────┘  │
│                                  │
│  [ SPRAWDŹ ]                     │
│                                  │
└──────────────────────────────────┘

Po sprawdzeniu (poprawna):

┌──────────────────────────────────┐
│  ┌────────────────────────────┐  │
│  │  ✅ Rysy         ← poprawna│  │
│  └────────────────────────────┘  │
│  ┌────────────────────────────┐  │
│  │  ○  Giewont                │  │
│  └────────────────────────────┘  │
│  ┌────────────────────────────┐  │
│  │  ❌ Śnieżka       ← błędna│  │
│  └────────────────────────────┘  │
│  ┌────────────────────────────┐  │
│  │  ○  Kasprowy Wierch        │  │
│  └────────────────────────────┘  │
│                                  │
│  💡 Rysy (2499 m) to najwyższy  │
│  szczyt w polskich Tatrach.      │
│                                  │
│  [ NASTĘPNE → ]                  │
└──────────────────────────────────┘

2. Video ​

┌──────────────────────────────────┐
│  ← Video                   ✕    │
├──────────────────────────────────┤
│                                  │
│  ┌────────────────────────────┐  │
│  │                            │  │
│  │                            │  │
│  │     ▶  (video player)     │  │
│  │                            │  │
│  │                            │  │
│  │  ▶ ████████░░ 5:32 / 8:00 │  │
│  └────────────────────────────┘  │
│                                  │
│  Dinozaury i ich świat           │
│  +50 XP                         │
│                                  │
│  ── Po obejrzeniu ──             │
│                                  │
│  Pytanie 1/3:                    │
│  Kiedy wyginęły dinozaury?       │
│                                  │
│  ○ 65 mln lat temu               │
│  ○ 100 mln lat temu              │
│  ○ 10 mln lat temu               │
│                                  │
│  [ SPRAWDŹ ]                     │
│                                  │
└──────────────────────────────────┘

3. Podcast ​

┌──────────────────────────────────┐
│  ← Podcast                 ✕    │
├──────────────────────────────────┤
│  ████████████████ ukończony      │
│                                  │
│  ┌────────────────────────────┐  │
│  │                            │  │
│  │      (cover art)           │  │
│  │                            │  │
│  └────────────────────────────┘  │
│                                  │
│  Tajemnice oceanu                │
│  +30 XP                         │
│                                  │
│  ┌────────────────────────────┐  │
│  │  ◀◀   ▶ / ⏸   ▶▶         │  │
│  │  ████████░░░░ 12:30/20:00 │  │
│  │  1x  1.5x  2x             │  │
│  └────────────────────────────┘  │
│                                  │
│  📜 Transkrypt                   │
│  ┌────────────────────────────┐  │
│  │ [12:30] Oceany pokrywają   │  │
│  │ ponad 70% powierzchni      │  │
│  │ Ziemi. W głębinach żyją    │  │
│  │ stworzenia, których...     │  │
│  │                            │  │
│  │ [13:15] Najgłębszy punkt   │  │
│  │ to Rów Mariański...        │  │
│  └────────────────────────────┘  │
│                                  │
│  [ UKOŃCZ PODCAST ]              │
│                                  │
└──────────────────────────────────┘

4. Zadanie Kreatywne ​

┌──────────────────────────────────┐
│  ← Kreatywne                ✕   │
├──────────────────────────────────┤
│  +40 XP                         │
│                                  │
│  Narysuj swoje wymarzone         │
│  zwierzę!                        │
│                                  │
│  Opisz, jakie ma cechy           │
│  i gdzie mieszka.                │
│                                  │
│  ┌────────────────────────────┐  │
│  │                            │  │
│  │  Wybierz sposób:           │  │
│  │                            │  │
│  │  ┌──────┐ ┌──────┐        │  │
│  │  │  📷  │ │  🎨  │        │  │
│  │  │Zdjęcie│ │Rysunek│       │  │
│  │  └──────┘ └──────┘        │  │
│  │  ┌──────┐                 │  │
│  │  │  📝  │                 │  │
│  │  │ Tekst│                 │  │
│  │  └──────┘                 │  │
│  │                            │  │
│  └────────────────────────────┘  │
│                                  │
│  ┌────────────────────────────┐  │
│  │ Opis (opcjonalnie):       │  │
│  │ _________________________ │  │
│  │ _________________________ │  │
│  └────────────────────────────┘  │
│                                  │
│  [ WYŚLIJ PRACĘ ]                │
│                                  │
└──────────────────────────────────┘

5. Mini-gra ​

┌──────────────────────────────────┐
│  ← Gra                     ✕    │
├──────────────────────────────────┤
│  Labirynt Wiedzy       +60 XP   │
│                                  │
│  ┌────────────────────────────┐  │
│  │                            │  │
│  │                            │  │
│  │                            │  │
│  │   (embedded mini-game      │  │
│  │    WebView / Flutter       │  │
│  │    canvas / Flame)         │  │
│  │                            │  │
│  │                            │  │
│  │                            │  │
│  │                            │  │
│  │                            │  │
│  │                            │  │
│  │                            │  │
│  └────────────────────────────┘  │
│                                  │
│  Czas: 02:45    Wynik: 850      │
│                                  │
└──────────────────────────────────┘

Animacja Ukończenia ​

Po zakończeniu zadania (dowolny typ) wyświetlany jest ekran z wynikami:

┌──────────────────────────────────┐
│                                  │
│        🎉 CONFETTI 🎉           │
│                                  │
│                                  │
│          ⭐ ŚWIETNIE! ⭐         │
│                                  │
│                                  │
│       ┌──────────────┐           │
│       │   +50 XP     │           │
│       └──────────────┘           │
│                                  │
│       XP: 1240 → 1290           │
│       ██████████████░░ Lvl 5     │
│                                  │
│  ┌────────────────────────────┐  │
│  │  🏅 Nowa odznaka!          │  │
│  │  "Odkrywca Dinozaurów"     │  │
│  └────────────────────────────┘  │
│                                  │
│  ┌────────────────────────────┐  │
│  │  🎉 LEVEL UP!              │  │
│  │  Poziom 5 → 6              │  │
│  └────────────────────────────┘  │
│                                  │
│  [ KONTYNUUJ ]                   │
│                                  │
└──────────────────────────────────┘

Komponenty ​

Wspólne (wszystkie typy) ​

KomponentOpis
TaskAppBarApp bar z nazwą typu, przyciskiem back i close
TaskProgressBarPasek postępu (np. pytanie 4/10)
XpPreviewBadge "+50 XP" widoczny podczas zadania
CompletionOverlayPełnoekranowy overlay z wynikami po ukończeniu
ConfettiAnimationAnimacja confetti (particle system)
XpCounterAnimowany licznik XP (count up)
BadgeEarnedCardKarta zdobytej odznaki
LevelUpCardKarta awansu na wyższy poziom
CloseConfirmDialog"Czy na pewno chcesz wyjść? Postęp zostanie zapisany."

Quiz ​

KomponentOpis
QuestionCardTreść pytania (tekst + opcjonalny obrazek)
AnswerOptionOpcja odpowiedzi (radio — single choice, checkbox — multi choice)
AnswerFeedbackFeedback: poprawna (zielona), błędna (czerwona) + wyjaśnienie
CheckButtonPrzycisk "SPRAWDŹ" (aktywny po wybraniu odpowiedzi)
NextButtonPrzycisk "NASTĘPNE" (po sprawdzeniu)

Video ​

KomponentOpis
VideoPlayerPlayer z kontrolkami (play/pause, seek, fullscreen)
VideoProgressBarPasek postępu video
ComprehensionQuizQuiz wyświetlany po obejrzeniu (reuse QuestionCard + AnswerOption)

Podcast ​

KomponentOpis
AudioPlayerPlayer: play/pause, prev/next 15s, seek bar
SpeedSelectorWybór prędkości: 1x, 1.5x, 2x
CoverArtOkładka podcastu
TranscriptViewPrzewijalny transkrypt z timestampami (auto-scroll do aktualnego)

Kreatywne ​

KomponentOpis
CreativePromptTreść polecenia
InputMethodPickerWybór: zdjęcie, rysunek, tekst
CameraCaptureEkran aparatu (camera plugin)
DrawingCanvasProsty canvas do rysowania (CustomPainter)
TextInputPole tekstowe (multiline)
SubmitButtonPrzycisk "WYŚLIJ PRACĘ"

Mini-gra ​

KomponentOpis
GameContainerKontener gry (WebView lub Flutter canvas / Flame)
GameHUDCzas, wynik, życia (overlay nad grą)
GameOverScreenEkran końca gry z wynikiem

Logika ​

Przepływ ogólny ​

  1. Wejście na ekran → GET /app/tasks/:id (pobranie danych)
  2. POST /app/tasks/:id/start (oznaczenie rozpoczęcia, timestamp)
  3. Wykonanie zadania (quiz, video, itp.)
  4. POST /app/tasks/:id/complete (wysyłka wyników) lub POST /app/tasks/:id/submit-creative
  5. Animacja ukończenia (confetti, XP, badge, level up)
  6. Przycisk "KONTYNUUJ" → powrót do lokacji (context.pop())

Quiz — szczegóły ​

  • Single choice: radio buttons, 1 poprawna odpowiedź
  • Multi choice: checkboxy, 1+ poprawnych odpowiedzi
  • Po "SPRAWDŹ" → feedback (poprawna/błędna) + wyjaśnienie
  • Nawet przy błędnej odpowiedzi → przejście dalej (nauka, nie egzamin)
  • Wynik = poprawne / wszystkie (przesyłany w complete)

Video — szczegóły ​

  • Video musi być obejrzane w min. 90% żeby odblokować quiz
  • Quiz (comprehension) po obejrzeniu: 2-3 pytania
  • Jeśli brak quizu → video samo w sobie jest wystarczające

Zadanie kreatywne — szczegóły ​

  • Upload: zdjęcie (JPEG, max 5MB), rysunek (PNG z canvas), tekst
  • Wysyłka jako multipart/form-data na /app/tasks/:id/submit-creative
  • Brak automatycznej oceny — review przez rodzica/moderatora (async)
  • XP przyznawane za wysłanie (nie za ocenę)

Endpointy ​

MetodaEndpointOpis
GET/app/tasks/:idPełne dane zadania
POST/app/tasks/:id/startOznacz rozpoczęcie
POST/app/tasks/:id/completeUkończ zadanie (wynik)
POST/app/tasks/:id/submit-creativeWyślij pracę kreatywną

Task Detail Response (quiz):

json
{
  "data": {
    "id": "task-q1",
    "title": "Zwierzęta Polski",
    "type": "quiz",
    "xp_reward": 40,
    "thumbnail_url": "https://...",
    "questions": [
      {
        "id": "q1",
        "text": "Jak nazywa się najwyższa góra w Polsce?",
        "image_url": null,
        "type": "single_choice",
        "answers": [
          { "id": "a1", "text": "Rysy" },
          { "id": "a2", "text": "Giewont" },
          { "id": "a3", "text": "Śnieżka" },
          { "id": "a4", "text": "Kasprowy Wierch" }
        ],
        "correct_answer_ids": ["a1"],
        "explanation": "Rysy (2499 m) to najwyższy szczyt w polskich Tatrach."
      }
    ]
  }
}

Task Detail Response (video):

json
{
  "data": {
    "id": "task-v1",
    "title": "Dinozaury i ich świat",
    "type": "video",
    "xp_reward": 50,
    "video_url": "https://...",
    "duration_seconds": 480,
    "thumbnail_url": "https://...",
    "comprehension_questions": [
      {
        "id": "cq1",
        "text": "Kiedy wyginęły dinozaury?",
        "type": "single_choice",
        "answers": [
          { "id": "a1", "text": "65 mln lat temu" },
          { "id": "a2", "text": "100 mln lat temu" },
          { "id": "a3", "text": "10 mln lat temu" }
        ],
        "correct_answer_ids": ["a1"]
      }
    ]
  }
}

Complete Request:

json
{
  "score": 8,
  "max_score": 10,
  "answers": [
    { "question_id": "q1", "answer_ids": ["a1"] },
    { "question_id": "q2", "answer_ids": ["a3"] }
  ],
  "duration_seconds": 245
}

Complete Response:

json
{
  "data": {
    "xp_earned": 50,
    "total_xp": 1290,
    "level_before": 5,
    "level_after": 6,
    "level_up": true,
    "badges_earned": [
      {
        "id": "badge-dino",
        "name": "Odkrywca Dinozaurów",
        "icon_url": "https://...",
        "description": "Ukończ wszystkie zadania o dinozaurach"
      }
    ]
  }
}

Submit Creative Request (multipart):

POST /app/tasks/:id/submit-creative
Content-Type: multipart/form-data

file: (binary — image/jpeg, image/png)
description: "Moje wymarzone zwierzę to smok..."
input_type: "photo" | "drawing" | "text"

Stany Ekranu ​

StanWidok
ŁadowanieSkeleton z shimmer
W trakcieLayout odpowiedni dla typu zadania
ZakończoneCompletionOverlay z wynikami
BłądErrorView z przyciskiem retry
WychodzenieCloseConfirmDialog (jeśli zadanie w trakcie)

Uwagi Techniczne ​

  • Video player: video_player + chewie (kontrolki)
  • Audio player: just_audio + custom UI
  • Rysunek: CustomPainter z GestureDetector (kolorowe pędzle, gumka, cofnij)
  • Mini-gry: flutter_inappwebview (WebView) lub Flame engine (natywne)
  • Upload plików: Dio multipart + progress indicator
  • Postęp quizu zapisywany lokalnie (na wypadek przerwania) — sync z serwerem przy complete
  • WillPopScope / PopScope → dialog potwierdzenia wyjścia

Lumos Islands v2 - Dokumentacja Projektowa