diff --git a/app/controllers/cards_controller.rb b/app/controllers/cards_controller.rb
index 809428f91..526806879 100644
--- a/app/controllers/cards_controller.rb
+++ b/app/controllers/cards_controller.rb
@@ -27,7 +27,9 @@ class CardsController < ApplicationController
end
def update
- @card.update! card_params
+ suppressing_broadcasts_unless_published(@card) do
+ @card.update! card_params
+ end
if @card.published?
render_card_replacement
@@ -50,6 +52,14 @@ class CardsController < ApplicationController
@card = Current.user.accessible_cards.find params[:id]
end
+ def suppressing_broadcasts_unless_published(card, &block)
+ if card.published?
+ yield
+ else
+ Collection.suppressing_turbo_broadcasts(&block)
+ end
+ end
+
def card_params
params.expect(card: [ :status, :title, :description, :image, tag_ids: [] ])
end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index d066632bd..11b793b17 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -24,7 +24,7 @@ class UsersController < ApplicationController
def show
@filter = Current.user.filters.new(creator_ids: [ @user.id ])
- @day_timeline = Current.user.timeline_for(Time.current, filter: @filter)
+ @day_timeline = Current.user.timeline_for(day_param, filter: @filter)
end
def update
@@ -50,6 +50,14 @@ class UsersController < ApplicationController
head :forbidden unless Current.user.can_change?(@user)
end
+ def day_param
+ if params[:day].present?
+ Time.zone.parse(params[:day])
+ else
+ Time.current
+ end
+ end
+
def user_params
params.expect(user: [ :name, :email_address, :password, :avatar ])
end
diff --git a/app/helpers/events_helper.rb b/app/helpers/events_helper.rb
index 0eecdb25f..9200f84b7 100644
--- a/app/helpers/events_helper.rb
+++ b/app/helpers/events_helper.rb
@@ -52,17 +52,6 @@ module EventsHelper
tag.div class: "events__time-block", style: "grid-area: #{row}/#{col}", &
end
- def event_next_page_link(next_day)
- if next_day
- tag.div id: "next_page",
- data: { controller: "fetch-on-visible",
- fetch_on_visible_url_value: events_days_path(
- day: next_day.strftime("%Y-%m-%d"),
- **@filter.as_params
- ) }
- end
- end
-
def event_action_sentence(event)
if event.action.comment_created?
comment_event_action_sentence(event)
diff --git a/app/helpers/pagination_helper.rb b/app/helpers/pagination_helper.rb
index 8f2fc7988..ee665e98a 100644
--- a/app/helpers/pagination_helper.rb
+++ b/app/helpers/pagination_helper.rb
@@ -35,6 +35,30 @@ module PaginationHelper
end
end
+ def with_automatic_pagination(name, page, **properties)
+ pagination_list name, paginate_on_scroll: true, **properties do
+ concat(pagination_frame_tag(name, page) do
+ yield
+ concat link_to_next_page(name, page, activate_when_observed: true)
+ end)
+ end
+ end
+
+ def day_timeline_pagination_frame_tag(day_timeline, &)
+ turbo_frame_tag day_timeline_pagination_frame_id_for(day_timeline.day), data: { timeline_target: "frame" }, role: "presentation", refresh: :morph, &
+ end
+
+ def day_timeline_pagination_frame_id_for(day)
+ "day-timeline-pagination-contents-#{day.strftime("%Y-%m-%d")}"
+ end
+
+ def day_timeline_pagination_link(day_timeline, filter)
+ if day_timeline.next_day
+ link_to "Load more...", events_days_path(day: day_timeline.next_day.strftime("%Y-%m-%d"), **filter.as_params),
+ data: { frame: day_timeline_pagination_frame_id_for(day_timeline.next_day), pagination_target: "paginationLink" }
+ end
+ end
+
private
def pagination_list(name, tag_element: :div, paginate_on_scroll: false, **properties, &block)
classes = properties.delete(:class)
diff --git a/app/views/cards/index.html.erb b/app/views/cards/index.html.erb
index 1e457c452..47d15dcb8 100644
--- a/app/views/cards/index.html.erb
+++ b/app/views/cards/index.html.erb
@@ -27,6 +27,8 @@
<%= turbo_frame_tag :cards_container do %>
- <%= render partial: "cards/display/preview", collection: @page.records, as: :card, locals: { draggable: true }, cached: ->(card) { cacheable_preview_parts_for(card) } %>
+ <%= with_automatic_pagination :cards_paginated_container, @page do %>
+ <%= render partial: "cards/display/preview", collection: @page.records, as: :card, locals: { draggable: true }, cached: ->(card) { cacheable_preview_parts_for(card) } %>
+ <% end %>
<% end %>
diff --git a/app/views/collections/show.html.erb b/app/views/collections/show.html.erb
index ac7343885..96392f1d2 100644
--- a/app/views/collections/show.html.erb
+++ b/app/views/collections/show.html.erb
@@ -1,6 +1,8 @@
<% @page_title = @collection.name %>
<% turbo_exempts_page_from_cache %>
+<%= turbo_stream_from @collection %>
+
<% content_for :head do %>
<%= tag.meta property: "og:title", content: @page_title %>
<%= tag.meta property: "og:description", content: Account.sole.name %>
diff --git a/app/views/events/days/index.html.erb b/app/views/events/days/index.html.erb
new file mode 100644
index 000000000..9529e8018
--- /dev/null
+++ b/app/views/events/days/index.html.erb
@@ -0,0 +1,4 @@
+<%= day_timeline_pagination_frame_tag @day_timeline do %>
+ <%= render "events/day", day_timeline: @day_timeline %>
+ <%= day_timeline_pagination_link(@day_timeline, @filter) %>
+<% end %>
diff --git a/app/views/events/days/index.turbo_stream.erb b/app/views/events/days/index.turbo_stream.erb
deleted file mode 100644
index cceb2d352..000000000
--- a/app/views/events/days/index.turbo_stream.erb
+++ /dev/null
@@ -1,7 +0,0 @@
-<%= turbo_stream.append :activity do %>
- <%= render "events/day", day_timeline: @day_timeline %>
-<% end %>
-
-<%= turbo_stream.replace :next_page do %>
- <%= event_next_page_link(@day_timeline.next_day) %>
-<% end %>
diff --git a/app/views/events/event/_layout.html.erb b/app/views/events/event/_layout.html.erb
index 48b25d0bd..63f8e696d 100644
--- a/app/views/events/event/_layout.html.erb
+++ b/app/views/events/event/_layout.html.erb
@@ -1,6 +1,6 @@
<%= link_to event.notifiable_target,
class: "event event--#{ event.action } #{ "golden-effect" if event.card.golden? } center-block flex flex-column full-width align-start justify-start position-relative",
- style: "--card-color: #{ card.closed? ? "var(--color-card-complete)" : card.color };",
+ style: "--card-color: #{ card.closed? ? "var(--color-card-complete)" : card.color };", target: "_top",
data: { related_element_target: "related",
related_element_group_value: card.id,
action: "mouseover->related-element#highlight mouseout->related-element#unhighlight" } do %>
diff --git a/app/views/events/index.html.erb b/app/views/events/index.html.erb
index dcc0101c7..dad76f7f2 100644
--- a/app/views/events/index.html.erb
+++ b/app/views/events/index.html.erb
@@ -1,7 +1,7 @@
<% @page_title = "Home" %>
<% @header_class = "header--events" %>
-<%= turbo_stream_from :activity_summaries %>
+<%= render "filters/broadcasts", filter: @filter %>
<% content_for :header do %>
<%= render "filters/menu", user_filtering: @user_filtering %>
@@ -14,7 +14,10 @@
<% end %>
-
- <%= render "events/day", day_timeline: @day_timeline %>
-
-<%= event_next_page_link(@day_timeline.next_day) %>
+<%= tag.div id: "activity", class: "events", data: { controller: "pagination", pagination_paginate_on_intersection_value: true } do %>
+ <%= day_timeline_pagination_frame_tag @day_timeline do %>
+ <%= render "events/day", day_timeline: @day_timeline %>
+
+ <%= day_timeline_pagination_link(@day_timeline, @filter) %>
+ <% end %>
+<% end %>
diff --git a/app/views/filters/_menu.html.erb b/app/views/filters/_menu.html.erb
index 7b84cdd60..a117bdfa7 100644
--- a/app/views/filters/_menu.html.erb
+++ b/app/views/filters/_menu.html.erb
@@ -1,4 +1,4 @@
-