Skip to content
This repository has been archived by the owner on Jun 1, 2024. It is now read-only.

feat: add screen request in flutter #1392

Merged
merged 9 commits into from
Feb 26, 2021
Merged
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
2 changes: 1 addition & 1 deletion flutter/beagle/assets/js/beagle.js

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions flutter/beagle/lib/beagle.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,5 @@ export 'package:beagle/model/beagle_ui_element.dart';
export 'package:beagle/beagle_widget.dart';
export 'package:beagle/model/beagle_config.dart';
export 'package:beagle/model/beagle_environment.dart';
export 'package:beagle/networking/beagle_request.dart';
export 'package:beagle/networking/beagle_screen_request.dart';
6 changes: 3 additions & 3 deletions flutter/beagle/lib/beagle_sdk.dart
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import 'package:beagle/interface/navigation_controller.dart';
import 'package:beagle/interface/storage.dart';
import 'package:beagle/logger/beagle_logger.dart';
import 'package:beagle/model/beagle_config.dart';
import 'package:beagle/model/network_strategy.dart';
import 'package:beagle/networking/beagle_network_strategy.dart';
import 'package:beagle/service_locator.dart';
import 'package:beagle/setup/beagle_design_system.dart';

Expand All @@ -50,7 +50,7 @@ class BeagleSdk {
Storage storage,
bool useBeagleHeaders,
Map<String, ActionHandler> actions,
NetworkStrategy strategy,
BeagleNetworkStrategy strategy,
Map<String, NavigationController> navigationControllers,
DesignSystem designSystem,
BeagleImageDownloader imageDownloader,
Expand All @@ -72,7 +72,7 @@ class BeagleSdk {
useBeagleHeaders: useBeagleHeaders ?? true,
actions:
actions == null ? defaultActions : {...defaultActions, ...actions},
strategy: strategy ?? NetworkStrategy.beagleWithFallbackToCache,
strategy: strategy ?? BeagleNetworkStrategy.beagleWithFallbackToCache,
navigationControllers: navigationControllers,
);
}
Expand Down
21 changes: 11 additions & 10 deletions flutter/beagle/lib/beagle_widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import 'package:beagle/components/beagle_undefined_widget.dart';
import 'package:beagle/interface/beagle_view.dart';
import 'package:beagle/model/beagle_ui_element.dart';
import 'package:beagle/model/route.dart';
import 'package:beagle/networking/beagle_screen_request.dart';
import 'package:flutter/widgets.dart';

