Skip to content

Commit

Permalink
feat: Adapt the lib
Browse files Browse the repository at this point in the history
  • Loading branch information
taorepoara committed Aug 10, 2023
1 parent 89973b2 commit 758676c
Show file tree
Hide file tree
Showing 13 changed files with 178 additions and 66 deletions.
95 changes: 87 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,23 +37,102 @@

## Prerequisites

To properly run this template, you will have to make sure that the Lenra CLI and docker with docker-compose are installed on your computer.
Installation instructions can be found here https://github.com/lenra-io/lenra_cli.
Add the dependency to your project:

```console
flutter pub add lenra_client_lib
```

<p align="right">(<a href="#top">back to top</a>)</p>


<!-- USAGE EXAMPLES -->
## Usage

To run the Javascript template just run:
```console
lenra dev
Add a `LenraApplicationWidget` to your app:

```dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:lenra_client/lenra_client.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: LenraApplicationWidget(
appName: 'Example Client',
clientId: 'XXX-XXX-XXX',
// If is in debug mode then use the local host else use the remote host
host: kDebugMode ? 'http://localhost:4444' : 'https://auth.lenra.io',
oauthRedirectUrl: kIsWeb
? '${Uri.base.scheme}://${Uri.base.host}:${Uri.base.port}/redirect.html'
: 'com.example.client://',
scopes: const ['app:websocket'],
customUriScheme: 'com.example.client',
child: const MyHomePage(title: 'Flutter Demo Home Page'),
),
);
}
}
```

You can then access the application by opening [`localhost:4000`](http://localhost:4000) on your web browser.

This template is a basic implementation of a Lenra application using the Javascript language. You can get your application started by using this template.
This while automatically start the authentication flow.

You can then add `LenraWidget` instances to your widget tree to link the widget to a Lenra view and use it data:

```dart
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
Widget build(BuildContext context) {
return LenraWidget(
route: "/counter/me",
builder: (ListenerCall listener, Map<String, dynamic> json) => Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'${json["value"]}',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => listener(json["onIncrement"]),
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
),
loader: const CircularProgressIndicator(),
);
}
}
```

<p align="right">(<a href="#top">back to top</a>)</p>

Expand Down
3 changes: 2 additions & 1 deletion example/client/lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:lenra/lenra.dart';
import 'package:lenra_client/lenra_client.dart';

void main() {
runApp(const MyApp());
Expand All @@ -19,6 +19,7 @@ class MyApp extends StatelessWidget {
useMaterial3: true,
),
home: LenraApplicationWidget(
appName: 'Example Client',
clientId: 'XXX-XXX-XXX',
// If is in debug mode then use the local host else use the remote host
host: kDebugMode ? 'http://localhost:4444' : 'https://auth.lenra.io',
Expand Down
2 changes: 1 addition & 1 deletion example/client/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.0"
lenra:
lenra_client:
dependency: "direct main"
description:
path: "../.."
Expand Down
2 changes: 1 addition & 1 deletion example/client/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ dependencies:
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
provider: ^6.0.5
lenra: {
lenra_client: {
path: ../../
}

Expand Down
8 changes: 0 additions & 8 deletions lib/lenra.dart

This file was deleted.

7 changes: 7 additions & 0 deletions lib/lenra_client.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
library lenra_client;

export 'package:lenra_client/view/lenra_app.dart';
export 'package:lenra_client/view/lenra_route.dart';
export 'package:lenra_client/view/lenra_widget.dart';
export 'package:lenra_client/oauth/oauth2_client.dart';
export 'package:lenra_client/oauth/oauth2_widget.dart';
6 changes: 0 additions & 6 deletions lib/model/token_provider.dart

This file was deleted.

3 changes: 0 additions & 3 deletions lib/oauth/oauth2_client.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
import 'dart:developer';

import 'package:flutter/foundation.dart';
import 'package:oauth2_client/access_token_response.dart';
import 'package:oauth2_client/oauth2_client.dart';
import 'package:oauth2_client/oauth2_helper.dart';
Expand Down
43 changes: 22 additions & 21 deletions lib/oauth/oauth2_widget.dart
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import 'package:flutter/material.dart';
import 'package:lenra/lenra.dart';
import 'package:lenra_client/lenra_client.dart';
import 'package:oauth2_client/access_token_response.dart';
import 'package:provider/provider.dart';

/// A widget that handles the Lenra OAuth2 authentication flow.
class LenraApplicationWidget extends StatelessWidget {
/// The UI to show after the authentication flow.
final Widget? child;
final Widget child;

/// The lenra instance's hostname and port.
final String host;

/// The OAuth2 redirect URL.
final String oauthRedirectUrl;

/// The name of the application.
final String appName;

/// The OAuth2 client ID.
final String clientId;

Expand All @@ -32,6 +34,7 @@ class LenraApplicationWidget extends StatelessWidget {
required this.child,
required this.host,
required this.oauthRedirectUrl,
required this.appName,
required this.clientId,
this.clientSecret,
this.scopes = const ["app:websocket"],
Expand All @@ -49,25 +52,23 @@ class LenraApplicationWidget extends StatelessWidget {
scopes: scopes,
);

return MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => TokenProvider()),
],
child: FutureBuilder(
future: oauth2.refreshToken(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text('Error ${snapshot.error}');
}
context.read<TokenProvider>().token =
snapshot.data as AccessTokenResponse;
return child!;
} else {
return const CircularProgressIndicator();
return FutureBuilder(
future: oauth2.refreshToken(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError) {
return Text('Error ${snapshot.error}');
}
},
),

return LenraApp(
appName,
token: snapshot.data as AccessTokenResponse,
child: child,
);
} else {
return const CircularProgressIndicator();
}
},
);
}
}
21 changes: 19 additions & 2 deletions lib/view/lenra_app.dart
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import 'package:flutter/widgets.dart';
import 'package:oauth2_client/access_token_response.dart';
import 'package:phoenix_wings/html.dart';

class LenraApp {
class LenraApp extends InheritedWidget {
final String appName;
late PhoenixSocket socket;

LenraApp(this.appName, {AccessTokenResponse? token}) {
LenraApp(this.appName,
{super.key, AccessTokenResponse? token, required super.child}) {
Map<String, String> params = {
"app": appName,
"token": token!.accessToken!,
Expand All @@ -19,4 +21,19 @@ class LenraApp {

socket.connect();
}

@override
bool updateShouldNotify(covariant InheritedWidget oldWidget) {
return false;
}

static LenraApp? maybeOf(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<LenraApp>();
}

static LenraApp of(BuildContext context) {
final LenraApp? result = maybeOf(context);
assert(result != null, 'No LenraApp found in context');
return result!;
}
}
3 changes: 2 additions & 1 deletion lib/view/lenra_route.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:lenra/view/lenra_app.dart';
import 'package:lenra_client/view/lenra_app.dart';
import 'package:json_patch/json_patch.dart';
import 'package:phoenix_wings/html.dart';

Expand All @@ -11,6 +11,7 @@ class LenraRoute {
late PhoenixChannel channel;

LenraRoute(LenraApp lenraApp, this.route, this.onChange) {
print("Join channel $route with app $lenraApp");
channel = lenraApp.socket.channel("route:$route", {"mode": "json"});

channel.on("ui", (data, ref, joinRef) {
Expand Down
49 changes: 36 additions & 13 deletions lib/view/lenra_widget.dart
Original file line number Diff line number Diff line change
@@ -1,33 +1,56 @@
import 'package:lenra/view/lenra_app.dart';
import 'package:lenra/view/lenra_route.dart';
import 'package:lenra/model/token_provider.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:lenra_client/view/lenra_app.dart';
import 'package:lenra_client/view/lenra_route.dart';

class LenraWidget extends StatefulWidget {
class LenraWidget extends StatelessWidget {
final String route;
final Widget Function(ListenerCall, Map<String, dynamic>) builder;
final Widget loader;
const LenraWidget(
{required this.route, required this.builder, required this.loader});
const LenraWidget({
required this.route,
required this.builder,
required this.loader,
super.key,
});

@override
Widget build(BuildContext context) {
return LenraRouteWidget(
app: LenraApp.of(context),
route: route,
builder: builder,
loader: loader,
);
}
}

class LenraRouteWidget extends StatefulWidget {
final LenraApp app;
final String route;
final Widget Function(ListenerCall, Map<String, dynamic>) builder;
final Widget loader;
LenraRouteWidget({
super.key,
required this.app,
required this.route,
required this.builder,
required this.loader,
});

@override
State<StatefulWidget> createState() {
return LenraWidgetState();
return LenraRouteWidgetState();
}
}

class LenraWidgetState extends State<LenraWidget> {
class LenraRouteWidgetState extends State<LenraRouteWidget> {
late LenraRoute lenraRoute;
Map<String, dynamic>? json;

@override
initState() {
super.initState();
lenraRoute = LenraRoute(
LenraApp("test", token: context.read<TokenProvider>().token),
widget.route,
updateState);
lenraRoute = LenraRoute(widget.app, widget.route, updateState);
}

@override
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: lenra
name: lenra_client
description: Official Lenra lib to create custom client apps in Flutter.
version: 0.0.0
homepage: https://www.lenra.io
Expand Down

0 comments on commit 758676c

Please sign in to comment.