mirror of
https://github.com/philomena-dev/philomena.git
synced 2025-02-20 04:14:23 +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
|
alias Philomena.Topics.Subscription
|
||||||
|
|
||||||
@doc """
|
def subscribed?(topic, nil), do: false
|
||||||
Returns the list of topic_subscriptions.
|
def subscribed?(topic, user) do
|
||||||
|
Subscription
|
||||||
## Examples
|
|> where(topic_id: ^topic.id, user_id: ^user.id)
|
||||||
|
|> Repo.exists?()
|
||||||
iex> list_topic_subscriptions()
|
|
||||||
[%Subscription{}, ...]
|
|
||||||
|
|
||||||
"""
|
|
||||||
def list_topic_subscriptions do
|
|
||||||
Repo.all(Subscription)
|
|
||||||
end
|
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 """
|
@doc """
|
||||||
Creates a subscription.
|
Creates a subscription.
|
||||||
|
|
||||||
|
@ -145,28 +123,10 @@ defmodule Philomena.Topics do
|
||||||
{:error, %Ecto.Changeset{}}
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def create_subscription(attrs \\ %{}) do
|
def create_subscription(topic, user) do
|
||||||
%Subscription{}
|
%Subscription{topic_id: topic.id, user_id: user.id}
|
||||||
|> Subscription.changeset(attrs)
|
|> Subscription.changeset(%{})
|
||||||
|> Repo.insert()
|
|> Repo.insert(on_conflict: :nothing)
|
||||||
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()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -181,20 +141,8 @@ defmodule Philomena.Topics do
|
||||||
{:error, %Ecto.Changeset{}}
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def delete_subscription(%Subscription{} = subscription) do
|
def delete_subscription(topic, user) do
|
||||||
Repo.delete(subscription)
|
%Subscription{topic_id: topic.id, user_id: user.id}
|
||||||
end
|
|> Repo.delete()
|
||||||
|
|
||||||
@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, %{})
|
|
||||||
end
|
end
|
||||||
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
|
defmodule PhilomenaWeb.TopicController do
|
||||||
use PhilomenaWeb, :controller
|
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
|
alias Philomena.Repo
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
|
||||||
|
@ -51,6 +51,9 @@ defmodule PhilomenaWeb.TopicController do
|
||||||
total_pages: div(topic.post_count + 25 - 1, 25)
|
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -60,6 +60,12 @@ defmodule PhilomenaWeb.Router do
|
||||||
resources "/hide", Image.HideController, only: [:create, :delete], singleton: true
|
resources "/hide", Image.HideController, only: [:create, :delete], singleton: true
|
||||||
resources "/subscription", Image.SubscriptionController, only: [:create, :delete], singleton: true
|
resources "/subscription", Image.SubscriptionController, only: [:create, :delete], singleton: true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resources "/forums", ForumController, only: [] do
|
||||||
|
resources "/topics", TopicController, only: [] do
|
||||||
|
resources "/subscription", Topic.SubscriptionController, only: [:create, :delete], singleton: true
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/", PhilomenaWeb do
|
scope "/", PhilomenaWeb do
|
||||||
|
|
|
@ -24,10 +24,7 @@ h1 = @topic.title
|
||||||
.flex--fixed.block__header__item
|
.flex--fixed.block__header__item
|
||||||
=> @topic.post_count - 1
|
=> @topic.post_count - 1
|
||||||
' replies
|
' replies
|
||||||
/= if current_user
|
= render PhilomenaWeb.Topic.SubscriptionView, "_subscription.html", forum: @forum, topic: @topic, watching: @watching, conn: @conn
|
||||||
/ = subscription_link(@topic, current_user)
|
|
||||||
/- else
|
|
||||||
' Login to subscribe to responses
|
|
||||||
|
|
||||||
/ Display the poll, if any
|
/ Display the poll, if any
|
||||||
/= render partial: 'polls/display', locals: { poll: @topic.poll }
|
/= 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