mirror of
https://github.com/philomena-dev/philomena.git
synced 2025-01-19 22:27:59 +01:00
add conversations controller/templates
This commit is contained in:
parent
02fc81f23b
commit
f28fcc59d0
15 changed files with 147 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
44
lib/philomena_web/controllers/conversation_controller.ex
Normal file
44
lib/philomena_web/controllers/conversation_controller.ex
Normal file
|
@ -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
|
|
@ -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
|
||||
|
|
34
lib/philomena_web/templates/conversation/index.html.slime
Normal file
34
lib/philomena_web/templates/conversation/index.html.slime
Normal file
|
@ -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
|
22
lib/philomena_web/templates/conversation/show.html.slime
Normal file
22
lib/philomena_web/templates/conversation/show.html.slime
Normal file
|
@ -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
|
18
lib/philomena_web/templates/message/_message.html.slime
Normal file
18
lib/philomena_web/templates/message/_message.html.slime
Normal file
|
@ -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)
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
9
lib/philomena_web/views/conversation_view.ex
Normal file
9
lib/philomena_web/views/conversation_view.ex
Normal file
|
@ -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
|
3
lib/philomena_web/views/message_view.ex
Normal file
3
lib/philomena_web/views/message_view.ex
Normal file
|
@ -0,0 +1,3 @@
|
|||
defmodule PhilomenaWeb.MessageView do
|
||||
use PhilomenaWeb, :view
|
||||
end
|
Loading…
Reference in a new issue