| j / k | Scroll down / up |
| gg | Scroll to top |
| G | Scroll to bottom |
| ⌘K / / | Open search |
| ? | Show this help |
| Esc | Close search / help |
| n / N | Next / previous section |
| h | Go to landing |
| d | Go to docs |
| : | Command mode — type section name |
Press ? or Esc to close
A few deliberate choices keep the app smooth. None are clever — they are just consistent.
Large responses parse on a background isolate when the Store is created with shouldIsolate: true. The UI thread never blocks on fromJson.
Future<ApiResponse<T, void>> execute<T>({
required Future<Response> Function() request,
required T Function(dynamic) parser,
required T empty,
bool shouldIsolate = false,
}) async {
final response = await request();
final parsed = shouldIsolate
? await Isolate.run(() => parser(response.data))
: parser(response.data);
return ApiResponse.initial(data: parsed).success(data: parsed);
} StatefulShellRoute.indexedStack keeps every tab's widget tree alive. Switching tabs is instant — no rebuild, no refetch.
Most stores and data sources are registerLazySingleton. They are constructed on first use, not at startup, so cold launch stays fast.
Inner tabs and heavy lists use KeepAliveWrapper so they are not disposed when scrolled out of an indexed stack or page view.
KeepAliveWrapper(
child: const HeavyList(),
) | Where | Mechanism |
|---|---|
| TipTap images | Custom CacheManager |
| Avatars / feed | CachedNetworkImage |
| Local media | File cache via MediaUploadStore |