PluginProbe
Friends / 2.8.5
Friends v2.8.5
4.3.2 4.3.1 4.3.0 4.2.2 4.2.1 4.2.0 4.1.0 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.0 2.9.1 All 88 releases
friends / friends.js

friends.js in Friends 2.8.5, at friends.js

598 lines 14.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /* global jQuery */
2 ( function ( $, wp, friends ) {
3 const $document = $( document );
4 let alreadySearching = '';
5 let alreadyLoading = false;
6 const bottomOffsetLoadNext = 2000;
7 let searchResultFocused = false;
8
9 wp = wp || { ajax: { send() {}, post() {} } };
10
11 $document.on(
12 'keydown',
13 'input#master-search, .form-autocomplete a',
14 function ( e ) {
15 const code = e.keyCode ? e.keyCode : e.which;
16 const results = $( this )
17 .closest( '.form-autocomplete' )
18 .find( '.menu .menu-item a' );
19 if ( 40 === code ) {
20 if ( false === searchResultFocused ) {
21 searchResultFocused = 0;
22 } else if ( searchResultFocused + 1 < results.length ) {
23 searchResultFocused += 1;
24 }
25 } else if ( 38 === code ) {
26 if ( false === searchResultFocused ) {
27 searchResultFocused = -1;
28 } else {
29 searchResultFocused -= 1;
30 if ( -1 === searchResultFocused ) {
31 $( 'input#master-search' ).focus();
32 return false;
33 }
34 }
35 } else {
36 return;
37 }
38
39 const el = results.get( searchResultFocused );
40 if ( el ) {
41 el.focus();
42 }
43 return false;
44 }
45 );
46
47 $document.on( 'keyup', 'input#master-search', function () {
48 const input = $( this );
49 const query = input.val().trim();
50
51 if ( alreadySearching === query ) {
52 return;
53 }
54 const menu = input.closest( '.form-autocomplete' ).find( '.menu' );
55
56 if ( ! query ) {
57 menu.hide();
58 return;
59 }
60
61 const searchIndicator = input
62 .closest( '.form-autocomplete-input' )
63 .find( '.form-icon' );
64
65 wp.ajax.send( 'friends-autocomplete', {
66 data: {
67 q: query,
68 },
69 beforeSend() {
70 searchIndicator.addClass( 'loading' );
71 alreadySearching = query;
72 },
73 success( results ) {
74 searchIndicator.removeClass( 'loading' );
75 searchResultFocused = false;
76 if ( results ) {
77 menu.html( results ).show();
78 } else {
79 menu.hide();
80 }
81 },
82 } );
83 } );
84 $document.on(
85 'click',
86 'a.friends-auth-link, button.comments.friends-auth-link',
87 function () {
88 const $this = jQuery( this );
89 const token = $this.data( 'token' );
90
91 if ( ! token ) {
92 return;
93 }
94 let href = $this.attr( 'href' );
95
96 const parts = token.split( /-/ );
97 const now = new Date();
98 if ( now / 1000 > parts[ 1 ] ) {
99 wp.ajax
100 .post( 'friends_refresh_link_token', {
101 _ajax_nonce: $this.data( 'nonce' ),
102 friend: $this.data( 'friend' ),
103 url: href,
104 } )
105 .done( function ( response ) {
106 if ( response.data ) {
107 $this.data( 'token', response.data.token );
108 }
109 } );
110
111 // eslint-disable-next-line no-alert
112 window.alert( friends.text_link_expired );
113 return false;
114 }
115
116 if ( href && href.indexOf( 'friend_auth=' ) < 0 ) {
117 let hash = href.indexOf( '#' );
118 if ( hash >= 0 ) {
119 hash = href.substr( hash );
120 href = href.substr( 0, href.length - hash.length );
121 } else {
122 hash = '';
123 }
124
125 if ( href.indexOf( '?' ) >= 0 ) {
126 href += '&';
127 } else {
128 href += '?';
129 }
130 href += 'friend_auth=' + token + hash;
131 $this.attr( 'href', href );
132 }
133
134 if ( $this.is( 'button' ) ) {
135 window.location.href = href;
136 return false;
137 }
138 }
139 );
140
141 $( function () {
142 $( '#only_subscribe' ).on( 'change', function () {
143 $( this )
144 .closest( 'form' )
145 .find( '#submit' )
146 .text( this.checked ? '1' : '2' );
147 } );
148 $( '#post-format-switcher select' ).on( 'change', function () {
149 const re = new RegExp( '/type/[^/$]+' ),
150 v = $( this ).val();
151 let url;
152 const urlPart = v ? '/type/' + v + '/' : '/';
153 if ( window.location.href.match( re ) ) {
154 url = window.location.href.replace( re, urlPart );
155 } else {
156 url = window.location.href.replace( /\/$/, '' ) + urlPart;
157 }
158 window.location.href = url;
159 } );
160 } );
161
162 $document.on( 'click', 'a.friends-trash-post', function () {
163 const button = $( this );
164
165 wp.ajax.send( 'trash-post', {
166 data: {
167 _ajax_nonce: button.data( 'trash-nonce' ),
168 id: button.data( 'id' ),
169 },
170 success() {
171 button
172 .text( friends.text_undo )
173 .attr( 'class', 'friends-untrash-post' );
174 },
175 } );
176 return false;
177 } );
178
179 $document.on( 'click', 'a.friends-untrash-post', function () {
180 const button = $( this );
181
182 wp.ajax.send( 'untrash-post', {
183 data: {
184 _ajax_nonce: button.data( 'untrash-nonce' ),
185 id: button.data( 'id' ),
186 },
187 success() {
188 button
189 .text( friends.text_trash_post )
190 .attr( 'class', 'friends-trash-post' );
191 },
192 } );
193 return false;
194 } );
195
196 $document.on( 'click', 'a.collapse-post', function ( e ) {
197 if ( e.metaKey || e.altKey || e.shiftKey ) {
198 $( this ).trigger( 'dblclick' );
199 return;
200 }
201
202 const card = $( this ).closest( 'article' );
203 let collapsed;
204 if ( card.closest( 'section.all-collapsed' ).length ) {
205 card.toggleClass( 'uncollapsed' );
206 collapsed = ! card.is( '.uncollapsed' );
207 } else {
208 card.toggleClass( 'collapsed' );
209 collapsed = card.is( '.collapsed' );
210 }
211 if ( collapsed ) {
212 $( this )
213 .find( 'i' )
214 .removeClass( 'dashicons-fullscreen-exit-alt' )
215 .addClass( 'dashicons-fullscreen-alt' );
216 } else {
217 $( this )
218 .find( 'i' )
219 .removeClass( 'dashicons-fullscreen-exit-alt' )
220 .addClass( 'dashicons-fullscreen-alt' );
221 }
222
223 return false;
224 } );
225
226 $document.on( 'dblclick', 'a.collapse-post', function () {
227 // Collapse-toggle all visible.
228 $( this ).closest( 'section' ).toggleClass( 'all-collapsed' );
229 $( this )[ 0 ].scrollIntoView();
230 $( window ).trigger( 'scroll' );
231 return false;
232 } );
233
234 $document.on(
235 'dblclick',
236 'section.all-collapsed article, article.collapsed, article.uncollapsed',
237 function () {
238 $( this ).closest( 'article' ).find( 'a.collapse-post' ).trigger( 'click' );
239 return false;
240 }
241 );
242
243 $document.on( 'click', 'article a.comments', function ( e ) {
244 if ( e.metaKey || e.altKey || e.shiftKey ) {
245 return;
246 }
247
248 const $this = $( this );
249 const content = $this.closest( 'article' ).find( '.comments-content' );
250 if ( content.data( 'loaded' ) ) {
251 content.toggle();
252 } else {
253 content.show();
254 wp.ajax.send( 'friends-load-comments', {
255 data: {
256 _ajax_nonce: $this.data( 'cnonce' ),
257 post_id: $this.data( 'id' ),
258 },
259 success( comments ) {
260 content.html( comments ).data( 'loaded', true );
261 },
262 error( message ) {
263 content.html( message );
264 },
265 } );
266 }
267 return false;
268 } );
269
270 $document.on( 'change', 'select.friends-change-post-format', function () {
271 const select = $( this );
272
273 wp.ajax.send( 'friends-change-post-format', {
274 data: {
275 _ajax_nonce: select.data( 'change-post-format-nonce' ),
276 id: select.data( 'id' ),
277 format: select.val(),
278 },
279 success() {
280 // TODO: add some visual indication.
281 },
282 } );
283 return false;
284 } );
285
286 $( window ).scroll( function () {
287 if (
288 $( document ).scrollTop() <
289 $( document ).height() - bottomOffsetLoadNext
290 ) {
291 return;
292 }
293 nextPage();
294 } );
295
296 $( document ).on( 'click', '.nav-previous', function () {
297 nextPage();
298 return false;
299 } );
300
301 function nextPage() {
302 if ( alreadyLoading ) {
303 return;
304 }
305
306 if ( friends.current_page >= friends.max_page ) {
307 return;
308 }
309
310 wp.ajax.send( 'friends-load-next-page', {
311 data: {
312 query_vars: friends.query_vars,
313 page: friends.current_page,
314 qv_sign: friends.qv_sign,
315 },
316 beforeSend() {
317 $( 'section.posts .posts-navigation .nav-previous' ).addClass(
318 'loading'
319 );
320 alreadyLoading = true;
321 },
322 success( newPosts ) {
323 $(
324 'section.posts .posts-navigation .nav-previous'
325 ).removeClass( 'loading' );
326 if ( newPosts ) {
327 $( 'section.posts' )
328 .find( 'article:last-of-type' )
329 .after( newPosts );
330 if (
331 ++friends.current_page < friends.max_page &&
332 /<article/.test( newPosts )
333 ) {
334 alreadyLoading = false;
335 } else {
336 $( 'section.posts .posts-navigation' ).text(
337 friends.text_no_more_posts
338 );
339 }
340 }
341 },
342 } );
343 }
344
345 /* Reactions */
346 $( function () {
347 $document.on( 'click', 'button.friends-reaction', function () {
348 wp.ajax.send( 'friends-toggle-react', {
349 data: {
350 _ajax_nonce: $( this ).data( 'nonce' ),
351 post_id: $( this ).data( 'id' ),
352 reaction: $( this ).data( 'emoji' ),
353 },
354 success() {
355 window.location.reload();
356 },
357 } );
358 return false;
359 } );
360
361 $( '.friends-reaction-picker' ).on( 'click', 'button', function () {
362 wp.ajax.send( 'friends-toggle-react', {
363 data: {
364 _ajax_nonce: $( this )
365 .closest( '.friends-reaction-picker' )
366 .data( 'nonce' ),
367 post_id: $( this )
368 .closest( '.friends-reaction-picker' )
369 .data( 'id' ),
370 reaction: $( this ).data( 'emoji' ),
371 },
372 success() {
373 window.location.reload();
374 },
375 } );
376 return false;
377 } );
378 } );
379
380 /* ActivityPub */
381 $( function () {
382 $document.on( 'click', 'a.friends-reblog', function () {
383 const $this = $( this );
384 wp.ajax.send( 'friends-reblog', {
385 data: {
386 _ajax_nonce: $this.data( 'nonce' ),
387 post_id: $this.data( 'id' ),
388 },
389 success() {
390 $this
391 .find( 'i.friends-reblog-status' )
392 .addClass( 'dashicons dashicons-saved' );
393 },
394 } );
395 return false;
396 } );
397 } );
398
399 $document.on( 'click', 'a.send-new-message', function () {
400 $( '#friends-send-new-message' )
401 .toggle()
402 .find(
403 'textarea:visible, .block-editor-default-block-appender__content'
404 )
405 .focus();
406 return false;
407 } );
408
409 $document.on( 'click', 'button.delete-conversation', function () {
410 // eslint-disable-next-line no-alert
411 return window.confirm( friends.text_del_convers );
412 } );
413
414 $document.on( 'click', 'a.display-message', function () {
415 const $this = $( this ).closest( 'div' );
416 const conversation = $this.find( 'div.conversation' );
417 if ( conversation.is( ':visible' ) ) {
418 conversation.hide();
419 } else {
420 conversation.show();
421 const messages = conversation.find( '.messages' ).get( 0 );
422 messages.scrollTop = messages.scrollHeight;
423 $this.find( 'a.display-message' ).removeClass( 'unread' );
424 wp.ajax.send( 'friends-mark-read', {
425 data: {
426 _ajax_nonce: $this.data( 'nonce' ),
427 post_id: $this.data( 'id' ),
428 },
429 success() {},
430 } );
431 conversation
432 .find(
433 'textarea:visible, .block-editor-default-block-appender__content'
434 )
435 .focus();
436 }
437
438 return false;
439 } );
440
441 $document.on( 'mouseenter', 'h2#page-title a.dashicons', function () {
442 if ( $( this ).hasClass( 'not-starred' ) ) {
443 if ( $( this ).hasClass( 'dashicons-star-empty' ) ) {
444 $( this )
445 .removeClass( 'dashicons-star-empty' )
446 .addClass( 'dashicons-star-filled' );
447 }
448 } else if ( $( this ).hasClass( 'starred' ) ) {
449 if ( $( this ).hasClass( 'dashicons-star-filled' ) ) {
450 $( this )
451 .removeClass( 'dashicons-star-filled' )
452 .addClass( 'dashicons-star-empty' );
453 }
454 }
455 } );
456
457 $document.on( 'mouseleave', 'h2#page-title a.dashicons', function () {
458 if ( $( this ).hasClass( 'not-starred' ) ) {
459 if ( $( this ).hasClass( 'dashicons-star-filled' ) ) {
460 $( this )
461 .removeClass( 'dashicons-star-filled' )
462 .addClass( 'dashicons-star-empty' );
463 }
464 } else if ( $( this ).hasClass( 'starred' ) ) {
465 if ( $( this ).hasClass( 'dashicons-star-empty' ) ) {
466 $( this )
467 .removeClass( 'dashicons-star-empty' )
468 .addClass( 'dashicons-star-filled' );
469 }
470 }
471 } );
472
473 $document.on(
474 'click',
475 'h2#page-title a.dashicons.starred, h2#page-title a.dashicons.not-starred',
476 function () {
477 let removeClass = 'dashicons-star-filled starred';
478 let addClass = 'dashicons-star-empty not-starred';
479 const $this = $( this );
480 if ( $this.hasClass( 'not-starred' ) ) {
481 const s = removeClass;
482 removeClass = addClass;
483 addClass = s;
484 }
485 wp.ajax.send( 'friends-star', {
486 data: {
487 friend_id: $this.data( 'id' ),
488 _ajax_nonce: $this.data( 'nonce' ),
489 starred: $this.hasClass( 'starred' ) ? 0 : 1,
490 },
491 beforeSend() {
492 $this
493 .removeClass(
494 removeClass +
495 ' dashicons-star-filled dashicons-star-empty'
496 )
497 .addClass( 'form-icon loading' );
498 },
499 success() {
500 $this
501 .removeClass( 'form-icon loading' )
502 .addClass( addClass );
503 },
504 } );
505 return false;
506 }
507 );
508
509 function getAcct( href ) {
510 const url = new URL( href );
511 const username = url.pathname.replace( /\/$/, '' ).split( '/' ).pop();
512 return '@' + username.replace( /^@/, '' ) + '@' + url.hostname;
513 }
514
515 function insertTextInGutenberg( text ) {
516 let element, val, regex;
517 if ( jQuery( '.is-root-container p' ).length ) {
518 element = jQuery( '.is-root-container p' )[ 0 ];
519 element.focus();
520 window.getSelection().collapse( element.firstChild, element.textContent.length );
521 document.execCommand( 'insertText', false, text + ' ' );
522 } else {
523 val = text + ' ' + jQuery( '.friends-status-content' ).val();
524 jQuery( '.friends-status-content' ).val( val.replace( /^(@[^@]+@[^ ]+ )+/g, text + ' ' ) );
525 }
526 }
527
528 $document.on( 'click', '.activitypub_preview a', function () {
529 if ( ! $( this ).hasClass( 'mention' ) ) {
530 return true;
531 }
532 insertTextInGutenberg( getAcct( $( this ).attr( 'href' ) ) );
533 return false;
534 } );
535
536 $document.on( 'keyup', 'input.activitypub_preview_url', function () {
537 const input = $( this );
538 const form = input.closest( 'form' );
539 const preview = form.find( '.activitypub_preview' );
540 const url = input.val().trim();
541
542 if ( alreadySearching === url ) {
543 return;
544 }
545
546 preview.html( '<figcaption><a href=""></a></figcaption><blockquote>' );
547 preview.find( 'blockquote' ).text( friends.text_checking_url );
548 preview.find( 'a' ).attr( 'href', url ).text( url );
549 form.find( '.boost-link' ).attr( 'href', '?boost=' + escape( url ) );
550 form.find( '.reply-to-link' ).attr( 'href', '?in_reply_to=' + escape( url ) );
551
552 const searchIndicator = input
553 .closest( '.form-autocomplete-input' )
554 .find( '.form-icon' );
555
556 wp.ajax.send( 'friends-in-reply-to-preview', {
557 data: {
558 url,
559 },
560 beforeSend() {
561 searchIndicator.addClass( 'loading' );
562 alreadySearching = url;
563 },
564 success( results ) {
565 searchIndicator.removeClass( 'loading' );
566 if ( results ) {
567 preview.find( 'blockquote' ).html( results.html ).show();
568 input.closest( 'form' ).find( 'button' ).prop( 'disabled', false );
569 insertTextInGutenberg( getAcct( results.author ) );
570 } else {
571 preview.hide();
572 input.closest( 'form' ).find( 'button' ).prop( 'disabled', false );
573 }
574 },
575 error( results ) {
576 searchIndicator.removeClass( 'loading' );
577 input.closest( 'form' ).find( 'button' ).prop( 'disabled', true );
578 preview.find( 'blockquote' ).text( results ).show();
579 },
580 } );
581 } );
582
583 $document.on( 'click', '.quick-reply', function () {
584 $( '#quick-post-panel' ).addClass( 'open' );
585 $( '#quick-post-panel input#friends_in_reply_to' )
586 .val( $( this ).data( 'url' ) )
587 .trigger( 'keyup' );
588
589 $( '#quick-post-panel' )[ 0 ].scrollIntoView();
590 return false;
591 } );
592
593 $document.on( 'click', '.quick-post-panel-toggle', function () {
594 $( '#quick-post-panel' ).toggleClass( 'open' );
595 return false;
596 } );
597 } )( jQuery, window.wp, window.friends );
598