Skip to content

Commit

Permalink
[flutter_adaptive_scaffold] Fuchsia is mobile. (flutter#2727)
Browse files Browse the repository at this point in the history
  • Loading branch information
a-wallen authored Oct 24, 2022
1 parent b85f308 commit 0e6f7fd
Show file tree
Hide file tree
Showing 7 changed files with 307 additions and 153 deletions.
4 changes: 4 additions & 0 deletions packages/flutter_adaptive_scaffold/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.0.8

Make fuchsia a mobile platform.

## 0.0.7

* Patch duplicate key error in SlotLayout.
Expand Down
27 changes: 13 additions & 14 deletions packages/flutter_adaptive_scaffold/lib/src/breakpoints.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@
import 'package:flutter/material.dart';

const Set<TargetPlatform> _desktop = <TargetPlatform>{
TargetPlatform.fuchsia,
TargetPlatform.linux,
TargetPlatform.macOS,
TargetPlatform.windows
};

const Set<TargetPlatform> _mobile = <TargetPlatform>{
TargetPlatform.android,
TargetPlatform.fuchsia,
TargetPlatform.iOS,
TargetPlatform.android
};

/// A group of standard breakpoints built according to the material
Expand Down Expand Up @@ -89,18 +90,16 @@ class WidthPlatformBreakpoint extends Breakpoint {

@override
bool isActive(BuildContext context) {
bool size = false;
final bool isRightPlatform =
platform?.contains(Theme.of(context).platform) ?? true;
if (begin != null && end != null) {
size = MediaQuery.of(context).size.width >= begin! &&
MediaQuery.of(context).size.width < end!;
} else if (begin != null && end == null) {
size = MediaQuery.of(context).size.width >= begin!;
} else if (begin == null && end != null) {
size = MediaQuery.of(context).size.width < end!;
}
return size && isRightPlatform;
final TargetPlatform host = Theme.of(context).platform;
final bool isRightPlatform = platform?.contains(host) ?? true;

// Null boundaries are unbounded, assign the max/min of their associated
// direction on a number line.
final double width = MediaQuery.of(context).size.width;
final double lowerBound = begin ?? double.negativeInfinity;
final double upperBound = end ?? double.infinity;

return width >= lowerBound && width < upperBound && isRightPlatform;
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_adaptive_scaffold/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: flutter_adaptive_scaffold
description: Widgets to easily build adaptive layouts, including navigation elements.
version: 0.0.7
version: 0.0.8
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_adaptive_scaffold%22
repository: https://github.com/flutter/packages/tree/main/packages/flutter_adaptive_scaffold

Expand Down
154 changes: 16 additions & 138 deletions packages/flutter_adaptive_scaffold/test/adaptive_scaffold_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@

import 'package:flutter/material.dart';
import 'package:flutter_adaptive_scaffold/src/adaptive_scaffold.dart';
import 'package:flutter_adaptive_scaffold/src/breakpoints.dart';
import 'package:flutter_test/flutter_test.dart';
import 'simulated_layout.dart';
import 'test_breakpoints.dart';

void main() {
testWidgets('adaptive scaffold lays out slots as expected',
Expand All @@ -20,8 +21,8 @@ void main() {
final Finder primaryNav = find.byKey(const Key('primaryNavigation'));
final Finder primaryNav1 = find.byKey(const Key('primaryNavigation1'));

await tester.binding.setSurfaceSize(SimulatedLayout.mobile.size);
await tester.pumpWidget(SimulatedLayout.mobile.app());
await tester.binding.setSurfaceSize(SimulatedLayout.small.size);
await tester.pumpWidget(SimulatedLayout.small.app());
await tester.pumpAndSettle();

expect(smallBody, findsOneWidget);
Expand All @@ -33,8 +34,8 @@ void main() {
expect(tester.getTopLeft(smallSBody), const Offset(200, 0));
expect(tester.getTopLeft(bottomNav), const Offset(0, 744));

await tester.binding.setSurfaceSize(SimulatedLayout.tablet.size);
await tester.pumpWidget(SimulatedLayout.tablet.app());
await tester.binding.setSurfaceSize(SimulatedLayout.medium.size);
await tester.pumpWidget(SimulatedLayout.medium.app());
await tester.pumpAndSettle();

expect(smallBody, findsNothing);
Expand All @@ -49,8 +50,8 @@ void main() {
expect(tester.getTopLeft(primaryNav), Offset.zero);
expect(tester.getBottomRight(primaryNav), const Offset(88, 800));

await tester.binding.setSurfaceSize(SimulatedLayout.desktop.size);
await tester.pumpWidget(SimulatedLayout.desktop.app());
await tester.binding.setSurfaceSize(SimulatedLayout.large.size);
await tester.pumpWidget(SimulatedLayout.large.app());
await tester.pumpAndSettle();

expect(body, findsNothing);
Expand All @@ -71,10 +72,10 @@ void main() {
final Finder b = find.byKey(const Key('body'));
final Finder sBody = find.byKey(const Key('sBody'));

await tester.binding.setSurfaceSize(SimulatedLayout.mobile.size);
await tester.pumpWidget(SimulatedLayout.mobile.app());
await tester.binding.setSurfaceSize(SimulatedLayout.tablet.size);
await tester.pumpWidget(SimulatedLayout.tablet.app());
await tester.binding.setSurfaceSize(SimulatedLayout.small.size);
await tester.pumpWidget(SimulatedLayout.small.app());
await tester.binding.setSurfaceSize(SimulatedLayout.medium.size);
await tester.pumpWidget(SimulatedLayout.medium.app());

await tester.pump();
await tester.pump(const Duration(milliseconds: 200));
Expand Down Expand Up @@ -112,11 +113,11 @@ void main() {
final Finder b = find.byKey(const Key('body'));
final Finder sBody = find.byKey(const Key('sBody'));

await tester.binding.setSurfaceSize(SimulatedLayout.mobile.size);
await tester.pumpWidget(SimulatedLayout.mobile.app(animations: false));
await tester.binding.setSurfaceSize(SimulatedLayout.small.size);
await tester.pumpWidget(SimulatedLayout.small.app(animations: false));

await tester.binding.setSurfaceSize(SimulatedLayout.tablet.size);
await tester.pumpWidget(SimulatedLayout.tablet.app(animations: false));
await tester.binding.setSurfaceSize(SimulatedLayout.medium.size);
await tester.pumpWidget(SimulatedLayout.medium.app(animations: false));

await tester.pump();
await tester.pump(const Duration(milliseconds: 200));
Expand Down Expand Up @@ -209,126 +210,3 @@ class PreferredSizeWidgetImpl extends StatelessWidget
@override
Size get preferredSize => const Size(200, 200);
}

class TestBreakpoint0 extends Breakpoint {
@override
bool isActive(BuildContext context) {
return MediaQuery.of(context).size.width >= 0 &&
MediaQuery.of(context).size.width < 800;
}
}

class TestBreakpoint800 extends Breakpoint {
@override
bool isActive(BuildContext context) {
return MediaQuery.of(context).size.width >= 800 &&
MediaQuery.of(context).size.width < 1000;
}
}

class TestBreakpoint1000 extends Breakpoint {
@override
bool isActive(BuildContext context) {
return MediaQuery.of(context).size.width >= 1000;
}
}

class NeverOnBreakpoint extends Breakpoint {
@override
bool isActive(BuildContext context) {
return false;
}
}

class TestScaffold extends StatefulWidget {
const TestScaffold({
super.key,
this.initialIndex = 0,
this.isAnimated = true,
});

final int initialIndex;
final bool isAnimated;

static const List<NavigationDestination> destinations =
<NavigationDestination>[
NavigationDestination(
key: Key('Inbox'),
icon: Icon(Icons.inbox),
label: 'Inbox',
),
NavigationDestination(
key: Key('Articles'),
icon: Icon(Icons.article),
label: 'Articles',
),
NavigationDestination(
key: Key('Chat'),
icon: Icon(Icons.chat),
label: 'Chat',
),
];

@override
State<TestScaffold> createState() => TestScaffoldState();
}

class TestScaffoldState extends State<TestScaffold> {
late int index = widget.initialIndex;

@override
Widget build(BuildContext context) {
return AdaptiveScaffold(
selectedIndex: index,
onSelectedIndexChange: (int index) {
setState(() {
this.index = index;
});
},
drawerBreakpoint: NeverOnBreakpoint(),
internalAnimations: widget.isAnimated,
smallBreakpoint: TestBreakpoint0(),
mediumBreakpoint: TestBreakpoint800(),
largeBreakpoint: TestBreakpoint1000(),
destinations: TestScaffold.destinations,
smallBody: (_) => Container(color: Colors.red),
body: (_) => Container(color: Colors.green),
largeBody: (_) => Container(color: Colors.blue),
smallSecondaryBody: (_) => Container(color: Colors.red),
secondaryBody: (_) => Container(color: Colors.green),
largeSecondaryBody: (_) => Container(color: Colors.blue),
);
}
}

enum SimulatedLayout {
mobile(width: 400, navSlotKey: 'bottomNavigation'),
tablet(width: 800, navSlotKey: 'primaryNavigation'),
desktop(width: 1100, navSlotKey: 'primaryNavigation1');

const SimulatedLayout({
required double width,
required this.navSlotKey,
}) : _width = width;

final double _width;
final double _height = 800;
final String navSlotKey;

Size get size => Size(_width, _height);

MaterialApp app({
int initialIndex = 0,
bool animations = true,
}) {
return MaterialApp(
home: MediaQuery(
data: MediaQueryData(size: size),
child: TestScaffold(
initialIndex: initialIndex,
isAnimated: animations,
),
),
);
}
}
54 changes: 54 additions & 0 deletions packages/flutter_adaptive_scaffold/test/breakpoint_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'simulated_layout.dart';

void main() {
testWidgets('Desktop breakpoints do not show on mobile device',
(WidgetTester tester) async {
// Pump a small layout on a mobile device. The small slot
// should give the mobile slot layout, not the desktop layout.
await tester.pumpWidget(SimulatedLayout.small.slot);
await tester.pumpAndSettle();
expect(find.byKey(const Key('Breakpoints.smallMobile')), findsOneWidget);
expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsNothing);

// Do the same with a medium layout on a mobile
await tester.pumpWidget(SimulatedLayout.medium.slot);
await tester.pumpAndSettle();
expect(find.byKey(const Key('Breakpoints.mediumMobile')), findsOneWidget);
expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsNothing);

// Large layout on mobile
await tester.pumpWidget(SimulatedLayout.large.slot);
await tester.pumpAndSettle();
expect(find.byKey(const Key('Breakpoints.largeMobile')), findsOneWidget);
expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsNothing);
}, variant: TargetPlatformVariant.mobile());

testWidgets('Mobile breakpoints do not show on desktop device',
(WidgetTester tester) async {
// Pump a small layout on a desktop device. The small slot
// should give the mobile slot layout, not the desktop layout.
await tester.pumpWidget(SimulatedLayout.small.slot);
await tester.pumpAndSettle();
expect(find.byKey(const Key('Breakpoints.smallDesktop')), findsOneWidget);
expect(find.byKey(const Key('Breakpoints.smallMobile')), findsNothing);

// Do the same with a medium layout on a desktop
await tester.pumpWidget(SimulatedLayout.medium.slot);
await tester.pumpAndSettle();
expect(find.byKey(const Key('Breakpoints.mediumDesktop')), findsOneWidget);
expect(find.byKey(const Key('Breakpoints.mediumMobile')), findsNothing);

// Large layout on desktop
await tester.pumpWidget(SimulatedLayout.large.slot);
await tester.pumpAndSettle();
expect(find.byKey(const Key('Breakpoints.largeDesktop')), findsOneWidget);
expect(find.byKey(const Key('Breakpoints.largeMobile')), findsNothing);
}, variant: TargetPlatformVariant.desktop());
}
Loading

0 comments on commit 0e6f7fd

Please sign in to comment.