Compare commits

..

1 commit

10 changed files with 195 additions and 131 deletions

114
README.md
View file

@ -1,99 +1,47 @@
# LocalSpend (Mobile App.) # LocalSpend Mobile App.
Looking to discover if the value of spending local can be measured, understood and shown. This repo. contains the mobile application for use with the LocalSpend system,
using Flutter.
This repository contains the mobile application for the LocalSpend system. See also: ## Getting Started
* the [Web application](https://github.com/Pear-Trading/Foodloop-Web); and Follow these steps to get the project up-and-running:
* the [server](https://github.com/Pear-Trading/Foodloop-Server).
## Table of Contents 1. Install [Flutter](https://flutter.dev/docs/get-started/install)
1. Set up [your editor](https://flutter.dev/docs/get-started/editor)
1. If this is your first Flutter project, install the [Flutter SDK](https://flutter.dev/docs/get-started/test-drive)
1. Add the line `flutter.sdk=⟨ path to Flutter SDK ⟩` to the file `androud/local.properties`
* [Tech Stack](#tech-stack) ## Building
* [Features](#features)
* [Installation](#installation)
* [Configuration](#configuration)
* [Usage](#usage)
* [Testing](#testing)
* [Code Formatting](#code-formatting)
* [Documentation](#documentation)
* [Acknowledgments](#acknowledgements)
* [License](#license)
* [Contact](#contact)
## Technology Stack To build an apk from dev, use:
```
The mobile app. is written in [Dart](https://dart.dev/). flutter build apk -t lib/main_dev.dart
| Technology | Description | Link |
|-------------|---------------------------------|---------------------|
| Flutter | Cross-platform mobile framework | [Link][flutter] |
[flutter]: https://flutter.dev/
## Features
This mobile app. provides:
- user authentication; and
- transaction logging.
## Installation
1. Install [Flutter](https://flutter.dev/docs/get-started/install);
1. if this is your first Flutter project, install the [Flutter SDK](https://flutter.dev/docs/get-started/test-drive);
1. set up [your editor](https://flutter.dev/docs/get-started/editor):
- we recommend using [Android Studio](https://developer.android.com/studio).
1. add the line `flutter.sdk=⟨ path to Flutter SDK ⟩` to the file `android/local.properties`.
## Configuration
App. configuration settings are found in `pubspec.yaml`.
Build settings are found in the `android/` directory, in the `build.gradle`, `gradle.properties` and `settings.gradle` files.
## Usage
### Development
To activate debugging, add the following import statement:
```dart
import 'package:flutter/foundation.dart';
``` ```
After that, you can generate debugging output using `debugPrint()`. ## Debugging
### Production ```
// debug
import 'package:flutter/foundation.dart';
debugPrint('$foo');
```
Run `flutter build apk -t lib/main_dev.dart` to generate an APK file. ## Further Reading
## Testing A few resources to get you started if this is your first Flutter project:
TODO - [Lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook)
## Code Formatting For help getting started with Flutter, view our
[online documentation](https://flutter.io/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
TODO https://github.com/putraxor/flutter-login-ui
https://github.com/pbirdsall/medium_splash_tokenauth
## Documentation Related repos:
TODO - [`Pear-Trading/FoodLoop-Web`](https://github.com/Pear-Trading/FoodLoop-Web)
- [`Pear-Trading/Foodloop-Server`](https://github.com/Pear-Trading/Foodloop-Server)
## Acknowledgements
LocalLoop is the result of collaboration between the [Small Green Consultancy](http://www.smallgreenconsultancy.co.uk/), [Shadowcat Systems](https://shadow.cat/), [Independent Lancaster](http://www.independent-lancaster.co.uk/) and the [Ethical Small Traders Association](http://www.lancasteresta.org/).
## License
This project is released under the [MIT license](https://mit-license.org/).
## Contact
| Name | Link(s) |
|----------------|-------------------|
| Mark Keating | [Email][mkeating] |
| Michael Hallam | [Email][mhallam] |
[mkeating]: mailto:m.keating@shadowcat.co.uk
[mhallam]: mailto:info@lancasteresta.org

View file

@ -8,7 +8,7 @@ if (localPropertiesFile.exists()) {
def flutterRoot = localProperties.getProperty('flutter.sdk') def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) { if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") throw GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
} }
def flutterVersionCode = localProperties.getProperty('flutter.versionCode') def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
@ -58,4 +58,7 @@ dependencies {
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.google.firebase:firebase-messaging:20.3.0'
} }
apply plugin: 'com.google.gms.google-services'

View file

@ -14,6 +14,7 @@
FlutterApplication and put your custom class here. --> FlutterApplication and put your custom class here. -->
<application <application
android:label="SpendTracker" android:label="SpendTracker"
android:name=".Application"
android:icon="@mipmap/ic_launcher"> android:icon="@mipmap/ic_launcher">
<meta-data <meta-data

View file

@ -0,0 +1,21 @@
package uk.co.localspend.localspend;
import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService;
import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin;
public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override
public void onCreate() {
super.onCreate();
FlutterFirebaseMessagingService.setPluginRegistrant(this);
}
@Override
public void registerWith(PluginRegistry registry) {
FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin"));
}
}

View file

@ -5,7 +5,8 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:3.3.0' classpath 'com.android.tools.build:gradle:4.0.1'
classpath 'com.google.gms:google-services:4.3.4'
} }
} }

View file

@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

2
lib/env/dev.json vendored
View file

@ -1,5 +1,5 @@
{ {
"env": "DEV", "env": "DEV",
"production": false, "production": false,
"apiUrl": "https://dev.localspend.co.uk/api" "apiUrl": "https://localhost:/api"
} }

View file

@ -7,9 +7,12 @@ import 'package:local_spend/pages/spash_screen.dart';
import 'package:local_spend/pages/more_page.dart'; import 'package:local_spend/pages/more_page.dart';
import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:local_spend/common/apifunctions/get_graph_data.dart'; import 'package:local_spend/common/apifunctions/get_graph_data.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
void main() { void main() {
runApp(MyApp()); runApp(
MyApp()
);
} }
void loadGraphs() {} void loadGraphs() {}
@ -22,27 +25,43 @@ class GraphWithTitle {
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
// TODO: load graphs on app login and send to graph widgets // TODO: load graphs on app login and send to graph widgets
return new MaterialApp( _firebaseMessaging.configure(
onMessage: (Map<String, dynamic> message) async {
print('onMessage: $message');
},
onLaunch: (Map<String, dynamic> message) async {
print('onLaunch: $message');
},
onResume: (Map<String, dynamic> message) async {
print('onResume: $message');
},
);
// Required on iOS; non-op on Android.
_firebaseMessaging.requestNotificationPermissions();
return MaterialApp(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
localizationsDelegates: [ localizationsDelegates: [
GlobalMaterialLocalizations.delegate, GlobalMaterialLocalizations.delegate,
GlobalWidgetsLocalizations.delegate, GlobalWidgetsLocalizations.delegate,
], ],
supportedLocales: [Locale("en")], supportedLocales: [Locale('en')],
title: "Local Spend Tracker", title: 'Local Spend Tracker',
theme: new ThemeData( theme: ThemeData(
primarySwatch: Colors.blueGrey, primarySwatch: Colors.blueGrey,
), ),
routes: <String, WidgetBuilder>{ routes: <String, WidgetBuilder>{
"/HomePage": (BuildContext context) => HomePage(), '/HomePage': (BuildContext context) => HomePage(),
"/LoginPage": (BuildContext context) => LoginPage(), '/LoginPage': (BuildContext context) => LoginPage(),
'/MapPage': (BuildContext context) => MapPage(), '/MapPage': (BuildContext context) => MapPage(),
"/ReceiptPage": (BuildContext context) => ReceiptPage2(), '/ReceiptPage': (BuildContext context) => ReceiptPage2(),
"/MorePage": (BuildContext context) => MorePage(), '/MorePage': (BuildContext context) => MorePage(),
}, },
home: SplashScreen(), home: SplashScreen(),
); );

View file

@ -14,7 +14,7 @@ packages:
name: analyzer name: analyzer
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.39.15" version: "0.39.14"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -63,21 +63,21 @@ packages:
name: build_resolvers name: build_resolvers
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.10" version: "1.3.11"
build_runner: build_runner:
dependency: "direct dev" dependency: "direct dev"
description: description:
name: build_runner name: build_runner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.10.0" version: "1.10.1"
build_runner_core: build_runner_core:
dependency: transitive dependency: transitive
description: description:
name: build_runner_core name: build_runner_core
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.2.0" version: "6.0.1"
built_collection: built_collection:
dependency: transitive dependency: transitive
description: description:
@ -147,7 +147,7 @@ packages:
name: code_builder name: code_builder
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.4.0" version: "3.5.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
@ -204,6 +204,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.3"
file: file:
dependency: transitive dependency: transitive
description: description:
@ -211,6 +218,41 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.2.1" version: "5.2.1"
firebase:
dependency: transitive
description:
name: firebase
url: "https://pub.dartlang.org"
source: hosted
version: "7.3.0"
firebase_core:
dependency: transitive
description:
name: firebase_core
url: "https://pub.dartlang.org"
source: hosted
version: "0.5.0+1"
firebase_core_platform_interface:
dependency: transitive
description:
name: firebase_core_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
firebase_core_web:
dependency: transitive
description:
name: firebase_core_web
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
firebase_messaging:
dependency: "direct main"
description:
name: firebase_messaging
url: "https://pub.dartlang.org"
source: hosted
version: "7.0.3"
fixnum: fixnum:
dependency: transitive dependency: transitive
description: description:
@ -248,7 +290,7 @@ packages:
name: flutter_plugin_android_lifecycle name: flutter_plugin_android_lifecycle
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.8" version: "1.0.11"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -272,14 +314,14 @@ packages:
name: google_maps_flutter name: google_maps_flutter
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.28+1" version: "0.5.33"
google_maps_flutter_platform_interface: google_maps_flutter_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: google_maps_flutter_platform_interface name: google_maps_flutter_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.4"
graphs: graphs:
dependency: transitive dependency: transitive
description: description:
@ -293,7 +335,7 @@ packages:
name: html name: html
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.14.0+3" version: "0.14.0+4"
http: http:
dependency: "direct main" dependency: "direct main"
description: description:
@ -342,14 +384,14 @@ packages:
name: json_annotation name: json_annotation
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.1" version: "3.1.0"
json_serializable: json_serializable:
dependency: "direct main" dependency: "direct main"
description: description:
name: json_serializable name: json_serializable
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.3.0" version: "3.5.0"
linkify: linkify:
dependency: transitive dependency: transitive
description: description:
@ -384,7 +426,7 @@ packages:
name: mime name: mime
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.6+3" version: "0.9.7"
node_interop: node_interop:
dependency: transitive dependency: transitive
description: description:
@ -426,7 +468,14 @@ packages:
name: path_provider_platform_interface name: path_provider_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.3"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.4+1"
pedantic: pedantic:
dependency: "direct dev" dependency: "direct dev"
description: description:
@ -441,20 +490,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.1" version: "2.2.1"
platform_detect:
dependency: transitive
description:
name: platform_detect
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: plugin_platform_interface name: plugin_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.3"
pool: pool:
dependency: transitive dependency: transitive
description: description:
@ -496,21 +538,21 @@ packages:
name: sa_anicoto name: sa_anicoto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.3"
sa_multi_tween: sa_multi_tween:
dependency: transitive dependency: transitive
description: description:
name: sa_multi_tween name: sa_multi_tween
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.1" version: "1.1.2"
sa_stateless_animation: sa_stateless_animation:
dependency: transitive dependency: transitive
description: description:
name: sa_stateless_animation name: sa_stateless_animation
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.1" version: "1.0.3"
sa_v1_migration: sa_v1_migration:
dependency: transitive dependency: transitive
description: description:
@ -524,14 +566,14 @@ packages:
name: shared_preferences name: shared_preferences
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.8" version: "0.5.12"
shared_preferences_linux: shared_preferences_linux:
dependency: transitive dependency: transitive
description: description:
name: shared_preferences_linux name: shared_preferences_linux
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.2+1" version: "0.0.2+2"
shared_preferences_macos: shared_preferences_macos:
dependency: transitive dependency: transitive
description: description:
@ -553,13 +595,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.2+7" version: "0.1.2+7"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+1"
shelf: shelf:
dependency: transitive dependency: transitive
description: description:
name: shelf name: shelf
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.7.7" version: "0.7.9"
shelf_web_socket: shelf_web_socket:
dependency: transitive dependency: transitive
description: description:
@ -573,7 +622,7 @@ packages:
name: simple_animations name: simple_animations
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.2.1" version: "2.2.2"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -585,7 +634,7 @@ packages:
name: source_gen name: source_gen
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.6" version: "0.9.7+1"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
@ -627,7 +676,14 @@ packages:
name: supercharged name: supercharged
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.10.0"
supercharged_dart:
dependency: transitive
description:
name: supercharged_dart
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
@ -662,7 +718,7 @@ packages:
name: url_launcher name: url_launcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.5.0" version: "5.7.2"
url_launcher_linux: url_launcher_linux:
dependency: transitive dependency: transitive
description: description:
@ -676,21 +732,28 @@ packages:
name: url_launcher_macos name: url_launcher_macos
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.1+7" version: "0.0.1+8"
url_launcher_platform_interface: url_launcher_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_platform_interface name: url_launcher_platform_interface
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.7" version: "1.0.8"
url_launcher_web: url_launcher_web:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_web name: url_launcher_web
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.2" version: "0.1.4+1"
url_launcher_windows:
dependency: transitive
description:
name: url_launcher_windows
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1+1"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@ -712,6 +775,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.0"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.3"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:

View file

@ -28,6 +28,7 @@ dependencies:
simple_animations: ^2.2.1 simple_animations: ^2.2.1
google_maps_flutter: ^0.5.20+5 google_maps_flutter: ^0.5.20+5
json_serializable: ^3.3.0 json_serializable: ^3.3.0
firebase_messaging: ^7.0.0
# 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.
cupertino_icons: ^0.1.2 cupertino_icons: ^0.1.2