<% new_message ||= false %> <% current_author = defined?(current_user) ? current_user : send(BulletTrain::Conversations.current_participant_helper_method) %> <% current_user_message = message.author == current_author %> <% avatar = capture do %> <% if message.membership %> <img src="<%= membership_profile_photo_url(message.membership) %>" title="<%= message.user_name %>" alt="<%= message.user_name %>" class="w-6 h-6 rounded-full <%= current_user_message ? 'order-2' : 'order-1' %>"> <% elsif message.participant %> <div class="<%= current_user_message ? 'order-2' : 'order-1' %>"> <% if BulletTrain::Conversations.respond_to?(:participant_avatar_partial) && BulletTrain::Conversations.participant_avatar_partial %> <%= render BulletTrain::Conversations.participant_avatar_partial, participant: message.participant %> <% end %> </div> <% end %> <% end %> <% next_message ||= message.next_message %> <%# A message series is a series of messages by the same user, each message within 5 minutes of the previous message. It has nothing to do with replies and message threads %> <% next_message_in_series = (message.author == next_message&.author) && (message.created_at > next_message.created_at - 5.minutes) && (message.parent_message_id == next_message&.parent_message_id || message.id == next_message.parent_message_id)%> <% if next_message_in_series %> <% avatar = nil %> <% end %> <%# We set this to true when rendering the messages for the reply view. All messages in the thread are shown in order without any other messages from the conversation %> <% show_as_thread ||= false %> <%# placeholder messages are used when displaying a reply to a message that we need to show out of order with the rest %> <% placeholder_message ||= false %> <% if avatar.nil? %> <% avatar = capture do %> <div style="height: 24px; width: 24px;" class="<%= current_user_message ? 'order-2' : 'order-1' %>"></div> <% end %> <% end %> <% rounding_modifier = message_corner_class(next_message_in_series, current_user_message) %> <% timestamp = next_message_in_series || show_as_thread ? '' : time_ago_in_words(message.created_at) + " ago" %> <% threaded_message = message.threaded? %> <% thread_started_by_current_user = message.thread_origin_user == current_author %> <% last_message_in_thread = !placeholder_message && threaded_message && (message.next_message.nil? || message.next_message.thread_id != message.thread_id)%> <% out_of_thread_message = !show_as_thread && threaded_message && message.reply? && message.previous_message != message.previous_message_in_thread %> <% has_replies = message.replies.any? && message.next_message == message.next_message_in_thread %> <% border_side = thread_started_by_current_user ? :left : :right %> <% show_borders = !show_as_thread && threaded_message %> <% if out_of_thread_message %> <%= render 'account/shared/message', message: message.thread_origin_message, next_message: message, placeholder_message: true, show_as_thread: show_as_thread %> <% end %> <div class="chat-message" <% unless show_as_thread %> data-reply-target="message" data-user="<%= message.author.label_string %>" data-message-id="<%= message.parent_message_id || message.id %>" data-action="mouseleave->reply#hideReplyButton" <% end %> > <div class="group flex <%= 'justify-end' if current_user_message %> <%= 'opacity-20' if new_message %> items-stretch"> <% if show_borders %> <% if (has_replies || placeholder_message) %> <%= message_thread_border(side: border_side, position: :start) unless show_as_thread %> <% end %> <% if message.reply? && ((current_user_message && thread_started_by_current_user) || (!current_user_message && !thread_started_by_current_user) ) %> <%= message_thread_border(side: border_side, position: (last_message_in_thread ? :end : :middle)) %> <% end %> <% end %> <div class="flex flex-col <%= 'mb-0.5' if next_message_in_series %>"> <div class="flex items-end relative <%= 'justify-end' if current_user_message %>" data-action="<%= 'click->reply#preventDefault' if show_as_thread %>"> <div class="flex flex-col space-y-2 text-xs max-w-xs mx-2 <%= current_user_message ? 'order-1 items-end' : 'order-3 items-start' %> z-10 transition-all duration-300" data-action="<%= 'mouseenter->reply#showReplyButton click->reply#showReplyButton' unless placeholder_message || show_as_thread %>" data-show-class="<%= current_user_message ? 'mr-10' : 'ml-10' %>" > <% if placeholder_message %> <div class="cursor-pointer" data-thread-url="<%= url_for([:thread, :account, message.thread_origin_message || message]) %>" data-action="click->reply#reply"><span class="px-2 py-1 text-xs text-slate-300 rounded-lg inline-block <%= rounding_modifier %> border-primary-300 border break-words sm:max-w-sm max-w-tiny"><%= Nokogiri::HTML.fragment(trix_sanitize(message.body)).text.truncate(80) %></span></div> <% else %> <div><span class="px-4 py-2 rounded-lg inline-block <%= rounding_modifier %> <%= current_user_message ? ' bg-primary-600 text-white' : ' bg-slate-300 text-slate-600' %> "><%= trix_sanitize(message.body) %></span></div> <% end %> </div> <%= avatar %> <% unless placeholder_message || show_as_thread %> <div class="order-2 absolute text-slate-400 bottom-1 hover:text-slate-500 <%= current_user_message ? 'right-10' : 'left-10' %> z-0"> <button data-action="click->reply#reply" data-thread-url="<%= url_for([:thread, :account, message.thread_origin_message || message]) %>" > <svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 stroke-current" fill="none" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" /> </svg> </button> </div> <% end %> </div> <% if message.replies.any? && !show_as_thread %> <div class="<%= 'text-right' if current_user_message %>"> <button class="text-xs text-primary-400 text-right mr-12 ml-12" data-thread-url="<%= url_for([:thread, :account, message.thread_origin_message || message]) %>" data-action="reply#reply"><%= message.replies.size %> <%= t("conversations/messages.navigation.reply").pluralize(message.replies.size) %></button> </div> <% end %> </div> </div> <% unless next_message_in_series || placeholder_message %> <div class="flex"> <% if show_borders && !last_message_in_thread %> <% if (thread_started_by_current_user && current_user_message) || (!thread_started_by_current_user && !current_user_message) %> <%= message_thread_border(side: border_side, position: :middle) %> <% end %> <% end %> <div class="flex flex-grow order-1 <%= current_user_message ? 'justify-end items-end pr-8' : 'justify-start items-start pl-8' %> <%= 'mb-3' unless next_message_in_series %>"> <div class="<%= show_as_thread ? 'text-slate-400' : 'text-slate-300' %> text-sm"> <strong><%= message.author.name %></strong> <%= timestamp %> </div> </div> </div> <% end %> <% if message.replies.any? && false %> <div class="mb-4"> <% message.replies.each do |reply| %> <div class="flex text-xs font-extralight text-slate-300 ml-12"> <div class="<%= 'w-full' if current_user_message %>"></div> <svg version="1.0" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 682" class="w-5 h-5 stroke-current mt-4 text-slate-50 fill-current"> <path d="M0 57.7c.1 145.1 4.1 224 14.5 281.1 19.4 106.3 65.2 156.4 166.3 181.7 48.7 12.1 111.4 18.8 211.7 22.5 23.8.9 196.6 2.8 268.2 3H683l.2 67.8.3 67.8 170.3-102.1L1024 477.3l-170.2-102-170.3-102-.3 67.8-.2 67.9h-75.8c-184.7 0-266.9-4.8-327.2-19-34.2-8.1-62.8-21.1-81.2-37-36.1-31.3-52.3-76.8-58.8-165.5-2-28-3-69.2-3-127.8V0H0v57.7z"/> </svg> <div class="flex flex-col mr-10 min-w-max"> <div class="pt-0 mr-2 ml-4 text-xxs"><%= reply.membership.label_string %> reply: </div> <div class="bg-slate-100 rounded py-2 px-4 mt-0 text-slate-400 max-w-md"><%= reply.body.html_safe %></div> </div> </div> <% end %> </div> <% end %> </div>