master
aeris 5 years ago
parent dfce46388b
commit e95f766883
  1. 2
      Gemfile
  2. 2
      Gemfile.lock
  3. 26
      source/index.html.erb
  4. 2
      source/index.ics.erb
  5. 89
      source/javascripts/site.js.coffee
  6. 166
      source/stylesheets/site.css.scss

@ -14,3 +14,5 @@ gem 'icalendar'
gem 'tzinfo-data', platforms: %i[mswin mingw jruby]
gem 'wdm', platforms: %i[mswin mingw]
gem 'betterlorem'

@ -34,6 +34,7 @@ GEM
execjs
awesome_print (1.8.0)
backports (3.11.1)
betterlorem (0.1.2)
bootstrap-sass (3.3.7)
autoprefixer-rails (>= 5.2.1)
sass (>= 3.3.4)
@ -176,6 +177,7 @@ PLATFORMS
DEPENDENCIES
actionmailer
awesome_print
betterlorem
bootstrap-sass
icalendar
middleman (~> 4.2)

@ -1,5 +1,5 @@
<%
planning = YAML.load File.read File.join Middleman::Application.root, 'config/2018.yml'
planning = YAML.load File.read File.join Middleman::Application.root, 'config/current.yml'
def parse_time(time)
hour, min = time.split ':'
@ -31,13 +31,13 @@
</thead>
<tbody>
<tr>
<td>
<th>
<ul>
<% (10..21).each do |hour| %>
<li data-time="<%= hour %>:00"><%= hour %>:00</li>
<% end %>
</ul>
</td>
</th>
<% planning.each do |_, events| %>
<% events.each do |_, events| %>
<td>
@ -76,17 +76,13 @@
</div>
</div>
<div class="modal">
<header class="header">
<div class="content">
<span class="date"></span>
<h3 class="name"></h3>
</div>
<div class="header-bg"></div>
</header>
<div class="body">
<div class="event-info"></div>
<div class="body-bg"></div>
<div class="modal hidden">
<div class="header">
<div class="time"></div>
<div class="title"></div>
<div class="author"></div>
</div>
<a href="#" class="close">Close</a>
<div class="body"></div>
<div class="close"></div>
<div class="cover"></div>
</div>

@ -7,7 +7,7 @@
Icalendar::Values::DateTime.new date
end
planning = YAML.load File.read File.join Middleman::Application.root, 'config/2018.yml'
planning = YAML.load File.read File.join Middleman::Application.root, 'config/current.yml'
cal = Icalendar::Calendar.new
cal.append_custom_property 'NAME', 'PSES 2018'

@ -1,5 +1,11 @@
class TimeTable
constructor: (@element) ->
constructor: (@element, @modal) ->
events = @element.querySelectorAll 'tbody td li'
for event in events
# JS scoping hell
event.addEventListener 'click', ((_this, _event) ->
-> _this.modal.open _event
)(this, event)
parse_time: (time) ->
time = time.split ':'
@ -23,7 +29,7 @@ class TimeTable
ratio = (time - from.time) / (to.time - from.time)
top = from.top + (to.top - from.top) * ratio
Math.round top
top
position: (times, element) ->
from = @parse_time element.dataset.from
@ -36,7 +42,7 @@ class TimeTable
bottom = @prorate including_to, to
root = element.parentElement
width = root.clientWidth
width = root.offsetWidth
element.style.top = "#{top}px"
element.style.height = "#{bottom - top}px"
@ -46,7 +52,7 @@ class TimeTable
init: ->
times = []
hours = @element.querySelectorAll 'tbody td:first-child li'
hours = @element.querySelectorAll 'tbody th li'
for hour in hours
time = @parse_time hour.dataset.time
times.push {
@ -61,18 +67,81 @@ class TimeTable
top: rect.top + rect.height
}
events = @element.querySelectorAll 'tbody td:not(:first-child) li'
events = @element.querySelectorAll 'tbody td li'
for event in events
@position times, event
class Modal
size: { width: 800, height: 480 }
constructor: (@modal) ->
@header = @modal.querySelector '.header'
@body = @modal.querySelector '.body'
close = => @modal.classList.add 'hidden'
@modal.querySelector('.close').addEventListener 'click', close
@modal.querySelector('.cover').addEventListener 'click', close
open: (@event) ->
start = @event.getBoundingClientRect()
scroll = {
top: window.pageYOffset,
left: window.pageXOffset
}
modal =
width: Math.round window.innerWidth * .8
height: Math.round window.innerHeight * .8
modal =
width: Math.min modal.width, @size.width
height: Math.min modal.height, @size.height
modal.top = Math.round (window.innerHeight - modal.height) / 2 + scroll.top
modal.left = Math.round (window.innerWidth - modal.width) / 2 + scroll.left
header_width = Math.round modal.width / 3
@modal.style.top = "#{start.top + scroll.top}px"
@modal.style.left = "#{start.left + scroll.left}px"
@modal.style.width = "#{start.width}px"
@modal.style.height = "#{start.height}px"
@header.style.width = "#{start.width}px"
@header.style.height = "#{start.height}px"
@body.style.width = '0px'
@body.style.height = "#{start.height}px"
time = @event.querySelector('.time').textContent
@header.querySelector('.time').textContent = time
title = @event.querySelector('.title').textContent
@header.querySelector('.title').textContent = title
author = @event.querySelector('.author').textContent
@header.querySelector('.author').textContent = author
description = @event.querySelector('.description').textContent
@body.textContent = ''
@header.classList = @event.classList
@header.classList.add 'header'
@modal.classList.remove 'hidden'
@modal.classList.add 'transition'
@modal.style.top = "#{modal.top}px"
@modal.style.left = "#{modal.left}px"
@modal.style.width = "#{modal.width}px"
@modal.style.height = "#{modal.height}px"
@header.style.width = "#{header_width}px"
@header.style.height = "#{modal.height}px"
@body.style.width = "#{modal.height - header_width}px"
@body.style.height = "#{modal.height}px"
@body.textContent = description
@modal.addEventListener 'transitionend', =>
@modal.removeEventListener 'transitionend', this
@modal.classList.remove 'transition'
init = ->
modal = new Modal document.querySelector '.modal'
tables = document.querySelectorAll 'table.timetable'
for table in tables
new TimeTable(table).init()
new TimeTable(table, modal).init()
document.addEventListener 'DOMContentLoaded', init
window.addEventListener 'resize', init

