Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix scrolling bug #46

Merged
merged 5 commits into from
Aug 28, 2024
Merged
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
8 changes: 7 additions & 1 deletion app/controllers/messages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@ class MessagesController < ApplicationController

# GET /messages or /messages.json
def index
@messages = Message.all
@messages = if @chat
@chat.messages.order(created_at: :asc)
else
Message.all.order(created_at: :asc)
end

@messages
end

# GET /messages/1 or /messages/1.json
Expand Down
44 changes: 12 additions & 32 deletions app/views/chats/show.html.erb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<div class="mx-auto w-full flex flex-col min-h-screen">
<div class="mx-auto w-full flex flex-col min-h-screen" id="chat-container">
<!-- Breadcrumbs -->
<nav class="mb-4">
<ul class="flex space-x-2 text-gray-600">
Expand All @@ -11,7 +11,6 @@
</li>
</ul>
</nav>

<!-- Main Content -->
<div class="w-full flex justify-between items-center">
<div>
Expand All @@ -27,15 +26,11 @@
<% end %>
</div>
</div>

<!-- Messages -->
<div class="flex-grow overflow-auto" id="messages-container-<%[email protected]%>">
<%= render partial: 'messages/message', collection: @chat.messages.order(created_at: :asc) %>
</div>

<turbo-frame id="messages-<%[email protected]%>" src="<%= chat_messages_path(@chat) %>"></turbo-frame>
<!-- Input Form Fixed at Bottom -->
<div class="w-full fixed bottom-0 left-0 bg-white p-4 border-t border-gray-300">
<%= form_with(model: [@chat, Message.new], local: true, class: 'flex space-x-2') do |f| %>
<%= form_with(model: [@chat, Message.new], remote: true, class: 'flex space-x-2') do |f| %>
<%= f.text_field :content, class: 'flex-grow p-2 border border-gray-300 rounded-lg' %>
<button type="submit" class="flex items-center justify-center space-x-2 rounded-lg py-2 px-4 bg-sky-600 text-white font-medium">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6">
Expand All @@ -46,34 +41,19 @@
<% end %>
</div>

<!-- JavaScript to start the whole page scrolled to the bottom and refresh messages -->
<script>
function scrollToBottom() {
window.scrollTo(0, document.body.scrollHeight);
}

document.addEventListener("turbo:load", scrollToBottom); // Trigger on Turbo page load
document.addEventListener("DOMContentLoaded", scrollToBottom); // Trigger on full page load

// Optional: Scroll to the most recent message after submitting a new message
document.querySelector('form').addEventListener('submit', function() {
setTimeout(scrollToBottom, 3000); // slight delay to ensure the new message is rendered
});

