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>
60 lines
2.7 KiB
Markdown
60 lines
2.7 KiB
Markdown
# 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`](../../lib/providers/server_provider.dart).
|
|
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.
|