Rebuild delta mode
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<div id="projects">
|
||||
<div id="background"></div>
|
||||
<div id="submap">
|
||||
<div class="loader fa fa-fw fa-map flicker" id="map_loading"></div>
|
||||
</div>
|
||||
@@ -31,15 +32,15 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="feed">
|
||||
<div id="posts">
|
||||
<div id="feed-panel">
|
||||
<div id="poster"></div>
|
||||
<div id="posts_list"></div>
|
||||
<div id="loading"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="elems">
|
||||
<div id="settings-button" class="spot-control"><i class="fa fa-menu fa-fw"></i></div>
|
||||
<div id="post-button" class="spot-control"><i class="fa fa-fw"></i></div>
|
||||
<div id="settings-button" class="spot-control"><i class="fa fa-menu"></i></div>
|
||||
<div id="post-button" class="spot-control"><i class="fa"></i></div>
|
||||
<div id="legend" class="leaflet-control-layers leaflet-control leaflet-control-layers-expanded">
|
||||
<div class="track"><span class="line main"></span><span class="desc">[#]lang:track_main[#]</span></div>
|
||||
<div class="track"><span class="line off-track"></span><span class="desc">[#]lang:track_off-track[#]</span></div>
|
||||
@@ -56,7 +57,7 @@ oSpot.onSamePageMove = function(asHash) {
|
||||
self.tmp('$Map').empty();
|
||||
self.tmp('map', null);
|
||||
self.tmp('$PostList').empty();
|
||||
setFeedUpdateTimer(false);
|
||||
setFeedUpdateTimer(-1);
|
||||
initProject(asHash.items[0]);
|
||||
}
|
||||
return false;
|
||||
@@ -82,14 +83,18 @@ oSpot.onResize = function() {
|
||||
};
|
||||
|
||||
oSpot.onQuitPage = function() {
|
||||
setFeedUpdateTimer(false);
|
||||
setFeedUpdateTimer(-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
oSpot.onKeydown = function(oEvent) {
|
||||
switch(oEvent.which) {
|
||||
case 27:
|
||||
if(!$('#lightboxOverlay').is(':visible')) toggleFeedPanel(false);
|
||||
$bFeedPanelOpen = isFeedPanelOpen();
|
||||
$bSettingsPanelOpen = isSettingsPanelOpen();
|
||||
$bAnimation = ($bFeedPanelOpen && $bSettingsPanelOpen)?'none':null;
|
||||
if($bFeedPanelOpen) toggleFeedPanel(false, $bAnimation);
|
||||
if($bSettingsPanelOpen) toggleSettingsPanel(false, $bAnimation);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -112,12 +117,17 @@ function isFeedPanelOpen() {
|
||||
return self.tmp('$Projects').hasClass('with-feed');
|
||||
}
|
||||
|
||||
function toggleSettingsPanel(bShow) {
|
||||
function toggleSettingsPanel(bShow, sMapAction) {
|
||||
self.tmp('$Projects').toggleClass('with-settings', (typeof bShow === 'undefined')?null:bShow);
|
||||
oSpot.onResize();
|
||||
if(isMobile()) $('#post-button').toggle(!isSettingsPanelOpen());
|
||||
|
||||
oSpot.tmp('map').panBy([(isSettingsPanelOpen()?-1:1)*self.tmp('$Settings').outerWidth(true)/2, 0], {duration: 0.5});
|
||||
sMapAction = sMapAction || 'panTo';
|
||||
switch(sMapAction) {
|
||||
case 'none': break;
|
||||
case 'panTo': oSpot.tmp('map').panBy([(isSettingsPanelOpen()?-1:1)*self.tmp('$Settings').outerWidth(true)/2, 0], {duration: 0.5}); break;
|
||||
case 'panToInstant': oSpot.tmp('map').panBy([(isSettingsPanelOpen()?-1:1)*self.tmp('$Settings').outerWidth(true)/2, 0]); break;
|
||||
}
|
||||
}
|
||||
|
||||
function isSettingsPanelOpen() {
|
||||
@@ -174,16 +184,18 @@ function initPage(asHash) {
|
||||
|
||||
//Post Panel one-off init (see initPosts for project related init)
|
||||
//Scrollbar
|
||||
self.tmp('simple-bar', new SimpleBar($('#posts')[0]));
|
||||
self.tmp('simple-bar', new SimpleBar($('#feed-panel')[0]));
|
||||
self.tmp('simple-bar').getScrollElement().addEventListener('scroll', onFeedScroll);
|
||||
|
||||
//Add "Loading" Post
|
||||
getPost({type: 'loading', headerless: true, formatted_time: '', relative_time: ''}).appendTo($('#loading'));
|
||||
|
||||
/*
|
||||
//Mobile events
|
||||
$("#feed").onSwipe(function(aiDelta){
|
||||
if(aiDelta.x > self.tmp('$Feed').outerWidth(true)/3 && aiDelta.x > Math.abs(aiDelta.y)) toggleFeedPanel(false);
|
||||
});
|
||||
*/
|
||||
|
||||
//Feed Panel
|
||||
initPosts();
|
||||
@@ -257,7 +269,7 @@ function initPosts() {
|
||||
function()
|
||||
{
|
||||
$('#post').val('');
|
||||
updateFeed(true);
|
||||
onAutoUpdate();
|
||||
},
|
||||
{
|
||||
id_project: self.vars(['project', 'id']),
|
||||
@@ -331,11 +343,6 @@ function setUserInterface() {
|
||||
}
|
||||
}
|
||||
|
||||
function onAutoUpdate(bStart) {
|
||||
if(!bStart && self.tmp('simple-bar').getScrollElement().scrollTop == 0) updateFeed(true, true);
|
||||
setFeedUpdateTimer(60, onAutoUpdate);
|
||||
}
|
||||
|
||||
function getElevWidth() {
|
||||
var
|
||||
iPageWidth = self.tmp('$Projects').width(),
|
||||
@@ -518,28 +525,18 @@ function initSpotMessages(aoMessages, aoTracks) {
|
||||
}
|
||||
|
||||
//Conversion of hours into natural language
|
||||
var iTimeMinutes = 0, iTimeHours = 0, iTimeDays = Math.floor(iTime/8); //8 hours a day
|
||||
if(iTimeDays > 1) iTimeDays = Math.round(iTimeDays * 2) / 2; //Round down to the closest half day
|
||||
else {
|
||||
iTimeDays = 0;
|
||||
iTimeHours = Math.floor(iTime);
|
||||
iTime -= iTimeHours;
|
||||
|
||||
iTimeMinutes = Math.floor(iTime * 4) * 15; //Round down to the closest 15 minutes
|
||||
}
|
||||
var sDuration = '~ '
|
||||
+(iTimeDays>0?(iTimeDays+(iTimeDays%2==0?'':'½')+' '+oSpot.lang(iTimeDays>1?'unit_days':'unit_day')):'')//Days
|
||||
+((iTimeHours>0 || iTimeDays==0)?iTimeHours+oSpot.lang('unit_hour'):'') //Hours
|
||||
+((iTimeDays>0 || iTimeMinutes==0)?'':iTimeMinutes) //Minutes
|
||||
var sDuration = oSpot.getNaturalDuration(iTime);
|
||||
|
||||
//Tooltip details info
|
||||
$TooltipBody.append($('<div>', {'class':'separator'}));
|
||||
var $TooltipDetails = $('<div>', {'class':'details'}).appendTo($TooltipBody);
|
||||
$('<p>', {'class':'detail'}).addIcon('fa-distance fa-fw', true).append(Math.round(iDistance/1000)+'km').appendTo($TooltipDetails);
|
||||
$('<p>', {'class':'detail'}).addIcon('fa-time fa-fw', true).append(sDuration).appendTo($TooltipDetails);
|
||||
$('<p>', {'class':'detail'}).addIcon('fa-elev-gain fa-fw', true).append(iElevGain+'m').appendTo($TooltipDetails);
|
||||
$('<p>', {'class':'detail'}).addIcon('fa-elev-drop fa-fw', true).append(iElevDrop+'m').appendTo($TooltipDetails);
|
||||
|
||||
$TooltipBody
|
||||
.append($('<div>', {'class':'separator'}))
|
||||
.append($('<div>', {'class':'details'})
|
||||
.append($('<p>', {'class':'detail'}).addIcon('fa-distance fa-fw', true).append(Math.round(iDistance/1000)+'km'))
|
||||
.append($('<p>', {'class':'detail'}).addIcon('fa-time fa-fw', true).append(sDuration))
|
||||
.append($('<p>', {'class':'detail'}).addIcon('fa-elev-gain fa-fw', true).append(iElevGain+'m'))
|
||||
.append($('<p>', {'class':'detail'}).addIcon('fa-elev-drop fa-fw', true).append(iElevDrop+'m'))
|
||||
);
|
||||
|
||||
//Trail Start/End
|
||||
self.tmp(['trail-markers', asProperties.name], {
|
||||
'start' : L.marker(new L.latLng(aiCoords[0][1], aiCoords[0][0]), {icon: getDivIcon('track-start')}),
|
||||
@@ -558,22 +555,43 @@ function initSpotMessages(aoMessages, aoTracks) {
|
||||
}
|
||||
}).addTo(oMap));
|
||||
|
||||
//Last message
|
||||
var oLastMsg = (aoMessages.length > 0)?aoMessages[aoMessages.length-1]:{};
|
||||
|
||||
//Centering map
|
||||
var iPanelWidth = isMobile()?0:parseInt(self.tmp('$Feed').outerWidth(true));
|
||||
if(
|
||||
self.vars(['project', 'mode']) == self.consts.modes.blog &&
|
||||
aoMessages.length > 0 &&
|
||||
!$.isEmptyObject(oLastMsg) &&
|
||||
self.getHash()[2] != 'message'
|
||||
) {
|
||||
//Zoom on last message
|
||||
var oLastMsg = aoMessages[aoMessages.length-1];
|
||||
oMap.setView(L.latLng(oLastMsg.latitude, oLastMsg.longitude), 15);
|
||||
oMap.panBy([iPanelWidth/2, 0]);
|
||||
}
|
||||
else oMap.fitBounds(self.tmp('track').getBounds(), {paddingTopLeft: L.point(5, self.tmp('marker_size').height + 5), paddingBottomRight: L.point(5 + iPanelWidth, 5)});
|
||||
|
||||
//Add Spot messages
|
||||
addSpotMessages(aoMessages);
|
||||
|
||||
//Open tooltip on latest message in mobile mode
|
||||
if(
|
||||
!$.isEmptyObject(oLastMsg) &&
|
||||
self.vars(['project', 'mode']) == self.consts.modes.blog &&
|
||||
(!oLastMsg.medias || oLastMsg.medias.length < 3) &&
|
||||
isMobile()
|
||||
) oSpot.tmp(['markers', oLastMsg.id_message]).openPopup();
|
||||
|
||||
/*
|
||||
oSpot.tmp('tracks', aoTracks);
|
||||
next(24, 0, 0, 5);
|
||||
*/
|
||||
}
|
||||
|
||||
function addSpotMessages(aoMessages) {
|
||||
|
||||
//Spot Messages
|
||||
var iWorkSpaceMinWidth = self.tmp('$Projects').width() - self.tmp('$Feed').outerWidth(true) - self.tmp('$Settings').outerWidth(true);
|
||||
var iWorkSpaceMinWidth = isMobile()?self.tmp('$Projects').width():(self.tmp('$Projects').width() - self.tmp('$Feed').outerWidth(true) - self.tmp('$Settings').outerWidth(true));
|
||||
$.each(aoMessages, function(iKey, oMsg){
|
||||
|
||||
//Marker
|
||||
@@ -581,7 +599,7 @@ function initSpotMessages(aoMessages, aoTracks) {
|
||||
id: oMsg.id_message,
|
||||
riseOnHover: true,
|
||||
icon: getDivIcon('message-in fa-rotate-270')
|
||||
}).addTo(oMap);
|
||||
}).addTo(self.tmp('map'));
|
||||
|
||||
//Tooltip
|
||||
$Tooltip = $('<div>', {'class':'info-window'})
|
||||
@@ -621,21 +639,8 @@ function initSpotMessages(aoMessages, aoTracks) {
|
||||
offset: new L.Point(0, -30)
|
||||
});
|
||||
|
||||
//Open tooltip on latest message in mobile mode
|
||||
if(
|
||||
iKey === (aoMessages.length - 1) &&
|
||||
self.vars(['project', 'mode']) == self.consts.modes.blog &&
|
||||
(!oMsg.medias || oMsg.medias.length < 3) &&
|
||||
isMobile()
|
||||
) oMarker.openPopup();
|
||||
|
||||
oSpot.tmp(['markers', oMsg.id_message], oMarker);
|
||||
});
|
||||
|
||||
/*
|
||||
oSpot.tmp('tracks', aoTracks);
|
||||
next(24, 0, 0, 5);
|
||||
*/
|
||||
}
|
||||
|
||||
function toggleSoftPopup(e, sMode) {
|
||||
@@ -662,44 +667,6 @@ function toggleSoftPopup(e, sMode) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
function next(iCurrTrack, iCurrIndex, iCurrOffset, iCurrZoom) {
|
||||
var aoTracks = oSpot.tmp('tracks');
|
||||
var aoOffset = {0:[0,0], 1:[-1,0], 2:[-1,1], 3:[0,1], 4:[1,1], 5:[1,0], 6:[1,-1], 7:[0,-1], 8:[-1,-1]};
|
||||
|
||||
console.log('Getting Track '+iCurrTrack+'/'+(aoTracks.features.length - 1)+', '+
|
||||
'Point '+iCurrIndex+'/'+(aoTracks.features[iCurrTrack].geometry.coordinates.length - 1)+', '+
|
||||
'Zoom '+iCurrZoom+'/14, '+
|
||||
'Offset ['+aoOffset[iCurrOffset][0]+','+aoOffset[iCurrOffset][1]+']');
|
||||
|
||||
//Position map
|
||||
var iLat = aoTracks.features[iCurrTrack].geometry.coordinates[iCurrIndex][1] + aoOffset[iCurrOffset][1] * 0.0347910214271;
|
||||
var iLng = aoTracks.features[iCurrTrack].geometry.coordinates[iCurrIndex][0] + aoOffset[iCurrOffset][0] * 0.1016235351560;
|
||||
oSpot.tmp('map').setView(L.latLng(iLat, iLng), iCurrZoom);
|
||||
|
||||
//Go to next
|
||||
iCurrOffset++;
|
||||
if(iCurrZoom < 13 || iCurrOffset > 8) {
|
||||
iCurrOffset = 0;
|
||||
iCurrZoom++;
|
||||
if(iCurrZoom > 14) {
|
||||
iCurrZoom = 5;
|
||||
iCurrIndex += 100;
|
||||
if(!(iCurrIndex in aoTracks.features[iCurrTrack].geometry.coordinates)) {
|
||||
iCurrIndex = 0;
|
||||
iCurrTrack++;
|
||||
if(!(iCurrTrack in aoTracks.features)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
timer = setTimeout(function(){next(iCurrTrack, iCurrIndex, iCurrOffset, iCurrZoom);}, 1000);
|
||||
}
|
||||
function stop() {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
*/
|
||||
|
||||
function getDivIcon(sIcon) {
|
||||
return L.divIcon({
|
||||
className: '',
|
||||
@@ -715,12 +682,50 @@ function onFeedScroll() {
|
||||
if(($Box.scrollTop() + $(window).height()) / $BoxContent.height() >= 0.8) updateFeed();
|
||||
}
|
||||
|
||||
function onAutoUpdate(bStart) {
|
||||
bStart = bStart || false;
|
||||
if(!bStart) checkNewFeed();
|
||||
setFeedUpdateTimer(60, onAutoUpdate);
|
||||
}
|
||||
|
||||
function checkNewFeed() {
|
||||
self.get(
|
||||
'new_feed',
|
||||
function(asData) {
|
||||
var iItemCount = Object.keys(asData.feed).length;
|
||||
if(iItemCount > 0) self.tmp('ref_id_first', asData.ref_id_first);
|
||||
|
||||
//Feed
|
||||
var $Posts = $('<div>');
|
||||
$.each(asData.feed, function(iKey, asPost) {
|
||||
$Posts.append(getPost(asPost));
|
||||
});
|
||||
self.tmp('$PostList').prepend($Posts.children());
|
||||
|
||||
//Markers
|
||||
addSpotMessages(asData.messages);
|
||||
|
||||
//Message Last Update
|
||||
updateSettingsPanel(asData.last_update);
|
||||
}, {
|
||||
id_project: self.vars(['project', 'id']),
|
||||
id: self.tmp('ref_id_first')
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
function setFeedUpdateTimer(iSeconds, fCallback) {
|
||||
if(typeof self.tmp('update_timer') != 'undefined') clearTimeout(self.tmp('update_timer'));
|
||||
if(iSeconds >= 0) self.tmp('update_timer', setTimeout(fCallback, iSeconds * 1000));
|
||||
}
|
||||
|
||||
function updateFeed(bFirstChunk, bDiscrete, fCallback) {
|
||||
bFirstChunk = bFirstChunk || false;
|
||||
bDiscrete = bDiscrete || false;
|
||||
fCallback = fCallback || function(){};
|
||||
|
||||
if(bFirstChunk) self.tmp('ref_id', 0);
|
||||
//First/Last Item displayed on the feed
|
||||
if(bFirstChunk) self.tmp('ref_id_last', 0);
|
||||
|
||||
if(self.tmp('updatable')) {
|
||||
if(!self.tmp('out-of-data') || bFirstChunk) {
|
||||
@@ -729,39 +734,36 @@ function updateFeed(bFirstChunk, bDiscrete, fCallback) {
|
||||
|
||||
var $Posts = $('<div>');
|
||||
|
||||
if(bFirstChunk===true) {
|
||||
self.tmp('news_chunk', 0);
|
||||
}
|
||||
|
||||
self.get(
|
||||
'feed',
|
||||
'next_feed',
|
||||
function(asData) {
|
||||
$('#loading').hide();
|
||||
var iItemCount = Object.keys(asData.feed).length;
|
||||
|
||||
//Update pointers
|
||||
self.tmp('out-of-data', iItemCount < self.vars('chunk_size'));
|
||||
if(iItemCount > 0) {
|
||||
self.tmp('ref_id_last', asData.ref_id_last);
|
||||
if(bFirstChunk === true) self.tmp('ref_id_first', asData.ref_id_first);
|
||||
}
|
||||
|
||||
self.tmp('ref_id', asData.ref_id);
|
||||
|
||||
//Add posts
|
||||
if(bFirstChunk === true) self.tmp('$PostList').empty();
|
||||
$.each(asData.feed, function(iKey, asPost){
|
||||
$Posts.append(getPost(asPost));
|
||||
});
|
||||
|
||||
self.tmp('news_chunk', self.tmp('news_chunk') + 1);
|
||||
self.tmp('out-of-data', Object.keys(asData.feed).length != self.vars('chunk_size'));
|
||||
|
||||
if(bFirstChunk===true) self.tmp('$PostList').empty();
|
||||
self.tmp('$PostList').append($Posts.children());
|
||||
|
||||
self.tmp('$PostList').find('img').waitForImages(true).done(fCallback);
|
||||
|
||||
self.tmp('updatable', true);
|
||||
}, {
|
||||
id_project: self.vars(['project', 'id']),
|
||||
chunk: self.tmp('news_chunk'),
|
||||
id: self.tmp('ref_id')
|
||||
id: self.tmp('ref_id_last')
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
else if(bFirstChunk) setFeedUpdateTimer(0.2);
|
||||
else if(bFirstChunk) setFeedUpdateTimer(0.2, function(){updateFeed(bFirstChunk, bDiscrete, fCallback);});
|
||||
}
|
||||
|
||||
function focusOnPost(oFocusPost) {
|
||||
@@ -780,16 +782,10 @@ function focusOnPost(oFocusPost) {
|
||||
else console.log('Missing element ID '+sElemId);
|
||||
|
||||
//Reset Hash
|
||||
flushHash(['post', 'message']);
|
||||
oSpot.flushHash(['post', 'message']);
|
||||
}
|
||||
}
|
||||
|
||||
function setFeedUpdateTimer(iSeconds, fCallback) {
|
||||
fCallback = fCallback || function(){updateFeed(true);};
|
||||
if(typeof self.tmp('update_timer') != 'undefined') clearTimeout(self.tmp('update_timer'));
|
||||
if(iSeconds > 0) self.tmp('update_timer', setTimeout(fCallback, iSeconds * 1000));
|
||||
}
|
||||
|
||||
function getPost(asPost) {
|
||||
asPost.headerless = asPost.headerless || false;
|
||||
var bLink = false;
|
||||
@@ -946,17 +942,41 @@ function getGoogleMapsLink(asInfo) {
|
||||
}).text(asInfo.lat_dms+' '+asInfo.lon_dms);
|
||||
}
|
||||
|
||||
function updateHash(sType, iId) {
|
||||
sType = sType || '';
|
||||
iId = iId || 0;
|
||||
/*
|
||||
function next(iCurrTrack, iCurrIndex, iCurrOffset, iCurrZoom) {
|
||||
var aoTracks = oSpot.tmp('tracks');
|
||||
var aoOffset = {0:[0,0], 1:[-1,0], 2:[-1,1], 3:[0,1], 4:[1,1], 5:[1,0], 6:[1,-1], 7:[0,-1], 8:[-1,-1]};
|
||||
|
||||
var asHash = self.getHash();
|
||||
if(iId) self.setHash(asHash.page, [asHash.items[0], sType, iId]);
|
||||
}
|
||||
console.log('Getting Track '+iCurrTrack+'/'+(aoTracks.features.length - 1)+', '+
|
||||
'Point '+iCurrIndex+'/'+(aoTracks.features[iCurrTrack].geometry.coordinates.length - 1)+', '+
|
||||
'Zoom '+iCurrZoom+'/14, '+
|
||||
'Offset ['+aoOffset[iCurrOffset][0]+','+aoOffset[iCurrOffset][1]+']');
|
||||
|
||||
function flushHash(asTypes) {
|
||||
asTypes = asTypes || [];
|
||||
var asHash = self.getHash();
|
||||
if(asHash.items.length > 1 && (asTypes.length == 0 || asTypes.indexOf(asHash.items[1]) != -1)) self.setHash(asHash.page, [asHash.items[0]]);
|
||||
//Position map
|
||||
var iLat = aoTracks.features[iCurrTrack].geometry.coordinates[iCurrIndex][1] + aoOffset[iCurrOffset][1] * 0.0347910214271;
|
||||
var iLng = aoTracks.features[iCurrTrack].geometry.coordinates[iCurrIndex][0] + aoOffset[iCurrOffset][0] * 0.1016235351560;
|
||||
oSpot.tmp('map').setView(L.latLng(iLat, iLng), iCurrZoom);
|
||||
|
||||
//Go to next
|
||||
iCurrOffset++;
|
||||
if(iCurrZoom < 13 || iCurrOffset > 8) {
|
||||
iCurrOffset = 0;
|
||||
iCurrZoom++;
|
||||
if(iCurrZoom > 14) {
|
||||
iCurrZoom = 5;
|
||||
iCurrIndex += 100;
|
||||
if(!(iCurrIndex in aoTracks.features[iCurrTrack].geometry.coordinates)) {
|
||||
iCurrIndex = 0;
|
||||
iCurrTrack++;
|
||||
if(!(iCurrTrack in aoTracks.features)) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
timer = setTimeout(function(){next(iCurrTrack, iCurrIndex, iCurrOffset, iCurrZoom);}, 1000);
|
||||
}
|
||||
</script>
|
||||
function stop() {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
*/
|
||||
</script>
|
||||
Reference in New Issue
Block a user