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 7 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
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 "../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 @@ -24,6 +24,7 @@ import { AppContext } from "../App";
import { shareQR } from "../components/QrCode";
import { storageClear } from "../plugin/storage";
import { getAppVersion } from "../plugin/clientStats";
import { fetchOPCode, getSettings } from "../controlHelper";

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

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

async function getConnectURL() {
ControlHelper.getSettings().then(function(response) {
getSettings().then(function(response) {
var newConnectSettings ={}
newConnectSettings.url = response.connectUrl;
console.log(response);
Expand All @@ -208,7 +208,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
128 changes: 128 additions & 0 deletions www/js/controlHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import { DateTime } from "luxon";

import { getRawEntries } from "./commHelper";
import { logInfo, displayError } from "./plugin/logger";
import i18next from "./i18nextInit" ;

interface fsWindow extends Window {
requestFileSystem: (
type: number,
size: number,
successCallback: (fs: any) => void,
errorCallback?: (error: any) => void
) => void;
LocalFileSystem: {
TEMPORARY: number;
PERSISTENT: number;
};
};

declare let window: fsWindow;
the-bay-kay marked this conversation as resolved.
Show resolved Hide resolved

export const getMyData = function(startTs: Date) {
// We are only retrieving data for a single day to avoid
// running out of memory on the phone
const startTime = DateTime.fromJSDate(startTs);
const endTime = startTime.endOf("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 writeDumpFile = function(result) {
const resultList = result.phone_data;
return new Promise<void>(function(resolve, reject) {
window.requestFileSystem(window.LocalFileSystem.TEMPORARY, 0, function(fs) {
console.log(`file system open: ${fs.name}`);
the-bay-kay marked this conversation as resolved.
Show resolved Hide resolved
fs.root.getFile(dumpFile, { create: true, exclusive: false }, function (fileEntry) {
console.log(`fileEntry ${fileEntry.nativeURL} is file? ${fileEntry.isFile.toString()}`)
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function() {
console.log("Successful file write...");
resolve();
}
fileWriter.onerror = function(e) {
console.log(`Failed file write: ${e.toString()}`);
reject();
}

// if data object is not passed in, create a new blog instead.
the-bay-kay marked this conversation as resolved.
Show resolved Hide resolved
const dataObj = new Blob([JSON.stringify(resultList, null, 2)],
{ type: "application/json" });
fileWriter.write(dataObj);
})

});
});
});
}

const emailData = function() {
the-bay-kay marked this conversation as resolved.
Show resolved Hide resolved
return new Promise<void>(function(resolve, reject) {
window.requestFileSystem(window.LocalFileSystem.TEMPORARY, 0, function(fs) {
console.log("During email, file system open: " + fs.name);
fs.root.getFile(dumpFile, null, function(fileEntry) {
console.log(`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;
console.log(`Successfull file read with ${readResult.length} characters`);
const dataArray = JSON.parse(readResult);
console.log(`Successfully read resultList of size ${dataArray.length}`);
var attachFile = fileEntry.nativeURL;
the-bay-kay marked this conversation as resolved.
Show resolved Hide resolved
if (window['device'].platform === "android")
attachFile = "app://cache/" + dumpFile;
if (window['device'].platform === "ios")
alert(i18next.t("email-service.email-account-mail-app"));
const email = {
'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(email, function (result) {
console.log(`Share Completed? ${result.completed}`); // On Android, most likely returns false
console.log(`Shared to app: ${result.app}`);
resolve();
}, function (msg) {
console.log(`Sharing failed with message ${msg}`);
});
}
reader.readAsText(file);
}, function(error) {
displayError(error, "Error while downloading JSON dump");
reject(error);
})
});
});
});
};

// Simulate old conversion to get correct UnixInteger for endMoment data
const getUnixNum = (dateData: DateTime) => {
const tempDate = dateData.toFormat("dd MMM yyyy");
return DateTime.fromFormat(tempDate, "dd MMM yyyy").toUnixInteger();
};

getRawEntries(null, getUnixNum(startTime), startTime.toUnixInteger())
the-bay-kay marked this conversation as resolved.
Show resolved Hide resolved
.then(writeDumpFile)
.then(emailData)
.then(function() {
logInfo("Email queued successfully");
})
.catch(function(error) {
displayError(error, "Error emailing JSON dump");
})
};

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

export const getSettings = (() => {
return window["cordova"].plugins.BEMConnectionSettings.getSettings();
});
123 changes: 4 additions & 119 deletions www/js/services.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import angular from 'angular';
import { getRawEntries } from './commHelper';

import { logInfo} from './plugin/logger'
angular.module('emission.services', ['emission.plugin.logger'])

.service('ReferHelper', function($http) {
Expand All @@ -22,7 +22,7 @@ angular.module('emission.services', ['emission.plugin.logger'])
//}*/
}
})
.service('UnifiedDataLoader', function($window, Logger) {
.service('UnifiedDataLoader', function($window) {
var combineWithDedup = function(list1, list2) {
var combinedList = list1.concat(list2);
return combinedList.filter(function(value, i, array) {
Expand Down Expand Up @@ -51,10 +51,10 @@ angular.module('emission.services', ['emission.plugin.logger'])
if (localError && remoteError) {
reject([localError, remoteError]);
} else {
Logger.log("About to dedup localResult = "+localResult.length
logInfo("About to dedup localResult = "+localResult.length
+"remoteResult = "+remoteResult.length);
var dedupedList = combiner(localResult, remoteResult);
Logger.log("Deduped list = "+dedupedList.length);
logInfo("Deduped list = "+dedupedList.length);
resolve(dedupedList);
}
}
Expand Down Expand Up @@ -102,121 +102,6 @@ angular.module('emission.services', ['emission.plugin.logger'])
return combinedPromise(localPromise, remotePromise, combineWithDedup);
}
})
.service('ControlHelper', function($window,
$ionicPopup,
Logger) {

this.writeFile = function(fileEntry, resultList) {
// Create a FileWriter object for our FileEntry (log.txt).
}

this.getMyData = function(startTs) {
var fmt = "YYYY-MM-DD";
// We are only retrieving data for a single day to avoid
// running out of memory on the phone
var startMoment = moment(startTs);
var endMoment = moment(startTs).endOf("day");
var dumpFile = startMoment.format(fmt) + "."
+ endMoment.format(fmt)
+ ".timeline";
alert("Going to retrieve data to "+dumpFile);

var writeDumpFile = function(result) {
return new Promise(function(resolve, reject) {
var resultList = result.phone_data;
window.requestFileSystem(window.LocalFileSystem.TEMPORARY, 0, function(fs) {
console.log('file system open: ' + fs.name);
fs.root.getFile(dumpFile, { create: true, exclusive: false }, function (fileEntry) {
console.log("fileEntry "+fileEntry.nativeURL+" is file?" + fileEntry.isFile.toString());
fileEntry.createWriter(function (fileWriter) {
fileWriter.onwriteend = function() {
console.log("Successful file write...");
resolve();
// readFile(fileEntry);
};

fileWriter.onerror = function (e) {
console.log("Failed file write: " + e.toString());
reject();
};

// If data object is not passed in,
// create a new Blob instead.
var dataObj = new Blob([JSON.stringify(resultList, null, 2)],
{ type: 'application/json' });
fileWriter.write(dataObj);
});
// this.writeFile(fileEntry, resultList);
});
});
});
}


var emailData = function(result) {
return new Promise(function(resolve, reject) {
window.requestFileSystem(window.LocalFileSystem.TEMPORARY, 0, function(fs) {
console.log("During email, file system open: "+fs.name);
fs.root.getFile(dumpFile, null, function(fileEntry) {
console.log("fileEntry "+fileEntry.nativeURL+" is file?"+fileEntry.isFile.toString());
fileEntry.file(function (file) {
var reader = new FileReader();

reader.onloadend = function() {
console.log("Successful file read with " + this.result.length +" characters");
var dataArray = JSON.parse(this.result);
console.log("Successfully read resultList of size "+dataArray.length);
// displayFileData(fileEntry.fullPath + ": " + this.result);
var attachFile = fileEntry.nativeURL;
if (ionic.Platform.isAndroid()) {
// At least on nexus, getting a temporary file puts it into
// the cache, so I can hardcode that for now
attachFile = "app://cache/"+dumpFile;
}
if (ionic.Platform.isIOS()) {
alert(i18next.t('email-service.email-account-mail-app'));
}
var email = {
attachments: [
attachFile
],
subject: i18next.t('email-service.email-data.subject-data-dump-from-to', {start: startMoment.format(fmt),end: endMoment.format(fmt)}),
body: i18next.t('email-service.email-data.body-data-consists-of-list-of-entries')
}
$window.cordova.plugins.email.open(email).then(resolve());
}
reader.readAsText(file);
}, function(error) {
$ionicPopup.alert({title: "Error while downloading JSON dump",
template: error});
reject(error);
});
});
});
});
};

getRawEntries(null, startMoment.unix(), endMoment.unix())
.then(writeDumpFile)
.then(emailData)
.then(function() {
Logger.log("Email queued successfully");
})
.catch(function(error) {
Logger.displayError("Error emailing JSON dump", error);
})
};

this.getOPCode = function() {
return window.cordova.plugins.OPCodeAuth.getOPCode();
};

this.getSettings = function() {
return window.cordova.plugins.BEMConnectionSettings.getSettings();
};

})

.factory('Chats', function() {
// Might use a resource here that returns a JSON array

Expand Down