Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🎛️ ControlHelper Rewrite #1052

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
4f84643
Fixed JSON Object Dump
the-bay-kay Oct 4, 2023
1130508
Replaced moment objects with DateTime
the-bay-kay Oct 4, 2023
2e9173b
Fixed issue with UnixInteger conversion
the-bay-kay Oct 5, 2023
8825d06
Updated Logger usage, cleaned up controlHelper
the-bay-kay Oct 5, 2023
46832c7
Rewrote controlHelper as a separate TS file
the-bay-kay Oct 9, 2023
4960803
Small code-quality updates to controlHelper.ts
the-bay-kay Oct 10, 2023
6fd2e73
Email now uses socialShare library
the-bay-kay Oct 12, 2023
3420577
Updated debug statements, format changes
the-bay-kay Oct 16, 2023
92cd6fb
Split getData into multiple functions
the-bay-kay Oct 16, 2023
1ec3a49
Merge branch 'react-testing-setup' of https://github.com/jiji14/e-mis…
the-bay-kay Oct 17, 2023
d31a7a1
Set Up tests for controlHelper
the-bay-kay Oct 17, 2023
b8404da
Set up types folder, added new tests
the-bay-kay Oct 18, 2023
c22a605
Updated type files, improved tests
the-bay-kay Oct 18, 2023
20f6d04
Minor adjustments to controlHelper tests
the-bay-kay Oct 19, 2023
f0da15e
Changed time conversion, fixed minor issues
the-bay-kay Oct 23, 2023
5e61cb9
Updated types to match UnifiedDataLoader, PR #1073
the-bay-kay Oct 27, 2023
905e52c
Moved rewrites into `www/js/services`
the-bay-kay Oct 27, 2023
d107e21
Merge branch 'service_rewrite_2023' of https://github.com/e-mission/e…
the-bay-kay Oct 30, 2023
4b7b9d2
Updated `controlHelper` imports
the-bay-kay Oct 30, 2023
4dd295c
Refactored `controlHelper.ts`, updated fileIO
the-bay-kay Oct 31, 2023
24a9d95
Updated jest testing, cordovaMocks
the-bay-kay Oct 31, 2023
c2ab799
Added rejection test
the-bay-kay Nov 1, 2023
fffcd00
Expanded mocks, added tests
the-bay-kay Nov 1, 2023
05deecf
Merge branch 'service_rewrite_2023' into controlHelper-rewrite
the-bay-kay Nov 2, 2023
6723ca3
Merge branch 'type_interfaces' into controlHelper-rewrite
the-bay-kay Nov 2, 2023
58a3411
Ran prettier on controlHelper
the-bay-kay Nov 2, 2023
428f191
Fixed merge conflict artifact
the-bay-kay Nov 2, 2023
4afd9ec
remove js/diary/diaryTypes.ts
JGreenlee Nov 4, 2023
8cb3691
expand diaryTypes
JGreenlee Nov 4, 2023
12e8029
Expanded diaryTypes
the-bay-kay Nov 7, 2023
bc9dfaf
Merge branch 'type_interfaces' into update_type_interfaces
the-bay-kay Nov 9, 2023
4d19a9d
Merge pull request #1 from JGreenlee/update_type_interfaces
the-bay-kay Nov 9, 2023
4a96b9d
Minor adjustments to diaryTypes
the-bay-kay Nov 9, 2023
9247efe
Merge branch 'type_interfaces' into controlHelper-rewrite
the-bay-kay Nov 10, 2023
05b287a
index.html fix
the-bay-kay Nov 10, 2023
bc90720
Merge branch 'service_rewrite_2023' into controlHelper-rewrite
the-bay-kay Nov 10, 2023
2177000
Merge branch 'service_rewrite_2023' into controlHelper-rewrite
the-bay-kay Nov 13, 2023
2c02e37
Ran prettier, removed broken tests
the-bay-kay Nov 17, 2023
dbe76d1
Switched to old fileIO, fixes issue with android
the-bay-kay Nov 17, 2023
a232e3f
Revert "Switched to old fileIO, fixes issue with android"
the-bay-kay Nov 27, 2023
369b3ad
Changed fileIO directory to fix android issue
the-bay-kay Nov 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions www/__mocks__/cordovaMocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export const mockFile = () => {
window['cordova'].file = {
dataDirectory: '../path/to/data/directory',
applicationStorageDirectory: '../path/to/app/storage/directory',
tempDirectory: '../path/to/temp/directory',
};
};

