Browse Source

make game_player map self-updating

testing
Burathar 4 years ago
parent
commit
48b7431c74
  1. 39
      app/main/routes.py
  2. 11
      app/static/assets/leaflet/utils.js
  3. 88
      app/templates/game_player.html

39
app/main/routes.py

@ -93,7 +93,7 @@ def send_location(username):
# Check if previous two locations are exactly the same, # Check if previous two locations are exactly the same,
# if so, only update timestamp of last location # if so, only update timestamp of last location
if last_location: if last_location:
if datetime.utcnow() - last_location.timestamp < timedelta(minutes=1): if datetime.utcnow() - last_location.timestamp < timedelta(seconds=30):
return '', 204 return '', 204
if (latitude == last_location.latitude and if (latitude == last_location.latitude and
longitude == last_location.longitude and longitude == last_location.longitude and
@ -110,6 +110,43 @@ def send_location(username):
db.session.commit() db.session.commit()
return '', 204 return '', 204
@bp.route('/game/<game_name>/get_locations', methods=['POST'])
@login_required
def poll_locations(game_name):
game = Game.query.filter_by(name=game_name).first_or_404()
role = current_user.role_in_game(game)
if role is None or role == Role.none:
abort(403)
payload = request.get_json()
if payload is None:
abort(400)
mode = get_value_if_key_exists(payload, 'mode', 'last')
last_update = get_value_if_key_exists(payload, 'last_update', 'none')
last_update = datetime.strptime(last_update, '%Y-%m-%d %H:%M:%S:%f') if last_update != 'none' else datetime.min
requested_users = get_value_if_key_exists(payload, 'requested_users', 'none')
#print(f'mode: {mode}\nlast_request: {last_update}\nrequested_users: {requested_users}')
response_objects = []
if role == Role.owner:
for username in requested_users:
user = get_user_locations(game, username, mode, last_update)
if user:
response_objects.append(user)
response_objects = [obj for obj_list in response_objects for obj in obj_list]
return json.dumps(response_objects, cls=LocationEncoder)
def get_value_if_key_exists(dictionary, key, default=None):
return dictionary[key] if key in dictionary else default
def get_user_locations(game, username, mode, last_update):
user = User.query.filter_by(name=username).first()
if user is None:
return None
if mode == 'accumulative':
if game.end_time < last_update:
return []
return [location for location in user.locations_during_game(game) if location.timestamp - last_update > timedelta(milliseconds=1)]
@bp.route('/user/<username>') @bp.route('/user/<username>')
@login_required @login_required
def user_profile(username): def user_profile(username):

11
app/static/assets/leaflet/utils.js

@ -25,6 +25,15 @@ var bluePlayerIcon = new L.Icon({
shadowSize: [41, 41] shadowSize: [41, 41]
}); });
var bluePlayerIconMini = new L.Icon({
iconUrl: '/static/assets/leaflet/images/person-marker-icon-2x-blue.png',
shadowUrl: '/static/assets/leaflet/images/marker-shadow.png',
iconSize: [10, 16.4],
iconAnchor: [5, 16.4],
popupAnchor: [1, -34],
shadowSize: [16.4, 16.4]
});
var greenPlayerIcon = new L.Icon({ var greenPlayerIcon = new L.Icon({
iconUrl: '/static/assets/leaflet/images/person-marker-icon-2x-green.png', iconUrl: '/static/assets/leaflet/images/person-marker-icon-2x-green.png',
shadowUrl: '/static/assets/leaflet/images/marker-shadow.png', shadowUrl: '/static/assets/leaflet/images/marker-shadow.png',
@ -50,6 +59,7 @@ function addObjectiveMarker(map, objective){
} else { } else {
objectiveMarker.bindTooltip(`<b>${objective['name']}</b>`).openPopup(); objectiveMarker.bindTooltip(`<b>${objective['name']}</b>`).openPopup();
} }
return objectiveMarker
} }
function addPlayerMarker(map, player, icon=bluePlayerIcon){ function addPlayerMarker(map, player, icon=bluePlayerIcon){
@ -61,6 +71,7 @@ function addPlayerMarker(map, player, icon=bluePlayerIcon){
var timestamp_local = moment(timestamp_utc).local().format('YYYY-MM-DD HH:mm'); var timestamp_local = moment(timestamp_utc).local().format('YYYY-MM-DD HH:mm');
playerMarker.bindTooltip(`<b>${player['username']}</b><br> playerMarker.bindTooltip(`<b>${player['username']}</b><br>
${timestamp_local}`).openPopup(); ${timestamp_local}`).openPopup();
return playerMarker
} }
function getMap(){ function getMap(){

88
app/templates/game_player.html

@ -9,6 +9,7 @@
{% endblock %} {% endblock %}
{% block app_content %} {% block app_content %}
<meta name="csrf-token" content="{{ csrf_token() }}">
<h1>Player: {{ player.user.name }}</h1> <h1>Player: {{ player.user.name }}</h1>
<hr> <hr>
<div class="row"> <div class="row">
@ -82,20 +83,93 @@
locations = [] locations = []
} }
for (var i = 0; i < locations.length; i++) { var markers, lastMarker;
addPlayerMarker(map, locations[i]) updateMarkers();
var polyline;
updatePolyline();
// zoom the map to the polyline
map.fitBounds(polyline.getBounds(), {
maxZoom : 13
});
function updateMarkers(){
if(markers != undefined){
markers.forEach(function(marker){
marker.remove()
});
}
markers = []
for (var i = 0; i < locations.length -1; i++) {
markers.push(addPlayerMarker(map, locations[i], bluePlayerIconMini))
}
if(lastMarker != undefined){
lastMarker.remove()
}
lastMarker = addPlayerMarker(map, locations[locations.length-1], bluePlayerIcon)
} }
if (locations.length > 0) { function updatePolyline(){
var polyline = L.polyline(locations.map(l => [l.latitude, l.longitude]), { if(polyline != undefined){
map.removeLayer(polyline)
}
if (locations.length == 0) { return }
polyline = L.polyline(locations.map(l => [l.latitude, l.longitude]), {
color: 'blue', color: 'blue',
opacity: 0.6, opacity: 0.6,
}).addTo(map); }).addTo(map);
}
// zoom the map to the polyline // Poll Locations
map.fitBounds(polyline.getBounds(), { var csrftoken = $('meta[name=csrf-token]').attr('content')
maxZoom : 13 $.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken)
}
}
})
function get_newest_date(locations){
return new Date(Math.max.apply(null, locations.map(function(e) {
return new Date(e.timestamp_utc);
})));
}
setInterval(function() {pollLocations()}, 10 * 1000);
function pollLocations() {
$.ajax({
type: "POST",
url: "{{ url_for('main.poll_locations', game_name=player.game.name) }}",
data: JSON.stringify({
requested_users: ['{{ player.user.name }}'],
mode: 'accumulative',
last_update: moment(get_newest_date(locations)).format("YYYY-MM-DD HH:mm:ss:SSSS")
}),
contentType: "application/json; charset=utf-8",
dataType: 'json',
success: handleResponse,
error: function(error) {
console.log(error);
}
});
}
function handleResponse(data){
data.filter(item => item.latitude && item.longitude && item.timestamp_utc && item.username)
.forEach(function (item, index) {
if (item.username == '{{ player.user.name }}' && new Date(item.timestamp_utc) > get_newest_date(locations) ){
lastItem = locations[locations.length-1]
if (lastItem.latitude == item.latitude && lastItem.longitude == item.longitude){
lastItem.timestamp_utc = item.timestamp_utc
} else{
locations.push(item)
}
}
}); });
updatePolyline()
updateMarkers()
} }
//Ajax for Generate Code button //Ajax for Generate Code button

Loading…
Cancel
Save