PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / 2.5.0
Forumax – AI Powered Advanced Community Forum Plugin v2.5.0
2.5.0 2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 trunk 1.0.8 1.1.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 2.0.0 All 30 releases
bbp-core / assets / frontend / js / avatar-upload.js

avatar-upload.js in Forumax – AI Powered Advanced Community Forum Plugin 2.5.0, at assets/frontend/js/avatar-upload.js

156 lines 4.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Forumax – Avatar Upload Handler
3 *
4 * Handles the client-side logic for uploading and removing
5 * custom profile avatars via AJAX on the bbPress user edit page.
6 *
7 * @package Forumax
8 * @since 2.2.0
9 */
10 ( function( $ ) {
11 'use strict';
12
13 var $preview = $( '#frmx-avatar-preview' ),
14 $img = $( '#frmx-avatar-img' ),
15 $removeBtn = $( '#frmx-avatar-remove' ),
16 $fileInput = $( '#frmx-avatar-input' ),
17 $hiddenId = $( '#frmx-avatar-id' ),
18 $status = $( '#frmx-avatar-status' );
19
20 /**
21 * Display a temporary status message.
22 *
23 * @param {string} message The message text.
24 * @param {string} type Status type: 'success', 'error', or 'info'.
25 */
26 function showStatus( message, type ) {
27 type = type || 'info';
28 $status
29 .removeClass( 'frmx-status-success frmx-status-error frmx-status-info' )
30 .addClass( 'frmx-status-' + type )
31 .text( message )
32 .fadeIn( 200 );
33
34 if ( 'info' !== type ) {
35 setTimeout( function() {
36 $status.fadeOut( 300 );
37 }, 4000 );
38 }
39 }
40
41 /**
42 * Handle avatar file selection and upload.
43 */
44 $fileInput.on( 'change', function( e ) {
45 var file = e.target.files[ 0 ];
46
47 if ( ! file ) {
48 return;
49 }
50
51 // Validate file type.
52 var allowedTypes = [ 'image/jpeg', 'image/png', 'image/gif', 'image/webp' ];
53 if ( allowedTypes.indexOf( file.type ) === -1 ) {
54 showStatus( frmx_avatar.error, 'error' );
55 $fileInput.val( '' );
56 return;
57 }
58
59 // Validate file size.
60 if ( file.size > frmx_avatar.max_size ) {
61 showStatus( frmx_avatar.max_size_text, 'error' );
62 $fileInput.val( '' );
63 return;
64 }
65
66 // Show uploading status.
67 showStatus( frmx_avatar.uploading, 'info' );
68 $preview.addClass( 'frmx-avatar-uploading' );
69
70 // Prepare form data.
71 var formData = new FormData();
72 formData.append( 'action', 'frmx_upload_avatar' );
73 formData.append( 'nonce', frmx_avatar.nonce );
74 formData.append( 'avatar_file', file );
75 formData.append( 'user_id', $( 'input[name="bbp_user_id"]' ).val() || $( 'input[name="user_id"]' ).val() || '' );
76
77 // Upload via AJAX.
78 $.ajax( {
79 url: frmx_avatar.ajax_url,
80 type: 'POST',
81 data: formData,
82 processData: false,
83 contentType: false,
84 success: function( response ) {
85 $preview.removeClass( 'frmx-avatar-uploading' );
86
87 if ( response.success ) {
88 $img.attr( 'src', response.data.avatar_url );
89 $hiddenId.val( response.data.attachment_id );
90 showStatus( response.data.message, 'success' );
91
92 // Show remove button if not visible.
93 if ( $removeBtn.length === 0 ) {
94 $preview.append(
95 '<button type="button" class="frmx-avatar-remove" id="frmx-avatar-remove" title="Remove Photo">' +
96 '<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>' +
97 '</button>'
98 );
99 $removeBtn = $( '#frmx-avatar-remove' );
100 }
101 } else {
102 showStatus( response.data.message || frmx_avatar.error, 'error' );
103 }
104 },
105 error: function() {
106 $preview.removeClass( 'frmx-avatar-uploading' );
107 showStatus( frmx_avatar.error, 'error' );
108 }
109 } );
110
111 // Reset file input so the same file can be re-selected.
112 $fileInput.val( '' );
113 } );
114
115 /**
116 * Handle avatar removal.
117 */
118 $( document ).on( 'click', '#frmx-avatar-remove', function( e ) {
119 e.preventDefault();
120
121 if ( ! confirm( frmx_avatar.confirm ) ) {
122 return;
123 }
124
125 showStatus( frmx_avatar.removing, 'info' );
126 $preview.addClass( 'frmx-avatar-uploading' );
127
128 $.ajax( {
129 url: frmx_avatar.ajax_url,
130 type: 'POST',
131 data: {
132 action: 'frmx_remove_avatar',
133 nonce: frmx_avatar.nonce,
134 user_id: $( 'input[name="bbp_user_id"]' ).val() || $( 'input[name="user_id"]' ).val() || ''
135 },
136 success: function( response ) {
137 $preview.removeClass( 'frmx-avatar-uploading' );
138
139 if ( response.success ) {
140 $img.attr( 'src', response.data.avatar_url );
141 $hiddenId.val( '' );
142 $removeBtn.remove();
143 $removeBtn = $( '#frmx-avatar-remove' );
144 showStatus( response.data.message, 'success' );
145 } else {
146 showStatus( response.data.message || frmx_avatar.error, 'error' );
147 }
148 },
149 error: function() {
150 $preview.removeClass( 'frmx-avatar-uploading' );
151 showStatus( frmx_avatar.error, 'error' );
152 }
153 } );
154 } );
155 } )( jQuery );
156