utils/sync_settings_ui/lib/src/sync_settings_widget.dart
Krzysztof kuhy Rudnicki 06ca32ce6d sync_settings_ui: split sync_settings_screen.dart 382 -> 192
sync_settings_widget.dart   68  — the public StatefulWidget and its callbacks
  sync_settings_sections.dart 132 — the two sections the screen composes
  sync_settings_screen.dart   192 — the State: loading, connecting, build

Uses `part`/`part of`, not imports: _FirebaseSection and _BackupSection are
library-private, so a sibling file cannot import them at all — extracting them
as ordinary files would not compile.

Two shapes tried and rejected on the way: an `extension _BackupActions` on the
State (an extension cannot call the protected setState), and moving build()
out of the class (it is an @override and has to stay). Both reverted from HEAD
rather than patched around.

flutter analyze clean, 29 tests pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CFSGeWxHPY5rHUGrPqhcmG
2026-08-22 15:38:58 +02:00

69 lines
2.9 KiB
Dart

part of 'sync_settings_screen.dart';
/// The shared "Sync settings" screen: Firebase sync (primary, shown by
/// default) and an optional local backup section.
///
/// Generalized from the near-identical settings screens duplicated across
/// the todo app, diet_guard_app, workout_app, wake_alarm/phone_app and
/// home_inventory. Only the sync-related fields migrate here -- app-specific
/// settings (kcal goals, exercise thresholds, notifications, the
/// battery-exemption toggle) stay behind in each app's own Settings screen,
/// reached via a `ListTile` link to this one.
class SyncSettingsScreen extends StatefulWidget {
/// Creates a [SyncSettingsScreen].
const SyncSettingsScreen({
required this.accountLoader,
required this.accountSaver,
required this.accountClearer,
required this.sessionProbe,
required this.firebaseFactory,
this.googleFirebaseFactory,
this.googleAvailable,
this.backup,
super.key,
});
/// Reads the stored Firebase account. Injected because the keystore is a
/// platform channel `flutter test` has no binding for.
final Future<FirebaseAccount?> Function() accountLoader;
/// Persists the account. See [accountLoader].
final Future<void> Function(FirebaseAccount) accountSaver;
/// Forgets the account and any cached session. See [accountLoader].
final Future<void> Function() accountClearer;
/// Whether a Firebase session is stored.
///
/// Separate from [accountLoader] because the two answer different
/// questions: the account marker is bookkeeping, the session is the
/// credential. A device can hold the second without the first, and
/// reporting only the first is what made a syncing phone read as
/// "not connected".
final Future<bool> Function() sessionProbe;
/// Builds the Firebase backend from the stored account. Injected so tests
/// can supply a fake.
final Future<FirebaseRestClient?> Function() firebaseFactory;
/// Builds the Firebase backend via Google sign-in. Separate from
/// [firebaseFactory] because it reaches the Google plugin's platform
/// channel. Null hides the "Sign in with Google" button entirely.
final Future<FirebaseRestClient?> Function()? googleFirebaseFactory;
/// Narrows whether to offer the Google button. Can only turn it off, never
/// on: the button always requires a non-null [googleFirebaseFactory]
/// regardless of this value, so a host that sets this true without also
/// wiring the factory does not get a button that can never succeed. Tests
/// pass `false` to model a platform that reports Google sign-in
/// unsupported even though a factory is wired.
final bool? googleAvailable;
/// Optional local export/import section. Null omits the "Backup" section
/// entirely (diet_guard, wake_alarm have no local backup format).
final BackupSlot? backup;
@override
State<SyncSettingsScreen> createState() => _SyncSettingsScreenState();
}