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

Fix the weird issue where the map popup breaks maps in the diary list #823

Merged
merged 11 commits into from
May 2, 2022
Merged
1 change: 1 addition & 0 deletions www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@
<script src="js/diary.js"></script>
<script src="js/diary/list.js"></script>
<script src="js/diary/infinite_scroll_list.js"></script>
<script src="js/diary/infinite_scroll_detail.js"></script>
<script src="js/diary/current.js"></script>
<script src="js/diary/detail.js"></script>
<script src="js/diary/services.js"></script>
Expand Down
12 changes: 11 additions & 1 deletion www/js/diary.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
angular.module('emission.main.diary',['emission.main.diary.list',
'emission.main.diary.infscrolllist',
'emission.main.diary.infscrolldetail',
'emission.main.diary.detail',
'emission.main.diary.services',
'emission.main.diary.current',])
Expand Down Expand Up @@ -34,7 +35,16 @@ angular.module('emission.main.diary',['emission.main.diary.list',
controller: 'InfiniteDiaryListCtrl'
},
}

})

.state('root.main.inf_scroll-detail', {
url: "/inf_scroll/:tripId",
views: {
'main-inf-scroll': {
templateUrl: "templates/diary/infinite_scroll_detail.html",
controller: 'InfiniteDiaryDetailCtrl'
},
}
})

