Send notification emails to followers and members when a group publishes
a new event Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
@@ -4,7 +4,7 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Invite do
|
||||
"""
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.{Actor, Member}
|
||||
alias Mobilizon.Web.Email.Group
|
||||
alias Mobilizon.Web.Email.Member, as: EmailMember
|
||||
require Logger
|
||||
|
||||
import Mobilizon.Federation.ActivityPub.Utils,
|
||||
@@ -56,7 +56,7 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Invite do
|
||||
|
||||
maybe_federate(activity)
|
||||
maybe_relay_if_group_activity(activity)
|
||||
Group.send_invite_to_user(member)
|
||||
EmailMember.send_invite_to_user(member)
|
||||
{:ok, activity, member}
|
||||
end
|
||||
else
|
||||
|
||||
@@ -5,7 +5,7 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Remove do
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.{Actor, Member}
|
||||
alias Mobilizon.Federation.ActivityPub.Activity
|
||||
alias Mobilizon.Web.Email.Group
|
||||
alias Mobilizon.Web.Email.Member, as: EmailMember
|
||||
require Logger
|
||||
|
||||
import Mobilizon.Federation.ActivityPub.Utils,
|
||||
@@ -34,7 +34,7 @@ defmodule Mobilizon.Federation.ActivityPub.Actions.Remove do
|
||||
subject: "member_removed"
|
||||
)
|
||||
|
||||
Group.send_notification_to_removed_member(member)
|
||||
EmailMember.send_notification_to_removed_member(member)
|
||||
|
||||
remove_data = %{
|
||||
"to" => [group_members_url],
|
||||
|
||||
@@ -16,6 +16,7 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
|
||||
alias Mobilizon.Service.Notifications.Scheduler
|
||||
alias Mobilizon.Share
|
||||
alias Mobilizon.Tombstone
|
||||
alias Mobilizon.Web.Email.Group
|
||||
import Mobilizon.Federation.ActivityPub.Utils, only: [make_create_data: 2, make_update_data: 2]
|
||||
require Logger
|
||||
|
||||
@@ -30,6 +31,8 @@ defmodule Mobilizon.Federation.ActivityPub.Types.Events do
|
||||
case EventsManager.create_event(args) do
|
||||
{:ok, %Event{} = event} ->
|
||||
EventActivity.insert_activity(event, subject: "event_created")
|
||||
# TODO make this async
|
||||
Group.notify_of_new_event(event)
|
||||
event_as_data = Convertible.model_to_as(event)
|
||||
audience = Audience.get_audience(event)
|
||||
create_data = make_create_data(event_as_data, Map.merge(audience, additional))
|
||||
|
||||
@@ -1626,4 +1626,21 @@ defmodule Mobilizon.Actors do
|
||||
@spec preload_followers(Actor.t(), boolean) :: Actor.t()
|
||||
defp preload_followers(actor, true), do: Repo.preload(actor, [:followers])
|
||||
defp preload_followers(actor, false), do: actor
|
||||
|
||||
@spec list_actors_to_notify_from_group_event(Actor.t()) :: Follower.t()
|
||||
def list_actors_to_notify_from_group_event(%Actor{id: actor_id}) do
|
||||
Actor
|
||||
|> join(:left, [a], f in Follower, on: a.id == f.actor_id)
|
||||
|> join(:left, [a], m in Member, on: a.id == m.actor_id)
|
||||
|> where(
|
||||
[a, f],
|
||||
is_nil(a.domain) and f.target_actor_id == ^actor_id and f.approved == true and
|
||||
f.notify == true
|
||||
)
|
||||
|> or_where(
|
||||
[a, _f, m],
|
||||
is_nil(a.domain) and m.parent_id == ^actor_id and m.role in ^@member_roles
|
||||
)
|
||||
|> Repo.all()
|
||||
end
|
||||
end
|
||||
|
||||
@@ -134,7 +134,7 @@ defmodule Mobilizon.Service.Notifier.Email do
|
||||
"participation_event_comment" => true,
|
||||
"event_new_pending_participation" => true,
|
||||
"event_new_participation" => false,
|
||||
"event_created" => false,
|
||||
"event_created" => true,
|
||||
"event_updated" => false,
|
||||
"discussion_updated" => false,
|
||||
"post_published" => false,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
defmodule Mobilizon.Web.Email.Group do
|
||||
@moduledoc """
|
||||
Handles emails sent about participation.
|
||||
Handles emails sent about group changes.
|
||||
"""
|
||||
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
|
||||
|
||||
@@ -9,68 +9,62 @@ defmodule Mobilizon.Web.Email.Group do
|
||||
|
||||
alias Mobilizon.{Actors, Config, Users}
|
||||
alias Mobilizon.Actors.{Actor, Member}
|
||||
alias Mobilizon.Users.User
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Users.{Setting, User}
|
||||
alias Mobilizon.Web.Email
|
||||
|
||||
@doc """
|
||||
Send emails to local user
|
||||
"""
|
||||
@spec send_invite_to_user(Member.t()) :: :ok
|
||||
def send_invite_to_user(%Member{actor: %Actor{user_id: nil}}), do: :ok
|
||||
@spec notify_of_new_event(Event.t()) :: :ok
|
||||
def notify_of_new_event(%Event{attributed_to: %Actor{} = group} = event) do
|
||||
# TODO: When we have events restricted to members, don't send emails to followers
|
||||
group
|
||||
|> Actors.list_actors_to_notify_from_group_event()
|
||||
|> Enum.each(¬ify_follower(event, group, &1))
|
||||
end
|
||||
|
||||
def send_invite_to_user(
|
||||
%Member{actor: %Actor{user_id: user_id}, parent: %Actor{} = group, role: :invited} =
|
||||
member
|
||||
) do
|
||||
with %User{email: email} = user <- Users.get_user!(user_id) do
|
||||
locale = Map.get(user, :locale, "en")
|
||||
def notify_of_new_event(%Event{}), do: :ok
|
||||
|
||||
defp notify_follower(%Event{} = _event, %Actor{}, %Actor{user_id: nil}), do: :ok
|
||||
|
||||
defp notify_follower(%Event{} = event, %Actor{type: :Group} = group, %Actor{
|
||||
id: profile_id,
|
||||
user_id: user_id
|
||||
}) do
|
||||
%User{
|
||||
email: email,
|
||||
locale: locale,
|
||||
settings: %Setting{timezone: timezone},
|
||||
activity_settings: activity_settings
|
||||
} = Users.get_user_with_activity_settings!(user_id)
|
||||
|
||||
if profile_id != event.organizer_actor_id &&
|
||||
accepts_new_events_notifications(activity_settings) do
|
||||
Gettext.put_locale(locale)
|
||||
%Actor{name: invited_by_name} = inviter = Actors.get_actor(member.invited_by_id)
|
||||
|
||||
subject =
|
||||
gettext(
|
||||
"You have been invited by %{inviter} to join group %{group}",
|
||||
inviter: invited_by_name,
|
||||
group: group.name
|
||||
"📅 Just scheduled by %{group}: %{event}",
|
||||
group: Actor.display_name(group),
|
||||
event: event.title
|
||||
)
|
||||
|
||||
Email.base_email(to: email, subject: subject)
|
||||
|> assign(:locale, locale)
|
||||
|> assign(:inviter, inviter)
|
||||
|> assign(:group, group)
|
||||
|> assign(:event, event)
|
||||
|> assign(:timezone, timezone)
|
||||
|> assign(:subject, subject)
|
||||
|> render(:group_invite)
|
||||
|> render(:event_group_follower_notification)
|
||||
|> Email.Mailer.send_email_later()
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
# Only send notification to local members
|
||||
def send_notification_to_removed_member(%Member{actor: %Actor{user_id: nil}}), do: :ok
|
||||
|
||||
def send_notification_to_removed_member(%Member{
|
||||
actor: %Actor{user_id: user_id},
|
||||
parent: %Actor{} = group,
|
||||
role: :rejected
|
||||
}) do
|
||||
with %User{email: email, locale: locale} <- Users.get_user!(user_id) do
|
||||
Gettext.put_locale(locale)
|
||||
|
||||
subject =
|
||||
gettext(
|
||||
"You have been removed from group %{group}",
|
||||
group: group.name
|
||||
)
|
||||
|
||||
Email.base_email(to: email, subject: subject)
|
||||
|> assign(:locale, locale)
|
||||
|> assign(:group, group)
|
||||
|> assign(:subject, subject)
|
||||
|> render(:group_member_removal)
|
||||
|> Email.Mailer.send_email_later()
|
||||
|
||||
:ok
|
||||
@spec accepts_new_events_notifications(list()) :: boolean()
|
||||
defp accepts_new_events_notifications(activity_settings) do
|
||||
case Enum.find(activity_settings, &(&1.key == "event_created" && &1.method == "email")) do
|
||||
nil -> false
|
||||
%{enabled: enabled} -> enabled
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
78
lib/web/email/member.ex
Normal file
78
lib/web/email/member.ex
Normal file
@@ -0,0 +1,78 @@
|
||||
defmodule Mobilizon.Web.Email.Member do
|
||||
@moduledoc """
|
||||
Handles emails sent about group members.
|
||||
"""
|
||||
use Bamboo.Phoenix, view: Mobilizon.Web.EmailView
|
||||
|
||||
import Bamboo.Phoenix
|
||||
import Mobilizon.Web.Gettext
|
||||
|
||||
alias Mobilizon.{Actors, Users}
|
||||
alias Mobilizon.Actors.{Actor, Member}
|
||||
alias Mobilizon.Users.User
|
||||
alias Mobilizon.Web.Email
|
||||
|
||||
@doc """
|
||||
Send emails to local user
|
||||
"""
|
||||
@spec send_invite_to_user(Member.t()) :: :ok
|
||||
def send_invite_to_user(%Member{actor: %Actor{user_id: nil}}), do: :ok
|
||||
|
||||
def send_invite_to_user(
|
||||
%Member{actor: %Actor{user_id: user_id}, parent: %Actor{} = group, role: :invited} =
|
||||
member
|
||||
) do
|
||||
with %User{email: email} = user <- Users.get_user!(user_id) do
|
||||
locale = Map.get(user, :locale, "en")
|
||||
Gettext.put_locale(locale)
|
||||
%Actor{name: invited_by_name} = inviter = Actors.get_actor(member.invited_by_id)
|
||||
|
||||
subject =
|
||||
gettext(
|
||||
"You have been invited by %{inviter} to join group %{group}",
|
||||
inviter: invited_by_name,
|
||||
group: group.name
|
||||
)
|
||||
|
||||
Email.base_email(to: email, subject: subject)
|
||||
|> assign(:locale, locale)
|
||||
|> assign(:inviter, inviter)
|
||||
|> assign(:group, group)
|
||||
|> assign(:subject, subject)
|
||||
|> render(:group_invite)
|
||||
|> Email.Mailer.send_email_later()
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
# Only send notification to local members
|
||||
def send_notification_to_removed_member(%Member{actor: %Actor{user_id: nil}}), do: :ok
|
||||
|
||||
def send_notification_to_removed_member(%Member{
|
||||
actor: %Actor{user_id: user_id},
|
||||
parent: %Actor{} = group,
|
||||
role: :rejected
|
||||
}) do
|
||||
with %User{email: email, locale: locale} <- Users.get_user!(user_id) do
|
||||
Gettext.put_locale(locale)
|
||||
|
||||
subject =
|
||||
gettext(
|
||||
"You have been removed from group %{group}",
|
||||
group: group.name
|
||||
)
|
||||
|
||||
Email.base_email(to: email, subject: subject)
|
||||
|> assign(:locale, locale)
|
||||
|> assign(:group, group)
|
||||
|> assign(:subject, subject)
|
||||
|> render(:group_member_removal)
|
||||
|> Email.Mailer.send_email_later()
|
||||
|
||||
:ok
|
||||
end
|
||||
end
|
||||
|
||||
# TODO : def send_confirmation_to_inviter()
|
||||
end
|
||||
@@ -0,0 +1 @@
|
||||
<%= cond do %><%= @end_date == nil -> %><%= render("date/event_tz_date.text", date: @start_date, event: @event, timezone: @timezone, locale: @locale) %><% is_same_day?(@start_date, @end_date) -> %><%= gettext "On %{date} from %{start_time} to %{end_time}", date: datetime_to_date_string(@start_date, @locale), start_time: datetime_to_time_string(@start_date, @locale), end_time: datetime_to_time_string(@end_date, @locale) %><%= if @event.options.timezone != @timezone do %> <%= gettext "🌐 %{timezone} %{offset}", timezone: @event.options.timezone, offset: Cldr.DateTime.Formatter.zone_gmt(@start_date) %><% end %><% true -> %><%= gettext "From the %{start} to the %{end}", start: datetime_to_string(@start_date, @locale, :short), end: datetime_to_string(@end_date, @locale, :short) %><%= if @event.options.timezone != @timezone do %> <%= gettext "🌐 %{timezone} %{offset}", timezone: @event.options.timezone, offset: Cldr.DateTime.Formatter.zone_gmt(@start_date) %><% end %><% end %>
|
||||
@@ -0,0 +1,47 @@
|
||||
<!-- HERO -->
|
||||
<tr>
|
||||
<td bgcolor="#474467" align="center" style="padding: 0px 10px 0px 10px;">
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
<table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
|
||||
<tr>
|
||||
<td align="center" valign="top" width="600">
|
||||
<![endif]-->
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" >
|
||||
<tr>
|
||||
<td bgcolor="#ffffff" align="center" valign="top" style="padding: 40px 20px 20px 20px; border-radius: 4px 4px 0px 0px; color: #3A384C; font-family: 'Roboto', Helvetica, Arial, sans-serif; font-size: 48px; font-weight: 400; line-height: 48px;">
|
||||
<h1 style="font-size: 48px; font-weight: 400; margin: 0;">
|
||||
<%= gettext "%{group} scheduled a new event", group: Mobilizon.Actors.Actor.display_name(@group) %>
|
||||
</h1>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
<!-- COPY BLOCK -->
|
||||
<tr>
|
||||
<td bgcolor="#E6E4F4" align="center" style="padding: 0px 10px 0px 10px;">
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
<table align="center" border="0" cellspacing="0" cellpadding="0" width="600">
|
||||
<tr>
|
||||
<td align="center" valign="top" width="600">
|
||||
<![endif]-->
|
||||
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="max-width: 600px;" >
|
||||
<!-- COPY -->
|
||||
<tr>
|
||||
<td bgcolor="#ffffff" align="left" style="padding: 20px 15px 0px 15px; color: #474467; font-family: 'Roboto', Helvetica, Arial, sans-serif; font-size: 18px; font-weight: 400; line-height: 25px;" >
|
||||
<%= render("participation/event_card.html", event: @event, timezone: @timezone, locale: @locale, action: "event") %>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--[if (gte mso 9)|(IE)]>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<![endif]-->
|
||||
</td>
|
||||
</tr>
|
||||
@@ -0,0 +1,3 @@
|
||||
<%= gettext "%{group} scheduled a new event:", group: Mobilizon.Actors.Actor.display_name(@group) %>
|
||||
|
||||
<%= render("participation/event_card.text", event: @event, timezone: @timezone, locale: @locale, action: "event") %>
|
||||
@@ -45,12 +45,12 @@
|
||||
<ul style="margin: 0;padding: 0;list-style-type: none;">
|
||||
<%= for participation <- @participations do %>
|
||||
<li style="padding: 0; border: 1px solid rgba(0,0,0,.125); border-radius: .25rem; margin-bottom: 10px">
|
||||
<%= render("participation/event_card.html", event: participation.event, timezone: @timezone, locale: @locale) %>
|
||||
<%= render("participation/event_card.html", event: participation.event, timezone: @timezone, locale: @locale, action: "participation") %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<%= render("participation/event_card.html", event: @participation.event, timezone: @timezone, locale: @locale) %>
|
||||
<%= render("participation/event_card.html", event: @participation.event, timezone: @timezone, locale: @locale, action: "participation") %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -45,12 +45,12 @@
|
||||
<ul style="margin: 0;">
|
||||
<%= for participation <- @participations do %>
|
||||
<li>
|
||||
<%= render("participation/event_card.html", event: participation.event, timezone: @timezone, locale: @locale) %>
|
||||
<%= render("participation/event_card.html", event: participation.event, timezone: @timezone, locale: @locale, action: "participation") %>
|
||||
</li>
|
||||
<% end %>
|
||||
</ul>
|
||||
<% else %>
|
||||
<%= render("participation/event_card.html", event: @participation.event, timezone: @timezone, locale: @locale) %>
|
||||
<%= render("participation/event_card.html", event: @participation.event, timezone: @timezone, locale: @locale, action: "participation") %>
|
||||
<% end %>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<tbody style="vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
<!-- row for datetime -->
|
||||
<tr style="vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0 12px 24px 0; border: 0;" valign="baseline" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0 12px 12px 0; border: 0;" valign="baseline" align="left">
|
||||
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABgAAAAYADwa0LPAAAAf0lEQVRIx2NgGEDwH4opUsdEa1eiW+DNwMDwBM1F/wlgZHWPGRgYPPFZ+JgIAwnhR8gGMmIJT2oAuLl0jwOqAxZCXiQRYATx0A+iAYsDfABbUsYZZ0M/iIa+BeREMkmZkO5B9ARKk1tUMzBAinycwJOBsjrhEQMDgwetQ2WYAQCSDEUsvZlgYAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0xMC0xNFQxNDo1MTowNyswMDowMCvAzKIAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjEtMTAtMTRUMTQ6NTE6MDcrMDA6MDBanXQeAAAAAElFTkSuQmCC" style="outline: none; text-decoration: none; width: 21px; max-width: 100%; clear: both; display: block; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
</td>
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0 0 12px; border: 0;" valign="top" align="left">
|
||||
@@ -29,7 +29,7 @@
|
||||
<%= if @event.physical_address do %>
|
||||
<!-- venue block -->
|
||||
<tr style="vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0 12px 24px 0; border: 0;" valign="baseline" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0 12px 12px 0; border: 0;" valign="baseline" align="left">
|
||||
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABgAAAAYADwa0LPAAABHklEQVRIx+XUsUoDQRQF0EMUtNPGYGsULMTeNuonqJ8SsNZ/kLSW/kEaLQykMvoJNoKdGkWCQrTYDS6b3c1O1i4XbjHz3rt35u2+YR5Qxznu8RGzj7M4VgnHGOAnhwMcVREfFYiPOZrFpD7l5Gm+YS1LaCHH4BSHqb1XXOIOW1hOxJYwxE3ZGzykTviCjUS8ERsmc/ohLXpPFV9k5LRNfvAJ1HIMvkrk1abUFKKX0aJGIr6Z0aJeltBijsEt9hLrVVGPr+L1CVYyakpjR/lfdMzdEAPoBoh3Q8XhIMBgfxYD6JQQ78wqTjSxnwXiQ2xXMYBWgUGrqjjRQGW16lr+WxaMOp4S4s9Y/y/xMZr4jtksWxRyxUfRk9HxN9FzgF/m1ZTuGrd6hAAAACV0RVh0ZGF0ZTpjcmVhdGUAMjAyMS0xMC0xNFQxNDo1Mjo0NyswMDowMES9eVsAAAAldEVYdGRhdGU6bW9kaWZ5ADIwMjEtMTAtMTRUMTQ6NTI6NDcrMDA6MDA14MHnAAAAAElFTkSuQmCC" style="outline: none; text-decoration: none; width: 21px; max-width: 100%; clear: both; display: block; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
</td>
|
||||
<td class="m_8261046153705514309event__content_local" style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0; border: 0;" valign="top" align="left">
|
||||
@@ -42,7 +42,7 @@
|
||||
<% end %>
|
||||
<%= if @event.options.is_online do %>
|
||||
<tr style="vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0 12px 24px 0; border: 0;" valign="baseline" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0 12px 12px 0; border: 0;" valign="baseline" align="left">
|
||||
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAABgAAAAYADwa0LPAAABWUlEQVRIx+WUP04CURDGf5pIQsROOAMHsNSgVmpp9AZ6AG1MiA1CsZ6DCxiwMx5BtKNQGs2uLf9aFov9DC8s++ftNiZOMpmdnW/mm8x78+A/SAVoAa/AVNoDmorlknNgDMwjdAyc5Snuq9ADUAM2pftARzE/C0nF6PwmBlcXZgSUbQhaRucABeAe8AAXcPQPoCvsnQ3Bm5Jq8h3C83cUO5DfsyGYKKkk31tB8K3YFosDD8l6BME8wQeYya7FYCIJBrI7su0VmPYSZoCFNNVRR36BYOYu4UN+FLZhQ2Be03oM7laYIbBtQwDB8vwuWpfgtpSkh0bnPnBqW9wkGRH9VAzzFC/KlgmW6IXg+k703TDGUrQtfgK8A7spsHvAh3JSyQbQN8bwBFwAVRaPXRW4BJ4NXF+5iXIdM/MkvUpD4OUgcJeLrdrkGdklVe4x8JWh+0/gKEdzf1R+ADQolKDXzQqjAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDIxLTEwLTE1VDEzOjA5OjAzKzAwOjAwbhSTzgAAACV0RVh0ZGF0ZTptb2RpZnkAMjAyMS0xMC0xNVQxMzowOTowMyswMDowMB9JK3IAAAAASUVORK5CYII=" style="outline: none; text-decoration: none; width: 21px; max-width: 100%; clear: both; display: block; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
</td>
|
||||
<td class="m_8261046153705514309event__content_local" style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0; border: 0;" valign="top" align="left">
|
||||
@@ -55,27 +55,52 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="event__content_attend" style="vertical-align: middle; margin: 0; padding: 0; border: 0;">
|
||||
<table class="button btn-attend event__content_position" style="border-spacing: 0; border-collapse: collapse; vertical-align: baseline; text-align: left; width: auto; margin: 0; padding: 0; border: 0;">
|
||||
<tbody style="vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
<tr style="vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0; border: 0;" valign="baseline" align="left">
|
||||
<table style="border-spacing: 0; border-collapse: collapse; vertical-align: baseline; text-align: left; margin: 0; padding: 0; border: 0;">
|
||||
<tbody style="vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
<tr style="vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(255,255,255); font-family: Helvetica,Arial,sans-serif; font-weight: 500; line-height: 1.3; font-size: 16px; border-radius: 4px; margin: 0; padding: 0px; border: none;" valign="middle" bgcolor="FE3859" align="center">
|
||||
<a href={Routes.page_url(Mobilizon.Web.Endpoint, :event, @event.uuid)} style="color: rgb(255,255,255); font-family: Helvetica,Arial,sans-serif; font-weight: bold; text-align: left; line-height: 14px; text-decoration: none; vertical-align: baseline; font-size: 16px; display: inline-block; border-radius: 3px; white-space: nowrap; margin: 0; padding: 12px 32px; border: none;" target="_blank">
|
||||
<%= gettext("Manage your participation") %>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<%= case @action do %>
|
||||
<% "participation" -> %>
|
||||
<div class="event__content_attend" style="vertical-align: middle; margin: 0; padding: 0; border: 0;">
|
||||
<table class="button btn-attend event__content_position" style="border-spacing: 0; border-collapse: collapse; vertical-align: baseline; text-align: left; width: auto; margin: 0; padding: 0; border: 0;">
|
||||
<tbody style="vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
<tr style="vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0; border: 0;" valign="baseline" align="left">
|
||||
<table style="border-spacing: 0; border-collapse: collapse; vertical-align: baseline; text-align: left; margin: 0; padding: 0; border: 0;">
|
||||
<tbody style="vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
<tr style="vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(255,255,255); font-family: Helvetica,Arial,sans-serif; font-weight: 500; line-height: 1.3; font-size: 16px; border-radius: 4px; margin: 0; padding: 0px; border: none;" valign="middle" bgcolor="FE3859" align="center">
|
||||
<a href={Routes.page_url(Mobilizon.Web.Endpoint, :event, @event.uuid)} style="color: rgb(255,255,255); font-family: Helvetica,Arial,sans-serif; font-weight: bold; text-align: left; line-height: 14px; text-decoration: none; vertical-align: baseline; font-size: 16px; display: inline-block; border-radius: 3px; white-space: nowrap; margin: 0; padding: 12px 32px; border: none;" target="_blank">
|
||||
<%= gettext("Manage your participation") %>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<% "event" -> %>
|
||||
<div class="event__content_attend" style="vertical-align: middle; margin: 0; padding: 0; border: 0;">
|
||||
<table class="button btn-attend event__content_position" style="border-spacing: 0; border-collapse: collapse; vertical-align: baseline; text-align: left; width: auto; margin: 0; padding: 0; border: 0;">
|
||||
<tbody style="vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
<tr style="vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0; border: 0;" valign="baseline" align="left">
|
||||
<table style="border-spacing: 0; border-collapse: collapse; vertical-align: baseline; text-align: left; margin: 0; padding: 0; border: 0;">
|
||||
<tbody style="vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
<tr style="vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(255,255,255); font-family: Helvetica,Arial,sans-serif; font-weight: 500; line-height: 1.3; font-size: 16px; border-radius: 4px; margin: 0; padding: 0px; border: none;" valign="middle" bgcolor="FE3859" align="center">
|
||||
<a href={Routes.page_url(Mobilizon.Web.Endpoint, :event, @event.uuid)} style="color: rgb(255,255,255); font-family: Helvetica,Arial,sans-serif; font-weight: bold; text-align: left; line-height: 14px; text-decoration: none; vertical-align: baseline; font-size: 16px; display: inline-block; border-radius: 3px; white-space: nowrap; margin: 0; padding: 12px 32px; border: none;" target="_blank">
|
||||
<%= gettext("Participate") %>
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<%= gettext("Date:") %> <%= render("date/event_tz_date_range.text", event: @event, start_date: datetime_tz_convert(@event.begins_on, @event.options.timezone), end_date: datetime_tz_convert(@event.ends_on, @event.options.timezone), timezone: @timezone, locale: @locale) %>
|
||||
<%= gettext("Address:") %> <%= if @event.physical_address do %><%= render_address(@event.physical_address) %><% end %><%= if @event.options.is_online do %><%= gettext "Online event" %><% end %>
|
||||
|
||||
<%= case @action do %><% "participation" -> %><%= gettext("Manage your participation:") %> <%= Routes.page_url(Mobilizon.Web.Endpoint, :event, @event.uuid) %><% "event" -> %><%= gettext("Participate:") %> <%= Routes.page_url(Mobilizon.Web.Endpoint, :event, @event.uuid) %><% end %>
|
||||
@@ -2,25 +2,25 @@
|
||||
<tbody style="vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
<tr style="vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<td style="word-wrap: break-word; border-collapse: collapse; color: rgb(10,10,10); font-family: Helvetica,Arial,sans-serif; font-weight: normal; line-height: 1.3; font-size: 16px; margin: 0; padding: 0; border: 0;" valign="baseline" align="left">
|
||||
<a href={Routes.page_url(Mobilizon.Web.Endpoint, :event, @event.uuid)} style="color: rgb(66,81,90); font-family: Helvetica,Arial,sans-serif; font-weight: 700; text-align: left; line-height: 1.4; text-decoration: none; vertical-align: baseline; font-size: 22px; letter-spacing: 0.2px; margin: 0 0 30px; padding: 0; border: 0;" target="_blank">
|
||||
<%= @event.title %>
|
||||
</a>
|
||||
<div style="vertical-align: baseline; width: 100%; margin: 0 0 0 10px; padding: 0; border: 0;display: flex;">
|
||||
<%= cond do %>
|
||||
<% @event.attributed_to != nil and @event.attributed_to.avatar != nil && @event.attributed_to.avatar.url != nil -> %>
|
||||
<img style="float: left;border-radius: 75%;margin-right: 8px;max-width: 30px;margin-top: auto;margin-bottom: auto;" src={@event.attributed_to.avatar.url}>
|
||||
<img style="float: left;border-radius: 75%;margin-right: 8px;max-width: 30px;margin-top: auto;margin-bottom: 5px;" src={@event.attributed_to.avatar.url} />
|
||||
<% @event.organizer_actor.avatar != nil and @event.organizer_actor.avatar.url != nil -> %>
|
||||
<img style="float: left;border-radius: 75%;margin-right: 8px;max-width: 30px;margin-top: auto;margin-bottom: auto;" src={@event.organizer_actor.avatar.url}>
|
||||
<img style="float: left;border-radius: 75%;margin-right: 8px;max-width: 30px;margin-top: auto;margin-bottom: 5px;" src={@event.organizer_actor.avatar.url} />
|
||||
<% true -> %>
|
||||
<% end %>
|
||||
<div class="event-info__title" style="vertical-align: top; float: left; width: 75%; margin: 0; padding: 0; border: 0;">
|
||||
<a href={Routes.page_url(Mobilizon.Web.Endpoint, :event, @event.uuid)} style="color: rgb(66,81,90); font-family: Helvetica,Arial,sans-serif; font-weight: 700; text-align: left; line-height: 1.4; text-decoration: none; vertical-align: baseline; font-size: 22px; letter-spacing: 0.2px; margin: 0 0 30px; padding: 0; border: 0;" target="_blank">
|
||||
<%= @event.title %>
|
||||
</a>
|
||||
<p style="color: rgb(254,56,89); font-family: Helvetica,Arial,sans-serif; font-weight: 400; line-height: 1.5; font-size: 16px; vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<div style="vertical-align: top; float: left; width: 75%; margin: 0; padding: 0; border: 0;">
|
||||
<p style="font-family: Helvetica,Arial,sans-serif; font-weight: 400; line-height: 1.5; font-size: 16px; vertical-align: baseline; margin: 0; padding: 0; border: 0;" align="left">
|
||||
<%= if @event.attributed_to do %>
|
||||
<a href={Routes.page_url(:actor, Mobilizon.Actors.Actor.preferred_username_and_domain(@event.attributed_to))} style="color: rgb(254,56,89); font-family: Helvetica,Arial,sans-serif; font-weight: normal; text-align: left; line-height: 1.3; text-decoration: none; vertical-align: baseline; margin: 0; padding: 0; border: 0;" target="_blank">
|
||||
<a href={Routes.page_url(Mobilizon.Web.Endpoint, :actor, Mobilizon.Actors.Actor.preferred_username_and_domain(@event.attributed_to)) |> raw} style="color: rgb(254,56,89); font-family: Helvetica,Arial,sans-serif; font-weight: normal; text-align: left; line-height: 1.3; text-decoration: none; vertical-align: baseline; margin: 0; padding: 0; border: 0;" target="_blank">
|
||||
<%= @event.attributed_to.name || @event.attributed_to.preferred_username %>
|
||||
</a>
|
||||
<% else %>
|
||||
<span style="color: rgb(254,56,89); font-family: Helvetica,Arial,sans-serif; font-weight: normal; text-align: left; line-height: 1.3; text-decoration: none; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
<span style="font-family: Helvetica,Arial,sans-serif; font-weight: normal; text-align: left; line-height: 1.3; text-decoration: none; vertical-align: baseline; margin: 0; padding: 0; border: 0;">
|
||||
<%= @event.organizer_actor.name || @event.organizer_actor.preferred_username %>
|
||||
</span>
|
||||
<% end %>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<%= gettext("Title: %{title}", title: @event.title) %>
|
||||
|
||||
<%= if @event.attributed_to do %><%= gettext("Organizer: %{organizer}", organizer: @event.attributed_to.name || @event.attributed_to.preferred_username) %> <%= Routes.page_url(Mobilizon.Web.Endpoint, :actor, Mobilizon.Actors.Actor.preferred_username_and_domain(@event.attributed_to)) %><% else %><%= gettext("Organizer: %{organizer}", organizer: @event.organizer_actor.name || @event.organizer_actor.preferred_username) %><% end %>
|
||||
@@ -4,9 +4,9 @@
|
||||
<!-- event image end -->
|
||||
<% end %>
|
||||
<%= render("participation/card/_title.html", event: @event) %>
|
||||
<%= render("participation/card/_metadata.html", event: @event, timezone: @timezone, locale: @locale) %>
|
||||
<%= render("participation/card/_metadata.html", event: @event, timezone: @timezone, locale: @locale, action: @action) %>
|
||||
<%= if @event.description do %>
|
||||
<div class="event-working" style="vertical-align: baseline; width: 450px; margin: 0 0 0 10px; padding: 7.5px 0 15px; border: 0;">
|
||||
<div class="event-working" style="vertical-align: baseline; margin: 0 0 0 10px; padding: 7.5px 0 15px; border: 0;">
|
||||
<p style="color: rgb(46,62,72); font-family: Helvetica,Arial,sans-serif; font-weight: 700; line-height: 1.5; font-size: 16px; vertical-align: baseline; margin: 0; padding: 0 0 7.5px; border: 0;" align="left">
|
||||
<%= gettext("Details") %>
|
||||
</p>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<%= render("participation/card/_title.text", event: @event) %>
|
||||
|
||||
<%= render("participation/card/_metadata.text", event: @event, timezone: @timezone, locale: @locale, action: @action) %>
|
||||
|
||||
<%= if @event.description do %><%= gettext("Details:") %>
|
||||
<%= process_description(@event.description) %>
|
||||
<%= if String.length(@event.description) > 200 do %><%= gettext("Read more : %{url}", url: Routes.page_url(Mobilizon.Web.Endpoint, :event, @event.uuid)) |> raw %><% end %><% end %>
|
||||
Reference in New Issue
Block a user