57 lines
2.6 KiB
Dart
57 lines
2.6 KiB
Dart
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
|
|
import '../../features/notification_parsing/application/inbox_controller.dart';
|
|
import '../../features/notification_parsing/application/notification_ingest_worker.dart';
|
|
import '../../features/notification_parsing/application/parsing_settings_controller.dart';
|
|
import '../../features/notification_parsing/application/parsing_worker.dart';
|
|
import '../../features/user/application/active_user_controller.dart';
|
|
import 'app_bottom_nav.dart';
|
|
|
|
class AppScaffold extends ConsumerWidget {
|
|
const AppScaffold({super.key, required this.navigationShell});
|
|
|
|
final StatefulNavigationShell navigationShell;
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
// Активируем ParsingWorker (keepAlive) на уровне оболочки, чтобы очередь
|
|
// парсинга драйнилась на любой вкладке, пока приложение открыто, — а не
|
|
// только при заходе на «Главную». До появления активного пользователя
|
|
// (/onboarding вне shell) активировать нечего.
|
|
final userId = ref.watch(activeUserControllerProvider).value?.id;
|
|
if (userId != null) {
|
|
ref.watch(parsingWorkerProvider(userId));
|
|
// Нативный слушатель уведомлений — только Android.
|
|
if (defaultTargetPlatform == TargetPlatform.android) {
|
|
ref.watch(notificationIngestWorkerProvider(userId));
|
|
}
|
|
}
|
|
|
|
// `?? false` совпадает с дефолтом ParsingSettings.enabled — без мигания
|
|
// вкладки на кадре первой загрузки настроек (см. redirect в app_router).
|
|
final showInbox =
|
|
ref.watch(parsingSettingsControllerProvider).value?.enabled ?? false;
|
|
// Watch на уровне шелла заодно держит autoDispose-стрим счётчика живым
|
|
// на всех вкладках (раньше это делал колокольчик в MonthHeader).
|
|
final inboxCount = userId == null
|
|
? 0
|
|
: (ref.watch(inboxCountProvider(userId)).value ?? 0);
|
|
|
|
return Scaffold(
|
|
body: navigationShell,
|
|
bottomNavigationBar: AppBottomNav(
|
|
activeIndex: navigationShell.currentIndex,
|
|
onTap: (i) => navigationShell.goBranch(
|
|
i,
|
|
initialLocation: i == navigationShell.currentIndex,
|
|
),
|
|
showInbox: showInbox,
|
|
inboxCount: inboxCount,
|
|
),
|
|
);
|
|
}
|
|
}
|