diff --git a/android/app/src/main/kotlin/fr/astrolabe/astronote_app/MainActivity.kt b/android/app/src/main/kotlin/fr/astrolabe/astronote_app/MainActivity.kt
index 706262d..77f35ec 100644
--- a/android/app/src/main/kotlin/fr/astrolabe/astronote_app/MainActivity.kt
+++ b/android/app/src/main/kotlin/fr/astrolabe/astronote_app/MainActivity.kt
@@ -1,6 +1,69 @@
package fr.astrolabe.astronote_app
+import android.content.BroadcastReceiver
+import android.os.Bundle
+import android.content.Context
+import android.content.Intent
+import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
+import io.flutter.embedding.engine.FlutterEngine
+import io.flutter.plugin.common.EventChannel
+import io.flutter.plugin.common.EventChannel.EventSink
+import io.flutter.plugin.common.MethodChannel
+import io.flutter.plugins.GeneratedPluginRegistrant
-class MainActivity: FlutterActivity() {
+class MainActivity : FlutterActivity() {
+
+ private val CHANNEL = "https://demo.endi.coop"
+ private val EVENTS = "https://demo.endi.coop/login?nextpage=%2F"
+ private var startString: String? = null
+ private var linksReceiver: BroadcastReceiver? = null
+
+ override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
+ GeneratedPluginRegistrant.registerWith(flutterEngine)
+
+ MethodChannel(flutterEngine.dartExecutor, CHANNEL).setMethodCallHandler { call, result ->
+ if (call.method == "initialLink") {
+ if (startString != null) {
+ result.success(startString)
+ }
+ }
+ }
+
+ EventChannel(flutterEngine.dartExecutor, EVENTS).setStreamHandler(
+ object : EventChannel.StreamHandler {
+ override fun onListen(args: Any?, events: EventSink) {
+ linksReceiver = createChangeReceiver(events)
+ }
+
+ override fun onCancel(args: Any?) {
+ linksReceiver = null
+ }
+ }
+ )
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ val intent = getIntent()
+ startString = intent.data?.toString()
+ }
+
+ override fun onNewIntent(intent: Intent) {
+ super.onNewIntent(intent)
+ if (intent.action === Intent.ACTION_VIEW) {
+ linksReceiver?.onReceive(this.applicationContext, intent)
+ }
+ }
+
+ fun createChangeReceiver(events: EventSink): BroadcastReceiver? {
+ return object : BroadcastReceiver() {
+ override fun onReceive(context: Context, intent: Intent) { // assuming intent.getAction() is Intent.ACTION_VIEW
+ val dataString = intent.dataString
+ ?: events.error("UNAVAILABLE", "Link unavailable", null)
+ events.success(dataString)
+ }
+ }
+ }
}
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 5bc5275..5b7006a 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -41,5 +41,9 @@
UIViewControllerBasedStatusBarAppearance
+ com.apple.developer.associated-domains
+
+ applinks:demo.endi.coop
+
diff --git a/lib/bloc.dart b/lib/bloc.dart
new file mode 100644
index 0000000..211aa1d
--- /dev/null
+++ b/lib/bloc.dart
@@ -0,0 +1,48 @@
+import 'dart:async';
+
+import 'package:flutter/services.dart';
+
+abstract class Bloc {
+ void dispose();
+}
+
+class DeepLinkBloc extends Bloc {
+ //Event Channel creation
+ static const stream =
+ const EventChannel('https://demo.endi.coop/login?nextpage=%2F');
+
+ //Method channel creation
+ static const platform = const MethodChannel('https://demo.endi.coop');
+
+ StreamController _stateController = StreamController();
+
+ Stream get state => _stateController.stream;
+
+ Sink get stateSink => _stateController.sink;
+
+ //Adding the listener into contructor
+ DeepLinkBloc() {
+ //Checking application start by deep link
+ startUri().then(_onRedirected);
+ //Checking broadcast stream, if deep link was clicked in opened appication
+ stream.receiveBroadcastStream().listen((d) => _onRedirected(d));
+ }
+
+ _onRedirected(String uri) {
+ // Throw deep link URI into the BloC's stream
+ stateSink.add(uri);
+ }
+
+ @override
+ void dispose() {
+ _stateController.close();
+ }
+
+ Future startUri() async {
+ try {
+ return platform.invokeMethod('initialLink');
+ } on PlatformException catch (e) {
+ return "Failed to Invoke: '${e.message}'.";
+ }
+ }
+}
diff --git a/lib/views/HomeLog.dart b/lib/endi.dart
similarity index 56%
rename from lib/views/HomeLog.dart
rename to lib/endi.dart
index d3bc8c9..3f73abc 100644
--- a/lib/views/HomeLog.dart
+++ b/lib/endi.dart
@@ -1,48 +1,57 @@
-import 'package:provider/provider.dart';
import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+import 'bloc.dart';
import 'package:url_launcher/url_launcher.dart';
+import 'package:flushbar/flushbar.dart';
-class HomeLog extends StatefulWidget {
+class EndiLog extends StatefulWidget {
@override
- _HomeLogState createState() => _HomeLogState();
+ _EndiLogState createState() => _EndiLogState();
}
-class _HomeLogState extends State {
+class _EndiLogState extends State {
TextStyle style = TextStyle(fontFamily: 'Varela Round', fontSize: 20.0);
- final GlobalKey _globalKey = GlobalKey();
@override
Widget build(BuildContext context) {
- return Scaffold(
- key: _globalKey,
- body: SingleChildScrollView(
- child: Container(
- height: MediaQuery.of(context).size.height,
- color: Colors.white,
- child: Padding(
- padding: EdgeInsets.all(50),
- child: Column(
- children: [
- SizedBox(height: 40),
- _logoApp(),
- _titleApp(),
- SizedBox(height: 90),
- _emailField(),
- SizedBox(height: 30),
- _passwordField(),
- SizedBox(height: 50),
- _logButton(),
- SizedBox(height: 70),
- _enDIUrl(),
- SizedBox(height: 10),
- _astrolabeUrl()
- ],
- ),
- ),
- ),
- ),
- );
+ DeepLinkBloc _bloc = Provider.of(context);
+ return StreamBuilder(
+ stream: _bloc.state,
+ builder: (context, snapshot) {
+ if (!snapshot.hasData) {
+ return Container(
+ child: Center(child: Text('No deep link was used ')));
+ } else {
+ return SingleChildScrollView(
+ child: Container(
+ height: MediaQuery.of(context).size.height,
+ color: Colors.white,
+ child: Padding(
+ padding: EdgeInsets.all(50),
+ child: Column(
+ children: [
+// SizedBox(height: 40),
+ _logoApp(),
+ _titleApp(),
+ SizedBox(height: 80),
+ _emailField(),
+ SizedBox(height: 30),
+ _passwordField(),
+ SizedBox(height: 50),
+ _logButton(),
+ SizedBox(height: 70),
+ _enDIUrl(),
+ SizedBox(height: 5),
+ _astrolabeUrl()
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+ });
}
+
Widget _logoApp() {
return SizedBox(
height: 100.0,
@@ -67,7 +76,7 @@ class _HomeLogState extends State {
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
labelText: "E-mail",
border:
- OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
+ OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
);
}
@@ -79,7 +88,7 @@ class _HomeLogState extends State {
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
labelText: "Mot de passe",
border:
- OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
+ OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
);
}
@@ -99,18 +108,22 @@ class _HomeLogState extends State {
));
}
+ void showErrorFlushbar(BuildContext context) {
+ Flushbar(
+ message: "Impossible d'ouvrir le lien",
+ backgroundColor: Colors.red[300],
+ duration: Duration(seconds: 3),
+ // Show it with a cascading operator
+ )..show(context);
+ }
+
void _launchLinkEnDI() async {
const url = "https://endi.coop";
if (await canLaunch(url)) {
await launch(url);
} else {
- final snack = SnackBar(
- content: Text("Impossible de lancer le lien"),
- duration: Duration(seconds: 4),
- backgroundColor: Colors.red[300],
- );
- _globalKey.currentState.showSnackBar(snack);
+ showErrorFlushbar(context);
}
}
@@ -120,12 +133,7 @@ class _HomeLogState extends State {
if (await canLaunch(url)) {
await launch(url);
} else {
- final snack = SnackBar(
- content: Text("Impossible de lancer le lien"),
- duration: Duration(seconds: 4),
- backgroundColor: Colors.red[300],
- );
- _globalKey.currentState.showSnackBar(snack);
+ showErrorFlushbar(context);
}
}
@@ -154,5 +162,4 @@ class _HomeLogState extends State {
),
);
}
-
}
diff --git a/lib/main.dart b/lib/main.dart
index 3f53b7b..d572967 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
-import 'views/HomeLog.dart';
+import 'bloc.dart';
+import 'package:provider/provider.dart';
+import 'endi.dart';
void main() => runApp(MyApp());
@@ -7,11 +9,14 @@ class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
+ DeepLinkBloc _bloc = DeepLinkBloc();
+
return MaterialApp(
- home: HomeLog(),
- debugShowCheckedModeBanner: false,
- );
+ debugShowCheckedModeBanner: false,
+ home: Scaffold(
+ body: Provider(
+ create: (context) => _bloc,
+ dispose: (context, bloc) => bloc.dispose(),
+ child: EndiLog())));
}
}
-
-
diff --git a/pubspec.lock b/pubspec.lock
index 2c689ae..9176334 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -64,13 +64,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
- email_validator:
+ flushbar:
dependency: "direct main"
description:
- name: email_validator
+ name: flushbar
url: "https://pub.dartlang.org"
source: hosted
- version: "1.0.5"
+ version: "1.10.4"
flutter:
dependency: "direct main"
description: flutter
@@ -267,5 +267,5 @@ packages:
source: hosted
version: "3.6.1"
sdks:
- dart: ">=2.7.0 <3.0.0"
+ dart: ">=2.7.2 <3.0.0"
flutter: ">=1.16.0 <2.0.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 2218d8e..a08acdd 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -24,7 +24,7 @@ dependencies:
flutter:
sdk: flutter
provider: ^4.3.1
- email_validator: '^1.0.0'
+ flushbar: ^1.10.4
url_launcher: ^5.5.0
# The following adds the Cupertino Icons font to your application.