mirror of
https://github.com/philomena-dev/philomena.git
synced 2025-01-20 06:37:59 +01:00
add interactions
This commit is contained in:
parent
6513fb39b8
commit
d60c6ccb06
14 changed files with 409 additions and 273 deletions
|
@ -5,9 +5,9 @@
|
|||
import { fetchJson } from './utils/requests';
|
||||
|
||||
const endpoints = {
|
||||
fave: `${window.booru.apiEndpoint}interactions/fave`,
|
||||
vote: `${window.booru.apiEndpoint}interactions/vote`,
|
||||
hide: `${window.booru.apiEndpoint}interactions/hide`,
|
||||
vote(imageId) { return `/images/${imageId}/vote` },
|
||||
fave(imageId) { return `/images/${imageId}/fave` },
|
||||
hide(imageId) { return `/images/${imageId}/hide` },
|
||||
};
|
||||
|
||||
const spoilerDownvoteMsg =
|
||||
|
@ -22,10 +22,8 @@ function onImage(id, selector, cb) {
|
|||
function setScore(imageId, data) {
|
||||
onImage(imageId, '.score',
|
||||
el => el.textContent = data.score);
|
||||
onImage(imageId, '.votes',
|
||||
el => el.textContent = data.votes);
|
||||
onImage(imageId, '.favorites',
|
||||
el => el.textContent = data.favourites);
|
||||
el => el.textContent = data.faves);
|
||||
onImage(imageId, '.upvotes',
|
||||
el => el.textContent = data.upvotes);
|
||||
onImage(imageId, '.downvotes',
|
||||
|
@ -73,10 +71,8 @@ function resetHidden(imageId) {
|
|||
el => el.classList.remove('active'));
|
||||
}
|
||||
|
||||
function interact(type, imageId, value) {
|
||||
return fetchJson('PUT', endpoints[type], {
|
||||
class: 'Image', id: imageId, value
|
||||
})
|
||||
function interact(type, imageId, method, data = {}) {
|
||||
return fetchJson(method, endpoints[type](imageId), data)
|
||||
.then(res => res.json())
|
||||
.then(res => setScore(imageId, res));
|
||||
}
|
||||
|
@ -129,37 +125,37 @@ const targets = {
|
|||
|
||||
/* Active-state targets first */
|
||||
'.interaction--upvote.active'(imageId) {
|
||||
interact('vote', imageId, 'false')
|
||||
interact('vote', imageId, 'DELETE')
|
||||
.then(() => resetVoted(imageId));
|
||||
},
|
||||
'.interaction--downvote.active'(imageId) {
|
||||
interact('vote', imageId, 'false')
|
||||
interact('vote', imageId, 'DELETE')
|
||||
.then(() => resetVoted(imageId));
|
||||
},
|
||||
'.interaction--fave.active'(imageId) {
|
||||
interact('fave', imageId, 'false')
|
||||
interact('fave', imageId, 'DELETE')
|
||||
.then(() => resetFaved(imageId));
|
||||
},
|
||||
'.interaction--hide.active'(imageId) {
|
||||
interact('hide', imageId, 'false')
|
||||
interact('hide', imageId, 'DELETE')
|
||||
.then(() => resetHidden(imageId));
|
||||
},
|
||||
|
||||
/* Inactive targets */
|
||||
'.interaction--upvote:not(.active)'(imageId) {
|
||||
interact('vote', imageId, 'up')
|
||||
interact('vote', imageId, 'POST', { up: true })
|
||||
.then(() => { resetVoted(imageId); showUpvoted(imageId); });
|
||||
},
|
||||
'.interaction--downvote:not(.active)'(imageId) {
|
||||
interact('vote', imageId, 'down')
|
||||
interact('vote', imageId, 'POST', { up: false })
|
||||
.then(() => { resetVoted(imageId); showDownvoted(imageId); });
|
||||
},
|
||||
'.interaction--fave:not(.active)'(imageId) {
|
||||
interact('fave', imageId, 'true')
|
||||
interact('fave', imageId, 'POST')
|
||||
.then(() => { resetVoted(imageId); showFaved(imageId); showUpvoted(imageId); });
|
||||
},
|
||||
'.interaction--hide:not(.active)'(imageId) {
|
||||
interact('hide', imageId, 'true')
|
||||
interact('hide', imageId, 'POST')
|
||||
.then(() => { showHidden(imageId); });
|
||||
},
|
||||
|
||||
|
|
|
@ -4,101 +4,51 @@ defmodule Philomena.ImageFaves do
|
|||
"""
|
||||
|
||||
import Ecto.Query, warn: false
|
||||
alias Philomena.Repo
|
||||
alias Ecto.Multi
|
||||
|
||||
alias Philomena.Images.Image
|
||||
alias Philomena.ImageFaves.ImageFave
|
||||
|
||||
@doc """
|
||||
Returns the list of image_faves.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_image_faves()
|
||||
[%ImageFave{}, ...]
|
||||
Creates a image_hide.
|
||||
|
||||
"""
|
||||
def list_image_faves do
|
||||
Repo.all(ImageFave)
|
||||
end
|
||||
def create_fave_transaction(image, user) do
|
||||
fave =
|
||||
%ImageFave{image_id: image.id, user_id: user.id}
|
||||
|> ImageFave.changeset(%{})
|
||||
|
||||
@doc """
|
||||
Gets a single image_fave.
|
||||
image_query =
|
||||
Image
|
||||
|> where(id: ^image.id)
|
||||
|
||||
Raises `Ecto.NoResultsError` if the Image fave does not exist.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_image_fave!(123)
|
||||
%ImageFave{}
|
||||
|
||||
iex> get_image_fave!(456)
|
||||
** (Ecto.NoResultsError)
|
||||
|
||||
"""
|
||||
def get_image_fave!(id), do: Repo.get!(ImageFave, id)
|
||||
|
||||
@doc """
|
||||
Creates a image_fave.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_image_fave(%{field: value})
|
||||
{:ok, %ImageFave{}}
|
||||
|
||||
iex> create_image_fave(%{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_image_fave(attrs \\ %{}) do
|
||||
%ImageFave{}
|
||||
|> ImageFave.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Updates a image_fave.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> update_image_fave(image_fave, %{field: new_value})
|
||||
{:ok, %ImageFave{}}
|
||||
|
||||
iex> update_image_fave(image_fave, %{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def update_image_fave(%ImageFave{} = image_fave, attrs) do
|
||||
image_fave
|
||||
|> ImageFave.changeset(attrs)
|
||||
|> Repo.update()
|
||||
Multi.new
|
||||
|> Multi.insert(:fave, fave)
|
||||
|> Multi.update_all(:inc_faves_count, image_query, inc: [faves_count: 1])
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a ImageFave.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_image_fave(image_fave)
|
||||
{:ok, %ImageFave{}}
|
||||
|
||||
iex> delete_image_fave(image_fave)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_image_fave(%ImageFave{} = image_fave) do
|
||||
Repo.delete(image_fave)
|
||||
end
|
||||
def delete_fave_transaction(image, user) do
|
||||
fave_query =
|
||||
ImageFave
|
||||
|> where(image_id: ^image.id)
|
||||
|> where(user_id: ^user.id)
|
||||
|
||||
@doc """
|
||||
Returns an `%Ecto.Changeset{}` for tracking image_fave changes.
|
||||
image_query =
|
||||
Image
|
||||
|> where(id: ^image.id)
|
||||
|
||||
## Examples
|
||||
Multi.new
|
||||
|> Multi.delete_all(:unfave, fave_query)
|
||||
|> Multi.run(:dec_faves_count, fn repo, %{unfave: {faves, nil}} ->
|
||||
{count, nil} =
|
||||
image_query
|
||||
|> repo.update_all(inc: [faves_count: -faves])
|
||||
|
||||
iex> change_image_fave(image_fave)
|
||||
%Ecto.Changeset{source: %ImageFave{}}
|
||||
|
||||
"""
|
||||
def change_image_fave(%ImageFave{} = image_fave) do
|
||||
ImageFave.changeset(image_fave, %{})
|
||||
{:ok, count}
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,101 +4,51 @@ defmodule Philomena.ImageHides do
|
|||
"""
|
||||
|
||||
import Ecto.Query, warn: false
|
||||
alias Philomena.Repo
|
||||
alias Ecto.Multi
|
||||
|
||||
alias Philomena.Images.Image
|
||||
alias Philomena.ImageHides.ImageHide
|
||||
|
||||
@doc """
|
||||
Returns the list of image_hides.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_image_hides()
|
||||
[%ImageHide{}, ...]
|
||||
|
||||
"""
|
||||
def list_image_hides do
|
||||
Repo.all(ImageHide)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single image_hide.
|
||||
|
||||
Raises `Ecto.NoResultsError` if the Image hide does not exist.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_image_hide!(123)
|
||||
%ImageHide{}
|
||||
|
||||
iex> get_image_hide!(456)
|
||||
** (Ecto.NoResultsError)
|
||||
|
||||
"""
|
||||
def get_image_hide!(id), do: Repo.get!(ImageHide, id)
|
||||
|
||||
@doc """
|
||||
Creates a image_hide.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_image_hide(%{field: value})
|
||||
{:ok, %ImageHide{}}
|
||||
|
||||
iex> create_image_hide(%{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_image_hide(attrs \\ %{}) do
|
||||
%ImageHide{}
|
||||
|> ImageHide.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
end
|
||||
def create_hide_transaction(image, user) do
|
||||
hide =
|
||||
%ImageHide{image_id: image.id, user_id: user.id}
|
||||
|> ImageHide.changeset(%{})
|
||||
|
||||
@doc """
|
||||
Updates a image_hide.
|
||||
image_query =
|
||||
Image
|
||||
|> where(id: ^image.id)
|
||||
|
||||
## Examples
|
||||
|
||||
iex> update_image_hide(image_hide, %{field: new_value})
|
||||
{:ok, %ImageHide{}}
|
||||
|
||||
iex> update_image_hide(image_hide, %{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def update_image_hide(%ImageHide{} = image_hide, attrs) do
|
||||
image_hide
|
||||
|> ImageHide.changeset(attrs)
|
||||
|> Repo.update()
|
||||
Multi.new
|
||||
|> Multi.insert(:hide, hide)
|
||||
|> Multi.update_all(:inc_hides_count, image_query, inc: [hides_count: 1])
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a ImageHide.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_image_hide(image_hide)
|
||||
{:ok, %ImageHide{}}
|
||||
|
||||
iex> delete_image_hide(image_hide)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_image_hide(%ImageHide{} = image_hide) do
|
||||
Repo.delete(image_hide)
|
||||
end
|
||||
def delete_hide_transaction(image, user) do
|
||||
hide_query =
|
||||
ImageHide
|
||||
|> where(image_id: ^image.id)
|
||||
|> where(user_id: ^user.id)
|
||||
|
||||
@doc """
|
||||
Returns an `%Ecto.Changeset{}` for tracking image_hide changes.
|
||||
image_query =
|
||||
Image
|
||||
|> where(id: ^image.id)
|
||||
|
||||
## Examples
|
||||
Multi.new
|
||||
|> Multi.delete_all(:unhide, hide_query)
|
||||
|> Multi.run(:dec_hides_count, fn repo, %{unhide: {hides, nil}} ->
|
||||
{count, nil} =
|
||||
image_query
|
||||
|> repo.update_all(inc: [hides_count: -hides])
|
||||
|
||||
iex> change_image_hide(image_hide)
|
||||
%Ecto.Changeset{source: %ImageHide{}}
|
||||
|
||||
"""
|
||||
def change_image_hide(%ImageHide{} = image_hide) do
|
||||
ImageHide.changeset(image_hide, %{})
|
||||
{:ok, count}
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,101 +4,62 @@ defmodule Philomena.ImageVotes do
|
|||
"""
|
||||
|
||||
import Ecto.Query, warn: false
|
||||
alias Philomena.Repo
|
||||
alias Ecto.Multi
|
||||
|
||||
alias Philomena.Images.Image
|
||||
alias Philomena.ImageVotes.ImageVote
|
||||
|
||||
@doc """
|
||||
Returns the list of image_votes.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> list_image_votes()
|
||||
[%ImageVote{}, ...]
|
||||
|
||||
"""
|
||||
def list_image_votes do
|
||||
Repo.all(ImageVote)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single image_vote.
|
||||
|
||||
Raises `Ecto.NoResultsError` if the Image vote does not exist.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> get_image_vote!(123)
|
||||
%ImageVote{}
|
||||
|
||||
iex> get_image_vote!(456)
|
||||
** (Ecto.NoResultsError)
|
||||
|
||||
"""
|
||||
def get_image_vote!(id), do: Repo.get!(ImageVote, id)
|
||||
|
||||
@doc """
|
||||
Creates a image_vote.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> create_image_vote(%{field: value})
|
||||
{:ok, %ImageVote{}}
|
||||
|
||||
iex> create_image_vote(%{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_image_vote(attrs \\ %{}) do
|
||||
%ImageVote{}
|
||||
|> ImageVote.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
end
|
||||
def create_vote_transaction(image, user, up) do
|
||||
vote =
|
||||
%ImageVote{image_id: image.id, user_id: user.id, up: up}
|
||||
|> ImageVote.changeset(%{})
|
||||
|
||||
@doc """
|
||||
Updates a image_vote.
|
||||
image_query =
|
||||
Image
|
||||
|> where(id: ^image.id)
|
||||
|
||||
## Examples
|
||||
upvotes = if up, do: 1, else: 0
|
||||
downvotes = if up, do: 0, else: 1
|
||||
|
||||
iex> update_image_vote(image_vote, %{field: new_value})
|
||||
{:ok, %ImageVote{}}
|
||||
|
||||
iex> update_image_vote(image_vote, %{field: bad_value})
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def update_image_vote(%ImageVote{} = image_vote, attrs) do
|
||||
image_vote
|
||||
|> ImageVote.changeset(attrs)
|
||||
|> Repo.update()
|
||||
Multi.new
|
||||
|> Multi.insert(:vote, vote)
|
||||
|> Multi.update_all(:inc_vote_count, image_query, inc: [upvotes_count: upvotes, downvotes_count: downvotes, score: upvotes - downvotes])
|
||||
end
|
||||
|
||||
@doc """
|
||||
Deletes a ImageVote.
|
||||
|
||||
## Examples
|
||||
|
||||
iex> delete_image_vote(image_vote)
|
||||
{:ok, %ImageVote{}}
|
||||
|
||||
iex> delete_image_vote(image_vote)
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def delete_image_vote(%ImageVote{} = image_vote) do
|
||||
Repo.delete(image_vote)
|
||||
end
|
||||
def delete_vote_transaction(image, user) do
|
||||
upvote_query =
|
||||
ImageVote
|
||||
|> where(image_id: ^image.id)
|
||||
|> where(user_id: ^user.id)
|
||||
|> where(up: true)
|
||||
|
||||
@doc """
|
||||
Returns an `%Ecto.Changeset{}` for tracking image_vote changes.
|
||||
downvote_query =
|
||||
ImageVote
|
||||
|> where(image_id: ^image.id)
|
||||
|> where(user_id: ^user.id)
|
||||
|> where(up: false)
|
||||
|
||||
## Examples
|
||||
image_query =
|
||||
Image
|
||||
|> where(id: ^image.id)
|
||||
|
||||
iex> change_image_vote(image_vote)
|
||||
%Ecto.Changeset{source: %ImageVote{}}
|
||||
Multi.new
|
||||
|> Multi.delete_all(:unupvote, upvote_query)
|
||||
|> Multi.delete_all(:undownvote, downvote_query)
|
||||
|> Multi.run(:dec_votes_count, fn repo, %{unupvote: {upvotes, nil}, undownvote: {downvotes, nil}} ->
|
||||
{count, nil} =
|
||||
image_query
|
||||
|> repo.update_all(inc: [upvotes_count: -upvotes, downvotes_count: -downvotes, score: downvotes - upvotes])
|
||||
|
||||
"""
|
||||
def change_image_vote(%ImageVote{} = image_vote) do
|
||||
ImageVote.changeset(image_vote, %{})
|
||||
{:ok, count}
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -104,6 +104,22 @@ defmodule Philomena.Images do
|
|||
Image.changeset(image, %{})
|
||||
end
|
||||
|
||||
def reindex_image(%Image{} = image) do
|
||||
spawn fn ->
|
||||
Image
|
||||
|> preload(^indexing_preloads())
|
||||
|> where(id: ^image.id)
|
||||
|> Repo.one()
|
||||
|> Image.index_document()
|
||||
end
|
||||
|
||||
image
|
||||
end
|
||||
|
||||
def indexing_preloads do
|
||||
[:user, :favers, :downvoters, :upvoters, :hiders, :deleter, :gallery_interactions, tags: [:aliases, :aliased_tag]]
|
||||
end
|
||||
|
||||
alias Philomena.Images.Subscription
|
||||
|
||||
@doc """
|
||||
|
|
|
@ -83,4 +83,13 @@ defmodule Philomena.Images.Image do
|
|||
|> cast(attrs, [])
|
||||
|> validate_required([])
|
||||
end
|
||||
|
||||
def interaction_data(image) do
|
||||
%{
|
||||
score: image.score,
|
||||
faves: image.faves_count,
|
||||
upvotes: image.upvotes_count,
|
||||
downvotes: image.downvotes_count
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
60
lib/philomena/interactions.ex
Normal file
60
lib/philomena/interactions.ex
Normal file
|
@ -0,0 +1,60 @@
|
|||
defmodule Philomena.Interactions do
|
||||
import Ecto.Query
|
||||
|
||||
alias Philomena.ImageHides.ImageHide
|
||||
alias Philomena.ImageFaves.ImageFave
|
||||
alias Philomena.ImageVotes.ImageVote
|
||||
alias Philomena.Repo
|
||||
|
||||
def user_interactions(_images, nil),
|
||||
do: []
|
||||
|
||||
def user_interactions(images, user) do
|
||||
ids =
|
||||
images
|
||||
|> Enum.flat_map(fn
|
||||
nil -> []
|
||||
%{id: id} -> [id]
|
||||
enum -> Enum.map(enum, & &1.id)
|
||||
end)
|
||||
|> Enum.uniq()
|
||||
|
||||
hide_interactions =
|
||||
ImageHide
|
||||
|> select([h], %{image_id: h.image_id, user_id: h.user_id, interaction_type: ^"hidden", value: ^""})
|
||||
|> where([h], h.image_id in ^ids)
|
||||
|> where(user_id: ^user.id)
|
||||
|
||||
fave_interactions =
|
||||
ImageFave
|
||||
|> select([f], %{image_id: f.image_id, user_id: f.user_id, interaction_type: ^"faved", value: ^""})
|
||||
|> where([f], f.image_id in ^ids)
|
||||
|> where(user_id: ^user.id)
|
||||
|
||||
upvote_interactions =
|
||||
ImageVote
|
||||
|> select([v], %{image_id: v.image_id, user_id: v.user_id, interaction_type: ^"voted", value: ^"up"})
|
||||
|> where([v], v.image_id in ^ids)
|
||||
|> where(user_id: ^user.id, up: true)
|
||||
|
||||
downvote_interactions =
|
||||
ImageVote
|
||||
|> select([v], %{image_id: v.image_id, user_id: v.user_id, interaction_type: ^"voted", value: ^"down"})
|
||||
|> where([v], v.image_id in ^ids)
|
||||
|> where(user_id: ^user.id, up: false)
|
||||
|
||||
[
|
||||
hide_interactions,
|
||||
fave_interactions,
|
||||
upvote_interactions,
|
||||
downvote_interactions
|
||||
]
|
||||
|> union_all_queries()
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
defp union_all_queries([query]),
|
||||
do: query
|
||||
defp union_all_queries([query | rest]),
|
||||
do: query |> union_all(^union_all_queries(rest))
|
||||
end
|
|
@ -1,7 +1,9 @@
|
|||
defmodule PhilomenaWeb.ActivityController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.{Images, Images.Image, Images.Feature, Comments.Comment, Channels.Channel, Topics.Topic, Forums.Forum}
|
||||
alias Philomena.{Images.Image, ImageFeatures.ImageFeature, Comments.Comment, Channels.Channel, Topics.Topic, Forums.Forum}
|
||||
alias Philomena.Interactions
|
||||
alias Philomena.Images
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
||||
|
@ -15,8 +17,11 @@ defmodule PhilomenaWeb.ActivityController do
|
|||
%{
|
||||
query: %{
|
||||
bool: %{
|
||||
must_not: filter,
|
||||
must: image_query
|
||||
must: image_query,
|
||||
must_not: [
|
||||
filter,
|
||||
%{term: %{hidden_from_users: true}}
|
||||
],
|
||||
}
|
||||
},
|
||||
sort: %{created_at: :desc}
|
||||
|
@ -30,8 +35,11 @@ defmodule PhilomenaWeb.ActivityController do
|
|||
%{
|
||||
query: %{
|
||||
bool: %{
|
||||
must_not: filter,
|
||||
must: %{range: %{first_seen_at: %{gt: "now-3d"}}}
|
||||
must: %{range: %{first_seen_at: %{gt: "now-3d"}}},
|
||||
must_not: [
|
||||
filter,
|
||||
%{term: %{hidden_from_users: true}}
|
||||
]
|
||||
}
|
||||
},
|
||||
sort: [%{score: :desc}, %{first_seen_at: :desc}]
|
||||
|
@ -67,8 +75,11 @@ defmodule PhilomenaWeb.ActivityController do
|
|||
%{
|
||||
query: %{
|
||||
bool: %{
|
||||
must_not: filter,
|
||||
must: watched_query
|
||||
must: watched_query,
|
||||
must_not: [
|
||||
filter,
|
||||
%{term: %{hidden_from_users: true}}
|
||||
]
|
||||
}
|
||||
},
|
||||
sort: %{created_at: :desc}
|
||||
|
@ -80,7 +91,7 @@ defmodule PhilomenaWeb.ActivityController do
|
|||
|
||||
featured_image =
|
||||
Image
|
||||
|> join(:inner, [i], f in Feature, on: [image_id: i.id])
|
||||
|> join(:inner, [i], f in ImageFeature, on: [image_id: i.id])
|
||||
|> order_by([i, f], desc: f.created_at)
|
||||
|> limit(1)
|
||||
|> preload([:tags])
|
||||
|
@ -105,6 +116,12 @@ defmodule PhilomenaWeb.ActivityController do
|
|||
|> limit(6)
|
||||
|> Repo.all()
|
||||
|
||||
interactions =
|
||||
Interactions.user_interactions(
|
||||
[images, top_scoring, watched, featured_image],
|
||||
user
|
||||
)
|
||||
|
||||
render(
|
||||
conn,
|
||||
"index.html",
|
||||
|
@ -114,7 +131,8 @@ defmodule PhilomenaWeb.ActivityController do
|
|||
watched: watched,
|
||||
featured_image: featured_image,
|
||||
streams: streams,
|
||||
topics: topics
|
||||
topics: topics,
|
||||
interactions: interactions
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
60
lib/philomena_web/controllers/image/fave_controller.ex
Normal file
60
lib/philomena_web/controllers/image/fave_controller.ex
Normal file
|
@ -0,0 +1,60 @@
|
|||
defmodule PhilomenaWeb.Image.FaveController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.{Images, Images.Image}
|
||||
alias Philomena.{ImageFaves, ImageVotes}
|
||||
alias Philomena.Repo
|
||||
alias Ecto.Multi
|
||||
|
||||
plug PhilomenaWeb.Plugs.FilterBannedUsers
|
||||
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true
|
||||
|
||||
def create(conn, _params) do
|
||||
user = conn.assigns.current_user
|
||||
image = conn.assigns.image
|
||||
|
||||
Multi.append(
|
||||
ImageFaves.delete_fave_transaction(image, user),
|
||||
ImageFaves.create_fave_transaction(image, user)
|
||||
)
|
||||
|> Multi.append(ImageVotes.delete_vote_transaction(image, user))
|
||||
|> Multi.append(ImageVotes.create_vote_transaction(image, user, true))
|
||||
|> Repo.transaction()
|
||||
|> case do
|
||||
{:ok, _result} ->
|
||||
image =
|
||||
Images.get_image!(image.id)
|
||||
|> Images.reindex_image()
|
||||
|
||||
conn
|
||||
|> json(Image.interaction_data(image))
|
||||
|
||||
_error ->
|
||||
conn
|
||||
|> Plug.Conn.put_status(409)
|
||||
|> json(%{})
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, _params) do
|
||||
user = conn.assigns.current_user
|
||||
image = conn.assigns.image
|
||||
|
||||
ImageFaves.delete_fave_transaction(image, user)
|
||||
|> Repo.transaction()
|
||||
|> case do
|
||||
{:ok, _result} ->
|
||||
image =
|
||||
Images.get_image!(image.id)
|
||||
|> Images.reindex_image()
|
||||
|
||||
conn
|
||||
|> json(Image.interaction_data(image))
|
||||
|
||||
_error ->
|
||||
conn
|
||||
|> Plug.Conn.put_status(409)
|
||||
|> json(%{})
|
||||
end
|
||||
end
|
||||
end
|
58
lib/philomena_web/controllers/image/hide_controller.ex
Normal file
58
lib/philomena_web/controllers/image/hide_controller.ex
Normal file
|
@ -0,0 +1,58 @@
|
|||
defmodule PhilomenaWeb.Image.HideController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.{Images, Images.Image}
|
||||
alias Philomena.ImageHides
|
||||
alias Philomena.Repo
|
||||
alias Ecto.Multi
|
||||
|
||||
plug PhilomenaWeb.Plugs.FilterBannedUsers
|
||||
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true
|
||||
|
||||
def create(conn, _params) do
|
||||
user = conn.assigns.current_user
|
||||
image = conn.assigns.image
|
||||
|
||||
Multi.append(
|
||||
ImageHides.delete_hide_transaction(image, user),
|
||||
ImageHides.create_hide_transaction(image, user)
|
||||
)
|
||||
|> Repo.transaction()
|
||||
|> case do
|
||||
{:ok, _result} ->
|
||||
image =
|
||||
Images.get_image!(image.id)
|
||||
|> Images.reindex_image()
|
||||
|
||||
conn
|
||||
|> json(Image.interaction_data(image))
|
||||
|
||||
_error ->
|
||||
conn
|
||||
|> Plug.Conn.put_status(409)
|
||||
|> json(%{})
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, _params) do
|
||||
user = conn.assigns.current_user
|
||||
image = conn.assigns.image
|
||||
|
||||
ImageHides.delete_hide_transaction(image, user)
|
||||
|> Repo.transaction()
|
||||
|> case do
|
||||
{:ok, _result} ->
|
||||
image =
|
||||
Images.get_image!(image.id)
|
||||
|> Images.reindex_image()
|
||||
|
||||
conn
|
||||
|> json(Image.interaction_data(image))
|
||||
|
||||
_error ->
|
||||
conn
|
||||
|> Plug.Conn.put_status(409)
|
||||
|> json(%{})
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,18 +1,58 @@
|
|||
defmodule PhilomenaWeb.Image.VoteController do
|
||||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.Images.Image
|
||||
# alias Philomena.Repo
|
||||
# alias Ecto.Multi
|
||||
alias Philomena.{Images, Images.Image}
|
||||
alias Philomena.ImageVotes
|
||||
alias Philomena.Repo
|
||||
alias Ecto.Multi
|
||||
|
||||
plug PhilomenaWeb.Plugs.FilterBannedUsers
|
||||
plug :load_and_authorize_resource, model: Image, id_name: "image_id", persisted: true
|
||||
|
||||
def create(conn, _params) do
|
||||
def create(conn, params) do
|
||||
user = conn.assigns.current_user
|
||||
image = conn.assigns.image
|
||||
|
||||
Multi.append(
|
||||
ImageVotes.delete_vote_transaction(image, user),
|
||||
ImageVotes.create_vote_transaction(image, user, params["up"] == true)
|
||||
)
|
||||
|> Repo.transaction()
|
||||
|> case do
|
||||
{:ok, _result} ->
|
||||
image =
|
||||
Images.get_image!(image.id)
|
||||
|> Images.reindex_image()
|
||||
|
||||
conn
|
||||
|> json(Image.interaction_data(image))
|
||||
|
||||
_error ->
|
||||
conn
|
||||
|> Plug.Conn.put_status(409)
|
||||
|> json(%{})
|
||||
end
|
||||
end
|
||||
|
||||
def delete(conn, _params) do
|
||||
user = conn.assigns.current_user
|
||||
image = conn.assigns.image
|
||||
|
||||
ImageVotes.delete_vote_transaction(image, user)
|
||||
|> Repo.transaction()
|
||||
|> case do
|
||||
{:ok, _result} ->
|
||||
image =
|
||||
Images.get_image!(image.id)
|
||||
|> Images.reindex_image()
|
||||
|
||||
conn
|
||||
|> json(Image.interaction_data(image))
|
||||
|
||||
_error ->
|
||||
conn
|
||||
|> Plug.Conn.put_status(409)
|
||||
|> json(%{})
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,6 +2,7 @@ defmodule PhilomenaWeb.ImageController do
|
|||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.{Images.Image, Comments.Comment, Textile.Renderer}
|
||||
alias Philomena.Interactions
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
||||
|
@ -20,13 +21,18 @@ defmodule PhilomenaWeb.ImageController do
|
|||
Image |> preload([:tags, :user])
|
||||
)
|
||||
|
||||
render(conn, "index.html", images: images)
|
||||
interactions =
|
||||
Interactions.user_interactions(images, conn.assigns.current_user)
|
||||
|
||||
render(conn, "index.html", images: images, interactions: interactions)
|
||||
end
|
||||
|
||||
def show(conn, %{"id" => _id}) do
|
||||
image = conn.assigns.image
|
||||
|
||||
comments =
|
||||
Comment
|
||||
|> where(image_id: ^conn.assigns.image.id)
|
||||
|> where(image_id: ^image.id)
|
||||
|> preload([:image, user: [awards: :badge]])
|
||||
|> order_by(desc: :created_at)
|
||||
|> limit(25)
|
||||
|
@ -40,9 +46,12 @@ defmodule PhilomenaWeb.ImageController do
|
|||
%{comments | entries: Enum.zip(comments.entries, rendered)}
|
||||
|
||||
description =
|
||||
%{body: conn.assigns.image.description}
|
||||
%{body: image.description}
|
||||
|> Renderer.render_one()
|
||||
|
||||
render(conn, "show.html", image: conn.assigns.image, comments: comments, description: description)
|
||||
interactions =
|
||||
Interactions.user_interactions([image], conn.assigns.current_user)
|
||||
|
||||
render(conn, "show.html", image: image, comments: comments, description: description, interactions: interactions)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,13 +2,14 @@ defmodule PhilomenaWeb.SearchController do
|
|||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.Images.{Image, Query}
|
||||
alias Philomena.Interactions
|
||||
alias Pow.Plug
|
||||
|
||||
import Ecto.Query
|
||||
|
||||
def index(conn, params) do
|
||||
filter = conn.assigns[:compiled_filter]
|
||||
user = conn |> Plug.current_user()
|
||||
filter = conn.assigns.compiled_filter
|
||||
user = conn.assigns.current_user
|
||||
|
||||
with {:ok, query} <- Query.compile(user, params["q"]) do
|
||||
images =
|
||||
|
@ -21,8 +22,11 @@ defmodule PhilomenaWeb.SearchController do
|
|||
Image |> preload(:tags)
|
||||
)
|
||||
|
||||
interactions =
|
||||
Interactions.user_interactions(images, user)
|
||||
|
||||
conn
|
||||
|> render("index.html", images: images, search_query: params["q"])
|
||||
|> render("index.html", images: images, search_query: params["q"], interactions: interactions)
|
||||
else
|
||||
{:error, msg} ->
|
||||
conn
|
||||
|
|
|
@ -54,6 +54,11 @@ defmodule PhilomenaWeb.Router do
|
|||
|
||||
resources "/notifications", NotificationController, only: [:index, :delete]
|
||||
resources "/conversations", ConversationController, only: [:index, :show]
|
||||
resources "/images", ImageController, only: [] 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
|
||||
end
|
||||
end
|
||||
|
||||
scope "/", PhilomenaWeb do
|
||||
|
|
Loading…
Reference in a new issue