refactor: planning

This commit is contained in:
mco-system 2023-04-16 18:38:01 +11:00
parent 45ea9077a4
commit 9d52c03cc8
8 changed files with 152 additions and 278 deletions

View File

@ -14,7 +14,7 @@ log:
handlers: [wsgi]
propagate: no
root:
level: INFO
level: DEBUG
handlers: [wsgi]
app:
secret_key: xxx

View File

@ -24,7 +24,6 @@ class AppConfig:
# ------------------------------------------------------------------------------
logger = logging.getLogger('wsgi')
app = Flask(__name__)
minify(app=app, html=True, js=True, cssless=True)
# ------------------------------------------------------------------------------
# -- Local configuration
@ -45,6 +44,8 @@ except Exception as err:
logger.critical("[{}] {}".format(err.__class__, str(err)))
sys.exit(1)
if app.local_config["log"]["root"]["level"] != "DEBUG":
minify(app=app, html=True, js=True, cssless=True)
# ------------------------------------------------------------------------------
# -- Tools
@ -56,6 +57,15 @@ def page_not_found(err):
def get_slots():
return backend.get(endpoint=f"events/{app.local_config['pretalx']['event']}/schedules/{app.local_config['pretalx']['schedule']}").json()
def get_speaker_biography(name):
try:
speaker_info = backend.get(endpoint=f"events/{app.local_config['pretalx']['event']}/speakers/", params={"q": name}).json()
logging.info(speaker_info)
return speaker_info["results"][0]["biography"].strip()
except Exception as err:
logging.error(f"UnknownSpeakerError: {name}")
return None
# ------------------------------------------------------------------------------
# -- Custom filters
# ------------------------------------------------------------------------------
@ -107,6 +117,9 @@ def index():
@app.route('/planning', methods=['GET'])
def planning():
slots = get_slots()
for slot in slots["slots"]:
for speaker in slot["speakers"]:
speaker["biography"] = get_speaker_biography(speaker["name"])
return render_template("planning.html",
slots=sorted(slots["slots"],
key=lambda slot: slot["slot"]["start"]),

View File

@ -1,225 +0,0 @@
@media screen and (min-width: 45em) {
.slot {
display: flex;
flex: 1;
justify-content: center;
text-align: center;
flex-direction: row;
margin: 0.3em 0;
width: 20em;
}
.slot_info .details {
visibility: hidden;
font-weight: bold;
background-color: var(--main-color);
color: var(--alt-main-color);
text-align: left;
padding: 1em;
border-radius: 6px;
position: absolute;
z-index: 1;
bottom: 0;
left: 0;
opacity: 0;
transition: opacity 1s;
transform: translateX(-2em) translateY(102%);
width: 27.5em;
overflow-y: auto;
border-style: solid;
border-color: var(--alt-main-color);
border-width: 1px;
}
}
@media screen and (max-width: 44em) {
.slot {
display: flex;
flex: 1;
justify-content: center;
text-align: center;
flex-direction: row;
margin: 0.3em 0;
width: 21em;
}
.slot_info .details {
visibility: hidden;
font-weight: bold;
background-color: var(--main-color);
color: var(--alt-main-color);
text-align: left;
padding: 1em;
border-radius: 6px;
position: absolute;
z-index: 1;
bottom: 0;
left: 0;
opacity: 0;
transition: opacity 1s;
transform: translateX(-2em) translateY(102%);
width: 28em;
overflow-y: auto;
border-style: solid;
border-color: var(--alt-main-color);
border-width: 1px;
}
}
.slot_info,
.slot_info_buttons {
display: flex;
flex-direction: row;
align-content: flex-start;
}
.metadata, .data {
display: flex;
flex-direction: column;
justify-content: start;
align-content: flex-start;
padding: 0.5em;
border-style: solid;
}
.metadata {
width: 7em;
border-radius: 10px 0 0 10px;
color: var(--main-color);
font-family: pfdintextcompprothin;
border-width: 1px 0 0px 1px;
text-align: left;
}
.data {
width: 14em;
background-color: var(--main-color);
color: var(--alt-main-color);
border-color: var(--main-color);
border-width: 1px 1px 1px 0;
font-family: pfdintextcompprothin;
text-align: left;
}
.metadata > .slot_info_buttons > .button,
.metadata > .slot_info_buttons > .slot_info > .button {
font-size: 1em;
margin-right: 0.3em;
}
.title {
font-family: pfdintextcompprothin;
font-weight: bold;
margin-bottom: 0.5em;
}
.speakers {
font-family: pfdintextcompprothin;
font-weight: bold;
margin-bottom: 0.2em;
}
.speaker {
position: relative;
display: inline-block;
}
.speaker_details:hover {
cursor: pointer;
}
.speaker .details {
visibility: hidden;
background-color: var(--main-color);
color: var(--alt-main-color);
text-align: left;
padding: 1em;
border-radius: 6px;
position: absolute;
z-index: 1;
bottom: 0;
left: 0;
opacity: 0;
transition: opacity 1s;
transform: translateY(102%);
overflow-y: auto;
border-style: solid;
border-color: var(--alt-main-color);
border-width: 1px;
}
.speaker .details::after {
content: "";
position: relative;
margin-left: -5px;
border-width: 5px;
}
.speaker:hover .details {
visibility: visible;
opacity: 1;
font-size: 0.7em;
padding: 0.2em;
}
.speaker > .details > img,
.abstract > img {
max-width: 200px;
max-height: 200px;
float: left;
margin: 0 0.5em 0.5em 0;
}
.speaker > .details > p {
text-align: justify;
font-size: 0.5em;
}
.slot_info {
position: relative;
}
.slot_info .details > .description {
margin-top: 1em;
}
.slot_info .details::after {
content: "";
position: relative;
margin-left: -5px;
border-width: 5px;
}
.slot_info:hover .details {
visibility: visible;
opacity: 1;
font-size: 0.7em;
padding: 0.2em;
}
.slot_info > .details > img,
.abstract > img {
max-width: 200px;
max-height: 200px;
float: left;
margin: 0 0.5em 0.5em 0;
}
.slot_info > .details > p {
text-align: justify;
font-size: 0.5em;
}
.abstract > p {
text-align: justify;
font-size: 1em;
}
.data > .details {
font-family: pfdintextcompprothin;
font-weight: bold;
margin-bottom: 0.2em;
font-size: 0.8em;
}
.data > .resources > .resource > a {
color: var(--main-bg-color);
}

View File

@ -0,0 +1,66 @@
.slot {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
align-content: center;
margin-bottom: 1em;
width: 20em;
}
.slot_header {
margin: 0;
width: 20em;
font-family: pfdintextcompprothin;
font-weight: bold;
}
.slot_title {
border-radius: 1em 0 0 0;
color: var(--main-color);
padding: 0.5em;
text-align: center;
display: flex;
flex-direction: row;
justify-content: flex-start;
align-content: flex-start;
align-items: flex-start;
width: 20em;
cursor: pointer;
}
.slot_title .title{
margin-left: 0.5em;
}
.slot_info {
background-color: var(--main-color);
color: var(--alt-main-color);
margin: 0;
padding: 0.5em;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-content: flex-start;
align-items: flex-start;
border-radius: 0 0 0 1em;
}
.speaker {
cursor: pointer;
}
.speakers > .speaker > .name > span {
text-decoration: underline;
}
.speaker_details,
.slot_details {
visibility: hidden;
display: none;
}
.speaker_img,
.slot_img {
width: 18em;
}

View File

@ -0,0 +1,14 @@
function switch_visibility(item){
console.log(item.style.visibility);
console.log(item.style.display);
if (item.style.visibility == "hidden" || item.style.display == "none") {
item.style.visibility = "visible";
item.style.display = "block";
} else if (item.style.visibility == "" && item.style.display == "") {
item.style.visibility = "visible";
item.style.display = "block";
} else {
item.style.visibility = "hidden";
item.style.display = "none";
}
}

View File

@ -4,6 +4,7 @@
<title>THSF 2023: S/Extraire</title>
<meta name="viewport" content="initial-scale=1.0">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<script src="{{ url_for('static', filename='scripts/thsf23.js') }}"></script>
<link rel="stylesheet"
href="{{ url_for('static', filename='css/colors.css') }}">
<link rel="stylesheet"
@ -19,7 +20,7 @@
<link rel="stylesheet"
href="{{ url_for('static', filename='css/tooltip.css') }}">
<link rel="stylesheet"
href="{{ url_for('static', filename='css/planning.css') }}">
href="{{ url_for('static', filename='css/slot.css') }}">
<link rel="icon"
type="image/png"
href="{{ url_for('static', filename='images/favicon.png') }}">

View File

@ -2,7 +2,6 @@
{% block content %}
<div class="content">
{% for slot in slots %}
{% set index = loop.index %}
{% if filter %}
{% if slot.submission_type.en | lower in filter %}
{% include "slot.html" %}

View File

@ -1,58 +1,64 @@
<div class="slot">
<div class="metadata {{ slot.slot.start | date2dayclass}}">
<div class="speakers">
{% for speaker in slot.speakers %}
<div class="speaker">
{{speaker.name | title}}
{% if speaker.avatar or speaker.biography %}
<i class="speaker_details fa-solid fa-user"></i>
<div class="details">
{% if speaker.avatar %}
<img src="{{speaker.avatar}}"
alt=""
title="">
{% endif %}
{% if speaker['biography'] %}
<p class="thin">{{speaker.biography}}</p>
{% endif %}
</div>
{% endif %}
</div><br>
{% endfor %}
<div class="slot_header">
<div class="slot_title {{ slot.slot.start | date2dayclass}}"
onclick="switch_visibility(document.getElementById('{{slot.code}}'))">
<i class="black {{slot.submission_type.fr | toicon }}"></i>
<span class="title">{{slot.title}}</span>
</div>
<div class="slot_info_buttons">
<i class="button slot_tooltip black {{slot.submission_type.fr | toicon }}">
<span class="slot_tooltiptext thin">
{{slot.submission_type.fr}}
</span>
</i>
<div class="slot_info">
<i class="button slot_info_details black fa-solid fa-circle-info"></i>
<div id="detail_{{index}}"
class="details thin">
<div class="abstract">
{% if slot['image'] %}
<img class="data_img"
src="{{slot.image}}"
alt=""
title="">
<div class="slot_info">
<div class="start">
<i class="fa-solid fa-caret-right"></i>
{{slot.slot.start | date2dmyhm}} - {{slot.duration}} minutes ({{slot.content_locale | capitalize}})
</div>
<div class="room">
<i class="fa-solid fa-caret-right"></i>
{{slot.slot.room.fr}}
</div>
<div class="speakers">
{% for speaker in slot.speakers %}
<div class="speaker">
<div class="name" onclick="switch_visibility(document.getElementById('{{speaker.code}}'))">
<i class="fa-solid fa-user"></i>
<span>{{speaker.name | title}}</span>
</div>
{% if speaker.avatar or speaker.biography %}
<div id="{{speaker.code}}" class="speaker_details">
{% if speaker.avatar %}
<div class="speaker_avatar">
<img class="speaker_img"
src="{{speaker.avatar}}"
alt="{{speaker.name | title}}"
title="{{speaker.name | title}}">
</div>
{% endif %}
{% if speaker.biography %}
<div class="speaker_biography">
<div class="speaker_biography">
{{ speaker.biography }}
</div>
</div>
{% endif %}
</div>
{% endif %}
<p>{{slot.abstract}}</p>
</div>
<div class="description">
{{slot.description}}
</div>
{% endfor %}
</div>
<div id="{{slot.code}}" class="slot_details">
<div class="abstract">
{% if slot.image %}
<img class="slot_img"
src="{{slot.image}}"
alt="{{slot.name}}"
title="{{slot.name}}">
{% endif %}
{% if slot.abstract %}
<p>{{slot.abstract}}</p>
{% endif %}
{% if slot.description %}
<p>{{slot.description}}</p>
{% endif %}
</div>
</div>
</div>
</div>
<div class="data">
<div class="details">
<div class="title black">
{{slot.title}}
</div>
<div class="room"><i class="fa-solid fa-caret-right"></i> {{slot.slot.room.fr}}</div>
<div class="start"><i class="fa-solid fa-caret-right"></i> {{slot.slot.start | date2dmyhm}} - {{slot.duration}} minutes ({{slot.content_locale | capitalize}})</div>
</div>
</div>
</div>