Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Project published notification view and template #1792

Draft
wants to merge 10 commits into
base: main
Choose a base branch
from
17 changes: 17 additions & 0 deletions funnel/models/notification_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
'RegistrationCancellationNotification',
'RegistrationConfirmationNotification',
'ProjectStartingNotification',
'ProjectPublishedNotification',
'OrganizationAdminMembershipNotification',
'OrganizationAdminMembershipRevokedNotification',
]
Expand Down Expand Up @@ -153,6 +154,22 @@ class ProjectStartingNotification(
# This is a notification triggered without an actor


class ProjectPublishedNotification(
DocumentHasProfile, Notification, type='project_published'
jace marked this conversation as resolved.
Show resolved Hide resolved
):
"""Notifications of a newly published project."""

category = notification_categories.participant
title = __("When a project is published")
description = __(
"Notifies all members of a profile when a new project is published"
)

document_model = Project
jace marked this conversation as resolved.
Show resolved Hide resolved
roles = ['project_crew', 'project_participant', 'account_participant']
exclude_actor = False # Send to everyone including the actor


# --- Comment notifications ------------------------------------------------------------


Expand Down
8 changes: 4 additions & 4 deletions funnel/templates/notifications/layout_email.html.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@

<center role="article" aria-roledescription="email" lang="en">
<!--[if mso | IE]>
<table class="header-container" align="left" role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: #f0f0f0; text-align: left";>
<table role="presentation" border="0" cellpadding="0" cellspacing="0" width="100%" style="background-color: #f0f0f0;">
<tr>
<td>
<![endif]-->
Expand All @@ -356,9 +356,9 @@
1. max-width for all clients except Desktop Windows Outlook, allowing the email to squish on narrow but never go wider than 600px.
2. MSO tags for Desktop Windows Outlook enforce a 600px width.
#}
<div align="left" class="email-container">
<div align="center" class="email-container">
<!--[if mso]>
<table class="header-container" align="left" role="presentation" cellspacing="0" cellpadding="0" border="0" width="600" style="text-align: left">
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" width="600">
<tr>
<td>
<![endif]-->
Expand Down Expand Up @@ -434,7 +434,7 @@

{# Email content : BEGIN #}
<table align="center" role="presentation" cellspacing="0" cellpadding="0" border="0" width="100%">
{% if view %}
{% if view.hero_image %}
{# Hero image centered : BEGIN #}
{%- if view.hero_image %}
{{ hero_image(view.hero_image, view.email_heading or '') }}
Expand Down
127 changes: 127 additions & 0 deletions funnel/templates/notifications/project_published_email.html.jinja2
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
{%- extends "notifications/layout_email.html.jinja2" -%}
{%- from "notifications/macros_email.html.jinja2" import cta_button, rsvp_footer, pinned_update -%}

{% block stylesheet %}
<style>
a {
text-decoration: none;
font-weight: bold;
color: #1f2d3d;
}
.project-banner__box__image {
position: relative;
transform: translate(0, -8px);
object-fit: cover;
width: 100%;
height: 100%;
}
.mui-list--unstyled {
padding-left: 0;
list-style: none;
}
.mui--align-middle {
vertical-align: middle !important;
}
.fa-icon--right-margin {
margin-right: 8px;
}
.project_time {
margin: 8px 0 8px;
font-size: 16px;
font-weight: 600;
text-align: right !important;
}
.mui--text-light {
color: #4d5763;
}
.button-td,
.button-a {
border-radius: 4px;
background-color: #4d5763;
transition: all 100ms ease-in;
font-family: sans-serif;
font-size: 15px;
line-height: 15px;
text-decoration: none;
}
.button-a {
border: 1px solid #4d5763;
padding: 13px 17px;
color: #ffffff;
display: block;
}
.button-td-primary:hover,
.button-a-primary:hover {
background-color: #1f2d3d !important;
border-color: #1f2d3d !important;
}
.project-banner__profile-details {
display: -webkit-box-flex;
display: -ms-flexbox;
display: flex;
line-height: 30px;
margin-left: 0;
}
.project_title {
line-height: 1rem;
margin-top: 0;
margin-bottom: 0;
}
.project_details {
padding: 0;
}
.profile-details__text {
margin-left: 4px;
}
</style>
{% endblock stylesheet %}
{%- block content -%}

<tr>
<td>
{%- if view.project.bg_image.url %}
<img class="project-banner__box__image" src="{{ view.project.bg_image.resize(700) }}" alt="{{ view.project.title }}"/>
{%- else %}
<img class="project-banner__box__image" src="{{ url_for('static', filename='img/default-banner.png') }}" alt="{{ view.project.title }}"/>
{% endif %}
</td>
</tr>
<tr>
<td class="project_details" align="left">
<div class="project-banner__profile-details">
{%- if view.project.profile.logo_url.url %}
<a href="{{ view.project.profile.url_for() }}">
<img src="{{ view.project.profile.logo_url.resize(30) }}" alt="{{ view.project.profile.title }}"/>
</a>
{% endif %}
<a href="{{ view.project.profile.url_for() }}" class="profile-details__text">{{ view.project.profile.title }}</a>
</div>
</td>
</tr>
<tr width="100%">
<td align="left">
<h2 class="project_title"><a href="{{ view.project.url_for() }}">{{ view.project.title }}</a></h2>
<p class="project_time">{{ view.project.start_at|datetime(format='dd MMM YYYY') }} | {{ view.project.start_at|datetime(format='HH:MM') }}</p>
</td>
</tr>
<tr>
<td>
{{ view.project.description.html }}
</td>
</tr>
<br>

{# Button : BEGIN #}
{{ cta_button(view.project.url_for(_external=true), gettext("Register") )}}
{# Button : END #}

{# {{ pinned_update(view, project) }} #}

<tr>
<td class="line-separator"></td>
</tr>
<tr>
<td class="footer-text">{{ view.reason }}</td>
</tr>

{%- endblock content -%}
1 change: 1 addition & 0 deletions funnel/views/notifications/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
comment_notification,
organization_membership_notification,
project_crew_notification,
project_published_notification,
project_starting_notification,
proposal_notification,
rsvp_notification,
Expand Down
52 changes: 52 additions & 0 deletions funnel/views/notifications/project_published_notification.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Project published notification."""

from __future__ import annotations

from flask import render_template

from baseframe import _, __

from ...models import Project, ProjectPublishedNotification
from ...transports.sms import TwoLineTemplate
from ..helpers import shortlink
from ..notification import RenderNotification


@ProjectPublishedNotification.renderer
class RenderProjectPublishedNotification(RenderNotification):
"""Notify account followers when a new project is published."""

project: Project
aliases = {'document': 'project'}
jace marked this conversation as resolved.
Show resolved Hide resolved
emoji_prefix = "📰 "
reason = __(
"You are receiving this because you have registered for this or related"
" projects"
)

@property
def actor(self):
return self.project.user

def web(self):
return render_template('notifications/update_new_web.html.jinja2', view=self)

def email_subject(self):
return self.emoji_prefix + _("{update} ({project})").format(
update=self.project.title, project=self.project.joined_title
)

def email_content(self):
return render_template(
'notifications/project_published_email.html.jinja2', view=self
)

def sms(self) -> TwoLineTemplate:
return TwoLineTemplate(
text1=_("Update in {project}:").format(project=self.project.joined_title),
text2=self.project.title,
url=shortlink(
self.update.url_for(_external=True, **self.tracking_tags('sms')),
shorter=True,
),
)
2 changes: 2 additions & 0 deletions funnel/views/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
RSVP_STATUS,
Profile,
Project,
ProjectPublishedNotification,
RegistrationCancellationNotification,
RegistrationConfirmationNotification,
Rsvp,
Expand Down Expand Up @@ -572,6 +573,7 @@ def transition(self) -> ReturnView:
transition() # call the transition
db.session.commit()
flash(transition.data['message'], 'success')
dispatch_notification(ProjectPublishedNotification(document=self.obj))
jace marked this conversation as resolved.
Show resolved Hide resolved
else:
flash(_("Invalid transition for this project"), 'error')
abort(403)
Expand Down