Files
Client/CLAUDE.md
T

4.6 KiB
Raw Blame History

MarianumMobile Client

Flutter-App für die Schul-Community: Webuntis-Stundenplan, Nextcloud Talk + Files, Custom MHSL-Backend (Breaker, Custom Events, Push).

Stack

  • Flutter (Dart >= 3.8)
  • State: flutter_bloc + hydrated_bloc (persistente BLoCs pro Modul)
  • Navigation: persistent_bottom_nav_bar_v2 mit zentraler AppRoutes-Klasse als Single Entry Point
  • HTTP: dio, lokales Caching via localstore (Generic RequestCache<T>)
  • Calendar: syncfusion_flutter_calendar
  • Datum/Zeit: jiffy wird nur über die Extensions in lib/extensions/date_time.dart verwendet
  • Code-Gen: freezed, json_serializable

Ordnerstruktur

lib/
├── api/                    HTTP-Layer pro Backend (mhsl/, marianumcloud/, webuntis/, holidays/)
├── state/app/modules/      BLoC pro Feature-Modul (timetable, chat, chat_list, files, ...)
├── state/app/infrastructure LoadableState<T>, DataLoader, geteilte BLoC-Bausteine
├── view/                   Screens
│   ├── login/              Login-Flow
│   └── pages/              ein Verzeichnis pro Modul (timetable, files, talk, ...)
├── widget/                 Geteilte UI-Komponenten (Dialoge, Buttons, Sheets)
├── extensions/             DateTime-, Text-, TimeOfDay-Extensions
├── routing/                AppRoutes (Single Navigation Entry)
├── theming/                Light/Dark Theme
├── storage/                Freezed Settings-Modelle (HydratedBloc-persistent)
├── notification/           Firebase + flutter_local_notifications
└── utils/                  Helper (clipboard_helper, debouncer, download_manager, ...)

Konventionen

Navigation: Ausschließlich über AppRoutes.openX(context, ...). Direkte Navigator.push(...) für volle Pages sind nicht erlaubt Navigator.pop für Sheets/Dialogs bleibt am Call-Site.

Dialoge:

  • Info/Fehler: InfoDialog.show(context, body, copyable: true, title: '...') aus lib/widget/info_dialog.dart.
  • Bestätigung: ConfirmDialog(...).asDialog(context) aus lib/widget/confirm_dialog.dart. Async-Bestätigung nutzt onConfirmAsync (zeigt Spinner und Inline-Fehler über AsyncDialogAction).
  • Kein inline AlertDialog/SimpleDialog mehr.

Bottom-Sheets: Detail-Sheets gehen über showDetailsBottomSheet(context, header: ..., children: (ctx) => [...]) aus lib/widget/details_bottom_sheet.dart. Header ist optional.

Async-Actions: Statt manuelles Spinner+Try/Catch die AsyncActionButton-Familie aus lib/widget/async_action_button.dart (AsyncActionButton, AsyncTextButton, AsyncIconButton, AsyncFab, AsyncListTile, AsyncDialogAction, runWithErrorDialog). Fehler-Mapping läuft über errorBuilder oder zentral über errorToUserMessage aus lib/api/errors/error_mapper.dart.

Clipboard: Über copyToClipboard(context, text) aus lib/utils/clipboard_helper.dart. Zeigt automatisch SnackBar.

Datum/Zeit-Formatierung: Über die Extensions in lib/extensions/date_time.dart: dt.formatHm(), dt.formatDate(), dt.formatDateTime(), dt.formatDateShort(), dt.formatRelative(), start.timeRangeTo(end). Kein direktes Jiffy.parseFromDateTime(...).format(pattern: '...') im View-Code.

Settings: Pro Feature ein Freezed-Modell unter lib/storage/, persistiert via HydratedBloc.

Build / Run

flutter pub get
dart run build_runner build --delete-conflicting-outputs   # nach Änderungen an Freezed/JSON-Modellen
flutter run                                                  # Debug auf angeschlossenem Device
flutter analyze                                              # statische Analyse, muss 0 Issues melden
flutter test                                                 # Tests (siehe test/)

Backend-Integrationen

Backend Pfad Zweck
Webuntis lib/api/webuntis/ Stundenplan, Klassen, Räume, Lehrer
Nextcloud (Talk + WebDAV) lib/api/marianumcloud/ Chats, Datei-Verwaltung
Custom MHSL-Server lib/api/mhsl/ Breaker, Custom Events, Notify, Noten
Holiday-Calendar lib/api/holidays/ Ferien

nextcloud-Paket ist auf einen Custom-Fork gepinnt (siehe pubspec.yaml dependency_overrides).

Tests

test/ deckt aktuell nur Kern-Funktionen ab (DateTime-Extensions, AsyncActionController, LessonResolver). Beim Hinzufügen neuer pure-function-Helper bitte Test mit dazu.