diff --git a/Ejectable/App.tsx b/Ejectable/App.tsx
index d06e8d88..da127ffe 100644
--- a/Ejectable/App.tsx
+++ b/Ejectable/App.tsx
@@ -9,11 +9,9 @@ import useCachedResources from './hooks/useCachedResources';
import useColorScheme from './hooks/useColorScheme';
import Navigation from './navigation';
import { Trips } from './GT2';
-import * as fs from 'fs';
-
-export var debug:boolean = false;
- var expoGeoState:any;
+ var debug:boolean = false;
+ var expoGeoState:any = null;
export default function App() {
const isLoadingComplete = useCachedResources();
@@ -29,12 +27,11 @@ export default function App() {
if (status !== 'granted') {
setErrorMsg('Permission to access location was denied');
return;
- }
+ } else Trips.setLocEnabled(true);
let location = await Location.getCurrentPositionAsync({});
setLocation(location);
- if (!errorMsg && location)
- Trips.deltaLoc(JSON.stringify(location));
+ Trips.deltaLoc(location);
})();
}, []);
diff --git a/Ejectable/Coordinate.tsx b/Ejectable/Coordinate.tsx
index 8becb22b..563be6a7 100644
--- a/Ejectable/Coordinate.tsx
+++ b/Ejectable/Coordinate.tsx
@@ -3,13 +3,13 @@
public mLatitude:number = 0.0;
public mLongitude:number = 0.0;
- mResults:any = [0, 0];
- PI_OVER_180:number = 0.017453292519943295769236907684886;
- EARTH_RADIUS:number = 6371009;
+ mResults:any = [0, 0];
+ PI_OVER_180:number = 0.017453292519943295769236907684886;
+ EARTH_RADIUS:number = 6371009;
constructor (longitude:number, latitude:number) {
this.mLongitude = longitude;
- this.mLatitude = latitude;
+ this.mLatitude = latitude;
}
getLongitude() { return this.mLongitude; }
setLongitude(longitude:number) { this.mLongitude = longitude; }
diff --git a/Ejectable/GT2.tsx b/Ejectable/GT2.tsx
index 53d7dfbc..85e9d2f9 100644
--- a/Ejectable/GT2.tsx
+++ b/Ejectable/GT2.tsx
@@ -1,8 +1,19 @@
-import * as React from 'react';
+import React, { useState, useEffect } from 'react';
+import * as Location from 'expo-location';
import { Coordinate } from "./Coordinate";
import { Text, View } from './components/Themed';
-import { Alert, StyleSheet } from 'react-native';
-import { useState, useEffect } from 'react';
+import { Button, StyleSheet } from 'react-native';
+
+ var debug:boolean = false;
+export var endPending:boolean = false;
+ var expoGeoState:any = null;
+export var locEnabled:boolean = false;
+
+ const heartbeat:number = 500;
+ const displayBeat:number = 3;
+
+export function getEndPending() { return(endPending) }
+export function toggleEndPending() { endPending = !endPending;}
const styles = StyleSheet.create({
tripText: {
@@ -14,68 +25,154 @@ const styles = StyleSheet.create({
fontWeight: 'bold',
}});
-var lastLoc:any = null;
-const heartbeat:number = 500;
-const displayBeat:number = 3;
-class Chronometer {
+function Monitor() {
- public display:string = "00.00.00";
- clock:number = 0;
- intervalID:any = null;
+ const [location, setLocation] = useState(Object);
+ const [errorMsg, setErrorMsg] = useState("");
+
+ useEffect(() => {
+ (async () => {
+ let { status } = await Location.requestBackgroundPermissionsAsync();
+ if (status !== 'granted') {
+ setErrorMsg('Permission to monitor location was denied');
+ return;
+ } else Trips.setLocEnabled(true);
+
+ let location = await Location.getCurrentPositionAsync({});
+ setLocation(location);
+ Trips.deltaLoc(location);
+ })();
+ }, []);
+
+ expoGeoState = 'Waiting..';
+ if (errorMsg) {
+ expoGeoState = errorMsg;
+ } else if (location) {
+ expoGeoState = JSON.stringify(location);
+ }
+
+
+ }
+
+
+class Trip {
+
+ public elapsed:string = "00.00.00";
+ ticks:number = 0;
+ interval:any;
+ segments:number = 1;
+ distance:number = 0;
+ ds:number = 0;
+ CO2:number = 0.0;
+ loc:Coordinate = new Coordinate(0.0,0.0);
+ startPoint:Coordinate = new Coordinate(0.0,0.0)
+
tick() {let hours:number = 0, minutes:number = 0, seconds:number = 0;
- this.clock++;
- hours = this.clock < 3600 ? 0 : (this.clock / 3600);
- minutes = this.clock < 60 ? 0 : (this.clock - (hours * 3600)) / 60;
- seconds = this.clock % 60;
- this.display = hours + ":" + minutes + ":" + seconds;
+ this.ticks++;
+ hours = this.ticks < 3600 ? 0 : (this.ticks / 3600);
+ minutes = this.ticks < 60 ? 0 : (this.ticks - (hours * 3600)) / 60;
+ seconds = this.ticks % 60;
+ this.elapsed = hours.toFixed(0) + ":" + minutes.toFixed(0) + ":" + seconds.toFixed(0);
}
- public start() { this.clock = 0;
- this.intervalID = setInterval(this.tick, heartbeat);
- }
- public resume() { this.intervalID = setInterval(this.tick, heartbeat); }
- public stop() { clearInterval(this.intervalID); }
+ public start() { this.interval = setInterval(() => this.tick(), heartbeat); }
+ public resume() { this.startPoint = new Coordinate(0.0,0.0)
+ this.loc = new Coordinate(0.0, 0.0);
+ this.segments++;
+ this.interval = setInterval(() => this.tick(), heartbeat); }
+ public stop() { this.ds = this.loc.distanceTo(this.startPoint);
+ this.distance += this.ds;
+ clearInterval(this.interval);
+
+ }
}
-
+interface expoGeoObj {
+ coords: [
+ altitude:number,
+ altitudeAccuracy:number,
+ latitude:number,
+ accuracy:number,
+ longitude:number,
+ heading:number,
+ speed:number,
+ timestamp:number
+ ]
+}
+
export class GT2 {
- loc:Coordinate = new Coordinate(0,0);
- clock:Chronometer = new Chronometer();
- startPoint:Coordinate = new Coordinate(0,0);
+ trip:Trip = new Trip();
+ endPoint:Coordinate = new Coordinate(0.0,0.0);
+ startPoint:Coordinate = new Coordinate(0.0,0.0);
displayInterval:number = displayBeat * heartbeat;
public distance:number = 0.0;
- co2Rate:number = 0.0;
- currTime:number = 0;
- lastTime:number = 0;
+ co2Rate:number = 250.0;
z:number = 0.0;
- public v:number = 0.0;
+ public v:number = 0.0;
public inProgress:boolean = false;
public paused:boolean = false;
public elapsed:number = 0.0;
- segments:number = 0;
elevation:number = 0.0;
+ public units:string = "km";
+ public CO2Effect:string = "carbon burden";
+
nTrips:number = 0;
- parseGeoExpo(key:string, value:any) {}
+ n:number = 0.0;
+ m:number = 0.0;
+
public deltaLoc(lastFix:any) {
+ lastFix = JSON.stringify(lastFix);
+ let expoFix:expoGeoObj = JSON.parse(lastFix);
+ this.trip.loc.setLongitude(expoFix.coords['longitude']);
+ this.trip.loc.setLatitude(expoFix.coords['latitude']);
+
+ if (this.trip.startPoint.mLatitude == 0.0) {
+ this.trip.startPoint.mLatitude = this.trip.loc.mLatitude;
+ this.trip.startPoint.mLongitude = this.trip.loc.mLongitude;
+ }
+
+ this.trip.ds = this.trip.loc.distanceTo(this.trip.startPoint);
+
+ }
+
+ public end() {
+
+ this.trip.stop();
+ this.inProgress = false;
+ this.nTrips++;
+ toggleEndPending();
+
+ }
+
+ public setLocEnabled(value:boolean) { locEnabled = value}
+
+ public pause() {
+
+ if (!this.paused) {
+ this.trip.stop();
+ this.paused = true;
+ } else {
+ this.trip.resume();
+ this.paused = false;
+ }
+
}
public reset() {
- this.startPoint = new Coordinate(0,0);
this.distance = 0.0;
- this.co2Rate = 0.0;
- this.currTime = 0;
- this.lastTime = 0;
- this.loc = new Coordinate(0,0);
+ this.co2Rate = 0.0;
+ this.endPoint = new Coordinate(0,0);
+ this.startPoint = new Coordinate(0,0);
this.v = 0;
this.inProgress = false;
this.paused = false;
@@ -83,42 +180,40 @@ export class GT2 {
}
- public end() {
-
- this.clock.stop();
- this.inProgress = false;
- this.nTrips++;
-
- }
-
- public pause() {
-
- if (!this.paused) {
- this.clock.stop();
- this.paused = true;
- } else {
- this.clock.start();
- this.paused = false;
- }
-
- }
-
public start() {
this.reset();
- this.clock.start();
+ this.trip = new Trip();
+ this.trip.start();
this.inProgress = true;
+
}
-
+
+ lt:number = 0.0;
+
+ public getTripSummary() : string {
+
+ return (
+ 'Elapsed - ' + this.trip.elapsed + '\n' +
+ 'Origin: ' + 'lat: ' + this.trip.loc.mLatitude.toFixed(8) +
+ ' long: ' + this.trip.loc.mLongitude.toFixed(8) + '\n' +
+ 'Destination: ' + 'lat: ' + this.trip.loc.mLatitude.toFixed(8) +
+ ' long: ' + this.trip.loc.mLongitude.toFixed(8) + '\n' +
+ 'CO2: ' + this.trip.CO2 + ' grams ' + this.CO2Effect );
+
+ }
+
public getTripPanel() : string {
- if (this.inProgress)
- return (
- 'Elapsed - ' + this.clock.display + '\n' +
- 'Geo: ' + 'lat: ' + this.loc.mLatitude + ' long: ' + this.loc.mLatitude + '\n' +
- 'Vector: ' + 'distance: ' + this.distance + ' velocity: ' + this.v + '\n' +
+ if (this.inProgress) {
+ return (
+ 'Elapsed - ' + this.trip.elapsed + '\n' +
+ 'Geo: ' + 'lat: ' + this.trip.loc.mLatitude.toFixed(8) +
+ ' long: ' + this.trip.loc.mLongitude.toFixed(8) + '\n' +
+ 'Vector: ' + 'distance: ' + this.trip.ds + ' velocity: ' + this.v + '\n' +
'Altitude: ' + this.elevation + '\n');
- else return("No trip in progress. " + this.nTrips + " trip(s) completed");
+ }
+ else return("No trip in progress. " + this.nTrips + " trip(s) completed.");
}
@@ -149,14 +244,44 @@ export class TripDisplay extends React.Component {
render() {
- return(
-
+ if (!debug)
+ return(
+
{Trips.getTripPanel() }
- );
+ );
+ else;
+ return(
+
+
+ {Trips.getTripPanel() }
+
+ {expoGeoState}
+ );
+
}
}
-
+
+export class TripSummary extends React.Component {
+
+ constructor(props:any) {
+ super(props);
+ this.state = { slug: null };
+ }
+
+ render() {
+
+ return(
+
+
+ {Trips.getTripSummary() }
+
+ );
+
+ }
+
+}
+
export var Trips:GT2 = new GT2();
diff --git a/Ejectable/navigation/index.tsx b/Ejectable/navigation/index.tsx
index b591fdfa..7364d4d3 100644
--- a/Ejectable/navigation/index.tsx
+++ b/Ejectable/navigation/index.tsx
@@ -42,6 +42,7 @@ function RootNavigator() {
+
);
@@ -51,7 +52,7 @@ function RootNavigator() {
* A bottom tab navigator displays tab buttons on the bottom of the display to switch screens.
* https://reactnavigation.org/docs/bottom-tab-navigator
*/
-const BottomTab = createBottomTabNavigator();
+export const BottomTab = createBottomTabNavigator();
function BottomTabNavigator() {
const colorScheme = useColorScheme();
diff --git a/Ejectable/screens/HomeScreen.tsx b/Ejectable/screens/HomeScreen.tsx
index 90c5662f..90a74e2c 100644
--- a/Ejectable/screens/HomeScreen.tsx
+++ b/Ejectable/screens/HomeScreen.tsx
@@ -5,7 +5,10 @@ import { ScreenInfo3 } from '../components/ScreenInfo';
const image = { uri: "https://meansofproduction.biz/images/GREENT.jpg" };
-export default function HomeScreen() {
+export var nav:any = null;
+
+export default function HomeScreen(navigation:any) {
+ nav = navigation;
return (
diff --git a/Ejectable/screens/SettingsScreen.tsx b/Ejectable/screens/SettingsScreen.tsx
index 2b8d4854..3c427e56 100644
--- a/Ejectable/screens/SettingsScreen.tsx
+++ b/Ejectable/screens/SettingsScreen.tsx
@@ -4,6 +4,7 @@ import { Text, View } from '../components/Themed';
import { useState } from 'react';
import ScreenInfo from '../components/ScreenInfo';
import { SafeAreaView } from 'react-native-safe-area-context';
+import { Trips } from '../GT2';
export default function SettingsScreen() {
const [number, onChangeNumber] = React.useState("");
@@ -26,15 +27,27 @@ export default function SettingsScreen() {
diff --git a/Ejectable/screens/TripScreen.tsx b/Ejectable/screens/TripScreen.tsx
index b4dce39f..9c0baa8b 100644
--- a/Ejectable/screens/TripScreen.tsx
+++ b/Ejectable/screens/TripScreen.tsx
@@ -3,7 +3,8 @@ import { useState } from 'react';
import { Alert, Button, StyleSheet } from 'react-native';
import { Text, View } from '../components/Themed';
import { ScreenInfo2 } from '../components/ScreenInfo';
-import { TripDisplay, Trips } from '../GT2';
+import EndScreenInfo from '../components/EndScreenInfo';
+import { locEnabled, getEndPending, toggleEndPending, TripDisplay, Trips } from '../GT2';
const styles = StyleSheet.create({
container: {
@@ -30,8 +31,12 @@ const styles = StyleSheet.create({
function startTrip() {
+ if (!locEnabled ) {
+ Alert.alert("You must enable both foreground\n and background location tracking.");
+ return;
+ }
+
Trips.start();
- Alert.alert('Trip Started');
}
@@ -48,18 +53,14 @@ function pauseTrip() {
}
-function endTrip() {
+function endTrip() { Trips.end(); }
- Trips.end();
- Alert.alert('Trip Ended');
-
-}
-
-export default function TripScreen() {
+export default function TripScreen( navigation:any ) {
const [sButtonText, setSButtonText] = useState("Start");
- const [pButtonText, setPButtonText] = useState("Pause");
+ const [pButtonText, setPButtonText] = useState("Pause");
+ if (!getEndPending())
return (
Trip Control
@@ -69,8 +70,8 @@ export default function TripScreen() {
{
- if (!Trips.inProgress) {setSButtonText("End");startTrip();}
- else {setSButtonText('Start');setPButtonText('Pause');endTrip();}}
+ if (!Trips.inProgress) {setSButtonText("End");startTrip();setPButtonText('Pause');}
+ else {setSButtonText('Start');endTrip();}}
}
/>
- );
+ );
+ else
+ return (
+
+ Trip Control
+
+
+ { toggleEndPending(); if (getEndPending()) Alert.alert("t"); else Alert.alert("f"); }}
+ />
+
+ );
+
}
diff --git a/Ejectable/tsconfig.json b/Ejectable/tsconfig.json
index 88044a25..2058e5e5 100644
--- a/Ejectable/tsconfig.json
+++ b/Ejectable/tsconfig.json
@@ -1,6 +1,6 @@
-{
+{
"extends": "expo/tsconfig.base",
- "compilerOptions": {
+ "compilerOptions": {
"strict": true
- }
+ }
}
diff --git a/README.md b/README.md
index d66437c3..a141c946 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
## 2.0.0
- An Expo version of exactly the same functionality as the original 2011 app slightly enhanced
- except it's a completed and x-platform app.
+ except it's a completed and x-platform app and the overall trip fuel consumption has been corrected.
This first replacement on play and first version on app store using an expo build will be maintained
but the binaries will be available [here](https://sameboat.live/sb-app) after 2.1 replaces it on the app stores.