mirror of
https://github.com/philomena-dev/philomena.git
synced 2025-01-19 14:17:59 +01:00
galleries
This commit is contained in:
parent
c918e4f7ab
commit
885488d40e
22 changed files with 430 additions and 77 deletions
|
@ -4,9 +4,13 @@ defmodule Philomena.Galleries do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import Ecto.Query, warn: false
|
import Ecto.Query, warn: false
|
||||||
|
alias Ecto.Multi
|
||||||
alias Philomena.Repo
|
alias Philomena.Repo
|
||||||
|
|
||||||
alias Philomena.Galleries.Gallery
|
alias Philomena.Galleries.Gallery
|
||||||
|
alias Philomena.Galleries.Interaction
|
||||||
|
alias Philomena.Notifications
|
||||||
|
alias Philomena.Images
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns the list of galleries.
|
Returns the list of galleries.
|
||||||
|
@ -104,7 +108,7 @@ defmodule Philomena.Galleries do
|
||||||
|
|
||||||
def reindex_gallery(%Gallery{} = gallery) do
|
def reindex_gallery(%Gallery{} = gallery) do
|
||||||
spawn fn ->
|
spawn fn ->
|
||||||
gallery
|
Gallery
|
||||||
|> preload(^indexing_preloads())
|
|> preload(^indexing_preloads())
|
||||||
|> where(id: ^gallery.id)
|
|> where(id: ^gallery.id)
|
||||||
|> Repo.one()
|
|> Repo.one()
|
||||||
|
@ -126,36 +130,144 @@ defmodule Philomena.Galleries do
|
||||||
[:subscribers, :creator, :interactions]
|
[:subscribers, :creator, :interactions]
|
||||||
end
|
end
|
||||||
|
|
||||||
alias Philomena.Galleries.Subscription
|
def add_image_to_gallery(gallery, image) do
|
||||||
|
Multi.new()
|
||||||
|
|> Multi.run(:interaction, fn repo, %{} ->
|
||||||
|
position = (last_position(gallery.id) || -1) + 1
|
||||||
|
|
||||||
@doc """
|
%Interaction{gallery_id: gallery.id}
|
||||||
Returns the list of gallery_subscriptions.
|
|> Interaction.changeset(%{"image_id" => image.id, "position" => position})
|
||||||
|
|> repo.insert()
|
||||||
|
end)
|
||||||
|
|> Multi.run(:gallery, fn repo, %{} ->
|
||||||
|
now = DateTime.utc_now()
|
||||||
|
|
||||||
## Examples
|
{count, nil} =
|
||||||
|
Gallery
|
||||||
|
|> where(id: ^gallery.id)
|
||||||
|
|> repo.update_all(inc: [image_count: 1], set: [updated_at: now])
|
||||||
|
|
||||||
iex> list_gallery_subscriptions()
|
{:ok, count}
|
||||||
[%Subscription{}, ...]
|
end)
|
||||||
|
|> Repo.isolated_transaction(:serializable)
|
||||||
"""
|
|
||||||
def list_gallery_subscriptions do
|
|
||||||
Repo.all(Subscription)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
def remove_image_from_gallery(gallery, image) do
|
||||||
Gets a single subscription.
|
Multi.new()
|
||||||
|
|> Multi.run(:interaction, fn repo, %{} ->
|
||||||
|
%Interaction{gallery_id: gallery.id, image_id: image.id}
|
||||||
|
|> repo.delete()
|
||||||
|
end)
|
||||||
|
|> Multi.run(:gallery, fn repo, %{} ->
|
||||||
|
now = DateTime.utc_now()
|
||||||
|
|
||||||
Raises `Ecto.NoResultsError` if the Subscription does not exist.
|
{count, nil} =
|
||||||
|
Gallery
|
||||||
|
|> where(id: ^gallery.id)
|
||||||
|
|> repo.update_all(inc: [image_count: -1], set: [updated_at: now])
|
||||||
|
|
||||||
## Examples
|
{:ok, count}
|
||||||
|
end)
|
||||||
|
|> Repo.isolated_transaction(:serializable)
|
||||||
|
end
|
||||||
|
|
||||||
iex> get_subscription!(123)
|
defp last_position(gallery_id) do
|
||||||
%Subscription{}
|
Interaction
|
||||||
|
|> where(gallery_id: ^gallery_id)
|
||||||
|
|> Repo.aggregate(:max, :position)
|
||||||
|
end
|
||||||
|
|
||||||
iex> get_subscription!(456)
|
def notify_gallery(gallery) do
|
||||||
** (Ecto.NoResultsError)
|
spawn fn ->
|
||||||
|
subscriptions =
|
||||||
|
gallery
|
||||||
|
|> Repo.preload(:subscriptions)
|
||||||
|
|> Map.fetch!(:subscriptions)
|
||||||
|
|
||||||
"""
|
Notifications.notify(
|
||||||
def get_subscription!(id), do: Repo.get!(Subscription, id)
|
gallery,
|
||||||
|
subscriptions,
|
||||||
|
%{
|
||||||
|
actor_id: gallery.id,
|
||||||
|
actor_type: "Gallery",
|
||||||
|
actor_child_id: nil,
|
||||||
|
actor_child_type: nil,
|
||||||
|
action: "added images to"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
gallery
|
||||||
|
end
|
||||||
|
|
||||||
|
def reorder_gallery(gallery, image_ids) do
|
||||||
|
spawn fn ->
|
||||||
|
interactions =
|
||||||
|
Interaction
|
||||||
|
|> where([gi], gi.image_id in ^image_ids)
|
||||||
|
|> order_by(^position_order(gallery))
|
||||||
|
|> Repo.all()
|
||||||
|
|
||||||
|
interaction_positions =
|
||||||
|
interactions
|
||||||
|
|> Enum.with_index()
|
||||||
|
|> Map.new(fn {interaction, index} -> {index, interaction.position} end)
|
||||||
|
|
||||||
|
images_present = Map.new(interactions, &{&1.image_id, true})
|
||||||
|
requested =
|
||||||
|
image_ids
|
||||||
|
|> Enum.filter(&images_present[&1])
|
||||||
|
|> Enum.with_index()
|
||||||
|
|> Map.new()
|
||||||
|
|
||||||
|
changes =
|
||||||
|
interactions
|
||||||
|
|> Enum.with_index()
|
||||||
|
|> Enum.flat_map(fn {interaction, current_index} ->
|
||||||
|
new_index = requested[interaction.image_id]
|
||||||
|
|
||||||
|
case new_index == current_index do
|
||||||
|
true ->
|
||||||
|
[]
|
||||||
|
|
||||||
|
false ->
|
||||||
|
[
|
||||||
|
[
|
||||||
|
id: interaction.id,
|
||||||
|
gallery_id: interaction.gallery_id,
|
||||||
|
image_id: interaction.image_id,
|
||||||
|
position: interaction_positions[new_index]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
# Do the update in a single statement
|
||||||
|
Repo.insert_all(
|
||||||
|
Interaction,
|
||||||
|
changes,
|
||||||
|
on_conflict: :replace_all_except_primary_key,
|
||||||
|
conflict_target: [:id]
|
||||||
|
)
|
||||||
|
|
||||||
|
# Now update all the associated images
|
||||||
|
Images.reindex_images(Map.keys(requested))
|
||||||
|
end
|
||||||
|
|
||||||
|
gallery
|
||||||
|
end
|
||||||
|
|
||||||
|
defp position_order(%{order_position_asc: true}), do: [asc: :position]
|
||||||
|
defp position_order(_gallery), do: [desc: :position]
|
||||||
|
|
||||||
|
alias Philomena.Galleries.Subscription
|
||||||
|
|
||||||
|
def subscribed?(_gallery, nil), do: false
|
||||||
|
def subscribed?(gallery, user) do
|
||||||
|
Subscription
|
||||||
|
|> where(gallery_id: ^gallery.id, user_id: ^user.id)
|
||||||
|
|> Repo.exists?()
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Creates a subscription.
|
Creates a subscription.
|
||||||
|
@ -169,28 +281,10 @@ defmodule Philomena.Galleries do
|
||||||
{:error, %Ecto.Changeset{}}
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def create_subscription(attrs \\ %{}) do
|
def create_subscription(gallery, user) do
|
||||||
%Subscription{}
|
%Subscription{gallery_id: gallery.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 """
|
||||||
|
@ -205,20 +299,13 @@ defmodule Philomena.Galleries do
|
||||||
{:error, %Ecto.Changeset{}}
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def delete_subscription(%Subscription{} = subscription) do
|
def delete_subscription(gallery, user) do
|
||||||
Repo.delete(subscription)
|
%Subscription{gallery_id: gallery.id, user_id: user.id}
|
||||||
|
|> Repo.delete()
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
def clear_notification(_gallery, nil), do: nil
|
||||||
Returns an `%Ecto.Changeset{}` for tracking subscription changes.
|
def clear_notification(gallery, user) do
|
||||||
|
Notifications.delete_unread_notification("Gallery", gallery.id, user)
|
||||||
## Examples
|
|
||||||
|
|
||||||
iex> change_subscription(subscription)
|
|
||||||
%Ecto.Changeset{source: %Subscription{}}
|
|
||||||
|
|
||||||
"""
|
|
||||||
def change_subscription(%Subscription{} = subscription) do
|
|
||||||
Subscription.changeset(subscription, %{})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,11 +10,14 @@ defmodule Philomena.Galleries.Gallery do
|
||||||
alias Philomena.Images.Image
|
alias Philomena.Images.Image
|
||||||
alias Philomena.Users.User
|
alias Philomena.Users.User
|
||||||
alias Philomena.Galleries.Interaction
|
alias Philomena.Galleries.Interaction
|
||||||
|
alias Philomena.Galleries.Subscription
|
||||||
|
|
||||||
schema "galleries" do
|
schema "galleries" do
|
||||||
belongs_to :thumbnail, Image, source: :thumbnail_id
|
belongs_to :thumbnail, Image, source: :thumbnail_id
|
||||||
belongs_to :creator, User, source: :creator_id
|
belongs_to :creator, User, source: :creator_id
|
||||||
has_many :interactions, Interaction
|
has_many :interactions, Interaction
|
||||||
|
has_many :subscriptions, Subscription
|
||||||
|
has_many :subscribers, through: [:subscriptions, :user]
|
||||||
|
|
||||||
field :title, :string
|
field :title, :string
|
||||||
field :spoiler_warning, :string
|
field :spoiler_warning, :string
|
||||||
|
|
|
@ -5,11 +5,10 @@ defmodule Philomena.Galleries.Interaction do
|
||||||
alias Philomena.Galleries.Gallery
|
alias Philomena.Galleries.Gallery
|
||||||
alias Philomena.Images.Image
|
alias Philomena.Images.Image
|
||||||
|
|
||||||
@primary_key false
|
# fixme: unique-key this off (gallery_id, image_id)
|
||||||
|
|
||||||
schema "gallery_interactions" do
|
schema "gallery_interactions" do
|
||||||
belongs_to :gallery, Gallery, primary_key: true
|
belongs_to :gallery, Gallery
|
||||||
belongs_to :image, Image, primary_key: true
|
belongs_to :image, Image
|
||||||
|
|
||||||
field :position, :integer
|
field :position, :integer
|
||||||
end
|
end
|
||||||
|
|
|
@ -228,15 +228,20 @@ defmodule Philomena.Images do
|
||||||
end
|
end
|
||||||
|
|
||||||
def reindex_image(%Image{} = image) do
|
def reindex_image(%Image{} = image) do
|
||||||
|
reindex_images([image.id])
|
||||||
|
|
||||||
|
image
|
||||||
|
end
|
||||||
|
|
||||||
|
def reindex_images(image_ids) do
|
||||||
spawn fn ->
|
spawn fn ->
|
||||||
Image
|
Image
|
||||||
|> preload(^indexing_preloads())
|
|> preload(^indexing_preloads())
|
||||||
|> where(id: ^image.id)
|
|> where([i], i.id in ^image_ids)
|
||||||
|> Repo.one()
|
|> Image.reindex()
|
||||||
|> Image.index_document()
|
|
||||||
end
|
end
|
||||||
|
|
||||||
image
|
image_ids
|
||||||
end
|
end
|
||||||
|
|
||||||
def indexing_preloads do
|
def indexing_preloads do
|
||||||
|
|
|
@ -43,6 +43,7 @@ defmodule Philomena.Images.Image do
|
||||||
has_many :hiders, through: [:hides, :user]
|
has_many :hiders, through: [:hides, :user]
|
||||||
many_to_many :tags, Tag, join_through: "image_taggings", on_replace: :delete
|
many_to_many :tags, Tag, join_through: "image_taggings", on_replace: :delete
|
||||||
has_one :intensity, ImageIntensity
|
has_one :intensity, ImageIntensity
|
||||||
|
has_many :galleries, through: [:gallery_interactions, :image]
|
||||||
|
|
||||||
field :image, :string
|
field :image, :string
|
||||||
field :image_name, :string
|
field :image_name, :string
|
||||||
|
|
37
lib/philomena_web/controllers/gallery/image_controller.ex
Normal file
37
lib/philomena_web/controllers/gallery/image_controller.ex
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
defmodule PhilomenaWeb.Gallery.ImageController do
|
||||||
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
|
alias Philomena.Images.Image
|
||||||
|
alias Philomena.Galleries.Gallery
|
||||||
|
alias Philomena.Images
|
||||||
|
alias Philomena.Galleries
|
||||||
|
|
||||||
|
plug PhilomenaWeb.CanaryMapPlug, create: :edit, delete: :edit
|
||||||
|
plug :load_and_authorize_resource, model: Gallery, id_name: "gallery_id", persisted: true
|
||||||
|
|
||||||
|
plug PhilomenaWeb.CanaryMapPlug, create: :show, delete: :show
|
||||||
|
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true
|
||||||
|
|
||||||
|
def create(conn, _params) do
|
||||||
|
gallery = conn.assigns.gallery
|
||||||
|
image = conn.assigns.image
|
||||||
|
|
||||||
|
{:ok, _gallery} = Galleries.add_image_to_gallery(gallery, image)
|
||||||
|
Galleries.notify_gallery(gallery)
|
||||||
|
Galleries.reindex_gallery(gallery)
|
||||||
|
Images.reindex_image(image)
|
||||||
|
|
||||||
|
json(conn, %{})
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(conn, _params) do
|
||||||
|
gallery = conn.assigns.gallery
|
||||||
|
image = conn.assigns.image
|
||||||
|
|
||||||
|
{:ok, _gallery} = Galleries.remove_image_from_gallery(gallery, image)
|
||||||
|
Galleries.reindex_gallery(gallery)
|
||||||
|
Images.reindex_image(image)
|
||||||
|
|
||||||
|
json(conn, %{})
|
||||||
|
end
|
||||||
|
end
|
17
lib/philomena_web/controllers/gallery/order_controller.ex
Normal file
17
lib/philomena_web/controllers/gallery/order_controller.ex
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
defmodule PhilomenaWeb.Gallery.OrderController do
|
||||||
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
|
alias Philomena.Galleries.Gallery
|
||||||
|
alias Philomena.Galleries
|
||||||
|
|
||||||
|
plug PhilomenaWeb.CanaryMapPlug, update: :edit
|
||||||
|
plug :load_and_authorize_resource, model: Gallery, id_name: "gallery_id", persisted: true
|
||||||
|
|
||||||
|
def update(conn, %{"image_ids" => image_ids}) when is_list(image_ids) do
|
||||||
|
gallery = conn.assigns.gallery
|
||||||
|
|
||||||
|
Galleries.reorder_gallery(gallery, image_ids)
|
||||||
|
|
||||||
|
json(conn, %{})
|
||||||
|
end
|
||||||
|
end
|
18
lib/philomena_web/controllers/gallery/read_controller.ex
Normal file
18
lib/philomena_web/controllers/gallery/read_controller.ex
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
defmodule PhilomenaWeb.Gallery.ReadController do
|
||||||
|
import Plug.Conn
|
||||||
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
|
alias Philomena.Galleries.Gallery
|
||||||
|
alias Philomena.Galleries
|
||||||
|
|
||||||
|
plug :load_resource, model: Gallery, id_name: "gallery_id", persisted: true
|
||||||
|
|
||||||
|
def create(conn, _params) do
|
||||||
|
gallery = conn.assigns.gallery
|
||||||
|
user = conn.assigns.current_user
|
||||||
|
|
||||||
|
Galleries.clear_notification(gallery, user)
|
||||||
|
|
||||||
|
send_resp(conn, :ok, "")
|
||||||
|
end
|
||||||
|
end
|
34
lib/philomena_web/controllers/gallery/report_controller.ex
Normal file
34
lib/philomena_web/controllers/gallery/report_controller.ex
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
defmodule PhilomenaWeb.Gallery.ReportController do
|
||||||
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
|
alias PhilomenaWeb.ReportController
|
||||||
|
alias PhilomenaWeb.ReportView
|
||||||
|
alias Philomena.Galleries.Gallery
|
||||||
|
alias Philomena.Reports.Report
|
||||||
|
alias Philomena.Reports
|
||||||
|
|
||||||
|
plug PhilomenaWeb.FilterBannedUsersPlug
|
||||||
|
plug PhilomenaWeb.UserAttributionPlug
|
||||||
|
plug PhilomenaWeb.CaptchaPlug when action in [:create]
|
||||||
|
plug PhilomenaWeb.CanaryMapPlug, new: :show, create: :show
|
||||||
|
plug :load_and_authorize_resource, model: Gallery, id_name: "gallery_id", persisted: true, preload: [:creator]
|
||||||
|
|
||||||
|
def new(conn, _params) do
|
||||||
|
gallery = conn.assigns.gallery
|
||||||
|
action = Routes.gallery_report_path(conn, :create, gallery)
|
||||||
|
changeset =
|
||||||
|
%Report{reportable_type: "Gallery", reportable_id: gallery.id}
|
||||||
|
|> Reports.change_report()
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_view(ReportView)
|
||||||
|
|> render("new.html", reportable: gallery, changeset: changeset, action: action)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create(conn, params) do
|
||||||
|
gallery = conn.assigns.gallery
|
||||||
|
action = Routes.gallery_report_path(conn, :create, gallery)
|
||||||
|
|
||||||
|
ReportController.create(conn, action, gallery, "Gallery", params)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,35 @@
|
||||||
|
defmodule PhilomenaWeb.Gallery.SubscriptionController do
|
||||||
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
|
alias Philomena.Galleries.Gallery
|
||||||
|
alias Philomena.Galleries
|
||||||
|
|
||||||
|
plug PhilomenaWeb.CanaryMapPlug, create: :show, delete: :show
|
||||||
|
plug :load_and_authorize_resource, model: Gallery, id_name: "gallery_id", persisted: true
|
||||||
|
|
||||||
|
def create(conn, _params) do
|
||||||
|
gallery = conn.assigns.gallery
|
||||||
|
user = conn.assigns.current_user
|
||||||
|
|
||||||
|
case Galleries.create_subscription(gallery, user) do
|
||||||
|
{:ok, _subscription} ->
|
||||||
|
render(conn, "_subscription.html", gallery: gallery, watching: true, layout: false)
|
||||||
|
|
||||||
|
{:error, _changeset} ->
|
||||||
|
render(conn, "_error.html", layout: false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete(conn, _params) do
|
||||||
|
gallery = conn.assigns.gallery
|
||||||
|
user = conn.assigns.current_user
|
||||||
|
|
||||||
|
case Galleries.delete_subscription(gallery, user) do
|
||||||
|
{:ok, _subscription} ->
|
||||||
|
render(conn, "_subscription.html", gallery: gallery, watching: false, layout: false)
|
||||||
|
|
||||||
|
{:error, _changeset} ->
|
||||||
|
render(conn, "_error.html", layout: false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -2,6 +2,7 @@ defmodule PhilomenaWeb.GalleryController do
|
||||||
use PhilomenaWeb, :controller
|
use PhilomenaWeb, :controller
|
||||||
|
|
||||||
alias PhilomenaWeb.ImageLoader
|
alias PhilomenaWeb.ImageLoader
|
||||||
|
alias PhilomenaWeb.NotificationCountPlug
|
||||||
alias Philomena.ImageSorter
|
alias Philomena.ImageSorter
|
||||||
alias Philomena.Interactions
|
alias Philomena.Interactions
|
||||||
alias Philomena.Galleries.Gallery
|
alias Philomena.Galleries.Gallery
|
||||||
|
@ -31,16 +32,24 @@ defmodule PhilomenaWeb.GalleryController do
|
||||||
|
|
||||||
def show(conn, _params) do
|
def show(conn, _params) do
|
||||||
gallery = conn.assigns.gallery
|
gallery = conn.assigns.gallery
|
||||||
|
user = conn.assigns.current_user
|
||||||
query = "gallery_id:#{gallery.id}"
|
query = "gallery_id:#{gallery.id}"
|
||||||
params = Map.put(conn.params, "q", query)
|
params = Map.put(conn.params, "q", query)
|
||||||
sort = ImageSorter.parse_sort(%{"sf" => "gallery_id:#{gallery.id}", "sd" => position_order(gallery)})
|
sort = ImageSorter.parse_sort(%{"sf" => "gallery_id:#{gallery.id}", "sd" => position_order(gallery)})
|
||||||
|
|
||||||
{:ok, images} = ImageLoader.search_string(conn, query, queries: sort.queries, sorts: sort.sorts)
|
{:ok, images} = ImageLoader.search_string(conn, query, queries: sort.queries, sorts: sort.sorts)
|
||||||
interactions = Interactions.user_interactions(images, conn.assigns.current_user)
|
interactions = Interactions.user_interactions(images, user)
|
||||||
|
|
||||||
|
watching = Galleries.subscribed?(gallery, user)
|
||||||
|
gallery_images = Jason.encode!(Enum.map(images, & &1.id))
|
||||||
|
|
||||||
|
Galleries.clear_notification(gallery, user)
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|
|> NotificationCountPlug.call([])
|
||||||
|> Map.put(:params, params)
|
|> Map.put(:params, params)
|
||||||
|> render("show.html", layout_class: "layout--wide", gallery: gallery, images: images, interactions: interactions)
|
|> assign(:clientside_data, [gallery_images: gallery_images])
|
||||||
|
|> render("show.html", layout_class: "layout--wide", watching: watching, gallery: gallery, images: images, interactions: interactions)
|
||||||
end
|
end
|
||||||
|
|
||||||
def new(conn, _params) do
|
def new(conn, _params) do
|
||||||
|
|
|
@ -3,7 +3,7 @@ defmodule PhilomenaWeb.ImageController do
|
||||||
|
|
||||||
alias PhilomenaWeb.ImageLoader
|
alias PhilomenaWeb.ImageLoader
|
||||||
alias PhilomenaWeb.NotificationCountPlug
|
alias PhilomenaWeb.NotificationCountPlug
|
||||||
alias Philomena.{Images, Images.Image, Comments.Comment, Textile.Renderer}
|
alias Philomena.{Images, Images.Image, Comments.Comment, Galleries.Gallery, Galleries.Interaction, Textile.Renderer}
|
||||||
alias Philomena.Servers.ImageProcessor
|
alias Philomena.Servers.ImageProcessor
|
||||||
alias Philomena.Interactions
|
alias Philomena.Interactions
|
||||||
alias Philomena.Comments
|
alias Philomena.Comments
|
||||||
|
@ -70,6 +70,8 @@ defmodule PhilomenaWeb.ImageController do
|
||||||
watching =
|
watching =
|
||||||
Images.subscribed?(image, conn.assigns.current_user)
|
Images.subscribed?(image, conn.assigns.current_user)
|
||||||
|
|
||||||
|
{user_galleries, image_galleries} = image_and_user_galleries(image, conn.assigns.current_user)
|
||||||
|
|
||||||
render(
|
render(
|
||||||
conn,
|
conn,
|
||||||
"show.html",
|
"show.html",
|
||||||
|
@ -77,6 +79,8 @@ defmodule PhilomenaWeb.ImageController do
|
||||||
comments: comments,
|
comments: comments,
|
||||||
image_changeset: image_changeset,
|
image_changeset: image_changeset,
|
||||||
comment_changeset: comment_changeset,
|
comment_changeset: comment_changeset,
|
||||||
|
image_galleries: image_galleries,
|
||||||
|
user_galleries: user_galleries,
|
||||||
description: description,
|
description: description,
|
||||||
interactions: interactions,
|
interactions: interactions,
|
||||||
watching: watching,
|
watching: watching,
|
||||||
|
@ -110,4 +114,23 @@ defmodule PhilomenaWeb.ImageController do
|
||||||
|> render("new.html", changeset: changeset)
|
|> render("new.html", changeset: changeset)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp image_and_user_galleries(_image, nil), do: {[], []}
|
||||||
|
defp image_and_user_galleries(image, user) do
|
||||||
|
image_galleries =
|
||||||
|
Gallery
|
||||||
|
|> where(creator_id: ^user.id)
|
||||||
|
|> join(:inner, [g], gi in Interaction, on: g.id == gi.gallery_id and gi.image_id == ^image.id)
|
||||||
|
|> Repo.all()
|
||||||
|
|
||||||
|
image_gallery_ids = Enum.map(image_galleries, & &1.id)
|
||||||
|
|
||||||
|
user_galleries =
|
||||||
|
Gallery
|
||||||
|
|> where(creator_id: ^user.id)
|
||||||
|
|> where([g], g.id not in ^image_gallery_ids)
|
||||||
|
|> Repo.all()
|
||||||
|
|
||||||
|
{user_galleries, image_galleries}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -125,7 +125,12 @@ defmodule PhilomenaWeb.Router do
|
||||||
|
|
||||||
resources "/reports", ReportController, only: [:index]
|
resources "/reports", ReportController, only: [:index]
|
||||||
resources "/user_links", UserLinkController, only: [:index, :new, :create, :show]
|
resources "/user_links", UserLinkController, only: [:index, :new, :create, :show]
|
||||||
resources "/galleries", GalleryController, only: [:new, :create, :edit, :update, :delete]
|
resources "/galleries", GalleryController, only: [:new, :create, :edit, :update, :delete] do
|
||||||
|
resources "/images", Gallery.ImageController, only: [:create, :delete], singleton: true
|
||||||
|
resources "/order", Gallery.OrderController, only: [:update], singleton: true
|
||||||
|
resources "/read", Gallery.ReadController, only: [:create], singleton: true
|
||||||
|
resources "/subscription", Gallery.SubscriptionController, only: [:create, :delete], singleton: true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scope "/", PhilomenaWeb do
|
scope "/", PhilomenaWeb do
|
||||||
|
@ -188,7 +193,9 @@ defmodule PhilomenaWeb.Router do
|
||||||
end
|
end
|
||||||
resources "/posts", PostController, only: [:index]
|
resources "/posts", PostController, only: [:index]
|
||||||
resources "/commissions", CommissionController, only: [:index]
|
resources "/commissions", CommissionController, only: [:index]
|
||||||
resources "/galleries", GalleryController, only: [:index, :show]
|
resources "/galleries", GalleryController, only: [:index, :show] do
|
||||||
|
resources "/reports", Gallery.ReportController, only: [:new, :create]
|
||||||
|
end
|
||||||
resources "/adverts", AdvertController, only: [:show]
|
resources "/adverts", AdvertController, only: [:show]
|
||||||
resources "/pages", PageController, only: [:show]
|
resources "/pages", PageController, only: [:show]
|
||||||
resources "/dnp", DnpEntryController, only: [:index, :show]
|
resources "/dnp", DnpEntryController, only: [:index, :show]
|
||||||
|
|
|
@ -16,7 +16,7 @@ elixir:
|
||||||
= pagination
|
= pagination
|
||||||
|
|
||||||
.flex__right
|
.flex__right
|
||||||
a href="#"
|
a href=Routes.gallery_report_path(@conn, :new, @gallery)
|
||||||
i.fa.fa-exclamation-triangle>
|
i.fa.fa-exclamation-triangle>
|
||||||
span.hide-mobile Report
|
span.hide-mobile Report
|
||||||
|
|
||||||
|
@ -29,13 +29,13 @@ elixir:
|
||||||
a.rearrange-button.js-rearrange href='#' data-click-hide='.js-rearrange' data-click-show='.js-save,#gallery-rearrange-info'
|
a.rearrange-button.js-rearrange href='#' data-click-hide='.js-rearrange' data-click-show='.js-save,#gallery-rearrange-info'
|
||||||
i.fa.fa-sort>
|
i.fa.fa-sort>
|
||||||
' Rearrange
|
' Rearrange
|
||||||
/data-reorder-path=gallery_order_path(@gallery)
|
|
||||||
a.rearrange-button.js-save.hidden href='#' data-click-hide='.js-save,#gallery-rearrange-info' data-click-show='.js-rearrange'
|
a.rearrange-button.js-save.hidden href='#' data-click-hide='.js-save,#gallery-rearrange-info' data-click-show='.js-rearrange' data-reorder-path=Routes.gallery_order_path(@conn, :update, @gallery)
|
||||||
i.fa.fa-check>
|
i.fa.fa-check>
|
||||||
' Save
|
' Save
|
||||||
|
|
||||||
= if show_subscription_link?(@gallery.creator, @conn.assigns.current_user) do
|
= if show_subscription_link?(@gallery.creator, @conn.assigns.current_user) do
|
||||||
/= subscription_link(@gallery, current_user)
|
= render PhilomenaWeb.Gallery.SubscriptionView, "_subscription.html", watching: @watching, gallery: @gallery, conn: @conn
|
||||||
|
|
||||||
.block__header.block__header--light.block__header--sub
|
.block__header.block__header--light.block__header--sub
|
||||||
span.block__header__title A gallery by
|
span.block__header__title A gallery by
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
#js-subscription-target
|
||||||
|
' Error!
|
|
@ -0,0 +1,23 @@
|
||||||
|
elixir:
|
||||||
|
watch_path = Routes.gallery_subscription_path(@conn, :create, @gallery)
|
||||||
|
watch_class = if @watching, do: "hidden", else: ""
|
||||||
|
|
||||||
|
unwatch_path = Routes.gallery_subscription_path(@conn, :delete, @gallery)
|
||||||
|
unwatch_class = if @watching, do: "", else: "hidden"
|
||||||
|
|
||||||
|
= if @conn.assigns.current_user do
|
||||||
|
span#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
|
|
@ -0,0 +1,39 @@
|
||||||
|
.dropdown.block__header__dropdown-tab
|
||||||
|
a href="#"
|
||||||
|
i.fa.fa-images>
|
||||||
|
span.hide-limited-desktop.hide-mobile Galleries
|
||||||
|
span data-click-preventdefault="true"
|
||||||
|
i.fa.fa-caret-down>
|
||||||
|
.dropdown__content.dropdown__content-right
|
||||||
|
.block
|
||||||
|
.block__content.add-to-gallery-list
|
||||||
|
.block__list
|
||||||
|
a.block__list__link.primary href=Routes.gallery_path(@conn, :index, include_image: @image.id)
|
||||||
|
i.fa.fa-table>
|
||||||
|
span.hide-mobile Featured in
|
||||||
|
|
||||||
|
= if Enum.any?(@image_galleries) or Enum.any?(@user_galleries) do
|
||||||
|
ul.block__list.js-gallery-list
|
||||||
|
= for gallery <- @user_galleries do
|
||||||
|
li id="gallery_#{gallery.id}"
|
||||||
|
a.block__list__link.js-gallery-add data-fetchcomplete-hide="#gallery_#{gallery.id} .js-gallery-add" data-fetchcomplete-show="#gallery_#{gallery.id} .js-gallery-remove" data-method="post" data-remote="true" href=Routes.gallery_image_path(@conn, :create, gallery, image_id: @image.id)
|
||||||
|
= gallery.title
|
||||||
|
a.block__list__link.active.js-gallery-remove.hidden data-fetchcomplete-hide="#gallery_#{gallery.id} .js-gallery-remove" data-fetchcomplete-show="#gallery_#{gallery.id} .js-gallery-add" data-method="delete" data-remote="true" href=Routes.gallery_image_path(@conn, :delete, gallery, image_id: @image.id)
|
||||||
|
= gallery.title
|
||||||
|
|
||||||
|
= for gallery <- @image_galleries do
|
||||||
|
li id="gallery_#{gallery.id}"
|
||||||
|
a.block__list__link.js-gallery-add.hidden data-fetchcomplete-hide="#gallery_#{gallery.id} .js-gallery-add" data-fetchcomplete-show="#gallery_#{gallery.id} .js-gallery-remove" data-method="post" data-remote="true" href=Routes.gallery_image_path(@conn, :create, gallery, image_id: @image.id)
|
||||||
|
= gallery.title
|
||||||
|
a.block__list__link.active.js-gallery-remove data-fetchcomplete-hide="#gallery_#{gallery.id} .js-gallery-remove" data-fetchcomplete-show="#gallery_#{gallery.id} .js-gallery-add" data-method="delete" data-remote="true" href=Routes.gallery_image_path(@conn, :delete, gallery, image_id: @image.id)
|
||||||
|
= gallery.title
|
||||||
|
|
||||||
|
.block__list
|
||||||
|
= if @conn.assigns.current_user do
|
||||||
|
a.block__list__link.primary href=Routes.gallery_path(@conn, :new, with_image: @image.id)
|
||||||
|
i.fa.fa-plus>
|
||||||
|
span.hide-limited-desktop.hide-mobile Create a gallery
|
||||||
|
- else
|
||||||
|
a.block__list__link.primary href=Routes.pow_registration_path(@conn, :new)
|
||||||
|
i.fa.fa-user-plus>
|
||||||
|
span.hide-limited-desktop.hide-mobile Register to create a gallery
|
|
@ -33,6 +33,7 @@
|
||||||
i.fa.fa-eye-slash
|
i.fa.fa-eye-slash
|
||||||
.stretched-mobile-links
|
.stretched-mobile-links
|
||||||
= render PhilomenaWeb.Image.SubscriptionView, "_subscription.html", watching: @watching, image: @image, conn: @conn
|
= render PhilomenaWeb.Image.SubscriptionView, "_subscription.html", watching: @watching, image: @image, conn: @conn
|
||||||
|
= render PhilomenaWeb.ImageView, "_add_to_gallery_dropdown.html", image: @image, image_galleries: @image_galleries, user_galleries: @user_galleries, conn: @conn
|
||||||
.stretched-mobile-links
|
.stretched-mobile-links
|
||||||
a href="#{pretty_url(@image, false, false)}" rel="nofollow" title="View (tags in filename)"
|
a href="#{pretty_url(@image, false, false)}" rel="nofollow" title="View (tags in filename)"
|
||||||
i.fa.fa-eye>
|
i.fa.fa-eye>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
= render PhilomenaWeb.ImageView, "_image_meta.html", image: @image, watching: @watching, conn: @conn
|
= render PhilomenaWeb.ImageView, "_image_meta.html", image: @image, watching: @watching, image_galleries: @image_galleries, user_galleries: @user_galleries, conn: @conn
|
||||||
= render PhilomenaWeb.ImageView, "_image_page.html", image: @image, conn: @conn
|
= render PhilomenaWeb.ImageView, "_image_page.html", image: @image, conn: @conn
|
||||||
|
|
||||||
.layout--narrow
|
.layout--narrow
|
||||||
|
|
|
@ -4,7 +4,13 @@
|
||||||
=> @notification.action
|
=> @notification.action
|
||||||
|
|
||||||
strong>
|
strong>
|
||||||
= link @notification.actor.title, to: "#"
|
= link @notification.actor.title, to: Routes.gallery_path(@conn, :show, @notification.actor)
|
||||||
/= link @notification.actor.title, to: Routes.gallery_path(@conn, :show, @notification.actor)
|
|
||||||
|
|
||||||
=> pretty_time @notification.updated_at
|
=> pretty_time @notification.updated_at
|
||||||
|
|
||||||
|
.flex.flex--centered.flex--no-wrap
|
||||||
|
a.button.button--separate-right title="Delete" href=Routes.gallery_read_path(@conn, :create, @notification.actor) data-method="post" data-remote="true" data-fetchcomplete-hide="#notification-#{@notification.id}"
|
||||||
|
i.fa.fa-trash
|
||||||
|
|
||||||
|
a.button title="Unsubscribe" href=Routes.gallery_subscription_path(@conn, :delete, @notification.actor) data-method="delete" data-remote="true" data-fetchcomplete-hide="#notification-#{@notification.id}"
|
||||||
|
i.fa.fa-bell-slash
|
3
lib/philomena_web/views/gallery/subscription_view.ex
Normal file
3
lib/philomena_web/views/gallery/subscription_view.ex
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
defmodule PhilomenaWeb.Gallery.SubscriptionView do
|
||||||
|
use PhilomenaWeb, :view
|
||||||
|
end
|
|
@ -5,6 +5,7 @@ defmodule PhilomenaWeb.ReportView do
|
||||||
alias Philomena.Comments.Comment
|
alias Philomena.Comments.Comment
|
||||||
alias Philomena.Commissions.Commission
|
alias Philomena.Commissions.Commission
|
||||||
alias Philomena.Conversations.Conversation
|
alias Philomena.Conversations.Conversation
|
||||||
|
alias Philomena.Galleries.Gallery
|
||||||
alias Philomena.Posts.Post
|
alias Philomena.Posts.Post
|
||||||
alias Philomena.Users.User
|
alias Philomena.Users.User
|
||||||
|
|
||||||
|
@ -52,6 +53,9 @@ defmodule PhilomenaWeb.ReportView do
|
||||||
def link_to_reported_thing(conn, %Commission{} = r),
|
def link_to_reported_thing(conn, %Commission{} = r),
|
||||||
do: link "#{r.user.name}'s commission page", to: Routes.profile_commission_path(conn, :show, r.user)
|
do: link "#{r.user.name}'s commission page", to: Routes.profile_commission_path(conn, :show, r.user)
|
||||||
|
|
||||||
|
def link_to_reported_thing(conn, %Gallery{} = r),
|
||||||
|
do: link "Gallery '#{r.title}' by #{r.creator.name}", to: Routes.gallery_path(conn, :show, r)
|
||||||
|
|
||||||
def link_to_reported_thing(conn, %Post{} = r),
|
def link_to_reported_thing(conn, %Post{} = r),
|
||||||
do: link "Post in #{r.topic.title}", to: Routes.forum_topic_path(conn, :show, r.topic.forum, r.topic, post_id: r.id) <> "#post_#{r.id}"
|
do: link "Post in #{r.topic.title}", to: Routes.forum_topic_path(conn, :show, r.topic.forum, r.topic, post_id: r.id) <> "#post_#{r.id}"
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue