ghost 4.27.2 → 4.30.1

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.
Files changed (67) hide show
  1. package/content/themes/casper/assets/built/screen.css +1 -1
  2. package/content/themes/casper/assets/built/screen.css.map +1 -1
  3. package/content/themes/casper/assets/css/screen.css +41 -44
  4. package/content/themes/casper/package.json +1 -1
  5. package/content/themes/casper/partials/post-card.hbs +1 -1
  6. package/core/boot.js +3 -5
  7. package/core/built/assets/{ghost-dark-485081d359d3ce1412ccd09a8f5b83d9.css → ghost-dark-1594d07a0716e0253a78234c8e42d765.css} +1 -1
  8. package/core/built/assets/{ghost.min-3224fe43ca0ca4d6184f579d165ad801.js → ghost.min-884660873d56fcc3d2a3b9fe94c9f022.js} +76 -76
  9. package/core/built/assets/{ghost.min-e272e8cd67577087cee1c853694e2852.css → ghost.min-c21fea11c3f431994a8ee7c47a8ed145.css} +1 -1
  10. package/core/built/assets/icons/file-download.svg +1 -0
  11. package/core/built/assets/icons/file-upload.svg +1 -0
  12. package/core/built/assets/{vendor.min-08ca94a205555a22db64e8d595062c63.js → vendor.min-a2fd1e62ce6da8911fee8e812d8c6ceb.js} +147 -94
  13. package/core/frontend/apps/amp/lib/views/amp.hbs +94 -2
  14. package/core/frontend/services/theme-engine/i18n/i18n.js +11 -12
  15. package/core/frontend/services/theme-engine/i18n/index.js +1 -2
  16. package/core/frontend/services/theme-engine/i18n/theme-i18n.js +5 -4
  17. package/core/frontend/src/cards/css/audio.css +69 -32
  18. package/core/frontend/src/cards/css/before-after.css +47 -0
  19. package/core/frontend/src/cards/css/bookmark.css +6 -5
  20. package/core/frontend/src/cards/css/button.css +4 -3
  21. package/core/frontend/src/cards/css/callout.css +4 -4
  22. package/core/frontend/src/cards/css/file.css +126 -0
  23. package/core/frontend/src/cards/css/nft.css +3 -8
  24. package/core/frontend/src/cards/css/product.css +79 -58
  25. package/core/frontend/src/cards/css/toggle.css +31 -22
  26. package/core/frontend/src/cards/css/video.css +336 -0
  27. package/core/frontend/src/cards/js/audio.js +1 -1
  28. package/core/frontend/src/cards/js/before-after.js +41 -0
  29. package/core/frontend/src/cards/js/video.js +232 -0
  30. package/core/frontend/web/middleware/error-handler.js +2 -2
  31. package/core/frontend/web/site.js +2 -1
  32. package/core/server/api/canary/oembed.js +1 -2
  33. package/core/server/data/db/state-manager.js +5 -8
  34. package/core/server/lib/image/cached-image-size-from-url.js +3 -4
  35. package/core/server/lib/image/image-utils.js +2 -2
  36. package/core/server/lib/image/index.js +1 -2
  37. package/core/server/run-update-check.js +1 -13
  38. package/core/server/services/email-analytics/index.js +2 -4
  39. package/core/server/services/email-analytics/jobs/fetch-latest.js +2 -21
  40. package/core/server/services/integrations/integrations-service.js +2 -2
  41. package/core/server/services/invites/index.js +0 -2
  42. package/core/server/services/invites/invites.js +3 -3
  43. package/core/server/services/jobs/job-service.js +1 -1
  44. package/core/server/services/mega/template.js +15 -11
  45. package/core/server/services/members/api.js +0 -1
  46. package/core/server/services/members/config.js +4 -7
  47. package/core/server/services/members/service.js +1 -4
  48. package/core/server/services/notifications/index.js +0 -2
  49. package/core/server/services/notifications/notifications.js +4 -5
  50. package/core/server/services/stripe/index.js +0 -2
  51. package/core/server/services/twitter-embed.js +2 -1
  52. package/core/server/web/admin/app.js +4 -2
  53. package/core/server/web/admin/views/default-prod.html +4 -4
  54. package/core/server/web/admin/views/default.html +4 -4
  55. package/core/server/web/api/app.js +3 -2
  56. package/core/server/web/api/canary/admin/app.js +4 -2
  57. package/core/server/web/api/canary/content/app.js +4 -2
  58. package/core/server/web/api/v2/admin/app.js +4 -2
  59. package/core/server/web/api/v2/content/app.js +4 -2
  60. package/core/server/web/api/v3/admin/app.js +4 -2
  61. package/core/server/web/api/v3/content/app.js +4 -2
  62. package/core/server/web/members/app.js +6 -4
  63. package/core/server/web/shared/middleware/index.js +0 -4
  64. package/core/shared/labs.js +7 -7
  65. package/package.json +22 -20
  66. package/yarn.lock +205 -126
  67. package/core/server/web/shared/middleware/error-handler.js +0 -224
