PluginProbe
WpStream – Live Streaming, Video on Demand, Pay Per View / trunk
WpStream – Live Streaming, Video on Demand, Pay Per View vtrunk
4.14.0 4.13.2 4.13.1 4.13 4.12.5 4.12.4 4.12.3 4.12.2 4.12.1 4.12 4.4.4 4.4.5 4.4.6 4.4.7 4.4.8 4.4.9 4.5 4.5.1 4.5.11 4.5.11.1 4.5.11.2 4.5.11.4 4.5.11.5 4.5.11.6 4.5.12 All 180 releases
wpstream / js / dashboard-script.js

dashboard-script.js in WpStream – Live Streaming, Video on Demand, Pay Per View trunk, at js/dashboard-script.js

365 lines 16.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /*
2 * WpStream front-end dashboard script.
3 *
4 * Powers the member dashboard modals: initializes Select2 on the taxonomy/
5 * channel pickers and wires the AJAX save handlers for editing a channel, the
6 * user account, billing/shipping addresses, and removing the profile picture.
7 * Localized data (ajaxurl, messages) is provided via wpstream_dashboard_script_vars.
8 */
9 jQuery(document).ready(function (jQuery) {
10 "use strict";
11
12 // Enhance the taxonomy/channel multi-selects with Select2 (Bootstrap 5 theme).
13 jQuery('#wpstream-user-channel-selection,#wpstream_edit_category,#wpstream_edit_post_tag,#wpstream_edit_wpstream_actors,#wpstream_edit_wpstream_category,#wpstream_edit_wpstream_movie_rating,#wpstream_edit_product_cat,#wpstream_edit_product_tag').select2({
14 theme: "bootstrap-5",
15 width: jQuery(this).data('width') ? jQuery(this).data('width') : jQuery(this).hasClass('w-100') ? '100%' : 'style',
16 placeholder: jQuery(this).data('placeholder'),
17 closeOnSelect: false,
18 });
19
20
21
22 // Bind all dashboard interactions once the DOM is ready.
23 wpstream_dashboard_user_menu();
24 wpstream_edit_account_function();
25 wpstream_edit_address_function('wpstream_edit_address_save');
26 wpstream_edit_address_function('wpstream_edit_address_save_shipping');
27 wpstream_delete_profile_picture();
28 wpstream_edit_channel_function();
29 });
30
31 /**
32 * Wire the "save channel" modal button.
33 *
34 * Collects the channel fields (title, description, paid flag/price, thumbnail,
35 * gallery images, taxonomies) and POSTs them to the save-channel AJAX action,
36 * then updates the dashboard UI (thumbnail, texts, price visibility, gallery,
37 * trailer/preview videos) from the response.
38 */
39 function wpstream_edit_channel_function() {
40 jQuery('#wpstream_edit_channel_save').on('click', function () {
41
42 // Gather the channel form values and the security nonce.
43 var nonce = jQuery('input[name="wpstream_nonce"]').val();
44 var wpstream_admin_ajax_url = wpstream_dashboard_script_vars.ajaxurl;
45 var thumb_id = jQuery('.wpstream_uploaded_images').attr('data-imageid');
46 var title = jQuery('#channel_name').val();
47 var description = jQuery('#wstream_description').val();
48 // Paid flag: 1 when the "paid" checkbox is ticked, else 0.
49 var channel_paid = 0;
50 var isChecked = jQuery('input[name="channel_paid"]').is(':checked');
51 if (isChecked) {
52 channel_paid = 1;
53 }
54
55 var channel_price = jQuery('#channel_price').val();
56 var images = jQuery('#attachid').val();
57 var postID = jQuery(this).attr('data-postID');
58
59 // Collect selected terms per taxonomy into a { taxonomy: values } map.
60 var categories = {};
61 // wpstream_edit_channel_taxonomy_wrapper
62
63 jQuery('.wpstream_taxonomies').each(function(){
64 var selected_tax = jQuery(this).attr('data-tax');
65 var selected_val = jQuery(this).val();
66 categories[selected_tax]=selected_val;
67 });
68
69
70
71 jQuery.ajax({
72 type: 'POST',
73 url: wpstream_admin_ajax_url, // WordPress AJAX URL,
74 dataType: 'json',
75 data: {
76 action: 'wpstream_dashboard_save_channel_data',
77 thumb_id: thumb_id,
78 title: title,
79 description: description,
80 channel_paid: channel_paid,
81 channel_price: channel_price,
82 images: images,
83 postID: postID,
84 selected_categories:categories,
85 nonce: nonce
86
87
88 },
89 success: function (response) {
90
91 // On success, reflect the saved values back into the dashboard view.
92 if (response.success) {
93
94 // Update the thumbnail, title and description displays.
95 jQuery('.event_thumb_wrapper').css('background-image', 'url('+response.data.thumburl+')');
96 jQuery('#wpstream_channel_title').empty().text(title);
97 jQuery('#wpstream_channel_description').empty().html(description);
98
99 // Show or hide the price row depending on the paid flag.
100 if(channel_paid == 0){
101 jQuery('.wpstream-dashboard-details_price').hide();
102 }else{
103 jQuery('.wpstream-dashboard-details_price').show();
104 }
105
106 // Refresh price, gallery images and taxonomy chips, then close the modal.
107 jQuery('#wpstream_channel_price').empty().text(channel_price);
108 jQuery('.wpstream_uploaded_images_wrapper').empty().html(response.data.images);
109 jQuery('.wpstream-theme-dashboard-chanel-gallery__list').empty().html(response.data.images);
110
111 jQuery('.wpstream_taxonomies_wrapper').empty().html(response.data.taxonomies);
112 jQuery('#wpstream_edit_channel_modal').modal('hide');
113
114 // Check if there is a trailer video
115 var trailerVideoWrapper = jQuery('.wpstream-theme-dashboard-channel-video-trailer__video');
116 if ( trailerVideoWrapper.find('#wpstream-video-trailer').length > 0 ) {
117 // Existing trailer: swap the source and reload the element.
118 jQuery('#wpstream-video-trailer video source').attr('src', response.data.video_trailer);
119 jQuery('#wpstream-video-trailer video')[0].load();
120 } else {
121 // If there is no trailer video, create it
122 trailerVideoWrapper.empty();
123 trailerVideoWrapper.append(`<div class="wpstream-video-trailer" id="wpstream-video-trailer">` +
124 `<video height="240" controls><source src="${response.data.video_trailer}" type="video/mp4"></video></div>`);
125 }
126 // Check if there is a preview video
127 var previewVideoWrapper = jQuery('.wpstream-theme-dashboard-channel-video-preview__video');
128 if ( previewVideoWrapper.find('#wpstream-video-preview').length > 0 ) {
129 // Existing preview: swap the source and reload the element.
130 jQuery('#wpstream-video-preview video source').attr('src', response.data.video_preview);
131 jQuery('#wpstream-video-preview video')[0].load();
132 } else {
133 // If there is no preview video, create it
134 previewVideoWrapper.empty();
135 previewVideoWrapper.append(`<div class="wpstream-video-preview" id="wpstream-video-preview">` +
136 `<video height="240" controls><source src="${response.data.video_preview}" type="video/mp4"></video></div>`);
137 }
138 } else {
139 // Server reported failure.
140 console.log('Error');
141 }
142
143
144 },
145 error: function (err) {
146 // Network/transport failure: log and notify the user.
147 console.log(err);
148 // Handle AJAX error
149 alert('AJAX request failed.');
150 }
151 });
152 });
153 }
154
155 /**
156 * Initialize the dashboard header profile-image popover menu.
157 *
158 * Disposes any previous popover instance before creating a new one so repeated
159 * calls do not stack Bootstrap popovers on the same element.
160 */
161 var popover;
162 function wpstream_dashboard_user_menu() {
163 var profileImage = document.getElementById('dashboard-header_profile-image');
164 // Tear down a prior popover to avoid duplicates.
165 if(typeof popover !== 'undefined' ){
166 popover.dispose();
167 }
168 // Create the bottom-placed popover on the profile image.
169 popover = new bootstrap.Popover(profileImage, {
170 placement: 'bottom',
171 });
172 }
173
174 /**
175 * Wire an address-save modal button (billing or shipping).
176 *
177 * Reads every input/select in the modal, POSTs them to the save-address AJAX
178 * action, and on success closes the modal and mirrors the values into the
179 * matching display fields.
180 *
181 * @param {string} button_id Id of the save button to bind.
182 */
183 function wpstream_edit_address_function(button_id) {
184 // Which address this button saves: the shipping modal's button saves
185 // shipping, every other caller is the billing modal.
186 var address_type = button_id === 'wpstream_edit_address_save_shipping' ? 'shipping' : 'billing';
187 jQuery('#' + button_id).on('click', function () {
188 // Security nonce and AJAX endpoint.
189 var nonce = jQuery('input[name="wpstream_nonce"]').val();
190 var wpstream_admin_ajax_url = wpstream_dashboard_script_vars.ajaxurl;
191
192 // Get the values from the form fields
193 var modalBody = jQuery(this).closest('.modal-content');
194 var inputData = [];
195
196 // Find all input elements in the modal body.
197 //var inputs = jQuery('.modal-body input,.modal-body select');
198 var inputs = modalBody.find('input, select');
199
200 // Loop through each input element and add its ID and value to the array.
201 inputs.each(function () {
202 var element = jQuery(this);
203 var inputId = element.attr('id');
204 var inputValue = element.val();
205 inputData.push({id: inputId, value: inputValue});
206 });
207
208 jQuery.ajax({
209 type: 'POST',
210 url: wpstream_admin_ajax_url, // WordPress AJAX URL,
211 dataType: 'json',
212 // Action, nonce, collected fields, and which address is saved.
213 data: {
214 action: 'wpstream_dashboard_save_user_address',
215 nonce: nonce,
216 inputData: inputData,
217 type: address_type
218 },
219 success: function (response) {
220
221 if (response.success) {
222 // Close both address modals and mirror each value into its display field.
223 jQuery('#wpstream_edit_addr_modal').modal('hide');
224 jQuery('#wpstream_edit_addr_modal_shipping').modal('hide');
225 for (var i = 0; i < inputData.length; i++) {
226 var inputId = inputData[i].id;
227 var inputValue = inputData[i].value;
228 // Set the value of the input element based on its ID.
229 jQuery('#wpstream_display_' + inputId).empty().text(inputValue);
230 }
231 } else {
232 // No-op on a non-success response.
233 }
234 },
235 error: function () {
236 // Handle AJAX error
237 alert('AJAX request failed.');
238 }
239 });
240 }
241 )
242 }
243
244 /**
245 * Wire the "remove profile picture" button.
246 *
247 * POSTs the current image id to the delete-attachment AJAX action and, on
248 * success, clears the stored image id and resets both avatar images to the
249 * default returned by the server.
250 */
251 function wpstream_delete_profile_picture() {
252 jQuery('#wpstream_remove_profile').on('click', function () {
253 // The attachment to delete, endpoint, and nonce.
254 var imageId = jQuery('#wpstream_remove_profile').attr('data-image-id');
255 var ajaxurl = wpstream_dashboard_script_vars.ajaxurl;
256 var nonce = jQuery('#wpstream_profile_image_upload').val();
257
258 jQuery.ajax({
259 type: 'POST',
260 url: ajaxurl,
261 dataType: 'json',
262 data: {
263 action: 'wpstream_delete_profile_attachment',
264 image_id: imageId,
265 security: nonce,
266 },
267 success: function (response) {
268 if (response.success) {
269 // Clear the stored id and swap both avatars back to the default image.
270 jQuery('#wpstream_remove_profile').attr('data-image-id', '');
271 jQuery('#profile-image,#dashboard-header_profile-image').attr('src', response.data.default);
272 }
273 }
274 });
275 });
276 }
277
278 /**
279 * Wire the "save account" modal button.
280 *
281 * Validates the optional password change (current required, new fields must
282 * match), then POSTs the account fields to the save-user-data AJAX action and
283 * updates the display fields or shows the relevant error on the response.
284 */
285 function wpstream_edit_account_function() {
286 jQuery('#wpstream_edit_account_save').on('click', function () {
287 // Get the values from the form fields
288 var firstName = jQuery('#account_first_name').val();
289 var lastName = jQuery('#account_last_name').val();
290 var displayName = jQuery('#account_display_name').val();
291 var email = jQuery('#account_email').val();
292 var aboutMe = jQuery('#account_about_me').val();
293 var currentPassword = jQuery('#password_current').val();
294 var newPassword1 = jQuery('#password_1').val();
295 var newPassword2 = jQuery('#password_2').val();
296 var message_password = jQuery('.wpstream_passoword_change_notification');
297 var message_account = jQuery('.wpstream_account_change_notification');
298 var nonce = jQuery('input[name="wpstream_nonce"]').val();
299 var wpstream_admin_ajax_url = wpstream_dashboard_script_vars.ajaxurl;
300
301
302 // Check if the passwords meet the conditions
303 if (newPassword1 !== '' && newPassword2 !== '') {
304 // A new password requires the current one and both new fields to match.
305 if (currentPassword === '') {
306 message_password.empty().text(wpstream_dashboard_script_vars.currentPassEmpty)
307 return
308 } else if (newPassword1 != newPassword2) {
309 message_password.empty().text(wpstream_dashboard_script_vars.passNoMatch)
310 return
311 }
312 }
313
314 // Make an AJAX request to save the user's data
315 jQuery.ajax({
316 type: 'POST',
317 url: wpstream_admin_ajax_url, // WordPress AJAX URL,
318 dataType: 'json',
319 data: {
320 action: 'wpstream_dashboard_save_user_data',
321 nonce: nonce,
322 firstName: firstName,
323 lastName: lastName,
324 displayName: displayName,
325 email: email,
326 newPassword1: newPassword1,
327 newPassword2: newPassword2,
328 currentPassword: currentPassword,
329 aboutMe
330 },
331 success: function (response) {
332
333 if (response.success) {
334 // Mirror the saved values into their display fields and close the modal.
335 message_password.empty().text(response.message);
336 jQuery('#wpstream_first_name_value').empty().text(firstName);
337 jQuery('#wpstream_last_name_value').empty().text(lastName);
338 jQuery('#wpstream_display_name_value').empty().text(displayName);
339 jQuery('#wpstream_email_value').empty().text(email);
340 jQuery('#wpstream_about_me_value').empty().text(aboutMe);
341 jQuery('#wpstream_edit_account_modal').modal('hide');
342
343 // Refresh the header username label.
344 jQuery('.dashboard-header_profile-username').text(firstName+' '+lastName);
345
346 // A password change invalidates the session, so reload the page.
347 if (response.data.passwordchanged) {
348 location.reload();
349 }
350 } else {
351 // Surface whichever error the server reported (password or account).
352 if (response.data.failpass) {
353 message_password.empty().text(response.data.failpass)
354 } else if (response.data.failaccount) {
355 message_account.empty().text(response.data.failaccount)
356 }
357 }
358 },
359 error: function () {
360 // Handle AJAX error
361 alert('AJAX request failed.');
362 }
363 });
364 });
365 }