|
1 <?php |
|
2 /* |
|
3 Plugin Name: Include Mastodon Feed |
|
4 Plugin URI: https://wolfgang.lol/code/include-mastodon-feed-wordpress-plugin |
|
5 Description: Plugin providing [include-mastodon-feed] shortcode |
|
6 Version: 1.9.4 |
|
7 Author: wolfgang.lol |
|
8 Author URI: https://wolfgang.lol |
|
9 */ |
|
10 |
|
11 namespace IncludeMastodonFeedPlugin; |
|
12 |
|
13 // set defaults |
|
14 $constants = [ |
|
15 [ |
|
16 'key' => 'INCLUDE_MASTODON_FEED_DEBUG', |
|
17 'value' => false, |
|
18 ], |
|
19 [ |
|
20 'key' => 'INCLUDE_MASTODON_FEED_DEFAULT_INSTANCE', |
|
21 'value' => false, |
|
22 ], |
|
23 [ |
|
24 'key' => 'INCLUDE_MASTODON_FEED_LIMIT', |
|
25 'value' => 20, |
|
26 ], |
|
27 [ |
|
28 'key' => 'INCLUDE_MASTODON_FEED_EXCLUDE_BOOSTS', |
|
29 'value' => false, |
|
30 ], |
|
31 [ |
|
32 'key' => 'INCLUDE_MASTODON_FEED_EXCLUDE_REPLIES', |
|
33 'value' => false, |
|
34 ], |
|
35 [ |
|
36 'key' => 'INCLUDE_MASTODON_FEED_EXCLUDE_CONVERSATIONSTARTERS', |
|
37 'value' => false, |
|
38 ], |
|
39 [ |
|
40 'key' => 'INCLUDE_MASTODON_FEED_ONLY_PINNED', |
|
41 'value' => false, |
|
42 ], |
|
43 [ |
|
44 'key' => 'INCLUDE_MASTODON_FEED_ONLY_MEDIA', |
|
45 'value' => false, |
|
46 ], |
|
47 [ |
|
48 'key' => 'INCLUDE_MASTODON_FEED_PRESERVE_IMAGE_ASPECT_RATIO', |
|
49 'value' => false, |
|
50 ], |
|
51 [ |
|
52 'key' => 'INCLUDE_MASTODON_FEED_TAGGED', |
|
53 'value' => false, |
|
54 ], |
|
55 [ |
|
56 'key' => 'INCLUDE_MASTODON_FEED_LINKTARGET', |
|
57 'value' => '_self', |
|
58 ], |
|
59 [ |
|
60 'key' => 'INCLUDE_MASTODON_FEED_SHOW_PREVIEWCARDS', |
|
61 'value' => true, |
|
62 ], |
|
63 |
|
64 // set styles |
|
65 [ |
|
66 'key' => 'INCLUDE_MASTODON_FEED_DARKMODE', |
|
67 'value' => false, |
|
68 ], |
|
69 [ |
|
70 'key' => 'INCLUDE_MASTODON_FEED_STYLE_BG_LIGHT_COLOR', |
|
71 'value' => 'rgba(100, 100, 100, 0.15)', |
|
72 ], |
|
73 [ |
|
74 'key' => 'INCLUDE_MASTODON_FEED_STYLE_BG_DARK_COLOR', |
|
75 'value' => 'rgba(155, 155, 155, 0.15)', |
|
76 ], |
|
77 [ |
|
78 'key' => 'INCLUDE_MASTODON_FEED_STYLE_ACCENT_COLOR', |
|
79 'value' => 'rgb(99, 100, 255)', |
|
80 ], |
|
81 [ |
|
82 'key' => 'INCLUDE_MASTODON_FEED_STYLE_ACCENT_FONT_COLOR', |
|
83 'value' => 'rgb(255, 255, 255)', |
|
84 ], |
|
85 [ |
|
86 'key' => 'INCLUDE_MASTODON_FEED_STYLE_BORDER_RADIUS', |
|
87 'value' => '0.25rem', |
|
88 ], |
|
89 [ |
|
90 'key' => 'INCLUDE_MASTODON_FEED_HIDE_STATUS_META', |
|
91 'value' => false, |
|
92 ], |
|
93 [ |
|
94 'key' => 'INCLUDE_MASTODON_FEED_HIDE_DATETIME', |
|
95 'value' => false, |
|
96 ], |
|
97 // set texts and localization |
|
98 [ |
|
99 'key' => 'INCLUDE_MASTODON_FEED_TEXT_LOADING', |
|
100 'value' => 'Loading Mastodon feed...', |
|
101 ], |
|
102 [ |
|
103 'key' => 'INCLUDE_MASTODON_FEED_TEXT_NO_STATUSES', |
|
104 'value' => 'No statuses availablae', |
|
105 ], |
|
106 [ |
|
107 'key' => 'INCLUDE_MASTODON_FEED_TEXT_BOOSTED', |
|
108 'value' => 'boosted 🚀', |
|
109 ], |
|
110 [ |
|
111 'key' => 'INCLUDE_MASTODON_FEED_TEXT_VIEW_ON_INSTANCE', |
|
112 'value' => 'view on instance', |
|
113 ], |
|
114 [ |
|
115 'key' => 'INCLUDE_MASTODON_FEED_TEXT_SHOW_CONTENT', |
|
116 'value' => 'Show content', |
|
117 ], |
|
118 [ |
|
119 'key' => 'INCLUDE_MASTODON_FEED_TEXT_PERMALINK_PRE', |
|
120 'value' => 'on', |
|
121 ], |
|
122 [ |
|
123 'key' => 'INCLUDE_MASTODON_FEED_TEXT_PERMALINK_POST', |
|
124 'value' => '', |
|
125 ], |
|
126 [ |
|
127 'key' => 'INCLUDE_MASTODON_FEED_TEXT_EDITED', |
|
128 'value' => '(edited)', |
|
129 ], |
|
130 [ |
|
131 'key' => 'INCLUDE_MASTODON_FEED_DATE_LOCALE', |
|
132 'value' => 'en-US', |
|
133 ], |
|
134 [ |
|
135 'key' => 'INCLUDE_MASTODON_FEED_DATE_OPTIONS', |
|
136 'value' => "{}", |
|
137 ], |
|
138 ]; |
|
139 foreach($constants as $constant) { |
|
140 if(!defined($constant['key'])) { |
|
141 define($constant['key'], $constant['value']); |
|
142 } |
|
143 } |
|
144 unset($constants); |
|
145 |
|
146 function error($msg) { |
|
147 return '[include-mastodon-feed] ' . $msg; |
|
148 } |
|
149 |
|
150 |
|
151 function init_styles() { |
|
152 ob_start(); |
|
153 ?> |
|
154 <style> |
|
155 :root { |
|
156 --include-mastodon-feed-bg-light: <?php echo filter_var( INCLUDE_MASTODON_FEED_STYLE_BG_LIGHT_COLOR, FILTER_UNSAFE_RAW ); ?>; |
|
157 --include-mastodon-feed-bg-dark: <?php echo filter_var( INCLUDE_MASTODON_FEED_STYLE_BG_DARK_COLOR, FILTER_UNSAFE_RAW ); ?>; |
|
158 --include-mastodon-feed-accent-color: <?php echo filter_var( INCLUDE_MASTODON_FEED_STYLE_ACCENT_COLOR, FILTER_UNSAFE_RAW ); ?>; |
|
159 --include-mastodon-feed-accent-font-color: <?php echo filter_var( INCLUDE_MASTODON_FEED_STYLE_ACCENT_FONT_COLOR, FILTER_UNSAFE_RAW ); ?>; |
|
160 --include-mastodon-feed-border-radius: <?php echo filter_var( INCLUDE_MASTODON_FEED_STYLE_BORDER_RADIUS, FILTER_UNSAFE_RAW ); ?>; |
|
161 } |
|
162 |
|
163 .include-mastodon-feed .status { |
|
164 margin: 0.5rem 0 1.5rem; |
|
165 border-radius: var(--include-mastodon-feed-border-radius); |
|
166 padding: 0.5rem; |
|
167 background: var(--include-mastodon-feed-bg-light); |
|
168 } |
|
169 .include-mastodon-feed .status a { |
|
170 color: var(--include-mastodon-feed-accent-color); |
|
171 text-decoration: none; |
|
172 word-wrap: break-word; |
|
173 } |
|
174 .include-mastodon-feed .status a:hover { |
|
175 text-decoration: underline; |
|
176 } |
|
177 .include-mastodon-feed .avatar { |
|
178 height: 1.25rem; |
|
179 border-radius: var(--include-mastodon-feed-border-radius); |
|
180 vertical-align: top; |
|
181 } |
|
182 .include-mastodon-feed .account { |
|
183 font-size: 0.8rem; |
|
184 } |
|
185 .include-mastodon-feed .account a { |
|
186 display: inline-block; |
|
187 } |
|
188 .include-mastodon-feed .account .booster { |
|
189 float: right; |
|
190 font-style: italic; |
|
191 } |
|
192 .include-mastodon-feed .boosted .account > a:first-child, |
|
193 .include-mastodon-feed .contentWarning a { |
|
194 border-radius: var(--include-mastodon-feed-border-radius); |
|
195 padding: 0.15rem 0.5rem; |
|
196 background: var(--include-mastodon-feed-accent-color); |
|
197 color: var(--include-mastodon-feed-accent-font-color); |
|
198 } |
|
199 .include-mastodon-feed .boosted .account > a:first-child:hover, |
|
200 .include-mastodon-feed .contentWarning a:hover { |
|
201 border-radius: var(--include-mastodon-feed-border-radius); |
|
202 padding: 0.15rem 0.5rem; |
|
203 background: var(--include-mastodon-feed-accent-font-color); |
|
204 color: var(--include-mastodon-feed-accent-color); |
|
205 text-decoration: none; |
|
206 } |
|
207 .include-mastodon-feed .contentWrapper.boosted { |
|
208 margin: 0.5rem 0; |
|
209 padding: 0.5rem; |
|
210 background: var(--include-mastodon-feed-bg-light); |
|
211 } |
|
212 .include-mastodon-feed .contentWarning { |
|
213 text-align: center; |
|
214 margin: 1rem; |
|
215 padding: 1rem; |
|
216 } |
|
217 .include-mastodon-feed .contentWarning .title { |
|
218 font-weight: bold; |
|
219 } |
|
220 .include-mastodon-feed img.emoji { |
|
221 height: 1rem; |
|
222 } |
|
223 .include-mastodon-feed .content .invisible { |
|
224 display: none; |
|
225 } |
|
226 .include-mastodon-feed .media { |
|
227 display: flex; |
|
228 justify-content: space-around; |
|
229 align-items: center; |
|
230 flex-wrap: wrap; |
|
231 gap: 0.5rem; |
|
232 margin: 1rem; |
|
233 } |
|
234 .include-mastodon-feed .media > div { |
|
235 flex-basis: calc(50% - 0.5rem); |
|
236 flex-grow: 1; |
|
237 } |
|
238 .include-mastodon-feed .media > .image { |
|
239 font-size: 0.8rem; |
|
240 font-weight: bold; |
|
241 text-align: center; |
|
242 } |
|
243 .include-mastodon-feed .media > .image a { |
|
244 border-radius: var(--include-mastodon-feed-border-radius); |
|
245 display: block; |
|
246 aspect-ratio: 1.618; |
|
247 background-size: cover; |
|
248 background-position: center; |
|
249 } |
|
250 .include-mastodon-feed .media > .image a:hover { |
|
251 filter: contrast(110%) brightness(130%) saturate(130%); |
|
252 } |
|
253 .include-mastodon-feed .media > .image a img { |
|
254 width: 100%; |
|
255 } |
|
256 .include-mastodon-feed .media > .gifv video { |
|
257 max-width: 100%; |
|
258 } |
|
259 |
|
260 .include-mastodon-feed .card { |
|
261 border-radius: var(--include-mastodon-feed-border-radius); |
|
262 margin: 1rem 0.5rem; |
|
263 } |
|
264 .include-mastodon-feed .card iframe { |
|
265 border-radius: var(--include-mastodon-feed-border-radius); |
|
266 width: 100%; |
|
267 height: 100%; |
|
268 aspect-ratio: 2 / 1.25; |
|
269 } |
|
270 .include-mastodon-feed .card a { |
|
271 border-radius: var(--include-mastodon-feed-border-radius); |
|
272 display: block; |
|
273 text-decoration: none; |
|
274 color: #000; |
|
275 } |
|
276 .include-mastodon-feed.dark .card a { |
|
277 color: #fff; |
|
278 } |
|
279 .include-mastodon-feed .card a:hover { |
|
280 text-decoration: none; |
|
281 background: var(--include-mastodon-feed-accent-color); |
|
282 color: var(--include-mastodon-feed-accent-font-color); |
|
283 } |
|
284 .include-mastodon-feed .card .meta { |
|
285 background: var(--include-mastodon-feed-bg-light); |
|
286 font-size: 0.8rem; |
|
287 padding: 1rem; |
|
288 } |
|
289 .include-mastodon-feed .card .image { |
|
290 margin-bottom: 0.5rem; |
|
291 text-align: center; |
|
292 } |
|
293 .include-mastodon-feed .card .image img { |
|
294 max-width: 75%; |
|
295 } |
|
296 .include-mastodon-feed .card .title { |
|
297 font-weight: bold; |
|
298 } |
|
299 .include-mastodon-feed.dark .status, |
|
300 .include-mastodon-feed.dark .contentWrapper.boosted, |
|
301 .include-mastodon-feed.dark .card { |
|
302 background: var(--include-mastodon-feed-bg-dark); |
|
303 } |
|
304 </style> |
|
305 <?php |
|
306 echo ob_get_clean(); |
|
307 } |
|
308 add_action('wp_head', __NAMESPACE__ . '\init_styles', 7); |
|
309 |
|
310 function init_scripts() { |
|
311 ob_start(); |
|
312 ?> |
|
313 <script> |
|
314 |
|
315 const mastodonFeedCreateElement = function(type, className = null) { |
|
316 let element = document.createElement(type); |
|
317 if(null !== className) { |
|
318 element.className = className; |
|
319 } |
|
320 return element; |
|
321 } |
|
322 |
|
323 const mastodonFeedCreateElementAccountLink = function(account) { |
|
324 let accountLinkElem = mastodonFeedCreateElement('a'); |
|
325 accountLinkElem.href = account.url; |
|
326 |
|
327 let accountImageElem = mastodonFeedCreateElement('img', 'avatar'); |
|
328 accountImageElem.src = account.avatar_static; |
|
329 |
|
330 accountLinkElem.addEventListener('mouseover', (event) => { |
|
331 accountLinkElem.querySelector('.avatar').src = account.avatar; |
|
332 }); |
|
333 accountLinkElem.addEventListener('mouseout', (event) => { |
|
334 accountLinkElem.querySelector('.avatar').src = account.avatar_static; |
|
335 }); |
|
336 |
|
337 accountLinkElem.appendChild(accountImageElem); |
|
338 // inject emojis |
|
339 let displayName = account.display_name; |
|
340 if(account.emojis.length > 0) { |
|
341 account.emojis.forEach(function(emoji) { |
|
342 displayName = mastodonFeedInjectEmoji(displayName, emoji); |
|
343 }); |
|
344 } |
|
345 accountLinkElem.innerHTML += ' ' + displayName; |
|
346 return accountLinkElem; |
|
347 } |
|
348 |
|
349 const mastodonFeedCreateElementPermalink = function(status, label) { |
|
350 let linkElem = mastodonFeedCreateElement('a'); |
|
351 linkElem.href = status.url; |
|
352 linkElem.appendChild(document.createTextNode(label)); |
|
353 return linkElem; |
|
354 } |
|
355 |
|
356 const mastodonFeedCreateElementMediaAttachments = function(status, options) { |
|
357 let attachments = status.media_attachments; |
|
358 let mediaWrapperElem = mastodonFeedCreateElement('div', 'media'); |
|
359 for(let mediaIndex = 0; mediaIndex < attachments.length; mediaIndex++) { |
|
360 let media = attachments[mediaIndex]; |
|
361 let mediaElem = mastodonFeedCreateElement('div', media.type); |
|
362 if('image' == media.type) { |
|
363 let mediaElemImgLink = mastodonFeedCreateElement('a'); |
|
364 mediaElemImgLink.href = status.url; |
|
365 if(null === media.remote_url) { |
|
366 mediaElemImgLink.style.backgroundImage = 'url("' + media.preview_url + '")'; |
|
367 } |
|
368 else { |
|
369 mediaElemImgLink.style.backgroundImage = 'url("' + media.remote_url + '")'; |
|
370 } |
|
371 if(null !== media.description) { |
|
372 mediaElem.title = media.description; |
|
373 } |
|
374 if(options.preserveImageAspectRatio) { |
|
375 let mediaElemImgImage = mastodonFeedCreateElement('img'); |
|
376 if(null === media.remote_url) { |
|
377 mediaElemImgImage.src = media.preview_url; |
|
378 } |
|
379 else { |
|
380 mediaElemImgImage.src = media.remote_url; |
|
381 } |
|
382 mediaElemImgLink.appendChild(mediaElemImgImage); |
|
383 } |
|
384 mediaElem.appendChild(mediaElemImgLink); |
|
385 } |
|
386 else if('gifv' == media.type) { |
|
387 let mediaElemGifvLink = mastodonFeedCreateElement('a'); |
|
388 mediaElemGifvLink.href = status.url; |
|
389 let mediaElemGifv = mastodonFeedCreateElement('video', 'requiresInteraction'); |
|
390 if(null === media.remote_url) { |
|
391 mediaElemGifv.src = media.url; |
|
392 } |
|
393 else { |
|
394 mediaElemGifv.src = media.remote_url; |
|
395 } |
|
396 mediaElemGifv.loop = true; |
|
397 mediaElemGifv.muted = 'muted'; |
|
398 if(null !== media.description) { |
|
399 mediaElemGifv.title = media.description; |
|
400 } |
|
401 mediaElemGifvLink.appendChild(mediaElemGifv); |
|
402 mediaElem.appendChild(mediaElemGifvLink); |
|
403 |
|
404 mediaElemGifv.addEventListener('mouseover', (event) => { |
|
405 mediaElemGifv.play(); |
|
406 }); |
|
407 mediaElemGifv.addEventListener('mouseout', (event) => { |
|
408 mediaElemGifv.pause(); |
|
409 mediaElemGifv.currentTime = 0; |
|
410 }); |
|
411 } |
|
412 else { |
|
413 // TODO implement support for other media types |
|
414 // currently only image and gifv support implemented |
|
415 mediaElem.innerHTML = 'Stripped ' + media.type + ' - only available on instance<br />'; |
|
416 let permalinkElem = mastodonFeedCreateElement('span', 'permalink'); |
|
417 permalinkElem.appendChild(mastodonFeedCreateElementPermalink(status, options.text.viewOnInstance)); |
|
418 mediaElem.appendChild(permalinkElem); |
|
419 } |
|
420 mediaWrapperElem.appendChild(mediaElem); |
|
421 } |
|
422 return mediaWrapperElem; |
|
423 } |
|
424 |
|
425 const mastodonFeedCreateElementPreviewCard = function(card) { |
|
426 let cardElem = mastodonFeedCreateElement('div', 'card'); |
|
427 |
|
428 if(null === card.html || card.html.length < 1) { |
|
429 let cardElemMeta = mastodonFeedCreateElement('div', 'meta'); |
|
430 |
|
431 if(null !== card.image) { |
|
432 let cardElemImageWrapper = mastodonFeedCreateElement('div', 'image'); |
|
433 let cardElemImage = mastodonFeedCreateElement('img'); |
|
434 cardElemImage.src = card.image; |
|
435 cardElemImageWrapper.appendChild(cardElemImage); |
|
436 cardElemMeta.appendChild(cardElemImageWrapper); |
|
437 } |
|
438 |
|
439 let cardElemTitle = mastodonFeedCreateElement('div', 'title'); |
|
440 cardElemTitle.innerHTML = card.title; |
|
441 cardElemMeta.appendChild(cardElemTitle); |
|
442 |
|
443 let cardElemDescription = mastodonFeedCreateElement('div', 'description'); |
|
444 cardElemDescription.innerHTML = card.description; |
|
445 cardElemMeta.appendChild(cardElemDescription); |
|
446 |
|
447 if(card.url === null) { |
|
448 cardElem.appendChild(cardElemMeta); |
|
449 } |
|
450 else { |
|
451 let cardElemLink = mastodonFeedCreateElement('a'); |
|
452 cardElemLink.href = card.url; |
|
453 cardElemLink.appendChild(cardElemMeta); |
|
454 cardElem.appendChild(cardElemLink); |
|
455 } |
|
456 } |
|
457 else { |
|
458 cardElem.innerHTML = card.html; |
|
459 } |
|
460 return cardElem; |
|
461 } |
|
462 |
|
463 const mastodonFeedCreateElementTimeinfo = function(status, options, url = false) { |
|
464 let createdInfo = mastodonFeedCreateElement('span', 'permalink'); |
|
465 createdInfo.innerHTML = ' ' + options.text.permalinkPre + ' '; |
|
466 if(false === url) { |
|
467 createdInfo.innerHTML += new Date(status.created_at).toLocaleString(options.localization.date.locale, options.localization.date.options); |
|
468 } |
|
469 else { |
|
470 createdInfo.appendChild(mastodonFeedCreateElementPermalink(status, new Date(status.created_at).toLocaleString(options.localization.date.locale, options.localization.date.options))); |
|
471 } |
|
472 createdInfo.innerHTML += ' ' + options.text.permalinkPost; |
|
473 return createdInfo; |
|
474 } |
|
475 |
|
476 const mastodonFeedInjectEmoji = function(string, emoji) { |
|
477 return string.replaceAll(':' + emoji.shortcode + ':', '<img class="emoji" src="' + emoji.url + '" title="' + emoji.shortcode + '" />'); |
|
478 } |
|
479 |
|
480 const mastodonFeedRenderStatuses = function(statuses, rootElem, options) { |
|
481 if(statuses.length < 1) { |
|
482 console.log(options); |
|
483 rootElem.innerHTML = options.text.noStatuses; |
|
484 } |
|
485 else { |
|
486 for(let i = 0; i < statuses.length; i++) { |
|
487 let status = statuses[i]; |
|
488 let isEdited = (null === status.edited_at ? true : false); |
|
489 let isReblog = (null === status.reblog ? false : true); |
|
490 |
|
491 let statusElem = mastodonFeedCreateElement('div', 'status'); |
|
492 |
|
493 // add account meta info |
|
494 if(!options.content.hideStatusMeta) { |
|
495 let accountElem = mastodonFeedCreateElement('div', 'account'); |
|
496 if(isReblog) { |
|
497 let boosterElem = mastodonFeedCreateElement('span', 'booster'); |
|
498 boosterElem.appendChild(document.createTextNode( options.text.boosted )); |
|
499 accountElem.appendChild(boosterElem); |
|
500 } |
|
501 accountElem.appendChild(mastodonFeedCreateElementAccountLink(status.account)); |
|
502 if(!options.content.hideDateTime) { |
|
503 accountElem.appendChild(mastodonFeedCreateElementTimeinfo(status, options, (isReblog ? false : status.url))); |
|
504 } |
|
505 if(null !== status.edited_at) { |
|
506 accountElem.innerHTML += ' ' + options.text.edited; |
|
507 } |
|
508 statusElem.appendChild(accountElem); |
|
509 } |
|
510 |
|
511 // prepare content rendering |
|
512 let showStatus = status; |
|
513 if(isReblog) { |
|
514 showStatus = status.reblog; |
|
515 } |
|
516 let contentWrapperElem = mastodonFeedCreateElement('div', 'contentWrapper' + (isReblog ? ' boosted' : '')); |
|
517 |
|
518 // add boosted post meta info |
|
519 if(isReblog) { |
|
520 let boostElem = mastodonFeedCreateElement('div', 'account'); |
|
521 let boostAccountLink = mastodonFeedCreateElementAccountLink(showStatus.account); |
|
522 boostElem.appendChild(boostAccountLink); |
|
523 boostElem.appendChild(mastodonFeedCreateElementTimeinfo(showStatus, options, showStatus.url)); |
|
524 |
|
525 contentWrapperElem.appendChild(boostElem); |
|
526 } |
|
527 |
|
528 let contentElem = mastodonFeedCreateElement('div', 'content'); |
|
529 |
|
530 // handle content warnings |
|
531 if(showStatus.sensitive || showStatus.spoiler_text.length > 0) { |
|
532 let cwElem = mastodonFeedCreateElement('div', 'contentWarning'); |
|
533 |
|
534 if(showStatus.spoiler_text.length > 0) { |
|
535 let cwTitleElem = mastodonFeedCreateElement('div', 'title'); |
|
536 cwTitleElem.innerHTML = showStatus.spoiler_text; |
|
537 cwElem.appendChild(cwTitleElem); |
|
538 } |
|
539 |
|
540 let cwLinkElem = mastodonFeedCreateElement('a'); |
|
541 cwLinkElem.href = '#'; |
|
542 cwLinkElem.onclick = function() { |
|
543 this.parentElement.style = 'display: none;'; |
|
544 this.parentElement.nextSibling.style = 'display: block;'; |
|
545 return false; |
|
546 } |
|
547 cwLinkElem.innerHTML = options.text.showContent; |
|
548 cwElem.appendChild(cwLinkElem); |
|
549 |
|
550 contentWrapperElem.appendChild(cwElem); |
|
551 contentElem.style = 'display: none;'; |
|
552 } |
|
553 |
|
554 // add regular content |
|
555 let renderContent = showStatus.content; |
|
556 // inject emojis |
|
557 if(showStatus.emojis.length > 0) { |
|
558 showStatus.emojis.forEach(function(emoji) { |
|
559 renderContent = mastodonFeedInjectEmoji(renderContent, emoji); |
|
560 }); |
|
561 } |
|
562 contentElem.innerHTML += renderContent; |
|
563 |
|
564 // handle media attachments |
|
565 if(showStatus.media_attachments.length > 0) { |
|
566 let mediaAttachmentsElem = mastodonFeedCreateElementMediaAttachments(showStatus, options); |
|
567 contentElem.appendChild(mediaAttachmentsElem); |
|
568 } |
|
569 |
|
570 // handle preview card |
|
571 if(options.showPreviewCards && showStatus.card != null) { |
|
572 let cardElem = mastodonFeedCreateElementPreviewCard(showStatus.card); |
|
573 contentElem.appendChild(cardElem); |
|
574 } |
|
575 |
|
576 contentWrapperElem.appendChild(contentElem); |
|
577 statusElem.appendChild(contentWrapperElem); |
|
578 rootElem.appendChild(statusElem); |
|
579 } |
|
580 } |
|
581 if('_self' != options.linkTarget) { |
|
582 rootElem.querySelectorAll('a').forEach(function(e) { |
|
583 e.target = options.linkTarget; |
|
584 }); |
|
585 } |
|
586 } |
|
587 |
|
588 const mastodonFeedLoad = function(url, elementId, options) { |
|
589 const xhr = new XMLHttpRequest(); |
|
590 xhr.open('GET', url, true); |
|
591 xhr.responseType = 'json'; |
|
592 xhr.onload = function() { |
|
593 const statuses = xhr.response; |
|
594 const rootElem = document.getElementById(elementId); |
|
595 rootElem.innerHTML = ''; |
|
596 <?php if(true === INCLUDE_MASTODON_FEED_DEBUG) : ?> |
|
597 console.log("<?php echo __NAMESPACE__; ?>", url); |
|
598 <?php endif; ?> |
|
599 if (xhr.status === 200) { |
|
600 <?php if(true === INCLUDE_MASTODON_FEED_DEBUG) : ?> |
|
601 console.log("<?php echo __NAMESPACE__; ?>", xhr.response); |
|
602 <?php endif; ?> |
|
603 if(options.excludeConversationStarters && statuses.length > 0) { |
|
604 const filteredStatuses = []; |
|
605 for(let i = 0; i < statuses.length; i++) { |
|
606 let includeStatus = true; |
|
607 if(statuses[i].mentions.length > 0) { |
|
608 const statusContent = document.createElement('div'); |
|
609 statusContent.innerHTML = statuses[i].content; |
|
610 const mentionUsername = statuses[i].mentions[0].acct.split('@')[0]; |
|
611 const plainTextContent = statusContent.textContent || statusContent.innerText; |
|
612 if(plainTextContent.substring(1, ('@' + mentionUsername).length) == mentionUsername) { |
|
613 includeStatus = false; |
|
614 } |
|
615 } |
|
616 if(includeStatus) { |
|
617 filteredStatuses.push(statuses[i]); |
|
618 } |
|
619 } |
|
620 mastodonFeedRenderStatuses(filteredStatuses, rootElem, options); |
|
621 } |
|
622 else { |
|
623 mastodonFeedRenderStatuses(statuses, rootElem, options); |
|
624 } |
|
625 } |
|
626 else { |
|
627 <?php if(true === INCLUDE_MASTODON_FEED_DEBUG) : ?> |
|
628 console.log("<?php echo __NAMESPACE__; ?>", xhr); |
|
629 <?php endif; ?> |
|
630 rootElem.appendChild(document.createTextNode(xhr.response.error)); |
|
631 } |
|
632 }; |
|
633 xhr.send(); |
|
634 } |
|
635 </script> |
|
636 <?php |
|
637 echo ob_get_clean(); |
|
638 } |
|
639 add_action('wp_footer', __NAMESPACE__ . '\init_scripts'); |
|
640 |
|
641 function display_feed($atts) { |
|
642 $atts = shortcode_atts( |
|
643 array( |
|
644 'instance' => ( INCLUDE_MASTODON_FEED_DEFAULT_INSTANCE === false ? false : filter_var( INCLUDE_MASTODON_FEED_DEFAULT_INSTANCE, FILTER_UNSAFE_RAW ) ), |
|
645 'account' => false, |
|
646 'tag' => false, |
|
647 'limit' => INCLUDE_MASTODON_FEED_LIMIT, |
|
648 'excludeboosts' => filter_var(esc_html(INCLUDE_MASTODON_FEED_EXCLUDE_BOOSTS), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), |
|
649 'excludereplies' => filter_var(esc_html(INCLUDE_MASTODON_FEED_EXCLUDE_REPLIES), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), |
|
650 'excludeconversationstarters' => filter_var(esc_html(INCLUDE_MASTODON_FEED_EXCLUDE_CONVERSATIONSTARTERS), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), |
|
651 'onlypinned' => filter_var(esc_html(INCLUDE_MASTODON_FEED_ONLY_PINNED), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), |
|
652 'onlymedia' => filter_var(esc_html(INCLUDE_MASTODON_FEED_ONLY_MEDIA), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), |
|
653 'preserveimageaspectratio' => filter_var(esc_html(INCLUDE_MASTODON_FEED_PRESERVE_IMAGE_ASPECT_RATIO), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), |
|
654 'tagged' => INCLUDE_MASTODON_FEED_TAGGED, |
|
655 'linktarget' => INCLUDE_MASTODON_FEED_LINKTARGET, |
|
656 'showpreviewcards' => filter_var(esc_html(INCLUDE_MASTODON_FEED_SHOW_PREVIEWCARDS), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), |
|
657 'hidestatusmeta' => filter_var(esc_html(INCLUDE_MASTODON_FEED_HIDE_STATUS_META), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), |
|
658 'hidedatetime' => filter_var(esc_html(INCLUDE_MASTODON_FEED_HIDE_DATETIME), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), |
|
659 'text-loading' => INCLUDE_MASTODON_FEED_TEXT_LOADING, |
|
660 'text-nostatuses' => INCLUDE_MASTODON_FEED_TEXT_NO_STATUSES, |
|
661 'text-boosted' => INCLUDE_MASTODON_FEED_TEXT_BOOSTED, |
|
662 'text-viewoninstance' => INCLUDE_MASTODON_FEED_TEXT_VIEW_ON_INSTANCE, |
|
663 'text-showcontent' => INCLUDE_MASTODON_FEED_TEXT_SHOW_CONTENT, |
|
664 'text-permalinkpre' => INCLUDE_MASTODON_FEED_TEXT_PERMALINK_PRE, |
|
665 'text-permalinkpost' => INCLUDE_MASTODON_FEED_TEXT_PERMALINK_POST, |
|
666 'text-edited' => INCLUDE_MASTODON_FEED_TEXT_EDITED, |
|
667 'date-locale' => INCLUDE_MASTODON_FEED_DATE_LOCALE, |
|
668 'date-options' => INCLUDE_MASTODON_FEED_DATE_OPTIONS, |
|
669 'darkmode' => filter_var(esc_html(INCLUDE_MASTODON_FEED_DARKMODE), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE), |
|
670 ), array_change_key_case($atts, CASE_LOWER) |
|
671 ); |
|
672 |
|
673 if(false === filter_var($atts['instance'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { |
|
674 return error('missing configuration: instance'); |
|
675 } |
|
676 if(false === filter_var($atts['account'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) && false === filter_var($atts['tag'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { |
|
677 return error('missing configuration: account id or tag'); |
|
678 } |
|
679 |
|
680 |
|
681 if(false !== filter_var($atts['account'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { |
|
682 $apiUrl = 'https://'.urlencode($atts['instance']).'/api/v1/accounts/'.$atts['account'].'/statuses'; |
|
683 } |
|
684 if(false !== filter_var($atts['tag'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { |
|
685 $apiUrl = 'https://'.urlencode($atts['instance']).'/api/v1/timelines/tag/'.urlencode($atts['tag']); |
|
686 } |
|
687 |
|
688 $getParams = []; |
|
689 if($atts['limit'] != 20 && $atts['limit'] > 0) { |
|
690 $getParams[] = 'limit=' . filter_var( $atts['limit'], FILTER_SANITIZE_NUMBER_INT ); |
|
691 } |
|
692 if(false !== filter_var($atts['excludeboosts'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { |
|
693 $getParams[] = 'exclude_reblogs=true'; |
|
694 } |
|
695 if(false !== filter_var($atts['excludereplies'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { |
|
696 $getParams[] = 'exclude_replies=true'; |
|
697 } |
|
698 if(true === filter_var($atts['onlypinned'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { |
|
699 $getParams[] = 'pinned=true'; |
|
700 } |
|
701 if(true === filter_var($atts['onlymedia'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { |
|
702 $getParams[] = 'only_media=true'; |
|
703 } |
|
704 if(false !== filter_var($atts['tagged'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE)) { |
|
705 $getParams[] = 'tagged=' . filter_var( $atts['tagged'], FILTER_UNSAFE_RAW ); |
|
706 } |
|
707 if(sizeof($getParams) > 0) { |
|
708 $apiUrl .= '?' . implode('&', $getParams); |
|
709 } |
|
710 $elemId = uniqid('include-mastodon-feed-'); |
|
711 ob_start(); |
|
712 ?> |
|
713 <script> |
|
714 window.addEventListener("load", () => { |
|
715 mastodonFeedLoad( |
|
716 "<?php echo sanitize_url( $apiUrl, ['https'] ); ?>", |
|
717 "<?php echo filter_var( $elemId, FILTER_UNSAFE_RAW ); ?>", |
|
718 { |
|
719 linkTarget: "<?php echo filter_var( $atts['linktarget'], FILTER_UNSAFE_RAW ); ?>", |
|
720 showPreviewCards: <?php echo (filter_var( $atts['showpreviewcards'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ? "true" : "false"); ?>, |
|
721 excludeConversationStarters: <?php echo (filter_var( $atts['excludeconversationstarters'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ? "true" : "false"); ?>, |
|
722 preserveImageAspectRatio: <?php echo (filter_var( $atts['preserveimageaspectratio'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ? "true" : "false"); ?>, |
|
723 content: { |
|
724 hideStatusMeta: <?php echo (filter_var( $atts['hidestatusmeta'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ? "true" : "false"); ?>, |
|
725 hideDateTime: <?php echo (filter_var( $atts['hidedatetime'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ? "true" : "false"); ?> |
|
726 }, |
|
727 text: { |
|
728 boosted: "<?php echo esc_js( $atts['text-boosted'] ); ?>", |
|
729 noStatuses: "<?php echo esc_html( $atts['text-nostatuses'] ); ?>", |
|
730 viewOnInstance: "<?php echo esc_js( $atts['text-viewoninstance'] ); ?>", |
|
731 showContent: "<?php echo esc_js( $atts['text-showcontent'] ); ?>", |
|
732 permalinkPre: "<?php echo esc_js( $atts['text-permalinkpre'] ); ?>", |
|
733 permalinkPost: "<?php echo esc_js( $atts['text-permalinkpost'] ); ?>", |
|
734 edited: "<?php echo esc_js( $atts['text-edited'] ); ?>", |
|
735 }, |
|
736 localization: { |
|
737 date: { |
|
738 locale: "<?php echo filter_var( $atts['date-locale'], FILTER_UNSAFE_RAW ); ?>", |
|
739 options: <?php echo filter_var( $atts['date-options'], FILTER_UNSAFE_RAW ); ?>, |
|
740 } |
|
741 } |
|
742 } |
|
743 ); |
|
744 }); |
|
745 </script> |
|
746 <div class="include-mastodon-feed<?php echo (true == $atts['darkmode'] ? ' dark' : ''); ?>" id="<?php echo esc_attr( $elemId ); ?>"><?php echo esc_html( $atts['text-loading'] ); ?></div> |
|
747 <?php |
|
748 return ob_get_clean(); |
|
749 } |
|
750 add_shortcode('include-mastodon-feed', __NAMESPACE__ . '\display_feed'); |