Commit bc6d5697 authored by Luca Braun's avatar Luca Braun

Merge remote-tracking branch 'origin/feature/dashboard' into feature/dashboard

parents 3a0e8452 2be2c232
# This is a generated file; do not edit or check into version control.
integration_test=C:\\Libs\\flutter\\packages\\integration_test\\
integration_test=C:\\_libs\\flutter\\packages\\integration_test\\
path_provider=C:\\_libs\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\path_provider-1.6.27\\
path_provider_linux=C:\\_libs\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\path_provider_linux-0.0.1+2\\
path_provider_macos=C:\\_libs\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\path_provider_macos-0.0.4+8\\
path_provider_windows=C:\\_libs\\flutter\\.pub-cache\\hosted\\pub.dartlang.org\\path_provider_windows-0.0.5\\
......@@ -3,6 +3,7 @@
#
# For more info see: https://dart.dev/go/dot-packages-deprecation
#
<<<<<<< HEAD
<<<<<<< Updated upstream
# Generated by pub on 2021-03-09 22:03:23.618434.
apex_flutter_sdk:file:///C:/Libs/flutter/.pub-cache/hosted/pub.dartlang.org/apex_flutter_sdk-1.1.1+1/lib/
......@@ -96,4 +97,62 @@ vector_math:file:///C:/Users/Luca/Documents/flutter/flutter_windows_1.22.5-stabl
vm_service:file:///C:/Users/Luca/Documents/flutter/flutter_windows_1.22.5-stable/flutter/.pub-cache/hosted/pub.dartlang.org/vm_service-5.5.0/lib/
webdriver:file:///C:/Users/Luca/Documents/flutter/flutter_windows_1.22.5-stable/flutter/.pub-cache/hosted/pub.dartlang.org/webdriver-2.1.2/lib/
>>>>>>> Stashed changes
=======
# Generated by pub on 2021-03-11 10:11:51.659292.
apex_flutter_sdk:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/apex_flutter_sdk-1.1.1+1/lib/
archive:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/archive-2.0.13/lib/
args:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/args-1.6.0/lib/
async:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/async-2.5.0/lib/
boolean_selector:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/boolean_selector-2.1.0/lib/
characters:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/characters-1.1.0/lib/
charcode:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/charcode-1.2.0/lib/
circlegraph:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/circlegraph-0.0.6/lib/
clock:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/clock-1.1.0/lib/
collection:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/collection-1.15.0/lib/
convert:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/convert-2.1.1/lib/
crypto:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/crypto-2.1.5/lib/
cupertino_icons:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/cupertino_icons-1.0.2/lib/
enhanced_future_builder:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/enhanced_future_builder-1.0.3/lib/
fake_async:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/fake_async-1.2.0/lib/
ffi:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/ffi-1.0.0/lib/
file:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/file-6.0.0/lib/
flutter:file:///C:/_libs/flutter/packages/flutter/lib/
flutter_driver:file:///C:/_libs/flutter/packages/flutter_driver/lib/
flutter_spinkit:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/flutter_spinkit-5.0.0/lib/
flutter_test:file:///C:/_libs/flutter/packages/flutter_test/lib/
fuchsia_remote_debug_protocol:file:///C:/_libs/flutter/packages/fuchsia_remote_debug_protocol/lib/
graphview:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/graphview-0.6.7/lib/
http:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/http-0.12.2/lib/
http_parser:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/http_parser-3.1.4/lib/
integration_test:file:///C:/_libs/flutter/packages/integration_test/lib/
localstorage:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/localstorage-3.0.6+9/lib/
logger:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/logger-0.9.4/lib/
matcher:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/matcher-0.12.10/lib/
meta:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/meta-1.3.0/lib/
path:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/path-1.8.0/lib/
path_provider:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider-1.6.27/lib/
path_provider_linux:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_linux-0.0.1+2/lib/
path_provider_macos:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_macos-0.0.4+8/lib/
path_provider_platform_interface:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_platform_interface-1.0.4/lib/
path_provider_windows:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/path_provider_windows-0.0.5/lib/
pedantic:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/pedantic-1.11.0/lib/
platform:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/platform-3.0.0/lib/
plugin_platform_interface:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/plugin_platform_interface-1.0.3/lib/
process:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/process-4.0.0/lib/
shamsi_date:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/shamsi_date-0.8.1/lib/
sky_engine:file:///C:/_libs/flutter/bin/cache/pkg/sky_engine/lib/
source_span:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/source_span-1.8.0/lib/
stack_trace:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/stack_trace-1.10.0/lib/
stream_channel:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/stream_channel-2.1.0/lib/
string_scanner:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/string_scanner-1.1.0/lib/
sync_http:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/sync_http-0.2.0/lib/
term_glyph:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/term_glyph-1.2.0/lib/
test_api:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/test_api-0.2.19/lib/
typed_data:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/typed_data-1.3.0/lib/
vector_math:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/vector_math-2.1.0/lib/
vm_service:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/vm_service-5.5.0/lib/
webdriver:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/webdriver-2.1.2/lib/
win32:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/win32-2.0.0/lib/
xdg_directories:file:///C:/_libs/flutter/.pub-cache/hosted/pub.dartlang.org/xdg_directories-0.1.2/lib/
>>>>>>> dashboard
dashboard:lib/
......@@ -14,5 +14,6 @@ import io.flutter.embedding.engine.FlutterEngine;
public final class GeneratedPluginRegistrant {
public static void registerWith(@NonNull FlutterEngine flutterEngine) {
flutterEngine.getPlugins().add(new dev.flutter.plugins.integration_test.IntegrationTestPlugin());
flutterEngine.getPlugins().add(new io.flutter.plugins.pathprovider.PathProviderPlugin());
}
}
sdk.dir=C:\\Users\\herry\\AppData\\Local\\Android\\sdk
flutter.sdk=C:\\Libs\\flutter
\ No newline at end of file
sdk.dir=C:\\Users\\Manuel\\AppData\\Local\\Android\\sdk
flutter.sdk=C:\\_libs\\flutter
\ No newline at end of file
This diff is collapsed.
class ServerConstants {
static const String host = "https://articonf1.itec.aau.at:30401/";
}
class LoginException implements Exception {
final String message;
LoginException(this.message);
}
import 'package:circlegraph/circlegraph.dart';
import 'package:dashboard/querying/datagetter.dart';
import 'package:dashboard/ui/util/logged_in_appbar.dart';
import 'package:enhanced_future_builder/enhanced_future_builder.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
......@@ -102,6 +103,7 @@ class CommunityGraphViewPage extends StatelessWidget {
Widget build(BuildContext context) {
return Scaffold(
appBar: LoggedInAppBar(),
backgroundColor: Colors.white,
floatingActionButton: FloatingActionButton(
onPressed: () => redirectToCommunityMetaGraph(context),
......
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
class LoadingScreen extends StatelessWidget {
final String message;
LoadingScreen({this.message = "Loading..."});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
SpinKitRotatingCircle(
color: Theme.of(context).primaryColor,
size: 150.0,
),
SizedBox(height: 16),
Text(message),
],
),
),
);
}
}
import 'package:dashboard/exceptions/login_exception.dart';
import 'package:dashboard/graphing/communitygraph.dart';
import 'package:dashboard/loading.dart';
import 'package:dashboard/ui/sign_in/loginpage.dart';
import 'package:dashboard/util/loginhelper.dart';
import 'package:dashboard/util/user.dart';
import 'package:enhanced_future_builder/enhanced_future_builder.dart';
import 'package:flutter/material.dart';
import 'graphing/usergraph.dart';
import 'graphing/communitygraph.dart';
......@@ -8,9 +14,32 @@ void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Future<BackendUser> _checkLoginStuff() async {
await Future.delayed(Duration(milliseconds: 500));
try {
return await LoginHelper().loggedInUser;
} on LoginException {
return null;
}
}
@override
Widget build(BuildContext context) => MaterialApp(
home: CommunityGraphViewPage("COVID19"),
home: EnhancedFutureBuilder<BackendUser>(
future: _checkLoginStuff(),
whenNotDone: LoadingScreen(),
rememberFutureResult: false,
whenDone: (BackendUser snapshotData) {
if (snapshotData == null) return LoginPage();
return CommunityGraphViewPage("worldnews");
},
),
);
}
......@@ -6,40 +6,39 @@ class LoginForm extends StatefulWidget {
final Function(String, String) loginAttempt;
final String error;
final bool isBusy;
LoginForm(this.loginAttempt, this.error);
LoginForm(this.loginAttempt, this.error, this.isBusy);
}
class _LoginFormState extends State<LoginForm> {
bool _busy = false;
String _username = "";
String _password = "";
void _submit() {
setState(() {
_busy = true;
});
widget.loginAttempt(_username, _password);
if (!widget.isBusy) widget.loginAttempt(_username, _password);
}
@override
Widget build(BuildContext context) {
_busy = false;
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
FractionallySizedBox(
widthFactor: 0.3,
child: Center(
child: TextField(
readOnly: _busy,
return FocusTraversalGroup(
policy: OrderedTraversalPolicy(),
child: FractionallySizedBox(
widthFactor: .6,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Image.asset(
"assets/articonf-logo.png",
),
SizedBox(height: 32),
TextField(
readOnly: widget.isBusy,
autofocus: true,
decoration: InputDecoration(
hintText: "Username",
counterText: "",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(
......@@ -53,42 +52,59 @@ class _LoginFormState extends State<LoginForm> {
maxLines: 1,
maxLength: 50,
),
),
),
FractionallySizedBox(
widthFactor: 0.3,
child: TextField(
readOnly: _busy,
autofocus: false,
obscureText: true,
decoration: InputDecoration(
hintText: "Password",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(
color: Colors.blue,
style: BorderStyle.solid,
SizedBox(height: 16),
TextField(
readOnly: widget.isBusy,
autofocus: false,
obscureText: true,
decoration: InputDecoration(
hintText: "Password",
counterText: "",
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(5.0),
borderSide: BorderSide(
color: Colors.blue,
style: BorderStyle.solid,
),
),
),
onChanged: (content) => _password = content,
minLines: 1,
maxLines: 1,
maxLength: 50,
),
onChanged: (content) => _password = content,
minLines: 1,
maxLines: 1,
maxLength: 50,
),
),
// error message
if (widget.error != null && widget.error.isNotEmpty)
Text(
widget.error,
style: TextStyle(color: Colors.red),
),
FloatingActionButton(
onPressed: _submit,
child: Icon(Icons.login),
backgroundColor: _busy ? Colors.grey : Colors.blue,
// error message
if (widget.error != null && widget.error.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: 16.0),
child: Text(
widget.error,
style: TextStyle(color: Colors.red),
),
),
// login button
SizedBox(height: 16),
TextButton.icon(
onPressed: _submit,
icon: Icon(
Icons.login,
size: 32,
color: Colors.white,
),
label: Text(
"Sign In",
style: TextStyle(fontSize: 20, color: Colors.white),
),
style: TextButton.styleFrom(
backgroundColor: widget.isBusy
? Colors.grey
: Theme.of(context).primaryColor,
padding: EdgeInsets.all(18),
),
),
],
),
],
),
);
}
}
import 'package:dashboard/exceptions/login_exception.dart';
import 'package:dashboard/main.dart';
import 'package:dashboard/ui/sign_in/login_form.dart';
import 'package:dashboard/util/loginhelper.dart';
import 'package:dashboard/util/user.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:logger/logger.dart';
class LoginPage extends StatefulWidget {
LoginPage();
@override
_LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
String _error;
bool _isBusy = false;
final Logger logger = Logger();
Widget build(BuildContext context) {
return Scaffold(
body: Container(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.blue[300],
Colors.blue,
],
),
),
padding: EdgeInsets.symmetric(horizontal: 32, vertical: 64),
child: Container(
color: Colors.white,
child: Row(
children: [
Expanded(
flex: 4,
child: Container(
child: LoginForm(tryLogin, _error, _isBusy),
),
),
Expanded(
flex: 3,
child: Container(
constraints: BoxConstraints.expand(),
child: Stack(
children: [
Container(
constraints: BoxConstraints.expand(),
child: Image.asset(
"assets/login_image.jpg",
fit: BoxFit.cover,
alignment: Alignment(-.2, 0),
),
),
Container(
color: Color.fromRGBO(33, 150, 243, .5),
),
],
),
),
),
],
),
),
),
);
}
///
/// attempts to receive a token from the server
///
void tryLogin(String username, String password) async {
logger.i("Loggin Attempt($username, ******)");
setState(() {
_error = "";
_isBusy = true;
});
BackendUser user;
await Future.delayed(Duration(seconds: 1));
try {
user = await LoginHelper().login(username, password);
} on LoginException catch (e) {
setState(() {
_error = e.message;
_isBusy = false;
});
return;
}
logger.i("token: ${user.token}");
// restart app (should login automatically)
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => MyApp(),
),
);
}
}
import 'package:dashboard/main.dart';
import 'package:dashboard/util/loginhelper.dart';
import 'package:flutter/material.dart';
class LoggedInAppBar extends PreferredSize {
@override
Size get preferredSize => Size.fromHeight(60);
Future<void> _onLogout(context) async {
await LoginHelper().logout();
Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => MyApp(),
),
);
}
@override
Widget build(BuildContext context) {
return AppBar(
backgroundColor: Colors.blue,
actions: [
Padding(
padding: const EdgeInsets.all(8.0),
child: TextButton.icon(
onPressed: () => _onLogout(context),
icon: Icon(
Icons.logout,
color: Colors.white,
size: 25,
),
label: Text(
"Logout",
style: TextStyle(
color: Colors.white,
fontSize: 20,
),
),
),
),
],
);
}
}
import 'dart:convert';
import 'dart:io';
import 'package:dashboard/constants/server_constants.dart';
import 'package:dashboard/exceptions/login_exception.dart';
import 'package:dashboard/util/user.dart';
import 'package:localstorage/localstorage.dart';
import 'package:logger/logger.dart';
import 'package:http/http.dart' as http;
class LoginHelper {
static final LoginHelper _instance = LoginHelper._internal();
factory LoginHelper() => _instance;
// private constructor
LoginHelper._internal();
final Logger _logger = Logger();
static const String _storageName = "login_storage";
static const String _keyUser = "user";
Future<LocalStorage> get _loginStorage async {
LocalStorage storage = LocalStorage(_storageName);
await storage.ready;
return storage;
}
Future<BackendUser> get loggedInUser async {
LocalStorage storage = await _loginStorage;
Map<String, dynamic> row = storage.getItem(_keyUser);
if (row == null) throw LoginException("No user is currently logged in");
return BackendUser.fromMap(row);
}
Future<void> logout() async {
LocalStorage storage = await _loginStorage;
storage.setItem(_keyUser, null);
}
Future<BackendUser> login(String username, String password) async {
if (username.isEmpty || password.isEmpty)
throw LoginException("Fields cannot be empty!");
String json = jsonEncode({
"username": username,
"password": password,
});
String url = "${ServerConstants.host}/api/tokens";
_logger.v("calling $url");
http.Response response = await http.post(
url,
headers: {
HttpHeaders.contentTypeHeader: "application/json",
},
body: json,
);
if (response.statusCode != 200) {
_logger.e(
"Server responded with (${response.statusCode}): ${response.body}");
if (response.statusCode == 400 &&
response.body.endsWith("does not exist"))
throw LoginException("No user was found!");
throw LoginException(
"An unexpected error occurred (${response.statusCode}");
}
_logger
.v("Server responded with (${response.statusCode}): ${response.body}");
Map<String, dynamic> data = jsonDecode(response.body);
String token = data["token"];
if (token == null || token.isEmpty)
throw LoginException("An unknown problem occurred!");
LocalStorage storage = await _loginStorage;
BackendUser user = BackendUser(username, token);
storage.setItem(_keyUser, user.toMap());
Map<String, dynamic> row = storage.getItem(_keyUser);
return BackendUser.fromMap(row);
}
}
class BackendUser {
final String username;
final String token;
BackendUser(this.username, this.token);
factory BackendUser.fromMap(Map<String, dynamic> row) =>
BackendUser(row["username"], row["token"]);
Map<String, dynamic> toMap() => {"username": username, "token": token};
}
......@@ -56,7 +56,7 @@ packages:
name: circlegraph
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.5"
version: "0.0.6"
clock:
dependency: transitive
description:
......@@ -106,6 +106,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
file:
dependency: transitive
description:
......@@ -123,6 +130,13 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_spinkit:
dependency: "direct main"
description:
name: flutter_spinkit
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.0"
flutter_test:
dependency: "direct dev"
description: flutter
......@@ -159,6 +173,13 @@ packages:
description: flutter
source: sdk
version: "0.9.2+2"
localstorage:
dependency: "direct main"
description:
name: localstorage
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.6+9"
logger:
dependency: "direct main"
description:
......@@ -187,6 +208,41 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
path_provider:
dependency: transitive
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.27"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+2"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+8"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.5"
pedantic:
dependency: transitive
description:
......@@ -201,6 +257,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
process:
dependency: transitive
description:
......@@ -297,6 +360,20 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
sdks:
dart: ">=2.12.0-0.0 <3.0.0"
flutter: ">=1.17.0"
dart: ">=2.12.0 <3.0.0"
flutter: ">=2.0.0"
......@@ -15,9 +15,11 @@ dependencies:
apex_flutter_sdk: ^1.1.1+1
enhanced_future_builder: ^1.0.3
http: ^0.12.2
circlegraph: ^0.0.5
circlegraph: ^0.0.6
cupertino_icons: ^1.0.1
logger: ^0.9.4
localstorage: ^3.0.6
flutter_spinkit: ^5.0.0
dev_dependencies:
flutter_test:
......@@ -28,6 +30,5 @@ dev_dependencies:
flutter:
assets:
- assets/user.png
- assets/carcarbinks.jpg
- assets/
uses-material-design: true
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment