add notification controller

This commit is contained in:
byte[] 2019-11-15 22:50:58 -05:00
parent 7f309f649e
commit 02fc81f23b
12 changed files with 131 additions and 1 deletions

View file

@ -17,12 +17,20 @@ defmodule Philomena.Polymorphic do
"User" => Philomena.Users.User
}
@preloads %{
"Comment" => [:user],
"Gallery" => [:creator],
"Image" => [:user],
"Post" => [:user],
"Topic" => [:forum, :user]
}
# Deal with Rails polymorphism BS
def load_polymorphic(structs, associations) when is_list(associations) do
Enum.reduce(associations, structs, fn asc, acc -> load_polymorphic(acc, asc) end)
end
def load_polymorphic(structs, {name, {id, type}}) do
def load_polymorphic(structs, {name, [{id, type}]}) do
modules_and_ids =
structs
|> Enum.group_by(&Map.get(&1, type), &Map.get(&1, id))
@ -34,9 +42,11 @@ defmodule Philomena.Polymorphic do
{nil, []}
{type, ids} ->
pre = Map.get(@preloads, type, [])
rows =
@classes[type]
|> where([m], m.id in ^ids)
|> preload(^pre)
|> Repo.all()
|> Map.new(fn r -> {r.id, r} end)

View file

@ -21,6 +21,8 @@ defmodule Philomena.Users.User do
has_many :public_links, Philomena.UserLinks.UserLink, where: [public: true, aasm_state: "verified"]
has_many :galleries, Philomena.Galleries.Gallery, foreign_key: :creator_id
has_many :awards, Philomena.Badges.Award
has_many :unread_notifications, Philomena.Notifications.UnreadNotification
has_many :notifications, through: [:unread_notifications, :notification]
belongs_to :current_filter, Philomena.Filters.Filter
belongs_to :deleted_by_user, Philomena.Users.User

View file

@ -0,0 +1,33 @@
defmodule PhilomenaWeb.NotificationController do
use PhilomenaWeb, :controller
alias Philomena.Notifications.{UnreadNotification, Notification}
alias Philomena.Polymorphic
alias Philomena.Repo
import Ecto.Query
def index(conn, _params) do
user = conn.assigns.current_user
notifications =
from n in Notification,
join: un in UnreadNotification, on: un.notification_id == n.id,
where: un.user_id == ^user.id
notifications =
notifications
|> Repo.paginate(conn.assigns.scrivener)
entries =
notifications.entries
|> Polymorphic.load_polymorphic(
actor: [actor_id: :actor_type],
actor_child: [actor_child_id: :actor_child_type]
)
notifications =
%{notifications | entries: entries}
render(conn, "index.html", notifications: notifications)
end
end

View file

@ -49,6 +49,12 @@ defmodule PhilomenaWeb.Router do
end
end
scope "/", PhilomenaWeb do
pipe_through [:browser, :ensure_totp, :protected]
resources "/notifications", NotificationController, only: [:index, :delete]
end
scope "/", PhilomenaWeb do
pipe_through [:browser, :ensure_totp]

View file

@ -0,0 +1,4 @@
strong>
= link @notification.actor.title, to: "#"
/= link @notification.actor.title, to: Routes.channel_path(@conn, :show, notification.actor)
=<> @notification.action

View file

@ -0,0 +1,14 @@
- forum = @notification.actor
- topic = @notification.actor_child
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: topic
=> @notification.action
' titled
strong>
= link topic.title, to: Routes.forum_topic_path(@conn, :show, forum, topic)
' in
=> link forum.name, to: Routes.forum_path(@conn, :show, forum)

View file

@ -0,0 +1,6 @@
=> render PhilomenaWeb.UserAttributionView, "_user.html", object: %{user: @notification.actor.creator}
=> @notification.action
strong>
= link @notification.actor.title, to: "#"
/= link @notification.actor.title, to: Routes.gallery_path(@conn, :show, @notification.actor)

View file

@ -0,0 +1,5 @@
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @notification.actor_child
=> @notification.action
strong
= link "##{@notification.actor_id}", to: Routes.image_path(@conn, :show, @notification.actor) <> "#comments"

View file

@ -0,0 +1,14 @@
= if @notification.actor do
.block.block--fixed.flex class="js-notification-id-#{@notification.id}"
= if @notification.actor_type == "Image" and @notification.actor do
.flex.flex--centered.flex__fixed.thumb-tiny-container.spacing-right
= 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
=> pretty_time @notification.updated_at
.flex.flex--centered.flex--no-wrap
a.button.button--separate-right title="Delete" data-click-markread=@notification.id
i.fa.fa-trash
a.button title="Unsubscribe" data-subscription-id=@notification.actor_id data-subscription-type=@notification.actor_type data-click-togglesubscription="unwatch" data-click-hide=".js-notification-id-#{@notification.id}"
.fa.fa-bell-slash

View file

@ -0,0 +1,8 @@
- topic = @notification.actor
- post = @notification.actor_child
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: post
=> @notification.action
strong
= link topic.title, to: Routes.forum_topic_path(@conn, :show, topic.forum, topic, post_id: post.id) <> "#post_#{post.id}"

View file

@ -0,0 +1,12 @@
- route = fn p -> Routes.notification_path(@conn, :index, p) end
h1 Notification Area
.walloftext
.block__header
= render PhilomenaWeb.PaginationView, "_pagination.html", page: @notifications, route: route
= for notification <- @notifications do
= render PhilomenaWeb.NotificationView, "_notification.html", notification: notification
p To get notifications on new comments and forum posts, click the 'Subscribe' button in the bar at the top of an image or forum topic. You'll get notifications here for any new posts or comments.
p By default you'll be subscribed to any images or topics you reply to. You can configure this in your user settings page.

View file

@ -0,0 +1,16 @@
defmodule PhilomenaWeb.NotificationView do
use PhilomenaWeb, :view
@template_paths %{
"Channel" => "_channel.html",
"Forum" => "_forum.html",
"Gallery" => "_gallery.html",
"Image" => "_image.html",
"LivestreamChannel" => "_channel.html",
"Topic" => "_topic.html"
}
def notification_template_path(actor_type) do
@template_paths[actor_type]
end
end