Bug 22804: OPAC Overdrive JavaScript contains untranslatable strings
[koha.git] / koha-tmpl / opac-tmpl / bootstrap / js / overdrive.js
1 /* global MSG_OVERDRIVE_LOGIN MSG_OVERDRIVE_LINK MSG_OVERDRIVE_LOGOUT MSG_OVERDRIVE_CHECKEDOUT_UNTIL MSG_DOWNLOAD MSG_OVERDRIVE_ACCESS_ONLINE MSG_OVERDRIVE_DOWNLOAD_AS MSG_CHECK_IN MSG_CHECK_OUT MSG_CHECKOUTS MSG_HOLDS MSG_ON_HOLD MSG_PLACE_HOLD MSG_CANCEL_HOLD MSG_OVERDRIVE_CANNOT_CHECKOUT MSG_CANCEL_HOLD_CONFIRM MSG_CHECK_IN_CONFIRM MSG_CHECK_OUT_CONFIRM OD_password_required */
2
3 if ( typeof KOHA == "undefined" || !KOHA ) {
4     var KOHA = {};
5 }
6
7 KOHA.OverDrive = ( function() {
8     var proxy_base_url = '/cgi-bin/koha/svc/overdrive_proxy';
9     var library_base_url = 'http://api.overdrive.com/v1/libraries/';
10     return {
11         Get: function( url, params, callback ) {
12             $.ajax( {
13                 type: 'GET',
14                 url: url.replace( /https?:\/\/api.overdrive.com\/v1/, proxy_base_url ),
15                 dataType: 'json',
16                 data: params,
17                 error: function( xhr, error ) {
18                     try {
19                         callback( JSON.parse( xhr.responseText ));
20                     } catch ( e ) {
21                         callback( {error: xhr.responseText || true} );
22                     }
23                 },
24                 success: callback
25             } );
26         },
27         GetCollectionURL: function( library_id, callback ) {
28             if ( KOHA.OverDrive.collection_url ) {
29                 callback( KOHA.OverDrive.collection_url );
30                 return;
31             }
32
33             KOHA.OverDrive.Get(
34                 library_base_url + library_id,
35                 {},
36                 function ( data ) {
37                     if ( data.error ) {
38                         callback( data );
39                         return;
40                     }
41
42                     KOHA.OverDrive.collection_url = data.links.products.href;
43
44                     callback( data.links.products.href );
45                 }
46             );
47         },
48         Search: function( library_id, q, limit, offset, callback ) {
49             KOHA.OverDrive.GetCollectionURL( library_id, function( data ) {
50                 if ( data.error ) {
51                     callback( data );
52                     return;
53                 }
54
55                 KOHA.OverDrive.Get(
56                     data,
57                     {q: q, limit: limit, offset: offset},
58                     callback
59                 );
60             } );
61         }
62     };
63 } )();
64
65 KOHA.OverDriveCirculation = new function() {
66     var svc_url = '/cgi-bin/koha/svc/overdrive';
67
68     var error_div = $('<div class="overdrive-error">');
69     function display_error ( error ) {
70         error_div.text(error);
71     }
72
73     var login_link = $('<a href="#">')
74         .click(function(e) {
75             e.preventDefault();
76             if( OD_password_required ) { $("#overdrive-login").modal('show'); }
77             else { login(""); }
78         })
79         .text( MSG_OVERDRIVE_LOGIN );
80
81     var login_div = $('<div class="overdrive-login">').append(login_link);
82
83     var details = null;
84
85     function is_logged_in() {
86         return details ? details.is_logged_in : false;
87     }
88
89     var checkout_popup = null;
90     $( document ).ready(function() {
91         checkout_popup = $("#overdrive-checkout");
92         $("#overdrive-login-form").submit(function(e){
93             e.preventDefault();
94             $("#overdrive-login").modal('hide');
95             var ODpassword = $("input[name='ODpassword']").val();
96             login( ODpassword );
97         });
98     });
99
100     $( document ).ready(function() {
101         var p = window.opener;
102         var cb;
103         if (p) {
104             try { cb = p.refresh_overdrive_account_details;}
105             catch(err){ return; } //Catch error if opener is not accessible
106             if (cb) {
107                 cb();
108             } else {
109                 p.location.reload();
110             }
111             window.close();
112         }
113     });
114
115     function display_account (container, data) {
116         if (!data.is_logged_in) {
117             $(container).append(login_div);
118             return;
119         }
120
121         var overdrive_link = $('<a href="https://www.overdrive.com/account/" target="overdrive-account" class="overdrive-link" style="float:right">')
122             .text( MSG_OVERDRIVE_LINK );
123         $(container).append(overdrive_link);
124
125         var logout_link = $('<a href="#logout" class="overdrive-logout" style="float:left">')
126             .click(function(e) {
127                 e.preventDefault();
128                 $(container).empty().append(error_div);
129                 logout(function(data) {
130                     display_account(container, data);
131                 });
132             }).text( MSG_OVERDRIVE_LOGOUT );
133         $(container).append(logout_link);
134         $(container).append('<br style="clear:both;"/>');
135
136         if (data.checkouts) {
137             var checkouts_div = $('<div class="overdrive-div">').html('<h3>' + MSG_CHECKOUTS + '</h3>');
138             var checkouts_list = $('<ul class="overdrive-list">');
139             data.checkouts.items.forEach(function(item) {
140                 item_line(checkouts_list, item);
141             });
142             checkouts_div.append(checkouts_list);
143             $(container).append(checkouts_div);
144         }
145
146         if (data.holds) {
147             var holds_div = $('<div class="overdrive-div">').html('<h3>' + MSG_HOLDS + '</h3>');
148             var holds_list = $('<ul class="overdrive-list">');
149             data.holds.items.forEach(function(item) {
150                 item_line(holds_list, item);
151             });
152             holds_div.append(holds_list);
153             $(container).append(holds_div);
154         }
155     }
156
157     function item_line(ul_el, item) {
158         var line = $('<li class="overdrive-item">');
159         if (item.images) {
160             var thumb_url = item.images.thumbnail;
161             if (thumb_url) {
162                 $('<img class="overdrive-item-thumbnail">')
163                     .attr("src", thumb_url)
164                     .appendTo(line);
165             }
166         }
167         $('<div class="overdrive-item-title">')
168             .text(item.title)
169             .appendTo(line);
170         $('<div class="overdrive-item-subtitle">')
171             .html(item.subtitle)
172             .appendTo(line);
173         $('<div class="overdrive-item-author">')
174             .text(item.author)
175             .appendTo(line);
176         var actions = $('<span class="actions">');
177         display_actions(actions, item.id);
178         $('<div id="action_'+item.id+'" class="actions-menu">')
179             .append(actions)
180             .appendTo(line);
181
182         $(ul_el).append(line);
183     }
184
185     function svc_ajax ( method, params, success_callback ) {
186         return $.ajax({
187             method: method,
188             dataType: "json",
189             url: svc_url,
190             data: params,
191             success: function (data) {
192                 if (data.error) {
193                     display_error(data.error);
194                 }
195                 success_callback(data);
196             },
197             error: function(jqXHR, textStatus, errorThrown) {
198                 display_error(errorThrown);
199             }
200         });
201     }
202
203     function load_account_details ( callback ) {
204         svc_ajax('get', { action: "account" }, function(data) {
205             details = data;
206             callback(data);
207         });
208     }
209
210     function login(p) {
211         svc_ajax('get', { action: "login", password: p }, function(data) {
212             details = null;
213             if( data.login_success ){
214                 $(login_div).detach();
215                 if( $("#overdrive-results-page").length > 0 ){
216                     location.reload();
217                 } else {
218                     KOHA.OverDriveCirculation.display_account_details( $("#opac-user-overdrive") );
219                 }
220             }
221         });
222     }
223
224     function logout (callback) {
225         svc_ajax('post', { action: "logout" }, function(data) {
226             details = null;
227             callback(data);
228         });
229     }
230
231     function item_action (params, el, copies_available) {
232         var id = params.id;
233         svc_ajax('post', params, function(data) {
234             if (data.checkouts) {
235                 details.checkouts = data.checkouts;
236             }
237             if (data.holds) {
238                 details.holds = data.holds;
239             }
240             display_actions(el, id, copies_available);
241         });
242     }
243
244     function item_is_checked_out (id) {
245         if ( !(details && details.checkouts) ) {
246             return null;
247         }
248         var id_uc = id.toUpperCase();
249         var items = details.checkouts.items;
250         for (var i = 0; i < items.length; i++) {
251             if ( items[i].id.toUpperCase() == id_uc ) {
252                 return items[i];
253             }
254         }
255         return null;
256     }
257
258     function item_is_on_hold (id) {
259         if ( !(details && details.holds) ) {
260             return false;
261         }
262         var id_uc = id.toUpperCase();
263         var items = details.holds.items;
264         for (var i = 0; i < items.length; i++) {
265             if ( items[i].id.toUpperCase() == id_uc ) {
266                 return items[i];
267             }
268         }
269         return null;
270     }
271
272     function display_actions(el, id, copies_available) {
273         $(el).empty();
274         if (is_logged_in()) {
275
276             var item = item_is_checked_out(id);
277             if (item) {
278                 var expires = new Date(item.expires);
279                 $('<span class="overdrive-item-status">')
280                     .text( MSG_OVERDRIVE_CHECKEDOUT_UNTIL  + " " + expires.toLocaleString())
281                     .appendTo(el);
282                 $(el).append(" ");
283
284                 if (item.format) {
285                     var download = $('<a href="#">').appendTo(el);
286                     decorate_button(download,  MSG_DOWNLOAD  + " " + item.format);
287                     svc_ajax('get', {action: "download-url", id: id, format: item.format}, function(data) {
288                         download.attr("href", data.action);
289                     });
290                     $(el).append(" ");
291                 }
292
293                 if (item.formats) {
294                     var lockable_formats = [];
295                     for (var f in item.formats) {
296                         if (f == item.format) continue;
297
298                         if (item.formats[f]) {
299                             var access = $('<a target="_blank">').appendTo(el);
300                             decorate_button(access,  MSG_OVERDRIVE_ACCESS_ONLINE + " " + f);
301                             svc_ajax('get', {action: "download-url", id: id, format: f}, function(data) {
302                                 access.attr("href", data.action);
303                             });
304                             $(el).append(" ");
305                         }
306                         else {
307                             lockable_formats.push(f);
308                         }
309                     }
310                     if (lockable_formats.length > 0 && checkout_popup) {
311                         $(el).append( ajax_button( MSG_OVERDRIVE_DOWNLOAD_AS, function() {
312                             checkout_format(el, id, lockable_formats, copies_available);
313                         }) ).append(" ");
314                     }
315                 }
316
317                 if (item.format) return item;
318
319                 $(el).append( ajax_button( MSG_CHECK_IN, function() {
320                     if( confirm( MSG_CHECK_IN_CONFIRM ) ) {
321                         item_action({action: "return", id: id}, el, copies_available + 1);
322                     }
323                 }) );
324
325                 return item;
326             }
327
328             item = item_is_on_hold(id);
329             if (item) {
330                 $('<span class="overdrive-status">')
331                     .text( MSG_ON_HOLD )
332                     .appendTo(el);
333                 $(el).append(" ");
334             }
335
336             if(copies_available && checkout_popup) {
337                 $(el).append( ajax_button( MSG_CHECK_OUT , function() {
338                     if( confirm( MSG_CHECK_OUT_CONFIRM ) ) {
339                         svc_ajax('post', {action: "checkout", id: id}, function(data) {
340                             if (data.checkouts) {
341                                 details.checkouts = data.checkouts;
342                             }
343                             if (data.holds) {
344                                 details.holds = data.holds;
345                             }
346                             item = display_actions(el, id, copies_available - 1);
347                             if (item && item.formats && !item.format) {
348                                 var has_available_formats = false;
349                                 var lockable_formats = [];
350                                 for (var f in item.formats) {
351                                     if (item.formats[f]) {
352                                         has_available_formats = true;
353                                         break;
354                                     }
355                                     lockable_formats.push(f);
356                                 }
357
358                                 if (!has_available_formats) {
359                                     checkout_format(el, id, lockable_formats, copies_available - 1);
360                                 }
361                             }
362                         });
363                     }
364                 }) );
365             }
366             else if (!item) {
367                 $(el).append( ajax_button( MSG_PLACE_HOLD, function() {
368                     item_action({action: "place-hold", id: id}, el, copies_available);
369                 }) );
370             }
371
372             if (item) {
373                 $(el).append( ajax_button( MSG_CANCEL_HOLD, function() {
374                     if( confirm( MSG_CANCEL_HOLD_CONFIRM ) ) {
375                         item_action({action: "remove-hold", id: id}, el, copies_available);
376                     }
377                 }) );
378             }
379             return item;
380         }
381     }
382
383     function ajax_button(label, on_click) {
384         var button = $('<a href="#">')
385             .click(function(e) {
386                 e.preventDefault();
387                 on_click();
388             });
389         decorate_button(button, label);
390         return button;
391     }
392
393     function decorate_button(button, label) {
394         $(button)
395             .addClass("btn btn-primary btn-mini")
396             .css("color","white")
397             .text(label);
398     }
399
400     function checkout_format(el, id, formats, copies_available) {
401         if (formats.length == 0) {
402             alert( MSG_OVERDRIVE_CANNOT_CHECKOUT );
403             return false;
404         }
405
406         var checkout_format_list = checkout_popup.find("ul.overdrive-format-list").empty();
407         formats.forEach(function (item) {
408             var li = $('<li>').appendTo(checkout_format_list);
409             $('<input name="checkout-format" type="radio">')
410                 .val(item)
411                 .appendTo(li);
412             li.append(item);
413         });
414         checkout_popup.modal("show");
415         checkout_popup.find(".overdrive-checkout-submit").click(function(e) {
416             e.preventDefault();
417             var format = checkout_format_list.find("input[type='radio'][name='checkout-format']:checked").val();
418             item_action({action: "checkout-format", id: id, format: format}, el, copies_available);
419             $(this).unbind( e );
420             checkout_popup.modal("hide");
421         });
422     }
423
424     this.with_account_details = function( el, callback ) {
425         $(el).append(error_div);
426         load_account_details(function(data) {
427             if (!data.is_logged_in) {
428                 $(el).append(login_div);
429             }
430             callback(data);
431         });
432     };
433
434     this.display_account_details = function( el ) {
435         window.refresh_overdrive_account_details = function () {
436             KOHA.OverDriveCirculation.display_account_details( el );
437         };
438         $(el).empty().append(error_div);
439         load_account_details(function(data) {
440             display_account(el, data);
441         });
442     };
443
444     this.display_error = function( el, error ) {
445         $(el).empty().append(error_div);
446         display_error(error);
447     };
448
449     this.is_logged_in = is_logged_in;
450
451     this.add_actions = function(el, id, copies_available) {
452         var actions = $('<span class="actions">');
453         display_actions(actions, id, copies_available);
454         $('<div id="action_'+id+'" class="actions-menu">')
455             .append(actions)
456             .appendTo(el);
457     };
458 };