Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 21 additions & 15 deletions lib/ui2/profile/profile.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Comment thread
sourcery-ai[bot] marked this conversation as resolved.
Resolved
Comment thread
abdulsaheel marked this conversation as resolved.
Resolved
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();
},
),
],
),
),
),
);
Expand Down
47 changes: 47 additions & 0 deletions test/language_picker_sheet_test.dart
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');
});
}
Loading