Polish floating bottom bar: elevation, height, overlap, and FAB shape
- Give the floating bar and search satellite the app's one shadow (nooDialogShadow) plus a smaller, tighter height on both platforms. - Let every tab's scrollable list compute its own bottom clearance (bottomBarClearance) instead of a flat 100px, so the floating bar no longer overlaps the last row/card. - Square the Android upload FAB off to a rounded-square radius when the bottom bar is attached, keeping it fully round only when floating. - Let a swipe on a file row trigger its action directly once dragged past 1.8x the reveal width, instead of requiring a second tap. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -92,7 +92,7 @@ class ActivityView extends StatelessWidget {
|
||||
final List<Widget> contentSlivers = [
|
||||
const SliverToBoxAdapter(child: SizedBox(height: NooSpace.md)),
|
||||
feed,
|
||||
...tabBottomInsetSlivers,
|
||||
...tabBottomInsetSlivers(context),
|
||||
];
|
||||
|
||||
final scrollView = CustomScrollView(
|
||||
|
||||
@@ -29,6 +29,7 @@ import '../widgets/noo/overlays/noo_sheet.dart';
|
||||
import '../widgets/noo/core/noo_button.dart';
|
||||
import '../widgets/share_sheet.dart';
|
||||
import '../widgets/sticky_header_delegate.dart';
|
||||
import '../widgets/tabs/tab_state_slivers.dart';
|
||||
import '../widgets/synced_header_scaffold.dart' show formatBytes;
|
||||
import 'file_viewer_screen.dart';
|
||||
import 'move_copy_destination_picker.dart';
|
||||
@@ -638,7 +639,7 @@ class _FavoritesViewState extends State<FavoritesView> {
|
||||
}, childCount: favorites.length),
|
||||
),
|
||||
),
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 100)),
|
||||
SliverToBoxAdapter(child: SizedBox(height: bottomBarClearance(context))),
|
||||
];
|
||||
|
||||
return PopScope(
|
||||
|
||||
@@ -39,11 +39,13 @@ import '../widgets/noo/lists/noo_selection_bar.dart';
|
||||
import '../widgets/noo/lists/noo_settings_row.dart';
|
||||
import '../widgets/noo/lists/noo_summary_card.dart';
|
||||
import '../widgets/noo/media/noo_grid_card.dart';
|
||||
import '../widgets/noo/nav/noo_bottom_bar.dart';
|
||||
import '../widgets/noo/noo_layout.dart';
|
||||
import '../widgets/noo/overlays/noo_sheet.dart';
|
||||
import '../widgets/share_sheet.dart';
|
||||
import '../widgets/sticky_header_delegate.dart';
|
||||
import '../widgets/synced_header_scaffold.dart' show formatBytes;
|
||||
import '../widgets/tabs/tab_state_slivers.dart';
|
||||
import 'file_viewer_screen.dart';
|
||||
import 'move_copy_destination_picker.dart';
|
||||
|
||||
@@ -815,6 +817,15 @@ class _FilesViewState extends State<FilesView> {
|
||||
}, childCount: browser.items.length),
|
||||
),
|
||||
),
|
||||
// List/grid/table above only pad NooSpace.lg at the bottom - plenty
|
||||
// once Scaffold shrinks the body above an attached bar, but floating
|
||||
// draws the body behind the bar instead, so it needs the bar's own
|
||||
// footprint added on top or the last row ends up under it.
|
||||
if (context.watch<SettingsController>().bottomBarStyle ==
|
||||
NooBottomBarStyle.floating)
|
||||
SliverToBoxAdapter(
|
||||
child: SizedBox(height: bottomBarClearance(context)),
|
||||
),
|
||||
];
|
||||
|
||||
return PopScope(
|
||||
|
||||
@@ -30,6 +30,7 @@ import '../widgets/noo/overlays/noo_sheet.dart';
|
||||
import '../widgets/share_sheet.dart';
|
||||
import '../widgets/sort_menu_button.dart' show sortFieldLabel;
|
||||
import '../widgets/sticky_header_delegate.dart';
|
||||
import '../widgets/tabs/tab_state_slivers.dart';
|
||||
import 'file_viewer_screen.dart';
|
||||
import 'move_copy_destination_picker.dart';
|
||||
|
||||
@@ -346,9 +347,10 @@ class _PhotosViewState extends State<PhotosView> {
|
||||
),
|
||||
],
|
||||
|
||||
// Fixed clearance so the last row isn't hidden behind the floating
|
||||
// nav bar, regardless of grid length.
|
||||
const SliverToBoxAdapter(child: SizedBox(height: 100)),
|
||||
// Clearance so the last row isn't hidden behind the nav bar,
|
||||
// regardless of grid length - see `bottomBarClearance`'s own doc
|
||||
// comment for why this has to be dynamic rather than a flat 100.
|
||||
SliverToBoxAdapter(child: SizedBox(height: bottomBarClearance(context))),
|
||||
];
|
||||
|
||||
return PopScope(
|
||||
|
||||
@@ -74,7 +74,7 @@ class _RecentViewState extends State<RecentView> {
|
||||
_buildDesktopTable(context, groups)
|
||||
else
|
||||
_buildMobileGroups(context, groups),
|
||||
...tabBottomInsetSlivers,
|
||||
...tabBottomInsetSlivers(context),
|
||||
];
|
||||
|
||||
return ColoredBox(
|
||||
|
||||
@@ -120,7 +120,7 @@ class _SharesViewState extends State<SharesView> {
|
||||
_buildDesktopTable(context, shares)
|
||||
else
|
||||
_buildMobileList(context, shares),
|
||||
...tabBottomInsetSlivers,
|
||||
...tabBottomInsetSlivers(context),
|
||||
];
|
||||
|
||||
return ColoredBox(
|
||||
|
||||
@@ -89,7 +89,7 @@ class _TrashViewState extends State<TrashView> {
|
||||
_buildDesktopTable(context, trash)
|
||||
else
|
||||
_buildMobileList(context, trash),
|
||||
...tabBottomInsetSlivers,
|
||||
...tabBottomInsetSlivers(context),
|
||||
];
|
||||
|
||||
return ColoredBox(
|
||||
|
||||
Reference in New Issue
Block a user