@ -1,6 +1,6 @@
@import 'bootstrap';
// @import 'bootstrap';
html {
* {
box-sizing: border-box;
}
@ -11,13 +11,32 @@ $event-color-2: #443453; // Martinique
$event-color-3: #A2B9B2; // Edward
$event-color-4: #f6b067; // Rajah
@mixin event($color) {
background-color: $color;
border-bottom: 5px solid darken($color, 5%);
}
@mixin transition($args...) {
-webkit-transition: $args;
-moz-transition: $args;
-o-transition: $args;
transition: $args;
}
table.timetable {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
tr {
th:first-child {
width: 50px;
}
th, td {
padding: 5px;
border: 1px solid #aaa;
}
}
thead {
@ -41,53 +60,140 @@ table.timetable {
}
tbody {
th {
font-size: 0.75em;
}
td {
vertical-align: top;
&:not(:first-child) {
ul {
li {
padding: 10px;
color: #fff;
&.half {
height: $line-height/2;
}
&.double {
height: 2*$line-height;
}
ul {
li {
padding: 10px;
color: #fff;
cursor: pointer;
&.half {
height: $line-height/2;
}
&.double {
height: 2*$line-height;
}
}
}
}
.cinema {
background-color: $event-color-1;
.hidden {
display: none;
}
.hall {
background-color: $event-color-2;
.description {
display: none;
}
}
}
.town {
background-color: $event-color-4;
}
.time {
font-size: 0.75em;
}
.time {
font-size: 0.75em;
.title {
font-weight: bold;
}
.author {
text-align: right;
}
.hidden {
display: none;
}
.cinema {
@include event($event-color-1);
}
.hall {
@include event($event-color-2);
}
.town {
@include event($event-color-4);
}
.modal {
position: absolute;
background-color: #fff;
display: flex;
&.hidden {
visibility: hidden;
}
.header {
height: 100%;
padding: 10px;
color: #fff;
}
.body {
height: 100%;
padding: 30px;
flex-grow: 1;
background-color: #fff;
}
&.transition {
&, .header, .body {
@include transition(width 500ms ease-in-out, height 500ms ease-in-out);
}
}
.title {
font-weight: bold;
.close {
position: absolute;
top: 0;
right: 0;
color: transparent;
white-space: nowrap;
text-indent: 100%;
height: 30px;
width: 30px;
cursor: pointer;
&::before, &::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 2px;
height: 15px;
background: #000;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
.author {
text-align: right;
&::before {
transform: translateX(-50%) translateY(-50%) rotate(45deg);
}
.description {
display: none;
&::after {
transform: translateX(-50%) translateY(-50%) rotate(-45deg);
}
}
.header, .body, .close {
z-index: 3;
}
.cover {
position: fixed;
z-index: 2;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, .8);
transition: visibility 500ms;
}
}

Loading…
Cancel
Save