fix: optimized swiping and address bar toggle on tap
This commit is contained in:
parent
ac998b394d
commit
0e2027c9e2
5 changed files with 466 additions and 78 deletions
|
|
@ -485,6 +485,61 @@ void main() {
|
|||
expect(find.byType(AddressBar), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('a short tap on the page brings a hidden address bar back',
|
||||
(tester) async {
|
||||
await pumpApp(tester);
|
||||
|
||||
// A page long enough to scroll.
|
||||
final tall = pageSource.replaceFirst(
|
||||
'</body>',
|
||||
'<p>Padding paragraph to make the page scroll.</p>' * 80 + '</body>');
|
||||
final page = parseSource(tall, 'https://example.com/index.html');
|
||||
deps.browser.currentPage.value = page;
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Scrolling down hides the address bar.
|
||||
await tester.drag(find.byType(ListView), const Offset(0, -300));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(AddressBar), findsNothing);
|
||||
|
||||
// A short tap on the page text returns it, the way a reader reaches
|
||||
// for it on a page that has nothing left to scroll.
|
||||
await tester.tapAt(tester.getCenter(find.byType(ListView)));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(AddressBar), findsOneWidget);
|
||||
|
||||
// A short tap hides it again.
|
||||
await tester.tapAt(tester.getCenter(find.byType(ListView)));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(AddressBar), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('a tap that opens a link keeps the address bar where it was',
|
||||
(tester) async {
|
||||
final sources = {
|
||||
'https://example.com/index.html': _page(
|
||||
'Index', '<h1>Index</h1><p><a href="next.html">The next page</a></p>'),
|
||||
'https://example.com/next.html':
|
||||
_page('Next', '<h1>Next</h1><p>The second page.</p>'),
|
||||
};
|
||||
final stubDeps = AppDependencies(
|
||||
database: MewsDatabase.test(NativeDatabase.memory()),
|
||||
fetch: FakeFetch(sources),
|
||||
strings: strings,
|
||||
);
|
||||
await tester.pumpWidget(MewsApp(deps: stubDeps, strings: strings));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await stubDeps.browser.open('https://example.com/index.html');
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// The tap follows a link, so it does not spend itself on the chrome.
|
||||
await tapRun(tester, 'The next page');
|
||||
|
||||
expect(stubDeps.browser.currentPage.value?.url, 'https://example.com/next.html');
|
||||
expect(find.byType(AddressBar), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('swiping back shows the previous page during the drag',
|
||||
(tester) async {
|
||||
final sources = {
|
||||
|
|
@ -528,6 +583,102 @@ void main() {
|
|||
expect(find.text('https://example.com/a.html'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('a swipe across the body navigates on a touch host',
|
||||
(tester) async {
|
||||
final sources = {
|
||||
'https://example.com/a.html':
|
||||
_page('Page A', '<h1>Page A</h1><p>The first pages content.</p>'),
|
||||
'https://example.com/b.html':
|
||||
_page('Page B', '<h1>Page B</h1><p>The second pages content.</p>'),
|
||||
};
|
||||
final stubDeps = AppDependencies(
|
||||
database: MewsDatabase.test(NativeDatabase.memory()),
|
||||
fetch: FakeFetch(sources),
|
||||
strings: strings,
|
||||
);
|
||||
await tester.pumpWidget(MewsApp(deps: stubDeps, strings: strings));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await stubDeps.browser.open('https://example.com/a.html');
|
||||
await stubDeps.browser.open('https://example.com/b.html');
|
||||
await _pumpUntil(tester, () => stubDeps.browser.backPage.value != null);
|
||||
|
||||
// The drag starts over the body text, not in an edge margin; a swipe
|
||||
// crosses the slop before the long press that starts a selection.
|
||||
final center = tester.getCenter(find.byType(SwipeNavigator));
|
||||
final gesture = await tester.startGesture(center);
|
||||
for (var i = 0; i < 6; i++) {
|
||||
await gesture.moveBy(const Offset(70, 0));
|
||||
await tester.pump();
|
||||
}
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(stubDeps.browser.currentPage.value?.url, 'https://example.com/a.html');
|
||||
});
|
||||
|
||||
testWidgets('a long press on body text keeps its drag for selection',
|
||||
(tester) async {
|
||||
final sources = {
|
||||
'https://example.com/a.html':
|
||||
_page('Page A', '<h1>Page A</h1><p>The first pages content.</p>'),
|
||||
'https://example.com/b.html':
|
||||
_page('Page B', '<h1>Page B</h1><p>The second pages content.</p>'),
|
||||
};
|
||||
final stubDeps = AppDependencies(
|
||||
database: MewsDatabase.test(NativeDatabase.memory()),
|
||||
fetch: FakeFetch(sources),
|
||||
strings: strings,
|
||||
);
|
||||
await tester.pumpWidget(MewsApp(deps: stubDeps, strings: strings));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await stubDeps.browser.open('https://example.com/a.html');
|
||||
await stubDeps.browser.open('https://example.com/b.html');
|
||||
await _pumpUntil(tester, () => stubDeps.browser.backPage.value != null);
|
||||
|
||||
// Hold on the paragraph long enough for the selection to begin, then
|
||||
// drag sideways: the selection keeps the finger, the page stays put.
|
||||
final text = tester.getCenter(find.textContaining('The second pages content'));
|
||||
final gesture = await tester.startGesture(text);
|
||||
await tester.pump(const Duration(milliseconds: 550));
|
||||
await gesture.moveBy(
|
||||
const Offset(300, 0),
|
||||
timeStamp: const Duration(milliseconds: 600),
|
||||
);
|
||||
await tester.pump();
|
||||
// No neighbor peeks in; the swipe never started.
|
||||
expect(find.text('Page A'), findsNothing);
|
||||
await gesture.up();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(stubDeps.browser.currentPage.value?.url, 'https://example.com/b.html');
|
||||
});
|
||||
|
||||
testWidgets('the chrome starts below the status bar on a phone',
|
||||
(tester) async {
|
||||
// View padding arrives in physical pixels; the framework scales it by
|
||||
// the device pixel ratio to the logical inset the reader sits below.
|
||||
final previous = tester.view.padding;
|
||||
tester.view.padding = FakeViewPadding(
|
||||
left: 0,
|
||||
right: 0,
|
||||
top: 44 * tester.view.devicePixelRatio,
|
||||
bottom: 0,
|
||||
);
|
||||
addTearDown(() => tester.view.padding = previous);
|
||||
|
||||
final stubDeps = AppDependencies(
|
||||
database: MewsDatabase.test(NativeDatabase.memory()),
|
||||
fetch: FakeFetch(const {}),
|
||||
strings: strings,
|
||||
);
|
||||
await tester.pumpWidget(MewsApp(deps: stubDeps, strings: strings));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(tester.getTopLeft(find.byType(AddressBar)).dy, 44);
|
||||
});
|
||||
|
||||
testWidgets('falls back to the wap subdomain before showing an error',
|
||||
(tester) async {
|
||||
final stubDeps = AppDependencies(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue