Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions examples/catalog_gallery/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
// found in the LICENSE file.

import 'dart:convert';

import 'package:args/args.dart';
import 'package:file/file.dart';
import 'package:file/local.dart';
import 'package:flutter/material.dart';
import 'package:genui/genui.dart';
import 'package:logging/logging.dart';

import 'samples_view.dart';

Expand All @@ -22,14 +24,14 @@ void main(List<String> args) {
samplesDir = fs.directory(results['samples'] as String);
} else {
final Directory current = fs.currentDirectory;
final Directory defaultSamples = fs
.directory(current.path)
.childDirectory('samples');
final Directory defaultSamples = fs.directory('${current.path}/samples');
if (defaultSamples.existsSync()) {
samplesDir = defaultSamples;
}
}

configureGenUiLogging(level: Level.ALL);

runApp(CatalogGalleryApp(samplesDir: samplesDir, fs: fs));
}

Expand All @@ -48,7 +50,26 @@ class CatalogGalleryApp extends StatefulWidget {
}

class _CatalogGalleryAppState extends State<CatalogGalleryApp> {
final Catalog catalog = CoreCatalogItems.asCatalog();
final Catalog catalog = Catalog([
CoreCatalogItems.audioPlayer,
CoreCatalogItems.button,
CoreCatalogItems.card,
CoreCatalogItems.checkBox,
CoreCatalogItems.column,
CoreCatalogItems.dateTimeInput,
CoreCatalogItems.divider,
CoreCatalogItems.icon,
CoreCatalogItems.image,
CoreCatalogItems.list,
CoreCatalogItems.modal,
CoreCatalogItems.choicePicker,
CoreCatalogItems.row,
CoreCatalogItems.slider,
CoreCatalogItems.tabs,
CoreCatalogItems.text,
CoreCatalogItems.textField,
CoreCatalogItems.video,
], catalogId: 'default');

@override
Widget build(BuildContext context) {
Expand Down
16 changes: 12 additions & 4 deletions examples/catalog_gallery/lib/sample_parser.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ class SampleParser {

static Sample parseString(String content) {
final List<String> lines = const LineSplitter().convert(content);
if (lines.firstOrNull == '---') {
lines.removeAt(0);
}
final int separatorIndex = lines.indexOf('---');

if (separatorIndex == -1) {
Expand All @@ -49,11 +52,16 @@ class SampleParser {
.convert(jsonlBody)
.where((line) => line.trim().isNotEmpty)
.map((line) {
final dynamic json = jsonDecode(line);
if (json is Map<String, dynamic>) {
return A2uiMessage.fromJson(json);
try {
final dynamic json = jsonDecode(line);
if (json is Map<String, dynamic>) {
return A2uiMessage.fromJson(json);
}
throw FormatException('Invalid JSON line: $line');
} on FormatException catch (e) {
print('Error parsing line: $line, error: $e');
rethrow;
}
throw FormatException('Invalid JSON line: $line');
}),
);

Expand Down
24 changes: 7 additions & 17 deletions examples/catalog_gallery/lib/samples_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -68,23 +68,12 @@ class _SamplesViewState extends State<SamplesView> {
});
}
} else if (update is SurfaceRemoved) {
if (_surfaceIds.contains(update.surfaceId)) {
setState(() {
final int removeIndex = _surfaceIds.indexOf(update.surfaceId);
_surfaceIds.removeAt(removeIndex);
if (_surfaceIds.isEmpty) {
_currentSurfaceIndex = 0;
} else {
if (_currentSurfaceIndex >= removeIndex &&
_currentSurfaceIndex > 0) {
_currentSurfaceIndex--;
}
if (_currentSurfaceIndex >= _surfaceIds.length) {
_currentSurfaceIndex = _surfaceIds.length - 1;
}
}
});
}
setState(() {
_surfaceIds.remove(update.surfaceId);
if (_currentSurfaceIndex >= _surfaceIds.length) {
_currentSurfaceIndex = 0;
}
});
}
});
}
Expand All @@ -99,6 +88,7 @@ class _SamplesViewState extends State<SamplesView> {
.toList();
setState(() {
_sampleFiles = files;
_sampleFiles.sort((a, b) => a.path.compareTo(b.path));
});
}

Expand Down
1 change: 1 addition & 0 deletions examples/catalog_gallery/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ dependencies:
sdk: flutter
genui: ^0.5.1
json_schema_builder: ^0.1.3
logging: ^1.3.0
yaml: ^3.1.3

