Fix parse app
This commit is contained in:
@@ -144,8 +144,9 @@ Active profile is stored in `app_preferences` (key `active_user_id`), read via
|
||||
`activeUserControllerProvider`. `appRouter` has a `redirect` callback + `refreshListenable`
|
||||
on this provider: until a user exists, all routes redirect to `/onboarding`; after
|
||||
`usersController.createUser`, the redirect clears and `UserSeeder.seedForNewUser(userId)`
|
||||
seeds default accounts, categories, and **demo transactions** (the demo seed is
|
||||
temporary — remove once add-transaction UX is finished).
|
||||
seeds default accounts and categories. Demo transactions are **not** auto-seeded — they're
|
||||
added only via the manual "seed demo" button in `profile_screen` (temporary; remove once
|
||||
add-transaction UX is finished).
|
||||
|
||||
Icon/color helpers that used to live in `_mock_data.dart` now live with their features:
|
||||
`features/categories/presentation/widgets/category_icon.dart` (`iconForCategory`,
|
||||
@@ -188,16 +189,25 @@ Icon/color helpers that used to live in `_mock_data.dart` now live with their fe
|
||||
|
||||
## What's left (priority order)
|
||||
|
||||
1. Analytics screen — `fl_chart` over transaction streams (analytics_screen + habit_analysis exist; expand charts)
|
||||
2. Remove demo transactions from `UserSeeder` once add-transaction flow is solid
|
||||
3. Persist theme/locale via `settingsController` (replace in-memory `themeModeController`);
|
||||
make `MaterialApp.router` read `locale` from settings
|
||||
4. Transfer transactions: fix balance aggregation (`case transfer: break;` in `month_summary.dart`)
|
||||
5. `shared/formatters/` — intl money + date formatters; migrate `MoneyText` + day grouping
|
||||
6. Expand test coverage (currently: transactions repo/controller/form, users controller, onboarding)
|
||||
1. Analytics screen — still a `PlaceholderScreen` hub (only the habit-analysis tile);
|
||||
`fl_chart` is not used anywhere in `analytics/` yet. Build charts over transaction streams.
|
||||
2. Persist **theme** via `settingsController`: `themeModeController` is still in-memory
|
||||
(`build() => ThemeMode.dark`) and `app.dart` reads it, not settings. The `settings.themeMode`
|
||||
column exists but is unused. Mirror `AppLocaleController` (locale is already persisted).
|
||||
3. Fully remove demo-transaction code from `UserSeeder` once the add-transaction flow is
|
||||
solid. Auto-seeding on user creation is already gone (`seedForNewUser` only seeds accounts
|
||||
+ categories); what remains is the manual path — `seedDemoTransactionsForUser` /
|
||||
`_seedDemoTransactions` + the "seed demo" button in `profile_screen`.
|
||||
4. `shared/formatters/` — empty; add intl money + date formatters; migrate `MoneyText` + day grouping.
|
||||
5. Expand test coverage (currently: transactions repo/controller/form, users controller, onboarding).
|
||||
|
||||
Done (was on this list): locale now persisted via settings (`AppLocaleController` reads
|
||||
`settingsStreamProvider`, `MaterialApp.router` reads `locale`); transfer balance aggregation is
|
||||
implemented in `month_summary.dart` (the `case transfer: break;` is the intentional "All accounts"
|
||||
branch — transfers count only when a specific account is selected).
|
||||
|
||||
## Open decisions (discuss before implementing)
|
||||
|
||||
- Transfer model: single record with `transferToAccountId` vs paired income+expense records
|
||||
- Transfer model: single record with `transferToAccountId` (current) vs paired income+expense records
|
||||
- Aggregates: client-side Provider (current) vs SQL `watchTotalsByCategory(period)` in DAO
|
||||
- `riverpod_lint`/`custom_lint`: re-add or keep omitted
|
||||
|
||||
+11
-8
@@ -4,21 +4,24 @@ import 'notification_parsing_providers.dart';
|
||||
|
||||
part 'notification_access_controller.g.dart';
|
||||
|
||||
/// Выдан ли доступ «Чтение уведомлений» (Android). На прочих платформах — false.
|
||||
@riverpod
|
||||
Future<bool> notificationAccessStatus(Ref ref) =>
|
||||
ref.watch(notificationListenerChannelProvider).isPermissionGranted();
|
||||
|
||||
/// Действия над разрешением: открыть системные настройки и обновить статус.
|
||||
/// Статус доступа «Чтение уведомлений» (Android; на прочих платформах — false)
|
||||
/// + действия: открыть системные настройки и перечитать статус.
|
||||
@riverpod
|
||||
class NotificationAccessController extends _$NotificationAccessController {
|
||||
@override
|
||||
void build() {}
|
||||
Future<bool> build() =>
|
||||
ref.watch(notificationListenerChannelProvider).isPermissionGranted();
|
||||
|
||||
/// Открывает системный экран «Доступ к уведомлениям».
|
||||
Future<void> openSettings() =>
|
||||
ref.read(notificationListenerChannelProvider).openSettings();
|
||||
|
||||
/// Перечитывает статус разрешения (например, после возврата из настроек).
|
||||
void refresh() => ref.invalidate(notificationAccessStatusProvider);
|
||||
/// `state = ...` вместо `ref.invalidate`: не задействует vsync-планировщик
|
||||
/// Riverpod, поэтому безопасно вызывать из `didChangeAppLifecycleState`.
|
||||
Future<void> refresh() async {
|
||||
state = await AsyncValue.guard(
|
||||
() => ref.read(notificationListenerChannelProvider).isPermissionGranted(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -185,7 +185,7 @@ class _NotificationAccessCardState
|
||||
|
||||
@override
|
||||
void didChangeAppLifecycleState(AppLifecycleState state) {
|
||||
if (state == AppLifecycleState.resumed) {
|
||||
if (state == AppLifecycleState.resumed && mounted) {
|
||||
ref.read(notificationAccessControllerProvider.notifier).refresh();
|
||||
}
|
||||
}
|
||||
@@ -194,7 +194,8 @@ class _NotificationAccessCardState
|
||||
Widget build(BuildContext context) {
|
||||
final p = context.palette;
|
||||
final l10n = context.l10n;
|
||||
final granted = ref.watch(notificationAccessStatusProvider).value ?? false;
|
||||
final granted =
|
||||
ref.watch(notificationAccessControllerProvider).value ?? false;
|
||||
|
||||
return _Card(
|
||||
children: [
|
||||
|
||||
@@ -21,7 +21,8 @@ UserSeeder userSeeder(Ref ref) => UserSeeder(
|
||||
);
|
||||
|
||||
/// Засевает базовый набор данных при создании нового пользователя:
|
||||
/// несколько счетов и категорий + демонстрационные транзакции.
|
||||
/// несколько счетов и категорий. Демо-транзакции автоматически НЕ создаются —
|
||||
/// их можно добавить вручную через [seedDemoTransactionsForUser] (кнопка в профиле).
|
||||
class UserSeeder {
|
||||
UserSeeder({
|
||||
required this.accountRepo,
|
||||
@@ -34,9 +35,8 @@ class UserSeeder {
|
||||
final TransactionRepository txRepo;
|
||||
|
||||
Future<void> seedForNewUser(String userId) async {
|
||||
final accounts = await _seedAccounts(userId);
|
||||
final categories = await _seedCategories(userId);
|
||||
await _seedDemoTransactions(userId, accounts, categories);
|
||||
await _seedAccounts(userId);
|
||||
await _seedCategories(userId);
|
||||
}
|
||||
|
||||
/// Добавляет демо-транзакции для существующего пользователя.
|
||||
|
||||
Reference in New Issue
Block a user