fix: use ValueKey<String> for reorderable grid and add status bar padding

flutter_reorderable_grid_view requires String keys, not int. Also
adds safe area top padding so the room grid doesn't overlap the
system status bar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-15 22:59:24 +01:00
parent 98f42ccb9c
commit 76cd98300d
4 changed files with 15 additions and 14 deletions

View File

@@ -123,7 +123,7 @@ class _RoomGridState extends ConsumerState<_RoomGrid> {
final l10n = AppLocalizations.of(context); final l10n = AppLocalizations.of(context);
final children = widget.rooms.map((rws) { final children = widget.rooms.map((rws) {
return RoomCard( return RoomCard(
key: ValueKey(rws.room.id), key: ValueKey('room-${rws.room.id}'),
roomWithStats: rws, roomWithStats: rws,
onEdit: () => context.go('/rooms/${rws.room.id}/edit'), onEdit: () => context.go('/rooms/${rws.room.id}/edit'),
onDelete: () => _showDeleteConfirmation(context, rws, l10n), onDelete: () => _showDeleteConfirmation(context, rws, l10n),
@@ -134,17 +134,19 @@ class _RoomGridState extends ConsumerState<_RoomGrid> {
scrollController: _scrollController, scrollController: _scrollController,
onReorder: (ReorderedListFunction<Widget> reorderFunc) { onReorder: (ReorderedListFunction<Widget> reorderFunc) {
final reordered = reorderFunc(children); final reordered = reorderFunc(children);
final newOrder = reordered final newOrder = reordered.map((w) {
.map((w) => (w.key! as ValueKey<int>).value) final keyStr = (w.key! as ValueKey<String>).value;
.toList(); return int.parse(keyStr.replaceFirst('room-', ''));
}).toList();
ref.read(roomActionsProvider.notifier).reorderRooms(newOrder); ref.read(roomActionsProvider.notifier).reorderRooms(newOrder);
}, },
builder: (reorderableChildren) { builder: (reorderableChildren) {
final topPadding = MediaQuery.of(context).padding.top;
return GridView.count( return GridView.count(
key: _gridViewKey, key: _gridViewKey,
controller: _scrollController, controller: _scrollController,
crossAxisCount: 2, crossAxisCount: 2,
padding: const EdgeInsets.all(12), padding: EdgeInsets.fromLTRB(12, 12 + topPadding, 12, 12),
mainAxisSpacing: 8, mainAxisSpacing: 8,
crossAxisSpacing: 8, crossAxisSpacing: 8,
childAspectRatio: 1.0, childAspectRatio: 1.0,

View File

@@ -397,25 +397,25 @@ abstract class AppLocalizations {
/// No description provided for @templatePickerTitle. /// No description provided for @templatePickerTitle.
/// ///
/// In de, this message translates to: /// In de, this message translates to:
/// **'Aufgaben aus Vorlagen hinzuf\u00fcgen?'** /// **'Aufgaben aus Vorlagen hinzufügen?'**
String get templatePickerTitle; String get templatePickerTitle;
/// No description provided for @templatePickerSkip. /// No description provided for @templatePickerSkip.
/// ///
/// In de, this message translates to: /// In de, this message translates to:
/// **'\u00dcberspringen'** /// **'Überspringen'**
String get templatePickerSkip; String get templatePickerSkip;
/// No description provided for @templatePickerAdd. /// No description provided for @templatePickerAdd.
/// ///
/// In de, this message translates to: /// In de, this message translates to:
/// **'Hinzuf\u00fcgen'** /// **'Hinzufügen'**
String get templatePickerAdd; String get templatePickerAdd;
/// No description provided for @templatePickerSelected. /// No description provided for @templatePickerSelected.
/// ///
/// In de, this message translates to: /// In de, this message translates to:
/// **'{count} ausgew\u00e4hlt'** /// **'{count} ausgewählt'**
String templatePickerSelected(int count); String templatePickerSelected(int count);
} }

View File

@@ -166,16 +166,16 @@ class AppLocalizationsDe extends AppLocalizations {
String get taskEmptyAction => 'Aufgabe erstellen'; String get taskEmptyAction => 'Aufgabe erstellen';
@override @override
String get templatePickerTitle => 'Aufgaben aus Vorlagen hinzuf\u00fcgen?'; String get templatePickerTitle => 'Aufgaben aus Vorlagen hinzufügen?';
@override @override
String get templatePickerSkip => '\u00dcberspringen'; String get templatePickerSkip => 'Überspringen';
@override @override
String get templatePickerAdd => 'Hinzuf\u00fcgen'; String get templatePickerAdd => 'Hinzufügen';
@override @override
String templatePickerSelected(int count) { String templatePickerSelected(int count) {
return '$count ausgew\u00e4hlt'; return '$count ausgewählt';
} }
} }

View File

@@ -1,4 +1,3 @@
// ignore_for_file: scoped_providers_should_specify_dependencies
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart'; import 'package:flutter_test/flutter_test.dart';