mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-30 14:57:59 +01:00
add topic subscriptions
This commit is contained in:
parent
8131782a20
commit
f9bdda08a7
7 changed files with 95 additions and 70 deletions
|
@ -104,35 +104,13 @@ defmodule Philomena.Topics do
|
|||
|
||||
alias Philomena.Topics.Subscription
|
||||
|
||||
@doc """
|
||||
Returns the list of topic_subscriptions.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_topic_subscriptions()
|
||||
[%Subscription{}, ...]
|
||||
|
||||
"""
|
||||
def list_topic_subscriptions do
|
||||
Repo.all(Subscription)
|
||||
def subscribed?(topic, nil), do: false
|
||||
def subscribed?(topic, user) do
|
||||
Subscription
|
||||
|> where(topic_id: ^topic.id, user_id: ^user.id)
|
||||
|> Repo.exists?()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single subscription.
|
||||
|
||||
Raises `Ecto.NoResultsError` if the Subscription does not exist.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_subscription!(123)
|
||||
%Subscription{}
|
||||
|
||||
iex> get_subscription!(456)
|
||||
** (Ecto.NoResultsError)
|
||||
|
||||
"""
|
||||
def get_subscription!(id), do: Repo.get!(Subscription, id)
|
||||
|
||||
@doc """
|
||||
Creates a subscription.
|
||||
|
||||
|
@ -145,28 +123,10 @@ defmodule Philomena.Topics do
|
|||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_subscription(attrs \\ %{}) do
|
||||
%Subscription{}
|
||||
|> Subscription.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Updates a subscription.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> update_subscription(subscription, %{field: new_value})
|
||||
{:ok, %Subscription{}}
|
||||
|
||||
iex> update_subscription(subscription, %{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def update_subscription(%Subscription{} = subscription, attrs) do
|
||||
subscription
|
||||
|> Subscription.changeset(attrs)
|
||||
|> Repo.update()
|
||||
def create_subscription(topic, user) do
|
||||
%Subscription{topic_id: topic.id, user_id: user.id}
|
||||
|> Subscription.changeset(%{})
|
||||
|> Repo.insert(on_conflict: :nothing)
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -181,20 +141,8 @@ defmodule Philomena.Topics do
|
|||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_subscription(%Subscription{} = subscription) do
|
||||
Repo.delete(subscription)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns an `%Ecto.Changeset{}` for tracking subscription changes.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> change_subscription(subscription)
|
||||
%Ecto.Changeset{source: %Subscription{}}
|
||||
|
||||
"""
|
||||
def change_subscription(%Subscription{} = subscription) do
|
||||
Subscription.changeset(subscription, %{})
|
||||
def delete_subscription(topic, user) do
|
||||
%Subscription{topic_id: topic.id, user_id: user.id}
|
||||
|> Repo.delete()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
defmodule PhilomenaWeb.Topic.SubscriptionController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.{Topics, Topics.Topic, Forums.Forum}
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
||||
plug PhilomenaWeb.Plugs.CanaryMapPlug, create: :show, delete: :show
|
||||
plug :load_and_authorize_resource, model: Forum, id_name: "forum_id", id_field: "short_name", persisted: true
|
||||
|
||||
def create(conn, %{"topic_id" => slug}) do
|
||||
topic = load_topic(conn, slug)
|
||||
user = conn.assigns.current_user
|
||||
|
||||
case Topics.create_subscription(topic, user) do
|
||||
{:ok, _subscription} ->
|
||||
render(conn, "_subscription.html", forum: conn.assigns.forum, topic: topic, watching: true, layout: false)
|
||||
|
||||
{:error, _changeset} ->
|
||||
render(conn, "_error.html", layout: false)
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, %{"topic_id" => slug}) do
|
||||
topic = load_topic(conn, slug)
|
||||
user = conn.assigns.current_user
|
||||
|
||||
case Topics.delete_subscription(topic, user) do
|
||||
{:ok, _subscription} ->
|
||||
render(conn, "_subscription.html", forum: conn.assigns.forum, topic: topic, watching: false, layout: false)
|
||||
|
||||
{:error, _changeset} ->
|
||||
render(conn, "_error.html", layout: false)
|
||||
end
|
||||
end
|
||||
|
||||
defp load_topic(conn, slug) do
|
||||
forum = conn.assigns.forum
|
||||
topic =
|
||||
Topic
|
||||
|> where(forum_id: ^forum.id, slug: ^slug, hidden_from_users: false)
|
||||
|> preload(:user)
|
||||
|> Repo.one()
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
defmodule PhilomenaWeb.TopicController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.{Forums.Forum, Topics.Topic, Posts.Post, Textile.Renderer}
|
||||
alias Philomena.{Forums.Forum, Topics, Topics.Topic, Posts.Post, Textile.Renderer}
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
||||
|
@ -51,6 +51,9 @@ defmodule PhilomenaWeb.TopicController do
|
|||
total_pages: div(topic.post_count + 25 - 1, 25)
|
||||
}
|
||||
|
||||
render(conn, "show.html", posts: posts)
|
||||
watching =
|
||||
Topics.subscribed?(topic, conn.assigns.current_user)
|
||||
|
||||
render(conn, "show.html", posts: posts, watching: watching)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -60,6 +60,12 @@ defmodule PhilomenaWeb.Router do
|
|||
resources "/hide", Image.HideController, only: [:create, :delete], singleton: true
|
||||
resources "/subscription", Image.SubscriptionController, only: [:create, :delete], singleton: true
|
||||
end
|
||||
|
||||
resources "/forums", ForumController, only: [] do
|
||||
resources "/topics", TopicController, only: [] do
|
||||
resources "/subscription", Topic.SubscriptionController, only: [:create, :delete], singleton: true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
scope "/", PhilomenaWeb do
|
||||
|
|
|
@ -24,10 +24,7 @@ h1 = @topic.title
|
|||
.flex--fixed.block__header__item
|
||||
=> @topic.post_count - 1
|
||||
' replies
|
||||
/= if current_user
|
||||
/ = subscription_link(@topic, current_user)
|
||||
/- else
|
||||
' Login to subscribe to responses
|
||||
= render PhilomenaWeb.Topic.SubscriptionView, "_subscription.html", forum: @forum, topic: @topic, watching: @watching, conn: @conn
|
||||
|
||||
/ Display the poll, if any
|
||||
/= render partial: 'polls/display', locals: { poll: @topic.poll }
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
elixir:
|
||||
watch_path = Routes.forum_topic_subscription_path(@conn, :create, @forum, @topic)
|
||||
watch_class = if @watching, do: "hidden", else: ""
|
||||
|
||||
unwatch_path = Routes.forum_topic_subscription_path(@conn, :delete, @forum, @topic)
|
||||
unwatch_class = if @watching, do: "", else: "hidden"
|
||||
|
||||
= if @conn.assigns.current_user do
|
||||
#js-subscription-target
|
||||
a.js-subscription-link href=watch_path class=watch_class data-remote="true" data-method="post"
|
||||
i.fa.fa-bell>
|
||||
span.hide-mobile
|
||||
' Subscribe
|
||||
|
||||
a.js-subscription-link href=unwatch_path class=unwatch_class data-remote="true" data-method="delete"
|
||||
i.fa.fa-bell-slash>
|
||||
span.hide-mobile
|
||||
' Unsubscribe
|
||||
- else
|
||||
a href=Routes.pow_session_path(@conn, :new)
|
||||
i.fa.fa-bell>
|
||||
span.hide-mobile
|
||||
' Subscribe
|
3
lib/philomena_web/views/topic/subscription_view.ex
Normal file
3
lib/philomena_web/views/topic/subscription_view.ex
Normal file
|
@ -0,0 +1,3 @@
|
|||
defmodule PhilomenaWeb.Topic.SubscriptionView do
|
||||
use PhilomenaWeb, :view
|
||||
end
|
Loading…
Reference in a new issue