Repository navigation
Profile: let the language picker sheet grow and scroll instead of ove… #613
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -212,22 +212,28 @@ Future<void> _pickLanguage(BuildContext c) async { | |
| context: c, | ||
| backgroundColor: p.card, | ||
| showDragHandle: true, | ||
| // The default sheet is capped at 9/16 of the screen; with seven languages | ||
| // the list overflowed it. Lift the cap and scroll if it still doesn't fit. | ||
| isScrollControlled: true, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win 🔎 Supported by static analysis🏁 Script executed: git diff c8e63556225f1b77d015ca8a84adc8998a1e7d04 a76c39a9c37d44e57c6f3576cf3b2cb9928691dc -- lib/ui2/profile/profile.dart
rg -n -i 'language|locale|setCode|System default|SingleChildScrollView|showModalBottomSheet' test lib/ui2/profile
rg --files -g 'AGENTS.md' -g '*test.dart' | head -200Repository: OpenStrap/edge Length of output: 4679 Add a regression test for the scrollable language sheet. The changed language-picker behavior has no accompanying widget test. Add a test with enough locale options to exceed a small viewport. Verify that the final option is reachable by scrolling, and that selecting it updates the locale and dismisses the sheet. 🤖 Prompt for AI Agents |
||
| useSafeArea: true, // a full-height sheet must not reach under the status bar | ||
| builder: (sheet) => SafeArea( | ||
| child: Column( | ||
| mainAxisSize: MainAxisSize.min, | ||
| children: [ | ||
| for (final code in options) | ||
| ListTile( | ||
| title: Text(_languageLabel(sheet, code), style: F.body.copyWith(color: p.ink)), | ||
| trailing: ctrl.code == code | ||
| ? Icon(LucideIcons.check, size: 18, color: p.on(C.blue)) | ||
| : null, | ||
| onTap: () async { | ||
| await ctrl.setCode(code); | ||
| if (sheet.mounted) Navigator.of(sheet).pop(); | ||
| }, | ||
| ), | ||
| ], | ||
| child: SingleChildScrollView( | ||
| child: Column( | ||
| mainAxisSize: MainAxisSize.min, | ||
| children: [ | ||
| for (final code in options) | ||
| ListTile( | ||
| title: Text(_languageLabel(sheet, code), style: F.body.copyWith(color: p.ink)), | ||
| trailing: ctrl.code == code | ||
| ? Icon(LucideIcons.check, size: 18, color: p.on(C.blue)) | ||
| : null, | ||
| onTap: () async { | ||
| await ctrl.setCode(code); | ||
| if (sheet.mounted) Navigator.of(sheet).pop(); | ||
| }, | ||
| ), | ||
| ], | ||
| ), | ||
| ), | ||
| ), | ||
| ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| // The language picker used to overflow its bottom sheet (capped at 9/16 of the | ||
| // screen) once the list grew past what fits. It must lay out without an | ||
| // overflow on a short screen, and every language must stay reachable. | ||
| import 'package:flutter/material.dart'; | ||
| import 'package:flutter_test/flutter_test.dart'; | ||
| import 'package:provider/provider.dart'; | ||
| import 'package:shared_preferences/shared_preferences.dart'; | ||
|
|
||
| import 'package:openstrap_edge/l10n/app_localizations.dart'; | ||
| import 'package:openstrap_edge/state/locale_controller.dart'; | ||
| import 'package:openstrap_edge/ui2/profile/profile.dart'; | ||
| import 'package:openstrap_edge/ui2/ui2.dart'; | ||
|
|
||
| void main() { | ||
| testWidgets('language sheet scrolls on a short screen and selects the last language', | ||
| (tester) async { | ||
| SharedPreferences.setMockInitialValues({}); | ||
| tester.view.physicalSize = const Size(360, 560); | ||
| tester.view.devicePixelRatio = 1; | ||
| addTearDown(tester.view.reset); | ||
|
|
||
| final ctrl = LocaleController.seed(null); | ||
| await tester.pumpWidget(ChangeNotifierProvider<LocaleController>.value( | ||
| value: ctrl, | ||
| child: MaterialApp( | ||
| theme: buildTheme(Brightness.dark), | ||
| localizationsDelegates: AppLocalizations.localizationsDelegates, | ||
| supportedLocales: AppLocalizations.supportedLocales, | ||
| home: const ProfileHomeView(stats: ProfileStats(name: 'Sahil')), | ||
| ), | ||
| )); | ||
| await tester.pumpAndSettle(); | ||
|
|
||
| await tester.tap(find.text('System default').first); | ||
| await tester.pumpAndSettle(); | ||
| expect(tester.takeException(), isNull, reason: 'sheet must not overflow'); | ||
|
|
||
| final last = find.text('中文'); | ||
| await tester.ensureVisible(last); | ||
| await tester.pumpAndSettle(); | ||
| await tester.tap(last); | ||
| await tester.pumpAndSettle(); | ||
|
|
||
| expect(ctrl.code, 'zh'); | ||
| expect(find.text('Deutsch'), findsNothing, reason: 'sheet should be dismissed'); | ||
| }); | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.