Skip to content
This repository was archived by the owner on Nov 8, 2022. It is now read-only.

Commit d466c75

Browse files
authored
refactor(delivery): redesign && rewrite (#404)
* refactor(delivery): back up mentions and notification * refactor(delivery): back up mentions and notification * refactor(delivery): back up mentions and notification wip * refactor(delivery): wip * refactor(delivery): wip * refactor(delivery): wip * refactor(delivery): wip * refactor(delivery): wip * refactor(delivery): re-org mention & dir, naming * refactor(delivery): move cite ORM opt to delegate & fmt, naming * refactor(delivery): fix dup case * refactor(delivery): wip * refactor(delivery): mention wip * refactor(delivery): cite fix * refactor(delivery): more test on mention * refactor(delivery): better naming * refactor(delivery): better naming * refactor(delivery): mini improve * refactor(delivery): rename fetch instead of paged_mention * refactor(delivery): notification wip * refactor(delivery): notification wip * refactor(delivery): notification wip * refactor(delivery): notification wip, cool * refactor(delivery): use common atom key * refactor(delivery): upvote hooks * refactor(delivery): upvote hooks for job & blog tests * refactor(delivery): collect hooks & tests * refactor(delivery): rename type -> thread in notification * refactor(delivery): fix test * refactor(delivery): fix test * refactor(delivery): enhence test * refactor(cite): naming adjust * refactor(mention): rename type -> thread * refactor(mention): clean up * refactor(mention): mention thread clean up * refactor(mention): fix test * refactor(mention): fix test * refactor(notify): test for follow * refactor(notify): hooks for follow & test * refactor(notify): wip * refactor(notify): mark read & re-org ORM functions * refactor(notify): clean up * refactor(notify): remove old delivery system * refactor(notify): remove mention parse when create article * refactor(notify): refactor account mailbox tests * refactor(notify): fix notify update * refactor(mailbox): mark read test & re-org * refactor(mailbox): remove old account mails tables * refactor(mailbox): read_all test * refactor(mailbox): paged mentions & test * refactor(mailbox): paged notification & test * refactor(mailbox): read in filter * refactor(mailbox): clean up wip * refactor(mailbox): fix tests
1 parent 380330d commit d466c75

File tree

97 files changed

+3138
-2461
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+3138
-2461
lines changed

config/config.exs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,11 @@ config :groupher_server, :general,
4747
user_achieve_upvote_weight: 1,
4848
user_achieve_watch_weight: 1,
4949
user_achieve_collect_weight: 2,
50-
user_achieve_follow_weight: 3
50+
user_achieve_follow_weight: 3,
51+
# others
52+
# 在这个时间段内,多条提醒消息将被合并为一条
53+
notify_group_interval_hour: 1,
54+
nofity_actions: [:upvote, :comment, :reply, :collect, :follow]
5155

5256
config :groupher_server, :customization,
5357
theme: "cyan",

lib/groupher_server/accounts/accounts.ex

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ defmodule GroupherServer.Accounts do
77
Fans,
88
CollectFolder,
99
Publish,
10-
Mails,
10+
Mailbox,
1111
Profile,
1212
UpvotedArticles,
1313
Search,
@@ -62,17 +62,12 @@ defmodule GroupherServer.Accounts do
6262
# upvoted articles
6363
defdelegate paged_upvoted_articles(user_id, filter), to: UpvotedArticles
6464

65-
# mentions
66-
defdelegate fetch_mentions(user, filter), to: Mails
65+
defdelegate mailbox_status(user), to: Mailbox
66+
defdelegate update_mailbox_status(user_id), to: Mailbox
67+
defdelegate mark_read(type, ids, user_id), to: Mailbox
68+
defdelegate mark_read_all(tyoe, user_id), to: Mailbox
6769

68-
# notifications
69-
defdelegate fetch_notifications(user, filter), to: Mails
70-
defdelegate fetch_sys_notifications(user, filter), to: Mails
71-
72-
# common message
73-
defdelegate mailbox_status(user), to: Mails
74-
defdelegate mark_mail_read_all(user, opt), to: Mails
75-
defdelegate mark_mail_read(mail, user), to: Mails
70+
defdelegate paged_mailbox_messages(type, user, filter), to: Mailbox
7671

7772
# customization
7873
defdelegate get_customization(user), to: Customization

lib/groupher_server/accounts/delegates/fans.ex

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ defmodule GroupherServer.Accounts.Delegate.Fans do
77
import Helper.ErrorCode
88
import ShortMaps
99

10-
alias Helper.{ORM, QueryBuilder, SpecType}
10+
alias Helper.{ORM, QueryBuilder, Later, SpecType}
1111
alias GroupherServer.{Accounts, Repo}
1212

13-
alias GroupherServer.Accounts.Model.{User, Embeds, UserFollower, UserFollowing}
13+
alias Accounts.Model.{User, Embeds, UserFollower, UserFollowing}
14+
alias Accounts.Delegate.Hooks
1415

1516
alias Ecto.Multi
1617

@@ -20,27 +21,30 @@ defmodule GroupherServer.Accounts.Delegate.Fans do
2021
follow a user
2122
"""
2223
@spec follow(User.t(), User.t()) :: {:ok, User.t()} | SpecType.gq_error()
23-
def follow(%User{id: user_id}, %User{id: follower_id}) do
24-
with true <- to_string(user_id) !== to_string(follower_id),
25-
{:ok, target_user} <- ORM.find(User, follower_id) do
24+
def follow(%User{} = user, %User{} = follower) do
25+
with true <- to_string(user.id) !== to_string(follower.id),
26+
{:ok, target_user} <- ORM.find(User, follower.id) do
2627
Multi.new()
2728
|> Multi.insert(
2829
:create_follower,
29-
UserFollower.changeset(%UserFollower{}, %{user_id: target_user.id, follower_id: user_id})
30+
UserFollower.changeset(%UserFollower{}, %{user_id: target_user.id, follower_id: user.id})
3031
)
3132
|> Multi.insert(
3233
:create_following,
3334
UserFollowing.changeset(%UserFollowing{}, %{
34-
user_id: user_id,
35+
user_id: user.id,
3536
following_id: target_user.id
3637
})
3738
)
3839
|> Multi.run(:update_user_follow_info, fn _, _ ->
39-
update_user_follow_info(target_user, user_id, :add)
40+
update_user_follow_info(target_user, user.id, :add)
4041
end)
4142
|> Multi.run(:add_achievement, fn _, _ ->
4243
Accounts.achieve(%User{id: target_user.id}, :inc, :follow)
4344
end)
45+
|> Multi.run(:after_hooks, fn _, _ ->
46+
Later.run({Hooks.Notify, :handle, [:follow, user, follower]})
47+
end)
4448
|> Repo.transaction()
4549
|> result()
4650
else
@@ -53,22 +57,25 @@ defmodule GroupherServer.Accounts.Delegate.Fans do
5357
undo a follow action to a user
5458
"""
5559
@spec undo_follow(User.t(), User.t()) :: {:ok, User.t()} | SpecType.gq_error()
56-
def undo_follow(%User{id: user_id}, %User{id: follower_id}) do
57-
with true <- to_string(user_id) !== to_string(follower_id),
58-
{:ok, target_user} <- ORM.find(User, follower_id) do
60+
def undo_follow(%User{} = user, %User{} = follower) do
61+
with true <- to_string(user.id) !== to_string(follower.id),
62+
{:ok, target_user} <- ORM.find(User, follower.id) do
5963
Multi.new()
6064
|> Multi.run(:delete_follower, fn _, _ ->
61-
ORM.findby_delete!(UserFollower, %{user_id: target_user.id, follower_id: user_id})
65+
ORM.findby_delete!(UserFollower, %{user_id: target_user.id, follower_id: user.id})
6266
end)
6367
|> Multi.run(:delete_following, fn _, _ ->
64-
ORM.findby_delete!(UserFollowing, %{user_id: user_id, following_id: target_user.id})
68+
ORM.findby_delete!(UserFollowing, %{user_id: user.id, following_id: target_user.id})
6569
end)
6670
|> Multi.run(:update_user_follow_info, fn _, _ ->
67-
update_user_follow_info(target_user, user_id, :remove)
71+
update_user_follow_info(target_user, user.id, :remove)
6872
end)
6973
|> Multi.run(:minus_achievement, fn _, _ ->
7074
Accounts.achieve(%User{id: target_user.id}, :dec, :follow)
7175
end)
76+
|> Multi.run(:after_hooks, fn _, _ ->
77+
Later.run({Hooks.Notify, :handle, [:undo, :follow, user, follower]})
78+
end)
7279
|> Repo.transaction()
7380
|> result()
7481
else
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
defmodule GroupherServer.Accounts.Delegate.Hooks.Notify do
2+
@moduledoc """
3+
notify hooks, for upvote, collect, comment, reply
4+
"""
5+
alias GroupherServer.{Accounts, Delivery}
6+
alias Accounts.Model.User
7+
8+
# 发布评论是特殊情况,单独处理
9+
def handle(:follow, %User{} = user, %User{} = from_user) do
10+
notify_attrs = %{
11+
action: :follow,
12+
user_id: user.id
13+
}
14+
15+
Delivery.send(:notify, notify_attrs, from_user)
16+
end
17+
18+
def handle(:undo, :follow, %User{} = user, %User{} = from_user) do
19+
notify_attrs = %{
20+
action: :follow,
21+
user_id: user.id
22+
}
23+
24+
Delivery.revoke(:notify, notify_attrs, from_user)
25+
end
26+
end
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
defmodule GroupherServer.Accounts.Delegate.Mailbox do
2+
import Ecto.Query, warn: false
3+
4+
import Helper.Utils, only: [done: 1]
5+
6+
alias GroupherServer.{Accounts, Delivery}
7+
8+
alias Accounts.Model.{Embeds, User}
9+
alias Helper.ORM
10+
11+
@default_mailbox_status Embeds.UserMailbox.default_status()
12+
13+
def mailbox_status(%User{mailbox: nil}), do: @default_mailbox_status |> done
14+
def mailbox_status(%User{mailbox: mailbox}), do: mailbox |> done
15+
16+
def mark_read(type, ids, %User{} = user) do
17+
Delivery.mark_read(type, ids, user)
18+
end
19+
20+
def mark_read_all(type, %User{} = user), do: Delivery.mark_read_all(type, user)
21+
22+
def paged_mailbox_messages(type, user, filter) do
23+
Delivery.fetch(type, user, filter)
24+
end
25+
26+
@doc "update messages count in mailbox"
27+
def update_mailbox_status(user_id) do
28+
with {:ok, user} <- ORM.find(User, user_id),
29+
{:ok, unread_mentions_count} <- Delivery.unread_count(:mention, user_id),
30+
{:ok, unread_notifications_count} <- Delivery.unread_count(:notification, user_id) do
31+
unread_total_count = unread_mentions_count + unread_notifications_count
32+
is_empty = unread_total_count < 1
33+
34+
mailbox = %{
35+
unread_mentions_count: unread_mentions_count,
36+
unread_notifications_count: unread_notifications_count,
37+
unread_total_count: unread_total_count,
38+
is_empty: is_empty
39+
}
40+
41+
user |> ORM.update_embed(:mailbox, mailbox)
42+
end
43+
end
44+
end

lib/groupher_server/accounts/delegates/mails.ex

Lines changed: 0 additions & 130 deletions
This file was deleted.

lib/groupher_server/accounts/delegates/profile.ex

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ defmodule GroupherServer.Accounts.Delegate.Profile do
7272
"""
7373
def update_subscribe_count(user_id) do
7474
with {:ok, user} <- ORM.find(User, user_id) do
75-
count_query = from(s in CommunitySubscriber, where: s.user_id == ^user.id)
76-
count = Repo.aggregate(count_query, :count)
75+
{:ok, count} = from(s in CommunitySubscriber, where: s.user_id == ^user.id) |> ORM.count()
7776

7877
user |> ORM.update(%{subscribed_communities_count: count})
7978
end
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
defmodule GroupherServer.Accounts.Model.Embeds.UserMailbox do
2+
@moduledoc """
3+
general article meta info for articles
4+
"""
5+
use Ecto.Schema
6+
use Accessible
7+
8+
import Ecto.Changeset
9+
10+
@optional_fields ~w(is_empty unread_total_count unread_mentions_count unread_notifications_count)a
11+
12+
def default_status() do
13+
%{
14+
is_empty: true,
15+
unread_total_count: 0,
16+
unread_mentions_count: 0,
17+
unread_notifications_count: 0
18+
}
19+
end
20+
21+
embedded_schema do
22+
field(:is_empty, :boolean, default: true)
23+
field(:unread_total_count, :integer, default: 0)
24+
field(:unread_mentions_count, :integer, default: 0)
25+
field(:unread_notifications_count, :integer, default: 0)
26+
end
27+
28+
def changeset(struct, params) do
29+
struct |> cast(params, @optional_fields)
30+
end
31+
end

0 commit comments

Comments
 (0)