Skip to content

Commit 1ad1092

Browse files
feat: table mode full-width default, details toggle, and entity settings (#184)
* feat: add details pane toggle provider and database columns Add per-section details pane toggle support for table mode: - StateProvider.family keyed by section name (dives, sites, etc.) - 8 new boolean columns in diverSettings table (v63 migration) - AppSettings fields and repository mapping for persistence * feat: add TableModeLayout shared widget Shared ConsumerWidget that encapsulates the layout state machine for table mode across all entity sections (Dives, Sites, Buddies, etc.). Manages toggling between full-width table, table+detail pane (MasterDetailScaffold), table+map side-by-side, and table+profile panel layouts. Profile and Details are mutually exclusive. * refactor: migrate Dives table mode to TableModeLayout Replace the ad-hoc table mode layout in DiveListPage with the shared TableModeLayout widget. This consolidates the profile panel, map toggle, detail pane, and column settings into TableModeLayout's state machine, removing ~100 lines of duplicated layout logic from DiveListContent. - Remove _buildTableMapView from DiveListPage (logic now in TableModeLayout) - Replace table mode branch with single TableModeLayout widget call - Simplify _buildTableModeScaffold to only provide embedded content - Remove DiveProfilePanel from _buildTableView (managed by TableModeLayout) - Remove duplicate map toggle from compact app bar in table mode - Update test comments to reflect profile panel ownership change * refactor: migrate Sites table mode to TableModeLayout Sites table mode now uses the shared TableModeLayout widget instead of managing its own standalone Scaffold/AppBar. Column settings, map toggle, and detail pane toggle are all handled by TableModeLayout. The content widget provides only the compact app bar (search, filter, sort) and the table view itself. * refactor: migrate Dive Centers table mode to TableModeLayout Dive Centers table mode now uses the shared TableModeLayout widget instead of managing its own standalone Scaffold/AppBar. Column settings, map toggle, and detail pane toggle are all handled by TableModeLayout. The content widget provides only the compact app bar (search, sort) and the table view itself. * refactor: migrate Buddies table mode to TableModeLayout Move table mode orchestration (app bar, column settings, detail pane) from BuddyListContent to TableModeLayout in BuddyListPage. Simplify _buildTableModeScaffold to only provide compact bar + table content. Add highlightedBuddyIdProvider for table mode selection tracking. * refactor: migrate Trips table mode to TableModeLayout Move table mode orchestration (app bar, column settings, detail pane) from TripListContent to TableModeLayout in TripListPage. Simplify _buildTableModeScaffold to only provide compact bar + table content. Add highlightedTripIdProvider for table mode selection tracking. * refactor: migrate Equipment table mode to TableModeLayout Move table mode orchestration (app bar, column settings, detail pane) from EquipmentListContent to TableModeLayout in EquipmentListPage. Table mode intercepts before the tab scaffold, showing only the Equipment items table. Simplify _buildTableModeScaffold to only provide compact bar + filter chips + table content. Add highlightedEquipmentIdProvider for table mode selection tracking. * refactor: migrate Certifications table mode to TableModeLayout Move table mode orchestration (app bar, column settings, detail pane) from CertificationListContent to TableModeLayout in CertificationListPage. Remove column settings from compact bar since TableModeLayout now manages them. Add highlightedCertificationIdProvider for table mode selection tracking. * refactor: migrate Courses table mode to TableModeLayout Move table mode orchestration (app bar, column settings, detail pane) from CourseListContent to TableModeLayout in CourseListPage. Remove column settings from compact bar since TableModeLayout now manages them. Add highlightedCourseIdProvider for table mode selection tracking. * feat: add EntityCardViewConfig generic model * feat: add card view config providers for all entity sections * feat: make ColumnConfigPage entity-aware with section selector Add a Section dropdown (Dives, Sites, Buddies, Trips, Equipment, Dive Centers, Certifications, Courses) above the view mode dropdown. Dives continues to use its existing config widgets; all other sections use new generic _EntityTableConfigSection and _EntityCardConfigSection widgets that work with EntityTableViewConfig<F> and EntityCardViewConfig<F>. Certifications and Courses restrict available modes to Table + Detailed. * feat: add details pane toggles to Settings > Appearance Add per-section SwitchListTile toggles for all 8 entity sections (Dives, Sites, Buddies, Trips, Equipment, Dive Centers, Certifications, Courses) that control the default state of the details pane in table mode. Uses the existing tableDetailsPaneProvider family provider. * fix: address test failures and formatting from table mode migration Fixes prefer_const_declarations lint in entity_card_view_config_test.dart by converting variable declaration to const and removing redundant inner const. * test: add list page widget tests for buddies, certifications, courses, equipment, sites, and dive centers Adds mobile-mode widget tests for the 6 list pages that had 0% patch coverage in the PR. Each file covers mobile rendering, loading state, empty state, FAB label, and (where applicable) data display — targeting the page-level branch coverage gap reported by Codecov. Co-authored-by: Eric Griffin <ericgriffin@users.noreply.github.com> * fix: resolve flutter analyze errors in list page tests Add missing diver_providers.dart import (currentDiverIdProvider) and buddy_repository.dart import (BuddyWithDiveCount) to 6 test files. Fix use_super_parameters warnings in mock notifier constructors. Co-authored-by: Eric Griffin <ericgriffin@users.noreply.github.com> * test: increase patch coverage for table mode full-width details toggle Add ~80 tests across 10 new and 4 modified test files to improve patch coverage from 37% toward 90% for PR #184. - List page layout branch tests for all 8 entity sections (mobile/table/desktop modes) - AppSettings copyWith and defaults for new showDetailsPane* fields - Runtime view mode provider unit tests (6 providers) - Appearance page interaction tests (toggles, dropdowns) - Highlighted entity ID provider tests (7 providers) * fix: initialize tableDetailsPaneProvider from persisted settings The provider now reads per-section details pane visibility from AppSettings on creation instead of defaulting to false. Updates all related tests to provide the required settingsProvider override. * fix: formatting * fix: tests * test: remove performance tests and clean up list page test overrides Delete standalone performance test files (perf_timer, data generator, repository benchmarks) and skip the performance tag by default in dart_test.yaml. Remove stale highlightedId provider overrides and error-suppression blocks from table-mode widget tests. * refactor: lift toolbar actions from list content widgets to list pages Move search, sort, filter, view mode, and column settings controls from individual list content widgets up to their parent list page widgets, integrating them into TableModeLayout's app bar. Adds columnSettingsAction parameter with vertical divider grouping, reworks detail pane / profile panel / map mutual exclusivity, and bridges provider-driven selection to MasterDetailScaffold via debounced timer. Includes appearance settings reorganization plan and design spec. * feat: add SectionAppearancePage for per-section appearance settings * feat: add initialSection param to ColumnConfigPage for section-scoped field config * refactor: rewrite AppearancePage as hub with section navigation tiles * feat: add routes for 8 appearance section sub-pages * refactor: update desktop appearance settings to hub + section sub-page layout * fix: remove unused imports from section appearance page test * fix: use 'Dive Sites' display name for consistency with hub navigation * docs: add design spec and implementation plan for startup migration progress (#186) * feat: add MigrationProgress data model (#186) * feat: add migration progress callback to AppDatabase (#186) Adds onMigrationProgress callback, migrationVersions list, and migrationStepCount helper to AppDatabase. Inserts reportProgress() calls after every migration block in onUpgrade so callers can track how many steps have completed vs. the total. * feat: add schema version pre-check and progress callback to DatabaseService (#186) * feat: add StartupWrapper widget with splash and migration progress UI (#186) * feat: rewire main.dart to use StartupWrapper for startup splash (#186) Move database/service initialization out of main() and into StartupWrapper, so runApp() is called immediately and the user sees a splash screen during init. * test: add widget tests for startup splash and migration progress UI (#186) * fix: resolve nested MaterialApp and add missing mounted guard (#186) - Return SubmersionRestart directly when ready instead of wrapping in MaterialApp, avoiding duplicate navigators/themes/overlays - Use same key for initializing and migrating states so AnimatedSize handles the progress bar transition (not a full Scaffold crossfade) - Add mounted check on the migrating setState for consistency * fix: correct view mode options — remove dense, add compact+table for buddies/equipment * fix: optimize v59 pressure migration to avoid full table scans (#187) The legacy pressure data migration was catastrophically slow due to SQLite choosing SCAN over index lookup for the NOT EXISTS subquery, causing O(n^2) row comparisons on large datasets. Replace the per-row NOT EXISTS with an EXCEPT set-difference on small distinct dive_id sets. Pre-compute first-tank mapping into an indexed temp table. Reuse dive_profile IDs instead of generating UUIDs per row. Boost page cache and defer secondary index creation during bulk insert. * fix: close databases on app detach to prevent Drift isolate FFI crash When the app exits, the Drift background isolate can outlive the Dart VM's FFI subsystem teardown, causing sqlite3_close_v2 to crash with "GetFfiCallbackMetadata called after shutdown". Closing both databases in the detached lifecycle state ensures SQLite is shut down cleanly before isolate teardown begins. * feat: add shared profile tracking index provider * feat: wire profile panel chart to shared tracking provider * feat: wire detail page to shared profile tracking provider Replace local _selectedPointNotifier and _heatMapHoverIndex with profileTrackingIndexProvider(diveId) so the detail page chart, deco section, and SAC panel all share synchronized tracking state. * style: format synchronized profile tracking files * fix: add MouseRegion.onExit to profile panel to clear tracking on mouse leave * docs: add synchronized profile tracking spec and plan * fix: show full-page map in table view on mobile instead of split * fix: use AppLifecycleListener.onExitRequested to close databases on exit The previous detached lifecycle handler was unreliable on macOS desktop — it either never fires or fires after the VM has already begun teardown. AppLifecycleListener.onExitRequested maps to applicationShouldTerminate: on macOS, which is async and fires before the app actually terminates, giving the database close() calls time to complete. * fix: skip desktop master-detail redirect when in table view mode Detail pages for buddies, sites, equipment, certifications, trips, and dive centers unconditionally redirected context.push navigation back to the master-detail URL, preventing double-click from opening full-page details in table view. Add the same viewMode table guard that dives already had. * test: increase unit test patch coverage for PR #184 Add comprehensive test coverage for the table-mode-full-width-details-toggle feature across 7 test files (+1149 lines, -139 lines): - New: profile_tracking_provider_test.dart (5 tests, was 0% covered) - Expanded: table_details_pane_provider_test.dart (all 8 section keys) - Expanded: settings_providers_details_pane_test.dart (computed getters, unitPreset, gfDisplay, showDepthColoredDiveCards) - Expanded: entity_card_view_config_test.dart (empty collection edge cases) - Expanded: section_appearance_page_test.dart (36 tests covering all 8 sections, dropdowns, toggles, callbacks, conditional sections) - Expanded: startup_page_test.dart (16 tests covering splash, migration progress, version mismatch error, generic error, close button) - Expanded: table_mode_layout_test.dart (mobile map full-page, column settings action, vertical divider, profile-only layout, section keys) * style: remove extra blank line in appearance page test * fix: address PR review comments for table mode and startup - Add setShowDetailsPaneForSection to SettingsNotifier so details pane toggle persists to DB (was only updating in-memory provider) - Wire both app bar toggle and settings page switch to persist - Guard profile toggle on onProfileToggled != null (was rendering interactive button with no callback) - Change ref.read to ref.watch for siteListViewModeProvider in build path - Make _closeApp async with best-effort DB close before exit - Update stale doc comments on _buildTableModeScaffold in 3 list content files to match actual implementation - Localize hard-coded strings in appearance and section appearance pages using new l10n keys and existing nav_* keys * fix: open SQLite read-only when probing schema version Avoids creating WAL/journal side-effect files when only reading PRAGMA user_version for the pre-migration step count check. * fix: revert createInBackground to synchronous NativeDatabase Reverts the initialize() method back to synchronous NativeDatabase, matching reinitializeAtPath() and the prior intentional fix. Background isolates can cause close() to hang indefinitely if called mid-migration. Progress bar updates still render between migration steps via the Future.delayed(Duration.zero) yield in reportProgress(). * fix: update tests for l10n and persistence changes - appearance_page_test: update expected section label from "Dive Sites" to "Sites" to match nav_sites l10n key - table_mode_layout_test: add explicit setShowDetailsPaneForSection override to mock notifier (noSuchMethod fallback can't handle it) * fix: add missing translations for appearance settings across all locales Add 6 untranslated keys (settings_appearance_general, sections, showDetailsPane, showDetailsPane_subtitle, showProfilePanel, showProfilePanel_subtitle) to ar, de, es, fr, he, hu, it, nl, pt, zh. * test: increase unit test patch coverage to 90% for PR #184 Add ~220 tests across 32 files covering table mode toolbar buttons, detail/edit/create builder closures, desktop redirect logic, startup page lifecycle, settings navigation, import wizard file pickers, device detail page, dive profile panel pointer tracking, and settings provider methods. * fix: formatting * fix: tests * fix: tests --------- Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
1 parent 35bf02d commit 1ad1092

127 files changed

Lines changed: 64586 additions & 49890 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<!-- Modify this file to customize your launch splash screen -->
32
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
4-
<item android:drawable="?android:colorBackground" />
5-
6-
<!-- You can insert your own image assets here -->
7-
<!-- <item>
8-
<bitmap
9-
android:gravity="center"
10-
android:src="@mipmap/launch_image" />
11-
</item> -->
3+
<item>
4+
<shape android:shape="rectangle">
5+
<gradient
6+
android:startColor="#FF00838F"
7+
android:endColor="#FF00796B"
8+
android:angle="315"
9+
android:type="linear" />
10+
</shape>
11+
</item>
1212
</layer-list>
Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<!-- Modify this file to customize your launch splash screen -->
32
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
4-
<item android:drawable="@android:color/white" />
5-
6-
<!-- You can insert your own image assets here -->
7-
<!-- <item>
8-
<bitmap
9-
android:gravity="center"
10-
android:src="@mipmap/launch_image" />
11-
</item> -->
3+
<item>
4+
<shape android:shape="rectangle">
5+
<gradient
6+
android:startColor="#FF00ACC1"
7+
android:endColor="#FF009688"
8+
android:angle="315"
9+
android:type="linear" />
10+
</shape>
11+
</item>
1212
</layer-list>

dart_test.yaml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
tags:
22
performance:
33
# Performance tests use large datasets and may take minutes to run.
4-
# Run explicitly: flutter test --tags performance
5-
# Or: flutter test test/performance/
4+
# Run explicitly: flutter test --run-skipped --tags performance
5+
# Or: flutter test --run-skipped test/performance/
6+
skip: "Slow performance tests; run with --run-skipped --tags performance"

0 commit comments

Comments
 (0)