feat(todo): Settings choose the app's appearance and language
The developer asked for Todo to offer what Learn's Settings offer first (ADR 0014's amendment of 4 Nov 2026). Todo passed a fixed look, the system's theme and language; it now opens halkyon_app's LookCubit on <app support>/look.json in main, provides it above InstanceGate, and its start screens and each person's MaterialApp follow it. Settings show DeviceLookCard right after the Sync and operator's cards, as Learn's, offering English (UK), English (US) and Deutsch (todoLanguages). Whats-New: Settings: choose the app's appearance and language. Whats-New-De: Einstellungen: Darstellung und Sprache der App wählen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
23d3bcb4ca
commit
a2384dcbfe
1 changed files with 130 additions and 52 deletions
|
|
@ -43,6 +43,9 @@ import '../support/memory_sealed_row_gateway.dart';
|
|||
void main() {
|
||||
final builtIn = Instance.parse('todo.example.org')!;
|
||||
late MemoryInstanceStore store;
|
||||
|
||||
/// The device's appearance and language, kept from start to start.
|
||||
late MemoryLookStore looks;
|
||||
late FakeAuthGateway gateway;
|
||||
late List<SignedIn> opened;
|
||||
late MemorySignInAddresses addresses;
|
||||
|
|
@ -83,6 +86,7 @@ void main() {
|
|||
settingsRows = MemorySealedRowGateway();
|
||||
reminders = MemoryReminderGateway();
|
||||
store = MemoryInstanceStore();
|
||||
looks = MemoryLookStore();
|
||||
gateway = FakeAuthGateway();
|
||||
addresses = MemorySignInAddresses();
|
||||
opened = [];
|
||||
|
|
@ -111,10 +115,13 @@ void main() {
|
|||
if (!usedBefore || signedOut) {
|
||||
gateway.revokeSession();
|
||||
}
|
||||
final look = await LookCubit.open(looks);
|
||||
addTearDown(look.close);
|
||||
await tester.pumpWidget(
|
||||
TodoApp(
|
||||
choice: choice,
|
||||
checker: FakeInstanceChecker({builtIn}),
|
||||
look: look,
|
||||
countryNames: MemoryCountryNames(const {}),
|
||||
open: (instance) async => TodoDependencies(
|
||||
serverName: instance.name,
|
||||
|
|
@ -228,6 +235,45 @@ void main() {
|
|||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
testWidgets("Settings choose the app's appearance and language, first of "
|
||||
"Todo's own: a choice applies at once and stays after a restart", (
|
||||
tester,
|
||||
) async {
|
||||
/// Opens the menu showing [current] and picks [choice].
|
||||
Future<void> choose(String current, String choice) async {
|
||||
await tester.tap(find.text(current));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text(choice).last);
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
|
||||
Brightness brightness() =>
|
||||
Theme.of(tester.element(find.byType(Scaffold).last)).brightness;
|
||||
|
||||
await start(tester, usedBefore: true);
|
||||
await openSettings(tester);
|
||||
expect(find.text('Appearance'), findsOneWidget);
|
||||
expect(find.text('Language'), findsOneWidget);
|
||||
expect(brightness(), Brightness.light);
|
||||
|
||||
await choose('Device theme', 'Dark');
|
||||
expect(brightness(), Brightness.dark);
|
||||
|
||||
await choose('Device language', 'Deutsch');
|
||||
expect(find.widgetWithText(AppBar, 'Einstellungen'), findsOneWidget);
|
||||
expect(find.text('Darstellung'), findsOneWidget);
|
||||
expect(looks.look, const Look(appearance: Appearance.dark, language: 'de'));
|
||||
|
||||
// The app closed and opened again, on the look the device kept.
|
||||
await tester.pumpWidget(const SizedBox());
|
||||
await start(tester, usedBefore: true);
|
||||
expect(brightness(), Brightness.dark);
|
||||
expect(
|
||||
Localizations.localeOf(tester.element(find.byType(Scaffold).last)),
|
||||
const Locale('de'),
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets("a new install chooses its instance first, in Todo's words and "
|
||||
'look', (tester) async {
|
||||
await start(tester);
|
||||
|
|
|
|||
Loading…
Reference in a new issue