// Function to fetch and update messages every 3 seconds
function refreshMessages() {
fetch("<%= chat_path(@chat) %>", {
headers: { 'X-Requested-With': 'XMLHttpRequest' }
})
.then(response => response.text())
.then(html => {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const newMessages = doc.querySelector('#messages-container-<%[email protected]%>').innerHTML;
document.querySelector('#messages-container-<%[email protected]%>').innerHTML = newMessages;
});
<!-- JavaScript to start the whole page scrolled to the bottom and refresh messages -->
<script>
function scrollToBottom() {
const turboFrame = document.getElementById('messages-list');
if (turboFrame) {
window.scrollTo(0, turboFrame.scrollHeight);
}
}

setInterval(refreshMessages, 4000);
document.addEventListener("turbo:frame-load", scrollToBottom); // Trigger on Turbo page load

</script>
</div>
65 changes: 39 additions & 26 deletions app/views/messages/_message.html.erb
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
<div id="<%= dom_id(message) %>" class="my-5 flex <%= message.user? ? 'justify-start' : 'justify-end' %>">
<div class="w-3/4">
<p class="text-xs text-gray-500 mb-1 <%= message.from == 'assistant' ? 'text-right' : '' %>">
<% if message.from == 'user' %>
<%= message.user.email %>
<% elsif message.from == 'assistant' %>
<%= message.chat.assistant.name %>
<turbo-frame id="message-<%=message.id%>">
<div id="<%= dom_id(message) %>" class="my-5 flex <%= message.user? ? 'justify-start' : 'justify-end' %>">
<div class="w-3/4">
<p class="text-xs text-gray-500 mb-1 <%= message.from == 'assistant' ? 'text-right' : '' %>">
<% if message.from == 'user' %>
<%= message.user.email %>
<% elsif message.from == 'assistant' %>
<%= message.chat.assistant.name %>
<% else %>
<%= message.from %>
<% end %>
</p>
<% if message.status === 'generating' %>
<div class="flex justify-end text-2xl text-gray-400">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-12 animate-pulse">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.625 9.75a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H8.25m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H12m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0h-.375m-13.5 3.01c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.184-4.183a1.14 1.14 0 0 1 .778-.332 48.294 48.294 0 0 0 5.83-.498c1.585-.233 2.708-1.626 2.708-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z" />
</svg>
</div>
<% if !message.user? %>
<script>
console.log("Generating");
setTimeout(function() {
const turboFrame = document.getElementById('message-<%=message.id%>');
turboFrame.src = null; // Clear the src attribute
turboFrame.src = `<%= chat_messages_path(@chat, message) %>`; // Set the new src to reload the frame
console.log(turboFrame.src);
}, 2000); // Delay of 5000 milliseconds (5 seconds)
</script>
<% end %>
<% else %>
<%= message.from %>
<div class="p-4 rounded-bl-2xl rounded-br-2xl <%= message.user? ? 'rounded-tr-2xl' : 'rounded-tl-2xl' %> <%= message.user? ? 'bg-white text-gray-900' : 'bg-sky-200 text-sky-700' %> border <%= message.user? ? 'border-stone-200' : 'border-blue-300' %> shadow-sm">
<p class="mb-3">
<%= render_markdown(message.content) if message.content.present? %>
<% if session[:debug] == "true" && message.prompt.present? %>
<textarea class="w-full rounded border bg-stone-100" rows=5><%= message.prompt %></textarea>
<% end %>
</p>
</div>
<% end %>
</p>
<% if message.status === 'generating' %>
<div class="flex justify-end text-2xl text-gray-400">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="size-12 animate-pulse">
<path stroke-linecap="round" stroke-linejoin="round" d="M8.625 9.75a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H8.25m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0H12m4.125 0a.375.375 0 1 1-.75 0 .375.375 0 0 1 .75 0Zm0 0h-.375m-13.5 3.01c0 1.6 1.123 2.994 2.707 3.227 1.087.16 2.185.283 3.293.369V21l4.184-4.183a1.14 1.14 0 0 1 .778-.332 48.294 48.294 0 0 0 5.83-.498c1.585-.233 2.708-1.626 2.708-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0 0 12 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018Z" />
</svg>
</div>
<% else %>
<div class="p-4 rounded-bl-2xl rounded-br-2xl <%= message.user? ? 'rounded-tr-2xl' : 'rounded-tl-2xl' %> <%= message.user? ? 'bg-white text-gray-900' : 'bg-sky-200 text-sky-700' %> border <%= message.user? ? 'border-stone-200' : 'border-blue-300' %> shadow-sm">
<p class="mb-3">
<%= render_markdown(message.content) if message.content.present? %>
</p>
<% if session[:debug] == "true" && message.prompt.present? %>
<textarea class="w-full rounded border bg-stone-100" rows=5><%= message.prompt %></textarea>
<% end %>
</div>
<% end %>
</div>
</div>
</div>
</turbo-frame>
42 changes: 24 additions & 18 deletions app/views/messages/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
<div class="w-full">
<% if notice.present? %>
<p class="py-2 px-3 bg-green-50 mb-5 text-green-500 font-medium rounded-lg inline-block" id="notice"><%= notice %></p>
<% end %>

<% content_for :title, "Messages" %>

<div class="flex justify-between items-center">
<h1 class="font-bold text-4xl">Messages</h1>
<%= link_to "New message", new_message_path, class: "rounded-lg py-3 px-5 bg-blue-600 text-white block font-medium" %>
</div>

<div id="messages" class="min-w-full">
<!-- app/views/messages/index.html.erb -->
<turbo-frame id="messages-<%[email protected]%>">
<div id="messages-list">
<% @messages.each do |message| %>
<%= render message %>
<p>
<%= link_to "Show this message", message, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium" %>
</p>
<%= render partial: 'messages/message', locals: { message: message } %>
<% end %>
<% if @messages.last.from == 'user' %>
<script>
reloadTurboFrameWithDelay(3000);
</script>
<% end %>
</div>
</div>


<script>
//If the last message is from a user, we refresh the list until the last message is not from a user
function reloadTurboFrameWithDelay(delay) {
setTimeout(function() {
const turboFrame = document.getElementById("messages-<%[email protected]%>");
if (turboFrame) {
turboFrame.src = turboFrame.src; // Set the new src to reload the frame
console.log("Reloading Turbo Frame:", turboFrame.src);
}
}, delay);
}
</script>
</turbo-frame>
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Rails.application.routes.draw do
resources :messages
resources :chats do
resources :messages, only: %i[create destroy index]
resources :messages
end
resources :assistants do
resources :chats, only: %i[create new]
Expand Down
Loading