feat: add Gemini and Spartan protocol support
This commit is contained in:
parent
a4a49f41d7
commit
fa7aa5557c
48 changed files with 4992 additions and 161 deletions
|
|
@ -1,4 +1,6 @@
|
|||
import 'dart:convert' show base64;
|
||||
import 'dart:io' show File;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:drift/native.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
|
@ -24,7 +26,7 @@ void main() {
|
|||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(TextField), findsOneWidget);
|
||||
expect(find.text('Enter a web address'), findsOneWidget);
|
||||
expect(find.text('Enter an address'), findsOneWidget);
|
||||
// The hub opens from the left icon; no floating button remains.
|
||||
expect(find.byIcon(Icons.menu), findsOneWidget);
|
||||
expect(find.byType(FloatingActionButton), findsNothing);
|
||||
|
|
@ -52,7 +54,7 @@ void main() {
|
|||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: StringsScope(
|
||||
strings: (await _strings()),
|
||||
strings: await _strings(),
|
||||
child: MewsPageView(
|
||||
page: page,
|
||||
palette: paletteFor(
|
||||
|
|
@ -77,6 +79,84 @@ void main() {
|
|||
await tester.pump();
|
||||
expect(opened, 'https://example.com/next.html');
|
||||
});
|
||||
|
||||
testWidgets('an image on a capsule arrives over the protocol', (tester) async {
|
||||
// A 1x1 PNG, small enough to spell out.
|
||||
final png = Uint8List.fromList(base64.decode(
|
||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=='));
|
||||
final dot = MewsPage(
|
||||
url: 'gemini://capsule.example/dot.png',
|
||||
lang: 'en',
|
||||
direction: TextDirection.ltr,
|
||||
variant: MewsVariant.plain,
|
||||
specVersion: 'gemtext',
|
||||
entries: const [],
|
||||
body: const [
|
||||
ImageBlock(src: 'gemini://capsule.example/dot.png', alt: 'A dot', allowed: true),
|
||||
],
|
||||
);
|
||||
|
||||
Future<Uint8List?> load(String url) async =>
|
||||
url == 'gemini://capsule.example/dot.png' ? png : null;
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: StringsScope(
|
||||
strings: await _strings(),
|
||||
child: MewsPageView(
|
||||
page: dot,
|
||||
palette: paletteFor(
|
||||
pageVariant: MewsVariant.plain, readerVariant: 'site', dark: false),
|
||||
fontFamily: 'Atkinson Hyperlegible',
|
||||
fontScale: 1.0,
|
||||
visitedUrls: const {},
|
||||
onLinkTap: (_) {},
|
||||
onFormSubmit: (_, _) {},
|
||||
fetchImageBytes: load,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// The image itself, decoded from the protocol's bytes.
|
||||
expect(find.byType(Image), findsOneWidget);
|
||||
|
||||
// An image that never arrives falls back to its alt text, the way a
|
||||
// missing image on the web does.
|
||||
final missing = MewsPage(
|
||||
url: 'gemini://capsule.example/none.png',
|
||||
lang: 'en',
|
||||
direction: TextDirection.ltr,
|
||||
variant: MewsVariant.plain,
|
||||
specVersion: 'gemtext',
|
||||
entries: const [],
|
||||
body: const [
|
||||
ImageBlock(src: 'gemini://capsule.example/none.png', alt: 'A dot', allowed: true),
|
||||
],
|
||||
);
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: StringsScope(
|
||||
strings: await _strings(),
|
||||
child: MewsPageView(
|
||||
page: missing,
|
||||
palette: paletteFor(
|
||||
pageVariant: MewsVariant.plain, readerVariant: 'site', dark: false),
|
||||
fontFamily: 'Atkinson Hyperlegible',
|
||||
fontScale: 1.0,
|
||||
visitedUrls: const {},
|
||||
onLinkTap: (_) {},
|
||||
onFormSubmit: (_, _) {},
|
||||
fetchImageBytes: load,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(Image), findsNothing);
|
||||
expect(find.textContaining('could not be loaded'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
|
||||
Future<Strings> _strings() async {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue