Add login screen + logic + appcontext + redirection to main
This commit is contained in:
parent
9e4cd502cc
commit
ea7f3876c1
42
lib/Components/rounded_button.dart
Normal file
42
lib/Components/rounded_button.dart
Normal file
@ -0,0 +1,42 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:manager_app/constants.dart';
|
||||
|
||||
class RoundedButton extends StatelessWidget {
|
||||
final String text;
|
||||
final Function press;
|
||||
final Color color, textColor;
|
||||
final double fontSize;
|
||||
|
||||
const RoundedButton({
|
||||
Key key,
|
||||
this.text,
|
||||
this.press,
|
||||
this.color = kPrimaryColor,
|
||||
this.textColor = kWhite,
|
||||
this.fontSize
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
return TextButton(
|
||||
style: ButtonStyle(
|
||||
padding: MaterialStateProperty.resolveWith((states) => EdgeInsets.symmetric(vertical: 25, horizontal: 85)),
|
||||
backgroundColor: MaterialStateColor.resolveWith((states) => color),
|
||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(30.0),
|
||||
)
|
||||
)
|
||||
),
|
||||
|
||||
onPressed: () => {
|
||||
press()
|
||||
},
|
||||
child: Text(
|
||||
text,
|
||||
style: new TextStyle(color: textColor, fontSize: fontSize, fontWeight: FontWeight.w400),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
35
lib/Components/rounded_input_field.dart
Normal file
35
lib/Components/rounded_input_field.dart
Normal file
@ -0,0 +1,35 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:manager_app/Components/text_field_container.dart';
|
||||
import 'package:manager_app/constants.dart';
|
||||
|
||||
class RoundedInputField extends StatelessWidget {
|
||||
final String hintText;
|
||||
final IconData icon;
|
||||
final ValueChanged<String> onChanged;
|
||||
const RoundedInputField({
|
||||
Key key,
|
||||
this.hintText,
|
||||
this.icon = Icons.person,
|
||||
this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextFieldContainer(
|
||||
child: TextField(
|
||||
onChanged: onChanged,
|
||||
cursorColor: kPrimaryColor,
|
||||
style: TextStyle(fontSize: 20, color: kBlack),
|
||||
decoration: InputDecoration(
|
||||
icon: Icon(
|
||||
icon,
|
||||
color: kPrimaryColor,
|
||||
),
|
||||
hintText: hintText,
|
||||
hintStyle: TextStyle(fontSize: 20.0, color: kBlack),
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
48
lib/Components/rounded_password_field.dart
Normal file
48
lib/Components/rounded_password_field.dart
Normal file
@ -0,0 +1,48 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:manager_app/Components/text_field_container.dart';
|
||||
import 'package:manager_app/constants.dart';
|
||||
|
||||
class RoundedPasswordField extends StatefulWidget {
|
||||
final ValueChanged<String> onChanged;
|
||||
const RoundedPasswordField({
|
||||
Key key,
|
||||
this.onChanged,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
_RoundedPasswordFieldState createState() => _RoundedPasswordFieldState();
|
||||
}
|
||||
|
||||
class _RoundedPasswordFieldState extends State<RoundedPasswordField> {
|
||||
bool isVisible = true;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return TextFieldContainer(
|
||||
child: TextField(
|
||||
obscureText: isVisible,
|
||||
onChanged: widget.onChanged,
|
||||
cursorColor: kPrimaryColor,
|
||||
style: TextStyle(fontSize: 20, color: kBlack),
|
||||
decoration: InputDecoration(
|
||||
hintText: "Password",
|
||||
hintStyle: TextStyle(fontSize: 20.0, color: kBlack),
|
||||
icon: Icon(
|
||||
Icons.lock,
|
||||
color: kPrimaryColor,
|
||||
),
|
||||
suffixIcon: IconButton(
|
||||
icon: Icon(Icons.visibility),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
isVisible = !isVisible;
|
||||
});
|
||||
},
|
||||
color: kPrimaryColor,
|
||||
),
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
25
lib/Components/text_field_container.dart
Normal file
25
lib/Components/text_field_container.dart
Normal file
@ -0,0 +1,25 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:manager_app/constants.dart';
|
||||
|
||||
class TextFieldContainer extends StatelessWidget {
|
||||
final Widget child;
|
||||
const TextFieldContainer({
|
||||
Key key,
|
||||
this.child,
|
||||
}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Size size = MediaQuery.of(context).size;
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 10),
|
||||
padding: EdgeInsets.symmetric(horizontal: 20, vertical: 5),
|
||||
width: size.width * 0.8,
|
||||
decoration: BoxDecoration(
|
||||
color: kTextLightColor,
|
||||
borderRadius: BorderRadius.circular(29),
|
||||
),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
18
lib/Models/managerContext.dart
Normal file
18
lib/Models/managerContext.dart
Normal file
@ -0,0 +1,18 @@
|
||||
import 'dart:convert';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:managerapi/api.dart';
|
||||
|
||||
|
||||
class ManagerAppContext with ChangeNotifier{
|
||||
String email;
|
||||
TokenDTO token;
|
||||
dynamic clientAPI;
|
||||
|
||||
ManagerAppContext({this.email, this.token});
|
||||
|
||||
// Implement toString to make it easier to see information about
|
||||
@override
|
||||
String toString() {
|
||||
return 'ManagerAppContext{email: $email, token: $token}';
|
||||
}
|
||||
}
|
||||
46
lib/Screens/Main/main_screen.dart
Normal file
46
lib/Screens/Main/main_screen.dart
Normal file
@ -0,0 +1,46 @@
|
||||
import 'package:manager_app/app_context.dart';
|
||||
import 'package:managerapi/api.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class MainScreen extends StatefulWidget {
|
||||
MainScreen({Key key, this.title}) : super(key: key);
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
_MainScreenState createState() => _MainScreenState();
|
||||
}
|
||||
|
||||
class _MainScreenState extends State<MainScreen> {
|
||||
int _counter = 0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appContext = Provider.of<AppContext>(context);
|
||||
|
||||
print(appContext.getContext().email);
|
||||
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'You have pushed the button this many times:',
|
||||
),
|
||||
Text(
|
||||
'$_counter',
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: () => print("YOULOU"),
|
||||
tooltip: 'Increment',
|
||||
child: Icon(Icons.add),
|
||||
), // This trailing comma makes auto-formatting nicer for build methods.
|
||||
);
|
||||
}
|
||||
}
|
||||
155
lib/Screens/login_screen.dart
Normal file
155
lib/Screens/login_screen.dart
Normal file
@ -0,0 +1,155 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:manager_app/Components/rounded_button.dart';
|
||||
import 'package:manager_app/Components/rounded_input_field.dart';
|
||||
import 'package:manager_app/Components/rounded_password_field.dart';
|
||||
import 'package:manager_app/Models/managerContext.dart';
|
||||
import 'package:manager_app/Screens/Main/main_screen.dart';
|
||||
import 'package:manager_app/app_context.dart';
|
||||
import 'package:manager_app/client.dart';
|
||||
import 'package:manager_app/constants.dart';
|
||||
import 'package:managerapi/api.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class LoginScreen extends StatefulWidget {
|
||||
LoginScreen({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
_LoginScreenState createState() => _LoginScreenState();
|
||||
}
|
||||
|
||||
class _LoginScreenState extends State<LoginScreen> {
|
||||
String email;// = "test@email.be";
|
||||
String password;// = "kljqsdkljqsd";
|
||||
final clientAPI = Client();
|
||||
|
||||
void authenticateTRY(dynamic appContext) async {
|
||||
print("try auth.. ");
|
||||
print(this.email);
|
||||
print(this.password);
|
||||
|
||||
// if () {} // Add if token exist and not null + not expired
|
||||
var isError = true;
|
||||
try {
|
||||
LoginDTO loginDTO = new LoginDTO(email: email, password: password);
|
||||
TokenDTO token = await clientAPI.authenticationApi.authenticationAuthenticateWithJson(loginDTO);
|
||||
print("Token ??");
|
||||
print(token);
|
||||
print(token.accessToken);
|
||||
setAccessToken(token.accessToken);
|
||||
isError = false;
|
||||
// Set the appContext
|
||||
if (appContext.getContext() == null) {
|
||||
ManagerAppContext managerAppContext = new ManagerAppContext();
|
||||
// store user info locally
|
||||
managerAppContext.email = email;
|
||||
managerAppContext.token = token;
|
||||
managerAppContext.clientAPI = clientAPI;
|
||||
print(managerAppContext);
|
||||
|
||||
appContext.setContext(managerAppContext);
|
||||
}
|
||||
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) {
|
||||
return MainScreen();
|
||||
},
|
||||
),
|
||||
(Route<dynamic> route) => false // For pushAndRemoveUntil
|
||||
);
|
||||
}
|
||||
catch (e) {
|
||||
print("error auth");
|
||||
}
|
||||
|
||||
/*if (!isError) {
|
||||
UserDetailDTO user = await clientAPI.userApi.userGetDetail("6071f74aaf542f03116f2b9b");
|
||||
print("user values ??");
|
||||
print(user.email);
|
||||
print(user.id);
|
||||
|
||||
List<ConfigurationDTO> configurations = await clientAPI.configurationApi.configurationGet();
|
||||
print("number of configurations " + configurations.length.toString());
|
||||
configurations.forEach((element) {
|
||||
print(element);
|
||||
});
|
||||
|
||||
List<SectionDTO> sections = await clientAPI.sectionApi.sectionGet();
|
||||
print("number of sections " + sections.length.toString());
|
||||
sections.forEach((element) {
|
||||
print(element);
|
||||
});
|
||||
|
||||
List<RessourceDTO> ressources = await clientAPI.ressourceApi.ressourceGet();
|
||||
print("number of ressources " + ressources.length.toString());
|
||||
ressources.forEach((element) {
|
||||
print(element);
|
||||
});
|
||||
}*/
|
||||
}
|
||||
|
||||
void setAccessToken(String accessToken) {
|
||||
clientAPI.apiApi.authentications.forEach((key, auth) {
|
||||
if (auth is OAuth) {
|
||||
auth.accessToken = accessToken;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final appContext = Provider.of<AppContext>(context);
|
||||
Size size = MediaQuery.of(context).size;
|
||||
|
||||
return Scaffold(
|
||||
body: Center(
|
||||
child: SingleChildScrollView(
|
||||
child: Container(
|
||||
height: size.height *0.5,
|
||||
width: size.width *0.5,
|
||||
decoration: BoxDecoration(
|
||||
color: kWhite,
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
color: kWhite.withOpacity(0.3),
|
||||
spreadRadius: 0.5,
|
||||
blurRadius: 0.5,
|
||||
offset: Offset(0, 1.5), // changes position of shadow
|
||||
),
|
||||
],
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 60.0, right: 60.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
RoundedInputField(
|
||||
hintText: "Your Email",
|
||||
onChanged: (value) {
|
||||
email = value;
|
||||
},
|
||||
),
|
||||
RoundedPasswordField(
|
||||
onChanged: (value) {
|
||||
password = value;
|
||||
},
|
||||
),
|
||||
SizedBox(height: size.height * 0.02),
|
||||
RoundedButton(
|
||||
text: "LOGIN",
|
||||
fontSize: 25,
|
||||
press: () {
|
||||
authenticateTRY(appContext);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
22
lib/app_context.dart
Normal file
22
lib/app_context.dart
Normal file
@ -0,0 +1,22 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'Models/managerContext.dart';
|
||||
|
||||
class AppContext with ChangeNotifier {
|
||||
ManagerAppContext _managerContext;
|
||||
|
||||
AppContext(this._managerContext);
|
||||
|
||||
getContext() => _managerContext;
|
||||
setContext(ManagerAppContext appContext) async {
|
||||
_managerContext = appContext;
|
||||
|
||||
// STORE IT LOCALLY (SQLite)
|
||||
//await DatabaseHelper.instance.update(appContext);
|
||||
|
||||
// Store it in Firestore
|
||||
//await FirestoreHelper.instance.add(appContext);
|
||||
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
@ -1,10 +1,17 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// Colors - TO FILL WIT CORRECT COLOR
|
||||
const kBackgroundColor = Color(0xFFFFFFFF);
|
||||
//const kBackgroundColor = Color(0xFFFFFFFF);
|
||||
const kTitleTextColor = Color(0xFF303030);
|
||||
const kBodyTextColor = Color(0xFF4B4B4B); // TODO
|
||||
const kTextLightColor = Color(0xFFCED5DF); // #ced5df
|
||||
|
||||
|
||||
const kBackgroundColor = Color(0xFFf5f5f7);
|
||||
const kPrimaryColor = Color(0xFFCA413F);
|
||||
const kTextLightColor = Color(0xFFE3DfDE);
|
||||
const kSecond = Color(0xFFC4B1AE);
|
||||
const kWhite = Color(0xFFFFFFFF);
|
||||
const kBlack = Color(0xFF000000);
|
||||
|
||||
/*
|
||||
const kTextStyle = TextStyle(
|
||||
|
||||
178
lib/main.dart
178
lib/main.dart
@ -1,12 +1,17 @@
|
||||
import 'package:manager_app/Models/managerContext.dart';
|
||||
import 'package:manager_app/Screens/Main/main_screen.dart';
|
||||
import 'package:managerapi/api.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'Screens/login_screen.dart';
|
||||
import 'app_context.dart';
|
||||
import 'client.dart';
|
||||
import 'constants.dart';
|
||||
|
||||
void main() {
|
||||
String initialRoute;
|
||||
|
||||
initialRoute = '/home';
|
||||
initialRoute = '/welcome';
|
||||
|
||||
final MyApp myApp = MyApp(
|
||||
initialRoute: initialRoute,
|
||||
@ -18,8 +23,8 @@ void main() {
|
||||
|
||||
class MyApp extends StatefulWidget {
|
||||
final String initialRoute;
|
||||
//final Context context;
|
||||
MyApp({this.initialRoute});
|
||||
final ManagerAppContext managerAppContext;
|
||||
MyApp({this.initialRoute, this.managerAppContext});
|
||||
|
||||
// This widget is the root of your application.
|
||||
@override
|
||||
@ -29,152 +34,29 @@ class MyApp extends StatefulWidget {
|
||||
class _MyAppState extends State<MyApp> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'Manager App Demo',
|
||||
initialRoute: widget.initialRoute,
|
||||
/*supportedLocales: [
|
||||
const Locale('en', 'US'),
|
||||
//const Locale('fr', 'FR'),
|
||||
],*/
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
scaffoldBackgroundColor: kBackgroundColor,
|
||||
//fontFamily: "Vollkorn",
|
||||
textTheme: TextTheme(bodyText1: TextStyle(color: kBodyTextColor)),
|
||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||
),
|
||||
routes: {
|
||||
'/home': (context) => MyHomePage(title: 'Manager App Demo Home Page')
|
||||
}
|
||||
return ChangeNotifierProvider<AppContext>(
|
||||
create: (_) => AppContext(widget.managerAppContext),
|
||||
child: MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
title: 'Manager App Demo',
|
||||
initialRoute: widget.initialRoute,
|
||||
/*supportedLocales: [
|
||||
const Locale('en', 'US'),
|
||||
//const Locale('fr', 'FR'),
|
||||
],*/
|
||||
theme: ThemeData(
|
||||
primarySwatch: Colors.blue,
|
||||
scaffoldBackgroundColor: kBackgroundColor,
|
||||
//fontFamily: "Vollkorn",
|
||||
textTheme: TextTheme(bodyText1: TextStyle(color: kBodyTextColor)),
|
||||
visualDensity: VisualDensity.adaptivePlatformDensity,
|
||||
),
|
||||
routes: {
|
||||
'/welcome': (context) => LoginScreen(),
|
||||
'/main': (context) => MainScreen(title: 'Manager App Demo Home Page')
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
MyHomePage({Key key, this.title}) : super(key: key);
|
||||
|
||||
// This widget is the home page of your application. It is stateful, meaning
|
||||
// that it has a State object (defined below) that contains fields that affect
|
||||
// how it looks.
|
||||
|
||||
// This class is the configuration for the state. It holds the values (in this
|
||||
// case the title) provided by the parent (in this case the App widget) and
|
||||
// used by the build method of the State. Fields in a Widget subclass are
|
||||
// always marked "final".
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
_MyHomePageState createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
int _counter = 0;
|
||||
|
||||
final clientAPI = Client();
|
||||
|
||||
void authenticateTRY() async {
|
||||
print("try auth.. ");
|
||||
|
||||
// if () {} // Add if token exist and not null + not expired
|
||||
var isError = true;
|
||||
try {
|
||||
LoginDTO loginDTO = new LoginDTO(email: "test@email.be", password: "kljqsdkljqsd");
|
||||
TokenDTO token = await clientAPI.authenticationApi.authenticationAuthenticateWithJson(loginDTO);
|
||||
print("Token ??");
|
||||
print(token);
|
||||
print(token.accessToken);
|
||||
setAccessToken(token.accessToken);
|
||||
isError = false;
|
||||
}
|
||||
catch (e) {
|
||||
print("error auth");
|
||||
}
|
||||
|
||||
if (!isError) {
|
||||
UserDetailDTO user = await clientAPI.userApi.userGetDetail("6071f74aaf542f03116f2b9b");
|
||||
print("user values ??");
|
||||
print(user.email);
|
||||
print(user.id);
|
||||
|
||||
List<ConfigurationDTO> configurations = await clientAPI.configurationApi.configurationGet();
|
||||
print("number of configurations " + configurations.length.toString());
|
||||
configurations.forEach((element) {
|
||||
print(element);
|
||||
});
|
||||
|
||||
List<SectionDTO> sections = await clientAPI.sectionApi.sectionGet();
|
||||
print("number of sections " + sections.length.toString());
|
||||
sections.forEach((element) {
|
||||
print(element);
|
||||
});
|
||||
|
||||
List<RessourceDTO> ressources = await clientAPI.ressourceApi.ressourceGet();
|
||||
print("number of ressources " + ressources.length.toString());
|
||||
ressources.forEach((element) {
|
||||
print(element);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void setAccessToken(String accessToken) {
|
||||
clientAPI.apiApi.authentications.forEach((key, auth) {
|
||||
if (auth is OAuth) {
|
||||
auth.accessToken = accessToken;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// This method is rerun every time setState is called, for instance as done
|
||||
// by the _incrementCounter method above.
|
||||
//
|
||||
// The Flutter framework has been optimized to make rerunning build methods
|
||||
// fast, so that you can just rebuild anything that needs updating rather
|
||||
// than having to individually change instances of widgets.
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
// Here we take the value from the MyHomePage object that was created by
|
||||
// the App.build method, and use it to set our appbar title.
|
||||
title: Text(widget.title),
|
||||
),
|
||||
body: Center(
|
||||
// Center is a layout widget. It takes a single child and positions it
|
||||
// in the middle of the parent.
|
||||
child: Column(
|
||||
// Column is also a layout widget. It takes a list of children and
|
||||
// arranges them vertically. By default, it sizes itself to fit its
|
||||
// children horizontally, and tries to be as tall as its parent.
|
||||
//
|
||||
// Invoke "debug painting" (press "p" in the console, choose the
|
||||
// "Toggle Debug Paint" action from the Flutter Inspector in Android
|
||||
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
|
||||
// to see the wireframe for each widget.
|
||||
//
|
||||
// Column has various properties to control how it sizes itself and
|
||||
// how it positions its children. Here we use mainAxisAlignment to
|
||||
// center the children vertically; the main axis here is the vertical
|
||||
// axis because Columns are vertical (the cross axis would be
|
||||
// horizontal).
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'You have pushed the button this many times:',
|
||||
),
|
||||
Text(
|
||||
'$_counter',
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: authenticateTRY,
|
||||
tooltip: 'Increment',
|
||||
child: Icon(Icons.add),
|
||||
), // This trailing comma makes auto-formatting nicer for build methods.
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
15
pubspec.lock
15
pubspec.lock
@ -109,6 +109,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
nested:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: nested
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
path:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -123,6 +130,13 @@ packages:
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "1.11.0"
|
||||
provider:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: provider
|
||||
url: "https://pub.dartlang.org"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
rxdart:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -193,3 +207,4 @@ packages:
|
||||
version: "2.1.0"
|
||||
sdks:
|
||||
dart: ">=2.12.0-0.0 <3.0.0"
|
||||
flutter: ">=1.16.0"
|
||||
|
||||
@ -25,6 +25,7 @@ dependencies:
|
||||
sdk: flutter
|
||||
|
||||
rxdart: 0.22.0
|
||||
provider: ^5.0.0
|
||||
managerapi:
|
||||
path: manager_api
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user