PluginProbe
Friends / 2.9.0
Friends v2.9.0
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.9.0, at friends.js

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