Files
noo/.claude/context/architecture.md
T
ayushyaandClaude Sonnet 5 0c877e619c Add CLAUDE.md with topic-specific context docs
Split project context into .claude/context/ (architecture, server,
styling, standards) instead of one large file, referenced from a
minimal root CLAUDE.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 00:25:53 -04:00

2.7 KiB

Architecture

Layout

lib/
  main.dart          # app root, theme wiring, top-level navigation switch
  models/             # plain data classes (NextcloudItem, NextcloudShare, ...)
  providers/           # ServerProvider — the single app-wide ChangeNotifier
  services/             # network/IO: NextcloudService, LoginFlowService
  theme/                 # AppTheme (Material 3 ThemeData)
  views/                  # one screen each (FilesView, PhotosView, ...)
  widgets/                 # reusable pieces shared across views
    details/                # the file-details bottom sheet and its tabs

views/ files are screens routed to directly (a tab, or pushed via Navigator). widgets/ files are building blocks used by more than one view (or complex enough to warrant their own file) — nothing in widgets/ owns app state itself; it reads it from the ServerProvider passed down or read via context.watch/context.read.

State management

There is exactly one ChangeNotifier: ServerProvider. It is created once in main() and provided at the root with provider's ChangeNotifierProvider. It owns:

  • auth/session state (isLoggedIn, isRestoringSession, login-flow status)
  • the active NextcloudService instance (null until logged in)
  • all fetched data (items, quota, activities)
  • navigation-within-files state (currentFolderPath, pathStack)
  • UI settings that persist across launches (theme mode, seed color, dynamic color toggle, bottom-bar opacity/blur, sort/filter/view-mode prefs)

New app-wide state belongs on ServerProvider as a private field + getter + a method that mutates it and calls notifyListeners(). Screen-local state (e.g. a TextEditingController, an expanded/collapsed flag) stays in that view's own State class — see standards.md for the split.

There's no separate repository/data layer: views call ServerProvider methods directly, which call NextcloudService/LoginFlowService.

Navigation / screen flow

main.dart's NextcloudApp picks the app's home screen from provider state, no named routes:

  • provider.isRestoringSession → _SplashView (spinner while flutter_secure_storage/shared_preferences are read on startup)
  • else !provider.isLoggedIn → LoginView (server-address entry + Login Flow v2)
  • else MainShellView

MainShellView is a bottom-nav IndexedStack with three persistent tabs — Files, Photos, Activity — each keeping its own ScrollController so state (scroll position, IndexedStack's built-but-hidden trees) survives tab switches. SearchView and the file-details sheet are pushed on top via Navigator/showModalBottomSheet rather than being tabs.