ghost 4.27.1 → 4.30.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 +1 -17
- package/content/themes/casper/package.json +1 -1
- package/content/themes/casper/partials/post-card.hbs +1 -1
- package/core/boot.js +3 -5
- package/core/built/assets/{ghost-dark-ae67fe157509b6e82c607ba560fc52e9.css → ghost-dark-1594d07a0716e0253a78234c8e42d765.css} +1 -1
- package/core/built/assets/{ghost.min-2d534cce15c43c646814b26f4beefb78.js → ghost.min-884660873d56fcc3d2a3b9fe94c9f022.js} +79 -79
- package/core/built/assets/{ghost.min-b1e58e098721e467388682a85a7c187d.css → ghost.min-c21fea11c3f431994a8ee7c47a8ed145.css} +1 -1
- package/core/built/assets/icons/audio-file.svg +5 -0
- package/core/built/assets/icons/file-download.svg +1 -0
- package/core/built/assets/icons/file-upload.svg +1 -0
- package/core/built/assets/icons/film-camera.svg +4 -0
- package/core/built/assets/icons/mute.svg +3 -0
- package/core/built/assets/icons/pause.svg +4 -0
- package/core/built/assets/icons/play.svg +3 -0
- package/core/built/assets/icons/unmute.svg +3 -0
- package/core/built/assets/{vendor.min-e433aa7d5620e7837f30e170cd43f84e.js → vendor.min-a2fd1e62ce6da8911fee8e812d8c6ceb.js} +240 -128
- package/core/frontend/apps/amp/lib/views/amp.hbs +94 -2
- package/core/frontend/services/theme-engine/i18n/i18n.js +11 -12
- package/core/frontend/services/theme-engine/i18n/index.js +1 -2
- package/core/frontend/services/theme-engine/i18n/theme-i18n.js +5 -4
- package/core/frontend/src/cards/css/audio.css +95 -30
- package/core/frontend/src/cards/css/before-after.css +47 -0
- package/core/frontend/src/cards/css/bookmark.css +6 -5
- package/core/frontend/src/cards/css/button.css +8 -7
- package/core/frontend/src/cards/css/callout.css +4 -4
- package/core/frontend/src/cards/css/file.css +126 -0
- package/core/frontend/src/cards/css/nft.css +9 -13
- package/core/frontend/src/cards/css/product.css +81 -52
- package/core/frontend/src/cards/css/toggle.css +31 -22
- package/core/frontend/src/cards/css/video.css +340 -0
- package/core/frontend/src/cards/js/audio.js +127 -128
- package/core/frontend/src/cards/js/before-after.js +41 -0
- package/core/frontend/src/cards/js/gallery.js +10 -8
- package/core/frontend/src/cards/js/toggle.js +16 -14
- package/core/frontend/src/cards/js/video.js +232 -0
- package/core/frontend/web/middleware/error-handler.js +2 -2
- package/core/frontend/web/site.js +2 -1
- package/core/server/api/canary/oembed.js +1 -2
- package/core/server/data/db/state-manager.js +5 -8
- package/core/server/lib/image/cached-image-size-from-url.js +3 -4
- package/core/server/lib/image/image-utils.js +2 -2
- package/core/server/lib/image/index.js +1 -2
- package/core/server/run-update-check.js +1 -13
- package/core/server/services/email-analytics/index.js +2 -4
- package/core/server/services/email-analytics/jobs/fetch-latest.js +2 -21
- package/core/server/services/integrations/integrations-service.js +2 -2
- package/core/server/services/invites/index.js +0 -2
- package/core/server/services/invites/invites.js +3 -3
- package/core/server/services/jobs/job-service.js +1 -1
- package/core/server/services/mega/post-email-serializer.js +3 -1
- package/core/server/services/mega/template.js +15 -11
- package/core/server/services/members/api.js +0 -1
- package/core/server/services/members/config.js +4 -7
- package/core/server/services/members/service.js +1 -4
- package/core/server/services/notifications/index.js +0 -2
- package/core/server/services/notifications/notifications.js +4 -5
- package/core/server/services/stripe/index.js +0 -2
- package/core/server/services/twitter-embed.js +2 -1
- package/core/server/web/admin/app.js +4 -2
- package/core/server/web/admin/views/default-prod.html +4 -4
- package/core/server/web/admin/views/default.html +4 -4
- package/core/server/web/api/app.js +3 -2
- package/core/server/web/api/canary/admin/app.js +4 -2
- package/core/server/web/api/canary/content/app.js +4 -2
- package/core/server/web/api/v2/admin/app.js +4 -2
- package/core/server/web/api/v2/content/app.js +4 -2
- package/core/server/web/api/v3/admin/app.js +4 -2
- package/core/server/web/api/v3/content/app.js +4 -2
- package/core/server/web/members/app.js +6 -4
- package/core/server/web/shared/middleware/index.js +0 -4
- package/core/shared/labs.js +9 -8
- package/package.json +28 -23
- package/yarn.lock +2589 -1988
- package/core/server/web/shared/middleware/error-handler.js +0 -224
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
|
|
1
|
+
(function() {
|
|
2
|
+
const toggleHeadingElements = document.getElementsByClassName("kg-toggle-heading");
|
|
2
3
|
|
|
3
|
-
const toggleFn = function(event) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
};
|
|
4
|
+
const toggleFn = function(event) {
|
|
5
|
+
const targetElement = event.target;
|
|
6
|
+
const parentElement = targetElement.closest('.kg-toggle-card');
|
|
7
|
+
var toggleState = parentElement.getAttribute("data-kg-toggle-state");
|
|
8
|
+
if (toggleState === 'close') {
|
|
9
|
+
parentElement.setAttribute('data-kg-toggle-state', 'open');
|
|
10
|
+
} else {
|
|
11
|
+
parentElement.setAttribute('data-kg-toggle-state', 'close');
|
|
12
|
+
}
|
|
13
|
+
};
|
|
13
14
|
|
|
14
|
-
for (let i = 0; i < toggleHeadingElements.length; i++) {
|
|
15
|
-
|
|
16
|
-
}
|
|
15
|
+
for (let i = 0; i < toggleHeadingElements.length; i++) {
|
|
16
|
+
toggleHeadingElements[i].addEventListener('click', toggleFn, false);
|
|
17
|
+
}
|
|
18
|
+
})();
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
const handleVideoPlayer = function (videoElementContainer) {
|
|
3
|
+
const videoPlayer = videoElementContainer.querySelector('.kg-video-player');
|
|
4
|
+
const videoPlayerContainer = videoElementContainer.querySelector('.kg-video-player-container');
|
|
5
|
+
const playIconContainer = videoElementContainer.querySelector('.kg-video-play-icon');
|
|
6
|
+
const pauseIconContainer = videoElementContainer.querySelector('.kg-video-pause-icon');
|
|
7
|
+
const seekSlider = videoElementContainer.querySelector('.kg-video-seek-slider');
|
|
8
|
+
const playbackRateContainer = videoElementContainer.querySelector('.kg-video-playback-rate');
|
|
9
|
+
const muteIconContainer = videoElementContainer.querySelector('.kg-video-mute-icon');
|
|
10
|
+
const unmuteIconContainer = videoElementContainer.querySelector('.kg-video-unmute-icon');
|
|
11
|
+
const volumeSlider = videoElementContainer.querySelector('.kg-video-volume-slider');
|
|
12
|
+
const videoEl = videoElementContainer.querySelector('video');
|
|
13
|
+
const durationContainer = videoElementContainer.querySelector('.kg-video-duration');
|
|
14
|
+
const currentTimeContainer = videoElementContainer.querySelector('.kg-video-current-time');
|
|
15
|
+
const largePlayIcon = videoElementContainer.querySelector('.kg-video-large-play-icon');
|
|
16
|
+
const videoOverlay = videoElementContainer.querySelector('.kg-video-overlay');
|
|
17
|
+
let playbackRates = [{
|
|
18
|
+
rate: 0.75,
|
|
19
|
+
label: '0.7×'
|
|
20
|
+
}, {
|
|
21
|
+
rate: 1.0,
|
|
22
|
+
label: '1×'
|
|
23
|
+
}, {
|
|
24
|
+
rate: 1.25,
|
|
25
|
+
label: '1.2×'
|
|
26
|
+
}, {
|
|
27
|
+
rate: 1.75,
|
|
28
|
+
label: '1.7×'
|
|
29
|
+
}, {
|
|
30
|
+
rate: 2.0,
|
|
31
|
+
label: '2×'
|
|
32
|
+
}];
|
|
33
|
+
|
|
34
|
+
let raf = null;
|
|
35
|
+
let currentPlaybackRateIdx = 1;
|
|
36
|
+
if (!!videoEl.loop) {
|
|
37
|
+
largePlayIcon.classList.add("kg-video-hide-animated");
|
|
38
|
+
videoOverlay.classList.add("kg-video-hide-animated");
|
|
39
|
+
}
|
|
40
|
+
const whilePlaying = () => {
|
|
41
|
+
seekSlider.value = Math.floor(videoEl.currentTime);
|
|
42
|
+
currentTimeContainer.textContent = calculateTime(seekSlider.value);
|
|
43
|
+
videoPlayer.style.setProperty('--seek-before-width', `${seekSlider.value / seekSlider.max * 100}%`);
|
|
44
|
+
raf = requestAnimationFrame(whilePlaying);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const showRangeProgress = (rangeInput) => {
|
|
48
|
+
if (rangeInput === seekSlider) {
|
|
49
|
+
videoPlayer.style.setProperty('--seek-before-width', rangeInput.value / rangeInput.max * 100 + '%');
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
videoPlayer.style.setProperty('--volume-before-width', rangeInput.value / rangeInput.max * 100 + '%');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const calculateTime = (secs) => {
|
|
57
|
+
const minutes = Math.floor(secs / 60);
|
|
58
|
+
const seconds = Math.floor(secs % 60);
|
|
59
|
+
const returnedSeconds = seconds < 10 ? `0${seconds}` : `${seconds}`;
|
|
60
|
+
return `${minutes}:${returnedSeconds}`;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const displayDuration = () => {
|
|
64
|
+
durationContainer.textContent = calculateTime(videoEl.duration);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const setSliderMax = () => {
|
|
68
|
+
seekSlider.max = Math.floor(videoEl.duration);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const displayBufferedAmount = () => {
|
|
72
|
+
if (videoEl.buffered.length > 0) {
|
|
73
|
+
const bufferedAmount = Math.floor(videoEl.buffered.end(videoEl.buffered.length - 1));
|
|
74
|
+
videoPlayer.style.setProperty('--buffered-width', `${(bufferedAmount / seekSlider.max) * 100}%`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (videoEl.readyState > 0) {
|
|
79
|
+
displayDuration();
|
|
80
|
+
setSliderMax();
|
|
81
|
+
displayBufferedAmount();
|
|
82
|
+
if (videoEl.autoplay) {
|
|
83
|
+
raf = requestAnimationFrame(whilePlaying);
|
|
84
|
+
playIconContainer.classList.add("kg-video-hide");
|
|
85
|
+
pauseIconContainer.classList.remove("kg-video-hide");
|
|
86
|
+
}
|
|
87
|
+
if (videoEl.muted) {
|
|
88
|
+
unmuteIconContainer.classList.add("kg-video-hide");
|
|
89
|
+
muteIconContainer.classList.remove("kg-video-hide");
|
|
90
|
+
}
|
|
91
|
+
} else {
|
|
92
|
+
videoEl.addEventListener('loadedmetadata', () => {
|
|
93
|
+
displayDuration();
|
|
94
|
+
setSliderMax();
|
|
95
|
+
displayBufferedAmount();
|
|
96
|
+
if (videoEl.autoplay) {
|
|
97
|
+
raf = requestAnimationFrame(whilePlaying);
|
|
98
|
+
playIconContainer.classList.add("kg-video-hide");
|
|
99
|
+
pauseIconContainer.classList.remove("kg-video-hide");
|
|
100
|
+
}
|
|
101
|
+
if (videoEl.muted) {
|
|
102
|
+
unmuteIconContainer.classList.add("kg-video-hide");
|
|
103
|
+
muteIconContainer.classList.remove("kg-video-hide");
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
videoElementContainer.onmouseover = () => {
|
|
109
|
+
if (!videoEl.loop) {
|
|
110
|
+
videoPlayerContainer.classList.remove("kg-video-hide-animated");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
videoElementContainer.onmouseleave = () => {
|
|
115
|
+
const isPlaying = !!(videoEl.currentTime > 0 && !videoEl.paused && !videoEl.ended && videoEl.readyState > 2);
|
|
116
|
+
if (isPlaying) {
|
|
117
|
+
videoPlayerContainer.classList.add("kg-video-hide-animated");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
videoElementContainer.addEventListener('click', () => {
|
|
122
|
+
if (!videoEl.loop) {
|
|
123
|
+
const isPlaying = !!(videoEl.currentTime > 0 && !videoEl.paused && !videoEl.ended && videoEl.readyState > 2);
|
|
124
|
+
if (isPlaying) {
|
|
125
|
+
handleOnPause();
|
|
126
|
+
} else {
|
|
127
|
+
handleOnPlay();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
videoEl.onplay = () => {
|
|
133
|
+
largePlayIcon.classList.add("kg-video-hide-animated");
|
|
134
|
+
videoOverlay.classList.add("kg-video-hide-animated");
|
|
135
|
+
playIconContainer.classList.add("kg-video-hide");
|
|
136
|
+
pauseIconContainer.classList.remove("kg-video-hide");
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
const handleOnPlay = () => {
|
|
140
|
+
largePlayIcon.classList.add("kg-video-hide-animated");
|
|
141
|
+
videoOverlay.classList.add("kg-video-hide-animated");
|
|
142
|
+
playIconContainer.classList.add("kg-video-hide");
|
|
143
|
+
pauseIconContainer.classList.remove("kg-video-hide");
|
|
144
|
+
videoEl.play();
|
|
145
|
+
raf = requestAnimationFrame(whilePlaying);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const handleOnPause = () => {
|
|
149
|
+
pauseIconContainer.classList.add("kg-video-hide");
|
|
150
|
+
playIconContainer.classList.remove("kg-video-hide");
|
|
151
|
+
videoEl.pause();
|
|
152
|
+
cancelAnimationFrame(raf);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
largePlayIcon.addEventListener('click', (event) => {
|
|
156
|
+
event.stopPropagation();
|
|
157
|
+
handleOnPlay();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
playIconContainer.addEventListener('click', (event) => {
|
|
161
|
+
event.stopPropagation();
|
|
162
|
+
handleOnPlay();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
pauseIconContainer.addEventListener('click', (event) => {
|
|
166
|
+
event.stopPropagation();
|
|
167
|
+
handleOnPause();
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
muteIconContainer.addEventListener('click', (event) => {
|
|
171
|
+
event.stopPropagation();
|
|
172
|
+
muteIconContainer.classList.add("kg-video-hide");
|
|
173
|
+
unmuteIconContainer.classList.remove("kg-video-hide");
|
|
174
|
+
videoEl.muted = false;
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
unmuteIconContainer.addEventListener('click', (event) => {
|
|
178
|
+
event.stopPropagation();
|
|
179
|
+
unmuteIconContainer.classList.add("kg-video-hide");
|
|
180
|
+
muteIconContainer.classList.remove("kg-video-hide");
|
|
181
|
+
videoEl.muted = true;
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
playbackRateContainer.addEventListener('click', (event) => {
|
|
185
|
+
event.stopPropagation();
|
|
186
|
+
let nextPlaybackRate = playbackRates[(currentPlaybackRateIdx + 1) % 5];
|
|
187
|
+
currentPlaybackRateIdx = currentPlaybackRateIdx + 1;
|
|
188
|
+
videoEl.playbackRate = nextPlaybackRate.rate;
|
|
189
|
+
playbackRateContainer.textContent = nextPlaybackRate.label;
|
|
190
|
+
});
|
|
191
|
+
|
|
192
|
+
videoEl.addEventListener('progress', displayBufferedAmount);
|
|
193
|
+
|
|
194
|
+
seekSlider.addEventListener('input', (e) => {
|
|
195
|
+
e.stopPropagation();
|
|
196
|
+
showRangeProgress(e.target);
|
|
197
|
+
currentTimeContainer.textContent = calculateTime(seekSlider.value);
|
|
198
|
+
if (!videoEl.paused) {
|
|
199
|
+
cancelAnimationFrame(raf);
|
|
200
|
+
}
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
seekSlider.addEventListener('change', (event) => {
|
|
204
|
+
event.stopPropagation();
|
|
205
|
+
videoEl.currentTime = seekSlider.value;
|
|
206
|
+
if (!videoEl.paused) {
|
|
207
|
+
requestAnimationFrame(whilePlaying);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
volumeSlider.addEventListener('click', (event) => {
|
|
212
|
+
event.stopPropagation();
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
seekSlider.addEventListener('click', (event) => {
|
|
216
|
+
event.stopPropagation();
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
volumeSlider.addEventListener('input', (e) => {
|
|
220
|
+
e.stopPropagation();
|
|
221
|
+
const value = e.target.value;
|
|
222
|
+
showRangeProgress(e.target);
|
|
223
|
+
videoEl.volume = value / 100;
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const videoCardElements = document.querySelectorAll('.kg-video-card');
|
|
228
|
+
|
|
229
|
+
for (let i = 0; i < videoCardElements.length; i++) {
|
|
230
|
+
handleVideoPlayer(videoCardElements[i]);
|
|
231
|
+
}
|
|
232
|
+
})();
|
|
@@ -7,7 +7,7 @@ const config = require('../../../shared/config');
|
|
|
7
7
|
const helpers = require('../../services/routing/helpers');
|
|
8
8
|
|
|
9
9
|
// @TODO: make this properly shared code
|
|
10
|
-
const
|
|
10
|
+
const {prepareError} = require('@tryghost/mw-error-handler');
|
|
11
11
|
|
|
12
12
|
const messages = {
|
|
13
13
|
oopsErrorTemplateHasError: 'Oops, seems there is an error in the error template.',
|
|
@@ -85,7 +85,7 @@ const themeErrorRenderer = (err, req, res, next) => {
|
|
|
85
85
|
|
|
86
86
|
module.exports.handleThemeResponse = [
|
|
87
87
|
// Make sure the error can be served
|
|
88
|
-
|
|
88
|
+
prepareError,
|
|
89
89
|
// Handle the error in Sentry
|
|
90
90
|
sentry.errorHandler,
|
|
91
91
|
// Render the error using theme template
|
|
@@ -20,6 +20,7 @@ const offersService = require('../../server/services/offers');
|
|
|
20
20
|
const customRedirects = require('../../server/services/redirects');
|
|
21
21
|
const siteRoutes = require('./routes');
|
|
22
22
|
const shared = require('../../server/web/shared');
|
|
23
|
+
const errorHandler = require('@tryghost/mw-error-handler');
|
|
23
24
|
const mw = require('./middleware');
|
|
24
25
|
const labs = require('../../shared/labs');
|
|
25
26
|
|
|
@@ -176,7 +177,7 @@ module.exports = function setupSiteApp(options = {}) {
|
|
|
176
177
|
siteApp.use(SiteRouter);
|
|
177
178
|
|
|
178
179
|
// ### Error handlers
|
|
179
|
-
siteApp.use(
|
|
180
|
+
siteApp.use(errorHandler.pageNotFound);
|
|
180
181
|
config.get('apps:internal').forEach((appName) => {
|
|
181
182
|
const app = require(path.join(config.get('paths').internalAppPath, appName));
|
|
182
183
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const KnexMigrator = require('knex-migrator');
|
|
2
2
|
const errors = require('@tryghost/errors');
|
|
3
|
+
const logging = require('@tryghost/logging');
|
|
3
4
|
|
|
4
5
|
const states = {
|
|
5
6
|
READY: 0,
|
|
@@ -8,7 +9,7 @@ const states = {
|
|
|
8
9
|
ERROR: 3
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
const printState = ({state
|
|
12
|
+
const printState = ({state}) => {
|
|
12
13
|
if (state === states.READY) {
|
|
13
14
|
logging.info('Database is in a ready state.');
|
|
14
15
|
}
|
|
@@ -67,13 +68,11 @@ class DatabaseStateManager {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
async makeReady(
|
|
71
|
+
async makeReady() {
|
|
71
72
|
try {
|
|
72
73
|
let state = await this.getState();
|
|
73
74
|
|
|
74
|
-
|
|
75
|
-
printState({state, logging});
|
|
76
|
-
}
|
|
75
|
+
printState({state});
|
|
77
76
|
|
|
78
77
|
if (state === states.READY) {
|
|
79
78
|
return;
|
|
@@ -89,9 +88,7 @@ class DatabaseStateManager {
|
|
|
89
88
|
|
|
90
89
|
state = await this.getState();
|
|
91
90
|
|
|
92
|
-
|
|
93
|
-
printState({state, logging});
|
|
94
|
-
}
|
|
91
|
+
printState({state});
|
|
95
92
|
} catch (error) {
|
|
96
93
|
let errorToThrow = error;
|
|
97
94
|
if (!errors.utils.isGhostError(error)) {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
const debug = require('@tryghost/debug')('utils:image-size-cache');
|
|
2
2
|
const errors = require('@tryghost/errors');
|
|
3
|
-
|
|
3
|
+
const logging = require('@tryghost/logging');
|
|
4
4
|
class CachedImageSizeFromUrl {
|
|
5
|
-
constructor({
|
|
6
|
-
this.logging = logging;
|
|
5
|
+
constructor({imageSize}) {
|
|
7
6
|
this.imageSize = imageSize;
|
|
8
7
|
this.cache = new Map();
|
|
9
8
|
}
|
|
@@ -37,7 +36,7 @@ class CachedImageSizeFromUrl {
|
|
|
37
36
|
return this.cache.get(url);
|
|
38
37
|
}).catch((err) => {
|
|
39
38
|
debug('Cached image (error):', url);
|
|
40
|
-
|
|
39
|
+
logging.error(err);
|
|
41
40
|
|
|
42
41
|
// in case of error we just attach the url
|
|
43
42
|
this.cache.set(url, url);
|
|
@@ -4,10 +4,10 @@ const Gravatar = require('./gravatar');
|
|
|
4
4
|
const ImageSize = require('./image-size');
|
|
5
5
|
|
|
6
6
|
class ImageUtils {
|
|
7
|
-
constructor({config,
|
|
7
|
+
constructor({config, urlUtils, settingsCache, storageUtils, storage, validator, request}) {
|
|
8
8
|
this.blogIcon = new BlogIcon({config, urlUtils, settingsCache, storageUtils});
|
|
9
9
|
this.imageSize = new ImageSize({config, storage, storageUtils, validator, urlUtils, request});
|
|
10
|
-
this.cachedImageSizeFromUrl = new CachedImageSizeFromUrl({
|
|
10
|
+
this.cachedImageSizeFromUrl = new CachedImageSizeFromUrl({imageSize: this.imageSize});
|
|
11
11
|
this.gravatar = new Gravatar({config, request});
|
|
12
12
|
}
|
|
13
13
|
}
|
|
@@ -4,8 +4,7 @@ const storage = require('../../adapters/storage');
|
|
|
4
4
|
const storageUtils = require('../../adapters/storage/utils');
|
|
5
5
|
const validator = require('@tryghost/validator');
|
|
6
6
|
const config = require('../../../shared/config');
|
|
7
|
-
const logging = require('@tryghost/logging');
|
|
8
7
|
const settingsCache = require('../../../shared/settings-cache');
|
|
9
8
|
const ImageUtils = require('./image-utils');
|
|
10
9
|
|
|
11
|
-
module.exports = new ImageUtils({config,
|
|
10
|
+
module.exports = new ImageUtils({config, urlUtils, settingsCache, storageUtils, storage, validator, request});
|
|
@@ -31,18 +31,6 @@ if (parentPort) {
|
|
|
31
31
|
(async () => {
|
|
32
32
|
const updateCheck = require('./update-check');
|
|
33
33
|
|
|
34
|
-
const logging = {
|
|
35
|
-
info(message) {
|
|
36
|
-
postParentPortMessage(message);
|
|
37
|
-
},
|
|
38
|
-
warn(message) {
|
|
39
|
-
postParentPortMessage(message);
|
|
40
|
-
},
|
|
41
|
-
error(message) {
|
|
42
|
-
postParentPortMessage(message);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
|
|
46
34
|
// INIT required services
|
|
47
35
|
const models = require('./models');
|
|
48
36
|
models.init();
|
|
@@ -54,7 +42,7 @@ if (parentPort) {
|
|
|
54
42
|
await settings.init();
|
|
55
43
|
// Finished INIT
|
|
56
44
|
|
|
57
|
-
await updateCheck(
|
|
45
|
+
await updateCheck();
|
|
58
46
|
|
|
59
47
|
postParentPortMessage(`Ran update check`);
|
|
60
48
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
const config = require('../../../shared/config');
|
|
2
|
-
const logging = require('@tryghost/logging');
|
|
3
2
|
const db = require('../../data/db');
|
|
4
3
|
const settings = require('../../../shared/settings-cache');
|
|
5
4
|
const {EmailAnalyticsService} = require('@tryghost/email-analytics-service');
|
|
@@ -9,11 +8,10 @@ const queries = require('./lib/queries');
|
|
|
9
8
|
|
|
10
9
|
module.exports = new EmailAnalyticsService({
|
|
11
10
|
config,
|
|
12
|
-
logging,
|
|
13
11
|
settings,
|
|
14
|
-
eventProcessor: new EventProcessor({db
|
|
12
|
+
eventProcessor: new EventProcessor({db}),
|
|
15
13
|
providers: [
|
|
16
|
-
new MailgunProvider({config, settings
|
|
14
|
+
new MailgunProvider({config, settings})
|
|
17
15
|
],
|
|
18
16
|
queries
|
|
19
17
|
});
|
|
@@ -28,24 +28,6 @@ if (parentPort) {
|
|
|
28
28
|
const config = require('../../../../shared/config');
|
|
29
29
|
const db = require('../../../data/db');
|
|
30
30
|
|
|
31
|
-
const logging = {
|
|
32
|
-
info(message) {
|
|
33
|
-
if (parentPort) {
|
|
34
|
-
parentPort.postMessage(message);
|
|
35
|
-
}
|
|
36
|
-
},
|
|
37
|
-
warn(message) {
|
|
38
|
-
if (parentPort) {
|
|
39
|
-
parentPort.postMessage(message);
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
error(message) {
|
|
43
|
-
if (parentPort) {
|
|
44
|
-
parentPort.postMessage(message);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
31
|
const settingsRows = await db.knex('settings')
|
|
50
32
|
.whereIn('key', ['mailgun_api_key', 'mailgun_domain', 'mailgun_base_url']);
|
|
51
33
|
|
|
@@ -69,10 +51,9 @@ if (parentPort) {
|
|
|
69
51
|
const emailAnalyticsService = new EmailAnalyticsService({
|
|
70
52
|
config,
|
|
71
53
|
settings,
|
|
72
|
-
|
|
73
|
-
eventProcessor: new EventProcessor({db, logging}),
|
|
54
|
+
eventProcessor: new EventProcessor({db}),
|
|
74
55
|
providers: [
|
|
75
|
-
new MailgunProvider({config, settings
|
|
56
|
+
new MailgunProvider({config, settings})
|
|
76
57
|
],
|
|
77
58
|
queries
|
|
78
59
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const {NotFoundError,
|
|
1
|
+
const {NotFoundError, InternalServerError} = require('@tryghost/errors');
|
|
2
2
|
const tpl = require('@tryghost/tpl');
|
|
3
3
|
|
|
4
4
|
const messages = {
|
|
@@ -29,7 +29,7 @@ class IntegrationsService {
|
|
|
29
29
|
withRelated: ['api_keys', 'webhooks']
|
|
30
30
|
});
|
|
31
31
|
} catch (err) {
|
|
32
|
-
throw new
|
|
32
|
+
throw new InternalServerError({
|
|
33
33
|
err: err
|
|
34
34
|
});
|
|
35
35
|
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
const settingsCache = require('../../../shared/settings-cache');
|
|
2
2
|
const mailService = require('../../services/mail');
|
|
3
|
-
const logging = require('@tryghost/logging');
|
|
4
3
|
const urlUtils = require('../../../shared/url-utils');
|
|
5
4
|
const Invites = require('./invites');
|
|
6
5
|
|
|
7
6
|
module.exports = new Invites({
|
|
8
7
|
settingsCache,
|
|
9
|
-
logging,
|
|
10
8
|
mailService,
|
|
11
9
|
urlUtils
|
|
12
10
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
const security = require('@tryghost/security');
|
|
2
2
|
const tpl = require('@tryghost/tpl');
|
|
3
|
+
const logging = require('@tryghost/logging');
|
|
3
4
|
|
|
4
5
|
const messages = {
|
|
5
6
|
invitedByName: '{invitedByName} has invited you to join {blogName}',
|
|
@@ -10,9 +11,8 @@ const messages = {
|
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
class Invites {
|
|
13
|
-
constructor({settingsCache,
|
|
14
|
+
constructor({settingsCache, mailService, urlUtils}) {
|
|
14
15
|
this.settingsCache = settingsCache;
|
|
15
|
-
this.logging = logging;
|
|
16
16
|
this.mailService = mailService;
|
|
17
17
|
this.urlUtils = urlUtils;
|
|
18
18
|
}
|
|
@@ -80,7 +80,7 @@ class Invites {
|
|
|
80
80
|
});
|
|
81
81
|
const helpText = tpl(messages.errorSendingEmail.help);
|
|
82
82
|
err.message = `${errorMessage} ${helpText}`;
|
|
83
|
-
|
|
83
|
+
logging.warn(err.message);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
return Promise.reject(err);
|
|
@@ -17,6 +17,6 @@ const workerMessageHandler = ({name, message}) => {
|
|
|
17
17
|
logging.info(`Worker for job ${name} sent a message: ${message}`);
|
|
18
18
|
};
|
|
19
19
|
|
|
20
|
-
const jobManager = new JobManager({
|
|
20
|
+
const jobManager = new JobManager({errorHandler, workerMessageHandler});
|
|
21
21
|
|
|
22
22
|
module.exports = jobManager;
|
|
@@ -240,7 +240,9 @@ const serialize = async (postModel, options = {isBrowserPreview: false, apiVersi
|
|
|
240
240
|
post.excerpt = post.excerpt.replace(/\s\[http(.*?)\]/g, '');
|
|
241
241
|
}
|
|
242
242
|
|
|
243
|
-
post.html = mobiledocLib.mobiledocHtmlRenderer.render(
|
|
243
|
+
post.html = mobiledocLib.mobiledocHtmlRenderer.render(
|
|
244
|
+
JSON.parse(post.mobiledoc), {target: 'email', postUrl: post.url}
|
|
245
|
+
);
|
|
244
246
|
|
|
245
247
|
// perform any email specific adjustments to the mobiledoc->HTML render output
|
|
246
248
|
// body wrapper is required so we can get proper top-level selections
|
|
@@ -74,8 +74,8 @@ table td {
|
|
|
74
74
|
max-width: 600px;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
.content a {
|
|
78
|
-
overflow-wrap: anywhere;
|
|
77
|
+
.content a {
|
|
78
|
+
overflow-wrap: anywhere;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
/* -------------------------------------
|
|
@@ -554,28 +554,32 @@ figure blockquote p {
|
|
|
554
554
|
}
|
|
555
555
|
|
|
556
556
|
.kg-nft-link {
|
|
557
|
-
display: block;
|
|
558
|
-
text-decoration: none !important;
|
|
559
|
-
color: #15212A !important;
|
|
557
|
+
display: block;
|
|
558
|
+
text-decoration: none !important;
|
|
559
|
+
color: #15212A !important;
|
|
560
560
|
font-family: inherit !important;
|
|
561
561
|
font-size: 14px;
|
|
562
562
|
line-height: 1.3em;
|
|
563
|
-
padding-top: 4px;
|
|
564
|
-
padding-right: 20px;
|
|
565
|
-
padding-left: 20px;
|
|
563
|
+
padding-top: 4px;
|
|
564
|
+
padding-right: 20px;
|
|
565
|
+
padding-left: 20px;
|
|
566
566
|
padding-bottom: 4px;
|
|
567
567
|
}
|
|
568
568
|
|
|
569
569
|
.kg-twitter-link {
|
|
570
|
-
display: block;
|
|
571
|
-
text-decoration: none !important;
|
|
572
|
-
color: #15212A !important;
|
|
570
|
+
display: block;
|
|
571
|
+
text-decoration: none !important;
|
|
572
|
+
color: #15212A !important;
|
|
573
573
|
font-family: inherit !important;
|
|
574
574
|
font-size: 15px;
|
|
575
575
|
padding: 8px;
|
|
576
576
|
line-height: 1.3em;
|
|
577
577
|
}
|
|
578
578
|
|
|
579
|
+
.kg-audio-thumbnail.placeholder {
|
|
580
|
+
background: ${templateSettings.accentColor || '#15212A'} !important;
|
|
581
|
+
}
|
|
582
|
+
|
|
579
583
|
.kg-callout-card {
|
|
580
584
|
display: flex;
|
|
581
585
|
margin: 0 0 1.5em 0;
|