From ea665b3299b5ea4740f689f4a4bbf606ae2a9f0d Mon Sep 17 00:00:00 2001 From: Elias Bonnici Date: Thu, 8 Aug 2024 15:46:11 +0200 Subject: [PATCH] Layout cells in `FlexBox` based on cell min width --- lib/app/views/app_page.dart | 10 +++-- lib/fido/views/passkeys_screen.dart | 36 ++--------------- lib/oath/views/account_list.dart | 10 +++-- lib/widgets/flex_box.dart | 61 ++++++++++++----------------- 4 files changed, 41 insertions(+), 76 deletions(-) diff --git a/lib/app/views/app_page.dart b/lib/app/views/app_page.dart index d6a0eb5d..09f50791 100755 --- a/lib/app/views/app_page.dart +++ b/lib/app/views/app_page.dart @@ -320,13 +320,16 @@ class _AppPageState extends ConsumerState { Widget? _buildAppBarTitle( BuildContext context, bool hasRail, bool hasManage, bool fullyExpanded) { final showNavigation = ref.watch(_navigationVisibilityProvider); + final showDetailView = ref.watch(_detailViewVisibilityProvider); + EdgeInsets padding; if (fullyExpanded) { - padding = EdgeInsets.only(left: showNavigation ? 280 : 72, right: 320); + padding = EdgeInsets.only( + left: showNavigation ? 280 : 72, right: showDetailView ? 320 : 0.0); } else if (!hasRail && hasManage) { padding = const EdgeInsets.only(right: 320); } else if (hasRail && hasManage) { - padding = const EdgeInsets.only(left: 72, right: 320); + padding = EdgeInsets.only(left: 72, right: showDetailView ? 320 : 0.0); } else if (hasRail && !hasManage) { padding = const EdgeInsets.only(left: 72); } else { @@ -627,7 +630,7 @@ class _AppPageState extends ConsumerState { opacity: visible ? 1 : 0, duration: const Duration(milliseconds: 300), child: Container( - color: Theme.of(context).colorScheme.secondaryContainer, + color: Theme.of(context).hoverColor, height: 1.0, ), ); @@ -643,6 +646,7 @@ class _AppPageState extends ConsumerState { hasManage, fullyExpanded, ), + centerTitle: true, leading: hasRail ? Row( mainAxisAlignment: MainAxisAlignment.spaceAround, diff --git a/lib/fido/views/passkeys_screen.dart b/lib/fido/views/passkeys_screen.dart index de079463..5c0b64da 100644 --- a/lib/fido/views/passkeys_screen.dart +++ b/lib/fido/views/passkeys_screen.dart @@ -548,9 +548,9 @@ class _FidoUnlockedPageState extends ConsumerState<_FidoUnlockedPage> { selected: _selected == cred, ), layout: layout, - spacing: layout == FlexLayout.grid ? 4.0 : null, - runSpacing: layout == FlexLayout.grid ? 4.0 : null, - getItemsPerRow: _getItemsPerRow, + cellMinWidth: 265, + spacing: layout == FlexLayout.grid ? 4.0 : 0.0, + runSpacing: layout == FlexLayout.grid ? 4.0 : 0.0, ) ], ), @@ -563,36 +563,6 @@ class _FidoUnlockedPageState extends ConsumerState<_FidoUnlockedPage> { ); } - int _getItemsPerRow(double width) { - int itemsPerRow = 1; - if (width <= 600) { - // single column - itemsPerRow = 1; - } else if (width <= 900) { - // 2 column - itemsPerRow = 2; - } else if (width < 1300) { - // 3 column - itemsPerRow = 3; - } else if (width < 1500) { - // 4 column - itemsPerRow = 4; - } else if (width < 1700) { - // 5 column - itemsPerRow = 5; - } else if (width < 1900) { - // 6 column - itemsPerRow = 6; - } else if (width < 2100) { - // 7 column - itemsPerRow = 7; - } else { - // 8 column - itemsPerRow = 8; - } - return itemsPerRow; - } - Widget _buildLoadingPage(BuildContext context) => AppPage( title: AppLocalizations.of(context)!.s_passkeys, capabilities: const [Capability.fido2], diff --git a/lib/oath/views/account_list.dart b/lib/oath/views/account_list.dart index b702dad8..c3682768 100755 --- a/lib/oath/views/account_list.dart +++ b/lib/oath/views/account_list.dart @@ -75,8 +75,9 @@ class AccountList extends ConsumerWidget { selected: value.credential == selected, large: pinnedLayout == FlexLayout.grid, ), - spacing: pinnedLayout == FlexLayout.grid ? 4.0 : null, - runSpacing: pinnedLayout == FlexLayout.grid ? 4.0 : null, + cellMinWidth: 250, + spacing: pinnedLayout == FlexLayout.grid ? 4.0 : 0.0, + runSpacing: pinnedLayout == FlexLayout.grid ? 4.0 : 0.0, layout: pinnedLayout, ), ], @@ -96,8 +97,9 @@ class AccountList extends ConsumerWidget { selected: value.credential == selected, large: normalLayout == FlexLayout.grid, ), - spacing: normalLayout == FlexLayout.grid ? 4.0 : null, - runSpacing: normalLayout == FlexLayout.grid ? 4.0 : null, + cellMinWidth: 250, + spacing: normalLayout == FlexLayout.grid ? 4.0 : 0.0, + runSpacing: normalLayout == FlexLayout.grid ? 4.0 : 0.0, layout: normalLayout, ), ], diff --git a/lib/widgets/flex_box.dart b/lib/widgets/flex_box.dart index 8a2ddbc6..4b2f9ca1 100644 --- a/lib/widgets/flex_box.dart +++ b/lib/widgets/flex_box.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:material_symbols_icons/symbols.dart'; @@ -19,50 +20,39 @@ enum FlexLayout { class FlexBox extends StatelessWidget { final List items; final Widget Function(T value) itemBuilder; - final int Function(double width)? getItemsPerRow; final FlexLayout layout; - final double? spacing; - final double? runSpacing; + final double cellMinWidth; + final double spacing; + final double runSpacing; const FlexBox({ super.key, required this.items, required this.itemBuilder, - this.getItemsPerRow, + required this.cellMinWidth, this.layout = FlexLayout.list, this.spacing = 0.0, this.runSpacing = 0.0, }); int _getItemsPerRow(double width) { - int itemsPerRow = 1; - if (layout == FlexLayout.grid) { - if (width <= 420) { - // single column - itemsPerRow = 1; - } else if (width <= 620) { - // 2 column - itemsPerRow = 2; - } else if (width < 860) { - // 3 column - itemsPerRow = 3; - } else if (width < 1200) { - // 4 column - itemsPerRow = 4; - } else if (width < 1500) { - // 5 column - itemsPerRow = 5; - } else if (width < 1800) { - // 6 column - itemsPerRow = 6; - } else if (width < 2000) { - // 7 column - itemsPerRow = 7; - } else { - // 8 column - itemsPerRow = 8; - } + // Calculate the maximum number of cells that can fit in one row + int cellsPerRow = (width / (cellMinWidth + spacing)).floor(); + + // Ensure there's at least one cell per row + if (cellsPerRow < 1) { + cellsPerRow = 1; } - return itemsPerRow; + + // Calculate the total width needed for the calculated number of cells and spacing + double totalWidthNeeded = + cellsPerRow * cellMinWidth + (cellsPerRow - 1) * spacing; + + // Adjust the number of cells per row if the calculated total width exceeds the available width + if (totalWidthNeeded > width) { + cellsPerRow = cellsPerRow - 1 > 0 ? cellsPerRow - 1 : 1; + } + + return cellsPerRow; } List> getChunks(int itemsPerChunk) { @@ -86,9 +76,8 @@ class FlexBox extends StatelessWidget { return LayoutBuilder( builder: (context, constraints) { final width = constraints.maxWidth; - final itemsPerRow = layout == FlexLayout.grid - ? getItemsPerRow?.call(width) ?? _getItemsPerRow(width) - : 1; + final itemsPerRow = + layout == FlexLayout.grid ? _getItemsPerRow(width) : 1; final chunks = getChunks(itemsPerRow); return Column( @@ -105,7 +94,7 @@ class FlexBox extends StatelessWidget { SizedBox(width: spacing), ], if (c.length < itemsPerRow) ...[ - // Prevents resizing when an items is removed + // Prevents resizing when an item is removed SizedBox(width: 8 * (itemsPerRow - c.length).toDouble()), Spacer( flex: itemsPerRow - c.length,