diff --git a/lib/philomena/galleries.ex b/lib/philomena/galleries.ex index f6ec80cf..f1cc04e0 100644 --- a/lib/philomena/galleries.ex +++ b/lib/philomena/galleries.ex @@ -4,9 +4,13 @@ defmodule Philomena.Galleries do """ import Ecto.Query, warn: false + alias Ecto.Multi alias Philomena.Repo alias Philomena.Galleries.Gallery + alias Philomena.Galleries.Interaction + alias Philomena.Notifications + alias Philomena.Images @doc """ Returns the list of galleries. @@ -104,7 +108,7 @@ defmodule Philomena.Galleries do def reindex_gallery(%Gallery{} = gallery) do spawn fn -> - gallery + Gallery |> preload(^indexing_preloads()) |> where(id: ^gallery.id) |> Repo.one() @@ -126,36 +130,144 @@ defmodule Philomena.Galleries do [:subscribers, :creator, :interactions] 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 """ - Returns the list of gallery_subscriptions. + %Interaction{gallery_id: gallery.id} + |> 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() - [%Subscription{}, ...] - - """ - def list_gallery_subscriptions do - Repo.all(Subscription) + {:ok, count} + end) + |> Repo.isolated_transaction(:serializable) end - @doc """ - Gets a single subscription. + def remove_image_from_gallery(gallery, image) do + 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) - %Subscription{} + defp last_position(gallery_id) do + Interaction + |> where(gallery_id: ^gallery_id) + |> Repo.aggregate(:max, :position) + end - iex> get_subscription!(456) - ** (Ecto.NoResultsError) + def notify_gallery(gallery) do + spawn fn -> + subscriptions = + gallery + |> Repo.preload(:subscriptions) + |> Map.fetch!(:subscriptions) - """ - def get_subscription!(id), do: Repo.get!(Subscription, id) + Notifications.notify( + 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 """ Creates a subscription. @@ -169,28 +281,10 @@ defmodule Philomena.Galleries 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(gallery, user) do + %Subscription{gallery_id: gallery.id, user_id: user.id} + |> Subscription.changeset(%{}) + |> Repo.insert(on_conflict: :nothing) end @doc """ @@ -205,20 +299,13 @@ defmodule Philomena.Galleries do {:error, %Ecto.Changeset{}} """ - def delete_subscription(%Subscription{} = subscription) do - Repo.delete(subscription) + def delete_subscription(gallery, user) do + %Subscription{gallery_id: gallery.id, user_id: user.id} + |> Repo.delete() 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 clear_notification(_gallery, nil), do: nil + def clear_notification(gallery, user) do + Notifications.delete_unread_notification("Gallery", gallery.id, user) end end diff --git a/lib/philomena/galleries/gallery.ex b/lib/philomena/galleries/gallery.ex index 3b0215f6..9ce4f132 100644 --- a/lib/philomena/galleries/gallery.ex +++ b/lib/philomena/galleries/gallery.ex @@ -10,11 +10,14 @@ defmodule Philomena.Galleries.Gallery do alias Philomena.Images.Image alias Philomena.Users.User alias Philomena.Galleries.Interaction + alias Philomena.Galleries.Subscription schema "galleries" do belongs_to :thumbnail, Image, source: :thumbnail_id belongs_to :creator, User, source: :creator_id has_many :interactions, Interaction + has_many :subscriptions, Subscription + has_many :subscribers, through: [:subscriptions, :user] field :title, :string field :spoiler_warning, :string diff --git a/lib/philomena/galleries/interaction.ex b/lib/philomena/galleries/interaction.ex index 889f0c56..7a0f7227 100644 --- a/lib/philomena/galleries/interaction.ex +++ b/lib/philomena/galleries/interaction.ex @@ -5,11 +5,10 @@ defmodule Philomena.Galleries.Interaction do alias Philomena.Galleries.Gallery alias Philomena.Images.Image - @primary_key false - + # fixme: unique-key this off (gallery_id, image_id) schema "gallery_interactions" do - belongs_to :gallery, Gallery, primary_key: true - belongs_to :image, Image, primary_key: true + belongs_to :gallery, Gallery + belongs_to :image, Image field :position, :integer end diff --git a/lib/philomena/images.ex b/lib/philomena/images.ex index 5c967217..3f706669 100644 --- a/lib/philomena/images.ex +++ b/lib/philomena/images.ex @@ -228,15 +228,20 @@ defmodule Philomena.Images do end def reindex_image(%Image{} = image) do + reindex_images([image.id]) + + image + end + + def reindex_images(image_ids) do spawn fn -> Image |> preload(^indexing_preloads()) - |> where(id: ^image.id) - |> Repo.one() - |> Image.index_document() + |> where([i], i.id in ^image_ids) + |> Image.reindex() end - image + image_ids end def indexing_preloads do diff --git a/lib/philomena/images/image.ex b/lib/philomena/images/image.ex index 883f5db7..65ca2757 100644 --- a/lib/philomena/images/image.ex +++ b/lib/philomena/images/image.ex @@ -43,6 +43,7 @@ defmodule Philomena.Images.Image do has_many :hiders, through: [:hides, :user] many_to_many :tags, Tag, join_through: "image_taggings", on_replace: :delete has_one :intensity, ImageIntensity + has_many :galleries, through: [:gallery_interactions, :image] field :image, :string field :image_name, :string diff --git a/lib/philomena_web/controllers/gallery/image_controller.ex b/lib/philomena_web/controllers/gallery/image_controller.ex new file mode 100644 index 00000000..40de0a83 --- /dev/null +++ b/lib/philomena_web/controllers/gallery/image_controller.ex @@ -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 \ No newline at end of file diff --git a/lib/philomena_web/controllers/gallery/order_controller.ex b/lib/philomena_web/controllers/gallery/order_controller.ex new file mode 100644 index 00000000..47a0d1c0 --- /dev/null +++ b/lib/philomena_web/controllers/gallery/order_controller.ex @@ -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 \ No newline at end of file diff --git a/lib/philomena_web/controllers/gallery/read_controller.ex b/lib/philomena_web/controllers/gallery/read_controller.ex new file mode 100644 index 00000000..b4bdca8e --- /dev/null +++ b/lib/philomena_web/controllers/gallery/read_controller.ex @@ -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 \ No newline at end of file diff --git a/lib/philomena_web/controllers/gallery/report_controller.ex b/lib/philomena_web/controllers/gallery/report_controller.ex new file mode 100644 index 00000000..18c953bf --- /dev/null +++ b/lib/philomena_web/controllers/gallery/report_controller.ex @@ -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 \ No newline at end of file diff --git a/lib/philomena_web/controllers/gallery/subscription_controller.ex b/lib/philomena_web/controllers/gallery/subscription_controller.ex new file mode 100644 index 00000000..f4e4e06d --- /dev/null +++ b/lib/philomena_web/controllers/gallery/subscription_controller.ex @@ -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 \ No newline at end of file diff --git a/lib/philomena_web/controllers/gallery_controller.ex b/lib/philomena_web/controllers/gallery_controller.ex index efb3e021..71739234 100644 --- a/lib/philomena_web/controllers/gallery_controller.ex +++ b/lib/philomena_web/controllers/gallery_controller.ex @@ -2,6 +2,7 @@ defmodule PhilomenaWeb.GalleryController do use PhilomenaWeb, :controller alias PhilomenaWeb.ImageLoader + alias PhilomenaWeb.NotificationCountPlug alias Philomena.ImageSorter alias Philomena.Interactions alias Philomena.Galleries.Gallery @@ -31,16 +32,24 @@ defmodule PhilomenaWeb.GalleryController do def show(conn, _params) do gallery = conn.assigns.gallery + user = conn.assigns.current_user query = "gallery_id:#{gallery.id}" params = Map.put(conn.params, "q", query) 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) - 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 + |> NotificationCountPlug.call([]) |> 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 def new(conn, _params) do diff --git a/lib/philomena_web/controllers/image_controller.ex b/lib/philomena_web/controllers/image_controller.ex index ac558e42..5dba4d21 100644 --- a/lib/philomena_web/controllers/image_controller.ex +++ b/lib/philomena_web/controllers/image_controller.ex @@ -3,7 +3,7 @@ defmodule PhilomenaWeb.ImageController do alias PhilomenaWeb.ImageLoader 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.Interactions alias Philomena.Comments @@ -70,6 +70,8 @@ defmodule PhilomenaWeb.ImageController do watching = Images.subscribed?(image, conn.assigns.current_user) + {user_galleries, image_galleries} = image_and_user_galleries(image, conn.assigns.current_user) + render( conn, "show.html", @@ -77,6 +79,8 @@ defmodule PhilomenaWeb.ImageController do comments: comments, image_changeset: image_changeset, comment_changeset: comment_changeset, + image_galleries: image_galleries, + user_galleries: user_galleries, description: description, interactions: interactions, watching: watching, @@ -110,4 +114,23 @@ defmodule PhilomenaWeb.ImageController do |> render("new.html", changeset: changeset) 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 diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index 1b09481b..b472fa9b 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -125,7 +125,12 @@ defmodule PhilomenaWeb.Router do resources "/reports", ReportController, only: [:index] 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 scope "/", PhilomenaWeb do @@ -188,7 +193,9 @@ defmodule PhilomenaWeb.Router do end resources "/posts", PostController, 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 "/pages", PageController, only: [:show] resources "/dnp", DnpEntryController, only: [:index, :show] diff --git a/lib/philomena_web/templates/gallery/show.html.slime b/lib/philomena_web/templates/gallery/show.html.slime index 23d04a7c..cdb6e96b 100644 --- a/lib/philomena_web/templates/gallery/show.html.slime +++ b/lib/philomena_web/templates/gallery/show.html.slime @@ -16,7 +16,7 @@ elixir: = pagination .flex__right - a href="#" + a href=Routes.gallery_report_path(@conn, :new, @gallery) i.fa.fa-exclamation-triangle> 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' i.fa.fa-sort> ' 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> ' Save = 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 span.block__header__title A gallery by diff --git a/lib/philomena_web/templates/gallery/subscription/_error.html.slime b/lib/philomena_web/templates/gallery/subscription/_error.html.slime new file mode 100644 index 00000000..b0c027de --- /dev/null +++ b/lib/philomena_web/templates/gallery/subscription/_error.html.slime @@ -0,0 +1,2 @@ +#js-subscription-target + ' Error! \ No newline at end of file diff --git a/lib/philomena_web/templates/gallery/subscription/_subscription.html.slime b/lib/philomena_web/templates/gallery/subscription/_subscription.html.slime new file mode 100644 index 00000000..43614c6c --- /dev/null +++ b/lib/philomena_web/templates/gallery/subscription/_subscription.html.slime @@ -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 \ No newline at end of file diff --git a/lib/philomena_web/templates/image/_add_to_gallery_dropdown.html.slime b/lib/philomena_web/templates/image/_add_to_gallery_dropdown.html.slime new file mode 100644 index 00000000..61bd4b04 --- /dev/null +++ b/lib/philomena_web/templates/image/_add_to_gallery_dropdown.html.slime @@ -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 diff --git a/lib/philomena_web/templates/image/_image_meta.html.slime b/lib/philomena_web/templates/image/_image_meta.html.slime index 59f0875f..bd842e7e 100644 --- a/lib/philomena_web/templates/image/_image_meta.html.slime +++ b/lib/philomena_web/templates/image/_image_meta.html.slime @@ -33,6 +33,7 @@ i.fa.fa-eye-slash .stretched-mobile-links = 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 a href="#{pretty_url(@image, false, false)}" rel="nofollow" title="View (tags in filename)" i.fa.fa-eye> diff --git a/lib/philomena_web/templates/image/show.html.slime b/lib/philomena_web/templates/image/show.html.slime index ffd4b250..ebd53d7d 100644 --- a/lib/philomena_web/templates/image/show.html.slime +++ b/lib/philomena_web/templates/image/show.html.slime @@ -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 .layout--narrow diff --git a/lib/philomena_web/templates/notification/_gallery.html.slime b/lib/philomena_web/templates/notification/_gallery.html.slime index 22ff6aa6..767cbc73 100644 --- a/lib/philomena_web/templates/notification/_gallery.html.slime +++ b/lib/philomena_web/templates/notification/_gallery.html.slime @@ -4,7 +4,13 @@ => @notification.action 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 \ No newline at end of file + => 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 \ No newline at end of file diff --git a/lib/philomena_web/views/gallery/subscription_view.ex b/lib/philomena_web/views/gallery/subscription_view.ex new file mode 100644 index 00000000..097862c1 --- /dev/null +++ b/lib/philomena_web/views/gallery/subscription_view.ex @@ -0,0 +1,3 @@ +defmodule PhilomenaWeb.Gallery.SubscriptionView do + use PhilomenaWeb, :view +end diff --git a/lib/philomena_web/views/report_view.ex b/lib/philomena_web/views/report_view.ex index 09fcc22d..686c4dc6 100644 --- a/lib/philomena_web/views/report_view.ex +++ b/lib/philomena_web/views/report_view.ex @@ -5,6 +5,7 @@ defmodule PhilomenaWeb.ReportView do alias Philomena.Comments.Comment alias Philomena.Commissions.Commission alias Philomena.Conversations.Conversation + alias Philomena.Galleries.Gallery alias Philomena.Posts.Post alias Philomena.Users.User @@ -52,6 +53,9 @@ defmodule PhilomenaWeb.ReportView do 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) + 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), 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}"