Browse Source

auto update players on map owner dashboard

testing
Burathar 4 years ago
parent
commit
8dda257a6f
  1. 5
      app/main/routes.py
  2. 3
      app/models/game.py
  3. 1
      app/models/user.py
  4. 37
      app/static/assets/leaflet/utils.js
  5. 56
      app/templates/game_owner_dashboard.html
  6. 57
      app/templates/game_player.html

5
app/main/routes.py

@ -145,7 +145,10 @@ def get_user_locations(game, username, mode, last_update):
if mode == 'accumulative': if mode == 'accumulative':
if game.end_time < last_update: if game.end_time < last_update:
return [] return []
return [location for location in user.locations_during_game(game) if location.timestamp - last_update > timedelta(milliseconds=1)] locations = user.locations_during_game(game)
if not locations:
return None
return [location for location in locations if location.timestamp - last_update > timedelta(milliseconds=1)]
@bp.route('/user/<username>') @bp.route('/user/<username>')
@login_required @login_required

3
app/models/game.py

@ -32,6 +32,9 @@ class Game(db.Model):
backref=db.backref('game', lazy='joined'), backref=db.backref('game', lazy='joined'),
cascade="save-update, merge, delete, delete-orphan") cascade="save-update, merge, delete, delete-orphan")
def usernames(self):
return [user.name for user in self.users]
def last_player_locations(self, offset=None): def last_player_locations(self, offset=None):
# pylint: disable=not-an-iterable # pylint: disable=not-an-iterable
return [location for location in return [location for location in

1
app/models/user.py

@ -24,7 +24,6 @@ class User(UserMixin, db.Model):
games = association_proxy('user_games', 'game', games = association_proxy('user_games', 'game',
creator=lambda game: GamePlayer(game=game)) creator=lambda game: GamePlayer(game=game))
locations = db.relationship( locations = db.relationship(
'Location', 'Location',
lazy='select', lazy='select',

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

@ -89,3 +89,40 @@ function getMap(){
}).addTo( map ); }).addTo( map );
return map return map
} }
var csrftoken = $('meta[name=csrf-token]').attr('content')
$.ajaxSetup({
beforeSend: function(xhr, settings) {
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken)
}
}
})
function pollLocations(url, requestedUsers, mode, playerLocations, responseHandler) {
$.ajax({
type: "POST",
url: url,
data: JSON.stringify({
requested_users: requestedUsers,
mode: mode,
last_update: moment(get_latest_date(playerLocations)).format("YYYY-MM-DD HH:mm:ss:SSSS")
}),
contentType: "application/json; charset=utf-8",
dataType: 'json',
success: function(data){
responseHandler(
data.filter(item => item.latitude && item.longitude && item.timestamp_utc && item.username)
)
},
error: function(error) {
console.log(error);
}
});
}
function get_latest_date(playerLocations){
return new Date(Math.max.apply(null, playerLocations.map(function(e) {
return new Date(e.timestamp_utc);
})));
}

56
app/templates/game_owner_dashboard.html