dev_dependencies:
Expand Down
5 changes: 3 additions & 2 deletions examples/catalog_gallery/samples/hello_world.sample
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
name: Test Sample
description: This is a test sample to verify the parser.
---
{"surfaceUpdate": {"surfaceId": "default", "components": [{"id": "text1", "component": {"Text": {"text": {"literalString": "Hello World"}}}}]}}
{"beginRendering": {"surfaceId": "default", "root": "text1"}}
{"surfaceUpdate": {"surfaceId": "default", "components": [{"id": "root", "props": { "component": "Text", "text": {"literalString": "Hello World"}}}]}}
{"createSurface": {"surfaceId": "default"}}
13 changes: 6 additions & 7 deletions examples/catalog_gallery/test/sample_parser_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ void main() {
name: Test Sample
description: A test description
---
{"surfaceUpdate": {"surfaceId": "default", "components": [{"id": "text1", "component": {"Text": {"text": {"literalString": "Hello"}}}}]}}
{"beginRendering": {"surfaceId": "default", "root": "text1"}}
{"updateComponents": {"surfaceId": "default", "components": [{"id": "text1", "component": "Text", "text": {"literalString": "Hello"}}]}}
{"createSurface": {"surfaceId": "default", "catalogId": "standard"}}
''';

final Sample sample = SampleParser.parseString(sampleContent);
Expand All @@ -23,17 +23,16 @@ description: A test description

final List<A2uiMessage> messages = await sample.messages.toList();
expect(messages.length, 2);
expect(messages.first, isA<SurfaceUpdate>());
expect(messages.last, isA<BeginRendering>());
expect(messages.first, isA<UpdateComponents>());
expect(messages.last, isA<CreateSurface>());

final update = messages.first as SurfaceUpdate;
final update = messages.first as UpdateComponents;
expect(update.surfaceId, 'default');
expect(update.components.length, 1);
expect(update.components.first.type, 'Text');

final begin = messages.last as BeginRendering;
final begin = messages.last as CreateSurface;
expect(begin.surfaceId, 'default');
expect(begin.root, 'text1');
});

test('SampleParser throws on missing separator', () {
Expand Down
44 changes: 42 additions & 2 deletions examples/catalog_gallery/test/widget_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import 'package:file/memory.dart';
import 'package:file/src/interface/directory.dart';
import 'package:file/src/interface/file.dart';

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
Expand All @@ -25,9 +26,10 @@ void main() {
final File sampleFile = samplesDir.childFile('test.sample');
sampleFile.writeAsStringSync('''
name: Test Sample
description: A test description
description: This is a test sample to verify the parser.
---
{"surfaceUpdate": {"surfaceId": "default", "components": [{"id": "text1", "component": {"Text": {"text": {"literalString": "Hello"}}}}]}}
{"surfaceUpdate": {"surfaceId": "default", "components": [{"id": "text1", "component": {"Text": {"text": {"literalString": "Hello World"}}}}]}}
{"beginRendering": {"surfaceId": "default", "root": "text1"}}
''');

await tester.pumpWidget(CatalogGalleryApp(samplesDir: samplesDir, fs: fs));
Expand All @@ -41,7 +43,45 @@ description: A test description
await tester.tap(find.text('Samples'));
await tester.pumpAndSettle();

// Verify that the sample file is listed.
// Verify that the sample file is listed.
expect(find.text('test'), findsOneWidget);
});

testWidgets('Loads sample with CreateSurface before SurfaceUpdate', (
WidgetTester tester,
) async {
final fs = MemoryFileSystem();
final Directory samplesDir = fs.directory('/samples')..createSync();
final File sampleFile = samplesDir.childFile('ordered.sample');
sampleFile.writeAsStringSync('''
name: Ordered Sample
description: Testing order.
---
{"createSurface": {"surfaceId": "s1", "catalogId": "default"}}
{"updateComponents": {"surfaceId": "s1", "components": [{"id": "root", "component": "Text", "text": {"literalString": "Ordered Success"}}]}}
''');

await tester.pumpWidget(Container()); // Clear previous widget tree
await tester.pumpAndSettle();
await tester.pumpWidget(
CatalogGalleryApp(key: UniqueKey(), samplesDir: samplesDir, fs: fs),
);
await tester.pumpAndSettle();

// Tap on the Samples tab to load the view
await tester.tap(find.text('Samples'));
await tester.pumpAndSettle();

// Verify sample is listed
expect(find.text('ordered'), findsOneWidget);

// Tap on sample
await tester.tap(find.text('ordered'));
await tester.pumpAndSettle();

// Verify surface is created and content is shown
expect(find.text('s1'), findsOneWidget); // Surface tab
expect(find.text('Ordered Success'), findsOneWidget); // Content
});
}
80 changes: 34 additions & 46 deletions examples/custom_backend/assets/data/saved-response-1.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,62 +9,50 @@
"args": {
"components": [
{
"component": {
"Heading": {
"level": "3",
"text": {
"literalString": "Here are some of the things I can help you with:"
}
}
"component": "Heading",
"level": "3",
"text": {
"literalString": "Here are some of the things I can help you with:"
},
"id": "heading_1"
},
{
"id": "multiple_choice_1",
"component": {
"MultipleChoice": {
"options": [
{
"label": {
"literalString": "Show a cat fact"
},
"value": "Show a cat fact"
},
{
"label": {
"literalString": "Show a dog fact"
},
"value": "Show a dog fact"
},
{
"value": "Help me generate UI",
"label": {
"literalString": "Help me generate UI"
}
},
{
"label": {
"literalString": "Answer a question"
},
"value": "Answer a question"
}
],
"selections": {
"path": "selection"
"component": "ChoicePicker",
"options": [
{
"label": {
"literalString": "Show a cat fact"
},
"value": "Show a cat fact"
},
{
"label": {
"literalString": "Show a dog fact"
},
"value": "Show a dog fact"
},
{
"value": "Help me generate UI",
"label": {
"literalString": "Help me generate UI"
}
},
{
"label": {
"literalString": "Answer a question"
},
"value": "Answer a question"
}
],
"value": {
"path": "selection"
}
},
{
"component": {
"Column": {
"children": {
"explicitList": [
"heading_1",
"multiple_choice_1"
]
}
}
"component": "Column",
"children": {
"explicitList": ["heading_1", "multiple_choice_1"]
},
"id": "root"
}
Expand Down
Loading
Loading