ghost 5.2.2 → 5.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/content/themes/casper/assets/built/screen.css +1 -1
- package/content/themes/casper/assets/built/screen.css.map +1 -1
- package/content/themes/casper/assets/css/screen.css +31 -1
- package/content/themes/casper/default.hbs +1 -0
- package/content/themes/casper/package.json +1 -1
- package/content/themes/casper/partials/icons/search.hbs +1 -0
- package/core/boot.js +3 -1
- package/core/bridge.js +7 -0
- package/core/built/assets/codemirror/{codemirror-d25c379b87ec8b33d54ac7149bc0b6ae.js → codemirror-30201ab2cff61db847193fc9f5ed922d.js} +1 -1
- package/core/built/assets/ghost-dark-9e5d1f0dfae41232e5e34e4d0df53ae0.css +1 -0
- package/core/built/assets/ghost.min-e7cfbd1800f8e99b9158f74f1e39cd76.css +1 -0
- package/core/built/assets/{ghost.min-971a0ff706bbf9e24f0b0a5770c8fc41.js → ghost.min-f4bba3a2a5ef256b82641345505d4f0f.js} +69 -66
- package/core/built/assets/icons/activity-placeholder.svg +3 -0
- package/core/built/assets/simplemde/{simplemde-3ffc0ec9e9fecf29b9a499db678c9e65.js → simplemde-fb4527da6e489b34dc24b28ea870b286.js} +1 -1
- package/core/built/assets/{vendor.min-ea369e6487643585f35409d474b06789.js → vendor.min-4076498ccd6c8412365f43b156084ed8.js} +119 -117
- package/core/built/assets/{vendor.min-ba66b98f7c24fa40e061c7ffc94f4e23.css → vendor.min-4a6661c574707ceca220aa2e76558995.css} +2 -1
- package/core/frontend/helpers/comment_count.js +25 -0
- package/core/frontend/helpers/comments.js +67 -0
- package/core/frontend/helpers/date.js +3 -1
- package/core/frontend/helpers/ghost_head.js +13 -0
- package/core/frontend/services/admin-auth-assets/index.js +4 -0
- package/core/frontend/services/admin-auth-assets/service.js +93 -0
- package/core/frontend/services/comment-counts-assets/index.js +4 -0
- package/core/frontend/services/comment-counts-assets/service.js +59 -0
- package/core/frontend/services/theme-engine/middleware/update-global-template-options.js +5 -1
- package/core/frontend/src/admin-auth/index.html +5 -0
- package/core/frontend/src/admin-auth/message-handler.js +75 -0
- package/core/frontend/src/comment-counts/js/comment-counts.js +71 -0
- package/core/frontend/web/site.js +3 -0
- package/core/server/api/{canary → endpoints}/actions.js +0 -0
- package/core/server/api/{canary → endpoints}/authentication.js +0 -0
- package/core/server/api/{canary → endpoints}/authors-public.js +0 -0
- package/core/server/api/endpoints/comments-comments.js +247 -0
- package/core/server/api/endpoints/comments.js +25 -0
- package/core/server/api/{canary → endpoints}/config.js +0 -0
- package/core/server/api/{canary → endpoints}/custom-theme-settings.js +0 -0
- package/core/server/api/{canary → endpoints}/db.js +0 -0
- package/core/server/api/{canary → endpoints}/email-post.js +0 -0
- package/core/server/api/{canary → endpoints}/email-previews.js +0 -0
- package/core/server/api/{canary → endpoints}/emails.js +0 -0
- package/core/server/api/endpoints/explore.js +12 -0
- package/core/server/api/{canary → endpoints}/files.js +0 -0
- package/core/server/api/{canary → endpoints}/identities.js +0 -0
- package/core/server/api/{canary → endpoints}/images.js +0 -0
- package/core/server/api/{canary → endpoints}/index.js +16 -0
- package/core/server/api/{canary → endpoints}/integrations.js +0 -0
- package/core/server/api/{canary → endpoints}/invites.js +0 -0
- package/core/server/api/{canary → endpoints}/labels.js +0 -0
- package/core/server/api/{canary → endpoints}/mail.js +0 -0
- package/core/server/api/{canary → endpoints}/media.js +0 -0
- package/core/server/api/{canary → endpoints}/member-signin-urls.js +0 -0
- package/core/server/api/{canary → endpoints}/members-stripe-connect.js +0 -0
- package/core/server/api/{canary → endpoints}/members.js +0 -0
- package/core/server/api/{canary → endpoints}/newsletters-public.js +0 -0
- package/core/server/api/{canary → endpoints}/newsletters.js +0 -0
- package/core/server/api/{canary → endpoints}/notifications.js +0 -0
- package/core/server/api/{canary → endpoints}/oembed.js +0 -0
- package/core/server/api/{canary → endpoints}/offers-public.js +0 -0
- package/core/server/api/{canary → endpoints}/offers.js +0 -0
- package/core/server/api/{canary → endpoints}/pages-public.js +0 -0
- package/core/server/api/{canary → endpoints}/pages.js +0 -0
- package/core/server/api/{canary → endpoints}/posts-public.js +0 -0
- package/core/server/api/{canary → endpoints}/posts.js +0 -0
- package/core/server/api/{canary → endpoints}/previews.js +0 -0
- package/core/server/api/{canary → endpoints}/redirects.js +0 -0
- package/core/server/api/{canary → endpoints}/roles.js +0 -0
- package/core/server/api/{canary → endpoints}/schedules.js +0 -0
- package/core/server/api/{canary → endpoints}/session.js +0 -0
- package/core/server/api/{canary → endpoints}/settings-public.js +0 -0
- package/core/server/api/{canary → endpoints}/settings.js +0 -0
- package/core/server/api/{canary → endpoints}/site.js +0 -0
- package/core/server/api/{canary → endpoints}/slack.js +0 -0
- package/core/server/api/{canary → endpoints}/slugs.js +0 -0
- package/core/server/api/{canary → endpoints}/snippets.js +0 -0
- package/core/server/api/{canary → endpoints}/stats.js +0 -0
- package/core/server/api/{canary → endpoints}/tags-public.js +0 -0
- package/core/server/api/{canary → endpoints}/tags.js +0 -0
- package/core/server/api/{canary → endpoints}/themes.js +0 -0
- package/core/server/api/{canary → endpoints}/tiers-public.js +0 -0
- package/core/server/api/{canary → endpoints}/tiers.js +0 -0
- package/core/server/api/{canary → endpoints}/users.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/index.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/permissions.js +3 -3
- package/core/server/api/{canary → endpoints}/utils/serializers/index.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/input/authors.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/input/db.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/input/index.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/input/integrations.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/input/media.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/input/members.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/input/pages.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/input/posts.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/input/settings.js +2 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/input/tags.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/input/tiers.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/input/users.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/input/utils/slug-filter-order.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/input/utils/url.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/input/webhooks.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/all.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/authentication.js +1 -1
- package/core/server/api/endpoints/utils/serializers/output/comments.js +5 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/config.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/custom-theme-settings.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/db.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/default.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/email-posts.js +0 -0
- package/core/server/api/endpoints/utils/serializers/output/explore.js +11 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/files.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/images.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/index.js +8 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mail.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/actions.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/authors.js +0 -0
- package/core/server/api/endpoints/utils/serializers/output/mappers/comments.js +50 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/emails.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/images.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/index.js +1 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/integrations.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/newsletters.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/pages.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/posts.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/settings.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/snippets.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/tags.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/mappers/users.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/media.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/members-stripe-connect.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/members.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/notifications.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/oembed.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/offers.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/pages.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/posts.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/previews.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/redirects.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/roles.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/schedules.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/session.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/settings.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/site.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/slack.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/slugs.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/themes.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/tiers.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/users.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/utils/clean.js +2 -1
- package/core/server/api/{canary → endpoints}/utils/serializers/output/utils/date.js +0 -0
- package/core/server/api/endpoints/utils/serializers/output/utils/extra-attrs.js +67 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/utils/post-gating.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/serializers/output/utils/url.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/validators/index.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/files.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/images.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/index.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/invitations.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/validators/input/invites.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/labels.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/media.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/members.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/oembed.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/pages.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/password_reset.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/validators/input/posts.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/settings.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/setup.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/validators/input/snippets.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/tags.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/tiers.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/input/users.js +1 -1
- package/core/server/api/{canary → endpoints}/utils/validators/input/webhooks.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/output/index.js +0 -0
- package/core/server/api/{canary → endpoints}/utils/validators/utils/json-schema.js +0 -0
- package/core/server/api/{canary → endpoints}/webhooks.js +0 -0
- package/core/server/api/index.js +1 -1
- package/core/server/data/exporter/table-lists.js +4 -2
- package/core/server/data/migrations/versions/5.3/2022-07-04-13-49-add-comments-table.js +13 -0
- package/core/server/data/migrations/versions/5.3/2022-07-05-09-36-add-comments-likes-table.js +9 -0
- package/core/server/data/migrations/versions/5.3/2022-07-05-09-47-add-comments-reports-table.js +10 -0
- package/core/server/data/migrations/versions/5.3/2022-07-05-10-00-add-comment-related-fields-to-members.js +21 -0
- package/core/server/data/migrations/versions/5.3/2022-07-05-12-55-add-comments-crud-permissions.js +68 -0
- package/core/server/data/migrations/versions/5.3/2022-07-05-15-35-add-comment-notifications-field-to-users-table.js +7 -0
- package/core/server/data/migrations/versions/5.3/2022-07-06-07-26-add-comments-enabled-setting.js +8 -0
- package/core/server/data/migrations/versions/5.3/2022-07-06-07-58-add-ghost-explore-integration-role.js +31 -0
- package/core/server/data/migrations/versions/5.3/2022-07-06-09-13-add-ghost-explore-integration-role-permissions.js +11 -0
- package/core/server/data/migrations/versions/5.3/2022-07-06-09-17-add-ghost-explore-integration.js +38 -0
- package/core/server/data/migrations/versions/5.3/2022-07-06-09-26-add-ghost-explore-integration-api-key.js +73 -0
- package/core/server/data/schema/default-settings/default-settings.json +14 -0
- package/core/server/data/schema/fixtures/fixtures.json +65 -2
- package/core/server/data/schema/schema.js +31 -1
- package/core/server/models/base/plugins/crud.js +15 -0
- package/core/server/models/comment-like.js +34 -0
- package/core/server/models/comment.js +163 -0
- package/core/server/models/member.js +2 -1
- package/core/server/models/user.js +2 -1
- package/core/server/services/auth/session/express-session.js +1 -1
- package/core/server/services/comments/email-templates/new-comment-reply.hbs +199 -0
- package/core/server/services/comments/email-templates/new-comment-reply.txt.js +14 -0
- package/core/server/services/comments/email-templates/new-comment.hbs +199 -0
- package/core/server/services/comments/email-templates/new-comment.txt.js +14 -0
- package/core/server/services/comments/emails.js +164 -0
- package/core/server/services/comments/index.js +26 -0
- package/core/server/services/comments/service.js +24 -0
- package/core/server/services/explore/index.js +18 -0
- package/core/server/services/explore/service.js +55 -0
- package/core/server/services/members/middleware.js +4 -4
- package/core/server/services/members/utils.js +2 -1
- package/core/server/services/permissions/can-this.js +18 -5
- package/core/server/services/permissions/parse-context.js +5 -0
- package/core/server/services/permissions/providers.js +17 -1
- package/core/server/services/posts/posts-service.js +14 -0
- package/core/server/services/users.js +84 -1
- package/core/server/web/admin/app.js +4 -0
- package/core/server/web/admin/views/default-prod.html +5 -5
- package/core/server/web/admin/views/default.html +5 -5
- package/core/server/web/api/app.js +2 -2
- package/core/server/web/api/{canary → endpoints}/admin/app.js +4 -4
- package/core/server/web/api/{canary → endpoints}/admin/middleware.js +1 -0
- package/core/server/web/api/{canary → endpoints}/admin/routes.js +6 -1
- package/core/server/web/api/{canary → endpoints}/content/app.js +4 -4
- package/core/server/web/api/{canary → endpoints}/content/middleware.js +0 -0
- package/core/server/web/api/{canary → endpoints}/content/routes.js +1 -1
- package/core/server/web/api/testmode/routes.js +1 -1
- package/core/server/web/comments/index.js +1 -0
- package/core/server/web/comments/routes.js +28 -0
- package/core/server/web/members/app.js +5 -0
- package/core/server/web/parent/frontend.js +1 -0
- package/core/shared/config/defaults.json +16 -6
- package/core/shared/config/env/config.testing.json +4 -0
- package/core/shared/config/overrides.json +1 -0
- package/core/shared/labs.js +2 -1
- package/core/shared/settings-cache/public.js +2 -1
- package/package.json +20 -20
- package/yarn.lock +425 -275
- package/Gruntfile.js +0 -384
- package/core/built/assets/ghost-dark-923c90399aa560625a983a6ae9abb38c.css +0 -1
- package/core/built/assets/ghost.min-c74f50609022cebf13ad28810def68b6.css +0 -1
- package/core/built/assets/img/contributors/AileenCGN-bf8b9ffbb34c0fd93beb8136af07771b.jpeg +0 -0
- package/core/built/assets/img/contributors/ErisDS-c958ccb9e3597320dee745a42f478569.jpeg +0 -0
- package/core/built/assets/img/contributors/GeorginaLusby-6cea5defddee3c4ea7320e580521e832.jpeg +0 -0
- package/core/built/assets/img/contributors/JohnONolan-47041b80c35c6341b9b929b03139aecc.jpeg +0 -0
- package/core/built/assets/img/contributors/acburdine-d9777fe2601dc215afb6723315829c89.jpeg +0 -0
- package/core/built/assets/img/contributors/bnookala-5896fcdd2f477495323e420efe890657.jpeg +0 -0
- package/core/built/assets/img/contributors/cobbspur-07ded67009757d12517621fc856eba62.jpeg +0 -0
- package/core/built/assets/img/contributors/dbalders-452347a406c2ca23657daea9100878f3.jpeg +0 -0
- package/core/built/assets/img/contributors/disordinary-b9997e5debb59b7aadc79ba90955b662.jpeg +0 -0
- package/core/built/assets/img/contributors/felixrieseberg-ecf29e8eadc58fab999c507049f898cf.jpeg +0 -0
- package/core/built/assets/img/contributors/frantzypants-637b03f85dff89700a661fde79daea5c.jpeg +0 -0
- package/core/built/assets/img/contributors/halfdan-00d6783e5fba2900ee1380939297d8ee.jpeg +0 -0
- package/core/built/assets/img/contributors/jaswilli-8cc9a8d2539ca03239d113dfb25ff5c2.jpeg +0 -0
- package/core/built/assets/img/contributors/kevinansfield-925606c55bc2f3f2f05c0fa58b953ad1.jpeg +0 -0
- package/core/built/assets/img/contributors/kevinkucharczyk-3c7dfe2a103a83737b9d5ee8e19d67f8.jpeg +0 -0
- package/core/built/assets/img/contributors/kirrg001-79823418f2ca21e81719653f0286f95b.jpeg +0 -0
- package/core/built/assets/img/contributors/mixonic-1ff87736dd02cfa080ae109b45131aa6.png +0 -0
- package/core/built/assets/img/contributors/rwjblue-5c7cc009cda45baca2d45f0d1ed19e48.jpeg +0 -0
- package/core/built/assets/img/contributors/sebgie-0fb02df00ee7834dbcc8beba84aec81e.png +0 -0
- package/core/built/assets/img/contributors/tgriesser-d871cbf74a871c0fb6d855e76a893f7e.png +0 -0
- package/core/server/api/canary/utils/serializers/output/utils/extra-attrs.js +0 -33
- package/urls.json +0 -597
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta name="viewport" content="width=device-width">
|
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
6
|
+
<title>💬 New comment on {{postTitle}}</title>
|
|
7
|
+
<style>
|
|
8
|
+
/* -------------------------------------
|
|
9
|
+
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
|
10
|
+
------------------------------------- */
|
|
11
|
+
@media only screen and (max-width: 620px) {
|
|
12
|
+
table[class=body] h1 {
|
|
13
|
+
font-size: 28px !important;
|
|
14
|
+
margin-bottom: 10px !important;
|
|
15
|
+
}
|
|
16
|
+
table[class=body] p,
|
|
17
|
+
table[class=body] ul,
|
|
18
|
+
table[class=body] ol,
|
|
19
|
+
table[class=body] td,
|
|
20
|
+
table[class=body] span,
|
|
21
|
+
table[class=body] a {
|
|
22
|
+
font-size: 16px !important;
|
|
23
|
+
}
|
|
24
|
+
table[class=body] .wrapper,
|
|
25
|
+
table[class=body] .article {
|
|
26
|
+
padding: 10px !important;
|
|
27
|
+
}
|
|
28
|
+
table[class=body] .content {
|
|
29
|
+
padding: 0 !important;
|
|
30
|
+
}
|
|
31
|
+
table[class=body] .container {
|
|
32
|
+
padding: 0 !important;
|
|
33
|
+
width: 100% !important;
|
|
34
|
+
}
|
|
35
|
+
table[class=body] .main {
|
|
36
|
+
border-left-width: 0 !important;
|
|
37
|
+
border-radius: 0 !important;
|
|
38
|
+
border-right-width: 0 !important;
|
|
39
|
+
}
|
|
40
|
+
table[class=body] .btn table {
|
|
41
|
+
width: 100% !important;
|
|
42
|
+
}
|
|
43
|
+
table[class=body] .btn a {
|
|
44
|
+
width: 100% !important;
|
|
45
|
+
}
|
|
46
|
+
table[class=body] .img-responsive {
|
|
47
|
+
height: auto !important;
|
|
48
|
+
max-width: 100% !important;
|
|
49
|
+
width: auto !important;
|
|
50
|
+
}
|
|
51
|
+
table[class=body] p[class=small],
|
|
52
|
+
table[class=body] a[class=small] {
|
|
53
|
+
font-size: 11px !important;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/* -------------------------------------
|
|
57
|
+
PRESERVE THESE STYLES IN THE HEAD
|
|
58
|
+
------------------------------------- */
|
|
59
|
+
@media all {
|
|
60
|
+
.ExternalClass {
|
|
61
|
+
width: 100%;
|
|
62
|
+
}
|
|
63
|
+
.ExternalClass,
|
|
64
|
+
.ExternalClass p,
|
|
65
|
+
.ExternalClass span,
|
|
66
|
+
.ExternalClass font,
|
|
67
|
+
.ExternalClass td,
|
|
68
|
+
.ExternalClass div {
|
|
69
|
+
line-height: 100%;
|
|
70
|
+
}
|
|
71
|
+
.recipient-link a {
|
|
72
|
+
color: inherit !important;
|
|
73
|
+
font-family: inherit !important;
|
|
74
|
+
font-size: inherit !important;
|
|
75
|
+
font-weight: inherit !important;
|
|
76
|
+
line-height: inherit !important;
|
|
77
|
+
text-decoration: none !important;
|
|
78
|
+
}
|
|
79
|
+
#MessageViewBody a {
|
|
80
|
+
color: inherit;
|
|
81
|
+
text-decoration: none;
|
|
82
|
+
font-size: inherit;
|
|
83
|
+
font-family: inherit;
|
|
84
|
+
font-weight: inherit;
|
|
85
|
+
line-height: inherit;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
hr {
|
|
89
|
+
border-width: 0;
|
|
90
|
+
height: 0;
|
|
91
|
+
margin-top: 34px;
|
|
92
|
+
margin-bottom: 34px;
|
|
93
|
+
border-bottom-width: 1px;
|
|
94
|
+
border-bottom-color: #EEF5F8;
|
|
95
|
+
}
|
|
96
|
+
a {
|
|
97
|
+
color: #3A464C;
|
|
98
|
+
}
|
|
99
|
+
</style>
|
|
100
|
+
</head>
|
|
101
|
+
<body style="background-color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.5em; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">
|
|
102
|
+
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
|
|
103
|
+
<tr>
|
|
104
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top;"> </td>
|
|
105
|
+
<td class="container" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; display: block; Margin: 0 auto; max-width: 540px; padding: 10px; width: 540px;">
|
|
106
|
+
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 600px; padding: 30px 20px;">
|
|
107
|
+
|
|
108
|
+
<!-- START CENTERED CONTAINER -->
|
|
109
|
+
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">Someone left a comment on your post</span>
|
|
110
|
+
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 8px;">
|
|
111
|
+
|
|
112
|
+
<!-- START MAIN CONTENT AREA -->
|
|
113
|
+
<tr>
|
|
114
|
+
<td class="wrapper" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; box-sizing: border-box;">
|
|
115
|
+
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
|
|
116
|
+
<tr>
|
|
117
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top;">
|
|
118
|
+
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 20px; color: #15212A; font-weight: bold; line-height: 25px; margin: 0; margin-bottom: 15px;">Hey there,</p>
|
|
119
|
+
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 32px;">Someone just replied to your comment on <a href="https://ghost.org">{{postTitle}}</a>.</p>
|
|
120
|
+
|
|
121
|
+
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box; background: #F9F9FA; border-radius: 7px;">
|
|
122
|
+
<tbody>
|
|
123
|
+
<tr>
|
|
124
|
+
<td align="left" style="padding: 16px;">
|
|
125
|
+
<table border="0" cellpadding="0" cellspacing="0">
|
|
126
|
+
<tr>
|
|
127
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; padding-right: 8px;">
|
|
128
|
+
<table border="0" cellpadding="0" cellspacing="0" width="44" height="44" style="width: 44px; height: 44px; background-color: #15171A; border-radius: 999px;">
|
|
129
|
+
<tr>
|
|
130
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 18px; color: #FFFFFF; text-align: center; font-weight: 500; height: 44px; width: 44px;">{{memberInitials}}</td>
|
|
131
|
+
</tr>
|
|
132
|
+
</table>
|
|
133
|
+
</td>
|
|
134
|
+
<td style="padding-right: 8px;">
|
|
135
|
+
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; padding-right: 8px; padding: 0; margin: 0; color: #15171A; font-weight: 600;">{{memberName}}</p>
|
|
136
|
+
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 13px; padding-right: 8px; padding: 0; margin: 0; color: #95A1AD;">{{#if memberBio}}{{memberBio}} • {{/if}}{{replyDate}}</p>
|
|
137
|
+
</td>
|
|
138
|
+
</tr>
|
|
139
|
+
</table>
|
|
140
|
+
</td>
|
|
141
|
+
</tr>
|
|
142
|
+
<tr>
|
|
143
|
+
<td align="left" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; padding-top: 0; padding-right: 16px; padding-bottom: 16px; padding-left: 16px; color: #15171A;">
|
|
144
|
+
{{{replyHtml}}}
|
|
145
|
+
</td>
|
|
146
|
+
</tr>
|
|
147
|
+
</tbody>
|
|
148
|
+
</table>
|
|
149
|
+
|
|
150
|
+
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box;">
|
|
151
|
+
<tbody>
|
|
152
|
+
<tr>
|
|
153
|
+
<td align="left" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; padding-top: 32px; padding-bottom: 12px;">
|
|
154
|
+
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: auto;">
|
|
155
|
+
<tbody>
|
|
156
|
+
<tr>
|
|
157
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; background-color: {{accentColor}}; border-radius: 5px; text-align: center;"> <a href="{{postUrl}}#ghost-comments-root" target="_blank" style="display: inline-block; color: #ffffff; background-color: {{accentColor}}; border: solid 1px {{accentColor}}; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 16px; font-weight: normal; margin: 0; padding: 9px 22px 10px; border-color: {{accentColor}};">View comments</a> </td>
|
|
158
|
+
</tr>
|
|
159
|
+
</tbody>
|
|
160
|
+
</table>
|
|
161
|
+
</td>
|
|
162
|
+
</tr>
|
|
163
|
+
</tbody>
|
|
164
|
+
</table>
|
|
165
|
+
<hr/>
|
|
166
|
+
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
|
|
167
|
+
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 25px; margin-top:0; color: #3A464C;">{{postUrl}}#ghost-comments-root</p>
|
|
168
|
+
</td>
|
|
169
|
+
</tr>
|
|
170
|
+
|
|
171
|
+
<!-- START FOOTER -->
|
|
172
|
+
<tr>
|
|
173
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; padding-top: 80px;">
|
|
174
|
+
<p class="small" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 18px; font-size: 11px; color: #738A94; font-weight: normal; margin: 0; margin-bottom: 2px;">This message was sent from <a class="small" href="{{siteUrl}}" style="text-decoration: underline; color: #738A94; font-size: 11px;">{{siteDomain}}</a> to <a class="small" href="mailto:{{toEmail}}" style="text-decoration: underline; color: #738A94; font-size: 11px;">{{toEmail}}</a></p>
|
|
175
|
+
</td>
|
|
176
|
+
</tr>
|
|
177
|
+
<tr>
|
|
178
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; padding-top: 2px">
|
|
179
|
+
<p class="small" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 18px; font-size: 11px; color: #738A94; font-weight: normal; margin: 0; margin-bottom: 2px;"><a class="small" href="{{profileUrl}}" style="text-decoration: underline; color: #738A94; font-size: 11px;">Manage your email preferences</a></p>
|
|
180
|
+
</td>
|
|
181
|
+
</tr>
|
|
182
|
+
|
|
183
|
+
<!-- END FOOTER -->
|
|
184
|
+
</table>
|
|
185
|
+
</td>
|
|
186
|
+
</tr>
|
|
187
|
+
|
|
188
|
+
<!-- END MAIN CONTENT AREA -->
|
|
189
|
+
</table>
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
<!-- END CENTERED CONTAINER -->
|
|
193
|
+
</div>
|
|
194
|
+
</td>
|
|
195
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top;"> </td>
|
|
196
|
+
</tr>
|
|
197
|
+
</table>
|
|
198
|
+
</body>
|
|
199
|
+
</html>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module.exports = function (data) {
|
|
2
|
+
return `
|
|
3
|
+
Hey there,
|
|
4
|
+
|
|
5
|
+
Someone just replied to your comment on "${data.postTitle}"
|
|
6
|
+
|
|
7
|
+
${data.postUrl}#comments-area
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Sent to ${data.toEmail} from ${data.siteDomain}.
|
|
12
|
+
You can manage your notification preferences at ${data.profileUrl}.
|
|
13
|
+
`;
|
|
14
|
+
};
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta name="viewport" content="width=device-width">
|
|
5
|
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
6
|
+
<title>💬 New comment on {{postTitle}}</title>
|
|
7
|
+
<style>
|
|
8
|
+
/* -------------------------------------
|
|
9
|
+
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
|
10
|
+
------------------------------------- */
|
|
11
|
+
@media only screen and (max-width: 620px) {
|
|
12
|
+
table[class=body] h1 {
|
|
13
|
+
font-size: 28px !important;
|
|
14
|
+
margin-bottom: 10px !important;
|
|
15
|
+
}
|
|
16
|
+
table[class=body] p,
|
|
17
|
+
table[class=body] ul,
|
|
18
|
+
table[class=body] ol,
|
|
19
|
+
table[class=body] td,
|
|
20
|
+
table[class=body] span,
|
|
21
|
+
table[class=body] a {
|
|
22
|
+
font-size: 16px !important;
|
|
23
|
+
}
|
|
24
|
+
table[class=body] .wrapper,
|
|
25
|
+
table[class=body] .article {
|
|
26
|
+
padding: 10px !important;
|
|
27
|
+
}
|
|
28
|
+
table[class=body] .content {
|
|
29
|
+
padding: 0 !important;
|
|
30
|
+
}
|
|
31
|
+
table[class=body] .container {
|
|
32
|
+
padding: 0 !important;
|
|
33
|
+
width: 100% !important;
|
|
34
|
+
}
|
|
35
|
+
table[class=body] .main {
|
|
36
|
+
border-left-width: 0 !important;
|
|
37
|
+
border-radius: 0 !important;
|
|
38
|
+
border-right-width: 0 !important;
|
|
39
|
+
}
|
|
40
|
+
table[class=body] .btn table {
|
|
41
|
+
width: 100% !important;
|
|
42
|
+
}
|
|
43
|
+
table[class=body] .btn a {
|
|
44
|
+
width: 100% !important;
|
|
45
|
+
}
|
|
46
|
+
table[class=body] .img-responsive {
|
|
47
|
+
height: auto !important;
|
|
48
|
+
max-width: 100% !important;
|
|
49
|
+
width: auto !important;
|
|
50
|
+
}
|
|
51
|
+
table[class=body] p[class=small],
|
|
52
|
+
table[class=body] a[class=small] {
|
|
53
|
+
font-size: 11px !important;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/* -------------------------------------
|
|
57
|
+
PRESERVE THESE STYLES IN THE HEAD
|
|
58
|
+
------------------------------------- */
|
|
59
|
+
@media all {
|
|
60
|
+
.ExternalClass {
|
|
61
|
+
width: 100%;
|
|
62
|
+
}
|
|
63
|
+
.ExternalClass,
|
|
64
|
+
.ExternalClass p,
|
|
65
|
+
.ExternalClass span,
|
|
66
|
+
.ExternalClass font,
|
|
67
|
+
.ExternalClass td,
|
|
68
|
+
.ExternalClass div {
|
|
69
|
+
line-height: 100%;
|
|
70
|
+
}
|
|
71
|
+
.recipient-link a {
|
|
72
|
+
color: inherit !important;
|
|
73
|
+
font-family: inherit !important;
|
|
74
|
+
font-size: inherit !important;
|
|
75
|
+
font-weight: inherit !important;
|
|
76
|
+
line-height: inherit !important;
|
|
77
|
+
text-decoration: none !important;
|
|
78
|
+
}
|
|
79
|
+
#MessageViewBody a {
|
|
80
|
+
color: inherit;
|
|
81
|
+
text-decoration: none;
|
|
82
|
+
font-size: inherit;
|
|
83
|
+
font-family: inherit;
|
|
84
|
+
font-weight: inherit;
|
|
85
|
+
line-height: inherit;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
hr {
|
|
89
|
+
border-width: 0;
|
|
90
|
+
height: 0;
|
|
91
|
+
margin-top: 34px;
|
|
92
|
+
margin-bottom: 34px;
|
|
93
|
+
border-bottom-width: 1px;
|
|
94
|
+
border-bottom-color: #EEF5F8;
|
|
95
|
+
}
|
|
96
|
+
a {
|
|
97
|
+
color: #3A464C;
|
|
98
|
+
}
|
|
99
|
+
</style>
|
|
100
|
+
</head>
|
|
101
|
+
<body style="background-color: #ffffff; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; -webkit-font-smoothing: antialiased; font-size: 14px; line-height: 1.5em; margin: 0; padding: 0; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;">
|
|
102
|
+
<table border="0" cellpadding="0" cellspacing="0" class="body" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
|
|
103
|
+
<tr>
|
|
104
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top;"> </td>
|
|
105
|
+
<td class="container" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; display: block; Margin: 0 auto; max-width: 540px; padding: 10px; width: 540px;">
|
|
106
|
+
<div class="content" style="box-sizing: border-box; display: block; Margin: 0 auto; max-width: 600px; padding: 30px 20px;">
|
|
107
|
+
|
|
108
|
+
<!-- START CENTERED CONTAINER -->
|
|
109
|
+
<span class="preheader" style="color: transparent; display: none; height: 0; max-height: 0; max-width: 0; opacity: 0; overflow: hidden; mso-hide: all; visibility: hidden; width: 0;">Someone left a comment on your post</span>
|
|
110
|
+
<table class="main" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; background: #ffffff; border-radius: 8px;">
|
|
111
|
+
|
|
112
|
+
<!-- START MAIN CONTENT AREA -->
|
|
113
|
+
<tr>
|
|
114
|
+
<td class="wrapper" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; box-sizing: border-box;">
|
|
115
|
+
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%;">
|
|
116
|
+
<tr>
|
|
117
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top;">
|
|
118
|
+
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 20px; color: #15212A; font-weight: bold; line-height: 25px; margin: 0; margin-bottom: 15px;">Hey there,</p>
|
|
119
|
+
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 32px;">Someone just left a comment on your post <a href="https://ghost.org">{{postTitle}}</a>.</p>
|
|
120
|
+
|
|
121
|
+
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box; background: #F9F9FA; border-radius: 7px;">
|
|
122
|
+
<tbody>
|
|
123
|
+
<tr>
|
|
124
|
+
<td align="left" style="padding: 16px;">
|
|
125
|
+
<table border="0" cellpadding="0" cellspacing="0">
|
|
126
|
+
<tr>
|
|
127
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; padding-right: 8px;">
|
|
128
|
+
<table border="0" cellpadding="0" cellspacing="0" width="44" height="44" style="width: 44px; height: 44px; background-color: #15171A; border-radius: 999px;">
|
|
129
|
+
<tr>
|
|
130
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 18px; color: #FFFFFF; text-align: center; font-weight: 500; height: 44px; width: 44px;">{{memberInitials}}</td>
|
|
131
|
+
</tr>
|
|
132
|
+
</table>
|
|
133
|
+
</td>
|
|
134
|
+
<td style="padding-right: 8px;">
|
|
135
|
+
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; padding-right: 8px; padding: 0; margin: 0; color: #15171A; font-weight: 600;">{{memberName}}</p>
|
|
136
|
+
<p style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 13px; padding-right: 8px; padding: 0; margin: 0; color: #95A1AD;">{{#if memberBio}}{{memberBio}} • {{/if}}{{commentDate}}</p>
|
|
137
|
+
</td>
|
|
138
|
+
</tr>
|
|
139
|
+
</table>
|
|
140
|
+
</td>
|
|
141
|
+
</tr>
|
|
142
|
+
<tr>
|
|
143
|
+
<td align="left" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; padding-top: 0; padding-right: 16px; padding-bottom: 16px; padding-left: 16px; color: #15171A;">
|
|
144
|
+
{{{commentHtml}}}
|
|
145
|
+
</td>
|
|
146
|
+
</tr>
|
|
147
|
+
</tbody>
|
|
148
|
+
</table>
|
|
149
|
+
|
|
150
|
+
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; box-sizing: border-box;">
|
|
151
|
+
<tbody>
|
|
152
|
+
<tr>
|
|
153
|
+
<td align="left" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; padding-top: 32px; padding-bottom: 12px;">
|
|
154
|
+
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: separate; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: auto;">
|
|
155
|
+
<tbody>
|
|
156
|
+
<tr>
|
|
157
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 16px; vertical-align: top; background-color: {{accentColor}}; border-radius: 5px; text-align: center;"> <a href="{{postUrl}}#ghost-comments-root" target="_blank" style="display: inline-block; color: #ffffff; background-color: {{accentColor}}; border: solid 1px {{accentColor}}; border-radius: 5px; box-sizing: border-box; cursor: pointer; text-decoration: none; font-size: 16px; font-weight: normal; margin: 0; padding: 9px 22px 10px; border-color: {{accentColor}};">View comments</a> </td>
|
|
158
|
+
</tr>
|
|
159
|
+
</tbody>
|
|
160
|
+
</table>
|
|
161
|
+
</td>
|
|
162
|
+
</tr>
|
|
163
|
+
</tbody>
|
|
164
|
+
</table>
|
|
165
|
+
<hr/>
|
|
166
|
+
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; color: #3A464C; font-weight: normal; margin: 0; line-height: 25px; margin-bottom: 5px;">You can also copy & paste this URL into your browser:</p>
|
|
167
|
+
<p style="word-break: break-all; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 15px; line-height: 25px; margin-top:0; color: #3A464C;">{{postUrl}}#ghost-comments-root</p>
|
|
168
|
+
</td>
|
|
169
|
+
</tr>
|
|
170
|
+
|
|
171
|
+
<!-- START FOOTER -->
|
|
172
|
+
<tr>
|
|
173
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; padding-top: 80px;">
|
|
174
|
+
<p class="small" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 18px; font-size: 11px; color: #738A94; font-weight: normal; margin: 0; margin-bottom: 2px;">This message was sent from <a class="small" href="{{siteUrl}}" style="text-decoration: underline; color: #738A94; font-size: 11px;">{{siteDomain}}</a> to <a class="small" href="mailto:{{toEmail}}" style="text-decoration: underline; color: #738A94; font-size: 11px;">{{toEmail}}</a></p>
|
|
175
|
+
</td>
|
|
176
|
+
</tr>
|
|
177
|
+
<tr>
|
|
178
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top; padding-top: 2px">
|
|
179
|
+
<p class="small" style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; line-height: 18px; font-size: 11px; color: #738A94; font-weight: normal; margin: 0; margin-bottom: 2px;"><a class="small" href="{{staffUrl}}" style="text-decoration: underline; color: #738A94; font-size: 11px;">Manage your email preferences</a></p>
|
|
180
|
+
</td>
|
|
181
|
+
</tr>
|
|
182
|
+
|
|
183
|
+
<!-- END FOOTER -->
|
|
184
|
+
</table>
|
|
185
|
+
</td>
|
|
186
|
+
</tr>
|
|
187
|
+
|
|
188
|
+
<!-- END MAIN CONTENT AREA -->
|
|
189
|
+
</table>
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
<!-- END CENTERED CONTAINER -->
|
|
193
|
+
</div>
|
|
194
|
+
</td>
|
|
195
|
+
<td style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol'; font-size: 14px; vertical-align: top;"> </td>
|
|
196
|
+
</tr>
|
|
197
|
+
</table>
|
|
198
|
+
</body>
|
|
199
|
+
</html>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module.exports = function (data) {
|
|
2
|
+
return `
|
|
3
|
+
Hey there,
|
|
4
|
+
|
|
5
|
+
Someone just posted a comment on your post "${data.postTitle}"
|
|
6
|
+
|
|
7
|
+
${data.postUrl}#comments-area
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
Sent to ${data.toEmail} from ${data.siteDomain}.
|
|
12
|
+
You can manage your notification preferences at ${data.staffUrl}.
|
|
13
|
+
`;
|
|
14
|
+
};
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
const {promises: fs} = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const moment = require('moment');
|
|
4
|
+
|
|
5
|
+
class CommentsServiceEmails {
|
|
6
|
+
constructor({config, logging, models, mailer, settingsCache, urlService, urlUtils}) {
|
|
7
|
+
this.config = config;
|
|
8
|
+
this.logging = logging;
|
|
9
|
+
this.models = models;
|
|
10
|
+
this.mailer = mailer;
|
|
11
|
+
this.settingsCache = settingsCache;
|
|
12
|
+
this.urlService = urlService;
|
|
13
|
+
this.urlUtils = urlUtils;
|
|
14
|
+
|
|
15
|
+
this.Handlebars = require('handlebars');
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async notifyPostAuthors(comment) {
|
|
19
|
+
const post = await this.models.Post.findOne({id: comment.get('post_id')}, {withRelated: ['authors']});
|
|
20
|
+
const member = await this.models.Member.findOne({id: comment.get('member_id')});
|
|
21
|
+
|
|
22
|
+
for (const author of post.related('authors')) {
|
|
23
|
+
if (!author.get('comment_notifications')) {
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const to = author.get('email');
|
|
28
|
+
const subject = '💬 You have a new comment on one of your posts';
|
|
29
|
+
|
|
30
|
+
const memberName = member.get('name') || 'Anonymous';
|
|
31
|
+
|
|
32
|
+
const templateData = {
|
|
33
|
+
siteTitle: this.settingsCache.get('title'),
|
|
34
|
+
siteUrl: this.urlUtils.getSiteUrl(),
|
|
35
|
+
siteDomain: this.siteDomain,
|
|
36
|
+
postTitle: post.get('title'),
|
|
37
|
+
postUrl: this.urlService.getUrlByResourceId(post.get('id'), {absolute: true}),
|
|
38
|
+
commentHtml: comment.get('html'),
|
|
39
|
+
commentDate: moment(comment.get('created_at')).tz(this.settingsCache.get('timezone')).format('D MMM YYYY'),
|
|
40
|
+
memberName: memberName,
|
|
41
|
+
memberBio: member.get('bio'),
|
|
42
|
+
memberInitials: this.extractInitials(memberName),
|
|
43
|
+
accentColor: this.settingsCache.get('accent_color'),
|
|
44
|
+
fromEmail: this.notificationFromAddress,
|
|
45
|
+
toEmail: to,
|
|
46
|
+
staffUrl: `${this.urlUtils.getAdminUrl()}ghost/#/settings/staff/${author.get('slug')}`
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const {html, text} = await this.renderEmailTemplate('new-comment', templateData);
|
|
50
|
+
|
|
51
|
+
this.sendMail({
|
|
52
|
+
to,
|
|
53
|
+
subject,
|
|
54
|
+
html,
|
|
55
|
+
text
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
async notifyParentCommentAuthor(reply) {
|
|
61
|
+
const parent = await this.models.Comment.findOne({id: reply.get('parent_id')});
|
|
62
|
+
const parentMember = parent.related('member');
|
|
63
|
+
|
|
64
|
+
if (parent?.get('status') !== 'published' || !parentMember.get('enable_comment_notifications')) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const to = parentMember.get('email');
|
|
69
|
+
const subject = '💬 You have a new reply on one of your comments';
|
|
70
|
+
|
|
71
|
+
const post = await this.models.Post.findOne({id: reply.get('post_id')});
|
|
72
|
+
const member = await this.models.Member.findOne({id: reply.get('member_id')});
|
|
73
|
+
|
|
74
|
+
const memberName = member.get('name') || 'Anonymous';
|
|
75
|
+
|
|
76
|
+
const templateData = {
|
|
77
|
+
siteTitle: this.settingsCache.get('title'),
|
|
78
|
+
siteUrl: this.urlUtils.getSiteUrl(),
|
|
79
|
+
siteDomain: this.siteDomain,
|
|
80
|
+
postTitle: post.get('title'),
|
|
81
|
+
postUrl: this.urlService.getUrlByResourceId(post.get('id'), {absolute: true}),
|
|
82
|
+
replyHtml: reply.get('html'),
|
|
83
|
+
replyDate: moment(reply.get('created_at')).tz(this.settingsCache.get('timezone')).format('D MMM YYYY'),
|
|
84
|
+
memberName: memberName,
|
|
85
|
+
memberBio: member.get('bio'),
|
|
86
|
+
memberInitials: this.extractInitials(memberName),
|
|
87
|
+
accentColor: this.settingsCache.get('accent_color'),
|
|
88
|
+
fromEmail: this.notificationFromAddress,
|
|
89
|
+
toEmail: to,
|
|
90
|
+
profileUrl: `${this.urlUtils.getSiteUrl()}#/portal/account/profile`
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const {html, text} = await this.renderEmailTemplate('new-comment-reply', templateData);
|
|
94
|
+
|
|
95
|
+
return this.sendMail({
|
|
96
|
+
to,
|
|
97
|
+
subject,
|
|
98
|
+
html,
|
|
99
|
+
text
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Utils
|
|
104
|
+
|
|
105
|
+
get siteDomain() {
|
|
106
|
+
const [, siteDomain] = this.urlUtils.getSiteUrl()
|
|
107
|
+
.match(new RegExp('^https?://([^/:?#]+)(?:[/:?#]|$)', 'i'));
|
|
108
|
+
|
|
109
|
+
return siteDomain;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
get membersAddress() {
|
|
113
|
+
// TODO: get from address of default newsletter?
|
|
114
|
+
return `noreply@${this.siteDomain}`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// TODO: duplicated from services/members/config - exrtact to settings?
|
|
118
|
+
get supportAddress() {
|
|
119
|
+
const supportAddress = this.settingsCache.get('members_support_address') || 'noreply';
|
|
120
|
+
|
|
121
|
+
// Any fromAddress without domain uses site domain, like default setting `noreply`
|
|
122
|
+
if (supportAddress.indexOf('@') < 0) {
|
|
123
|
+
return `${supportAddress}@${this.siteDomain}`;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return supportAddress;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
get notificationFromAddress() {
|
|
130
|
+
return this.supportAddress || this.membersAddress;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
extractInitials(name = '') {
|
|
134
|
+
const names = name.split(' ');
|
|
135
|
+
const initials = names.length > 1 ? [names[0][0], names[names.length - 1][0]] : [names[0][0]];
|
|
136
|
+
return initials.join('').toUpperCase();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async sendMail(message) {
|
|
140
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
141
|
+
this.logging.warn(message.text);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
let msg = Object.assign({
|
|
145
|
+
from: this.notificationFromAddress,
|
|
146
|
+
forceTextContent: true
|
|
147
|
+
}, message);
|
|
148
|
+
|
|
149
|
+
return this.mailer.send(msg);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async renderEmailTemplate(templateName, data) {
|
|
153
|
+
const htmlTemplateSource = await fs.readFile(path.join(__dirname, './email-templates/', `${templateName}.hbs`), 'utf8');
|
|
154
|
+
const htmlTemplate = this.Handlebars.compile(Buffer.from(htmlTemplateSource).toString());
|
|
155
|
+
const textTemplate = require(`./email-templates/${templateName}.txt.js`);
|
|
156
|
+
|
|
157
|
+
const html = htmlTemplate(data);
|
|
158
|
+
const text = textTemplate(data);
|
|
159
|
+
|
|
160
|
+
return {html, text};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
module.exports = CommentsServiceEmails;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class CommentsServiceWrapper {
|
|
2
|
+
init() {
|
|
3
|
+
const CommentsService = require('./service');
|
|
4
|
+
|
|
5
|
+
const config = require('../../../shared/config');
|
|
6
|
+
const logging = require('@tryghost/logging');
|
|
7
|
+
const models = require('../../models');
|
|
8
|
+
const {GhostMailer} = require('../mail');
|
|
9
|
+
const mailer = new GhostMailer();
|
|
10
|
+
const settingsCache = require('../../../shared/settings-cache');
|
|
11
|
+
const urlService = require('../url');
|
|
12
|
+
const urlUtils = require('../../../shared/url-utils');
|
|
13
|
+
|
|
14
|
+
this.api = new CommentsService({
|
|
15
|
+
config,
|
|
16
|
+
logging,
|
|
17
|
+
models,
|
|
18
|
+
mailer,
|
|
19
|
+
settingsCache,
|
|
20
|
+
urlService,
|
|
21
|
+
urlUtils
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
module.exports = new CommentsServiceWrapper();
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class CommentsService {
|
|
2
|
+
constructor({config, logging, models, mailer, settingsCache, urlService, urlUtils}) {
|
|
3
|
+
this.config = config;
|
|
4
|
+
this.logging = logging;
|
|
5
|
+
this.models = models;
|
|
6
|
+
this.mailer = mailer;
|
|
7
|
+
this.settingsCache = settingsCache;
|
|
8
|
+
this.urlService = urlService;
|
|
9
|
+
this.urlUtils = urlUtils;
|
|
10
|
+
|
|
11
|
+
const Emails = require('./emails');
|
|
12
|
+
this.emails = new Emails(this);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async sendNewCommentNotifications(comment) {
|
|
16
|
+
this.emails.notifyPostAuthors(comment);
|
|
17
|
+
|
|
18
|
+
if (comment.get('parent_id')) {
|
|
19
|
+
this.emails.notifyParentCommentAuthor(comment);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = CommentsService;
|