typedef OnCreateViewListener = void Function(BeagleView view);
Expand All @@ -31,17 +32,17 @@ typedef OnCreateViewListener = void Function(BeagleView view);
class BeagleWidget extends StatefulWidget {
const BeagleWidget({
Key key,
this.url,
this.onCreateView,
this.screenJson,
this.screenRequest,
}) : super(key: key);

/// Server URL will be used to make a request.
final String url;

/// that represents a local screen to be shown.
final String screenJson;

/// provides the url, method, headers and body to the request.
final BeagleScreenRequest screenRequest;

/// get a current BeagleView.
final OnCreateViewListener onCreateView;

Expand All @@ -62,17 +63,17 @@ class _BeagleWidget extends State<BeagleWidget> {

Future<void> _startBeagleView() async {
await BeagleSdk.getService().start();

_view = BeagleSdk.getService().createView()
..subscribe((tree) {
_view = BeagleSdk.getService().createView(
networkOptions: widget.screenRequest,
)..subscribe((tree) {
final widgetLoaded = _buildViewFromTree(tree);
setState(() {
widgetState = widgetLoaded;
});
});

if (widget.url != null) {
await _view.getNavigator().pushView(RemoteView(widget.url));
if (widget.screenRequest != null) {
await _view.getNavigator().pushView(RemoteView(widget.screenRequest.url));
} else {
await _view
.getNavigator()
Expand All @@ -95,6 +96,6 @@ class _BeagleWidget extends State<BeagleWidget> {

@override
Widget build(BuildContext context) {
return widgetState ?? const SizedBox.shrink();
return widgetState ?? const SizedBox.shrink();
}
}
21 changes: 14 additions & 7 deletions flutter/beagle/lib/bridge_impl/beagle_js_engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,17 @@ import 'package:beagle/interface/storage.dart';
import 'package:beagle/interface/types.dart';
import 'package:beagle/model/beagle_action.dart';
import 'package:beagle/model/beagle_ui_element.dart';
import 'package:beagle/model/request.dart';
import 'package:beagle/model/response.dart';
import 'package:beagle/networking/beagle_network_options.dart';
import 'package:beagle/networking/beagle_request.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:flutter_js/flutter_js.dart';

typedef ActionListener = void Function(
{BeagleAction action, BeagleView view, BeagleUIElement element});

typedef HttpListener = void Function(String requestId, Request request);
typedef HttpListener = void Function(String requestId, BeagleRequest request);

/// Provides an interface to run javascript code and listen to Beagle's core
/// events.
Expand Down Expand Up @@ -273,12 +274,18 @@ class BeagleJSEngine {
}
}

// todo: increment this to pass more configurations
/// Creates a new BeagleView and returns the created view id.
String createBeagleView() {
final result = _jsRuntime.evaluate('global.beagle.createBeagleView()');
final id = result.stringResult;
debugPrint('created beagle view with id $id');
String createBeagleView({
BeagleNetworkOptions networkOptions,
String initialControllerId,
}) {
final params = [BeagleNetworkOptions.toJsonEncode(networkOptions)];
if (initialControllerId != null) {
params.add(initialControllerId);
}
final script = 'global.beagle.createBeagleView(${params.join(', ')})';
final id = _jsRuntime.evaluate(script).stringResult;

return id;
}

Expand Down
16 changes: 8 additions & 8 deletions flutter/beagle/lib/bridge_impl/beagle_js_request_message.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
* limitations under the License.
*/

import 'package:beagle/bridge_impl/beagle_supported_http_methods.dart';
import 'package:beagle/model/request.dart';
import 'package:flutter_js/extensions/xhr.dart';
import 'package:beagle/networking/beagle_http_method.dart';
import 'package:beagle/networking/beagle_request.dart';
import 'package:beagle/utils/enum.dart';

/// Encapsulates a Beagle javascript HTTP request message.
class BeagleJSRequestMessage {
Expand All @@ -30,15 +30,15 @@ class BeagleJSRequestMessage {

String _requestId;
String _url;
HttpMethod _method;
BeagleHttpMethod _method;
Map<String, String> _headers;
String _body;

HttpMethod _getHttpMethod(Map<String, dynamic> json) {
BeagleHttpMethod _getHttpMethod(Map<String, dynamic> json) {
final String httpMethodStr =
json.containsKey('method') ? json['method'].toLowerCase() : 'get';

return BeagleSupportedHttpMethods().getHttpMethod(httpMethodStr);
return EnumUtils.fromString(BeagleHttpMethod.values, httpMethodStr);
}

Map<String, String> _getHeaders(Map<String, dynamic> json) {
Expand All @@ -50,7 +50,7 @@ class BeagleJSRequestMessage {

String get requestId => _requestId;

Request toRequest() {
return Request(_url, method: _method, headers: _headers, body: _body);
BeagleRequest toRequest() {
return BeagleRequest(_url, method: _method, headers: _headers, body: _body);
}
}
33 changes: 13 additions & 20 deletions flutter/beagle/lib/bridge_impl/beagle_service_js.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ import 'package:beagle/interface/global_context.dart';
import 'package:beagle/interface/http_client.dart';
import 'package:beagle/interface/navigation_controller.dart';
import 'package:beagle/interface/storage.dart';
import 'package:beagle/model/network_options.dart';
import 'package:beagle/model/network_strategy.dart';
import 'package:beagle/model/request.dart';
import 'package:beagle/networking/beagle_network_options.dart';
import 'package:beagle/networking/beagle_network_strategy.dart';
import 'package:beagle/networking/beagle_request.dart';
import 'package:beagle/utils/network_strategy.dart';

class BeagleServiceJS implements BeagleService {
BeagleServiceJS(
Expand Down Expand Up @@ -60,7 +61,7 @@ class BeagleServiceJS implements BeagleService {
@override
Map<String, ActionHandler> actions;
@override
NetworkStrategy strategy;
BeagleNetworkStrategy strategy;
@override
Map<String, NavigationController> navigationControllers;
@override
Expand Down Expand Up @@ -88,18 +89,6 @@ class BeagleServiceJS implements BeagleService {
return result;
}

// transforms the enum NetworkStrategy into the string expected by beagle web (js)
String getJsStrategyName() {
/* When calling toString in an enum, it returns EnumName.EnumValue, we just need the part after
the ".", which will give us the strategy name in camelCase. */
final strategyNameInCamelCase = strategy.toString().split('.')[1];
/* beagle web needs the strategy name in kebab-case, we use a regex to replace the uppercase
letters with a hyphen and the lower case equivalent. */
final strategyNameInKebabCase = strategyNameInCamelCase.replaceAllMapped(
RegExp('[A-Z]'), (match) => '-${match[0].toLowerCase()}');
return strategyNameInKebabCase;
}

@override
Future<void> start() async {
await _beagleJSEngine.start(storage: storage);
Expand All @@ -114,7 +103,7 @@ class BeagleServiceJS implements BeagleService {
'baseUrl': baseUrl,
'actionKeys': actions.keys.toList(),
'useBeagleHeaders': useBeagleHeaders,
'strategy': getJsStrategyName(),
'strategy': NetworkStrategyUtils.getJsStrategyName(strategy),
};
final navigationControllers = getNavigationControllersAsMap();
if (navigationControllers != null) {
Expand All @@ -125,7 +114,7 @@ class BeagleServiceJS implements BeagleService {
}

void _registerHttpListener() {
_beagleJSEngine.onHttpRequest((String id, Request request) async {
_beagleJSEngine.onHttpRequest((String id, BeagleRequest request) async {
final response = await httpClient.sendRequest(request);
_beagleJSEngine.respondHttpRequest(id, response);
});
Expand All @@ -143,7 +132,11 @@ class BeagleServiceJS implements BeagleService {

@override
BeagleView createView(
{NetworkOptions networkOptions, String initialControllerId}) {
return BeagleViewJS(_beagleJSEngine);
{BeagleNetworkOptions networkOptions, String initialControllerId}) {
return BeagleViewJS(
_beagleJSEngine,
networkOptions: networkOptions,
initialControllerId: initialControllerId,
);
}
}
39 changes: 0 additions & 39 deletions flutter/beagle/lib/bridge_impl/beagle_supported_http_methods.dart

This file was deleted.

11 changes: 6 additions & 5 deletions flutter/beagle/lib/bridge_impl/beagle_view_js.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ import 'package:beagle/interface/beagle_navigator.dart';
import 'package:beagle/interface/beagle_view.dart';
import 'package:beagle/interface/renderer.dart';
import 'package:beagle/model/beagle_ui_element.dart';
import 'package:beagle/model/network_options.dart';
import 'package:beagle/networking/beagle_network_options.dart';

class BeagleViewJS implements BeagleView {
BeagleViewJS(
this._beagleJSEngine, {
// ignore: avoid_unused_constructor_parameters
NetworkOptions networkOptions,
// ignore: avoid_unused_constructor_parameters
BeagleNetworkOptions networkOptions,
String initialControllerId,
}) {
_id = _beagleJSEngine.createBeagleView();
_id = _beagleJSEngine.createBeagleView(
networkOptions: networkOptions,
initialControllerId: initialControllerId,
);
BeagleViewJS.views[_id] = this;
_navigator = BeagleNavigatorJS(_beagleJSEngine, _id);
_renderer = RendererJS(_beagleJSEngine, _id);
Expand Down
16 changes: 8 additions & 8 deletions flutter/beagle/lib/default/default_http_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -17,24 +17,24 @@

import 'dart:async';
import 'package:beagle/interface/http_client.dart';
import 'package:beagle/model/request.dart';
import 'package:beagle/model/response.dart';
import 'package:flutter_js/extensions/xhr.dart';
import 'package:beagle/networking/beagle_http_method.dart';
import 'package:beagle/networking/beagle_request.dart';
import 'package:http/http.dart' as http;

class DefaultHttpClient implements HttpClient {
const DefaultHttpClient();
@override
Future<Response> sendRequest(Request req) async {
Future<Response> sendRequest(BeagleRequest req) async {
final handlers = {
HttpMethod.get: () => http.get(req.url, headers: req.headers),
HttpMethod.post: () =>
BeagleHttpMethod.get: () => http.get(req.url, headers: req.headers),
BeagleHttpMethod.post: () =>
http.post(req.url, headers: req.headers, body: req.body),
HttpMethod.put: () =>
BeagleHttpMethod.put: () =>
http.put(req.url, headers: req.headers, body: req.body),
HttpMethod.patch: () =>
BeagleHttpMethod.patch: () =>
http.patch(req.url, headers: req.headers, body: req.body),
HttpMethod.delete: () => http.delete(req.url, headers: req.headers),
BeagleHttpMethod.delete: () => http.delete(req.url, headers: req.headers),
};
final response = await handlers[req.method]();
return Response(response.statusCode, response.body, response.headers,
Expand Down
9 changes: 5 additions & 4 deletions flutter/beagle/lib/default/default_image_downloader.dart
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,19 @@ import 'dart:typed_data';

import 'package:beagle/interface/beagle_image_downloader.dart';
import 'package:beagle/interface/http_client.dart';
import 'package:beagle/model/request.dart';
import 'package:beagle/networking/beagle_request.dart';
import 'package:flutter/foundation.dart';

class DefaultBeagleImageDownloader implements BeagleImageDownloader {
DefaultBeagleImageDownloader({@required this.httpClient})
: assert(httpClient != null);
DefaultBeagleImageDownloader({
@required this.httpClient,
}) : assert(httpClient != null);

final HttpClient httpClient;

@override
Future<Uint8List> downloadImage(String url) async {
final request = Request(url);
final request = BeagleRequest(url);
final response = await httpClient.sendRequest(request);

if (response.status != HttpStatus.ok) {
Expand Down
Loading