.state('root.main.current', {
Expand Down
24 changes: 22 additions & 2 deletions www/js/diary/detail.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ angular.module('emission.main.diary.detail',['ui-leaflet', 'ng-walkthrough',
'emission.stats.clientstats',
'emission.incident.posttrip.manual'])

.controller("DiaryDetailCtrl", function($scope, $rootScope, $window, $ionicPlatform,
.controller("DiaryDetailCtrl", function($scope, $rootScope, $window, $injector, $ionicPlatform,
$state, $stateParams, ClientStats, $ionicActionSheet,
leafletData, leafletMapEvents, nzTour, KVStore,
Logger, Timeline, DiaryHelper, Config, ImperialConfig,
Logger, Timeline, DiaryHelper, SurveyOptions, Config, ImperialConfig,
CommHelper, PostTripManualMarker, $translate) {
console.log("controller DiaryDetailCtrl called with params = "+
JSON.stringify($stateParams));
$scope.surveyOpt = SurveyOptions.MULTILABEL;
$scope.tripFilterFactory = $injector.get($scope.surveyOpt.filter);
$scope.filterInputs = $scope.tripFilterFactory.configuredFilters;

$scope.mapCtrl = {};
angular.extend($scope.mapCtrl, {
Expand Down Expand Up @@ -74,6 +77,23 @@ angular.module('emission.main.diary.detail',['ui-leaflet', 'ng-walkthrough',
};
});

$scope.recomputeDisplayTrips = function() {
console.log("Called diary details.recomputeDisplayTrips");
// Let's copy over the userInput to the field expected by the checks (user_input)
// We definitely need to unify this ASAP
$scope.tripgj.user_input = $scope.tripgj.userInput;
const filterMap = $scope.filterInputs.map((f) => f.filter($scope.tripgj));
// again, we cannot use both filters in the detail screen because the trip
// version of in the list view doesn't have the expectation value filled
// out. We really need to unify ASAP!
console.log("filterMap = "+filterMap+" we will only use the second (unlabeled check)");
// if the trip was going to stay (not be filtered), we should not go back to the scroll list
// TODO: Unify with infinite scroll and remove this hack
if (!filterMap[1]) {
$state.go("root.main.diary");
}
};

if (!angular.isDefined($scope.trip) || !angular.isDefined($scope.tripgj)) {
console.log("Detail trip not defined, going back to the list view")
$state.go("root.main.diary");
Expand Down
175 changes: 175 additions & 0 deletions www/js/diary/infinite_scroll_detail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
'use strict';
angular.module('emission.main.diary.infscrolldetail',['ui-leaflet', 'ng-walkthrough',
'nvd3', 'emission.plugin.kvstore',
'emission.services',
'emission.config.imperial',
'emission.plugin.logger',
'emission.stats.clientstats',
'emission.incident.posttrip.manual'])

.controller("InfiniteDiaryDetailCtrl", function($scope, $rootScope, $injector, $window, $ionicPlatform,
$state, $stateParams, ClientStats, $ionicActionSheet,
leafletData, leafletMapEvents, nzTour, KVStore,
Logger, Timeline, DiaryHelper, SurveyOptions, Config, ImperialConfig,
CommHelper, PostTripManualMarker, $translate) {
console.log("controller InfiniteDiaryDetailCtrl called with params = "+
JSON.stringify($stateParams));
$scope.surveyOpt = SurveyOptions.MULTILABEL;
$scope.tripFilterFactory = $injector.get($scope.surveyOpt.filter);
$scope.filterInputs = $scope.tripFilterFactory.configuredFilters;

$scope.mapCtrl = {};
angular.extend($scope.mapCtrl, {
defaults : {
}
});

angular.extend($scope.mapCtrl.defaults, Config.getMapTiles())

var mapEvents = leafletMapEvents.getAvailableMapEvents();
for (var k in mapEvents) {
var eventName = 'leafletDirectiveMap.infscroll-detail.' + mapEvents[k];
$scope.$on(eventName, function(event, data){
try {
console.log("in mapEvents, event = "+JSON.stringify(event.name)+
" leafletEvent = "+JSON.stringify(data.leafletEvent.type)+
" leafletObject = "+JSON.stringify(data.leafletObject.getBounds()));
} catch (e) {
if (e instanceof TypeError) {
console.log("in mapEvents, event = "+JSON.stringify(event.name)+
" leafletEvent = "+JSON.stringify(data.leafletEvent.type)+
" leafletObject is undefined");
} else {
console.log(e);
}
}
$scope.eventDetected = event.name;
});
}

/*
leafletData.getMap('detail').then(function(map) {
map.on('touch', function(ev) {
alert("touch" + ev.latlng); // ev is an event object (MouseEvent in this case)
});
});
*/

$scope.$on('leafletDirectiveMap.infscroll-detail.resize', function(event, data) {
console.log("diary/detail received resize event, invalidating map size");
data.leafletObject.invalidateSize();
});

$scope.refreshTiles = function() {
$scope.$broadcast('invalidateSize');
};

$scope.trip = Timeline.getConfirmedTrip($stateParams.tripId);
Timeline.confirmedTrip2Geojson($scope.trip).then((tripgj) => {
$scope.$apply(() => {
$scope.tripgj = $scope.trip;
$scope.tripgj.data = tripgj;
$scope.tripgj.common = {};
$scope.tripgj.common.earlierOrLater = '';
$scope.tripgj.pointToLayer = DiaryHelper.pointFormat;

if (!angular.isDefined($scope.trip) || !angular.isDefined($scope.tripgj)) {
console.log("Detail trip = "+$scope.trip+" tripgj = "+$scope.tripgj+" not defined, going back to the list view")
$state.go("root.main.inf_scroll");
}
});
});

$scope.recomputeDisplayTrips = function() {
console.log("Called inf scroll details.recomputeDisplayTrips");
const filterMap = $scope.filterInputs.map((f) => f.filter($scope.trip));
const filterValue = filterMap.reduce((a, b) => a || b, false);
console.log("filterMap = "+filterMap+" value = "+filterValue);
// if the trip was going to stay (not be filtered), we should not go back to the scroll list
if (!filterValue) {
$state.go("root.main.inf_scroll");
}
};

/* START: ng-walkthrough code */
// Tour steps
var tour = {
config: {
mask: {
visibleOnNoTarget: true,
clickExit: true
},
previousText: $translate.instant('tour-previous'),
nextText: $translate.instant('tour-next'),
finishText: $translate.instant('tour-finish')
},
steps: [{
target: '#detail',
content: $translate.instant('details.tour-detail-content')
}, {
target: '#sectionList',
content: $translate.instant('details.tour-sectionList-content')
}, {
target: '#sectionPct',
content: $translate.instant('details.tour-sectionPct-content')
}]
};

var startWalkthrough = function () {
nzTour.start(tour).then(function(result) {
Logger.log("detail walkthrough start completed, no error");
}).catch(function(err) {
Logger.displayError("detail walkthrough start errored", err);
});
};


var checkDetailTutorialDone = function () {
var DETAIL_DONE_KEY = 'detail_tutorial_done';
var detailTutorialDone = KVStore.getDirect(DETAIL_DONE_KEY);
if (!detailTutorialDone) {
startWalkthrough();
KVStore.set(DETAIL_DONE_KEY, true);
}
};

$scope.startWalkthrough = function () {
startWalkthrough();
}

$scope.$on('$ionicView.afterEnter', function(ev) {
// Workaround from
// https://github.com/driftyco/ionic/issues/3433#issuecomment-195775629
if(ev.targetScope !== $scope)
return;
checkDetailTutorialDone();
});

$scope.$on('$ionicView.enter',function(){
$scope.startTime = moment().utc()
ClientStats.addEvent(ClientStats.getStatKeys().EXPANDED_TRIP).then(
function() {
console.log("Added "+ClientStats.getStatKeys().EXPANDED_TRIP+" event");
}
);
});

$scope.$on('$ionicView.leave',function() {
var timeOnPage = moment().utc() - $scope.startTime;
ClientStats.addReading(ClientStats.getStatKeys().DIARY_TIME, timeOnPage);
});

$ionicPlatform.on("pause", function() {
if ($state.$current == "root.main.diary.detail") {
var timeOnPage = moment().utc() - $scope.startTime;
ClientStats.addReading(ClientStats.getStatKeys().DIARY_TIME, timeOnPage);
}
})

$ionicPlatform.on("resume", function() {
if ($state.$current == "root.main.diary.detail") {
$scope.startTime = moment().utc()
}
})
/* END: ng-walkthrough code */
})
35 changes: 19 additions & 16 deletions www/js/diary/infinite_scroll_list.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ angular.module('emission.main.diary.infscrolllist',['ui-leaflet',
$timeout,
leafletData, Timeline, CommonGraph, DiaryHelper,
SurveyOptions,
Config, ImperialConfig, PostTripManualMarker, nzTour, KVStore, Logger, UnifiedDataLoader, $ionicPopover, $ionicModal, $translate) {
Config, ImperialConfig, PostTripManualMarker, nzTour, KVStore, Logger, UnifiedDataLoader, $ionicModal, $translate) {

// TODO: load only a subset of entries instead of everything

Expand Down Expand Up @@ -114,6 +114,7 @@ angular.module('emission.main.diary.infscrolllist',['ui-leaflet',
});
$scope.data.allTrips = ctList.concat($scope.data.allTrips);
Logger.log("After adding batch of size "+ctList.length+" cumulative size = "+$scope.data.allTrips.length);
Timeline.setInfScrollConfirmedTripList($scope.data.allTrips);
const oldestTrip = ctList[0];
if (oldestTrip) {
if (oldestTrip.start_ts <= $scope.infScrollControl.pipelineRange.start_ts) {
Expand Down Expand Up @@ -186,22 +187,9 @@ angular.module('emission.main.diary.infscrolllist',['ui-leaflet',
}
});

$ionicModal.fromTemplateUrl("templates/diary/trip-detail-popover.html", {
scope: $scope,
animation: 'slide-in-up'
}).then((popover) => {
$scope.tripDetailPopover = popover;
});

$scope.showDetail = function($event, trip) {
Timeline.confirmedTrip2Geojson(trip).then((tripgj) => {
$scope.currgj = trip;
$scope.currgj.data = tripgj;
$scope.currgj.pointToLayer = DiaryHelper.pointFormat;
$scope.tripDetailPopover.show();
leafletData.getMap("detailPopoverMap").then(function(map) {
map.invalidateSize();
});
$state.go("root.main.inf_scroll-detail", {
tripId: trip.id
});
}

Expand Down Expand Up @@ -534,6 +522,21 @@ angular.module('emission.main.diary.infscrolllist',['ui-leaflet',
ClientStats.addEvent(ClientStats.getStatKeys().CHECKED_INF_SCROLL).then(function() {
console.log("Added "+ClientStats.getStatKeys().CHECKED_INF_SCROLL+" event");
});
$scope.$apply(() => {
if ($scope.data && $scope.data.allTrips) {
$scope.data.allTrips.forEach(function(tripgj, tripIndex, array) {
let tripFromDiary = Timeline.getTripWrapper(tripgj.id);
// Since the label screen has trips from multiple days, we
// may not always find a matching trip in the diary
if (tripFromDiary) {
$scope.labelPopulateFactory.copyInputIfNewer(tripFromDiary, tripgj);
}
});
$scope.recomputeDisplayTrips();
} else {
console.log("No trips loaded yet, no inputs to copy over");
}
});
if($rootScope.barDetail){
readAndUpdateForDay($rootScope.barDetailDate);
$rootScope.barDetail = false;
Expand Down
22 changes: 22 additions & 0 deletions www/js/diary/list.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ angular.module('emission.main.diary.list',['ui-leaflet',
tripgj.display_end_time = DiaryHelper.getLocalTimeString(tripgj.data.properties.end_local_dt);
tripgj.display_distance = ImperialConfig.getFormattedDistance(tripgj.data.properties.distance);
tripgj.display_distance_suffix = ImperialConfig.getDistanceSuffix;
tripgj.display_date = moment(tripgj.data.properties.start_ts * 1000).format('ddd DD MMM YY');
tripgj.display_time = DiaryHelper.getFormattedTimeRange(tripgj.data.properties.start_ts,
tripgj.data.properties.end_ts);
tripgj.isDraft = DiaryHelper.isDraft(tripgj);
Expand Down Expand Up @@ -473,6 +474,27 @@ angular.module('emission.main.diary.list',['ui-leaflet',
ClientStats.addEvent(ClientStats.getStatKeys().CHECKED_DIARY).then(function() {
console.log("Added "+ClientStats.getStatKeys().CHECKED_DIARY+" event");
});
/*
In case we have set the labels in the label screen, we want them to
show up when we come to this screen. It is really hard to do this
using the original code, because the unification is not complete, and
the code to read the manual inputs is completely different.
Instead, let's find the corresponding trip from the label view and
copy over the `userInput` (and potentially the `user_input`) values over
*/
$scope.$apply(() => {
if ($scope.data && $scope.data.currDayTripWrappers) {
$scope.data.currDayTripWrappers.forEach(function(tripgj, tripIndex, array) {
let tripFromLabel = Timeline.getConfirmedTrip(tripgj.data.id);
// Should we just copy over the entry from the label screen
// NO, what if the user changed the labels here, then went to
// the profile and came back. Don't want to lose the upgraded entries
$scope.labelPopulateFactory.copyInputIfNewer(tripFromLabel, tripgj);
});
} else {
console.log("No trips loaded yet, no inputs to copy over");
}
});
if($rootScope.barDetail){
readAndUpdateForDay($rootScope.barDetailDate);
$rootScope.barDetail = false;
Expand Down
Loading