diff --git a/lib/petal_components.ex b/lib/petal_components.ex index e02633a8..d185e8e8 100644 --- a/lib/petal_components.ex +++ b/lib/petal_components.ex @@ -10,6 +10,7 @@ defmodule PetalComponents do Button, ButtonGroup, Card, + ChatBubble, Container, Dropdown, Field, diff --git a/lib/petal_components/chat_bubble.ex b/lib/petal_components/chat_bubble.ex new file mode 100644 index 00000000..d4a7f77f --- /dev/null +++ b/lib/petal_components/chat_bubble.ex @@ -0,0 +1,1123 @@ +defmodule PetalComponents.ChatBubble do + use Phoenix.Component + + # Base chat bubble component + attr(:author, :string, default: "Sarah Hill", doc: "author name for the chat message") + attr(:message, :string, default: "That's awesome. I think our users will really appreciate the improvements.", doc: "main message content") + attr(:time, :string, default: "10:13", doc: "timestamp for the message") + attr(:avatar_src, :string, default: "https://res.cloudinary.com/wickedsites/image/upload/v1604268092/unnamed_sagz0l.jpg", doc: "hosted avatar URL") + attr(:avatar_alt, :string, default: nil, doc: "alt text for avatar image") + attr(:kind, :atom, default: :default_chat_bubble, + values: [ + :default_chat_bubble, :voicenote, :file_attachment, + :image_attachment, :image_gallery, :url_preview_sharing, + :outline_chat_bubble, :outline_voicenote, :outline_file_attachment, + :outline_image_attachment, :outline_image_gallery, :outline_url_preview_sharing, + :clean_chat_bubble, :clean_voicenote, :clean_file_attachment, + :clean_image_attachment, :clean_image_gallery, :clean_url_preview_sharing + ], + doc: "determines the type of chat bubble to render" + ) + attr(:class, :any, default: nil, doc: "additional css classes") + attr(:rest, :global) + + # File attributes + attr(:file_name, :string, default: "Petal Components Terms & Conditions", doc: "name of the attached file") + attr(:file_size, :string, default: "18 MB", doc: "size of the attached file") + attr(:file_pages, :string, default: "12 Pages", doc: "number of pages in document") + attr(:file_type, :string, default: "PDF", doc: "type of file") + + # Voice note attributes + attr(:duration, :string, default: "3:42", doc: "duration of voice note") + + # Image attributes + attr(:image_src, :string, default: "https://images.unsplash.com/photo-1562664377-709f2c337eb2", doc: "URL of the attached image") + attr(:image_alt, :string, default: "Image attachment", doc: "alt text for attached image") + + # Gallery attributes + attr(:images, :list, + default: [ + "https://images.unsplash.com/photo-1552664730-d307ca884978", + "https://images.unsplash.com/photo-1551434678-e076c223a692", + "https://images.unsplash.com/photo-1562664377-709f2c337eb2", + "https://petal.build/images/logo_dark.svg" + ], + doc: "list of gallery image URLs" + ) + attr(:extra_images_count, :integer, default: 7, doc: "number of additional images not shown") + + # URL Preview attributes + attr(:url, :string, default: "https://petal.build/components", doc: "URL to preview") + attr(:url_title, :string, default: "Welcome to Petal Components", doc: "title of the URL preview") + attr(:url_description, :string, default: "A versatile set of beautifully styled components", doc: "description for the URL preview") + attr(:url_image, :string, default: "https://petal.build/images/favicon.png", doc: "image for the URL preview") + attr(:url_domain, :string, default: "github.com", doc: "domain name for the URL") + + def chat_bubble(assigns) do + case assigns.kind do + :default_chat_bubble -> render_default_chat_bubble(assigns) + :voicenote -> render_voicenote(assigns) + :file_attachment -> render_file_attachment(assigns) + :image_attachment -> render_image_attachment(assigns) + :image_gallery -> render_image_gallery(assigns) + :url_preview_sharing -> render_url_preview_sharing(assigns) + + # Outline variants + :outline_chat_bubble -> render_outline_chat_bubble(assigns) + :outline_voicenote -> render_outline_voicenote(assigns) + :outline_file_attachment -> render_outline_file_attachment(assigns) + :outline_image_attachment -> render_outline_image_attachment(assigns) + :outline_image_gallery -> render_outline_image_gallery(assigns) + :outline_url_preview_sharing -> render_outline_url_preview_sharing(assigns) + + # Clean variants + :clean_chat_bubble -> render_clean_chat_bubble(assigns) + :clean_voicenote -> render_clean_voicenote(assigns) + :clean_file_attachment -> render_clean_file_attachment(assigns) + :clean_image_attachment -> render_clean_image_attachment(assigns) + :clean_image_gallery -> render_clean_image_gallery(assigns) + :clean_url_preview_sharing -> render_clean_url_preview_sharing(assigns) + + # Default fallback + _ -> render_default_chat_bubble(assigns) + end + end + + defp render_header(assigns) do + ~H""" +
+ <%= @author %> + <%= @time %> +
+ """ +end + +defp render_default_chat_bubble(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +

<%= @message %>

+ Delivered +
+
+
+ """ +end + +defp render_waveform(assigns) do + ~H""" +
+ + + <%= assigns[:duration] %> +
+ """ +end + +defp render_voicenote(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:class, assigns[:class]) + |> assign(:duration, assigns[:duration]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> + <%= render_waveform(assigns) %> + Delivered +
+
+
+ """ +end + +defp render_file_attachment(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:class, assigns[:class]) + |> assign(:file_name, assigns[:file_name]) + |> assign(:file_size, assigns[:file_size]) + |> assign(:file_pages, assigns[:file_pages]) + |> assign(:file_type, assigns[:file_type]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+
+
+ <%= @author %> + <%= @time %> +
+
+
+ + + <%= @file_name %> + + + <%= @file_pages %> + + <%= @file_size %> + + <%= @file_type %> + +
+ +
+ + +
+ Download file +
+
+
+ Delivered +
+
+
+
+ """ +end + +defp render_image_attachment(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:image_src, assigns[:image_src]) + |> assign(:image_alt, assigns[:image_alt]) + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+
+
+ <%= @author %> + <%= @time %> +
+

<%= @message %>

+ +
+
+ + +
+ Download image +
+
+ {@image_alt} +
+ Delivered +
+
+
+
+ """ +end + +defp render_image_gallery(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:images, assigns[:images] || []) + |> assign(:extra_images_count, assigns[:extra_images_count] || 0) + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+
+
+ <%= @author %> + <%= @time %> +
+

<%= @message %>

+ + +
+ + <%= for {img, _index} <- Enum.with_index(Enum.take(@images, 3)) do %> +
+
+ + +
+ Download image +
+
+ +
+ <% end %> + + +
+ +
+ View more +
+ <%= if length(@images) > 3 do %> + + <% else %> +
+ <% end %> +
+
+ +
+ Delivered + +
+
+
+
+
+ """ +end + +defp render_url_preview_sharing(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:url, assigns[:url]) + |> assign(:url_title, assigns[:url_title]) + |> assign(:url_description, assigns[:url_description]) + |> assign(:url_image, assigns[:url_image]) + |> assign(:url_domain, assigns[:url_domain]) + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +

<%= @message %>

+

+ <%= @url %> +

+ + +
+

<%= @url_title %>

+

<%= @url_description %>

+ + + <%= @url_domain %> + +
+
+ Delivered +
+
+
+ """ +end + +defp render_outline_chat_bubble(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +
+

<%= @message %>

+
+ Delivered +
+
+
+ """ +end + +defp render_outline_voicenote(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +
+ <%= render_waveform(assigns) %> +
+ Delivered +
+
+
+ """ +end + +defp render_outline_file_attachment(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:file_name, assigns[:file_name]) + |> assign(:file_size, assigns[:file_size]) + |> assign(:file_pages, assigns[:file_pages]) + |> assign(:file_type, assigns[:file_type]) + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +
+
+
+ + + <%= @file_name %> + + + <%= @file_pages %> + + <%= @file_size %> + + <%= @file_type %> + +
+ +
+ +
+ Download file +
+
+
+
+ Delivered +
+
+
+ """ +end + +defp render_outline_image_attachment(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:image_src, assigns[:image_src]) + |> assign(:image_alt, assigns[:image_alt]) + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +

<%= @message %>

+
+
+
+ +
+ Download image +
+
+ {@image_alt} +
+
+ Delivered +
+
+
+ """ +end + +defp render_outline_image_gallery(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:images, assigns[:images] || []) + |> assign(:extra_images_count, assigns[:extra_images_count] || 0) + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +

<%= @message %>

+
+ +
+ <%= for {img, _index} <- Enum.with_index(Enum.take(@images, 3)) do %> +
+
+ +
+ Download image +
+
+ +
+ <% end %> + +
+ +
+ View more +
+ <%= if length(@images) > 3 do %> + + <% else %> +
+ <% end %> +
+
+ + +
+ +
+
+ Delivered +
+
+
+ """ +end + +defp render_outline_url_preview_sharing(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:url, assigns[:url]) + |> assign(:url_title, assigns[:url_title]) + |> assign(:url_description, assigns[:url_description]) + |> assign(:url_image, assigns[:url_image]) + |> assign(:url_domain, assigns[:url_domain]) + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +

<%= @message %>

+ + Delivered +
+
+
+ """ +end + +defp render_clean_chat_bubble(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +

<%= @message %>

+ Delivered +
+
+
+ """ +end + +defp render_clean_voicenote(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> + <%= render_waveform(assigns) %> + Delivered +
+
+
+ """ +end + +defp render_clean_file_attachment(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:file_name, assigns[:file_name]) + |> assign(:file_size, assigns[:file_size]) + |> assign(:file_pages, assigns[:file_pages]) + |> assign(:file_type, assigns[:file_type]) + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +
+
+ + + <%= @file_name %> + + + <%= @file_pages %> + + <%= @file_size %> + + <%= @file_type %> + +
+
+ +
+ Download file +
+
+
+ Delivered +
+
+
+ """ +end + +defp render_clean_image_attachment(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:image_src, assigns[:image_src]) + |> assign(:image_alt, assigns[:image_alt]) + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +
+

<%= @message %>

+
+
+
+
+ + +
+ Download image +
+
+ {@image_alt} +
+
+ Delivered +
+
+
+ """ +end + +defp render_clean_image_gallery(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:images, assigns[:images] || []) + |> assign(:extra_images_count, assigns[:extra_images_count] || 0) + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +

<%= @message %>

+
+ +
+ + <%= for {img, _index} <- Enum.with_index(Enum.take(@images, 3)) do %> +
+
+ + +
+ Download image +
+
+ +
+ <% end %> + + +
+ +
+ View more +
+ <%= if length(@images) > 3 do %> + + <% else %> +
+ <% end %> +
+
+
+ Delivered + +
+ +
+
+
+
+ """ +end + +defp render_clean_url_preview_sharing(assigns) do + assigns = + assigns + |> assign(:author, assigns[:author]) + |> assign(:message, assigns[:message]) + |> assign(:time, assigns[:time]) + |> assign(:avatar_src, assigns[:avatar_src]) + |> assign(:avatar_alt, assigns[:avatar_alt] || "#{assigns[:author]} image") + |> assign(:url, assigns[:url]) + |> assign(:url_title, assigns[:url_title]) + |> assign(:url_description, assigns[:url_description]) + |> assign(:url_image, assigns[:url_image]) + |> assign(:url_domain, assigns[:url_domain]) + |> assign(:class, assigns[:class]) + |> assign(:rest, assigns[:rest]) + + ~H""" +
+
+ {@avatar_alt} +
+ <%= render_header(assigns) %> +

<%= @message %>

+

+ <%= @url %> +

+ + +
+

<%= @url_title %>

+

<%= @url_description %>

+ + + <%= @url_domain %> + +
+
+ Delivered +
+
+
+ """ +end + +end diff --git a/test/petal/chat_bubble_test.exs b/test/petal/chat_bubble_test.exs new file mode 100644 index 00000000..e0a05850 --- /dev/null +++ b/test/petal/chat_bubble_test.exs @@ -0,0 +1,426 @@ +defmodule PetalComponents.ChatBubbleTest do + use ComponentCase + import PetalComponents.ChatBubble + +test "default chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + author="Test User" + message="Hello world" + time="12:45" + /> + """) + + assert html =~ "Test User" + assert html =~ "Hello world" + assert html =~ "12:45" + assert html =~ "Delivered" + assert html =~ "pc-chat-bubble--default" +end + +test "voice note chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:voicenote} + author="Voice User" + time="15:20" + duration="2:15" + /> + """) + + assert html =~ "Voice User" + assert html =~ "15:20" + assert html =~ "2:15" + assert html =~ "pc-chat-bubble--voice-note" + assert html =~ ~s( + """) + + assert html =~ "File User" + assert html =~ "16:45" + assert html =~ "Petal Components Terms & Conditions" + assert html =~ "18 MB" + assert html =~ "12 Pages" + assert html =~ "PDF" + assert html =~ "pc-chat-bubble--file-attachment" + assert html =~ "Download file" +end + +test "image attachment chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:image_attachment} + author="Image User" + time="17:00" + image_src="https://example.com/image.jpg" + image_alt="Example image" + /> + """) + + assert html =~ "Image User" + assert html =~ "17:00" + assert html =~ ~s(src="https://example.com/image.jpg") + assert html =~ ~s(alt="Example image") + assert html =~ "pc-chat-bubble--image-attachment" +end + +test "image gallery chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:image_gallery} + author="Gallery User" + time="18:00" + images={[ + "https://example.com/image1.jpg", + "https://example.com/image2.jpg", + "https://example.com/image3.jpg", + "https://example.com/image4.jpg" + ]} + extra_images_count={2} + /> + """) + + assert html =~ "Gallery User" + assert html =~ "18:00" + assert html =~ ~s(src="https://example.com/image1.jpg") + assert html =~ ~s(src="https://example.com/image2.jpg") + assert html =~ ~s(src="https://example.com/image3.jpg") + assert html =~ ~s(src="https://example.com/image4.jpg") + assert html =~ "pc-chat-bubble--image-gallery" +end + +test "URL preview sharing chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:url_preview_sharing} + author="URL User" + time="19:00" + url="https://example.com" + url_title="Example Title" + url_description="Example Description" + url_image="https://example.com/image.jpg" + url_domain="example.com" + /> + """) + + assert html =~ "URL User" + assert html =~ "19:00" + assert html =~ ~s(href="https://example.com") + assert html =~ "Example Title" + assert html =~ "Example Description" + assert html =~ ~s(src="https://example.com/image.jpg") + assert html =~ "example.com" + assert html =~ "pc-chat-bubble--url-preview" +end + +test "outline chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:outline_chat_bubble} + author="Outline User" + time="20:00" + message="Outline message" + /> + """) + + assert html =~ "Outline User" + assert html =~ "20:00" + assert html =~ "Outline message" + assert html =~ "Delivered" + assert html =~ "pc-chat-bubble--outline-chat-bubble" +end + +test "outline voicenote chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:outline_voicenote} + author="Outline Voice User" + time="23:00" + duration="3:00" + /> + """) + + assert html =~ "Outline Voice User" + assert html =~ "23:00" + assert html =~ "3:00" + assert html =~ "pc-chat-bubble--outline-voicenote" + assert html =~ ~s( + """) + + assert html =~ "Outline File User" + assert html =~ "00:00" + assert html =~ "Outline File.pdf" + assert html =~ "10 MB" + assert html =~ "5 Pages" + assert html =~ "PDF" + assert html =~ "pc-chat-bubble--outline-file-attachment" + assert html =~ "Download file" +end + +test "outline image attachment chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:outline_image_attachment} + author="Outline Image User" + time="01:00" + image_src="https://example.com/outline_image.jpg" + image_alt="Outline Example Image" + /> + """) + + assert html =~ "Outline Image User" + assert html =~ "01:00" + assert html =~ ~s(src="https://example.com/outline_image.jpg") + assert html =~ ~s(alt="Outline Example Image") + assert html =~ "pc-chat-bubble--outline-image-attachment" +end + +test "outline image gallery chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:outline_image_gallery} + author="Outline Gallery User" + time="01:00" + images={[ + "https://example.com/image1.jpg", + "https://example.com/image2.jpg", + "https://example.com/image3.jpg" + ]} + extra_images_count={5} + /> + """) + + assert html =~ "Outline Gallery User" + assert html =~ "01:00" + assert html =~ "pc-chat-bubble--outline-image-gallery" + assert html =~ ~s(src="https://example.com/image1.jpg") + assert html =~ ~s(src="https://example.com/image2.jpg") + assert html =~ ~s(src="https://example.com/image3.jpg") + assert html =~ "+5" +end + +test "outline URL preview sharing chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:outline_url_preview_sharing} + author="Outline URL User" + time="22:00" + url="https://example.com" + url_title="Outline Example Title" + url_description="Outline Example Description" + url_image="https://example.com/image.jpg" + url_domain="example.com" + /> + """) + + assert html =~ "Outline URL User" + assert html =~ "22:00" + assert html =~ ~s(href="https://example.com") + assert html =~ "Outline Example Title" + assert html =~ "Outline Example Description" + assert html =~ ~s(src="https://example.com/image.jpg") + assert html =~ "example.com" + assert html =~ "pc-chat-bubble--outline-url-preview" +end + +test "clean chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:clean_chat_bubble} + author="Clean User" + time="21:00" + message="Clean message" + /> + """) + + assert html =~ "Clean User" + assert html =~ "21:00" + assert html =~ "Clean message" + assert html =~ "Delivered" + assert html =~ "pc-chat-bubble--clean-chat-bubble" +end + +test "clean voicenote chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:clean_voicenote} + author="Clean Voice User" + time="23:00" + duration="3:00" + /> + """) + + assert html =~ "Clean Voice User" + assert html =~ "23:00" + assert html =~ "3:00" + assert html =~ "pc-chat-bubble--clean-voicenote" + assert html =~ ~s( + """) + + assert html =~ "Clean File User" + assert html =~ "00:00" + assert html =~ "Clean File.pdf" + assert html =~ "10 MB" + assert html =~ "5 Pages" + assert html =~ "PDF" + assert html =~ "pc-chat-bubble--clean-file-attachment" + assert html =~ "Download file" +end + +test "clean image attachment chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:clean_image_attachment} + author="Clean Image User" + time="02:00" + image_src="https://example.com/clean_image.jpg" + image_alt="Clean Example Image" + /> + """) + + assert html =~ "Clean Image User" + assert html =~ "02:00" + assert html =~ ~s(src="https://example.com/clean_image.jpg") + assert html =~ ~s(alt="Clean Example Image") + assert html =~ "pc-chat-bubble--clean-image-attachment" +end + +test "clean image gallery chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:clean_image_gallery} + author="Clean Gallery User" + time="03:00" + images={[ + "https://example.com/image1.jpg", + "https://example.com/image2.jpg", + "https://example.com/image3.jpg" + ]} + extra_images_count={4} + /> + """) + + assert html =~ "Clean Gallery User" + assert html =~ "03:00" + assert html =~ "pc-chat-bubble--clean-image-gallery" + assert html =~ ~s(src="https://example.com/image1.jpg") + assert html =~ ~s(src="https://example.com/image2.jpg") + assert html =~ ~s(src="https://example.com/image3.jpg") + assert html =~ "+4" +end + +test "clean URL preview sharing chat bubble" do + assigns = %{} + + html = + rendered_to_string(~H""" + <.chat_bubble + kind={:clean_url_preview_sharing} + author="Clean URL User" + time="02:00" + url="https://example.com" + url_title="Clean Example Title" + url_description="Clean Example Description" + url_image="https://example.com/image.jpg" + url_domain="example.com" + /> + """) + + assert html =~ "Clean URL User" + assert html =~ "02:00" + assert html =~ ~s(href="https://example.com") + assert html =~ "Clean Example Title" + assert html =~ "Clean Example Description" + assert html =~ ~s(src="https://example.com/image.jpg") + assert html =~ "example.com" + assert html =~ "pc-chat-bubble--clean-url-preview" +end +end \ No newline at end of file