Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.
Merged
4 changes: 2 additions & 2 deletions lib/groupher_server/cms/article_comment.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ defmodule GroupherServer.CMS.ArticleComment do
@report_threshold_for_fold 5

# 每篇文章最多含有置顶评论的条数
@pined_comment_limit 10
@pinned_comment_limit 10

@doc "latest participators stores in article article_comment_participators field"
def max_participator_count(), do: @max_participator_count
Expand All @@ -47,7 +47,7 @@ defmodule GroupherServer.CMS.ArticleComment do
def delete_hint(), do: @delete_hint

def report_threshold_for_fold, do: @report_threshold_for_fold
def pined_comment_limit, do: @pined_comment_limit
def pinned_comment_limit, do: @pinned_comment_limit

@type t :: %ArticleComment{}
schema "articles_comments" do
Expand Down
44 changes: 0 additions & 44 deletions lib/groupher_server/cms/article_pined_comment.ex

This file was deleted.

40 changes: 40 additions & 0 deletions lib/groupher_server/cms/article_pinned_comment.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
defmodule GroupherServer.CMS.ArticlePinnedComment do
@moduledoc false
alias __MODULE__

use Ecto.Schema
use Accessible

import Ecto.Changeset

alias GroupherServer.CMS
alias CMS.ArticleComment

# alias Helper.HTML

@required_fields ~w(article_comment_id)a
@optional_fields ~w(post_id job_id repo_id)a

@type t :: %ArticlePinnedComment{}
schema "articles_pinned_comments" do
belongs_to(:article_comment, ArticleComment, foreign_key: :article_comment_id)
belongs_to(:post, CMS.Post, foreign_key: :post_id)
belongs_to(:job, CMS.Job, foreign_key: :job_id)
belongs_to(:repo, CMS.Repo, foreign_key: :repo_id)

timestamps(type: :utc_datetime)
end

@doc false
def changeset(%ArticlePinnedComment{} = article_pined_comment, attrs) do
article_pined_comment
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
end

# @doc false
def update_changeset(%ArticlePinnedComment{} = article_pined_comment, attrs) do
article_pined_comment
|> cast(attrs, @required_fields ++ @optional_fields)
end
end
24 changes: 10 additions & 14 deletions lib/groupher_server/cms/delegates/article_comment.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
CURD and operations for article comments
"""
import Ecto.Query, warn: false
import Helper.Utils, only: [done: 1, get_config: 2]
import Helper.Utils, only: [done: 1]
import Helper.ErrorCode

import GroupherServer.CMS.Delegate.Helper, only: [mark_viewer_emotion_states: 3]
Expand All @@ -15,16 +15,15 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
alias GroupherServer.{Accounts, CMS, Repo}

alias Accounts.User
alias CMS.{ArticleComment, ArticlePinedComment, Embeds}
alias CMS.{ArticleComment, ArticlePinnedComment, Embeds}
alias Ecto.Multi

@supported_emotions get_config(:article, :comment_supported_emotions)
@max_participator_count ArticleComment.max_participator_count()
@default_emotions Embeds.ArticleCommentEmotion.default_emotions()
@delete_hint ArticleComment.delete_hint()

@default_comment_meta Embeds.ArticleCommentMeta.default_meta()
@pined_comment_limit ArticleComment.pined_comment_limit()
@pinned_comment_limit ArticleComment.pinned_comment_limit()

@doc """
[timeline-mode] list paged article comments
Expand Down Expand Up @@ -69,7 +68,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
do_paged_comment_replies(comment_id, filters, user)
end

