Browse Source

Use table instead of div

master
aeris 3 years ago
parent
commit
494846e5f9
  1. 1
      Gemfile
  2. 9
      Gemfile.lock
  3. 2
      config.rb
  4. 172
      source/index.html.erb
  5. 66
      source/javascripts/site.js.coffee
  6. 56
      source/stylesheets/site.css.scss

1
Gemfile

@ -4,7 +4,6 @@ gem 'middleman', '~> 4.3.3'
gem 'middleman-sprockets'
gem 'middleman-deploy', '~> 2.0.0.pre.alpha'
gem 'sass'
gem 'bootstrap-sass'
gem 'middleman-livereload'
group :development do

9
Gemfile.lock

@ -30,14 +30,9 @@ GEM
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
autoprefixer-rails (9.5.1)
execjs
awesome_print (1.8.0)
backports (3.14.0)
betterlorem (0.1.2)
bootstrap-sass (3.4.1)
autoprefixer-rails (>= 5.2.1)
sassc (>= 2.0.0)
builder (3.2.3)
byebug (11.0.1)
coderay (1.1.2)
@ -133,6 +128,8 @@ GEM
net-ssh (5.2.0)
nokogiri (1.10.3)
mini_portile2 (~> 2.4.0)
normalize-scss (7.0.1)
sass (~> 3.3)
padrino-helpers (0.13.3.4)
i18n (~> 0.6, >= 0.6.7)
padrino-support (= 0.13.3.4)
@ -191,12 +188,12 @@ DEPENDENCIES
actionmailer
awesome_print
betterlorem
bootstrap-sass
icalendar
middleman (~> 4.3.3)
middleman-deploy (~> 2.0.0.pre.alpha)
middleman-livereload
middleman-sprockets
normalize-scss
pry-byebug
redcarpet
sass

2
config.rb

@ -2,7 +2,7 @@ activate :sprockets
activate :i18n, mount_at_root: :fr
configure :development do
activate :livereload, apply_css_live: true, apply_js_live: true, no_swf: true if defined? Livereload
activate :livereload, apply_css_live: true, apply_js_live: true, no_swf: true
end
configure :build do

172
source/index.html.erb

@ -3,13 +3,48 @@
render = Redcarpet::Render::HTML
markdown = Redcarpet::Markdown.new render, autolink: true
planning = YAML.load(File.read File.join Middleman::Application.root, 'config/current.yml')
.deep_symbolize_keys
planning = File.join Middleman::Application.root, 'config/current.yml'
planning = YAML.load_file(planning).deep_symbolize_keys
def parse_time(time)
hour, min = time.split ':'
60 * hour.to_i + min.to_i
end
def to_time(time)
'%02d:%02d' % [time/60, time % 60]
end
FROM = parse_time('10:00')
TO = parse_time('21:00')
STEP = parse_time('00:30')
columns = planning.collect do |day, events|
events = events.collect do |location, events|
tmp = events.collect do |event|
from = parse_time event[:from]
to = parse_time event[:to]
height = (to - from) / STEP
event.merge from: from, to: to, height: height
end.sort { |a, b| a[:from] <=> b[:from] }
events = []
last = FROM
tmp.each do |event|
from, to = event.values_at :from, :to
if from > last
height = (from - last) / STEP
events << { placeholder: true, from: last, to: from, height: height }
end
last = to
events << event
end
unless last == TO
height = (TO - last) / STEP
events << { placeholder: true, from: last, to: TO, height: height }
end
[location, events]
end.collect { |l, es| { day: day, location: l, events: es } }
end.flatten 1
%>
<div class="container-fluid">
@ -20,8 +55,8 @@
<th rowspan="2">
<% link_to 'index.ics' do %>
<svg version="1.1" xmlns="http://www.w3.org/2000/svg"
x="0px" y="0px"
viewBox="0 0 60 60" style="enable-background:new 0 0 60 60;" xml:space="preserve">
x="0px" y="0px"
viewBox="0 0 60 60" style="enable-background:new 0 0 60 60;" xml:space="preserve">
<g>
<title>Calendrier</title>
<g>
@ -43,90 +78,81 @@
</g>
</svg>
<% end %>
<!--div class="giggity">
<div class="giggity">
<%= image_tag 'giggity.png', alt: 'Giggity', title: 'Giggity', class: 'logo' %>
<%= image_tag 'qrcode.png', class: 'qrcode hidden' %>
</div-->
</div>
</th>
<% planning.each do |day, events| %>
<% planning.each do |day, locations| %>
<%=
n = events.size
n = locations.size
attributes = n == 1 ? nil : { colspan: n }
content_tag :th, attributes do
I18n.l day, format: '%A %d %B'
end
content_tag(:th, attributes) { I18n.l day, format: '%A %d %B' }
%>
<% end %>
</tr>
<tr>
<% planning.each do |_, events| %>
<% events.each do |location, _| %>
<td>
<%= case location.to_sym
when :cinema
'Salle cinéma'
when :hall
'Accueil'
when :town
'Village asso'
when :young
'Espace jeunesse'
end
%>
</td>
<% end %>
<% planning.each do |day, locations|
locations.each do |location, _| %>
<th>
<%= case location.to_sym
when :cinema
'Salle cinéma'
when :hall
'Accueil'
when :town
'Village asso'
when :young
'Espace jeunesse'
end
%>
</th>
<% end %>
<% end %>
</tr>
</thead>
<tbody>
<tr>
<th>
<ul>
<% (10..21).each do |hour| %>
<li data-time="<%= hour %>:00"><%= hour %>:00</li>
<% end %>
</ul>
</th>
<% planning.each do |_, events| %>
<% events.each do |_, events|
events ||= []
events.sort! { |a, b| parse_time(a[:from]) <=> parse_time(b[:from]) }
%>
<td>
<ul>
<% events.each do |event| %>
<%
from, to = event[:from], event[:to]
duration = parse_time(to) - parse_time(from)
classes = [:event, event[:type]]
classes << :half if duration <= 30
classes << :double if duration >= 90
classes = classes.join ' '
%>
<% content_tag :li, class: classes, data: { from: from, to: to } do %>
<div class="time">
<%= from %> - <%= to %>
</div>
<div class="title">
<%= event[:title] %>
</div>
<div class="author">
<%= event[:author] %>
</div>
<div class="description">
<%=
description = event[:description]
markdown.render description if description
%>
</div>
<% end %>
<%
(FROM...TO).step(STEP).each do |time| %>
<tr>
<th><%= to_time(time) if time % 60 == 0 %></th>
<% columns.each do |column|
events = column[:events]
event = events.first
if event
from, to, height, placeholder = event.values_at :from, :to, :height, :placeholder
if from == time
events = events.delete_at 0
attributes = height == 1 ? {} : { rowspan: height }
%>
<% unless event[:placeholder]
content_tag :td, **attributes do %>
<% content_tag :div, class: "event #{event[:type]}" do %>
<div class="time">
<%= to_time from %> - <%= to_time to %>
</div>
<div class="title">
<%= event[:title] %>
</div>
<div class="author">
<%= event[:author] %>
</div>
<div class="description">
<%=
description = event[:description]
markdown.render description if description
%>
</div>
<% end %>
</ul>
</td>
<% end %>
<% else %>
<%= content_tag :td, '', **attributes %>
<% end %>
<% end %>
<% end %>
</tr>
<% end %>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<ul class="legend">

