feat(shell): the rail's logo leads Home
From medium windows on, the kingfisher atop the navigation rail is a button to Home, as a website's logo leads to its start, with the tick the rail's own choices make. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
abddd8b9b0
commit
ca8c3659bc
2 changed files with 45 additions and 18 deletions
|
|
@ -77,7 +77,7 @@ class _AppShellState() extends State<AppShell> {
|
||||||
selectedIndex: navigationShell.currentIndex,
|
selectedIndex: navigationShell.currentIndex,
|
||||||
labelType: NavigationRailLabelType.all,
|
labelType: NavigationRailLabelType.all,
|
||||||
onDestinationSelected: _select,
|
onDestinationSelected: _select,
|
||||||
leading: const _RailLogo(),
|
leading: _RailLogo(onTap: () => _select(0)),
|
||||||
destinations: [
|
destinations: [
|
||||||
for (final destination in destinations)
|
for (final destination in destinations)
|
||||||
NavigationRailDestination(
|
NavigationRailDestination(
|
||||||
|
|
@ -141,26 +141,41 @@ class _AppShellState() extends State<AppShell> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The kingfisher atop the rail. The icon has a white background, so it sits
|
/// The kingfisher atop the rail, leading Home ([onTap]) as a website's
|
||||||
/// in a rounded tile that reads on light and dark rails alike.
|
/// logo does. The icon has a white background, so it sits in a rounded tile
|
||||||
class const _RailLogo() extends StatelessWidget {
|
/// that reads on light and dark rails alike.
|
||||||
|
class const _RailLogo({required final VoidCallback onTap})
|
||||||
|
extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => Padding(
|
Widget build(BuildContext context) {
|
||||||
|
final l10n = AppLocalizations.of(context);
|
||||||
|
return Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||||
|
child: Tooltip(
|
||||||
|
message: l10n.shellTabHome,
|
||||||
|
child: Material(
|
||||||
|
type: MaterialType.transparency,
|
||||||
|
child: InkWell(
|
||||||
|
onTap: onTap,
|
||||||
|
borderRadius: BorderRadius.circular(9),
|
||||||
child: ClipRRect(
|
child: ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(9),
|
borderRadius: BorderRadius.circular(9),
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
'assets/icon/halkyon_icon.png',
|
'assets/icon/halkyon_icon.png',
|
||||||
width: 40,
|
width: 40,
|
||||||
height: 40,
|
height: 40,
|
||||||
// The source is 1024 px square; a 40 dp logo needs no more than this
|
// The source is 1024 px square; a 40 dp logo needs no more
|
||||||
// in memory, even at three times the density.
|
// than this in memory, even at three times the density.
|
||||||
cacheWidth: 120,
|
cacheWidth: 120,
|
||||||
semanticLabel: AppLocalizations.of(context).appTitle,
|
semanticLabel: l10n.appTitle,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A tab: its label and icons. Lucide's icons are outlines with few filled
|
/// A tab: its label and icons. Lucide's icons are outlines with few filled
|
||||||
/// companions: the library switches from a closed to an open book, and the
|
/// companions: the library switches from a closed to an open book, and the
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import 'package:halkyon_learn_flutter/src/core/widget/screen_tint.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/core/widget/top_gradient.dart';
|
import 'package:halkyon_learn_flutter/src/core/widget/top_gradient.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
|
import 'package:halkyon_learn_flutter/src/feature/card/data/card_repository.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/card/model/card_content.dart';
|
import 'package:halkyon_learn_flutter/src/feature/card/model/card_content.dart';
|
||||||
|
import 'package:halkyon_learn_flutter/src/feature/home/widget/home_screen.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/studyset/data/studyset_payload.dart';
|
import 'package:halkyon_learn_flutter/src/feature/studyset/data/studyset_payload.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset_content.dart';
|
import 'package:halkyon_learn_flutter/src/feature/studyset/model/studyset_content.dart';
|
||||||
import 'package:halkyon_learn_flutter/src/feature/studyset/widget/studyset_screen.dart';
|
import 'package:halkyon_learn_flutter/src/feature/studyset/widget/studyset_screen.dart';
|
||||||
|
|
@ -175,6 +176,17 @@ void main() {
|
||||||
expect(find.byType(NavigationBar), findsOneWidget);
|
expect(find.byType(NavigationBar), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets("in wider windows, the rail's logo leads Home, as a "
|
||||||
|
"website's does", (tester) async {
|
||||||
|
await showApp(tester);
|
||||||
|
await openJapanese(tester);
|
||||||
|
|
||||||
|
await tester.tap(find.bySemanticsLabel('Halkyon Learn'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(find.byType(HomeScreen), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('in wider windows, the rail stays inside a studyset', (
|
testWidgets('in wider windows, the rail stays inside a studyset', (
|
||||||
tester,
|
tester,
|
||||||
) async {
|
) async {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue