mirror of
https://github.com/Yubico/yubioath-flutter.git
synced 2024-12-23 02:01:36 +03:00
Layout cells in FlexBox
based on cell min width
This commit is contained in:
parent
cbedbfae4e
commit
ea665b3299
@ -320,13 +320,16 @@ class _AppPageState extends ConsumerState<AppPage> {
|
||||
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<AppPage> {
|
||||
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<AppPage> {
|
||||
hasManage,
|
||||
fullyExpanded,
|
||||
),
|
||||
centerTitle: true,
|
||||
leading: hasRail
|
||||
? Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
|
@ -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],
|
||||
|
@ -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,
|
||||
),
|
||||
],
|
||||
|
@ -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<T> extends StatelessWidget {
|
||||
final List<T> 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<List<T>> getChunks(int itemsPerChunk) {
|
||||
@ -86,9 +76,8 @@ class FlexBox<T> 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<T> 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,
|
||||
|
Loading…
Reference in New Issue
Block a user