Allow to join an open group
Also: * Refactor interacting with a remote event so that you can interact with a remote group as well * Add a setting for group admins to pick between an open and invite-only group * Fix new groups without posts/todos/resources/events/conversations URL set * Repair local groups that haven't got their posts/todos/resources/events/conversations URL set * Add a scheduled job to refresh remote groups every hour * Add a user setting to pick when to receive notifications when there's new members to approve (will be used when this feature is available) * Fix pagination for members Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
@@ -4,7 +4,7 @@ defmodule Mobilizon.Service.Notifications.Scheduler do
|
||||
"""
|
||||
|
||||
alias Mobilizon.{Actors, Users}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Actors.{Actor, Member}
|
||||
alias Mobilizon.Events.{Event, Participant}
|
||||
alias Mobilizon.Service.Workers.Notification
|
||||
alias Mobilizon.Users.{Setting, User}
|
||||
@@ -193,6 +193,77 @@ defmodule Mobilizon.Service.Notifications.Scheduler do
|
||||
|
||||
def pending_participation_notification(_), do: {:ok, nil}
|
||||
|
||||
def pending_membership_notification(%Actor{type: :Group, id: group_id}) do
|
||||
group_id
|
||||
|> Actors.list_all_administrator_members_for_group()
|
||||
|> Enum.map(fn %Member{actor: %Actor{id: actor_id}} ->
|
||||
Actors.get_actor(actor_id)
|
||||
end)
|
||||
|> Enum.each(fn actor -> pending_membership_admin_notification(actor, group_id) end)
|
||||
end
|
||||
|
||||
def pending_membership_notification(_), do: {:ok, nil}
|
||||
|
||||
defp pending_membership_admin_notification(%Actor{user_id: user_id}, group_id)
|
||||
when not is_nil(user_id) do
|
||||
case Users.get_user_with_settings!(user_id) do
|
||||
%User{} = user ->
|
||||
pending_membership_admin_notification_user(user, group_id)
|
||||
|
||||
# No user for actor, probably a remote actor, ignore
|
||||
_ ->
|
||||
{:ok, nil}
|
||||
end
|
||||
end
|
||||
|
||||
defp pending_membership_admin_notification_user(
|
||||
%User{
|
||||
id: user_id,
|
||||
locale: locale,
|
||||
settings: %Setting{
|
||||
notification_pending_membership: notification_pending_membership,
|
||||
timezone: timezone
|
||||
}
|
||||
},
|
||||
group_id
|
||||
) do
|
||||
send_at =
|
||||
case notification_pending_membership do
|
||||
:none ->
|
||||
nil
|
||||
|
||||
:direct ->
|
||||
:direct
|
||||
|
||||
:one_day ->
|
||||
calculate_next_day_notification(Date.utc_today(), timezone, locale)
|
||||
|
||||
:one_hour ->
|
||||
DateTime.utc_now()
|
||||
|> DateTime.shift_zone!(timezone)
|
||||
|> (&%{&1 | minute: 0, second: 0, microsecond: {0, 0}}).()
|
||||
end
|
||||
|
||||
params = %{
|
||||
user_id: user_id,
|
||||
group_id: group_id
|
||||
}
|
||||
|
||||
cond do
|
||||
# Sending directly
|
||||
send_at == :direct ->
|
||||
Notification.enqueue(:pending_membership_notification, params)
|
||||
|
||||
# Not sending
|
||||
is_nil(send_at) ->
|
||||
{:ok, nil}
|
||||
|
||||
# Sending to calculated time
|
||||
true ->
|
||||
Notification.enqueue(:pending_membership_notification, params, scheduled_at: send_at)
|
||||
end
|
||||
end
|
||||
|
||||
defp shift_zone(datetime, timezone) do
|
||||
case DateTime.shift_zone(datetime, timezone) do
|
||||
{:ok, shift_datetime} -> shift_datetime
|
||||
|
||||
12
lib/service/workers/refresh_groups.ex
Normal file
12
lib/service/workers/refresh_groups.ex
Normal file
@@ -0,0 +1,12 @@
|
||||
defmodule Mobilizon.Service.Workers.RefreshGroups do
|
||||
@moduledoc """
|
||||
Worker to build sitemap
|
||||
"""
|
||||
|
||||
alias Mobilizon.Federation.ActivityPub.Refresher
|
||||
|
||||
use Oban.Worker, queue: "background"
|
||||
|
||||
@impl Oban.Worker
|
||||
def perform(%Job{}), do: Refresher.refresh_all_external_groups()
|
||||
end
|
||||
Reference in New Issue
Block a user