@spec paged_article_comments_participators(T.comment_thread(), Integer.t(), T.paged_filter()) ::
@spec paged_article_comments_participators(T.article_thread(), Integer.t(), T.paged_filter()) ::
{:ok, T.paged_users()}
def paged_article_comments_participators(thread, article_id, filters) do
%{page: page, size: size} = filters
Expand Down Expand Up @@ -125,7 +124,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
update_article_comments_count(comment, :dec)
end)
|> Multi.run(:remove_pined_comment, fn _, _ ->
ORM.findby_delete(ArticlePinedComment, %{article_comment_id: comment.id})
ORM.findby_delete(ArticlePinnedComment, %{article_comment_id: comment.id})
end)
|> Multi.run(:delete_article_comment, fn _, _ ->
ORM.update(comment, %{body_html: @delete_hint, is_deleted: true})
Expand Down Expand Up @@ -236,7 +235,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do
}) do
with {:ok, info} <- match(thread),
query <-
from(p in ArticlePinedComment,
from(p in ArticlePinnedComment,
join: c in ArticleComment,
on: p.article_comment_id == c.id,
where: field(p, ^info.foreign_key) == ^article_id,
Expand All @@ -249,17 +248,14 @@ defmodule GroupherServer.CMS.Delegate.ArticleComment do

_ ->
preloaded_pined_comments =
Enum.slice(pined_comments, 0, @pined_comment_limit)
Enum.slice(pined_comments, 0, @pinned_comment_limit)
|> Repo.preload(reply_to: :author)

updated_entries = Enum.concat(preloaded_pined_comments, entries)

entries = Enum.concat(preloaded_pined_comments, entries)
pined_comment_count = length(pined_comments)

Map.merge(paged_comments, %{
entries: updated_entries,
total_count: paged_comments.total_count + pined_comment_count
})
total_count = paged_comments.total_count + pined_comment_count
paged_comments |> Map.merge(%{entries: entries, total_count: total_count})
end
end
end
Expand Down
33 changes: 24 additions & 9 deletions lib/groupher_server/cms/delegates/article_comment_action.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,20 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do

alias CMS.{
ArticleComment,
ArticlePinedComment,
ArticlePinnedComment,
ArticleCommentUpvote,
ArticleCommentReply,
Community,
# TODO: remove spec type
Post,
Job
}

alias Ecto.Multi

@article_threads Community.article_threads()
@max_parent_replies_count ArticleComment.max_parent_replies_count()
@pined_comment_limit ArticleComment.pined_comment_limit()
@pinned_comment_limit ArticleComment.pinned_comment_limit()

@spec pin_article_comment(Integer.t()) :: {:ok, ArticleComment.t()}
@doc "pin a comment"
Expand All @@ -41,22 +43,25 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do
Multi.new()
|> Multi.run(:checked_pined_comments_count, fn _, _ ->
count_query =
from(p in ArticlePinedComment,
from(p in ArticlePinnedComment,
where: field(p, ^info.foreign_key) == ^full_comment.article.id
)

pined_comments_count = Repo.aggregate(count_query, :count)

case pined_comments_count >= @pined_comment_limit do
true -> {:error, "only support #{@pined_comment_limit} pined comment for each article"}
false -> {:ok, :pass}
case pined_comments_count >= @pinned_comment_limit do
true ->
{:error, "only support #{@pinned_comment_limit} pinned comment for each article"}

false ->
{:ok, :pass}
end
end)
|> Multi.run(:update_comment_flag, fn _, _ ->
ORM.update(comment, %{is_pinned: true})
end)
|> Multi.run(:add_pined_comment, fn _, _ ->
ArticlePinedComment
ArticlePinnedComment
|> ORM.create(
%{article_comment_id: comment.id}
|> Map.put(info.foreign_key, full_comment.article.id)
Expand All @@ -74,7 +79,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do
ORM.update(comment, %{is_pinned: false})
end)
|> Multi.run(:remove_pined_comment, fn _, _ ->
ORM.findby_delete(ArticlePinedComment, %{article_comment_id: comment.id})
ORM.findby_delete(ArticlePinnedComment, %{article_comment_id: comment.id})
end)
|> Repo.transaction()
|> result()
Expand Down Expand Up @@ -256,9 +261,15 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do
end
end

defp get_article(%ArticleComment{repo_id: repo_id} = comment) when not is_nil(repo_id) do
with {:ok, article} <- ORM.find(CMS.Repo, comment.repo_id, preload: [author: :user]) do
{:repo, article}
end
end

@spec get_full_comment(String.t()) :: {:ok, T.article_info()} | {:error, nil}
defp get_full_comment(comment_id) do
query = from(c in ArticleComment, where: c.id == ^comment_id, preload: :post, preload: :job)
query = from(c in ArticleComment, where: c.id == ^comment_id, preload: ^@article_threads)

with {:ok, comment} <- Repo.one(query) |> done() do
extract_article_info(comment)
Expand All @@ -273,6 +284,10 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommentAction do
do_extract_article_info(:job, job)
end

defp extract_article_info(%ArticleComment{repo: %CMS.Repo{} = repo}) when not is_nil(repo) do
do_extract_article_info(:repo, repo)
end

@spec do_extract_article_info(T.article_thread(), T.article_common()) :: {:ok, T.article_info()}
defp do_extract_article_info(thread, article) do
with {:ok, article_with_author} <- Repo.preload(article, author: :user) |> done(),
Expand Down
3 changes: 1 addition & 2 deletions lib/groupher_server/cms/delegates/article_community.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommunity do
import Ecto.Query, warn: false

import Helper.ErrorCode
import ShortMaps
import Helper.Utils, only: [strip_struct: 1, done: 1]
import GroupherServer.CMS.Helper.Matcher2

Expand Down Expand Up @@ -202,7 +201,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCommunity do

def lock_article_comment(content), do: {:ok, content}

# check if the thread has aready enough pined articles
# check if the thread has aready enough pinned articles
defp check_pinned_article_count(community_id, thread) do
thread_upcase = thread |> to_string |> String.upcase()

Expand Down
4 changes: 2 additions & 2 deletions lib/groupher_server/cms/delegates/article_curd.ex
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do
|> join(:inner, [p], article in assoc(p, ^thread))
|> where([p, c, article], c.raw == ^community)
|> select([p, c, article], article)
# 10 pined articles per community/thread, at most
# 10 pinned articles per community/thread, at most
|> ORM.find_all(%{page: 1, size: 10}) do
concat_articles(pinned_articles, articles)
else
Expand Down Expand Up @@ -334,7 +334,7 @@ defmodule GroupherServer.CMS.Delegate.ArticleCURD do

normal_count = non_pinned_articles |> Map.get(:total_count)

# remote the pined article from normal_entries (if have)
# remote the pinned article from normal_entries (if have)
pind_ids = pick_by(pinned_entries, :id)
normal_entries = Enum.reject(normal_entries, &(&1.id in pind_ids))

Expand Down
2 changes: 0 additions & 2 deletions lib/groupher_server/cms/post.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ defmodule GroupherServer.CMS.Post do
Embeds,
Author,
ArticleComment,
ArticlePinedComment,
Community,
PostComment,
Tag,
Expand Down Expand Up @@ -63,7 +62,6 @@ defmodule GroupherServer.CMS.Post do
has_many(:comments, {"posts_comments", PostComment})

has_many(:article_comments, {"articles_comments", ArticleComment})
has_many(:article_pined_comments, {"articles_pined_comments", ArticlePinedComment})
field(:article_comments_count, :integer, default: 0)
field(:article_comments_participators_count, :integer, default: 0)
# 评论参与者,只保留最近 5 个
Expand Down
11 changes: 9 additions & 2 deletions lib/groupher_server/cms/repo.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ defmodule GroupherServer.CMS.Repo do

import Ecto.Changeset

alias GroupherServer.CMS
alias GroupherServer.{CMS, Accounts}

alias CMS.{
Author,
Embeds,
ArticleComment,
Community,
RepoContributor,
RepoLang,
Expand All @@ -24,7 +25,7 @@ defmodule GroupherServer.CMS.Repo do

@timestamps_opts [type: :utc_datetime_usec]
@required_fields ~w(title owner_name owner_url repo_url desc readme star_count issues_count prs_count fork_count watch_count)a
@optional_fields ~w(original_community_id last_sync homepage_url release_tag license upvotes_count collects_count mark_delete)a
@optional_fields ~w(original_community_id last_sync homepage_url release_tag license upvotes_count collects_count mark_delete article_comments_count article_comments_participators_count)a

@type t :: %Repo{}
schema "cms_repos" do
Expand Down Expand Up @@ -73,6 +74,12 @@ defmodule GroupherServer.CMS.Repo do

field(:last_sync, :utc_datetime)

has_many(:article_comments, {"articles_comments", ArticleComment})
field(:article_comments_count, :integer, default: 0)
field(:article_comments_participators_count, :integer, default: 0)
# 评论参与者,只保留最近 5 个
embeds_many(:article_comments_participators, Accounts.User, on_replace: :delete)

many_to_many(
:tags,
Tag,
Expand Down
1 change: 1 addition & 0 deletions lib/groupher_server_web/schema/cms/cms_types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ defmodule GroupherServerWeb.Schema.CMS.Types do
field(:original_community, :community, resolve: dataloader(CMS, :original_community))
field(:communities, list_of(:community), resolve: dataloader(CMS, :communities))

article_comments_fields()
viewer_has_state_fields()
# comments_count
# comments_participators
Expand Down
1 change: 0 additions & 1 deletion lib/helper/types.ex
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ defmodule Helper.Types do
}

@type article_thread :: :post | :job | :repo
@type comment_thread :: :post | :job

@type paged_filter :: %{
page: Integer.t(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule GroupherServer.Repo.Migrations.AddRepoInPinnedArtilceComments do
use Ecto.Migration

def change do
alter table(:articles_pined_comments) do
add(:repo_id, references(:cms_repos, on_delete: :delete_all))
end

create(index(:articles_pined_comments, [:repo_id]))

create(
unique_index(:articles_pined_comments, [:post_id, :job_id, :repo_id, :article_comment_id])
)
end
end
Loading