Skip to content

Commit

Permalink
Merge pull request #1052 from the-bay-kay/controlHelper-rewrite
Browse files Browse the repository at this point in the history
🎛️ ControlHelper Rewrite
  • Loading branch information
shankari authored Dec 6, 2023
2 parents c1f6dc3 + 369b3ad commit db19a5b
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 10 deletions.
1 change: 1 addition & 0 deletions www/__mocks__/cordovaMocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,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>
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 @@ -44,7 +45,6 @@ const ProfileSettings = () => {

//angular services needed
const NotificationScheduler = getAngularService('NotificationScheduler');
const ControlHelper = getAngularService('ControlHelper');

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

async function getConnectURL() {
ControlHelper.getSettings().then(
getSettings().then(
function (response) {
var newConnectSettings = {};
newConnectSettings.url = response.connectUrl;
Expand All @@ -230,7 +230,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) {
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) {
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 @@ -42,7 +42,7 @@ export type CompositeTrip = {
confirmed_trip: ObjectId;
distance: number;
duration: number;
end_confirmed_place: ConfirmedPlace;
end_confirmed_place: ServerData<ConfirmedPlace>;
end_fmt_time: string;
end_loc: { type: string; coordinates: number[] };
end_local_dt: LocalDt;
Expand All @@ -59,7 +59,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

0 comments on commit db19a5b

Please sign in to comment.