feat: Add auto-sync, fix partner linking UI, update sharing settings

- Add 10-second periodic auto-sync to CycleEntriesNotifier
- Fix husband_devotional_screen: use partnerId for isConnected check, navigate to SharingSettingsScreen instead of legacy mock dialog
- Remove obsolete _showConnectDialog method and mock data import
- Update husband_settings_screen: show 'Partner Settings' with linked partner name when connected
- Add SharingSettingsScreen: Pad Supplies toggle (disabled when pad tracking off), Intimacy always enabled
- Add CORS OPTIONS handler to backend server
- Add _ensureServerRegistration for reliable partner linking
- Add copy button to Invite Partner dialog
- Dynamic base URL for web (uses window.location.hostname)
This commit is contained in:
2026-01-09 17:20:49 -06:00
parent d28898cb81
commit 1c2c56e9e2
21 changed files with 1690 additions and 493 deletions

View File

@@ -9,6 +9,9 @@ import '../../services/notification_service.dart';
import '../../providers/user_provider.dart';
import '../../widgets/protected_wrapper.dart';
// Global flag to track if the check-in dialog has been shown this session
bool _hasShownCheckInSession = false;
class PadTrackerScreen extends ConsumerStatefulWidget {
final FlowIntensity? initialFlow;
final bool isSpotting;
@@ -81,7 +84,15 @@ class _PadTrackerScreenState extends ConsumerState<PadTrackerScreen> {
lastChange.month == now.month &&
lastChange.day == now.day;
// Check if we already showed it this session
if (_hasShownCheckInSession) {
debugPrint('_checkInitialPrompt: Already shown this session. Skipping.');
return;
}
if (!changedToday) {
_hasShownCheckInSession = true; // Mark as shown immediately
final result = await showDialog<_PadLogResult>(
context: context,
barrierDismissible: false,
@@ -91,7 +102,7 @@ class _PadTrackerScreenState extends ConsumerState<PadTrackerScreen> {
if (result != null) {
if (result.skipped) return;
_finalizeLog(
await _finalizeLog(
result.time,
result.flow,
supply: result.supply,
@@ -1162,7 +1173,7 @@ class _PadCheckInDialogState extends ConsumerState<_PadCheckInDialog> {
padding: const EdgeInsets.only(left: 16.0),
child: DropdownButtonFormField<PadType>(
isExpanded: true,
value: _borrowedType,
initialValue: _borrowedType,
items: PadType.values.map((t) {
return DropdownMenuItem(
value: t,