Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions app/assets/stylesheets/application/sidebar.css
Original file line number Diff line number Diff line change
Expand Up @@ -419,12 +419,45 @@
padding-inline-end: 0; /* Remove padding on the right side */
}

/* Style for the star button container */
[data-type="list_node"] .txt-small {
/* Style for the involvement button container */
[data-type="list_node"] .txt-small,
[data-type="list_node"] turbo-frame.txt-small {
margin-inline-start: 0; /* Reset left margin to maintain spacing with timestamp */
margin-inline-end: -1ch; /* Pull from the right side only */
}

/* Lazy-loaded involvement button placeholder */
turbo-frame[data-controller*="lazy-involvement"]:not([src]):empty::before {
content: "";
display: inline-block;
width: 20px;
height: 20px;
}

/* Sidebar loading indicator */
.sidebar__loading {
display: flex;
align-items: center;
justify-content: center;
padding: var(--block-space);
min-height: 200px;
}

.sidebar__loading .spinner {
color: var(--color-text);
opacity: 0.6;
}

/* Show loading indicator when turbo frame is loading */
turbo-frame#user_sidebar[src]:not([src=""]):not([complete]) .sidebar__loading {
display: flex;
}

turbo-frame#user_sidebar:not([src]) .sidebar__loading,
turbo-frame#user_sidebar[complete] .sidebar__loading {
display: none;
}

.rooms__new-btn {
position: relative;
z-index: 4;
Expand Down
19 changes: 19 additions & 0 deletions app/frontend/controllers/lazy_involvement_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
static values = { src: String, loaded: Boolean }

connect() {
this.loadedValue = false
}

load() {
if (this.loadedValue) return

const frame = this.element
if (this.srcValue && !frame.src) {
frame.src = this.srcValue
this.loadedValue = true
}
}
}
18 changes: 18 additions & 0 deletions app/frontend/controllers/lazy_involvement_trigger_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
static values = { target: String }

load() {
if (!this.targetValue) return

const frame = document.getElementById(this.targetValue)
if (frame) {
// Trigger the lazy-involvement controller to load
const lazyController = this.application.getControllerForElementAndIdentifier(frame, "lazy-involvement")
if (lazyController) {
lazyController.load()
}
}
}
}
24 changes: 24 additions & 0 deletions app/frontend/controllers/sidebar_loading_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
static targets = ["indicator"]

connect() {
// Hide loading indicator if content is already loaded
if (this.hasIndicatorTarget && this.element.querySelector(".sidebar__container")) {
this.hide()
}
}

show() {
if (this.hasIndicatorTarget) {
this.indicatorTarget.style.display = "flex"
}
}

hide() {
if (this.hasIndicatorTarget) {
this.indicatorTarget.style.display = "none"
}
}
}
27 changes: 21 additions & 6 deletions app/helpers/users/sidebar_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,26 @@ def has_unreads?
end

def sidebar_turbo_frame_tag(src: nil, &)
turbo_frame_tag :user_sidebar, src: src, target: "_top", data: {
controller: "rooms-list read-rooms turbo-frame",
rooms_list_unread_class: "unread",
rooms_list_badge_class: "badge",
action: "presence:present@window->rooms-list#read read-rooms:read->rooms-list#read turbo:frame-load->rooms-list#loaded refresh-room:visible@window->turbo-frame#reload".html_safe # otherwise -> is escaped
}, &
if block_given?
turbo_frame_tag :user_sidebar, src: src, target: "_top", data: {
controller: "rooms-list read-rooms turbo-frame",
rooms_list_unread_class: "unread",
rooms_list_badge_class: "badge",
action: "presence:present@window->rooms-list#read read-rooms:read->rooms-list#read turbo:frame-load->rooms-list#loaded refresh-room:visible@window->turbo-frame#reload".html_safe # otherwise -> is escaped
} do
yield
end
else
turbo_frame_tag :user_sidebar, src: src, target: "_top", data: {
controller: "rooms-list read-rooms turbo-frame sidebar-loading",
rooms_list_unread_class: "unread",
rooms_list_badge_class: "badge",
action: "presence:present@window->rooms-list#read read-rooms:read->rooms-list#read turbo:frame-load->rooms-list#loaded turbo:frame-load->sidebar-loading#hide refresh-room:visible@window->turbo-frame#reload".html_safe # otherwise -> is escaped
} do
content_tag :div, class: "sidebar__loading", data: { sidebar_loading_target: "indicator" } do
content_tag :div, "", class: "spinner"
end
end
end
end
end
19 changes: 13 additions & 6 deletions app/views/users/sidebars/rooms/_shared.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@
data-sidebar-starred-rooms-target="room" data-involvement="<%= involvement %>"
data-type="list_node"
<%= "hidden" if hide_in_starred_list %>
class="flex gap align-center justify-space-between">
class="flex gap align-center justify-space-between"
<% unless room.conversation_room? %>
data-controller="lazy-involvement-trigger"
data-lazy-involvement-trigger-target-value="<%= dom_id(room, dom_prefix(:sidebar, :involvement)) %>"
data-action="mouseenter->lazy-involvement-trigger#load"
<% end %>>
<%= link_to_room room,
class: [ "flex flex-item-grow gap align-center justify-space-between room full-height txt-nowrap overflow-ellipsis txt-lighter txt-undecorated pad-block position-relative", "unread": unread, "badge": has_notifications ],
style: "padding-block: calc(var(--block-space) / 4);" do %>
Expand All @@ -25,10 +30,12 @@
<% end %>

<% unless room.conversation_room? %>
<span class="txt-small">
<%= turbo_frame_tag dom_id(room, dom_prefix(:sidebar, :involvement)) do %>
<%= button_to_change_involvement(room, involvement, from_sidebar: true) %>
<% end %>
</span>
<%= turbo_frame_tag dom_id(room, dom_prefix(:sidebar, :involvement)),
class: "txt-small",
data: {
controller: "lazy-involvement",
lazy_involvement_src_value: room_involvement_path(room, from_sidebar: true)
} do %>
<% end %>
<% end %>
</div>