mirror of
https://github.com/godotengine/godot-showreel-voting.git
synced 2026-09-03 18:15:13 +03:00
add support for multiple store links
This commit is contained in:
@@ -26,6 +26,15 @@ def validate_urls(form, field):
|
||||
raise ValidationError(f'Invalid URL: {field.data}')
|
||||
|
||||
|
||||
def validate_store_urls(form, field):
|
||||
# Form is submitted with format: "url1;url2;url3"
|
||||
if field.data:
|
||||
urls = field.data.split(';')
|
||||
for url in urls:
|
||||
parsed = urlparse(url)
|
||||
if not all([parsed.scheme, parsed.netloc]):
|
||||
raise ValidationError(f'Invalid URL: {url}')
|
||||
|
||||
class CastVoteForm(FlaskForm):
|
||||
action = StringField('Action', validators=[validate_action])
|
||||
video_id = IntegerField('Video ID', validators=[InputRequired()])
|
||||
@@ -42,7 +51,7 @@ class VideoSubmissionForm(FlaskForm):
|
||||
video_link = StringField('Video Link', validators=[InputRequired(), validate_urls]) # TODO: Check specific URL formats
|
||||
video_download_link = StringField('Video Download Link', validators=[InputRequired(), validate_urls])
|
||||
follow_me_link = StringField('Follow Me Link', validators=[InputRequired(), validate_urls])
|
||||
store_link = StringField('Store Link', validators=[InputRequired(), validate_urls])
|
||||
store_link = StringField('Store Link', validators=[InputRequired(), validate_store_urls])
|
||||
|
||||
|
||||
class ManageShowreelsForm(FlaskForm):
|
||||
|
||||
@@ -206,7 +206,7 @@ def download_vote_results():
|
||||
video.video_link,
|
||||
video.video_download_link,
|
||||
video.contact_email,
|
||||
video.store_link,
|
||||
'\n'.join(video.store_link.split(';')),
|
||||
extract_steam_app_id(video.store_link),
|
||||
plus_votes,
|
||||
minus_votes,
|
||||
@@ -237,7 +237,6 @@ def submit():
|
||||
current_app.logger.warning("No active showreel or multiple active showreels found.")
|
||||
error_template = render_template('error.html', title="Submissions Closed", message="Submissions are currently closed.")
|
||||
return render_template('default.html', content = error_template, user=g.user)
|
||||
|
||||
form = VideoSubmissionForm()
|
||||
content = render_template('submit.html', user=g.user, form=form)
|
||||
return render_template('default.html', content = content, user=g.user)
|
||||
@@ -246,7 +245,20 @@ def submit():
|
||||
@bp.route('/submit', methods=['POST'])
|
||||
@auth.login_required
|
||||
def post_submit():
|
||||
form = VideoSubmissionForm()
|
||||
formdata = request.form.copy()
|
||||
|
||||
links = [
|
||||
formdata.get("store_link", "").strip(),
|
||||
formdata.get("store_link_2", "").strip(),
|
||||
formdata.get("store_link_3", "").strip(),
|
||||
formdata.get("store_link_4", "").strip(),
|
||||
formdata.get("store_link_5", "").strip(),
|
||||
]
|
||||
|
||||
formdata["store_link"] = ";".join(link for link in links if link)
|
||||
|
||||
form = VideoSubmissionForm(formdata)
|
||||
|
||||
if not form.validate():
|
||||
return render_template('submit.html', user=g.user, form=form)
|
||||
|
||||
@@ -356,7 +368,18 @@ def update_submission(video_id: int):
|
||||
if video.showreel.status != ShowreelStatus.OPENED_TO_SUBMISSIONS:
|
||||
return render_template('error.html', title="Cannot Update Submission", message="Submissions can only be updated while the showreel is open to submissions.")
|
||||
|
||||
form = VideoSubmissionForm()
|
||||
formdata = request.form.copy()
|
||||
|
||||
links = [
|
||||
formdata.get("store_link", "").strip(),
|
||||
formdata.get("store_link_2", "").strip(),
|
||||
formdata.get("store_link_3", "").strip(),
|
||||
formdata.get("store_link_4", "").strip(),
|
||||
formdata.get("store_link_5", "").strip(),
|
||||
]
|
||||
|
||||
formdata["store_link"] = ";".join(link for link in links if link)
|
||||
form = VideoSubmissionForm(formdata, obj=video)
|
||||
if not form.validate():
|
||||
return render_template('update-submissions.html', user=g.user, submissions=[video], open_showreel=video.showreel, form=form)
|
||||
|
||||
|
||||
@@ -50,7 +50,16 @@
|
||||
{% endfor %}<br>
|
||||
|
||||
{{ form.store_link.label }}<br>
|
||||
<p class="info">We will use this to promote your game in future events and showcase pages.</p>
|
||||
{{ form.store_link(size=100) }}<br>
|
||||
<div id="store-link-extra-container">
|
||||
{% for i in range(2, 6) %}
|
||||
<div class="store-link-extra" id="store-link-{{ i }}-container" style="display: none;">
|
||||
<label for="store-link-{{ i }}">Additional Store Link {{ i }}</label><br>
|
||||
<input type="url" id="store-link-{{ i }}" name="store_link_{{ i }}" size="100"><br>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% for error in form.store_link.errors %}
|
||||
<p class="error">{{ error }}</p>
|
||||
{% endfor %}<br>
|
||||
@@ -98,4 +107,40 @@
|
||||
previewContainer.style.display = 'block';
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
// Handle multiple store links
|
||||
const storeLinks = [
|
||||
document.getElementById("store_link"),
|
||||
document.getElementById("store-link-2"),
|
||||
document.getElementById("store-link-3"),
|
||||
document.getElementById("store-link-4"),
|
||||
document.getElementById("store-link-5")
|
||||
];
|
||||
|
||||
function updateStoreLinkVisibility() {
|
||||
for (let i = 1; i < storeLinks.length; i++) {
|
||||
const container = document.getElementById(`store-link-${i + 1}-container`);
|
||||
container.style.display = storeLinks[i - 1].value.trim() ? "block" : "none";
|
||||
}
|
||||
}
|
||||
|
||||
storeLinks.forEach(link => {
|
||||
link.addEventListener("input", updateStoreLinkVisibility);
|
||||
});
|
||||
|
||||
// populate form fields with existing links
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
const existingLinks = {{ form.store_link.data|tojson }}.split(';');
|
||||
for (let i = 0; i < existingLinks.length && i < storeLinks.length; i++) {
|
||||
storeLinks[i].value = existingLinks[i];
|
||||
const container = document.getElementById(`store-link-${i + 2}-container`);
|
||||
container.style.display = storeLinks[i].value.trim() ? "block" : "none";
|
||||
}
|
||||
|
||||
updateStoreLinkVisibility();
|
||||
});
|
||||
</script>
|
||||
@@ -4,7 +4,7 @@
|
||||
<p>Fill in the form to submit your video for the Godot Showreel.</p>
|
||||
</div>
|
||||
<hr>
|
||||
<form method="POST" enctype="multipart/form-data" hx-post="{{ url_for("votes.post_submit", _method='POST') }}" hx-target='#submission-form' hx-swap='outerHTML'>
|
||||
<form id="submission-form" method="POST" enctype="multipart/form-data" hx-post="{{ url_for("votes.post_submit", _method='POST') }}" hx-target='#submission-form' hx-swap='outerHTML'>
|
||||
{{ form.csrf_token }}
|
||||
|
||||
{{ form.game.label }}<br>
|
||||
@@ -49,9 +49,18 @@
|
||||
<p class="error">{{ error }}</p>
|
||||
{% endfor %}<br>
|
||||
|
||||
{{ form.store_link.label }}
|
||||
{{ form.store_link.label }}<br>
|
||||
<p class="info">We will use this to promote your game in future events and showcase pages.</p>
|
||||
{{ form.store_link(size=100) }}<br>
|
||||
<div id="store-link-extra-container">
|
||||
{% for i in range(2, 6) %}
|
||||
<div class="store-link-extra" id="store-link-{{ i }}-container" style="display: none;">
|
||||
<label for="store-link-{{ i }}">Additional Store Link {{ i }}</label><br>
|
||||
<input type="url" id="store-link-{{ i }}" name="store_link_{{ i }}" size="100"><br>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{% for error in form.store_link.errors %}
|
||||
<p class="error">{{ error }}</p>
|
||||
{% endfor %}<br>
|
||||
@@ -100,4 +109,28 @@
|
||||
previewContainer.style.display = 'block';
|
||||
});
|
||||
})
|
||||
</script>
|
||||
|
||||
<script>
|
||||
// Handle multiple store links
|
||||
const storeLinks = [
|
||||
document.getElementById("store_link"),
|
||||
document.getElementById("store-link-2"),
|
||||
document.getElementById("store-link-3"),
|
||||
document.getElementById("store-link-4"),
|
||||
document.getElementById("store-link-5")
|
||||
];
|
||||
|
||||
function updateStoreLinkVisibility() {
|
||||
for (let i = 1; i < storeLinks.length; i++) {
|
||||
const container = document.getElementById(`store-link-${i + 1}-container`);
|
||||
container.style.display = storeLinks[i - 1].value.trim() ? "block" : "none";
|
||||
}
|
||||
}
|
||||
|
||||
storeLinks.forEach(link => {
|
||||
link.addEventListener("input", updateStoreLinkVisibility);
|
||||
});
|
||||
|
||||
updateStoreLinkVisibility();
|
||||
</script>
|
||||
@@ -105,11 +105,24 @@
|
||||
<h2>Submission info:</h2>
|
||||
<div class="col-2">
|
||||
<p class="truncate" title="{{ data.game }}">Project: <strong>{{ data.game }}</strong></p>
|
||||
<p>Video Link: <a href="{{ data.video_link }}" target="_blank">{{ data.video_link }}</a></p>
|
||||
<p>Author: <strong>{{ data.author }}</strong></p>
|
||||
<p>Store Link: <a href="{{ data.store_link }}" target="_blank">{{ data.store_link }}</a></p>
|
||||
<p>Category: <strong>{{ data.category }}</strong></p>
|
||||
|
||||
<p>Follow them: <a href="{{ data.follow_me_link }}" target="_blank">{{ data.follow_me_link }}</a></p>
|
||||
<p>Video Link: <a href="{{ data.video_link }}" target="_blank">{{ data.video_link }}</a></p>
|
||||
<div>
|
||||
<p>Store Links</p>
|
||||
{% set store_links = data.store_link.split(';') %}
|
||||
<ul>
|
||||
{% for link in store_links %}
|
||||
{% if link %}
|
||||
<li>
|
||||
<a href="{{ link }}" target="_blank">{{ link }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -136,11 +136,24 @@
|
||||
<h2>Submission info:</h2>
|
||||
<div class="col-2">
|
||||
<p class="truncate" title="{{ data.game }}">Project: <strong>{{ data.game }}</strong></p>
|
||||
<p>Video Link: <a href="{{ data.video_link }}" target="_blank">{{ data.video_link }}</a></p>
|
||||
<p>Author: <strong>{{ data.author }}</strong></p>
|
||||
<p>Store Link: <a href="{{ data.store_link }}" target="_blank">{{ data.store_link }}</a></p>
|
||||
<p>Category: <strong>{{ data.category }}</strong></p>
|
||||
|
||||
<p>Video Link: <a href="{{ data.video_link }}" target="_blank">{{ data.video_link }}</a></p>
|
||||
<p>Follow them: <a href="{{ data.follow_me_link }}" target="_blank">{{ data.follow_me_link }}</a></p>
|
||||
<div>
|
||||
<p>Store Links</p>
|
||||
{% set store_links = data.store_link.split(';') %}
|
||||
<ul>
|
||||
{% for link in store_links %}
|
||||
{% if link %}
|
||||
<li>
|
||||
<a href="{{ link }}" target="_blank">{{ link }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user