Browse Source

[WIP] Adding support for updates via Javascript instead of forms.

feature/js
Daniel Perelman 2 years ago
parent
commit
f8f963ce51
3 changed files with 109 additions and 32 deletions
  1. +32
    -10
      fear_tracker/templates/game.html
  2. +2
    -0
      fear_tracker/urls.py
  3. +75
    -22
      fear_tracker/views.py

+ 32
- 10
fear_tracker/templates/game.html View File

@@ -2,13 +2,13 @@

{% block content %}
<header>
<div class="phase">{{ phase }} phase of turn #{{ turn }}</div>
<div class="phase">{{ status.phase }} phase of turn #{{ status.turn }}</div>
<div class="fear_summary">
<span class="available_fear_cards">{{ available_fear_cards }}</span>
<span class="available_fear_cards">{{ status.available_fear_cards }}</span>
😱🎴;
<span class="fear_to_next_card">{{ fear_to_next_card }}</span>
<span class="fear_to_next_card">{{ status.fear_to_next_card }}</span>
😱 to next 😱🎴;
<span class="fear_this_phase">{{ fear_this_phase }}</span>
<span class="fear_this_phase">{{ status.fear_this_phase }}</span>
😱 this phase
</div>
<div class="access-code">
@@ -24,9 +24,9 @@
</div>
<form action="#" method="POST">
{% csrf_token %}
<input type="hidden" name="game_turn" value="{{ turn }}">
<input type="hidden" name="game_phase" value="{{ phase_id }}">
<input type="hidden" name="phase_name" value="{{ phase }} phase of turn #{{ turn }}">
<input type="hidden" name="game_turn" value="{{ status.turn }}">
<input type="hidden" name="game_phase" value="{{ status.phase_id }}">
<input type="hidden" name="phase_name" value="{{ status.phase }} phase of turn #{{ status.turn }}">
<div class="players">
{% for order, player in players.items %}
<div class="player player-{{ player.order }}">
@@ -91,9 +91,31 @@
{% endfor %}
</div>
<input type="submit" name="update" value="Update fear">
{% if all_ready %}
<input type="submit" name="advance" value="Advance to next phase">
{% endif %}
<input type="submit" name="advance" value="Advance to next phase"{% if not all_ready %} disabled{% endif %}>
<input type="submit" name="revert" value="Revert to previous phase">
</form>
{% block game_refresh %}
{% if not results_only %}
<div class="button-container">
<a href="{% url 'game' access_code=access_code %}" class="button" id="button-refresh">Refresh</a>
</div>
<script>
var statusObj = JSON.parse("{{ status_json|escapejs }}");
function handleNewStatus(oldStatus, newStatus) {
{% block game_handle_new_status %}
return false;
{% endblock %}
}
setInterval(function() {
$.get("{% url 'status' access_code=access_code hash=status.hash %}", function(data, textStatus, jqXHR) {
if(JSON.stringify(data) != JSON.stringify(statusObj)) {
if(!handleNewStatus(statusObj, data)) {
document.getElementById("button-refresh").click();
}
}
}, "json");
}, 5000);
</script>
{% endif %}
{% endblock %}
{% endblock %}

+ 2
- 0
fear_tracker/urls.py View File

@@ -26,5 +26,7 @@ urlpatterns = [
path('', views.game, name='game'),
path('qr/', views.qr_code, name='qr_code'),
path('status/', views.status, name='status'),
url('^status/(?P<hashcode>[a-z0-9]{64})/',
views.status, name='status'),
])),
]

+ 75
- 22
fear_tracker/views.py View File

@@ -1,5 +1,7 @@
from collections import OrderedDict
from io import BytesIO
import hashlib
import json
import qrcode

from django.db import transaction
@@ -89,17 +91,77 @@ def qr_code(request, access_code):
return HttpResponse(output.getvalue(), content_type='image/png')


@transaction.atomic
@lookup_access_code
@require_http_methods(["HEAD", "GET", "POST"])
def game(request, game):
def load_players(game):
players = OrderedDict()
for player in game.player_set.order_by('order').all():
player.total_fear = 0
player.changed_to_ready = False
player.fear = OrderedDict()
players[player.order] = player

return players


def get_players_with_fear(game, current_phase=None, players=None):
if players is None:
players = load_players(game)
if current_phase is None:
current_phase = game.get_current_phase()

for fear in current_phase.fear_set.order_by('effect').all():
players[fear.player.order].fear[fear.effect] = {
'pure_fear': fear.pure_fear,
'towns': fear.towns_destroyed,
'cities': fear.cities_destroyed,
}
players[fear.player.order].total_fear +=\
fear.pure_fear + fear.towns_destroyed + 2*fear.cities_destroyed

return players


def game_status_object(game, current_phase=None, players_with_fear=None):
if current_phase is None:
current_phase = game.get_current_phase()
if players_with_fear is None:
players_with_fear = get_players_with_fear(game, current_phase)

players = OrderedDict()
for order, player in players.items():
players[order] = {
'ready': player.ready,
'fear': player.fear,
'total_fear': player.total_fear
}

status_obj = {
'turn': game.game_turn,
'phase': game.get_current_phase_name(),
'phase_id': game.game_phase,
'available_fear_cards': game.num_available_fear_cards(),
'fear_to_next_card': game.get_fear_to_next_card(),
'fear_this_phase': current_phase.fear_this_phase(),
'total_fear': game.get_current_total_fear(),
'players': players,
'all_ready': all(player.ready for player in players.values()),
}
h = hashlib.sha256()
h.update(json.dumps(status_obj).encode('utf-8'))
status_hash = h.hexdigest()
status_obj['hash'] = status_hash

return status_obj


@transaction.atomic
@lookup_access_code
@require_http_methods(["HEAD", "GET", "POST"])
def game(request, game):
# TODO Should check if game is over and redirect to summary table view.

players = load_players(game)
for player in players.values():
player.changed_to_ready = False

errors = []
fear_kind_dict = {
'fear': 'pure_fear',
@@ -198,14 +260,10 @@ def game(request, game):
for player in players.values():
player.ready = True

for fear in current_phase.fear_set.order_by('effect').all():
players[fear.player.order].fear[fear.effect] = {
'pure_fear': fear.pure_fear,
'towns': fear.towns_destroyed,
'cities': fear.cities_destroyed,
}
players[fear.player.order].total_fear +=\
fear.pure_fear + fear.towns_destroyed + 2*fear.cities_destroyed
players = get_players_with_fear(game, current_phase, players)
status_obj = game_status_object(game, current_phase, players)
status_string = json.dumps(status_obj)

for player in players.values():
info = player.fear
if not info:
@@ -217,17 +275,12 @@ def game(request, game):
'towns': 0,
'cities': 0,
}

return render(request, 'game.html', {
'access_code': game.access_code,
'turn': game.game_turn,
'phase': game.get_current_phase_name(),
'phase_id': game.game_phase,
'available_fear_cards': game.num_available_fear_cards(),
'fear_to_next_card': game.get_fear_to_next_card(),
'fear_this_phase': current_phase.fear_this_phase(),
'total_fear': game.get_current_total_fear(),
'status': status_obj,
'status_json': status_string,
'players': players,
'all_ready': all(player.ready for player in players.values()),
'range': range(21),
'errors': errors,
})
@@ -235,6 +288,6 @@ def game(request, game):

@lookup_access_code
@require_safe
def status(request, game):
def status(request, game, hashcode=None):
# TODO status json
pass

Loading…
Cancel
Save