PluginProbe ʕ •ᴥ•ʔ
Rich Showcase for Google Reviews / 3.1
Rich Showcase for Google Reviews v3.1
6.9.10 6.9.9 6.9.8 6.9.7 6.9.6 trunk 1.4 1.42 1.43 1.44 1.45 1.46 1.47 1.48 1.49 1.5 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.7 1.6.8 1.6.9 1.7 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8 1.8.1 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 1.9.1 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2 2.2.1 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 2.3 2.4 2.4.1 2.4.2 2.5 2.5.1 2.6 2.6.1 2.6.2 2.7 2.8 2.9 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.6.1 3.7 3.8 3.9 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.8.1 4.8.2 5.0 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.7.1 5.8 5.9 5.9.1 5.9.2 5.9.3 5.9.7 6.0 6.1 6.2 6.3 6.4 6.4.1 6.5 6.6 6.6.1 6.6.2 6.7 6.8 6.8.1 6.8.2 6.9 6.9.1 6.9.2 6.9.3 6.9.4 6.9.4.1 6.9.4.2 6.9.4.3 6.9.4.4 6.9.5
widget-google-reviews / assets / src / js / admin-main.js
widget-google-reviews / assets / src / js Last commit date
admin-apexcharts.js 3 years ago admin-builder.js 2 years ago admin-main.js 2 years ago public-blazy.min.js 4 years ago public-main.js 2 years ago public-time.js 3 years ago
admin-main.js
508 lines
1 jQuery(document).ready(function($) {
2
3 $('.grw-admin-page a.nav-tab').on('click', function(e) {
4 var $this = $(this), activeId = $this.attr('href');
5 $(activeId).show().siblings('.tab-content').hide();
6 $this.addClass('nav-tab-active').siblings().removeClass('nav-tab-active');
7 e.preventDefault();
8 });
9
10 /**
11 * Rate us feedback
12 */
13 var $rateus = $('#grw-rate_us');
14 if ($rateus.length) {
15 var $rateus_dlg = $('#grw-rate_us-feedback'),
16 $rateus_stars = $('#grw-rate_us-feedback-stars');
17
18 grw_svg_init();
19 if (window.location.href.indexOf('grw_feed_new=1') > -1) {
20 $rateus.addClass('grw-flash-visible');
21 }
22 $('.wp-star', $rateus).click(function() {
23 var rate = $(this).index() + 1;
24 if (rate > 3) {
25 $.post({
26 url : ajaxurl,
27 type : 'POST',
28 dataType : 'json',
29 data : {action: 'grw_rateus_ajax', rate: rate},
30 success : function(res) {
31 console.log(res);
32 }
33 });
34 var askUrl = (Math.random() * 1).toFixed(0) > 0 ?
35 'https://g.page/r/CZac_S7-Dh2NEBM/review' :
36 'https://wordpress.org/support/plugin/widget-google-reviews/reviews/?rate=' + rate + '#new-post';
37 window.open(askUrl, '_blank');
38 grw_rateus_close();
39 } else {
40 $rateus_stars.attr('data-rate', rate);
41 $rateus_stars.html(grw_stars(rate, '#fb8e28', 24));
42 $rateus_dlg.dialog({modal: true, width: '50%', maxWidth: '600px'});
43 $('.ui-widget-overlay').bind('click', function() {
44 $rateus_dlg.dialog('close');
45 });
46 }
47 });
48
49 $('.grw-rate_us-cancel').click(function() {
50 $rateus_dlg.dialog('close');
51 });
52
53 $('.grw-rate_us-send').click(function() {
54 $.post({
55 url : ajaxurl,
56 type : 'POST',
57 dataType : 'json',
58 data : {
59 action : 'grw_rateus_ajax_feedback',
60 rate : $rateus_stars.attr('data-rate'),
61 email : $('input', $rateus_dlg).val(),
62 msg : $('textarea', $rateus_dlg).val(),
63 },
64 success : function(res) {
65 $rateus_dlg.dialog({'title': 'Feedback sent'})
66 $rateus_dlg.html('<b style="color:#4cc74b">Thank you for your feedback!<br>' +
67 'We received it and will investigate your suggestions.</b>');
68
69 grw_rateus_close();
70 setTimeout(function() {
71 $rateus_dlg.fadeOut(500, function() { $rateus_dlg.dialog('close'); });
72 }, 1500);
73 }
74 });
75 });
76
77 function grw_rateus_close() {
78 setTimeout(function() {
79 $rateus.addClass('grw-flash-gout');
80 $rateus.removeClass('grw-flash-visible');
81 $rateus.removeClass('grw-flash-gout');
82 }, 1000);
83 }
84 }
85
86 /**
87 * Overview page
88 */
89 var $overviewRating = $('#grw-overview-rating');
90 if ($overviewRating.length) {
91
92 var MONTHS = 6,
93 $places = $('#grw-overview-places'),
94 $months = $('#grw-overview-months'),
95 $rating = $('#grw-overview-rating'),
96 $reviews = $('#grw-overview-reviews'),
97 chart = null;
98
99 grw_svg_init();
100
101 $places.change(function() {
102 ajax(this.value);
103 });
104
105 $months.change(function() {
106 MONTHS = this.value;
107 ajax($places.val());
108 });
109
110 ajax(0, function(res) {
111 /*
112 * Places select filled
113 */
114 $.each(res.places, function(i, place) {
115 $places.append($('<option>', {
116 value: place.id,
117 text : place.name
118 }));
119 });
120 });
121
122 function ajax(pid, cb) {
123 var data = {action: 'grw_overview_ajax'};
124
125 if (pid) {
126 data.place_id = pid;
127 }
128 jQuery.post({
129 url : ajaxurl,
130 type : 'POST',
131 dataType : 'json',
132 data : data,
133 success : function(res) {
134
135 if (!res) {
136 window.location.href = GRW_VARS.builderUrl;
137 return;
138 }
139
140 var place = res.places.length > 1 ? res.places.find(x => x.id == pid) : res.places[0];
141
142 /*
143 * Stats minmax grouping and calculate result
144 */
145 var stats_result = null;
146
147 if (res.stats_minmax.length) {
148
149 let minmax = {},
150 mintime = 0,
151 nowtime = (new Date().getTime() / 1000).toFixed(0);
152
153 for (let i = 0; i < res.stats_minmax.length; i++) {
154
155 let mm = res.stats_minmax[i],
156 gpid = mm.google_place_id;
157
158 mintime = !mintime || mm.time < mintime ? mm.time : mintime;
159
160 if (minmax[gpid]) {
161
162 minmax[gpid] = {
163 time : parseInt(nowtime - minmax[gpid].time),
164 rating : parseFloat((mm.rating - minmax[gpid].rating).toFixed(1)),
165 review_count : parseInt(mm.review_count - minmax[gpid].review_count)
166 };
167
168 if (stats_result) {
169 stats_result = {
170 time : minmax[gpid].time,
171 rating : stats_result.rating + minmax[gpid].rating,
172 review_count : stats_result.review_count + minmax[gpid].review_count
173 }
174 } else {
175 stats_result = minmax[gpid];
176 }
177
178 delete minmax[gpid];
179
180 } else {
181 minmax[gpid] = {
182 time : mintime,
183 rating : mm.rating,
184 review_count : mm.review_count
185 };
186 }
187
188 }
189 }
190
191 let $stats = $('#grw-overview-stats');
192 $stats.html('Not calculated yet');
193
194 if (stats_result) {
195 let sr = stats_result.rating,
196 src = stats_result.review_count;
197 $stats.html(
198 '<div class="grw-overview-h">While using the plugin</div>' +
199 '<div>' +
200 'Usage time: ' +
201 '<span class="grw-stat-val grw-stat-up">' + grw_s2dmy(stats_result.time) + '</span>' +
202 '</div>' +
203 '<div>' +
204 'Rating up: ' +
205 '<span class="grw-stat-val grw-stat-' + (sr < 0 ? 'down' : (sr > 0 ? 'up' : '')) + '">' + sr + '</span>' +
206 '</div>' +
207 '<div>' +
208 'Reviews up: ' +
209 '<span class="grw-stat-val grw-stat-' + (src < 0 ? 'down' : (src > 0 ? 'up' : '')) + '">' + src + '</span>' +
210 '</div>'
211 );
212 }
213
214 /*
215 * Render rating
216 */
217 $rating.html(
218 '<div class="wp-gr">' +
219 '<div class="grw-overview-h">' + place.name + '</div>' +
220 '<div>' +
221 '<span class="wp-google-rating">' + res.rating + '</span>' +
222 '<span class="wp-google-stars">' + grw_stars(res.rating, '#fb8e28', 20) + '</span>' +
223 '</div>' +
224 '<div class="wp-google-powered">Based on ' + res.review_count + ' reviews</div>' +
225
226 (place.updated ?
227 '<div class="wp-google-powered">Last updated: ' +
228 '<span class="wp-google-time">' +
229 WPacTime.getTime(parseInt(place.updated), _rplg_lang(), 'ago') +
230 '</span>' +
231 '</div>' : '') +
232 '</div>'
233 );
234
235 /*
236 * Render reviews
237 */
238 var list = '';
239 $.each(res.reviews, function(i, review) {
240 list += grw_review(review);
241 });
242 $reviews.html(
243 '<div class="wp-gr wpac">' +
244 '<div class="wp-google-reviews">' + list + '</div>' +
245 '</div>'
246 );
247 _rplg_timeago(document.querySelectorAll('.wpac [data-time]'));
248 _rplg_read_more();
249
250 $('.wp-review-hide', $reviews).unbind('click').click(function() {
251 grw_review_hide($(this));
252 return false;
253 });
254
255 /*
256 * Render stats
257 */
258
259 // 1) Grouped by Google place ID
260 var gs = {};
261 for (var s = 0; s < res.stats.length; s++) {
262 var stat = res.stats[s],
263 gpi = stat.google_place_id;
264
265 gs[gpi] = gs[gpi] || [];
266 gs[gpi].push({
267 time: parseInt(stat.time),
268 rating: parseFloat(stat.rating),
269 review_count: parseInt(stat.review_count)
270 });
271 }
272
273 // 2) Calculate how many months needs
274 var period = parseInt((res.stats[0].time - res.stats[res.stats.length - 1].time) / (60 * 60 * 24 * 30)),
275 months = period > 4 ? MONTHS : (period || 1);
276
277 // 2) Calculate stats by months (last six)
278 var ms = {},
279 today = new Date();
280
281 for (var i = 0; i < months; i++) {
282 var startDay = new Date(today.getFullYear(), today.getMonth() - i, 1),
283 endTime = new Date(today.getFullYear(), today.getMonth() + 1 - i, 0).getTime(),
284 month = startDay.toLocaleString('default', {month: 'short'}) + ' ' + startDay.getFullYear().toString().slice(-2);
285
286 ms[month] = ms[month] || {};
287
288 for (g in gs) {
289 var j = 0, xx = gs[g];
290
291 do {
292 var stat = xx[j++],
293 time = stat.time * 1000;
294
295 ms[month][g] = ms[month][g] || {};
296 ms[month][g].count = parseInt(stat.review_count);
297
298 } while(time > endTime && j < xx.length);
299 }
300 }
301
302 // 3) Summary and normalize
303 var cat = [], data = [], series = []; var ttt = {};
304 for (m in ms) {
305 var count = 0;
306 for (p in ms[m]) {
307 count += ms[m][p].count;
308
309 // --- TEMP ---
310 var pp = res.places.find(x => x.id == p)
311 ttt[pp.name] = ttt[pp.name] || {};
312 ttt[pp.name].data = ttt[pp.name].data || [];
313 ttt[pp.name].data.unshift(ms[m][p].count);
314 // --- TEMP ---
315
316 }
317 cat.unshift(m);
318 data.unshift(count);
319 }
320
321 // --- TEMP ---
322 for (tt in ttt) {
323 series.push({name: tt, data: ttt[tt].data});
324 }
325 // --- TEMP ---
326
327 // 4) Render chart
328 var options = {
329 series: [{
330 name: 'Reviews',
331 data: data
332 }],
333 chart: {
334 height: 350,
335 type: 'bar',
336 //stacked: true,
337 },
338 plotOptions: {
339 bar: {
340 dataLabels: {
341 position: 'top', // top, center, bottom
342 },
343 }
344 },
345 dataLabels: {
346 enabled: true,
347 offsetY: -20,
348 style: {
349 fontSize: '12px',
350 colors: ["#304758"]
351 }
352 },
353 tooltip: {
354 enabled: true,
355 intersect: false,
356 custom: function() { return ''; }
357 },
358 xaxis: {
359 categories: cat,
360 axisBorder: {
361 show: false
362 },
363 axisTicks: {
364 show: false
365 },
366 tooltip: {
367 enabled: true
368 }
369 },
370 yaxis: {
371 axisBorder: {
372 show: false
373 },
374 axisTicks: {
375 show: false,
376 }
377 },
378 title: {
379 text: 'Monthly reviews count',
380 align: 'center',
381 style: {
382 color: '#444'
383 }
384 }
385 };
386
387 if (chart) {
388 chart.updateOptions({series: [{name: 'Reviews', data: data}], xaxis: {categories: cat}});
389 } else {
390 chart = new ApexCharts(document.querySelector('#chart'), options);
391 chart.render();
392 }
393
394 cb && cb(res);
395 }
396 });
397 }
398 }
399
400 });
401
402 function grw_svg_init() {
403 var span = document.createElement('span');
404 span.style.display = 'none';
405 span.innerHTML = grw_svg();
406 document.body.appendChild(span);
407 }
408
409 function grw_svg() {
410 return '' +
411 '<svg>' +
412 '<defs>' +
413 '<g id="rp-star" width="17" height="17">' +
414 '<path d="M1728 647q0 22-26 48l-363 354 86 500q1 7 1 20 0 21-10.5 35.5t-30.5 14.5q-19 0-40-12l-449-236-449 236q-22 12-40 12-21 0-31.5-14.5t-10.5-35.5q0-6 2-20l86-500-364-354q-25-27-25-48 0-37 56-46l502-73 225-455q19-41 49-41t49 41l225 455 502 73q56 9 56 46z"></path>' +
415 '</g>' +
416 '<g id="rp-star-half" width="17" height="17">' +
417 '<path d="M1250 957l257-250-356-52-66-10-30-60-159-322v963l59 31 318 168-60-355-12-66zm452-262l-363 354 86 500q5 33-6 51.5t-34 18.5q-17 0-40-12l-449-236-449 236q-23 12-40 12-23 0-34-18.5t-6-51.5l86-500-364-354q-32-32-23-59.5t54-34.5l502-73 225-455q20-41 49-41 28 0 49 41l225 455 502 73q45 7 54 34.5t-24 59.5z"></path>' +
418 '</g>' +
419 '<g id="rp-star-o" width="17" height="17">' +
420 '<path d="M1201 1004l306-297-422-62-189-382-189 382-422 62 306 297-73 421 378-199 377 199zm527-357q0 22-26 48l-363 354 86 500q1 7 1 20 0 50-41 50-19 0-40-12l-449-236-449 236q-22 12-40 12-21 0-31.5-14.5t-10.5-35.5q0-6 2-20l86-500-364-354q-25-27-25-48 0-37 56-46l502-73 225-455q19-41 49-41t49 41l225 455 502 73q56 9 56 46z" fill="#ccc"></path>' +
421 '</g>' +
422 '<g id="rp-logo-g" height="44" width="44" fill="none" fill-rule="evenodd">' +
423 '<path d="M482.56 261.36c0-16.73-1.5-32.83-4.29-48.27H256v91.29h127.01c-5.47 29.5-22.1 54.49-47.09 71.23v59.21h76.27c44.63-41.09 70.37-101.59 70.37-173.46z" fill="#4285f4"></path><path d="M256 492c63.72 0 117.14-21.13 156.19-57.18l-76.27-59.21c-21.13 14.16-48.17 22.53-79.92 22.53-61.47 0-113.49-41.51-132.05-97.3H45.1v61.15c38.83 77.13 118.64 130.01 210.9 130.01z" fill="#34a853"></path><path d="M123.95 300.84c-4.72-14.16-7.4-29.29-7.4-44.84s2.68-30.68 7.4-44.84V150.01H45.1C29.12 181.87 20 217.92 20 256c0 38.08 9.12 74.13 25.1 105.99l78.85-61.15z" fill="#fbbc05"></path><path d="M256 113.86c34.65 0 65.76 11.91 90.22 35.29l67.69-67.69C373.03 43.39 319.61 20 256 20c-92.25 0-172.07 52.89-210.9 130.01l78.85 61.15c18.56-55.78 70.59-97.3 132.05-97.3z" fill="#ea4335"></path><path d="M20 20h472v472H20V20z"></path>' +
424 '</g>' +
425 '</defs>' +
426 '</svg>';
427 }
428
429 function grw_stars(rating, color, size) {
430 var str = '';
431 for (var i = 1; i < 6; i++) {
432 var score = rating - i;
433 if (score >= 0) {
434 str += grw_star('', color, size);
435 } else if (score > -1 && score < 0) {
436 if (score < -0.75) {
437 str += grw_star('-o', '#ccc', size);
438 } else if (score > -0.25) {
439 str += grw_star('', color, size);
440 } else {
441 str += grw_star('-half', color, size);
442 }
443 } else {
444 str += grw_star('-o', '#ccc', size);
445 }
446 }
447 return str;
448 }
449
450 function grw_star(prefix, color, size) {
451 return '' +
452 '<span class="wp-star">' +
453 '<svg viewBox="0 0 1792 1792" width="' + size + '" height="' + size + '">' +
454 '<use xlink:href="#rp-star' + prefix + '" fill="' + color + '"/>' +
455 '</svg>' +
456 '</span>';
457 }
458
459 function grw_review(review) {
460 return '' +
461 '<div class="wp-google-review' + (review.hide == '' ? '' : ' wp-review-hidden') + '">' +
462 '<div class="wp-google-right">' +
463 '<a href="' + review.author_url + '" class="wp-google-name" target="_blank" rel="nofollow noopener">' + review.author_name + '</a>' +
464 '<div class="wp-google-time" data-time="' + review.time + '"></div>' +
465 '<div class="wp-google-feedback">' +
466 '<span class="wp-google-stars">' + grw_stars(review.rating, '#fb8e28', 16) + '</span>' +
467 '<span class="wp-google-text">' + grw_trimtext(review.text, 50) + '</span>' +
468 '</div>' +
469 '<a href="#" class="wp-review-hide" data-id="' + review.id + '">' + (review.hide == '' ? 'Hide' : 'Show') + ' review</a>' +
470 '</div>' +
471 '</div>';
472 }
473
474 function grw_trimtext(text, size) {
475 if (size && text && text.length > size) {
476 var subtext = text.substring(0, size),
477 idx = subtext.indexOf(' ') + 1;
478
479 if (idx < 1 || size - idx > (size / 2)) {
480 idx = size;
481 }
482
483 var visibletext = '', invisibletext = '';
484 if (idx > 0) {
485 visibletext = text.substring(0, idx - 1);
486 invisibletext = text.substring(idx - 1, text.length);
487 }
488
489 return visibletext +
490 (invisibletext ?
491 '<span>... </span>' +
492 '<span class="wp-more">' + invisibletext + '</span>' +
493 '<span class="wp-more-toggle">read more</span>' : '');
494 } else {
495 return text;
496 }
497 }
498
499 function grw_s2dmy(s) {
500 let d = (s / (60 * 60 * 24)).toFixed(0);
501 if (d > 30) {
502 if (d > 365) {
503 return Math.round(d / 365) + ' years';
504 }
505 return Math.round(d / 30) + ' months';
506 }
507 return d + ' days';
508 }