@ -4,10 +4,10 @@
{{ super() }} {{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='assets/leaflet/leaflet.css') }}" /> <link rel="stylesheet" href="{{ url_for('static', filename='assets/leaflet/leaflet.css') }}" />
<script src="{{ url_for('static', filename='assets/leaflet/leaflet.js') }}"></script> <script src="{{ url_for('static', filename='assets/leaflet/leaflet.js') }}"></script>
<script src="{{ url_for('static', filename='assets/leaflet/utils.js') }}"></script>
{% endblock %} {% endblock %}
{% block app_content %} {% block app_content %}
<meta name="csrf-token" content="{{ csrf_token() }}">
<h1>{{ game.name }} Dashboard</h1> <h1>{{ game.name }} Dashboard</h1>
<a href="{{ url_for('game.change_game_settings', game_name=game.name) }}"> <a href="{{ url_for('game.change_game_settings', game_name=game.name) }}">
<button class="btn btn-primary">Change Game Settings</button> <button class="btn btn-primary">Change Game Settings</button>
@ -97,25 +97,65 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src="{{ url_for('static', filename='assets/leaflet/utils.js') }}"></script>
<script type="text/javascript", crossorigin="anonymous"> <script type="text/javascript", crossorigin="anonymous">
// Leaflet Map // Leaflet Map
map = getMap() var map = getMap()
markers = [] var objectMarkers = []
var playerMarkers = []
var objectives = JSON.parse('{{ json.dumps(game.objectives, cls=objective_encoder)|safe }}') var objectives = JSON.parse('{{ json.dumps(game.objectives, cls=objective_encoder)|safe }}')
for (var i = 0; i < objectives.length; i++){ for (var i = 0; i < objectives.length; i++){
addObjectiveMarker(map, objectives[i]) addObjectiveMarker(map, objectives[i])
markers.push([objectives[i].latitude, objectives[i].longitude]) objectMarkers.push([objectives[i].latitude, objectives[i].longitude])
} }
var players = JSON.parse('{{ json.dumps(game.last_player_locations(), cls=location_encoder)|safe }}') var players = JSON.parse('{{ json.dumps(game.last_player_locations(), cls=location_encoder)|safe }}')
updatePlayerMarkers()
if (objectMarkers.length + playerMarkers.length > 0) {
map.fitBounds(objectMarkers.concat(playerMarkers));
}
function updatePlayerMarkers(){
if(playerMarkers != undefined){
playerMarkers.forEach(function(marker){
marker.remove()
});
}
playerMarkers = []
for (var i = 0; i < players.length; i++) { for (var i = 0; i < players.length; i++) {
addPlayerMarker(map, players[i]) playerMarkers.push(addPlayerMarker(map, players[i], bluePlayerIcon))
markers.push([players[i].latitude, players[i].longitude]) }
} }
if (markers.length > 0) { // Poll Locations
map.fitBounds(markers); usernames = JSON.parse('{{ json.dumps(game.usernames())|safe }}')
setInterval(function() {
pollLocations(
"{{ url_for('main.poll_locations', game_name=game.name) }}",
usernames,
'accumulative',
players,
handleResponse
)}, 30 * 1000);
function handleResponse(data){
data.forEach(function (location) {
player = players.filter(function (player) {
return player.username == location.username;
})[0];
if (new Date(location.timestamp_utc) > new Date(player.timestamp_utc)){
//lastLocation = player[player.length-1] Not necesary because there is just one of each player
if (player.latitude == location.latitude && player.longitude == location.longitude){
player.timestamp_utc = location.timestamp_utc
} else{
players = players.filter(p => p !== player)
players.push(location)
}
}
});
updatePlayerMarkers()
} }
</script> </script>

57
app/templates/game_player.html

@ -5,7 +5,6 @@
{{ super() }} {{ super() }}
<link rel="stylesheet" href="{{ url_for('static', filename='assets/leaflet/leaflet.css') }}" /> <link rel="stylesheet" href="{{ url_for('static', filename='assets/leaflet/leaflet.css') }}" />
<script src="{{ url_for('static', filename='assets/leaflet/leaflet.js') }}"></script> <script src="{{ url_for('static', filename='assets/leaflet/leaflet.js') }}"></script>
<script src="{{ url_for('static', filename='assets/leaflet/utils.js') }}"></script>
{% endblock %} {% endblock %}
{% block app_content %} {% block app_content %}
@ -74,6 +73,7 @@
{% block scripts %} {% block scripts %}
{{ super() }} {{ super() }}
<script src="{{ url_for('static', filename='assets/leaflet/utils.js') }}"></script>
<script type="text/javascript" , crossorigin="anonymous"> <script type="text/javascript" , crossorigin="anonymous">
// Leaflet Map // Leaflet Map
map = getMap() map = getMap()
@ -120,51 +120,24 @@
} }
// Poll Locations // Poll Locations
var csrftoken = $('meta[name=csrf-token]').attr('content')
$.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()}, 30 * 1000); setInterval(function() {
pollLocations(
function pollLocations() { "{{ url_for('main.poll_locations', game_name=player.game.name) }}",
$.ajax({ ['{{ player.user.name }}'],
type: "POST", 'accumulative',
url: "{{ url_for('main.poll_locations', game_name=player.game.name) }}", locations,
data: JSON.stringify({ handleResponse
)}, 30 * 1000);
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){ function handleResponse(data){
data.filter(item => item.latitude && item.longitude && item.timestamp_utc && item.username) data.forEach(function (location) {
.forEach(function (item, index) { if (location.username == '{{ player.user.name }}' && new Date(location.timestamp_utc) > get_latest_date(locations) ){
if (item.username == '{{ player.user.name }}' && new Date(item.timestamp_utc) > get_newest_date(locations) ){ lastLocation = locations[locations.length-1]
lastItem = locations[locations.length-1] if (lastLocation.latitude == location.latitude && lastLocation.longitude == location.longitude){
if (lastItem.latitude == item.latitude && lastItem.longitude == item.longitude){ lastLocation.timestamp_utc = location.timestamp_utc
lastItem.timestamp_utc = item.timestamp_utc
} else{ } else{
locations.push(item) locations.push(location)
} }
} }
}); });

Loading…
Cancel
Save