fix(inventory): tappable photo dots + non-truncated quantity scale

- Photo carousel dots are now tappable (jump to that photo) with a larger hit
  area, so you can browse all images even when swiping the small thumbnail is
  awkward.
- The quantity unit scale is a Wrap instead of a horizontal scroll, so every
  unit stays visible instead of being cut off.
This commit is contained in:
vjrj 2026-07-08 13:59:21 +02:00
parent a69047326e
commit 46ef2c61cd
2 changed files with 35 additions and 21 deletions

View file

@ -154,22 +154,19 @@ class _QuantityPickerState extends State<QuantityPicker> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
SizedBox( // Wrap (not a horizontal scroll) so every unit stays visible.
height: 76, Wrap(
child: ListView.separated( spacing: 4,
scrollDirection: Axis.horizontal, runSpacing: 4,
itemCount: kinds.length, children: [
separatorBuilder: (_, _) => const SizedBox(width: 4), for (final kind in kinds)
itemBuilder: (context, i) { _ScaleItem(
final kind = kinds[i];
return _ScaleItem(
kind: kind, kind: kind,
label: unitLabel(t, kind), label: unitLabel(t, kind),
selected: _kind == kind, selected: _kind == kind,
onTap: () => _select(kind), onTap: () => _select(kind),
); ),
}, ],
),
), ),
if (_kind?.countable ?? false) ...[ if (_kind?.countable ?? false) ...[
const SizedBox(height: 8), const SizedBox(height: 8),

View file

@ -927,7 +927,16 @@ class _PhotoGalleryState extends State<_PhotoGallery> {
), ),
), ),
const SizedBox(height: 6), const SizedBox(height: 6),
if (photos.length > 1) _Dots(count: photos.length, active: page), if (photos.length > 1)
_Dots(
count: photos.length,
active: page,
onTap: (i) => _controller.animateToPage(
i,
duration: const Duration(milliseconds: 250),
curve: Curves.easeInOut,
),
),
TextButton.icon( TextButton.icon(
key: const Key('photo.add'), key: const Key('photo.add'),
onPressed: () => _addPhoto(cubit), onPressed: () => _addPhoto(cubit),
@ -968,10 +977,11 @@ class _CircleIconButton extends StatelessWidget {
} }
class _Dots extends StatelessWidget { class _Dots extends StatelessWidget {
const _Dots({required this.count, required this.active}); const _Dots({required this.count, required this.active, this.onTap});
final int count; final int count;
final int active; final int active;
final ValueChanged<int>? onTap;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -979,13 +989,20 @@ class _Dots extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
for (var i = 0; i < count; i++) for (var i = 0; i < count; i++)
Container( GestureDetector(
width: 6, behavior: HitTestBehavior.opaque,
height: 6, onTap: onTap == null ? null : () => onTap!(i),
margin: const EdgeInsets.symmetric(horizontal: 2), child: Padding(
decoration: BoxDecoration( // Bigger, tappable hit area around each dot.
shape: BoxShape.circle, padding: const EdgeInsets.all(6),
color: i == active ? seedGreen : Colors.black26, child: Container(
width: 8,
height: 8,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: i == active ? seedGreen : Colors.black26,
),
),
), ),
), ),
], ],