Change all app architecture
This commit is contained in:
parent
c902c29684
commit
384c67e9a3
@ -1,69 +1,7 @@
|
|||||||
package fr.astrolabe.astronote_app
|
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.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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -41,9 +41,6 @@
|
|||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>com.apple.developer.associated-domains</key>
|
|
||||||
<array>
|
|
||||||
<string>applinks:demo.endi.coop</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
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<String> _stateController = StreamController();
|
|
||||||
|
|
||||||
Stream<String> get state => _stateController.stream;
|
|
||||||
|
|
||||||
Sink<String> 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<String> startUri() async {
|
|
||||||
try {
|
|
||||||
return platform.invokeMethod('initialLink');
|
|
||||||
} on PlatformException catch (e) {
|
|
||||||
return "Failed to Invoke: '${e.message}'.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
165
lib/endi.dart
165
lib/endi.dart
@ -1,165 +0,0 @@
|
|||||||
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 EndiLog extends StatefulWidget {
|
|
||||||
@override
|
|
||||||
_EndiLogState createState() => _EndiLogState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _EndiLogState extends State<EndiLog> {
|
|
||||||
TextStyle style = TextStyle(fontFamily: 'Varela Round', fontSize: 20.0);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
DeepLinkBloc _bloc = Provider.of<DeepLinkBloc>(context);
|
|
||||||
return StreamBuilder<String>(
|
|
||||||
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: <Widget>[
|
|
||||||
// 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,
|
|
||||||
child: Image.asset(
|
|
||||||
"assets/astrolabe_logo.jpg",
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _titleApp() {
|
|
||||||
return Text(
|
|
||||||
"AstroNotes",
|
|
||||||
style: style.copyWith(color: Colors.black, fontSize: 40),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _emailField() {
|
|
||||||
return TextField(
|
|
||||||
style: style,
|
|
||||||
keyboardType: TextInputType.emailAddress,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
|
|
||||||
labelText: "E-mail",
|
|
||||||
border:
|
|
||||||
OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _passwordField() {
|
|
||||||
return TextField(
|
|
||||||
style: style,
|
|
||||||
obscureText: true,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
|
|
||||||
labelText: "Mot de passe",
|
|
||||||
border:
|
|
||||||
OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _logButton() {
|
|
||||||
return Material(
|
|
||||||
elevation: 5.0,
|
|
||||||
borderRadius: BorderRadius.circular(30.0),
|
|
||||||
color: Color(0xFF4A148C),
|
|
||||||
child: MaterialButton(
|
|
||||||
// minWidth: MediaQuery.of(context).size.width,
|
|
||||||
padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
|
|
||||||
onPressed: () {},
|
|
||||||
child: Text("Connexion",
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: style.copyWith(
|
|
||||||
color: Colors.white, fontWeight: FontWeight.bold)),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
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 {
|
|
||||||
showErrorFlushbar(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _launchLinkAstrolabe() async {
|
|
||||||
const url = "https://astrolabe.coop";
|
|
||||||
|
|
||||||
if (await canLaunch(url)) {
|
|
||||||
await launch(url);
|
|
||||||
} else {
|
|
||||||
showErrorFlushbar(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _enDIUrl() {
|
|
||||||
return InkWell(
|
|
||||||
onTap: _launchLinkEnDI,
|
|
||||||
child: Text(
|
|
||||||
"En collaboration avec enDI",
|
|
||||||
style: style.copyWith(
|
|
||||||
color: Colors.black,
|
|
||||||
fontSize: 15,
|
|
||||||
decoration: TextDecoration.underline),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget _astrolabeUrl() {
|
|
||||||
return InkWell(
|
|
||||||
onTap: _launchLinkAstrolabe,
|
|
||||||
child: Text(
|
|
||||||
"Développé par Astrolabe",
|
|
||||||
style: style.copyWith(
|
|
||||||
color: Colors.black,
|
|
||||||
fontSize: 15,
|
|
||||||
decoration: TextDecoration.underline),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +1,16 @@
|
|||||||
|
import 'package:astronote_app/screens/sign_in_screen.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'bloc.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
|
||||||
import 'endi.dart';
|
|
||||||
|
|
||||||
void main() => runApp(MyApp());
|
void main() => runApp(MyApp());
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
// This widget is the root of your application.
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
DeepLinkBloc _bloc = DeepLinkBloc();
|
|
||||||
|
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
debugShowCheckedModeBanner: false,
|
theme: ThemeData(
|
||||||
home: Scaffold(
|
fontFamily: 'Varela Round',
|
||||||
body: Provider<DeepLinkBloc>(
|
),
|
||||||
create: (context) => _bloc,
|
home: LoginScreen()
|
||||||
dispose: (context, bloc) => bloc.dispose(),
|
);
|
||||||
child: EndiLog())));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
18
lib/models/companies.dart
Normal file
18
lib/models/companies.dart
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
class Companies {
|
||||||
|
int id;
|
||||||
|
String name;
|
||||||
|
|
||||||
|
Companies({this.id, this.name});
|
||||||
|
|
||||||
|
Companies.fromJson(Map<String, dynamic> json) {
|
||||||
|
id = json['id'];
|
||||||
|
name = json['name'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['id'] = this.id;
|
||||||
|
data['name'] = this.name;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
33
lib/models/datas.dart
Normal file
33
lib/models/datas.dart
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import 'package:astronote_app/models/companies.dart';
|
||||||
|
|
||||||
|
class Datas {
|
||||||
|
String lastname;
|
||||||
|
List<Companies> companies;
|
||||||
|
String firstname;
|
||||||
|
String civilite;
|
||||||
|
|
||||||
|
Datas({this.lastname, this.companies, this.firstname, this.civilite});
|
||||||
|
|
||||||
|
Datas.fromJson(Map<String, dynamic> json) {
|
||||||
|
lastname = json['lastname'];
|
||||||
|
if (json['companies'] != null) {
|
||||||
|
companies = new List<Companies>();
|
||||||
|
json['companies'].forEach((v) {
|
||||||
|
companies.add(new Companies.fromJson(v));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
firstname = json['firstname'];
|
||||||
|
civilite = json['civilite'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['lastname'] = this.lastname;
|
||||||
|
if (this.companies != null) {
|
||||||
|
data['companies'] = this.companies.map((v) => v.toJson()).toList();
|
||||||
|
}
|
||||||
|
data['firstname'] = this.firstname;
|
||||||
|
data['civilite'] = this.civilite;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
28
lib/models/sign_in_api.dart
Normal file
28
lib/models/sign_in_api.dart
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import 'package:astronote_app/models/datas.dart';
|
||||||
|
|
||||||
|
class Api {
|
||||||
|
String status;
|
||||||
|
String api;
|
||||||
|
String id;
|
||||||
|
Datas datas;
|
||||||
|
|
||||||
|
Api ({this.status, this.api, this.id, this.datas});
|
||||||
|
|
||||||
|
Api.fromJson(Map<String, dynamic> json) {
|
||||||
|
status = json['status'];
|
||||||
|
api = json['api'];
|
||||||
|
id = json['id'];
|
||||||
|
datas = json['datas'] != null ? new Datas.fromJson(json['datas']) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
final Map<String, dynamic> data = new Map<String, dynamic>();
|
||||||
|
data['status'] = this.status;
|
||||||
|
data['api'] = this.api;
|
||||||
|
data['id'] = this.id;
|
||||||
|
if (this.datas != null) {
|
||||||
|
data['datas'] = this.datas.toJson();
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
52
lib/providers/sign_in.dart
Normal file
52
lib/providers/sign_in.dart
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import 'dart:convert';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
|
class SignIn with ChangeNotifier {
|
||||||
|
String cookie;
|
||||||
|
|
||||||
|
Future<void> login(String url, String email, String password) async {
|
||||||
|
String urlApi = url + '/api/v1/login';
|
||||||
|
|
||||||
|
Map<String, String> headers = {
|
||||||
|
"X-Requested-With": "XMLHttpRequest",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
};
|
||||||
|
var body = json.encode({"login": email, "password": password});
|
||||||
|
|
||||||
|
final response = await http.post(urlApi, headers: headers, body: body);
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
// If the server did return a 200 OK response,
|
||||||
|
// then parse the JSON.
|
||||||
|
print(response.headers['set-cookie']);
|
||||||
|
cookie = response.headers['set-cookie'];
|
||||||
|
//TODO : return http.get + company_choice_screen root
|
||||||
|
recoverUserData(urlApi);
|
||||||
|
// If the server did not return a 200 OK response,
|
||||||
|
// then throw an exception.
|
||||||
|
//TODO: error message ?
|
||||||
|
}
|
||||||
|
|
||||||
|
// final responseJson = json.decode(response.body);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> recoverUserData(String url) async {
|
||||||
|
Map<String, String> headers = {"X-Requested-With": "XMLHttpRequest","Cookie":cookie};
|
||||||
|
|
||||||
|
final response = await http.get(url, headers: headers);
|
||||||
|
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
// If the server did return a 200 OK response,
|
||||||
|
// then parse the JSON.
|
||||||
|
print(response.headers['datas']);
|
||||||
|
} else {
|
||||||
|
// If the server did not return a 200 OK response,
|
||||||
|
// then throw an exception.
|
||||||
|
}
|
||||||
|
// final responseJson = json.decode(response.body);
|
||||||
|
//
|
||||||
|
// print(responseJson);
|
||||||
|
}
|
||||||
|
}
|
0
lib/screens/company_choice_screen.dart
Normal file
0
lib/screens/company_choice_screen.dart
Normal file
0
lib/screens/dashboard_screen.dart
Normal file
0
lib/screens/dashboard_screen.dart
Normal file
85
lib/screens/sign_in_screen.dart
Normal file
85
lib/screens/sign_in_screen.dart
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'file:///D:/AndroidStudioProjects/astronote_app/lib/widgets/footer_sign_in_widget.dart';
|
||||||
|
|
||||||
|
import 'file:///D:/AndroidStudioProjects/astronote_app/lib/widgets/form_sign_in_widget.dart';
|
||||||
|
import 'package:astronote_app/widgets/header_sign__in_widget.dart';
|
||||||
|
|
||||||
|
class LoginScreen extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_LoginScreenState createState() => _LoginScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _LoginScreenState extends State<LoginScreen> {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
body: Container(
|
||||||
|
// width: double.infinity,
|
||||||
|
child: SingleChildScrollView(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
left: MediaQuery.of(context).size.height * 0.07,
|
||||||
|
right: MediaQuery.of(context).size.height * 0.07),
|
||||||
|
// scrollDirection: Axis.vertical,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
HeaderLogWidget(),
|
||||||
|
SizedBox(height: MediaQuery.of(context).size.height * 0.08),
|
||||||
|
FormLogWidget(),
|
||||||
|
SizedBox(height: MediaQuery.of(context).size.height * 0.08),
|
||||||
|
FooterLogWidget(),
|
||||||
|
SizedBox(height: MediaQuery.of(context).size.height * 0.05),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Widget _enDIUrl() {
|
||||||
|
// return InkWell(
|
||||||
|
// onTap: _enDIUrl,
|
||||||
|
// child: Text(
|
||||||
|
// "En collaboration avec enDI",
|
||||||
|
// style: style.copyWith(
|
||||||
|
// color: Colors.black,
|
||||||
|
// fontSize: 15.0,
|
||||||
|
// decoration: TextDecoration.underline),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// Widget _astrolabeUrl() {
|
||||||
|
// return InkWell(
|
||||||
|
// onTap: _launchLinkAstrolabe,
|
||||||
|
// child: Text(
|
||||||
|
// "Développé par Astrolabe",
|
||||||
|
// style: style.copyWith(
|
||||||
|
// color: Colors.black,
|
||||||
|
// fontSize: 15,
|
||||||
|
// decoration: TextDecoration.underline),
|
||||||
|
// ),
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// void launchLinkEnDI() async {
|
||||||
|
// const urlEndi = "hhuh";
|
||||||
|
//
|
||||||
|
// if (await canLaunch(urlEndi)) {
|
||||||
|
// await launch(urlEndi);
|
||||||
|
// } else {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// void _launchLinkAstrolabe() async {
|
||||||
|
// const url = "https://astrolabe.coop";
|
||||||
|
//
|
||||||
|
// if (await canLaunch(url)) {
|
||||||
|
// await launch(url);
|
||||||
|
// } else {
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
66
lib/widgets/footer_sign_in_widget.dart
Normal file
66
lib/widgets/footer_sign_in_widget.dart
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
|
|
||||||
|
class FooterLogWidget extends StatelessWidget {
|
||||||
|
final TextStyle style = TextStyle(fontFamily: 'Varela Round', fontSize: 20.0);
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
_enDIUrl(),
|
||||||
|
SizedBox(height: 5),
|
||||||
|
_astrolabeUrl()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _enDIUrl() {
|
||||||
|
return InkWell(
|
||||||
|
onTap: _launchLinkEnDI,
|
||||||
|
child: Text(
|
||||||
|
"En collaboration avec enDI",
|
||||||
|
style: style.copyWith(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 15.0,
|
||||||
|
decoration: TextDecoration.underline),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _astrolabeUrl() {
|
||||||
|
return InkWell(
|
||||||
|
onTap: _launchLinkAstrolabe,
|
||||||
|
child: Text(
|
||||||
|
"Développé par Astrolabe",
|
||||||
|
style: style.copyWith(
|
||||||
|
color: Colors.black,
|
||||||
|
fontSize: 15,
|
||||||
|
decoration: TextDecoration.underline),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _launchLinkEnDI() async {
|
||||||
|
const urlEndi = "https://endi.coop";
|
||||||
|
|
||||||
|
if (await canLaunch(urlEndi)) {
|
||||||
|
await launch(urlEndi);
|
||||||
|
} else {
|
||||||
|
//TODO : error message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _launchLinkAstrolabe() async {
|
||||||
|
const url = "https://astrolabe.coop";
|
||||||
|
|
||||||
|
if (await canLaunch(url)) {
|
||||||
|
await launch(url);
|
||||||
|
} else {
|
||||||
|
//TODO : error message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
109
lib/widgets/form_sign_in_widget.dart
Normal file
109
lib/widgets/form_sign_in_widget.dart
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:astronote_app/providers/sign_in.dart';
|
||||||
|
|
||||||
|
class FormLogWidget extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
_FormLogWidgetState createState() => _FormLogWidgetState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FormLogWidgetState extends State<FormLogWidget> {
|
||||||
|
TextStyle style = TextStyle(fontFamily: 'Varela Round', fontSize: 20.0);
|
||||||
|
|
||||||
|
bool _obscurePassword = true;
|
||||||
|
final GlobalKey<FormState> _formKey = GlobalKey();
|
||||||
|
bool _isLoading = false;
|
||||||
|
|
||||||
|
TextEditingController urlController = new TextEditingController();
|
||||||
|
TextEditingController emailController = new TextEditingController();
|
||||||
|
TextEditingController passwordController = new TextEditingController();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Form(
|
||||||
|
key: _formKey,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
_urlFormField(),
|
||||||
|
SizedBox(height: MediaQuery.of(context).size.height * 0.03),
|
||||||
|
_emailFormField(),
|
||||||
|
SizedBox(height: MediaQuery.of(context).size.height * 0.03),
|
||||||
|
_passwordFormField(),
|
||||||
|
SizedBox(height: MediaQuery.of(context).size.height * 0.07),
|
||||||
|
_logButton()
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _urlFormField() {
|
||||||
|
return TextFormField(
|
||||||
|
controller: urlController,
|
||||||
|
style: style,
|
||||||
|
keyboardType: TextInputType.url,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
|
||||||
|
labelText: "Lien enDI",
|
||||||
|
suffixIcon: Icon(Icons.link,color: Colors.indigo[900]),
|
||||||
|
border:
|
||||||
|
OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _emailFormField() {
|
||||||
|
return TextFormField(
|
||||||
|
controller: emailController,
|
||||||
|
style: style,
|
||||||
|
keyboardType: TextInputType.emailAddress,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
|
||||||
|
labelText: "E-mail",
|
||||||
|
suffixIcon: Icon(Icons.mail,color: Colors.indigo[900]),
|
||||||
|
border:
|
||||||
|
OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _passwordFormField() {
|
||||||
|
return TextFormField(
|
||||||
|
controller: passwordController,
|
||||||
|
style: style,
|
||||||
|
obscureText: _obscurePassword,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
|
||||||
|
labelText: "Mot de passe",
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: Icon(
|
||||||
|
_obscurePassword ? Icons.visibility : Icons.visibility_off,color: Colors.indigo[900]),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() => _obscurePassword = !_obscurePassword);
|
||||||
|
}),
|
||||||
|
border:
|
||||||
|
OutlineInputBorder(borderRadius: BorderRadius.circular(32.0))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _logButton() {
|
||||||
|
return Material(
|
||||||
|
elevation: 3.0,
|
||||||
|
borderRadius: BorderRadius.circular(30.0),
|
||||||
|
color: Colors.indigo[900],
|
||||||
|
child: MaterialButton(
|
||||||
|
// minWidth: MediaQuery.of(context).size.width,
|
||||||
|
padding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 15.0),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_isLoading = true;
|
||||||
|
});
|
||||||
|
SignIn().login(urlController.text, emailController.text, passwordController.text);
|
||||||
|
},
|
||||||
|
child: Text("Connexion",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: style.copyWith(
|
||||||
|
color: Colors.white, fontWeight: FontWeight.bold)),
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
29
lib/widgets/header_sign__in_widget.dart
Normal file
29
lib/widgets/header_sign__in_widget.dart
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class HeaderLogWidget extends StatelessWidget {
|
||||||
|
final TextStyle style = TextStyle(fontFamily: 'Varela Round', fontSize: 20.0);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Center(
|
||||||
|
child: Container(
|
||||||
|
margin: EdgeInsets.only(top: MediaQuery.of(context).size.height * 0.09),
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[_astrolabeLogo(), SizedBox(height: 5.0), _appTitle(context)],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _astrolabeLogo() {
|
||||||
|
return Image.asset(
|
||||||
|
"assets/astrolabe_logo.jpg",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _appTitle(BuildContext context) {
|
||||||
|
return Text("AstroNotes",
|
||||||
|
style:
|
||||||
|
style.copyWith(color: Colors.black, fontSize: 40));
|
||||||
|
}
|
||||||
|
}
|
105
pubspec.lock
105
pubspec.lock
@ -64,6 +64,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "0.1.3"
|
||||||
|
file:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: file
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "5.2.1"
|
||||||
flushbar:
|
flushbar:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -86,6 +93,20 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
http:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: http
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.12.2"
|
||||||
|
http_parser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: http_parser
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.4"
|
||||||
image:
|
image:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -93,6 +114,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.12"
|
version: "2.1.12"
|
||||||
|
intl:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: intl
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.16.1"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -121,6 +149,27 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.4"
|
version: "1.6.4"
|
||||||
|
path_provider_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_linux
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.1+2"
|
||||||
|
path_provider_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: path_provider_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.2"
|
||||||
|
pedantic:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: pedantic
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.9.0"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -128,6 +177,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.4.0"
|
version: "2.4.0"
|
||||||
|
platform:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: platform
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.1"
|
||||||
platform_detect:
|
platform_detect:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@ -142,6 +198,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
|
process:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: process
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.13"
|
||||||
provider:
|
provider:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -163,6 +226,41 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.3"
|
version: "2.1.3"
|
||||||
|
shared_preferences:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: shared_preferences
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.5.8"
|
||||||
|
shared_preferences_linux:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_linux
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.2+1"
|
||||||
|
shared_preferences_macos:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_macos
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.1+10"
|
||||||
|
shared_preferences_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.4"
|
||||||
|
shared_preferences_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: shared_preferences_web
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.2+7"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -259,6 +357,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.8"
|
version: "2.0.8"
|
||||||
|
xdg_directories:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xdg_directories
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.0"
|
||||||
xml:
|
xml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -23,9 +23,12 @@ environment:
|
|||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
provider: ^4.3.1
|
|
||||||
flushbar: ^1.10.4
|
|
||||||
url_launcher: ^5.5.0
|
url_launcher: ^5.5.0
|
||||||
|
flushbar: ^1.10.4
|
||||||
|
http: ^0.12.2
|
||||||
|
provider: ^4.3.1
|
||||||
|
shared_preferences: ^0.5.8
|
||||||
|
|
||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
|
Loading…
Reference in New Issue
Block a user