mirror of
https://github.com/philomena-dev/philomena.git
synced 2025-01-19 14:17:59 +01:00
add image subscriptions
This commit is contained in:
parent
29453f060f
commit
8131782a20
11 changed files with 98 additions and 82 deletions
|
@ -8,7 +8,7 @@ import { $ } from './utils/dom';
|
|||
import { fetchHtml, handleError } from './utils/requests';
|
||||
import { showBlock } from './utils/image';
|
||||
import { addTag } from './tagsinput';
|
||||
import { toggleSubscription, markRead } from './notifications';
|
||||
import { markRead } from './notifications';
|
||||
|
||||
// Event types and any qualifying conditions - return true to not run action
|
||||
const types = {
|
||||
|
@ -74,8 +74,6 @@ const actions = {
|
|||
|
||||
unfilter(data) { showBlock(data.el.closest('.image-show-container')); },
|
||||
|
||||
toggleSubscription,
|
||||
|
||||
markRead,
|
||||
|
||||
};
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
import { fetchJson, handleError } from './utils/requests';
|
||||
import { $, $$, hideEl, toggleEl } from './utils/dom';
|
||||
import { delegate } from './utils/events';
|
||||
import store from './utils/store';
|
||||
|
||||
const NOTIFICATION_INTERVAL = 600000,
|
||||
|
@ -14,16 +15,17 @@ function makeRequest(verb, action, body) {
|
|||
}
|
||||
|
||||
|
||||
function toggleSubscription(data) {
|
||||
const { subscriptionId, subscriptionType } = data.el.dataset;
|
||||
const subscriptionElements = $$(`.js-notification-${subscriptionType + subscriptionId}`);
|
||||
|
||||
makeRequest('PUT', data.value, { id: subscriptionId, actor_class: subscriptionType }) // eslint-disable-line camelcase
|
||||
.then(() => toggleEl(subscriptionElements))
|
||||
.catch(() => data.el.textContent = 'Error!');
|
||||
function bindSubscriptionLinks() {
|
||||
delegate(document, 'fetchcomplete', {
|
||||
'.js-subscription-link': event => {
|
||||
const target = $("#js-subscription-target");
|
||||
event.detail.text().then(text => {
|
||||
target.outerHTML = text;
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function markRead(data) {
|
||||
const notificationId = data.value;
|
||||
const notification = $(`.js-notification-id-${notificationId}`);
|
||||
|
@ -72,6 +74,8 @@ function setupNotifications() {
|
|||
|
||||
// Update ticker when the stored value changes - this will occur in all open tabs
|
||||
store.watch('notificationCount', updateNotificationTicker);
|
||||
|
||||
bindSubscriptionLinks();
|
||||
}
|
||||
|
||||
export { setupNotifications, toggleSubscription, markRead };
|
||||
export { setupNotifications, markRead };
|
||||
|
|
|
@ -122,35 +122,13 @@ defmodule Philomena.Images do
|
|||
|
||||
alias Philomena.Images.Subscription
|
||||
|
||||
@doc """
|
||||
Returns the list of image_subscriptions.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_image_subscriptions()
|
||||
[%Subscription{}, ...]
|
||||
|
||||
"""
|
||||
def list_image_subscriptions do
|
||||
Repo.all(Subscription)
|
||||
def subscribed?(image, nil), do: false
|
||||
def subscribed?(image, user) do
|
||||
Subscription
|
||||
|> where(image_id: ^image.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.
|
||||
|
||||
|
@ -163,28 +141,10 @@ defmodule Philomena.Images 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(image, user) do
|
||||
%Subscription{image_id: image.id, user_id: user.id}
|
||||
|> Subscription.changeset(%{})
|
||||
|> Repo.insert(on_conflict: :nothing)
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -199,20 +159,8 @@ defmodule Philomena.Images 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(image, user) do
|
||||
%Subscription{image_id: image.id, user_id: user.id}
|
||||
|> Repo.delete()
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
defmodule PhilomenaWeb.Image.SubscriptionController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.Images.Image
|
||||
alias Philomena.Images
|
||||
|
||||
plug PhilomenaWeb.Plugs.CanaryMapPlug, create: :show, delete: :show
|
||||
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true
|
||||
|
||||
def create(conn, _params) do
|
||||
image = conn.assigns.image
|
||||
user = conn.assigns.current_user
|
||||
|
||||
case Images.create_subscription(image, user) do
|
||||
{:ok, _subscription} ->
|
||||
render(conn, "_subscription.html", image: image, watching: true, layout: false)
|
||||
|
||||
{:error, _changeset} ->
|
||||
render(conn, "_error.html", layout: false)
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, _params) do
|
||||
image = conn.assigns.image
|
||||
user = conn.assigns.current_user
|
||||
|
||||
case Images.delete_subscription(image, user) do
|
||||
{:ok, _subscription} ->
|
||||
render(conn, "_subscription.html", image: image, watching: false, layout: false)
|
||||
|
||||
{:error, _changeset} ->
|
||||
render(conn, "_error.html", layout: false)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
defmodule PhilomenaWeb.ImageController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.{Images.Image, Comments.Comment, Textile.Renderer}
|
||||
alias Philomena.{Images, Images.Image, Comments.Comment, Textile.Renderer}
|
||||
alias Philomena.Interactions
|
||||
alias Philomena.Comments
|
||||
alias Philomena.Repo
|
||||
|
@ -57,6 +57,9 @@ defmodule PhilomenaWeb.ImageController do
|
|||
%Comment{}
|
||||
|> Comments.change_comment()
|
||||
|
||||
watching =
|
||||
Images.subscribed?(image, conn.assigns.current_user)
|
||||
|
||||
render(
|
||||
conn,
|
||||
"show.html",
|
||||
|
@ -64,7 +67,8 @@ defmodule PhilomenaWeb.ImageController do
|
|||
comments: comments,
|
||||
comment_changeset: comment_changeset,
|
||||
description: description,
|
||||
interactions: interactions
|
||||
interactions: interactions,
|
||||
watching: watching
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -58,6 +58,7 @@ defmodule PhilomenaWeb.Router do
|
|||
resources "/vote", Image.VoteController, only: [:create, :delete], singleton: true
|
||||
resources "/fave", Image.FaveController, only: [:create, :delete], singleton: true
|
||||
resources "/hide", Image.HideController, only: [:create, :delete], singleton: true
|
||||
resources "/subscription", Image.SubscriptionController, only: [:create, :delete], singleton: true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -30,9 +30,7 @@
|
|||
span.hide-span title="Hide"
|
||||
i.fa.fa-eye-slash
|
||||
.stretched-mobile-links
|
||||
a href="/" title="Related Images"
|
||||
i.fa.fa-sitemap>
|
||||
span.hide-limited-desktop.hide-mobile Related
|
||||
= render PhilomenaWeb.Image.SubscriptionView, "_subscription.html", watching: @watching, image: @image, conn: @conn
|
||||
.stretched-mobile-links
|
||||
a href="#{pretty_url(@image, false, false)}" rel="nofollow" title="View (tags in filename)"
|
||||
i.fa.fa-eye>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
= render PhilomenaWeb.ImageView, "_image_meta.html", image: @image, conn: @conn
|
||||
= render PhilomenaWeb.ImageView, "_image_meta.html", image: @image, watching: @watching, conn: @conn
|
||||
= render PhilomenaWeb.ImageView, "_image_page.html", image: @image, conn: @conn
|
||||
|
||||
.layout--narrow
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#js-subscription-target
|
||||
' Error!
|
|
@ -0,0 +1,23 @@
|
|||
elixir:
|
||||
watch_path = Routes.image_subscription_path(@conn, :create, @image)
|
||||
watch_class = if @watching, do: "hidden", else: ""
|
||||
|
||||
unwatch_path = Routes.image_subscription_path(@conn, :delete, @image)
|
||||
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/image/subscription_view.ex
Normal file
3
lib/philomena_web/views/image/subscription_view.ex
Normal file
|
@ -0,0 +1,3 @@
|
|||
defmodule PhilomenaWeb.Image.SubscriptionView do
|
||||
use PhilomenaWeb, :view
|
||||
end
|
Loading…
Reference in a new issue