diff --git a/.github/workflows/android-automated-sdk-install.yml b/.github/workflows/android-automated-sdk-install.yml index e700b16b4..140880587 100644 --- a/.github/workflows/android-automated-sdk-install.yml +++ b/.github/workflows/android-automated-sdk-install.yml @@ -40,6 +40,7 @@ jobs: - name: Install to a new SDK root run: | + export JAVA_HOME=$JAVA_HOME_11_X64 export ANDROID_SDK_ROOT=$NEW_ANDROID_SDK_ROOT echo "New SDK root $ANDROID_SDK_ROOT" printf "Y\nY\nY\nY\nY\n" | bash setup/prereq_android_sdk_install.sh @@ -47,6 +48,7 @@ jobs: - name: Verify that all packages are as expected shell: bash -l {0} run: | + export JAVA_HOME=$JAVA_HOME_11_X64 echo "Comparing $ANDROID_SDK_ROOT and $NEW_ANDROID_SDK_ROOT" $ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --list_installed > /tmp/existing_packages $NEW_ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager --list_installed > /tmp/new_packages @@ -56,6 +58,7 @@ jobs: - name: Verify that directory structure is consistent shell: bash -l -x {0} run: | + export JAVA_HOME=$JAVA_HOME_11_X64 export ANDROID_SDK_ROOT=$NEW_ANDROID_SDK_ROOT echo "New SDK root $ANDROID_SDK_ROOT" ls -al $ANDROID_SDK_ROOT diff --git a/.github/workflows/android-build.yml b/.github/workflows/android-build.yml index 38da371a9..25eb65317 100644 --- a/.github/workflows/android-build.yml +++ b/.github/workflows/android-build.yml @@ -6,9 +6,13 @@ name: osx-build-android # events but only for the master branch on: push: - branches: [ master ] + branches: + - master + - maint_upgrade_** pull_request: - branches: [ master ] + branches: + - master + - maint_upgrade_** schedule: # * is a special character in YAML so you have to quote this string - cron: '5 4 * * 0' diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index d6783e218..2c4ee344f 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -6,9 +6,13 @@ name: CI # events but only for the master branch on: push: - branches: [ master ] + branches: + - master + - maint_upgrade_** pull_request: - branches: [ master ] + branches: + - master + - maint_upgrade_** # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: diff --git a/.github/workflows/ios-build.yml b/.github/workflows/ios-build.yml index 62b2ccb0d..ad0ce2f01 100644 --- a/.github/workflows/ios-build.yml +++ b/.github/workflows/ios-build.yml @@ -6,9 +6,13 @@ name: osx-build-ios # events but only for the master branch on: push: - branches: [ master ] + branches: + - master + - maint_upgrade_** pull_request: - branches: [ master ] + branches: + - master + - maint_upgrade_** schedule: # * is a special character in YAML so you have to quote this string - cron: '5 4 * * 0' diff --git a/.github/workflows/serve-install.yml b/.github/workflows/serve-install.yml index 0f1dc21d2..288c1c8cb 100644 --- a/.github/workflows/serve-install.yml +++ b/.github/workflows/serve-install.yml @@ -6,9 +6,13 @@ name: osx-serve-install # events but only for the master branch on: push: - branches: [ master ] + branches: + - master + - maint_upgrade_** pull_request: - branches: [ master ] + branches: + - master + - maint_upgrade_** schedule: # * is a special character in YAML so you have to quote this string - cron: '5 4 * * 0' diff --git a/config.cordovabuild.xml b/config.cordovabuild.xml index c533fe541..6a0c1480e 100644 --- a/config.cordovabuild.xml +++ b/config.cordovabuild.xml @@ -1,5 +1,5 @@ - + emission A commute pattern tracker and carbon footprint estimator. @@ -42,14 +42,21 @@ + + To scan QR codes for the login token and the study + - - + + + + + + diff --git a/hooks/before_build/android/android_change_compile_implementation.js b/hooks/before_build/android/android_change_compile_implementation.js new file mode 100755 index 000000000..0e2e51999 --- /dev/null +++ b/hooks/before_build/android/android_change_compile_implementation.js @@ -0,0 +1,48 @@ +/* + * A hook to change provider in order to match with the application name. + */ + +var fs = require('fs'); +var path = require('path'); +var et = require('elementtree'); + +const LOG_NAME = "Changing compile to implementation "; + +var changeCompileToImplementation = function (file) { + if (fs.existsSync(file)) { + fs.readFile(file, 'utf8', function (err, data) { + var result = data.replace("compile", "implementation"); + fs.writeFile(file, result, 'utf8', function (err) { + if (err) throw new Error(LOG_NAME + 'Unable to write into ' + file + ': ' + err); + console.log(LOG_NAME + "" + file + " updated...") + }); + }); + } else { + console.error("Could not find file "+file+" skipping compile -> implementation change"); + } +} + +module.exports = function (context) { + // If Android platform is not installed, don't even execute + if (!context.opts.platforms.includes('android')) return; + + var config_xml = path.join(context.opts.projectRoot, 'config.xml'); + var data = fs.readFileSync(config_xml).toString(); + // If no data then no config.xml + if (data) { + var etree = et.parse(data); + console.log(LOG_NAME + "Retrieving application name...") + var applicationName = etree._root.attrib.id; + console.info(LOG_NAME + "Your application is " + applicationName); + const splitParts = applicationName.split(".") + var lastApplicationPart = splitParts[splitParts.length - 1]; + + var platformRoot = path.join(context.opts.projectRoot, 'platforms/android/') + + console.log(LOG_NAME + "Updating barcode scanner gradle..."); + var gradleFile = path.join(platformRoot, 'phonegap-plugin-barcodescanner/'+lastApplicationPart+'-barcodescanner.gradle'); + changeCompileToImplementation(gradleFile); + } else { + throw new Error(LOG_NAME + "Could not retrieve application name."); + } +} diff --git a/package.cordovabuild.json b/package.cordovabuild.json index 99188d589..f21d7c89e 100644 --- a/package.cordovabuild.json +++ b/package.cordovabuild.json @@ -1,6 +1,6 @@ { "name": "edu.berkeley.eecs.emission", - "version": "3.2.4", + "version": "3.2.8", "displayName": "emission", "license": "BSD-3-Clause", "repository": { @@ -8,9 +8,9 @@ "url": "git+https://github.com/e-mission/e-mission-phone.git" }, "devDependencies": { - "cordova": "10.0.0", - "@ionic/cli": "6.12.0", - "bower": "1.8.8" + "cordova": "11.1.0", + "@ionic/cli": "6.20.8", + "bower": "1.8.14" }, "cordova": { "platforms": [ @@ -19,9 +19,9 @@ ], "plugins": { "@havesource/cordova-plugin-push": { - "ANDROID_SUPPORT_V13_VERSION": "28.0.0", - "FCM_VERSION": "18.+", - "IOS_FIREBASE_MESSAGING_VERSION": "~> 6.32.2" + "ANDROIDX_CORE_VERSION": "1.6.+", + "FCM_VERSION": "23.+", + "IOS_FIREBASE_MESSAGING_VERSION": "~> 8.1.1" }, "cordova-plugin-ionic-keyboard": {}, "cordova-plugin-app-version": {}, @@ -39,63 +39,57 @@ "PHOTO_LIBRARY_USAGE_DESCRIPTION": "This app requires photo library access to share photos on social media." }, "cordova-plugin-inappbrowser": {}, - "cordova-plugin-local-notification": {}, - "cordova-plugin-ionic": { - "APP_ID": "e0d8cdec", - "CHANNEL_NAME": "Production", - "UPDATE_METHOD": "none", - "UPDATE_API": "https://api.ionicjs.com", - "MAX_STORE": "2" + "cordova-plugin-local-notification-12": { + "ANDROID_SUPPORT_V4_VERSION": "26.+", + "ANDROIDX_VERSION": "1.2.0", + "ANDROIDX_APPCOMPAT_VERSION": "1.3.1" }, "cordova-plugin-advanced-http": {}, "cordova-plugin-ionic-webview": { "ANDROID_SUPPORT_ANNOTATIONS_VERSION": "27.+" }, - "cordova-plugin-em-jwt-auth": { - "AUTH_VERSION": "19.2.0" - }, + "cordova-plugin-em-opcodeauth": {}, "cordova-plugin-em-server-communication": {}, "cordova-plugin-em-datacollection": { - "LOCATION_VERSION": "18.0.0", - "ANDROIDX_CORE_VERSION": "1.7.0", + "LOCATION_VERSION": "21.0.1", + "ANDROIDX_CORE_VERSION": "1.8.0", "ANDROIDX_WORK_VERSION": "2.7.1" }, "cordova-plugin-em-serversync": {}, "cordova-plugin-em-settings": {}, - "cordova-plugin-em-transition-notify": {}, "cordova-plugin-em-unifiedlogger": {}, "cordova-plugin-em-usercache": {}, "cordova-plugin-androidx-adapter": {}, - "phonegap-plugin-barcodescanner": {} + "phonegap-plugin-barcodescanner": { + "ANDROID_SUPPORT_V4_VERSION": "27.+" + } } }, "dependencies": { - "cordova-android": "10.1.0", + "cordova-android": "11.0.0", "cordova-ios": "6.2.0", - "cordova-plugin-advanced-http": "3.2.2", - "cordova-plugin-androidx-adapter": "git+https://github.com/dpa99c/cordova-plugin-androidx-adapter.git", - "cordova-plugin-app-version": "0.1.12", + "cordova-plugin-advanced-http": "3.3.1", + "cordova-plugin-androidx-adapter": "1.1.3", + "cordova-plugin-app-version": "0.1.14", "cordova-plugin-customurlscheme": "5.0.2", - "cordova-plugin-device": "2.0.3", - "cordova-plugin-em-datacollection": "git+https://github.com/e-mission/e-mission-data-collection.git#v1.7.4", - "cordova-plugin-em-jwt-auth": "git+https://github.com/e-mission/cordova-jwt-auth.git#v1.6.5", - "cordova-plugin-em-server-communication": "git+https://github.com/e-mission/cordova-server-communication.git#v1.2.4", - "cordova-plugin-em-serversync": "git+https://github.com/e-mission/cordova-server-sync.git#v1.2.9", + "cordova-plugin-device": "2.1.0", + "cordova-plugin-em-datacollection": "git+https://github.com/e-mission/e-mission-data-collection.git#v1.7.7", + "cordova-plugin-em-opcodeauth": "git+https://github.com/e-mission/cordova-jwt-auth.git#v1.7.1", + "cordova-plugin-em-server-communication": "git+https://github.com/e-mission/cordova-server-communication.git#v1.2.5", + "cordova-plugin-em-serversync": "git+https://github.com/e-mission/cordova-server-sync.git#v1.3.1", "cordova-plugin-em-settings": "git+https://github.com/e-mission/cordova-connection-settings.git#v1.2.3", - "cordova-plugin-em-transition-notify": "git+https://github.com/e-mission/e-mission-transition-notify.git#v1.2.7", - "cordova-plugin-em-unifiedlogger": "git+https://github.com/e-mission/cordova-unified-logger.git#v1.3.5", + "cordova-plugin-em-unifiedlogger": "git+https://github.com/e-mission/cordova-unified-logger.git#v1.3.6", "cordova-plugin-em-usercache": "git+https://github.com/e-mission/cordova-usercache.git#v1.1.5", "cordova-plugin-email-composer": "git+https://github.com/katzer/cordova-plugin-email-composer.git#0.10.1", - "cordova-plugin-file": "6.0.2", + "cordova-plugin-file": "7.0.0", "cordova-plugin-inappbrowser": "5.0.0", - "cordova-plugin-ionic": "5.5.1", "cordova-plugin-ionic-keyboard": "2.2.0", "cordova-plugin-ionic-webview": "5.0.0", - "cordova-plugin-local-notification": "https://github.com/timkellypa/cordova-plugin-local-notifications.git#083ccca0f4eee8fbec0cde1edd32207c286d2a04", - "cordova-plugin-x-socialsharing": "6.0.3", + "cordova-plugin-local-notification-12": "0.1.4", + "cordova-plugin-x-socialsharing": "6.0.4", "fs-extra": "^9.0.1", "klaw-sync": "^6.0.0", "phonegap-plugin-barcodescanner": "git+https://github.com/phonegap/phonegap-plugin-barcodescanner#v8.1.0", - "@havesource/cordova-plugin-push": "2.0.0" + "@havesource/cordova-plugin-push": "git+https://github.com/havesource/cordova-plugin-push.git#4.0.0-dev.0" } } diff --git a/setup/android_sdk_packages b/setup/android_sdk_packages index 38d07d1b8..5d3f6737b 100644 --- a/setup/android_sdk_packages +++ b/setup/android_sdk_packages @@ -1,7 +1,6 @@ -build-tools;30.0.1 -build-tools;30.0.2 -build-tools;30.0.3 build-tools;31.0.0 +build-tools;32.0.0 +build-tools;33.0.2 emulator extras;google;google_play_services extras;intel;Hardware_Accelerated_Execution_Manager @@ -9,6 +8,8 @@ patcher;v4 platform-tools platforms;android-30 platforms;android-31 +platforms;android-32 +platforms;android-33 system-images;android-22;google_apis;x86_64 system-images;android-23;google_apis;x86_64 system-images;android-24;google_apis_playstore;x86 @@ -16,7 +17,10 @@ system-images;android-25;google_apis_playstore;x86 system-images;android-26;google_apis_playstore;x86 system-images;android-27;google_apis_playstore;x86 system-images;android-28;google_apis_playstore;x86_64 -system-images;android-29;google_apis_playstore;x86 system-images;android-29;google_apis_playstore;x86_64 -system-images;android-30;google_apis_playstore;x86 system-images;android-30;google_apis_playstore;x86_64 +system-images;android-31;google_apis_playstore;x86_64 +system-images;android-32;google_apis;x86_64 +system-images;android-32;google_apis_playstore;x86_64 +system-images;android-33;google_apis;x86_64 +system-images;android-33;google_apis_playstore;x86_64 diff --git a/setup/export_shared_dep_versions.sh b/setup/export_shared_dep_versions.sh index 74ffb7087..930216b6e 100644 --- a/setup/export_shared_dep_versions.sh +++ b/setup/export_shared_dep_versions.sh @@ -1,13 +1,13 @@ -export NVM_VERSION=0.39.0 -export NODE_VERSION=14.18.1 -export NPM_VERSION=6.14.15 +export NVM_VERSION=0.39.3 +export NODE_VERSION=19.5.0 +export NPM_VERSION=9.3.1 # make sure that this is a stable version from # so that https://github.com/postmodern/ruby-versions # ideally, this would be the same version as the CI # Looks like brew supports only major and minor, not patch version -export RUBY_VERSION=2.7 -export COCOAPODS_VERSION=1.11.2 -export GRADLE_VERSION=7.1.1 +export RUBY_VERSION=3.0 +export COCOAPODS_VERSION=1.11.3 +export GRADLE_VERSION=7.6 export OSX_EXP_VERSION=12 export NVM_DIR="$HOME/.nvm" diff --git a/setup/prereq_android_sdk_install.sh b/setup/prereq_android_sdk_install.sh index 206b42add..e9767eeff 100644 --- a/setup/prereq_android_sdk_install.sh +++ b/setup/prereq_android_sdk_install.sh @@ -1,4 +1,4 @@ -TOOLS_VERSION=8092744 +TOOLS_VERSION=9477386 TOOLS_ZIP_FILENAME=commandlinetools-mac-${TOOLS_VERSION}_latest.zip echo "Installing command line tools from $TOOLS_ZIP_FILENAME" diff --git a/setup/setup_shared_native.sh b/setup/setup_shared_native.sh index 40ff7536c..382289001 100644 --- a/setup/setup_shared_native.sh +++ b/setup/setup_shared_native.sh @@ -26,7 +26,7 @@ sed -i -e "s|/usr/bin/env node|/usr/bin/env node --unhandled-rejections=strict|" npx cordova prepare -EXPECTED_COUNT=25 +EXPECTED_COUNT=23 INSTALLED_COUNT=`npx cordova plugin list | wc -l` echo "Found $INSTALLED_COUNT plugins, expected $EXPECTED_COUNT" if [ $INSTALLED_COUNT -lt $EXPECTED_COUNT ]; diff --git a/www/i18n/en.json b/www/i18n/en.json index 08732d04d..57b19aebf 100644 --- a/www/i18n/en.json +++ b/www/i18n/en.json @@ -55,7 +55,6 @@ "edit-demographics": "Edit Demographics", "username": "Username {{usernamedata}}", "tracking": "Tracking", - "enable-opgeofence": "Experimental trip start", "app-status": "App Status", "medium-accuracy": "Medium accuracy", "dark-theme": "Dark theme", @@ -347,7 +346,8 @@ "android-lt-6": "Enabled during app installation.", "android-6-9": "Please select 'allow'", "android-10": "Please select 'Allow all the time'", - "android-gte-11": "On the app settings page, choose the 'Location' permission and set it to 'Allow all the time'", + "android-11": "On the app settings page, choose the 'Location' permission and set it to 'Allow all the time'", + "android-gte-12": "On the app settings page, choose the 'Location' permission and set it to 'Allow all the time' and 'Precise'", "ios-lt-13": "Please select 'Always allow'", "ios-gte-13": "On the app settings page, please select 'Always' and 'Precise' and return here to continue" } @@ -378,7 +378,15 @@ "unusedapprestrict": { "name": "Unused apps disabled", "description": { - "android-disable": "On the app settings page, go to 'Permissions' and ensure that the app permissions will not be automatically reset.", + "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.'", + "ios": "Please allow." + } + }, + "ignorebatteryopt": { + "name": "Ignore battery optimizations", + "description": { + "android-disable": "On the optimization page, go to all apps, search for this app and turn off optimizations.", "ios": "Please allow." } } diff --git a/www/index.html b/www/index.html index b2cd1cf0e..37b8615a2 100644 --- a/www/index.html +++ b/www/index.html @@ -77,7 +77,6 @@ - @@ -94,7 +93,6 @@ - @@ -130,7 +128,6 @@ - diff --git a/www/js/app.js b/www/js/app.js index 402244fc6..ea36f87be 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -10,12 +10,12 @@ angular.module('emission', ['ionic', 'emission.controllers','emission.services', 'emission.plugin.logger', 'emission.splash.customURLScheme', 'emission.splash.referral', - 'emission.splash.updatecheck', 'emission.services.email', + 'emission.services.email', 'emission.intro', 'emission.main', 'pascalprecht.translate']) .run(function($ionicPlatform, $rootScope, $http, Logger, - CustomURLScheme, ReferralHandler, UpdateCheck) { + CustomURLScheme, ReferralHandler) { console.log("Starting run"); // ensure that plugin events are delivered after the ionicPlatform is ready // https://github.com/katzer/cordova-plugin-local-notifications#launch-details @@ -32,8 +32,6 @@ angular.module('emission', ['ionic', if (urlComponents.route == 'join') { ReferralHandler.setupGroupReferral(urlComponents); StartPrefs.loadWithPrefs(); - } else if (urlComponents.route == 'change_client') { - UpdateCheck.handleClientChangeURL(urlComponents); } }); // END: Global listeners diff --git a/www/js/appstatus/permissioncheck.js b/www/js/appstatus/permissioncheck.js index dfe136343..f39b4af82 100644 --- a/www/js/appstatus/permissioncheck.js +++ b/www/js/appstatus/permissioncheck.js @@ -171,13 +171,15 @@ controller("PermissionCheckControl", function($scope, $element, $attrs, if (version < 9) { androidSettingsDescTag = "intro.appstatus.locsettings.description.android-lt-9"; } - var androidPermDescTag = "intro.appstatus.locperms.description.android-gte-11"; + var androidPermDescTag = "intro.appstatus.locperms.description.android-gte-12"; if($scope.osver < 6) { androidPermDescTag = 'intro.appstatus.locperms.description.android-lt-6'; } else if ($scope.osver < 10) { androidPermDescTag = "intro.appstatus.locperms.description.android-6-9"; } else if ($scope.osver < 11) { androidPermDescTag= "intro.appstatus.locperms.description.android-10"; + } else if ($scope.osver < 12) { + androidPermDescTag= "intro.appstatus.locperms.description.android-11"; } console.log("description tags are "+androidSettingsDescTag+" "+androidPermDescTag); // location settings @@ -327,13 +329,33 @@ controller("PermissionCheckControl", function($scope, $element, $attrs, return checkOrFix(unusedAppsUnrestrictedCheck, $window.cordova.plugins.BEMDataCollection.isUnusedAppUnrestricted, $scope.recomputeBackgroundRestrictionStatus, showError=false); }; + let fixBatteryOpt = function() { + console.log("fix and refresh battery optimization permissions"); + return checkOrFix(ignoreBatteryOptCheck, $window.cordova.plugins.BEMDataCollection.fixIgnoreBatteryOptimizations, + $scope.recomputeBackgroundRestrictionStatus, showError=true); + }; + let checkBatteryOpt = function() { + console.log("fix and refresh battery optimization permissions"); + return checkOrFix(ignoreBatteryOptCheck, $window.cordova.plugins.BEMDataCollection.isIgnoreBatteryOptimizations, + $scope.recomputeBackgroundRestrictionStatus, showError=false); + }; + var androidUnusedDescTag = "intro.appstatus.unusedapprestrict.description.android-disable-gte-12"; + if ($scope.osver < 12) { + androidUnusedDescTag= "intro.appstatus.unusedapprestrict.description.android-disable-lt-12"; + } let unusedAppsUnrestrictedCheck = { name: $translate.instant("intro.appstatus.unusedapprestrict.name"), - desc: $translate.instant("intro.appstatus.unusedapprestrict.description.android-disable"), + desc: $translate.instant(androidUnusedDescTag), fix: fixPerms, refresh: checkPerms } - $scope.backgroundRestrictionChecks = [unusedAppsUnrestrictedCheck]; + let ignoreBatteryOptCheck = { + name: $translate.instant("intro.appstatus.ignorebatteryopt.name"), + desc: $translate.instant("intro.appstatus.ignorebatteryopt.description.android-disable"), + fix: fixBatteryOpt, + refresh: checkBatteryOpt + } + $scope.backgroundRestrictionChecks = [unusedAppsUnrestrictedCheck, ignoreBatteryOptCheck]; refreshChecks($scope.backgroundRestrictionChecks, $scope.recomputeBackgroundRestrictionStatus); } diff --git a/www/js/control/general-settings.js b/www/js/control/general-settings.js index 4eb3443fa..f50e43f8c 100644 --- a/www/js/control/general-settings.js +++ b/www/js/control/general-settings.js @@ -4,11 +4,9 @@ angular.module('emission.main.control',['emission.services', 'emission.i18n.utils', 'emission.main.control.collection', 'emission.main.control.sync', - 'emission.main.control.tnotify', 'ionic-datepicker', 'ionic-datepicker.provider', 'emission.splash.startprefs', - 'emission.splash.updatecheck', 'emission.main.metrics.factory', 'emission.stats.clientstats', 'emission.plugin.kvstore', @@ -23,9 +21,8 @@ angular.module('emission.main.control',['emission.services', $rootScope, KVStore, ionicDatePicker, StartPrefs, ControlHelper, EmailHelper, UploadHelper, ControlCollectionHelper, ControlSyncHelper, - ControlTransitionNotifyHelper, CarbonDatasetHelper, - UpdateCheck, i18nUtils, + i18nUtils, CalorieCal, ClientStats, CommHelper, Logger, $translate) { @@ -98,7 +95,7 @@ angular.module('emission.main.control',['emission.services', } $scope.viewQRCode = function($event) { - $scope.tokenURL = "emission://login_token?token="+$scope.settings.auth.email; + $scope.tokenURL = "emission://login_token?token="+$scope.settings.auth.opcode; if ($scope.qrp) { $scope.qrp.show($event); } else { @@ -174,7 +171,7 @@ angular.module('emission.main.control',['emission.services', console.log(response); }); }, function(error) { - console.log("While getting connect Url :" + error); + Logger.displayError("While getting connect url", error); }); }; @@ -194,26 +191,18 @@ angular.module('emission.main.control',['emission.services', }); }; - $scope.getTNotifySettings = function() { - ControlTransitionNotifyHelper.getTNotifySettings().then(function(showConfig) { + $scope.getOPCode = function() { + ControlHelper.getOPCode().then(function(opcode) { + console.log("opcode = "+opcode); $scope.$apply(function() { - $scope.settings.tnotify.show_config = showConfig; - }) - }); - }; - - $scope.getEmail = function() { - ControlHelper.getUserEmail().then(function(response) { - console.log("user email = "+response); - $scope.$apply(function() { - if (response == null) { - $scope.settings.auth.email = "Not logged in"; + if (opcode == null) { + $scope.settings.auth.opcode = "Not logged in"; } else { - $scope.settings.auth.email = response; + $scope.settings.auth.opcode = opcode; } }); }, function(error) { - $ionicPopup.alert("while getting email, "+error); + Logger.displayError("while getting opcode, ",error); }); }; $scope.showLog = function() { @@ -232,7 +221,7 @@ angular.module('emission.main.control',['emission.services', }); return response; }, function(error) { - $ionicPopup.alert("while getting current state, "+error); + Logger.displayError("while getting current state", error); }); }; @@ -246,9 +235,7 @@ angular.module('emission.main.control',['emission.services', $ionicPopup.alert({template: 'success -> '+result}); }); }, function(error) { - $scope.$apply(function() { - $ionicPopup.alert({template: 'error -> '+error}); - }); + Logger.displayError("while clearing user cache, error ->", error); }); } }); @@ -273,45 +260,13 @@ angular.module('emission.main.control',['emission.services', }); } - $scope.testTripEndNotify = function() { - $ionicPopup.alert({template: 'test for local notification 0.9.0-beta.3+ only'}); - /* - var testCfg = { - id: 737678, - title: $translate.instant('post-trip-prompt.notification-title'), - text: "Testing if this works", - icon: 'file://img/icon.png', - actions: "TRIP_CONFIRM" - }; - $window.cordova.plugins.notification.local.addActions('TRIP_CONFIRM', [{ - id: 'MUTE', - type: 'button', - title: 'Mute', - ui: 'decline' - },{ - id: 'SNOOZE', - type: 'button', - title: 'Snooze', - launch: true - },{ - id: 'CHOOSE', - type: 'button', - title: "Choose", - launch: true - }]); - $window.cordova.plugins.notification.local.schedule(testCfg); - */ - } - $scope.invalidateCache = function() { window.cordova.plugins.BEMUserCache.invalidateAllCache().then(function(result) { $scope.$apply(function() { $ionicPopup.alert({template: 'success -> '+result}); }); }, function(error) { - $scope.$apply(function() { - $ionicPopup.alert({template: 'error -> '+error}); - }); + Logger.displayError("while invalidating cache, error->", error); }); } @@ -340,23 +295,13 @@ angular.module('emission.main.control',['emission.services', $scope.settings = {}; $scope.settings.collect = {}; $scope.settings.sync = {}; - $scope.settings.tnotify = {}; $scope.settings.auth = {}; $scope.settings.connect = {}; $scope.settings.clientAppVer = ClientStats.getAppVersion(); - $scope.settings.channel = function(newName) { - return arguments.length ? (UpdateCheck.setChannel(newName)) : $scope.settings.storedChannel; - }; - UpdateCheck.getChannel().then(function(retVal) { - $scope.$apply(function() { - $scope.settings.storedChannel = retVal; - }); - }); $scope.getConnectURL(); $scope.getCollectionSettings(); $scope.getSyncSettings(); - $scope.getTNotifySettings(); - $scope.getEmail(); + $scope.getOPCode(); $scope.getState().then($scope.isTrackingOn).then(function(isTracking) { $scope.$apply(function() { console.log("Setting settings.collect.trackingOn = "+isTracking); @@ -493,8 +438,6 @@ angular.module('emission.main.control',['emission.services', $scope.forceState = ControlCollectionHelper.forceState; $scope.editCollectionConfig = ControlCollectionHelper.editConfig; $scope.editSyncConfig = ControlSyncHelper.editConfig; - $scope.editTNotifyConfig = ControlTransitionNotifyHelper.editConfig; - $scope.isAndroid = function() { return ionic.Platform.isAndroid(); @@ -526,16 +469,6 @@ angular.module('emission.main.control',['emission.services', } } - $scope.toggleExperimentalGeofence = function() { - Logger.log("Toggling experimental geofence from current state of "+$scope.settings.collect.experimentalGeofenceOn); - if ($scope.settings.collect.experimentalGeofenceOn) { - KVStore.remove("OP_GEOFENCE_CFG"); - return ControlCollectionHelper.forceTransition('INITIALIZE'); - } else { - KVStore.set("OP_GEOFENCE_CFG", {"enabled": true}); - return ControlCollectionHelper.forceTransition('INITIALIZE'); - } - } $scope.getExpandButtonClass = function() { return ($scope.expanded)? "icon ion-ios-arrow-up" : "icon ion-ios-arrow-down"; } @@ -594,9 +527,6 @@ angular.module('emission.main.control',['emission.services', $scope.userDataExpanded = function() { return $scope.dataExpanded && $scope.userDataSaved(); } - $scope.checkUpdates = function() { - UpdateCheck.checkForUpdates(); - } var handleNoConsent = function(resultDoc) { $ionicPopup.confirm({template: $translate.instant('general-settings.consent-not-found')}) @@ -667,7 +597,7 @@ angular.module('emission.main.control',['emission.services', const cbase64 = c[0].getAttribute('href'); prepopulateQRMessage.files = [cbase64]; - prepopulateQRMessage.url = $scope.settings.auth.email; + prepopulateQRMessage.url = $scope.settings.auth.opcode; window.plugins.socialsharing.shareWithOptions(prepopulateQRMessage, function(result) { console.log("Share completed? " + result.completed); // On Android apps mostly return false even while it's true diff --git a/www/js/controllers.js b/www/js/controllers.js index dedc94529..5f418ba92 100644 --- a/www/js/controllers.js +++ b/www/js/controllers.js @@ -1,21 +1,19 @@ 'use strict'; -angular.module('emission.controllers', ['emission.splash.updatecheck', - 'emission.splash.startprefs', +angular.module('emission.controllers', ['emission.splash.startprefs', 'emission.splash.pushnotify', 'emission.splash.storedevicesettings', 'emission.splash.localnotify', 'emission.splash.remotenotify', - 'emission.stats.clientstats', - 'emission.survey.multilabel.posttrip.prompt']) + 'emission.stats.clientstats']) .controller('RootCtrl', function($scope) {}) .controller('DashCtrl', function($scope) {}) .controller('SplashCtrl', function($scope, $state, $interval, $rootScope, - UpdateCheck, StartPrefs, PushNotify, StoreDeviceSettings, - LocalNotify, RemoteNotify, ClientStats, PostTripAutoPrompt) { + StartPrefs, PushNotify, StoreDeviceSettings, + LocalNotify, RemoteNotify, ClientStats) { console.log('SplashCtrl invoked'); // alert("attach debugger!"); // PushNotify.startupInit(); @@ -23,13 +21,6 @@ angular.module('emission.controllers', ['emission.splash.updatecheck', $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ console.log("Finished changing state from "+JSON.stringify(fromState) + " to "+JSON.stringify(toState)); - /* - if ($rootScope.checkedForUpdates) { - window.Logger.log(window.Logger.log("Already checked for update, skipping")); - } else { - UpdateCheck.checkForUpdates(); - $rootScope.checkedForUpdates = true; - } */ ClientStats.addReading(ClientStats.getStatKeys().STATE_CHANGED, fromState.name + '-2-' + toState.name).then(function() {}, function() {}); }); diff --git a/www/js/incident/post-trip-prompt.js b/www/js/incident/post-trip-prompt.js deleted file mode 100644 index 329187392..000000000 --- a/www/js/incident/post-trip-prompt.js +++ /dev/null @@ -1,259 +0,0 @@ -'use strict'; - -angular.module('emission.incident.posttrip.prompt', ['emission.plugin.logger']) -.factory("PostTripAutoPrompt", function($window, $ionicPlatform, $rootScope, $state, - $ionicPopup, Logger) { - var ptap = {}; - var REPORT = 737678; // REPORT on the phone keypad - var REPORT_INCIDENT_TEXT = 'REPORT_INCIDENT'; - var TRIP_END_EVENT = "trip_ended"; - - var reportMessage = function(platform) { - var platformSpecificMessage = { - "ios": "Swipe right to report any positive or negative experiences on this trip. Swipe left for more - Busy? Snooze 30 mins. Annoyed? Mute.", - "android": "Touch to report any positive or negative experiences on this trip. See options for more - Busy? Snooze 30 mins. Annoyed? Mute." - }; - var selMessage = platformSpecificMessage[platform]; - if (!angular.isDefined(selMessage)) { - selMessage = "Select to report any positive or negative experiences on this trip. More options - Busy? Snooze 30 mins. Annoyed? Mute."; - } - return selMessage; - }; - - var getTripEndReportNotification = function() { - var actions = [{ - identifier: 'MUTE', - title: 'Mute', - icon: 'res://ic_moreoptions', - activationMode: 'background', - destructive: false, - authenticationRequired: false - }, { - identifier: 'SNOOZE', - title: 'Snooze', - icon: 'res://ic_moreoptions', - activationMode: 'background', - destructive: false, - authenticationRequired: false - }, { - identifier: 'REPORT', - title: 'Yes', - icon: 'res://ic_signin', - activationMode: 'foreground', - destructive: false, - authenticationRequired: false - }]; - - var reportNotifyConfig = { - id: REPORT, - title: "Incident to report?", - text: reportMessage(ionic.Platform.platform()), - icon: 'file://img/icon.png', - smallIcon: 'res://ic_mood_question.png', - sound: null, - actions: actions, - category: REPORT_INCIDENT_TEXT, - autoClear: true - }; - Logger.log("Returning notification config "+JSON.stringify(reportNotifyConfig)); - return reportNotifyConfig; - } - - ptap.registerTripEnd = function() { - Logger.log( "registertripEnd received!" ); - // iOS - var notifyPlugin = $window.cordova.plugins.BEMTransitionNotification; - notifyPlugin.addEventListener(notifyPlugin.TRIP_END, getTripEndReportNotification()) - .then(function(result) { - // $window.broadcaster.addEventListener("TRANSITION_NAME", function(result) { - Logger.log("Finished registering "+notifyPlugin.TRIP_END+" with result "+JSON.stringify(result)); - }) - .catch(function(error) { - Logger.displayError("Unable to register notifications for trip end", error); - }); - } - - var getFormattedTime = function(ts_in_secs) { - if (angular.isDefined(ts_in_secs)) { - return moment(ts_in_secs * 1000).format('LT'); - } else { - return "---"; - } - }; - - var promptReport = function(notification, state, data) { - Logger.log("About to prompt whether to report a trip"); - var newScope = $rootScope.$new(); - angular.extend(newScope, notification.data); - newScope.getFormattedTime = getFormattedTime; - Logger.log("notification = "+JSON.stringify(notification)); - Logger.log("state = "+JSON.stringify(state)); - Logger.log("data = "+JSON.stringify(data)); - return $ionicPopup.show({title: "Report incident for trip", - scope: newScope, - template: "{{getFormattedTime(start_ts)}} -> {{getFormattedTime(end_ts)}}", - buttons: [{ - text: 'Report', - type: 'button-positive', - onTap: function(e) { - // e.preventDefault() will stop the popup from closing when tapped. - return true; - } - }, { - text: 'Skip', - type: 'button-positive', - onTap: function(e) { - return false; - } - }] - }) - } - - var cleanDataIfNecessary = function(notification, state, data) { - if ($ionicPlatform.is('ios') && angular.isDefined(notification.data)) { - Logger.log("About to parse "+notification.data); - notification.data = JSON.parse(notification.data); - } - }; - - var displayCompletedTrip = function(notification, state, data) { - Logger.log("About to display completed trip"); - - /* - promptReport(notification, state, data).then(function(res) { - if (res == true) { - console.log("About to go to incident map page"); - $state.go("root.main.incident", notification.data); - } else { - console.log("Skipped incident reporting"); - } - }); - */ - - Logger.log("About to go to diary, which now displays draft information"); - $rootScope.displayingIncident = true; - $state.go("root.main.diary"); - }; - - var checkCategory = function(notification) { - if (notification.category == REPORT_INCIDENT_TEXT) { - return true; - } else { - return false; - } - } - - ptap.registerUserResponse = function() { - Logger.log( "registerUserResponse received!" ); - $window.cordova.plugins.notification.local.on('action', function (notification, state, data) { - if (!checkCategory(notification)) { - Logger.log("notification "+notification+" is not an incident report, returning..."); - return; - } - if (data.identifier === 'REPORT') { - // alert("About to report"); - cleanDataIfNecessary(notification, state, data); - displayCompletedTrip(notification, state, data); - } else if (data.identifier == 'SNOOZE') { - var now = new Date().getTime(), - _30_mins_from_now = new Date(now + 30 * 60 * 1000); - var after_30_mins_prompt = getTripEndReportNotification(); - after_30_mins_prompt.at = _30_mins_from_now; - $window.cordova.plugins.notification.local.schedule([after_30_mins_prompt]); - if ($ionicPlatform.is('android')) { - $ionicPopup.alert({ - title: "Snoozed reminder", - template: "Will reappear in 30 mins" - }); - } - } else if (data.identifier === 'MUTE') { - var now = new Date().getTime(), - _1_min_from_now = new Date(now + 60 * 1000); - var notifyPlugin = $window.cordova.plugins.BEMTransitionNotification; - notifyPlugin.disableEventListener(notifyPlugin.TRIP_END, notification).then(function() { - if ($ionicPlatform.is('ios')) { - $window.cordova.plugins.notification.local.schedule([{ - id: REPORT, - title: "Notifications for TRIP_END incident report muted", - text: "Can be re-enabled from the Profile -> Developer Zone screen. Select to re-enable now, clear to ignore", - at: _1_min_from_now, - data: {redirectTo: "root.main.control"} - }]); - } else if ($ionicPlatform.is('android')) { - $ionicPopup.show({ - title: "Muted", - template: "Notifications for TRIP_END incident report muted", - buttons: [{ - text: 'Unmute', - type: 'button-positive', - onTap: function(e) { - return true; - } - }, { - text: 'Keep muted', - type: 'button-positive', - onTap: function(e) { - return false; - } - }] - }).then(function(res) { - if(res == true) { - notifyPlugin.enableEventListener(notifyPlugin.TRIP_END, notification); - } else { - Logger.log("User chose to keep the transition muted"); - } - }); - } - }).catch(function(error) { - Logger.displayError( - "Error while muting notifications for trip end. Try again later.", - error); - }); - } - }); - $window.cordova.plugins.notification.local.on('clear', function (notification, state, data) { - // alert("notification cleared, no report"); - }); - $window.cordova.plugins.notification.local.on('cancel', function (notification, state, data) { - // alert("notification cancelled, no report"); - }); - $window.cordova.plugins.notification.local.on('trigger', function (notification, state, data) { - // alert("triggered, no action"); - Logger.log("triggered, no action"); - if (!$ionicPlatform.is('ios')) { - Logger.log("notification is displayed even when app is in foreground, ignoring trigger"); - return; - } - if (!checkCategory(notification)) { - Logger.log("notification "+notification+" is not an incident report, returning..."); - return; - } - cleanDataIfNecessary(notification, state, data); - promptReport(notification, state, data).then(function(res) { - if (res == true) { - Logger.log("About to go to incident map page"); - displayCompletedTrip(notification, state, data); - } else { - Logger.log("Skipped incident reporting"); - } - }); - }); - $window.cordova.plugins.notification.local.on('click', function (notification, state, data) { - // alert("clicked, no action"); - if (!checkCategory(notification)) { - Logger.log("notification "+notification+" is not an incident report, returning..."); - return; - } - cleanDataIfNecessary(notification, state, data); - displayCompletedTrip(notification, state, data); - }); - } - - $ionicPlatform.ready().then(function() { - ptap.registerTripEnd(); - ptap.registerUserResponse(); - }); - - return ptap; - -}); diff --git a/www/js/intro.js b/www/js/intro.js index 23e49bc02..b853b2543 100644 --- a/www/js/intro.js +++ b/www/js/intro.js @@ -1,7 +1,6 @@ 'use strict'; angular.module('emission.intro', ['emission.splash.startprefs', - 'emission.splash.updatecheck', 'emission.survey.enketo.demographics', 'emission.appstatus.permissioncheck', 'emission.i18n.utils', @@ -24,7 +23,7 @@ angular.module('emission.intro', ['emission.splash.startprefs', .controller('IntroCtrl', function($scope, $rootScope, $state, $window, $ionicPlatform, $ionicSlideBoxDelegate, - $ionicPopup, $ionicHistory, ionicToast, $timeout, CommHelper, StartPrefs, SurveyLaunch, UpdateCheck, i18nUtils) { + $ionicPopup, $ionicHistory, ionicToast, $timeout, CommHelper, StartPrefs, SurveyLaunch, i18nUtils) { var allIntroFiles = Promise.all([ i18nUtils.geti18nFileName("templates/", "intro/summary", ".html"), @@ -171,7 +170,7 @@ angular.module('emission.intro', ['emission.splash.startprefs', Logger.log("From QR code, extracted token "+extractedToken); $scope.login(extractedToken); } else { - $ionicPopup.alert({template: "invalid token format"+result.text}); + $ionicPopup.alert({template: "invalid token format "+result.text}); } }, function (error) { @@ -180,19 +179,14 @@ angular.module('emission.intro', ['emission.splash.startprefs', }; $scope.login = function(token) { - window.cordova.plugins.BEMJWTAuth.setPromptedAuthToken(token).then(function(userEmail) { + window.cordova.plugins.OPCodeAuth.setOPCode(token).then(function(opcode) { // ionicToast.show(message, position, stick, time); // $scope.next(); - ionicToast.show(userEmail, 'middle', false, 2500); - if (userEmail == "null" || userEmail == "") { - $scope.alertError("Invalid login "+userEmail); + ionicToast.show(opcode, 'middle', false, 2500); + if (opcode == "null" || opcode == "") { + $scope.alertError("Invalid login "+opcode); } else { CommHelper.registerUser(function(successResult) { - UpdateCheck.getChannel().then(function(retVal) { - CommHelper.updateUser({ - client: retVal - }); - }); $scope.next(); }, function(errorResult) { $scope.alertError('User registration error', errorResult); diff --git a/www/js/services.js b/www/js/services.js index 6c1733182..f48239e1c 100644 --- a/www/js/services.js +++ b/www/js/services.js @@ -365,44 +365,41 @@ angular.module('emission.services', ['emission.plugin.logger', var emailData = function(result) { return new Promise(function(resolve, reject) { - window.cordova.plugins.BEMJWTAuth.getUserEmail().then(function(userEmail) { - 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($translate.instant('email-service.email-account-mail-app')); - } - var email = { - to: [userEmail], - attachments: [ - attachFile - ], - subject: $translate.instant('email-service.email-data.subject-data-dump-from-to', {start: startMoment.format(fmt),end: endMoment.format(fmt)}), - body: $translate.instant('email-service.email-data.body-data-consists-of-list-of-entries') - } - $window.cordova.plugins.email.open(email).then(resolve()); + 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($translate.instant('email-service.email-account-mail-app')); + } + var email = { + attachments: [ + attachFile + ], + subject: $translate.instant('email-service.email-data.subject-data-dump-from-to', {start: startMoment.format(fmt),end: endMoment.format(fmt)}), + body: $translate.instant('email-service.email-data.body-data-consists-of-list-of-entries') } - reader.readAsText(file); - }, function(error) { - $ionicPopup.alert({title: "Error while downloading JSON dump", - template: error}); - reject(error); - }); + $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); }); }); }); @@ -420,8 +417,8 @@ angular.module('emission.services', ['emission.plugin.logger', }) }; - this.getUserEmail = function() { - return window.cordova.plugins.BEMJWTAuth.getUserEmail(); + this.getOPCode = function() { + return window.cordova.plugins.OPCodeAuth.getOPCode(); }; this.getSettings = function() { diff --git a/www/js/splash/updatecheck.js b/www/js/splash/updatecheck.js deleted file mode 100644 index 74fbb5274..000000000 --- a/www/js/splash/updatecheck.js +++ /dev/null @@ -1,190 +0,0 @@ -'use strict'; - -angular.module('emission.splash.updatecheck', ['emission.plugin.logger', - 'emission.plugin.kvstore']) - -.factory('UpdateCheck', function($ionicPopup, $ionicPlatform, $rootScope, $window, Logger, KVStore, $translate) { - var uc = {}; - var CHANNEL_KEY = 'deploy_channel'; - - - /* - * Returns a promise that resolves to the name of the channel - * to load UI updates from. - */ - uc.getChannel = function() { - return KVStore.get(CHANNEL_KEY); - }; - - uc.setChannel = function(channelName) { - return KVStore.set(CHANNEL_KEY, channelName); - }; - - uc.initChannelPromise = function(currChannel) { - var deploy = $window.IonicCordova.deploy; - if (currChannel == null) { - Logger.log("currChannel == null, skipping deploy init"); - return Promise.resolve(null); - } else { - var config = { - appId: "e0d8cdec", - channel: currChannel - } - return deploy.configure(config); - } - }; - - var updateProgress = function(prog) { - $rootScope.$apply(function(){ - $rootScope.progress = prog; - $rootScope.isDownloading = true; - if(prog==100) { - $rootScope.isDownloading = false; - } - }); - } - - uc.checkPromise = function() { - var deploy = $window.IonicCordova.deploy; - return deploy.checkForUpdate(); - }; - - uc.downloadPromise = function() { - var deploy = $window.IonicCordova.deploy; - return deploy.downloadUpdate(updateProgress); - }; - - uc.extractPromise = function() { - var deploy = $window.IonicCordova.deploy; - return deploy.extractUpdate(updateProgress); - }; - - uc.redirectPromise = function() { - var deploy = $window.IonicCordova.deploy; - return deploy.reloadApp(); - }; - - uc.handleClientChangeURL = function(urlComponents) { - Logger.log("handleClientChangeURL = "+JSON.stringify(urlComponents)); - var operationArray = [] - if (urlComponents['clear_usercache'] == "true") { - Logger.log("About to clear usercache"); - operationArray.push(KVStore.clearAll()); - } - operationArray.push(uc.setChannel(urlComponents['new_client'])); - Promise.all(operationArray).then(function() { - Logger.log("successfully set the channel to "+urlComponents['new_client']); - uc.checkForUpdates(); - }).catch(function(error) { - Logger.displayError("Unable to handle client change", error); - }) - }; - - // Default to dev - var getChannelToUse = function() { - return uc.getChannel().then(function(channel) { - if (channel == null || channel == "") { - console.log("No saved channel found, skipping channel config") - channel = null; - }; - console.log("Returning channel "+channel) - return channel; - }); - } - - var applyUpdate = function() { - if ($rootScope.isDownloading) { - return; - } - $rootScope.progress = 0; - var downloadPop = $ionicPopup.show({ - title: $translate.instant('updatecheck.downloading-update'), - template: '', - scope: $rootScope, - buttons: [] - }); - uc.downloadPromise().then(function() { - $rootScope.progress = 0; - downloadPop.close(); - // alert("download -> extract"); - var extractPop = $ionicPopup.show({ - title: $translate.instant('updatecheck.extracting-update'), - template: '', - scope: $rootScope, - buttons: [] - }); - uc.extractPromise().then(function(res) { - extractPop.close(); - // alert("extract -> reload"); - Logger.log('Ionic Deploy: Update Success! ' + res); - var reloadAlert = $ionicPopup.alert({ - title: $translate.instant('updatecheck.done') - }); - reloadAlert.then(function(res) { - uc.redirectPromise(); - }); - }).catch(function(err) { - $rootScope.isDownloading = false; - extractPop.close(); - Logger.displayError("Extraction error", err); - }) - }).catch(function(err) { - $rootScope.isDownloading = false; - downloadPop.close(); - Logger.displayError("Download error", err); - }); - }; - - - // Check Ionic Deploy for new code - uc.checkForUpdates = function() { - console.log('Ionic Deploy: Checking for updates'); - getChannelToUse().then(function(currChannel) { - uc.initChannelPromise(currChannel).then(function() { - Logger.log("deploy init complete "); - uc.checkPromise().then(function(updateResponse) { - Logger.log('Ionic Deploy: Update available: ' + JSON.stringify(updateResponse)); - if (updateResponse.available == true) { - Logger.log('Ionic Deploy: found update, asking user: '); - - $ionicPopup.show({ - title: $translate.instant('updatecheck.download-new-ui', updateResponse), - templateUrl: 'templates/splash/release-notes.html', - scope: $rootScope, - buttons: [{ // Array[Object] (optional). Buttons to place in the popup footer. - text: $translate.instant('updatecheck.download-not-now'), - type: 'button-default', - }, { - text: $translate.instant('updatecheck.download-apply'), - type: 'button-positive', - onTap: function(e) { - return true; - } - }] - }).then(function(res){ - if(res) { - Logger.log('Ionic Deploy: User accepted deploy update'); - applyUpdate(); - } else { - Logger.log('User skipped deploy update'); - } - }); - } else { - // TODO: Figure out a better way to do this using promises - // $ionicPopup.alert({title: "Up to date!"}); - } - }) - }) - }).catch(function(err) { - $rootScope.isDownloading = false; - Logger.displayError("Unable to check for updates", err); - }) - } - - $ionicPlatform.ready().then(function() { - uc.checkForUpdates(); - }); - - return uc; -}); - diff --git a/www/js/survey/multilabel/post-trip-prompt.js b/www/js/survey/multilabel/post-trip-prompt.js deleted file mode 100644 index ecf173aa5..000000000 --- a/www/js/survey/multilabel/post-trip-prompt.js +++ /dev/null @@ -1,262 +0,0 @@ -'use strict'; - -angular.module('emission.survey.multilabel.posttrip.prompt', ['emission.plugin.logger']) -.factory("PostTripAutoPrompt", function($window, $ionicPlatform, $rootScope, $state, - $ionicPopup, Logger, $translate) { - var ptap = {}; - var REPORT = 737678; // REPORT on the phone keypad - var TRIP_CONFIRM_TEXT = 'TRIP_CONFIRM'; - var TRIP_END_EVENT = "trip_ended"; - - var reportMessage = function(platform) { - var platformSpecificMessage = { - "ios": $translate.instant('post-trip-prompt.platform-specific-message-ios'), - "android": $translate.instant('post-trip-prompt.platform-specific-message-android') - }; - var selMessage = platformSpecificMessage[platform]; - if (!angular.isDefined(selMessage)) { - selMessage = $translate.instant('post-trip-prompt.platform-specific-message-other'); - } - return selMessage; - }; - - var getTripEndReportNotification = function() { - var actions = [{ - id: 'MUTE', - type: 'button', - title: $translate.instant('post-trip-prompt.notification-option-mute'), - icon: 'res://ic_moreoptions', - launch: true, - destructive: false, - authenticationRequired: false - }, { - id: 'SNOOZE', - type: 'button', - title: $translate.instant('post-trip-prompt.notification-option-snooze'), - icon: 'res://ic_moreoptions', - launch: true, - destructive: false, - authenticationRequired: false - }, { - id: 'CHOOSE', - type: 'button', - title: $translate.instant('post-trip-prompt.notification-option-choose'), - icon: 'res://ic_signin', - launch: true, - destructive: false, - authenticationRequired: false - }]; - - var reportNotifyConfig = { - id: REPORT, - title: $translate.instant('post-trip-prompt.notification-title'), - text: reportMessage(ionic.Platform.platform()), - icon: 'file://img/icon.png', - smallIcon: 'res://ic_mood_question.png', - sound: null, - actions: actions, - actionGroupId: TRIP_CONFIRM_TEXT, - autoClear: true - }; - Logger.log("Returning notification config "+JSON.stringify(reportNotifyConfig)); - return reportNotifyConfig; - } - - ptap.registerTripEnd = function() { - Logger.log( "registertripEnd received!" ); - // iOS - var notifyPlugin = $window.cordova.plugins.BEMTransitionNotification; - notifyPlugin.addEventListener(notifyPlugin.TRIP_END, getTripEndReportNotification()) - .then(function(result) { - // $window.broadcaster.addEventListener("TRANSITION_NAME", function(result) { - Logger.log("Finished registering "+notifyPlugin.TRIP_END+" with result "+JSON.stringify(result)); - }) - .catch(function(error) { - Logger.displayError("Unable to register notifications for trip end", error); - }); - } - - var getFormattedTime = function(ts_in_secs) { - if (angular.isDefined(ts_in_secs)) { - return moment(ts_in_secs * 1000).format('LT'); - } else { - return "---"; - } - }; - - var promptReport = function(notification, state, data) { - Logger.log("About to prompt choose the mode for the trip"); - var newScope = $rootScope.$new(); - angular.extend(newScope, notification.data); - newScope.getFormattedTime = getFormattedTime; - Logger.log("notification = "+JSON.stringify(notification)); - Logger.log("state = "+JSON.stringify(state)); - Logger.log("data = "+JSON.stringify(data)); - return $ionicPopup.show({title: "Choose the travel mode and purpose of this trip", - scope: newScope, - template: "{{getFormattedTime(start_ts)}} -> {{getFormattedTime(end_ts)}}", - buttons: [{ - text: $translate.instant('post-trip-prompt.choose-mode'), - type: 'button-positive', - onTap: function(e) { - // e.preventDefault() will stop the popup from closing when tapped. - return true; - } - }, { - text: $translate.instant('post-trip-prompt.skip'), - type: 'button-positive', - onTap: function(e) { - return false; - } - }] - }) - } - - var cleanDataIfNecessary = function(notification, eventOpts) { - // as of version 0.9.0-beta.4, cleaning data is not necessary, since iOS also returns - // pre-parsed notification data. Let's leave this here for a bit in case we need it - // later, but we can also remove it if we don't need it for a year or so - }; - - var displayCompletedTrip = function(notification, eventOpts) { - /* - $rootScope.tripConfirmParams = notification.data; - Logger.log("About to display completed trip from notification "+ - JSON.stringify(notification.data)); - $state.go("root.main.tripconfirm", notification.data); - */ - Logger.log("About to go to diary, which now displays draft information"); - $rootScope.displayingIncident = true; - $state.go("root.main.diary"); - }; - - var checkCategory = function(notification) { - if (notification.actionGroupId == TRIP_CONFIRM_TEXT) { - return true; - } else { - return false; - } - } - - ptap.registerUserResponse = function() { - Logger.log( "registerUserResponse received!" ); - $window.cordova.plugins.notification.local.on('CHOOSE', function (notification, eventOpts) { - if (!checkCategory(notification)) { - Logger.log("notification "+notification+" is not an mode choice, returning..."); - return; - } - Logger.log("Notification, action event"); - cleanDataIfNecessary(notification, eventOpts); - displayCompletedTrip(notification, eventOpts); - }); - $window.cordova.plugins.notification.local.on('SNOOZE', function (notification, eventOpts) { - if (!checkCategory(notification)) { - Logger.log("notification "+notification+" is not an mode choice, returning..."); - return; - } - var now = new Date().getTime(), - _30_mins_from_now = new Date(now + 30 * 60 * 1000); - var after_30_mins_prompt = getTripEndReportNotification(); - after_30_mins_prompt.at = _30_mins_from_now; - $window.cordova.plugins.notification.local.schedule([after_30_mins_prompt]); - if ($ionicPlatform.is('android')) { - $ionicPopup.alert({ - title: $translate.instant('post-trip-prompt.snoozed-reminder'), - template: $translate.instant('post-trip-prompt.snoozed-reapper-message') - }); - } - }); - $window.cordova.plugins.notification.local.on('MUTE', function (notification, eventOpts) { - if (!checkCategory(notification)) { - Logger.log("notification "+notification+" is not an mode choice, returning..."); - return; - } - var now = new Date().getTime(), - _1_min_from_now = new Date(now + 60 * 1000); - var notifyPlugin = $window.cordova.plugins.BEMTransitionNotification; - notifyPlugin.disableEventListener(notifyPlugin.TRIP_END, notification).then(function() { - if ($ionicPlatform.is('ios')) { - $window.cordova.plugins.notification.local.schedule([{ - id: REPORT, - title: $translate.instant('post-trip-prompt.notifications-muted'), - text: $translate.instant('post-trip-prompt.notifications-reenabled'), - at: _1_min_from_now, - data: {redirectTo: "root.main.control"} - }]); - } else if ($ionicPlatform.is('android')) { - $ionicPopup.show({ - title: $translate.instant('post-trip-prompt.muted'), - template: $translate.instant('post-trip-prompt.notifications-muted'), - buttons: [{ - text: $translate.instant('post-trip-prompt.unmute'), - type: 'button-positive', - onTap: function(e) { - return true; - } - }, { - text: $translate.instant('post-trip-prompt.keep-muted'), - type: 'button-positive', - onTap: function(e) { - return false; - } - }] - }).then(function(res) { - if(res == true) { - notifyPlugin.enableEventListener(notifyPlugin.TRIP_END, notification); - } else { - Logger.log("User chose to keep the transition muted"); - } - }); - } - }).catch(function(error) { - Logger.displayError("Error while muting notifications for trip end. Try again later.", error); - }); - }); - $window.cordova.plugins.notification.local.on('clear', function (notification, eventOpts) { - // alert("notification cleared, no report"); - }); - $window.cordova.plugins.notification.local.on('cancel', function (notification, eventOpts) { - // alert("notification cancelled, no report"); - }); - $window.cordova.plugins.notification.local.on('trigger', function (notification, eventOpts) { - // alert("triggered, no action"); - Logger.log("Notification triggered"); - if (!checkCategory(notification)) { - Logger.log("notification "+notification+" is not an mode choice, returning..."); - return; - } - cleanDataIfNecessary(notification, eventOpts); - if($ionicPlatform.is('ios')) { - promptReport(notification, eventOpts).then(function(res) { - if (res == true) { - Logger.log("About to go to prompt page"); - displayCompletedTrip(notification, eventOpts); - } else { - Logger.log("Skipped confirmation reporting"); - } - }); - } else { - Logger.log("About to go to prompt page"); - displayCompletedTrip(notification, eventOpts); - } - }); - $window.cordova.plugins.notification.local.on('click', function (notification, eventOpts) { - // alert("clicked, no action"); - Logger.log("Notification, click event"); - if (!checkCategory(notification)) { - Logger.log("notification "+notification+" is not an mode choice, returning..."); - return; - } - cleanDataIfNecessary(notification, eventOpts); - displayCompletedTrip(notification, eventOpts); - }); - }; - - $ionicPlatform.ready().then(function() { - ptap.registerTripEnd(); - ptap.registerUserResponse(); - }); - - return ptap; - -}); diff --git a/www/templates/control/main-control.html b/www/templates/control/main-control.html index e8d5ad0cf..0ead0c751 100644 --- a/www/templates/control/main-control.html +++ b/www/templates/control/main-control.html @@ -1,7 +1,7 @@
-
{{settings.auth.email}}
+
{{settings.auth.opcode}}
@@ -22,15 +22,6 @@ -
-
{{'.enable-opgeofence'}}
- -
{{'.app-status'}}
@@ -65,10 +56,6 @@
{{'.share'}}
-
-
{{'.check-ui-updates'}}
-
-
{{'.download-json-dump'}}
@@ -135,16 +122,6 @@
{{'.nuke-all'}}
-
-
{{'.test-notification'}}
-
-
-
-
{{'.set-ui-channel'}}
- -
{{parseState(settings.collect.state)}}
@@ -187,17 +164,6 @@
{{settings.connect.url}}
- -
-
{{'.transition-notify'}}
-
-
- - -
-
-
-
{{'.app-version'}}
{{settings.clientAppVer}}