]> git.ktnx.net Git - lsl.git/blob - public/javascripts/lsl.js
add a splash screen
[lsl.git] / public / javascripts / lsl.js
1 "use strict";
2 (function(){
3 var uri_base, environment, devel_env;   // filled on page load from an HTML attribute
4 var start_time = Date.now();
5
6 var ui_icon_class_re = new RegExp('\\bui-icon-\\S+\\b');
7 var uri_id_re = new RegExp('/(\\d+)$');
8 var lists_version = -1;
9 var lists = [];
10 var selected_list;
11
12 function debug(...args) {
13     if (devel_env)
14         console.debug.apply(console, args);
15 }
16
17 function uri_id(uri) {
18     var m = uri.match(uri_id_re);
19     return m ? m[1] : null;
20 }
21 function add_list_item(data) {
22     var item = $('<li>').addClass('list-item-row').data('item', data);
23     var cb = $('<input type="checkbox">');
24     if (data.done) cb.prop('checked', true);
25     item.append(cb);
26     item.append($('<span class="description">').text(data.description || ''));
27     item.append($('<span class="edit-trigger">').text('…'));
28
29     $('#list-items').append(item);
30     $('#list-contents').addClass('have-list-items');
31 }
32 function got_lists_version(new_version) {
33     if (new_version != lists_version)
34         window.setTimeout(load_lists);
35 }
36 function got_list_version(new_version) {
37     if (new_version != selected_list.attr('lsl-version'))
38         window.setTimeout(
39             () => load_list_items(selected_list.data('lsl-uri'), selected_list));
40 }
41 function load_list_items(uri, target) {
42     $.get(uri)
43     .done(item_data => {
44         target.data('items', item_data);
45
46         // TODO: merge new items into existing ones
47         // keep track of the last existing item, and append new one
48         // after it, prepending if there is no last existing item
49         // the newly prepended/inserted item becomes the last existing
50         $('#list-contents').removeClass('have-list-items');
51         var item_list = $('#list-items').empty();
52
53         $.each(item_data.items, (i,item) => {
54             add_list_item(item);
55         });
56
57         got_lists_version(item_data.lists_version);
58     });
59 }
60 function select_list(new_selected_list) {
61     if (new_selected_list && selected_list
62         && new_selected_list.length && selected_list.length
63         && new_selected_list.get(0) == selected_list.get(0)
64     )
65         return;
66
67     if (new_selected_list && !new_selected_list.length)
68         new_selected_list = null;
69
70     $('#page').toggleClass('have-lists', !!new_selected_list);
71
72     if (selected_list)
73         selected_list.removeClass('selected');
74
75     if (new_selected_list) {
76         load_list_items(new_selected_list.data('lsl-uri'), new_selected_list);
77         new_selected_list.addClass('selected');
78         $('#selected-list-name').text(new_selected_list.data('lsl-name'));
79     }
80
81     selected_list = new_selected_list;
82 }
83 function load_lists() {
84     $.get(uri_base + '/api/v1/list')
85     .always(()=>{
86         var splash = $('#splash');
87         if (splash.length) {
88             var dur = splash.css('transition-duration');
89             if (dur && dur.endsWith('s')) {
90                 dur = 1000 * parseFloat(dur.substring(0, dur.length-1));
91             }
92             else
93                 dur = 1000;
94
95             var now = Date.now();
96             window.setTimeout(() => {
97                 splash.addClass('done');
98                 debug('scheduling splash removal in '+dur+'ms');
99                 window.setTimeout(()=>{ splash.remove(); }, dur);
100             },
101                 Math.max(0, 500 - (now - start_time))
102             );
103         }
104     })
105     .done(data => {
106         lists_version = data.lists_version;
107
108         var lists = $('#lists');
109         lists.find('>li').addClass('old');
110
111         $.each(data.lists, (i, list) => {
112             var list_id = uri_id(list.uri);
113             var existing = lists.find('li#list-'+list_id);
114             if (existing.length) {
115                 existing.data('lsl-version', list.version)
116                 .data('lsl-name', list.name)
117                 .text(list.name)
118                 .removeClass('old');
119             }
120             else {
121                 var list_item = $('<li>')
122                     .prop('id', 'list-'+list_id)
123                     .data('lsl-uri', list.uri)
124                     .data('lsl-version', list.version)
125                     .data('lsl-name', list.name)
126                     .text(list.name);
127                 lists.append(list_item);
128             }
129         });
130
131         if (!selected_list || selected_list.hasClass('old'))
132             select_list(lists.find('>li').eq(0));
133
134         lists.find('li.old').remove();
135     });
136 }
137 function new_list_submission_done(data) {
138     if (data.lists_version != lists_version) {
139         load_lists();
140         return;
141     }
142
143     console.log("TODO: easy-add new list");
144
145 }
146 function handle_new_list_submission(){
147     $.post(uri_base + '/api/v1/list',
148         JSON.stringify({name:$('input[name="list_name"]').val()}))
149     .done(new_list_submission_done);
150     return false;
151 }
152 function new_list_item_submission_done(data) {
153     got_lists_version(data.lists_version);
154     got_list_version(data.list_version);
155
156     var item_data = selected_list.data('items');
157
158     var new_item = {
159         description: $('#new-list-item input[type="text"]').val().trim(),
160         done: $('#new-list-item input[type="checkbox"]').prop('checked'),
161         version: 1,
162     };
163     item_data.items.push(new_item);
164     item_data.version = data.version;
165     add_list_item(new_item);
166
167     $('#new-list-item input').val('');
168 }
169 function handle_new_list_item_submission(){
170     var description = $('#new-list-item input[type="text"]').val().trim();
171     if (description.length == 0) return;
172
173     $.post(selected_list.data('lsl-uri'),
174         JSON.stringify({
175             description: description,
176             done: $('#new-list-item input[type="checkbox"]').prop('checked')
177         }),
178     )
179     .done(new_list_item_submission_done);
180 }
181 function handle_list_item_state_changed(ev) {
182     var item = $(ev.target).closest('li');
183     var cb = item.find('input[type="checkbox"]');
184     var item_data = item.data('item');
185
186     $.ajax(item_data.uri,
187         {   type: 'PUT',
188             data: JSON.stringify({
189                 version: item_data.version,
190                 done: cb.prop('checked')})
191         }
192     )
193     .done(function(resp){
194         item_data.version = resp.version;
195         got_lists_version(resp.lists_version);
196         got_list_version(resp.list_version);
197     });
198 }
199 $(function(){
200     uri_base = $('#page').attr('lsl-uri-base');
201     environment = $('#page').attr('lsl-environment');
202     devel_env = environment == 'development';
203
204     $(document).ajaxStart(function(){
205         $(document).addClass('blocked');
206         window.setTimeout(
207             function() {
208                 $(document).addClass('busy');
209             }
210         );
211     });
212     $(document).ajaxStop(function(){
213         $(document).removeClass('busy');
214         window.setTimeout(
215             function() {
216                 $(document).removeClass('blocked');
217             },
218             1000 );
219     });
220     $.ajaxSetup({contentType: 'application/json'});
221     $('button, input[type="submit"], input[type="reset"]').each(function(){
222         var class_prop = $(this).prop('class');
223         var icon_classes = class_prop.match(ui_icon_class_re);
224         $(this).button({icon: icon_classes?icon_classes[0]:null});
225     });
226
227     $('#new-list-sidebar-item button').on('click', handle_new_list_submission);
228     $('#new-list-sidebar-item input').on('keypress', function(ev) {
229         if (13 == ev.keyCode) {
230             handle_new_list_submission();
231             return false;
232         }
233
234         return true;
235     });
236     $('ul#lists').on('click', 'li', ev=>{
237         select_list($(ev.target));
238     });
239     $('#new-list-item button').on('click', handle_new_list_item_submission);
240     $('#new-list-item input').on('keypress', ev => {
241         if (13 == ev.keyCode) {
242             handle_new_list_item_submission();
243             return false;
244         }
245         return true;
246     });
247     $('#list-items').on('change', '.list-item-row input[type="checkbox"]', handle_list_item_state_changed);
248     load_lists();
249 });
250 })();