@@ -1,4 +1,340 @@
1
+
2
+ .kg-video-card {
3
+ position: relative;
4
+ --seek-before-width: 0%;
5
+ --volume-before-width: 100%;
6
+ --buffered-width: 0%;
7
+ }
8
+
1
9
  .kg-video-card video {
10
+ display: block;
2
11
  max-width: 100%;
3
12
  height: auto;
4
13
  }
14
+
15
+ .kg-video-container {
16
+ position: relative;
17
+ display: flex;
18
+ flex-direction: column;
19
+ align-items: center;
20
+ }
21
+
22
+ .kg-video-overlay {
23
+ position: absolute;
24
+ top: 0;
25
+ right: 0;
26
+ bottom: 0;
27
+ left: 0;
28
+ display: flex;
29
+ justify-content: center;
30
+ align-items: center;
31
+ background-image: linear-gradient(180deg,rgba(0,0,0,0.3) 0,transparent 70%,transparent 100%);
32
+ z-index: 999;
33
+ transition: opacity .2s ease-in-out;
34
+ }
35
+
36
+ .kg-video-large-play-icon {
37
+ display: flex;
38
+ justify-content: center;
39
+ align-items: center;
40
+ width: 72px;
41
+ height: 72px;
42
+ padding: 0;
43
+ background: rgba(0, 0, 0, 0.5);
44
+ border-radius: 50%;
45
+ transition: opacity .2s ease-in-out;
46
+ }
47
+
48
+ .kg-video-large-play-icon svg {
49
+ width: 20px;
50
+ height: auto;
51
+ margin-left: 2px;
52
+ fill: #fff;
53
+ }
54
+
55
+ .kg-video-player-container {
56
+ position: absolute;
57
+ bottom: 0;
58
+ width: 100%;
59
+ height: 80px;
60
+ background: linear-gradient(rgba(0,0,0,0), rgba(0,0,0,.5));
61
+ z-index: 999;
62
+ transition: opacity .2s ease-in-out;
63
+
64
+ }
65
+
66
+ .kg-video-player {
67
+ position: absolute;
68
+ bottom: 0;
69
+ display: flex;
70
+ align-items: center;
71
+ width: 100%;
72
+ z-index: 9999;
73
+ padding: 12px 16px;
74
+ }
75
+
76
+ .kg-video-current-time {
77
+ min-width: 38px;
78
+ padding: 0 4px;
79
+ color: #fff;
80
+ font-family: inherit;
81
+ font-size: .85em;
82
+ font-weight: 500;
83
+ line-height: 1.4em;
84
+ white-space: nowrap;
85
+ }
86
+
87
+ .kg-video-time {
88
+ color: rgba(255, 255, 255, 0.6);
89
+ font-family: inherit;
90
+ font-size: .85em;
91
+ font-weight: 500;
92
+ line-height: 1.4em;
93
+ white-space: nowrap;
94
+ }
95
+
96
+ .kg-video-duration {
97
+ padding: 0 4px;
98
+ }
99
+
100
+ .kg-video-play-icon,
101
+ .kg-video-pause-icon {
102
+ position: relative;
103
+ padding: 0px 4px 0 0;
104
+ font-size: 0;
105
+ background: transparent;
106
+ }
107
+
108
+ .kg-video-hide {
109
+ display: none !important;
110
+ }
111
+
112
+ .kg-video-hide-animated {
113
+ opacity: 0 !important;
114
+ transition: opacity .2s ease-in-out;
115
+ cursor: initial;
116
+ }
117
+
118
+ .kg-video-play-icon svg,
119
+ .kg-video-pause-icon svg {
120
+ width: 14px;
121
+ height: 14px;
122
+ fill: #fff;
123
+ }
124
+
125
+ .kg-video-seek-slider {
126
+ flex-grow: 1;
127
+ margin: 0 4px;
128
+ }
129
+
130
+ @media (max-width: 520px) {
131
+ .kg-video-seek-slider {
132
+ display: none;
133
+ }
134
+ }
135
+
136
+ .kg-video-playback-rate {
137
+ min-width: 37px;
138
+ padding: 0 4px;
139
+ color: #fff;
140
+ font-family: inherit;
141
+ font-size: .85em;
142
+ font-weight: 600;
143
+ line-height: 1.4em;
144
+ text-align: left;
145
+ background: transparent;
146
+ white-space: nowrap;
147
+ }
148
+
149
+ @media (max-width: 520px) {
150
+ .kg-video-playback-rate {
151
+ padding-left: 8px;
152
+ }
153
+ }
154
+
155
+ .kg-video-mute-icon,
156
+ .kg-video-unmute-icon {
157
+ position: relative;
158
+ bottom: -1px;
159
+ padding: 0 4px;
160
+ font-size: 0;
161
+ background: transparent;
162
+ }
163
+
164
+ @media (max-width: 520px) {
165
+ .kg-video-mute-icon,
166
+ .kg-video-unmute-icon {
167
+ margin-left: auto;
168
+ }
169
+ }
170
+
171
+ .kg-video-mute-icon svg,
172
+ .kg-video-unmute-icon svg {
173
+ width: 16px;
174
+ height: 16px;
175
+ fill: #fff;
176
+ }
177
+
178
+ .kg-video-volume-slider {
179
+ width: 80px;
180
+ }
181
+
182
+ @media (max-width: 300px) {
183
+ .kg-video-volume-slider {
184
+ display: none;
185
+ }
186
+ }
187
+
188
+ .kg-video-seek-slider::before {
189
+ content: "";
190
+ position: absolute;
191
+ left: 0;
192
+ width: var(--seek-before-width) !important;
193
+ height: 4px;
194
+ cursor: pointer;
195
+ background-color: #EBEEF0;
196
+ border-radius: 2px;
197
+ }
198
+
199
+ .kg-video-volume-slider::before {
200
+ content: "";
201
+ position: absolute;
202
+ left: 0;
203
+ width: var(--volume-before-width) !important;
204
+ height: 4px;
205
+ cursor: pointer;
206
+ background-color: #EBEEF0;
207
+ border-radius: 2px;
208
+ }
209
+
210
+ /* Resetting browser styles
211
+ /* --------------------------------------------------------------- */
212
+
213
+ .kg-video-card input[type=range] {
214
+ position: relative;
215
+ -webkit-appearance: none;
216
+ background: transparent;
217
+ }
218
+
219
+ .kg-video-card input[type=range]:focus {
220
+ outline: none;
221
+ }
222
+
223
+ .kg-video-card input[type=range]::-webkit-slider-thumb {
224
+ -webkit-appearance: none;
225
+ }
226
+
227
+ .kg-video-card input[type=range]::-ms-track {
228
+ cursor: pointer;
229
+ border-color: transparent;
230
+ color: transparent;
231
+ background: transparent;
232
+ }
233
+
234
+ .kg-video-card button {
235
+ display: flex;
236
+ align-items: center;
237
+ border: 0;
238
+ cursor: pointer;
239
+ }
240
+
241
+ .kg-video-card input[type="range"] {
242
+ height: auto;
243
+ padding: 0;
244
+ border: 0;
245
+ }
246
+
247
+ /* Chrome & Safari styles
248
+ /* --------------------------------------------------------------- */
249
+
250
+ .kg-video-card input[type="range"]::-webkit-slider-runnable-track {
251
+ width: 100%;
252
+ height: 4px;
253
+ cursor: pointer;
254
+ background: rgba(255, 255, 255, 0.2);
255
+ border-radius: 2px;
256
+ }
257
+
258
+ .kg-video-card input[type="range"]::-webkit-slider-thumb {
259
+ position: relative;
260
+ box-sizing: content-box;
261
+ width: 13px;
262
+ height: 13px;
263
+ margin: -5px 0 0 0;
264
+ border: 0;
265
+ cursor: pointer;
266
+ background: #fff;
267
+ border-radius: 50%;
268
+ box-shadow: 0 0 0 1px rgba(0,0,0,.08), 0 1px 4px rgba(0,0,0,0.24);
269
+ }
270
+
271
+ .kg-video-card input[type="range"]:active::-webkit-slider-thumb {
272
+ transform: scale(1.2);
273
+ }
274
+
275
+ /* Firefox styles
276
+ /* --------------------------------------------------------------- */
277
+
278
+ .kg-video-card input[type="range"]::-moz-range-track {
279
+ width: 100%;
280
+ height: 4px;
281
+ cursor: pointer;
282
+ background: rgba(255, 255, 255, 0.2);
283
+ border-radius: 2px;
284
+ }
285
+
286
+ .kg-video-card input[type="range"]::-moz-range-progress {
287
+ background: #EBEEF0;
288
+ border-radius: 2px;
289
+ }
290
+
291
+ .kg-video-card input[type="range"]::-moz-range-thumb {
292
+ box-sizing: content-box;
293
+ width: 13px;
294
+ height: 13px;
295
+ border: 0;
296
+ cursor: pointer;
297
+ background: #fff;
298
+ border-radius: 50%;
299
+ box-shadow: 0 0 0 1px rgba(0,0,0,.08), 0 1px 4px rgba(0,0,0,0.24);
300
+ }
301
+
302
+ .kg-video-card input[type="range"]:active::-moz-range-thumb {
303
+ transform: scale(1.2);
304
+ }
305
+
306
+ /* Edge & IE styles
307
+ /* --------------------------------------------------------------- */
308
+
309
+ .kg-video-card input[type="range"]::-ms-track {
310
+ width: 100%;
311
+ height: 3px;
312
+ border: solid transparent;
313
+ color: transparent;
314
+ cursor: pointer;
315
+ background: transparent;
316
+ }
317
+
318
+ .kg-video-card input[type="range"]::-ms-fill-lower {
319
+ background: #fff;
320
+ }
321
+
322
+ .kg-video-card input[type="range"]::-ms-fill-upper {
323
+ background: #EBEEF0;
324
+ }
325
+
326
+ .kg-video-card input[type="range"]::-ms-thumb {
327
+ box-sizing: content-box;
328
+ width: 13px;
329
+ height: 13px;
330
+ border: 0;
331
+ cursor: pointer;
332
+ background: #fff;
333
+ border-radius: 50%;
334
+ box-shadow: 0 0 0 1px rgba(0,0,0,.08), 0 1px 4px rgba(0,0,0,0.24);
335
+ }
336
+
337
+ .kg-video-card input[type="range"]:active::-ms-thumb {
338
+ transform: scale(1.2);
339
+ }
340
+
@@ -1,6 +1,6 @@
1
1
  (function() {
2
2
  const handleAudioPlayer = function (audioElementContainer) {
3
- const audioPlayerContainer = audioElementContainer.querySelector('.kg-player-container');
3
+ const audioPlayerContainer = audioElementContainer.querySelector('.kg-audio-player-container');
4
4
  const playIconContainer = audioElementContainer.querySelector('.kg-audio-play-icon');
5
5
  const pauseIconContainer = audioElementContainer.querySelector('.kg-audio-pause-icon');
6
6
  const seekSlider = audioElementContainer.querySelector('.kg-audio-seek-slider');
@@ -0,0 +1,41 @@
1
+ (function () {
2
+ const beforeAfterCards = [...document.querySelectorAll('.kg-before-after-card')];
3
+
4
+ for (let card of beforeAfterCards) {
5
+ const isFullWidth = card.classList.contains('kg-width-full');
6
+ const input = card.querySelector('input');
7
+ const overlay = card.querySelector('.kg-before-after-card-image-before');
8
+ const orientation = card.querySelector('div').getAttribute('data-orientation');
9
+ const images = [...card.querySelectorAll('img')];
10
+ const smallestImageWidth = Math.min(
11
+ ...images.map(img => parseInt(img.getAttribute('width')))
12
+ );
13
+
14
+ function updateSlider() {
15
+ if (orientation === 'vertical') {
16
+ overlay.setAttribute('style', `height: ${input.value}%`);
17
+ } else {
18
+ overlay.setAttribute('style', `width: ${input.value}%`);
19
+ }
20
+ }
21
+
22
+ function updateDimensions() {
23
+ const containerWidth = parseInt(getComputedStyle(card).getPropertyValue('width'));
24
+ const width = isFullWidth ? containerWidth : Math.min(smallestImageWidth, containerWidth);
25
+ for (let image of images) {
26
+ image.setAttribute('style', `width: ${width.toString()}px;`);
27
+ }
28
+ }
29
+
30
+ input.addEventListener('input', function () {
31
+ updateSlider();
32
+ });
33
+
34
+ window.addEventListener('resize', function () {
35
+ updateDimensions();
36
+ });
37
+
38
+ updateDimensions();
39
+ updateSlider();
40
+ }
41
+ })();
@@ -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 shared = require('../../../server/web/shared/middleware/error-handler');
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
- shared.prepareError,
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(shared.middleware.errorHandler.pageNotFound);
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
 
@@ -15,8 +15,7 @@ const Twitter = require('../../services/twitter-embed');
15
15
  const twitter = new Twitter({
16
16
  config: {
17
17
  bearerToken: config.get('twitter').privateReadOnlyToken
18
- },
19
- logging: require('@tryghost/logging')
18
+ }
20
19
  });
21
20
 
22
21
  oembed.registerProvider(nft);