66
source/javascripts/site.js.coffee

@ -1,75 +1,13 @@
class TimeTable
constructor: (@element, @modal) ->
events = @element.querySelectorAll 'tbody td > ul > li'
events = @element.querySelectorAll 'tbody td > div'
for event in events
# JS scoping hell
event.addEventListener 'click', ((_this, _event) ->
-> _this.modal.open _event
)(this, event)
parse_time: (time) ->
time = time.split ':'
hour = parseInt time[0]
min = parseInt time[1]
60 * hour + min
find_including: (times, time) ->
previous = null
for current in times
if previous?
if previous.time <= time < current.time
return [previous, current]
else
previous = current
null
prorate: (ref, time) ->
from = ref[0]
to = ref[1]
ratio = (time - from.time) / (to.time - from.time)
top = from.top + (to.top - from.top) * ratio
top
position: (times, element) ->
from = @parse_time(element.dataset.from)
to = @parse_time(element.dataset.to) - 5
including_from = @find_including times, from
including_to = @find_including times, to
top = @prorate including_from, from
bottom = @prorate including_to, to
root = element.parentElement
width = root.offsetWidth
element.style.top = "#{top + window.pageYOffset}px"
element.style.height = "#{bottom - top}px"
element.style.width = "#{width}px"
element.style.position = 'absolute'
init: ->
times = []
hours = @element.querySelectorAll 'tbody th > ul > li'
for hour in hours
time = @parse_time hour.dataset.time
times.push {
time: time,
top: hour.getBoundingClientRect().top
}
last = hours[hours.length - 1]
time = @parse_time last.dataset.time
rect = last.getBoundingClientRect()
times.push {
time: time + 60
top: rect.top + rect.height
}
events = @element.querySelectorAll 'tbody td > ul > li'
for event in events
@position times, event
init: () ->
class Modal
size: { width: 800, height: 480 }

56
source/stylesheets/site.css.scss

@ -45,6 +45,7 @@ body {
table.timetable {
width: 100%;
border-collapse: collapse;
border: 1px solid #aaa;
table-layout: fixed;
tr {
@ -69,43 +70,42 @@ table.timetable {
}
}
ul {
list-style-type: none;
padding: 0;
margin: 0;
li {
height: $line-height;
& {
margin-top: 5px;
}
tbody {
th, td {
height: 150px;
border-top: none;
border-bottom: none;
}
}
tbody {
th {
font-size: 0.75em;
vertical-align: top;
}
td {
//Fuck off, Firefox
//height: 100%;
position: relative;
vertical-align: top;
ul {
li {
padding: 10px;
cursor: pointer;
// text-align: justify;
overflow: hidden;
&.half {
height: $line-height/2;
}
&.double {
height: 2*$line-height;
}
}
& > div {
//Fuck off, Firefox
//width: 100%;
//height: 100%;
position: absolute;
top: 5px;
bottom: 5px;
left: 5px;
right: 5px;
//Fuck off, Firefox
//display: inline-table;
padding: 10px;
cursor: pointer;
// text-align: justify;
overflow: hidden;
}
}

Loading…
Cancel
Save