From b2f72ff66868d1b6a66e85c499ecb3ec2f7550d7 Mon Sep 17 00:00:00 2001 From: Kevin McConnell Date: Wed, 22 Jan 2025 14:38:38 +0000 Subject: [PATCH] Use Stimulus to position events by timezone --- app/assets/stylesheets/events.css | 8 ++++++++ app/helpers/events_helper.rb | 12 +++++++----- .../controllers/timeline_controller.js | 17 +++++++++++++++++ app/views/events/_day.html.erb | 6 +++--- app/views/events/_event.html.erb | 7 ++++--- 5 files changed, 39 insertions(+), 11 deletions(-) create mode 100644 app/javascript/controllers/timeline_controller.js diff --git a/app/assets/stylesheets/events.css b/app/assets/stylesheets/events.css index 4180e749d..34a180b3e 100644 --- a/app/assets/stylesheets/events.css +++ b/app/assets/stylesheets/events.css @@ -31,6 +31,10 @@ &:nth-child(1n + 57) { background-color: var(--color-highlight); } + + &.future { + display: none; + } } .event-grid-time { @@ -50,4 +54,8 @@ text-transform: uppercase; transform: translate(-50%, 50%); } + + &.future { + display: none; + } } diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb index 187276241..a58a168a5 100644 --- a/app/helpers/events_helper.rb +++ b/app/helpers/events_helper.rb @@ -27,17 +27,18 @@ module EventsHelper tag.div id: "next_page", data: { controller: "fetch-on-visible", fetch_on_visible_url_value: events_path(day: next_day) } end - def render_event_grid_cells(columns: 4, rows: 24) + def render_event_grid_cells(day, columns: 4, rows: 24) safe_join((2..rows + 1).map do |row| (1..columns).map do |col| - content_tag(:div, "", class: "event-grid-item", style: "grid-area: #{row}/#{col};") + time = day.beginning_of_day + (rows - row + 1).hours + tag.div class: "event-grid-item", style: "grid-area: #{row}/#{col};", data: { datetime: time.iso8601, timeline_target: "cell" } end end.flatten) end - def render_time_labels + def render_time_labels(day) safe_join((0..24).step(6).to_a.map do |hour| - time = Time.current.beginning_of_day + hour.hours + time = day.beginning_of_day + hour.hours label = if hour == 24 "midnight" else @@ -49,7 +50,8 @@ module EventsHelper datetime: time.strftime("%H:%M") ), class: "event-grid-time", - style: "grid-area: #{25 - (hour * 23/24)}/2 / #{25 - (hour * 23/24)}/4;" + style: "grid-area: #{25 - (hour * 23/24)}/2 / #{25 - (hour * 23/24)}/4;", + data: { timeline_target: "cell", datetime: time.iso8601 } ) end) end diff --git a/app/javascript/controllers/timeline_controller.js b/app/javascript/controllers/timeline_controller.js new file mode 100644 index 000000000..370239176 --- /dev/null +++ b/app/javascript/controllers/timeline_controller.js @@ -0,0 +1,17 @@ +import { Controller } from "@hotwired/stimulus" + +const MAX_ROWS = 25 + +export default class extends Controller { + static targets = [ "cell", "item" ] + + cellTargetConnected(target) { + const dt = new Date(target.dataset.datetime) + target.classList.toggle("future", dt > new Date()) + } + + itemTargetConnected(target) { + const dt = new Date(target.dataset.datetime) + target.style.gridRowStart = MAX_ROWS - dt.getHours() + } +} diff --git a/app/views/events/_day.html.erb b/app/views/events/_day.html.erb index 834472545..0eb310096 100644 --- a/app/views/events/_day.html.erb +++ b/app/views/events/_day.html.erb @@ -1,10 +1,10 @@ -
+

<%= event_day_title(activity_day) %>

<% if @events.any? %>
<%= render_column_headers %> - <%= render_event_grid_cells %> - <%= render_time_labels %> + <%= render_event_grid_cells(activity_day) %> + <%= render_time_labels(activity_day) %> <%= render events %>
<% else %> diff --git a/app/views/events/_event.html.erb b/app/views/events/_event.html.erb index 8db780b16..6afa4ce39 100644 --- a/app/views/events/_event.html.erb +++ b/app/views/events/_event.html.erb @@ -1,8 +1,9 @@ <% bubble = event.summary.bubble %> -<%= link_to bucket_bubble_path(bubble.bucket, bubble), class: "event panel shadow center flex-inline align-center justify-start gap position-relative", - style: "grid-area: #{ event.created_at.hour }/ #{ event_column(event) }; --panel-border-radius: 0.7em; --panel-padding: 0.3em 0.6em; --panel-size: auto; --bubble-color: #{ bubble.color }; #{ bubble_rotation(bubble) }", - data: { controller: "animation", animation_play_class: "bubble--wobble", animation_play_on_load_value: "true", action: "mouseover->animation#play" } do %> +<%= link_to bucket_bubble_path(bubble.bucket, bubble), + class: "event panel shadow center flex-inline align-center justify-start gap position-relative", + style: "grid-column-start: #{ event_column(event) }; --panel-border-radius: 0.7em; --panel-padding: 0.3em 0.6em; --panel-size: auto; --bubble-color: #{ bubble.color }; #{ bubble_rotation(bubble) }", + data: { controller: "animation", animation_play_class: "bubble--wobble", animation_play_on_load_value: "true", action: "mouseover->animation#play", timeline_target: "item", datetime: event.created_at.iso8601 } do %>
<%= bubble.title %>