Skip to content
Open
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
22 changes: 22 additions & 0 deletions examples/stac_gallery/assets/json/home_screen.json
Original file line number Diff line number Diff line change
Expand Up @@ -1440,5 +1440,27 @@
"assetPath": "assets/json/backdrop_filter_example.json"
}
}
},
{
"type": "listTile",
"leading": {
"type": "icon",
"icon": "cloud_download"
},
"title": {
"type": "text",
"data": "Stac Network Widget"
},
"subtitle": {
"type": "text",
"data": "Fetch data from network with loading and error states"
},
"onTap": {
"actionType": "navigate",
"widgetJson": {
"type": "exampleScreen",
"assetPath": "assets/json/network_widget_example.json"
}
}
}
]
74 changes: 74 additions & 0 deletions examples/stac_gallery/assets/json/network_widget_example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"type": "scaffold",
"appBar": {
"type": "appBar",
"title": {
"type": "text",
"data": "Network Widget Example"
}
},
"body": {
"type": "networkWidget",
"request": {
"actionType": "networkRequest",
"url": "https://httpbin.org/delay/2",
"method": "get"
},
"loadingWidget": {
"type": "center",
"child": {
"type": "column",
"mainAxisAlignment": "center",
"children": [
{
"type": "circularProgressIndicator"
},
{
"type": "sizedBox",
"height": 16.0
},
{
"type": "text",
"data": "Loading..."
}
]
}
},
"errorWidget": {
"type": "center",
"child": {
"type": "column",
"mainAxisAlignment": "center",
"children": [
{
"type": "icon",
"icon": "error",
"size": 48.0,
"color": "#E53935"
},
{
"type": "sizedBox",
"height": 16.0
},
{
"type": "text",
"data": "Failed to load",
"style": {
"fontSize": 18.0,
"fontWeight": "bold"
}
},
{
"type": "sizedBox",
"height": 8.0
},
{
"type": "text",
"data": "Please check your connection and try again"
}
]
}
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@ class StacNetworkWidgetParser extends StacParser<StacNetworkWidget> {

@override
Widget parse(BuildContext context, StacNetworkWidget model) {
return Stac.fromNetwork(context: context, request: model.request);
return Stac.fromNetwork(
context: context,
request: model.request,
loadingWidget: model.loadingWidget == null
? null
: (ctx) => StacService.fromStacWidget(
widget: model.loadingWidget!,
context: ctx,
) ??
const SizedBox(),
errorWidget: model.errorWidget == null
? null
: (ctx, error) => StacService.fromStacWidget(
widget: model.errorWidget!,
context: ctx,
) ??
const SizedBox(),
);
Comment on lines +21 to +35
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the parse extension method instead from StacWidgetParser. Like

loadingWidget: model.loadingWidget?.parse(context),
errorWidget: model.errorWidget?.parse(context),

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,21 @@ part 'stac_network_widget.g.dart';
@JsonSerializable()
class StacNetworkWidget extends StacWidget {
/// Creates a [StacNetworkWidget].
const StacNetworkWidget({required this.request});
const StacNetworkWidget({
required this.request,
this.loadingWidget,
this.errorWidget,
});

/// The network request to execute.
final StacNetworkRequest request;

/// Optional widget to render while the network request is in progress.
final StacWidget? loadingWidget;

/// Optional widget to render if the network request fails.
final StacWidget? errorWidget;

/// Widget type identifier.
@override
String get type => WidgetType.networkWidget.name;
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import 'package:flutter_test/flutter_test.dart';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we skip this test for now? It will be added again when we include full widget testing.

import 'package:stac_core/stac_core.dart';

void main() {
group('StacNetworkWidget', () {
test('should create from JSON with loadingWidget and errorWidget', () {
// Arrange
const json = {
'type': 'networkWidget',
'request': {
'actionType': 'networkRequest',
'url': 'https://example.com/data',
'method': 'get'
},
'loadingWidget': {
'type': 'text',
'data': 'Loading...'
},
'errorWidget': {
'type': 'text',
'data': 'Error occurred'
}
};

// Act
final widget = StacNetworkWidget.fromJson(json);

// Assert
expect(widget.request.url, equals('https://example.com/data'));
expect(widget.loadingWidget, isNotNull);
expect(widget.errorWidget, isNotNull);
});

test('should create from JSON without optional widgets', () {
// Arrange
const json = {
'type': 'networkWidget',
'request': {
'actionType': 'networkRequest',
'url': 'https://example.com/data',
'method': 'get'
}
};

// Act
final widget = StacNetworkWidget.fromJson(json);

// Assert
expect(widget.request.url, equals('https://example.com/data'));
expect(widget.loadingWidget, isNull);
expect(widget.errorWidget, isNull);
});

test('should serialize to JSON with loadingWidget and errorWidget', () {
// Arrange
final widget = StacNetworkWidget(
request: StacNetworkRequest(
url: 'https://example.com/data',
method: 'get',
),
loadingWidget: StacWidget.fromJson({'type': 'text', 'data': 'Loading...'}),
errorWidget: StacWidget.fromJson({'type': 'text', 'data': 'Error'}),
);

// Act
final json = widget.toJson();

// Assert
expect(json['request'], isNotNull);
expect(json['loadingWidget'], isNotNull);
expect(json['errorWidget'], isNotNull);
expect(json['loadingWidget']['data'], equals('Loading...'));
expect(json['errorWidget']['data'], equals('Error'));
});

test('should serialize to JSON without optional widgets', () {
// Arrange
final widget = StacNetworkWidget(
request: StacNetworkRequest(
url: 'https://example.com/data',
method: 'get',
),
);

// Act
final json = widget.toJson();

// Assert
expect(json['request'], isNotNull);
expect(json['loadingWidget'], isNull);
expect(json['errorWidget'], isNull);
});
});
}

Loading