Skip to content

Commit

Permalink
Merge pull request e-mission#1035 from e-mission/label_dashboard_prof…
Browse files Browse the repository at this point in the history
…ile_sept_2023

Merge 1.4.8 to master
  • Loading branch information
shankari authored Sep 23, 2023
2 parents fce117f + c341e35 commit 80b4794
Show file tree
Hide file tree
Showing 67 changed files with 2,213 additions and 1,263 deletions.
2 changes: 2 additions & 0 deletions package.cordovabuild.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"url": "git+https://github.com/e-mission/e-mission-phone.git"
},
"scripts": {
"setup-native": "./bin/download_settings_controls.js",
"build": "npx webpack --config webpack.prod.js && npx cordova build",
"build-dev": "npx webpack --config webpack.dev.js && npx cordova build",
"build-dev-android": "npx webpack --config webpack.dev.js && npx cordova build android",
Expand All @@ -26,6 +27,7 @@
"@babel/preset-typescript": "^7.21.4",
"@ionic/cli": "6.20.8",
"@types/luxon": "^3.3.0",
"@types/react": "^18.2.20",
"babel-loader": "^9.1.2",
"babel-plugin-angularjs-annotate": "^0.10.0",
"babel-plugin-optional-require": "^0.3.1",
Expand Down
3 changes: 3 additions & 0 deletions package.serve.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"scripts": {
"setup-serve": "./bin/download_settings_controls.js && ./bin/setup_autodeploy.js",
"serve": "webpack --config webpack.dev.js && concurrently -k \"phonegap --verbose serve\" \"webpack --config webpack.dev.js --watch\"",
"serve-prod": "webpack --config webpack.prod.js && concurrently -k \"phonegap --verbose serve\" \"webpack --config webpack.prod.js --watch\"",
"serve-only": "phonegap --verbose serve",
"test": "npx jest"
},
Expand All @@ -23,7 +24,9 @@
"@babel/preset-typescript": "^7.21.4",
"@ionic/cli": "6.20.8",
"@types/luxon": "^3.3.0",
"@types/react": "^18.2.20",
"babel-loader": "^9.1.2",
"babel-plugin-angularjs-annotate": "^0.10.0",
"babel-plugin-optional-require": "^0.3.1",
"concurrently": "^8.0.1",
"cordova": "^11.1.0",
Expand Down
2 changes: 2 additions & 0 deletions setup/setup_shared_native.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ cp setup/google-services.fake.for_ci.json google-services.json
echo "Setting up all npm packages"
npm install

npm run setup-native

# By default, node doesn't fail if any of the steps fail. This makes it hard to
# use in a CI environment, and leads to people reporting the node error rather
# than the underlying error. One solution is to pass in a command line argument to node
Expand Down
30 changes: 14 additions & 16 deletions www/__tests__/diaryHelper.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { getFormattedSectionProperties, getFormattedDate, motionTypeOf, isMultiDay, getFormattedDateAbbr, getFormattedTimeRange, getPercentages } from "../js/diary/diaryHelper";
import { useImperialConfig } from "../js/config/useImperialConfig";
import { getFormattedDate, isMultiDay, getFormattedDateAbbr, getFormattedTimeRange, getDetectedModes, getBaseModeByKey, modeColors } from "../js/diary/diaryHelper";

it('returns a formatted date', () => {
expect(getFormattedDate("2023-09-18T00:00:00-07:00")).toBe("Mon September 18, 2023");
Expand All @@ -19,10 +18,10 @@ it('returns a human readable time range', () => {
expect(getFormattedTimeRange("", "2023-09-18T00:00:00-09:30")).toBeFalsy();
});

it("returns a MotionType object", () => {
expect(motionTypeOf("WALKING")).toEqual({ name: "WALKING", icon: "walk", color: '#0068a5' });
expect(motionTypeOf("MotionTypes.WALKING")).toEqual({ name: "WALKING", icon: "walk", color: '#0068a5' });
expect(motionTypeOf("I made this type up")).toEqual({ name: "UNKNOWN", icon: "help", color: '#484848'});
it("returns a Base Mode for a given key", () => {
expect(getBaseModeByKey("WALKING")).toEqual({ name: "WALKING", icon: "walk", color: modeColors.blue });
expect(getBaseModeByKey("MotionTypes.WALKING")).toEqual({ name: "WALKING", icon: "walk", color: modeColors.blue });
expect(getBaseModeByKey("I made this type up")).toEqual({ name: "UNKNOWN", icon: "help", color: modeColors.grey });
});

it('returns true/false is multi day', () => {
Expand All @@ -41,25 +40,24 @@ let myFakeTrip2 = {sections: [
{ "sensed_mode_str": "BICYCLING", "distance": 715.3078629361006 }
]};

let myFakePcts = [
let myFakeDetectedModes = [
{ mode: "BICYCLING",
icon: "bike",
color: '#007e46',
color: modeColors.green,
pct: 89 },
{ mode: "WALKING",
icon: "walk",
color: '#0068a5',
color: modeColors.blue,
pct: 11 }];

let myFakePcts2 = [
let myFakeDetectedModes2 = [
{ mode: "BICYCLING",
icon: "bike",
color: '#007e46',
color: modeColors.green,
pct: 100 }];

it('returns the percetnages by mode for a trip', () => {
expect(getPercentages(myFakeTrip)).toEqual(myFakePcts);
expect(getPercentages(myFakeTrip2)).toEqual(myFakePcts2);
expect(getPercentages({})).toEqual({});
it('returns the detected modes, with percentages, for a trip', () => {
expect(getDetectedModes(myFakeTrip)).toEqual(myFakeDetectedModes);
expect(getDetectedModes(myFakeTrip2)).toEqual(myFakeDetectedModes2);
expect(getDetectedModes({})).toEqual([]); // empty trip, no sections, no modes
})

6 changes: 1 addition & 5 deletions www/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,12 @@
position: relative;
}

.fill-container div[class*='css-'] {
.fill-container > div[class*='css-'] {
height: 100%;
width: 100%;
position: absolute;
}

.fill-container div[class*='css-'] > div[class*='css-'] {
position: static;
}

/* Without this, the LabelTab does not fill the entire height of the screen.
It has something to do with React Navigation's NavigationContainer.
This should not be necessary once the entire app's routing has been
Expand Down
79 changes: 73 additions & 6 deletions www/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@
"app-version": "App Version",
"reminders-time-of-day": "Time of Day for Reminders ({{time}})",
"upcoming-notifications": "Upcoming Notifications",
"dummy-notification" : "Dummy Notification in 5 Seconds"
"dummy-notification" : "Dummy Notification in 5 Seconds",
"log-out": "Log Out"
},

"general-settings":{
Expand All @@ -65,9 +66,6 @@
"consent-found": "Consent found!",
"consented-to": "Consented to protocol {{protocol_id}}, {{approval_date}}",
"consented-ok": "OK",
"share-message": "Join me in making transportation greener and healthier \nDownload the emission app:",
"share-subject": "Emission - UC Berkeley Research Project",
"share-url": "https://bic2cal.eecs.berkeley.edu/#download",
"qrcode": "My OPcode",
"qrcode-share-title": "You can save your OPcode to login easily in the future!"
},
Expand Down Expand Up @@ -130,6 +128,10 @@
"select-mode-scroll": "Mode (👇 for more)",
"select-replaced-mode-scroll": "Replaces (👇 for more)",
"select-purpose-scroll": "Purpose (👇 for more)",
"delete-entry-confirm": "Are you sure you wish to delete this entry?",
"detected": "Detected:",
"labeled-mode": "Labeled Mode",
"detected-modes": "Detected Modes",
"today": "Today",
"no-more-travel": "No more travel to show",
"show-more-travel": "Show More Travel",
Expand Down Expand Up @@ -224,6 +226,7 @@
"fix": "Fix",
"refresh":"Refresh",
"overall-description": "This app works in the background to automatically build a travel diary for you. Make sure that all the settings below are green so that the app can work properly!",
"explanation-title": "What are these used for?",
"overall-loc-name": "Location",
"overall-loc-description": "We use the background location permission to track your location in the background, even when the app is closed. Reading background locations removes the need to turn tracking on and off, making the app easier to use and preventing battery drain.",
"locsettings": {
Expand Down Expand Up @@ -271,7 +274,8 @@
"name": "Unused apps disabled",
"description": {
"android-disable-lt-12": "On the app settings page, go to 'Permissions' and ensure that the app permissions will not be automatically reset.",
"android-disable-gte-12": "On the app settings page, turn off 'Remove permissions and free up space.'",
"android-disable-12": "On the app settings page, turn off 'Remove permissions and free up space.'",
"android-disable-gte-13": "On the app settings page, turn off 'Pause app activity if unused.'",
"ios": "Please allow."
}
},
Expand Down Expand Up @@ -350,6 +354,69 @@
"invalid-subgroup-no-default": "Invalid OPcode {{token}}, no subgroups, expected 'default' subgroup",
"unable-download-config": "Unable to download study config",
"invalid-opcode-format": "Invalid OPcode format",
"error-loading-config-app-start": "Error loading config on app start"
"error-loading-config-app-start": "Error loading config on app start",
"survey-missing-formpath": "Error while fetching resources in config: survey_info.surveys has a survey without a formPath"
},
"errors": {
"while-populating-composite": "Error while populating composite trips",
"while-loading-another-week": "Error while loading travel of {{when}} week",
"while-loading-specific-week": "Error while loading travel for the week of {{day}}"
},
"consent-text": {
"title":"NREL OPENPATH PRIVACY POLICY/TERMS OF USE",
"introduction":{
"header":"Introduction and Purpose",
"what-is-openpath":"This data is being collected through OpenPATH, an NREL open-sourced platform. The smart phone application, NREL OpenPATH (“App”), combines data from smartphone sensors, semantic user labels and a short demographic survey.",
"what-is-NREL":"NREL is a national laboratory of the U.S. Department of Energy, Office of Energy Efficiency and Renewable Energy, operated by Alliance for Sustainable Energy, LLC under Prime Contract No. DE-AC36-08GO28308. This Privacy Policy applies to the App provided by Alliance for Sustainable Energy, LLC. This App is provided solely for the purposes of collecting travel behavior data for the {{program_or_study}} and for research to inform public policy. None of the data collected by the App will never be sold or used for any commercial purposes, including advertising.",
"if-disagree":"IF YOU DO NOT AGREE WITH THE TERMS OF THIS PRIVACY POLICY, PLEASE DELETE THE APP"
},
"why":{
"header":"Why we collect this information"
},
"what":{
"header":"What information we collect",
"no-pii":"The App will never ask for any Personally Identifying Information (PII) such as name, email, address, or phone number.",
"phone-sensor":"It collects phone sensor data pertaining to your location (including background location), accelerometer, device-generated activity and mode recognition, App usage time, and battery usage. The App will create a “travel diary” based on your background location data to determine your travel patterns and location history.",
"labeling":"It will also ask you to periodically annotate these sensed trips with semantic labels, such as the trip mode, purpose, and replaced mode.",
"demographics":"It will also request sociodemographic information such as your approximate age, gender, and household type. The sociodemographic factors can be used to understand the influence of lifestyle on travel behavior, as well as generalize the results to a broader population.",
"open-source-data":"For the greatest transparency, the App is based on an open source platform, NREL’s OpenPATH. you can inspect the data that OpenPATH collects in the background at",
"open-source-analysis":"the analysis pipeline at",
"open-source-dashboard":"and the dashboard metrics at",
"on-nrel-site": "For the greatest transparency, the App is based on an open source platform, NREL’s OpenPATH. you can inspect the data that OpenPATH collects in the background, the analysis pipeline, and the dashboard metrics through links on the NREL OpenPATH website."
},
"opcode":{
"header":"How we associate information with you",
"not-autogen":"Program administrators will provide you with a 'opcode' that you will use to log in to the system. This long random string will be used for all further communication with the server. If you forget or lose your opcode, you may request it by providing your name and/or email address to the program administrator. Please do not contact NREL staff with opcode retrieval requests since we do not have access to the connection between your name/email and your opcode. The data that NREL automatically collects (phone sensor data, semidemographic data, etc.) will only be associated with your 'opcode'",
"autogen":"You are logging in with a randomly generated 'opcode' that has been generated by the platform. This long random string will used for all further communication with the server. Only you know the opcode that is associated with you. There is no “Forgot password” option, and NREL staff cannot retrieve your opcode, even if you provide your name or email address. This means that, unless you store your opcode in a safe place, you will not have access to your prior data if you switch phones or uninstall and reinstall the App."
},
"who-sees":{
"header":"Who gets to see the information",
"public-dash":"Aggregate metrics derived from the travel patterns will be made available on a public dashboard to provide transparency into the impact of the program. These metrics will focus on information summaries such as counts, distances and durations, and will not display individual travel locations or times.",
"individual-info":"Individual labeling rates and trip level information will only be made available to:",
"program-admins":"🧑 Program administrators from {{deployment_partner_name}} to {{raw_data_use}}, and",
"nrel-devs":"💻 NREL OpenPATH developers for debugging",
"TSDC-info":"The data will also be periodically archived in NREL’s Transportation Secure Data Center (TSDC) after a delay of 3 to 6 months. It will then be made available for legitimate research through existing, privacy-preserving TSDC operating procedures. Further information on the procedures is available",
"on-website":" on the website ",
"and-in":"and in",
"this-pub":" this publication ",
"and":"and",
"fact-sheet":" fact sheet",
"on-nrel-site": " through links on the NREL OpenPATH website."
},
"rights":{
"header":"Your rights",
"app-required":"You are required to track your travel patterns using the App as a condition of participation in the Program. If you wish to withdraw from the Program, you should contact the program administrator, {{program_admin_contact}} to discuss termination options. If you wish to stay in the program but not use the app, please contact your program administrator to negotiate an alternative data collection procedure before uninstalling the app. If you uninstall the app without approval from the program administrator, you may not have access to the benefits provided by the program.",
"app-not-required":"Participation in the {{program_or_study}} is completely voluntary. You have the right to decline to participate or to withdraw at any point in the Study without providing notice to NREL or the point of contact. If you do not wish to participate in the Study or to discontinue your participation in the Study, please delete the App.",
"destroy-data-pt1":"If you would like to have your data destroyed, please contact K. Shankari ",
"destroy-data-pt2":" requesting deletion. You must include your token in the request for deletion. Because we do not connect your identity with your token, we cannot delete your information without obtaining the token as part of the deletion request. We will then destroy all data associated with that deletion request, both in the online and archived datasets."
},
"questions":{
"header":"Questions",
"for-questions":"If you have any questions about the data collection goals and results, please contact the primary point of contact for the study, {{program_admin_contact}}. If you have any technical questions about app operation, please contact NREL’s K. Shankari ([email protected])."
},
"consent":{
"header":"Consent",
"press-button-to-consent":"Please select the button below to indicate that you have read and agree to this Privacy Policy, consent to the collection of your information, and want to participate in the {{program_or_study}}."
}
}
}
16 changes: 12 additions & 4 deletions www/js/appTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ const AppTheme = {
primary: '#0080b9', // lch(50% 50 250)
primaryContainer: '#90ceff', // lch(80% 40 250)
onPrimaryContainer: '#001e30', // lch(10% 50 250)
secondary: '#f2795c', // lch(65% 60 40)
secondaryContainer: '#ffb39e', // lch(80% 45 40)
secondary: '#c08331', // lch(60% 55 70)
secondaryContainer: '#fcefda', // lch(95% 12 80)
onSecondaryContainer: '#45392e', // lch(25% 10 65)
background: '#edf1f6', // lch(95% 3 250) - background of label screen, other screens still have this as CSS .pane
surface: '#fafdff', // lch(99% 30 250)
surfaceVariant: '#e0f0ff', // lch(94% 50 250) - background of DataTable
surfaceDisabled: '#c7e0f7', // lch(88% 15 250)
onSurfaceDisabled: '#3a4955', // lch(30% 10 250)
elevation: {
level0: 'transparent',
level1: '#fafdff', // lch(99% 30 250)
Expand All @@ -23,6 +26,8 @@ const AppTheme = {
level4: '#e0f0ff', // lch(94% 50 250)
level5: '#d6ebff', // lch(92% 50 250)
},
success: '#38872e', // lch(50% 55 135)
danger: '#f23934' // lch(55% 85 35)
},
roundness: 5,
};
Expand Down Expand Up @@ -57,12 +62,15 @@ const flavorOverrides = {
},
}
},
draft: { // for draft TripCards; a greyish color scheme
draft: { // for TripCards and LabelDetailsScreen of draft trips; a greyish color scheme
colors: {
primary: '#616971', // lch(44 6 250)
primaryContainer: '#b6bcc2', // lch(76 4 250)
background: '#eef1f4', // lch(95 2 250)
surface: '#eef1f4', // lch(95 2 250)
surfaceDisabled: '#c7cacd', // lch(81 2 250)
elevation: {
level1: '#dbddde', // lch(88 1 250)
level1: '#e1e3e4', // lch(90 1 250)
level2: '#d2d5d8', // lch(85 2 250)
},
}
Expand Down
41 changes: 41 additions & 0 deletions www/js/appstatus/ExplainPermissions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import React from "react";
import { Modal, ScrollView, useWindowDimensions, View } from "react-native";
import { Button, Dialog, Text } from 'react-native-paper';
import { useTranslation } from "react-i18next";

const ExplainPermissions = ({ explanationList, visible, setVisible }) => {
const { t } = useTranslation();
const { height: windowHeight } = useWindowDimensions();

return (
<Modal visible={visible}
onDismiss={() => setVisible(false)} >
<Dialog visible={visible}
onDismiss={() => setVisible(false)} >
<Dialog.Title>{t('intro.appstatus.explanation-title')}</Dialog.Title>
<Dialog.Content style={{maxHeight: windowHeight/1.5, paddingBottom: 0}}>
<ScrollView>
{explanationList?.map((li) =>
<View key={li.name}>
<Text variant="headlineSmall" key={li.name}>
{li.name}
</Text>
<Text variant="bodyMedium">
{li.desc}
</Text>
</View>
)}
</ScrollView>
</Dialog.Content>
<Dialog.Actions>
<Button
onPress={() => setVisible(false)}>
{t('join.close')}
</Button>
</Dialog.Actions>
</Dialog>
</Modal>
);
};

export default ExplainPermissions;
Loading

0 comments on commit 80b4794

Please sign in to comment.