Skip to content

Commit

Permalink
Refactor to match js interface
Browse files Browse the repository at this point in the history
  • Loading branch information
tom-quiltt committed Oct 2, 2023
1 parent 6eb2828 commit ff6fffc
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 62 deletions.
27 changes: 20 additions & 7 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:quiltt_connector/quiltt_connector.dart';
import 'package:quiltt_connector/configuration.dart';

void main() {
runApp(const MyApp());
Expand Down Expand Up @@ -65,15 +66,27 @@ class _MyHomePageState extends State<MyHomePage> {
}

_launchConnector() {
Configuration configuration = Configuration(
connectorId: "connector_id",
sessionToken: "session_token",
String token = "token";

QuilttConnectorConfiguration config = QuilttConnectorConfiguration(
connectorId: "connectorId",
oauthRedirectUrl: "quilttexample://open.flutter.app");

QuilttConnector quilttConnector = QuilttConnector(configuration);
quilttConnector.launch(context, (Result result) {
// handle result
_setConnectionId(result.connectionId!);
debugPrint(
'_launchConnector: ${config.connectorId}, $config.oauthRedirectUrl');
QuilttConnector quilttConnector = QuilttConnector();
quilttConnector.authenticate(token);
quilttConnector.connect(context, config, onEvent: (event) {
debugPrint("onEvent: ${event.eventMetadata}");
}, onExit: (event) {
debugPrint("onExit: ${event.eventMetadata}");
}, onExitSuccess: (event) {
debugPrint("onExitSuccess: ${event.eventMetadata}");
_setConnectionId(event.eventMetadata.connectionId!);
}, onExitAbort: (event) {
debugPrint("onExitAbort: ${event.eventMetadata}");
}, onExitError: (event) {
debugPrint("onExitError: ${event.eventMetadata}");
});
}

Expand Down
2 changes: 1 addition & 1 deletion example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.1.1"
version: "0.1.2"
sky_engine:
dependency: transitive
description: flutter
Expand Down
11 changes: 11 additions & 0 deletions lib/configuration.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class QuilttConnectorConfiguration {
String connectorId;
String oauthRedirectUrl;
String? connectionId;

QuilttConnectorConfiguration({
required this.connectorId,
required this.oauthRedirectUrl,
this.connectionId,
});
}
21 changes: 21 additions & 0 deletions lib/event.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
class EventMetadata {
String connectorId;
String? connectionId;
String? moveId;

EventMetadata({
required this.connectorId,
this.connectionId,
this.moveId,
});
}

class Event {
String type;
EventMetadata eventMetadata;

Event({
required this.type,
required this.eventMetadata,
});
}
179 changes: 125 additions & 54 deletions lib/quiltt_connector.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,70 +3,161 @@ library quiltt_connector;
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:url_launcher/url_launcher_string.dart';
import 'package:quiltt_connector/configuration.dart';
import 'package:quiltt_connector/event.dart';

/// This class is the entry point for the Quiltt Connector SDK.
class QuilttConnector {
late Configuration _configuration;
String? sessionToken;
late String connectorId;
late String connectionId;
final _WebViewPage _webViewPage = _WebViewPage();
final WebViewController controller = WebViewController();

/// Pass token to authenticate, authenticate through UI if token is absent
void authenticate(String token) {
sessionToken = token;
// controller.postMessage?
String javaScript = '''
const options = {
source: 'quiltt',
type: 'Options',
token: '$sessionToken',
};
window.postMessage(options);
''';
controller.runJavaScript(javaScript);
}

/// Connect to a connector
connect(
BuildContext context,
QuilttConnectorConfiguration config, {
Function(Event event)? onEvent,
Function(Event event)? onExit,
Function(Event event)? onExitSuccess,
Function(Event event)? onExitAbort,
Function(Event event)? onExitError,
}) {
connectorId = config.connectorId;
_webViewPage._init(controller, context, config,
token: sessionToken,
onEvent: onEvent,
onExit: onExit,
onExitSuccess: onExitSuccess,
onExitAbort: onExitAbort,
onExitError: onExitError);

QuilttConnector(Configuration configuration) {
_configuration = configuration;
Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
return _webViewPage.build(context, token: sessionToken);
}));
}

launch(BuildContext context, Function(Result result) success) {
_WebViewPage webViewPage = _WebViewPage();
webViewPage._init(_configuration, success, context);
/// Reconnect to a connector
reconnect(
BuildContext context,
QuilttConnectorConfiguration config, {
Function(Event event)? onEvent,
Function(Event event)? onExit,
Function(Event event)? onExitSuccess,
Function(Event event)? onExitAbort,
Function(Event event)? onExitError,
}) {
connectorId = config.connectorId;
connectionId = config.connectionId!;
_webViewPage._init(controller, context, config,
token: sessionToken,
onEvent: onEvent,
onExit: onExit,
onExitSuccess: onExitSuccess,
onExitAbort: onExitAbort,
onExitError: onExitError);

Navigator.push(context, MaterialPageRoute(builder: (BuildContext context) {
return webViewPage.build(context);
return _webViewPage.build(context,
token: sessionToken, connectionId: config.connectionId);
}));
}
}

class _WebViewPage {
late Function(Result result) _success;
late Configuration _config;
BuildContext? _context;

_init(Configuration config, Function(Result result) success,
BuildContext context) {
_success = success;
_config = config;
_context = context;
late WebViewController controller;
late BuildContext context;
late QuilttConnectorConfiguration config;
String? token;
Function(Event event)? onEvent;
Function(Event event)? onExit;
Function(Event event)? onExitSuccess;
Function(Event event)? onExitAbort;
Function(Event event)? onExitError;

_init(controller, context, QuilttConnectorConfiguration config,
{String? token,
Function(Event event)? onEvent,
Function(Event event)? onExit,
Function(Event event)? onExitSuccess,
Function(Event event)? onExitAbort,
Function(Event event)? onExitError}) {
this.controller = controller;
this.context = context;
this.token = token;
this.config = config;
this.onEvent = onEvent;
this.onExit = onExit;
this.onExitSuccess = onExitSuccess;
this.onExitAbort = onExitAbort;
this.onExitError = onExitError;
}

_closeWebView() {
if (_context != null && Navigator.canPop(_context!)) {
Navigator.pop(_context!);
if (Navigator.canPop(context)) {
controller.clearLocalStorage();
Navigator.pop(context);
}
}

_handleQuilttConnectorEvent(Uri uri) async {
EventMetadata eventMetadata = EventMetadata(
connectorId: config.connectorId,
connectionId: uri.queryParameters['connectionId'],
moveId: uri.queryParameters['moveId'],
);
String eventType = uri.host;
switch (uri.host) {
case "oauthrequested":
case 'oauthrequested':
var oauthUrl = Uri.decodeFull(uri.queryParameters['oauthUrl']!);
await launchUrlString(oauthUrl, mode: LaunchMode.externalApplication);
break;
case "exitsuccess":
_success(Result(uri.queryParameters['connectionId']));
case 'exitsuccess':
onExit?.call(Event(type: eventType, eventMetadata: eventMetadata));
onExitSuccess
?.call(Event(type: eventType, eventMetadata: eventMetadata));
_closeWebView();
case "exitabort":
case "exiterror":
case 'exitabort':
onExit?.call(Event(type: eventType, eventMetadata: eventMetadata));
onExitAbort?.call(Event(type: eventType, eventMetadata: eventMetadata));
_closeWebView();
case 'exiterror':
onExit?.call(Event(type: eventType, eventMetadata: eventMetadata));
onExitAbort?.call(Event(type: eventType, eventMetadata: eventMetadata));
_closeWebView();
default:
debugPrint("Unknown event: ${uri.host}");
debugPrint('Unknown event: ${uri.host}');
}
}

Widget build(BuildContext context) {
var oauthRedirectUrl = Uri.encodeComponent(_config.oauthRedirectUrl);
Widget build(BuildContext context, {String? token, String? connectionId}) {
var oauthRedirectUrl = Uri.encodeComponent(config.oauthRedirectUrl);
var connectorUrl =
"https://${_config.connectorId}.quiltt.app/?mode=webview&oauth_redirect_url=$oauthRedirectUrl";
var javaScript = """
'https://${config.connectorId}.quiltt.app/?mode=webview&oauth_redirect_url=$oauthRedirectUrl';
debugPrint(connectorUrl);
var javaScript = '''
const options = {
source: 'quiltt',
type: 'Options',
token: '${_config.sessionToken}',
connectorId: '${_config.connectorId}',
connectionId: '${_config.connectionId}',
token: '$token',
connectorId: '${config.connectorId}',
connectionId: '$connectionId',
};
const compactedOptions = Object.keys(options).reduce((acc, key) => {
if (options[key] !== 'null') {
Expand All @@ -75,8 +166,8 @@ class _WebViewPage {
return acc;
}, {});
window.postMessage(compactedOptions);
""";
WebViewController controller = WebViewController();
''';

controller
..setJavaScriptMode(JavaScriptMode.unrestricted)
..setNavigationDelegate(
Expand All @@ -90,7 +181,7 @@ class _WebViewPage {
onNavigationRequest: (NavigationRequest request) async {
Uri uri = Uri.parse(request.url);

if (uri.scheme == "quilttconnector") {
if (uri.scheme == 'quilttconnector') {
await _handleQuilttConnectorEvent(uri);
return NavigationDecision.prevent;
}
Expand All @@ -104,23 +195,3 @@ class _WebViewPage {
body: SafeArea(child: WebViewWidget(controller: controller)));
}
}

class Configuration {
String connectorId;
String oauthRedirectUrl;
String? connectionId;
String? sessionToken;

Configuration({
required this.connectorId,
required this.oauthRedirectUrl,
this.connectionId,
this.sessionToken,
});
}

class Result {
String? connectionId;

Result(this.connectionId);
}

0 comments on commit ff6fffc

Please sign in to comment.