Expand Down
7 changes: 7 additions & 0 deletions www/__mocks__/fileSystemMocks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
export const mockFileSystem = () => {
type MockFileWriter = {
onreadend: any;
onerror: (e: any) => void;
write: (obj: Blob) => void;
};
window['resolveLocalFileSystemURL'] = function (parentDir, handleFS) {
const fs = {
filesystem: {
Expand All @@ -9,6 +14,8 @@ export const mockFileSystem = () => {
let file = new File(['this is a mock'], 'loggerDB');
handleFile(file);
},
nativeURL: 'file:///Users/Jest/test/URL/',
isFile: true,
};
onSuccess(fileEntry);
},
Expand Down
2 changes: 1 addition & 1 deletion www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@
<div id="appRoot" class="fill-container" style="width: 100vw; height: 100vh;"></div>
</body>
<script src="dist/bundle.js"></script>
</html>
</html>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extraneous whitespace

6 changes: 2 additions & 4 deletions www/js/control/DataDatePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@
import React from 'react';
import { DatePickerModal } from 'react-native-paper-dates';
import { useTranslation } from 'react-i18next';
import { getAngularService } from '../angular-react-helper';
import { getMyData } from '../services/controlHelper';

const DataDatePicker = ({ date, setDate, open, setOpen, minDate }) => {
const { t, i18n } = useTranslation(); //able to pull lang from this
const ControlHelper = getAngularService('ControlHelper');

const onDismiss = React.useCallback(() => {
setOpen(false);
}, [setOpen]);
Expand All @@ -18,7 +16,7 @@ const DataDatePicker = ({ date, setDate, open, setOpen, minDate }) => {
(params) => {
setOpen(false);
setDate(params.date);
ControlHelper.getMyData(params.date);
getMyData(params.date);
},
[setOpen, setDate],
);
Expand Down
6 changes: 3 additions & 3 deletions www/js/control/ProfileSettings.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { storageClear } from '../plugin/storage';
import { getAppVersion } from '../plugin/clientStats';
import { getConsentDocument } from '../splash/startprefs';
import { logDebug } from '../plugin/logger';
import { fetchOPCode, getSettings } from '../services/controlHelper';

//any pure functions can go outside
const ProfileSettings = () => {
Expand All @@ -46,7 +47,6 @@ const ProfileSettings = () => {
const CarbonDatasetHelper = getAngularService('CarbonDatasetHelper');
const EmailHelper = getAngularService('EmailHelper');
const NotificationScheduler = getAngularService('NotificationScheduler');
const ControlHelper = getAngularService('ControlHelper');

//functions that come directly from an Angular service
const editCollectionConfig = () => setEditCollectionVis(true);
Expand Down Expand Up @@ -221,7 +221,7 @@ const ProfileSettings = () => {
}, [editSync]);

async function getConnectURL() {
ControlHelper.getSettings().then(
getSettings().then(
function (response) {
var newConnectSettings = {};
newConnectSettings.url = response.connectUrl;
Expand All @@ -236,7 +236,7 @@ const ProfileSettings = () => {

async function getOPCode() {
const newAuthSettings = {};
const opcode = await ControlHelper.getOPCode();
const opcode = await fetchOPCode();
if (opcode == null) {
newAuthSettings.opcode = 'Not logged in';
} else {
Expand Down
159 changes: 159 additions & 0 deletions www/js/services/controlHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { DateTime } from 'luxon';

import { getRawEntries } from './commHelper';
import { logInfo, displayError, logDebug, logWarn } from '../plugin/logger';
import { FsWindow } from '../types/fileShareTypes';
import { ServerResponse } from '../types/serverData';
import i18next from '../i18nextInit';

declare let window: FsWindow;

export const getMyDataHelpers = function (
fileName: string,
startTimeString: string,
endTimeString: string,
) {
const localWriteFile = function (result: ServerResponse<any>) {
const resultList = result.phone_data;
return new Promise<void>(function (resolve, reject) {
Comment on lines +16 to +18
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be combined with the similar function that saves loggerDB and userCacheDB?
Maybe create a new fileWriterService?

window['resolveLocalFileSystemURL'](window['cordova'].file.cacheDirectory, function (fs) {
fs.filesystem.root.getFile(
fileName,
{ create: true, exclusive: false },
function (fileEntry) {
logDebug(`fileEntry ${fileEntry.nativeURL} is file? ${fileEntry.isFile.toString()}`);
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function () {
logDebug('Successful file write...');
resolve();
};
fileWriter.onerror = function (e) {
logDebug(`Failed file write: ${e.toString()}`);
reject();
};
logDebug(`fileWriter is: ${JSON.stringify(fileWriter.onwriteend, null, 2)}`);
// if data object is not passed in, create a new blob instead.
const dataObj = new Blob([JSON.stringify(resultList, null, 2)], {
type: 'application/json',
});
fileWriter.write(dataObj);
});
},
);
});
});
};

const localShareData = function () {
return new Promise<void>(function (resolve, reject) {
window['resolveLocalFileSystemURL'](window['cordova'].file.cacheDirectory, function (fs) {
fs.filesystem.root.getFile(fileName, null, function (fileEntry) {
logDebug(`fileEntry ${fileEntry.nativeURL} is file? ${fileEntry.isFile.toString()}`);
fileEntry.file(
function (file) {
const reader = new FileReader();

reader.onloadend = function () {
const readResult = this.result as string;
logDebug(`Successfull file read with ${readResult.length} characters`);
const dataArray = JSON.parse(readResult);
logDebug(`Successfully read resultList of size ${dataArray.length}`);
let attachFile = fileEntry.nativeURL;
const shareObj = {
files: [attachFile],
message: i18next.t(
'email-service.email-data.body-data-consists-of-list-of-entries',
),
subject: i18next.t('email-service.email-data.subject-data-dump-from-to', {
start: startTimeString,
end: endTimeString,
}),
};
window['plugins'].socialsharing.shareWithOptions(
shareObj,
function (result) {
logDebug(`Share Completed? ${result.completed}`); // On Android, most likely returns false
logDebug(`Shared to app: ${result.app}`);
resolve();
},
function (msg) {
logDebug(`Sharing failed with message ${msg}`);
},
);
};
reader.readAsText(file);
},
function (error) {
displayError(error, 'Error while downloading JSON dump');
reject(error);
},
);
});
});
});
};

// window['cordova'].file.cacheDirectory is not guaranteed to free up memory,
// so it's good practice to remove the file right after it's used!
const localClearData = function () {
return new Promise<void>(function (resolve, reject) {
Comment on lines +96 to +99
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woo! Good addition to the existing functionality!

window['resolveLocalFileSystemURL'](window['cordova'].file.cacheDirectory, function (fs) {
fs.filesystem.root.getFile(fileName, null, function (fileEntry) {
fileEntry.remove(
() => {
logDebug(`Successfully cleaned up file ${fileName}`);
resolve();
},
(err) => {
logWarn(`Error deleting ${fileName} : ${err}`);
reject(err);
},
);
});
});
});
};

return {
writeFile: localWriteFile,
shareData: localShareData,
clearData: localClearData,
};
};

/**
* getMyData fetches timeline data for a given day, and then gives the user a prompt to share the data
* @param timeStamp initial timestamp of the timeline to be fetched.
*/
export const getMyData = function (timeStamp: Date) {
// We are only retrieving data for a single day to avoid
// running out of memory on the phone
const endTime = DateTime.fromJSDate(timeStamp);
const startTime = endTime.startOf('day');
const startTimeString = startTime.toFormat("yyyy'-'MM'-'dd");
const endTimeString = endTime.toFormat("yyyy'-'MM'-'dd");

const dumpFile = startTimeString + '.' + endTimeString + '.timeline';
alert(`Going to retrieve data to ${dumpFile}`);

const getDataMethods = getMyDataHelpers(dumpFile, startTimeString, endTimeString);

getRawEntries(null, startTime.toUnixInteger(), endTime.toUnixInteger())
.then(getDataMethods.writeFile)
.then(getDataMethods.shareData)
.then(getDataMethods.clearData)
.then(function () {
logInfo('Share queued successfully');
})
.catch(function (error) {
displayError(error, 'Error sharing JSON dump');
});
};

export const fetchOPCode = () => {
return window['cordova'].plugins.OPCodeAuth.getOPCode();
};

export const getSettings = () => {
return window['cordova'].plugins.BEMConnectionSettings.getSettings();
};
4 changes: 2 additions & 2 deletions www/js/types/diaryTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export type CompositeTrip = {
confirmed_trip: ObjectId;
distance: number;
duration: number;
end_confirmed_place: ConfirmedPlace;
end_confirmed_place: ServerData<ConfirmedPlace>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dumb typescript question for my edification: what does this change in aid of?

end_fmt_time: string;
end_loc: { type: string; coordinates: number[] };
end_local_dt: LocalDt;
Expand All @@ -56,7 +56,7 @@ export type CompositeTrip = {
raw_trip: ObjectId;
sections: any[]; // TODO
source: string;
start_confirmed_place: ConfirmedPlace;
start_confirmed_place: ServerData<ConfirmedPlace>;
start_fmt_time: string;
start_loc: { type: string; coordinates: number[] };
start_local_dt: LocalDt;
Expand Down
Loading