Bug fixes and improved handling of event editor.

This commit is contained in:
2019-10-18 22:00:52 +02:00
parent 56477948fc
commit 79d1bbbc46
12 changed files with 183 additions and 44 deletions

View File

@@ -1,4 +1,4 @@
from estusshots.orm import new_session, EventType, Season, Player, Drink, Enemy
from estusshots.orm import new_session, EventType, Season, Player, Drink, Enemy, Episode
def event_choices():
@@ -26,6 +26,13 @@ def player_choice():
return [(p.id, p.name) for p in players]
def player_choice_for_episode(episode: Episode):
"""
Create a list of ids and names for players of this episode
"""
return [(p.id, p.name) for p in episode.players]
def drink_choice():
"""
Query database for a list of all available drinks to select from

View File

@@ -1,17 +0,0 @@
class EditorModule{
setCurrentTime = (elemId: string) => {
const elem = document.getElementById(elemId) as HTMLInputElement;
if (!elem) return;
elem.value = this.currentTimeHHMM()
};
currentTimeHHMM = () => {
const d = new Date();
const hours = (d.getHours()<10 ? '0' : '') + d.getHours();
const minutes = (d.getMinutes()<10 ? '0' : '') + d.getMinutes();
return `${hours}:${minutes}`;
};
}
const editorModule = new EditorModule();

View File

@@ -17,4 +17,42 @@ var EditorModule = (function () {
return EditorModule;
}());
var editorModule = new EditorModule();
HTMLElement.prototype.addClass = function (cssClass) {
if (!this.classList.contains(cssClass)) {
this.classList.add(cssClass);
}
};
HTMLElement.prototype.removeClass = function (cssClass) {
if (this.classList.contains(cssClass)) {
console.log(this.classList);
this.classList.remove(cssClass);
}
};
var EventEditor;
(function (EventEditor) {
EventEditor.updateControls = function () {
var typeSelect = document.getElementById("event_type");
var selectedType = typeSelect.options[typeSelect.selectedIndex].value;
var penalties = document.querySelector(".penalty-container");
var player = document.getElementById("player_row");
var enemy = document.getElementById("enemy_row");
switch (selectedType) {
case "0":
penalties.addClass("d-none");
player.addClass("d-none");
enemy.addClass("d-none");
break;
case "1":
penalties.removeClass("d-none");
player.removeClass("d-none");
enemy.removeClass("d-none");
break;
case "2":
penalties.addClass("d-none");
player.removeClass("d-none");
enemy.removeClass("d-none");
break;
}
};
})(EventEditor || (EventEditor = {}));
//# sourceMappingURL=estus-shots.js.map

View File

@@ -1 +1 @@
{"version":3,"file":"estus-shots.js","sourceRoot":"","sources":["../../estus-shots.ts"],"names":[],"mappings":"AAAA;IAAA;QAAA,iBAcC;QAZC,mBAAc,GAAG,UAAC,MAAc;YAC9B,IAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAqB,CAAC;YACjE,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,IAAI,CAAC,KAAK,GAAG,KAAI,CAAC,eAAe,EAAE,CAAA;QACrC,CAAC,CAAC;QAEF,oBAAe,GAAG;YAChB,IAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;YACrB,IAAM,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC1D,IAAM,OAAO,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,GAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC;YAChE,OAAU,KAAK,SAAI,OAAS,CAAC;QAC/B,CAAC,CAAC;IACJ,CAAC;IAAD,mBAAC;AAAD,CAAC,AAdD,IAcC;AAED,IAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"}
{"version":3,"file":"estus-shots.js","sourceRoot":"","sources":["estus-shots.ts"],"names":[],"mappings":"AAAA;IAAA;QAAA,iBAcC;QAZC,mBAAc,GAAG,UAAC,MAAc;YAC9B,IAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAqB,CAAC;YACjE,IAAI,CAAC,IAAI;gBAAE,OAAO;YAClB,IAAI,CAAC,KAAK,GAAG,KAAI,CAAC,eAAe,EAAE,CAAA;QACrC,CAAC,CAAC;QAEF,oBAAe,GAAG;YAChB,IAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;YACrB,IAAM,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC1D,IAAM,OAAO,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,GAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC;YAChE,OAAU,KAAK,SAAI,OAAS,CAAC;QAC/B,CAAC,CAAC;IACJ,CAAC;IAAD,mBAAC;AAAD,CAAC,AAdD,IAcC;AAED,IAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;AAOxC,WAAW,CAAC,SAAS,CAAC,QAAQ,GAAG,UAAS,QAAgB;IACxD,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAC;QACrC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;KAC9B;AACH,CAAC,CAAC;AACF,WAAW,CAAC,SAAS,CAAC,WAAW,GAAG,UAAS,QAAgB;IAC3D,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAC;QACpC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC5B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;KACjC;AACH,CAAC,CAAC;AAEF,IAAU,WAAW,CAgCpB;AAhCD,WAAU,WAAW;IAER,0BAAc,GAAG;QAC1B,IAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,YAAY,CAAsB,CAAC;QAC9E,IAAM,YAAY,GAAG,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,KAAK,CAAC;QAExE,IAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,oBAAoB,CAAmB,CAAC;QACjF,IAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,CAAC,YAAY,CAAmB,CAAC;QACvE,IAAM,KAAK,GAAG,QAAQ,CAAC,cAAc,CAAC,WAAW,CAAmB,CAAC;QAErE,QAAQ,YAAY,EAAE;YAEpB,KAAK,GAAG;gBACN,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC7B,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC1B,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACzB,MAAM;YAEN,KAAK,GAAG;gBACN,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAChC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC7B,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC5B,MAAM;YAER,KAAK,GAAG;gBACN,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAC7B,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC7B,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;gBAC5B,MAAM;SACX;IACH,CAAC,CAAA;AAEH,CAAC,EAhCS,WAAW,KAAX,WAAW,QAgCpB"}

View File

@@ -0,0 +1,68 @@
class EditorModule{
setCurrentTime = (elemId: string) => {
const elem = document.getElementById(elemId) as HTMLInputElement;
if (!elem) return;
elem.value = this.currentTimeHHMM()
};
currentTimeHHMM = () => {
const d = new Date();
const hours = (d.getHours()<10 ? '0' : '') + d.getHours();
const minutes = (d.getMinutes()<10 ? '0' : '') + d.getMinutes();
return `${hours}:${minutes}`;
};
}
const editorModule = new EditorModule();
interface HTMLElement {
addClass(cssClass: string): void;
removeClass(cssClass: string): void;
}
HTMLElement.prototype.addClass = function(cssClass: string): void {
if (!this.classList.contains(cssClass)){
this.classList.add(cssClass);
}
};
HTMLElement.prototype.removeClass = function(cssClass: string): void {
if (this.classList.contains(cssClass)){
console.log(this.classList);
this.classList.remove(cssClass);
}
};
namespace EventEditor {
export let updateControls = () => {
const typeSelect = document.getElementById("event_type") as HTMLSelectElement;
const selectedType = typeSelect.options[typeSelect.selectedIndex].value;
const penalties = document.querySelector(".penalty-container") as HTMLDivElement;
const player = document.getElementById("player_row") as HTMLDivElement;
const enemy = document.getElementById("enemy_row") as HTMLDivElement;
switch (selectedType) {
// Pause
case "0":
penalties.addClass("d-none");
player.addClass("d-none");
enemy.addClass("d-none");
break;
// Death
case "1":
penalties.removeClass("d-none");
player.removeClass("d-none");
enemy.removeClass("d-none");
break;
// Victory
case "2":
penalties.addClass("d-none");
player.removeClass("d-none");
enemy.removeClass("d-none");
break;
}
}
}

View File

@@ -4,6 +4,12 @@
{% block title %}{{ model.page_title }} {{ super() }}{% endblock %}
{% block page %}
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function(event) {
EventEditor.updateControls();
});
</script>
<div class="text-center">
<h1>{{ model.form_title }}</h1>
@@ -27,7 +33,7 @@
{{ form.event_type.label(class_="form-control-label") }}
</div>
<div class="col-lg-10">
{{ form.event_type(class_="form-control") }}
{{ form.event_type(class_="form-control", onchange="EventEditor.updateControls()") }}
</div>
</div>
@@ -47,7 +53,7 @@
</div>
<div class="form-group row required">
<div id="player_row" class="form-group row required">
<div class="col-lg-2">
{{ form.player.label(class_="form-control-label") }}
</div>
@@ -56,7 +62,7 @@
</div>
</div>
<div class="form-group row required">
<div id="enemy_row" class="form-group row required">
<div class="col-lg-2">
{{ form.enemy.label(class_="form-control-label") }}
</div>
@@ -75,14 +81,19 @@
</div>
<div class="penalty-container">
<h4>Penalties</h4>
{% for penalty in form.penalties %}
{{ penalty.hidden_tag() }}
<div class="penalty-item">
<div class="form-group row">
{{ penalty.penalty_id }}
{{ penalty.player_id }}
{{ penalty.player }}
<label class="form-control-label">{{ penalty.player.data }}</label>
{{ penalty.drink }}
<div class="col-lg-2">
<label class="form-control-label">{{ penalty.player.data }}</label>
</div>
<div class="col-lg-10">
{{ penalty.drink(class_="form-control") }}
</div>
</div>
{% endfor %}
</div>

View File

@@ -40,24 +40,20 @@ def enemy_edit(enemy_id: int):
form_title="Edit Enemy",
post_url=f"/enemy/{enemy_id}/edit",
)
db = orm.new_session()
enemy = db.query(Enemy).get(enemy_id)
form = forms.EnemyForm()
if request.method == "GET":
db = orm.new_session()
enemy = db.query(Enemy).filter(Enemy.id == enemy_id).first()
form = forms.EnemyForm()
form.season_id.data = enemy.season_id if enemy.season_id else -1
form.name.data = enemy.name
form.is_boss.data = enemy.boss
form.enemy_id.data = enemy_id
model.form_title = f'Edit Enemy "{enemy.name}"'
return render_template("generic_form.html", model=model, form=form)
else:
form = forms.EnemyForm()
if form.validate_on_submit():
db = orm.new_session()
enemy = db.query(Enemy).filter(Enemy.id == enemy_id).first()
if not enemy:
enemy = Enemy()
db.add(enemy)

View File

@@ -86,4 +86,4 @@ def episode_edit(season_id: int, episode_id: int):
if errors:
model.errors = {"Error saving episode": [errors]}
return render_template("generic_form.html", model=model, form=form)
return redirect(url_for("episode_detail", season_id=season_id, episode_id=episode_id))
return redirect(url_for("episode_detail", season_id=season.id, episode_id=episode.id))

View File

@@ -60,6 +60,7 @@ def event_new(s_id: int, ep_id: int):
form = forms.EventForm()
form.episode_id.data = ep_id
form.enemy.choices = choices.enemy_choice_for_season(s_id)
form.player.choices = choices.player_choice_for_episode(episode)
form.event_type.data = EventType.Death.value
Penalty = namedtuple("Penalty", ["penalty_id", "player_id", "player", "drink"])

View File

@@ -26,27 +26,26 @@ def player_edit(player_id: int):
form_title=f"Edit Player",
post_url=f"/player/{player_id}/edit",
)
db = orm.new_session()
player = db.query(Player).filter(Player.id == player_id).first()
form = forms.PlayerForm()
# Edit Existing Player
if request.method == "GET":
db = orm.new_session()
player = db.query(Player).filter(Player.id == player_id).first()
form = forms.PlayerForm()
form.player_id.data = player.id
form.anonymize.data = player.anon
form.real_name.data = player.real_name
form.alias.data = player.alias
form.hex_id.data = player.hex_id
model.form_title = f'Edit Player "{player.name}"'
return render_template("generic_form.html", model=model, form=form)
# Save POSTed data
else:
form = forms.PlayerForm()
if form.validate_on_submit():
db = orm.new_session()
player = db.query(Player).filter(Player.id == player_id).first()
if not player:
player = Player()
db.add(player)
player.populate_from_form(form)
db.commit()
return redirect("/player")

37
static/js/estus-shots.js Normal file
View File

@@ -0,0 +1,37 @@
var EditorModule = /** @class */ (function () {
function EditorModule() {
var _this = this;
this.setCurrentTime = function (elemId) {
var elem = document.getElementById(elemId);
if (!elem)
return;
elem.value = _this.currentTimeHHMM();
};
this.currentTimeHHMM = function () {
var d = new Date();
var hours = (d.getHours() < 10 ? '0' : '') + d.getHours();
var minutes = (d.getMinutes() < 10 ? '0' : '') + d.getMinutes();
return hours + ":" + minutes;
};
}
return EditorModule;
}());
var editorModule = new EditorModule();
var EventEditor;
(function (EventEditor) {
EventEditor.updateControls = function () {
var typeSelect = document.getElementById("event_type");
var selectedType = typeSelect.options[typeSelect.selectedIndex].value;
switch (selectedType) {
case "0":
console.log("Pause");
break;
case "1":
break;
case "2":
break;
default:
console.log("Unknown event type: " + selectedType);
}
};
})(EventEditor || (EventEditor = {}));

View File

@@ -4,10 +4,9 @@
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": true,
"outDir": "./estusshots/static/js"
"sourceMap": true
},
"include": [
"**/*.ts"
],
]
}