From f28fcc59d0fb39edd1fc20ac41073ee9c880a83d Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Fri, 15 Nov 2019 23:38:42 -0500 Subject: [PATCH] add conversations controller/templates --- lib/philomena/conversations/conversation.ex | 2 + lib/philomena/users/ability.ex | 8 ++++ .../controllers/conversation_controller.ex | 44 +++++++++++++++++++ lib/philomena_web/router.ex | 1 + .../templates/conversation/index.html.slime | 34 ++++++++++++++ .../templates/conversation/show.html.slime | 22 ++++++++++ .../templates/message/_message.html.slime | 18 ++++++++ .../templates/notification/_forum.html.slime | 2 +- .../notification/_gallery.html.slime | 2 +- .../templates/notification/_image.html.slime | 2 +- .../notification/_notification.html.slime | 2 +- .../templates/notification/_topic.html.slime | 2 +- .../templates/notification/index.html.slime | 2 +- lib/philomena_web/views/conversation_view.ex | 9 ++++ lib/philomena_web/views/message_view.ex | 3 ++ 15 files changed, 147 insertions(+), 6 deletions(-) create mode 100644 lib/philomena_web/controllers/conversation_controller.ex create mode 100644 lib/philomena_web/templates/conversation/index.html.slime create mode 100644 lib/philomena_web/templates/conversation/show.html.slime create mode 100644 lib/philomena_web/templates/message/_message.html.slime create mode 100644 lib/philomena_web/views/conversation_view.ex create mode 100644 lib/philomena_web/views/message_view.ex diff --git a/lib/philomena/conversations/conversation.ex b/lib/philomena/conversations/conversation.ex index 7db30650..70060db8 100644 --- a/lib/philomena/conversations/conversation.ex +++ b/lib/philomena/conversations/conversation.ex @@ -2,6 +2,8 @@ defmodule Philomena.Conversations.Conversation do use Ecto.Schema import Ecto.Changeset + @derive {Phoenix.Param, key: :slug} + schema "conversations" do belongs_to :from, Philomena.Users.User belongs_to :to, Philomena.Users.User diff --git a/lib/philomena/users/ability.ex b/lib/philomena/users/ability.ex index f16d604e..dc575c4f 100644 --- a/lib/philomena/users/ability.ex +++ b/lib/philomena/users/ability.ex @@ -1,6 +1,7 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do alias Philomena.Users.User alias Philomena.Comments.Comment + alias Philomena.Conversations.Conversation alias Philomena.Images.Image alias Philomena.Forums.Forum alias Philomena.Topics.Topic @@ -27,6 +28,9 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do when level in ["normal", "assistant", "staff"], do: true def can?(%User{role: "moderator"}, :show, %Topic{hidden_from_users: true}), do: true + # View conversations + def can?(%User{role: "moderator"}, :show, %Conversation{}), do: true + # # Assistants can... # @@ -43,6 +47,10 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do # Users and anonymous users can... # + # View conversations they are involved in + def can?(%User{id: id}, :show, %Conversation{to_id: id}), do: true + def can?(%User{id: id}, :show, %Conversation{from_id: id}), do: true + # View filters they own and system filters def can?(_user, :show, %Filter{system: true}), do: true def can?(%User{id: id}, :show, %Filter{user_id: id}), do: true diff --git a/lib/philomena_web/controllers/conversation_controller.ex b/lib/philomena_web/controllers/conversation_controller.ex new file mode 100644 index 00000000..5bf87df7 --- /dev/null +++ b/lib/philomena_web/controllers/conversation_controller.ex @@ -0,0 +1,44 @@ +defmodule PhilomenaWeb.ConversationController do + use PhilomenaWeb, :controller + + alias Philomena.Conversations.{Conversation, Message} + alias Philomena.Textile.Renderer + alias Philomena.Repo + import Ecto.Query + + plug PhilomenaWeb.Plugs.FilterBannedUsers when action in [:new, :create] + plug :load_and_authorize_resource, model: Conversation, id_field: "slug", only: :show + + def index(conn, _params) do + user = conn.assigns.current_user + + conversations = + Conversation + |> where([c], (c.from_id == ^user.id and not c.from_hidden) or (c.to_id == ^user.id and not c.to_hidden)) + |> order_by(desc: :last_message_at) + |> preload([:to, :from]) + |> Repo.paginate(conn.assigns.scrivener) + + render(conn, "index.html", conversations: conversations) + end + + def show(conn, _params) do + conversation = conn.assigns.conversation + + messages = + Message + |> where(conversation_id: ^conversation.id) + |> order_by(asc: :created_at) + |> preload([:from]) + |> Repo.paginate(conn.assigns.scrivener) + + rendered = + messages.entries + |> Renderer.render_collection() + + messages = + %{messages | entries: Enum.zip(messages.entries, rendered)} + + render(conn, "index.html", conversation: conversation, messages: messages) + end +end \ No newline at end of file diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index f4afaea7..72442d2f 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -53,6 +53,7 @@ defmodule PhilomenaWeb.Router do pipe_through [:browser, :ensure_totp, :protected] resources "/notifications", NotificationController, only: [:index, :delete] + resources "/conversations", ConversationController, only: [:index, :show] end scope "/", PhilomenaWeb do diff --git a/lib/philomena_web/templates/conversation/index.html.slime b/lib/philomena_web/templates/conversation/index.html.slime new file mode 100644 index 00000000..422e621e --- /dev/null +++ b/lib/philomena_web/templates/conversation/index.html.slime @@ -0,0 +1,34 @@ +elixir: + route = fn p -> Routes.conversation_path(@conn, :index, p) end + pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @conversations, route: route, conn: @conn + +h1 My Conversations +.block + .block__header + = pagination + + .block__content + table.table.table--communication-list + thead + tr + th.table--communication-list__name Conversation + th.table--communication-list__stats With + th.table--communication-list__options Options + tbody + = for c <- @conversations do + td.table--communication-list__name + => link c.title, to: Routes.conversation_path(@conn, :show, c) + + .small-text.hide-mobile + ' Started + = pretty_time(c.created_at) + ' , last message + = pretty_time(c.last_message_at) + + td.table--communication-list__stats + = render PhilomenaWeb.UserAttributionView, "_user.html", object: %{user: other_party(@current_user.id, c)}, conn: @conn + td.table--communication-list__options + | Last message + + .block__header.block__header--light + = pagination \ No newline at end of file diff --git a/lib/philomena_web/templates/conversation/show.html.slime b/lib/philomena_web/templates/conversation/show.html.slime new file mode 100644 index 00000000..c9902bd0 --- /dev/null +++ b/lib/philomena_web/templates/conversation/show.html.slime @@ -0,0 +1,22 @@ +elixir: + route = fn p -> Routes.conversation_path(@conn, :show, @conversation, p) end + pagination = render PhilomenaWeb.PaginationView, "_pagination.html", page: @messages, route: route, conn: @conn + other = other_party(@current_user.id, @conversation) + +h1 = @conversation.title +.block + .block__header + => link "Message Center", to: Routes.conversation_path(@conn, :index) + ' » + => link @conversation.title, to: Routes.conversation_path(@conn, :show, @conversation) + ' Conversation with + => render PhilomenaWeb.UserAttributionView, "_user.html", object: %{user: other}, conn: @conn + .block__header--sub.block__header--light + = pagination + += for {message, body} <- @messages do + = render PhilomenaWeb.MessageView, "_message.html", message: message, body: body, conn: @conn + +.block + .block__header.block__header--light + = pagination diff --git a/lib/philomena_web/templates/message/_message.html.slime b/lib/philomena_web/templates/message/_message.html.slime new file mode 100644 index 00000000..d8b0a484 --- /dev/null +++ b/lib/philomena_web/templates/message/_message.html.slime @@ -0,0 +1,18 @@ +article.block.communication + .block__content.flex.flex--no-wrap + .flex__fixed.spacing-right + = render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: @message.from}, conn: @conn, class: "avatar--100px" + .flex__grow.communication__body + span.communication__body__sender-name + = render PhilomenaWeb.UserAttributionView, "_user.html", object: %{user: @message.from}, badges: true, conn: @conn + + br + + .communication__body__text + == @body + + .block__content.communication__options + .flex.flex--wrap.flex--spaced-out + div + ' Posted + = pretty_time(@message.created_at) diff --git a/lib/philomena_web/templates/notification/_forum.html.slime b/lib/philomena_web/templates/notification/_forum.html.slime index 81fcfcfa..d62746ed 100644 --- a/lib/philomena_web/templates/notification/_forum.html.slime +++ b/lib/philomena_web/templates/notification/_forum.html.slime @@ -1,7 +1,7 @@ - forum = @notification.actor - topic = @notification.actor_child -=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: topic +=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: topic, conn: @conn => @notification.action ' titled diff --git a/lib/philomena_web/templates/notification/_gallery.html.slime b/lib/philomena_web/templates/notification/_gallery.html.slime index cc25b25d..3e2f9599 100644 --- a/lib/philomena_web/templates/notification/_gallery.html.slime +++ b/lib/philomena_web/templates/notification/_gallery.html.slime @@ -1,4 +1,4 @@ -=> render PhilomenaWeb.UserAttributionView, "_user.html", object: %{user: @notification.actor.creator} +=> render PhilomenaWeb.UserAttributionView, "_user.html", object: %{user: @notification.actor.creator}, conn: @conn => @notification.action strong> diff --git a/lib/philomena_web/templates/notification/_image.html.slime b/lib/philomena_web/templates/notification/_image.html.slime index 7ab04e72..72d04b10 100644 --- a/lib/philomena_web/templates/notification/_image.html.slime +++ b/lib/philomena_web/templates/notification/_image.html.slime @@ -1,4 +1,4 @@ -=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @notification.actor_child +=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @notification.actor_child, conn: @conn => @notification.action strong diff --git a/lib/philomena_web/templates/notification/_notification.html.slime b/lib/philomena_web/templates/notification/_notification.html.slime index d076099e..b51180d2 100644 --- a/lib/philomena_web/templates/notification/_notification.html.slime +++ b/lib/philomena_web/templates/notification/_notification.html.slime @@ -5,7 +5,7 @@ = render PhilomenaWeb.ImageView, "_image_container.html", image: @notification.actor, size: :thumb_tiny, conn: @conn .flex.flex--centered.flex__grow div - => render PhilomenaWeb.NotificationView, notification_template_path(@notification.actor_type), notification: @notification + => render PhilomenaWeb.NotificationView, notification_template_path(@notification.actor_type), notification: @notification, conn: @conn => pretty_time @notification.updated_at .flex.flex--centered.flex--no-wrap a.button.button--separate-right title="Delete" data-click-markread=@notification.id diff --git a/lib/philomena_web/templates/notification/_topic.html.slime b/lib/philomena_web/templates/notification/_topic.html.slime index d2edd3bc..fa6a2eda 100644 --- a/lib/philomena_web/templates/notification/_topic.html.slime +++ b/lib/philomena_web/templates/notification/_topic.html.slime @@ -1,7 +1,7 @@ - topic = @notification.actor - post = @notification.actor_child -=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: post +=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: post, conn: @conn => @notification.action strong diff --git a/lib/philomena_web/templates/notification/index.html.slime b/lib/philomena_web/templates/notification/index.html.slime index 508a13cc..ad9d51d4 100644 --- a/lib/philomena_web/templates/notification/index.html.slime +++ b/lib/philomena_web/templates/notification/index.html.slime @@ -3,7 +3,7 @@ h1 Notification Area .walloftext .block__header - = render PhilomenaWeb.PaginationView, "_pagination.html", page: @notifications, route: route + = render PhilomenaWeb.PaginationView, "_pagination.html", page: @notifications, route: route, conn: @conn = for notification <- @notifications do = render PhilomenaWeb.NotificationView, "_notification.html", notification: notification diff --git a/lib/philomena_web/views/conversation_view.ex b/lib/philomena_web/views/conversation_view.ex new file mode 100644 index 00000000..b4c2c1d7 --- /dev/null +++ b/lib/philomena_web/views/conversation_view.ex @@ -0,0 +1,9 @@ +defmodule PhilomenaWeb.ConversationView do + use PhilomenaWeb, :view + + def other_party(user_id, %{to_id: user_id} = conversation), + do: conversation.from + + def other_party(_user_id, conversation), + do: conversation.to +end \ No newline at end of file diff --git a/lib/philomena_web/views/message_view.ex b/lib/philomena_web/views/message_view.ex new file mode 100644 index 00000000..b57e0623 --- /dev/null +++ b/lib/philomena_web/views/message_view.ex @@ -0,0 +1,3 @@ +defmodule PhilomenaWeb.MessageView do + use PhilomenaWeb, :view +end \ No newline at end of file