corrade-nucleus-nucleons – Blame information for rev 17

Subversion Repositories:
Rev:
Rev Author Line No. Line
10 office 1 <!DOCTYPE html>
2  
3 <html lang="en">
4 <head>
5 <meta charset="utf-8">
6 <meta http-equiv="X-UA-Compatible" content="IE=edge">
7 <meta name="viewport" content="width=device-width, initial-scale=1">
8 <meta name="description" content="Corrade Nucleon">
9 <meta name="author" content="Wizardry and Steamworks">
10 <link rel="icon" href="favicon.ico">
11  
12 <title>Corrade Nucleus - Pack Rat Inventory Manager</title>
13  
14 <!-- Bootstrap core CSS -->
15 <link href="/bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
16 <!-- Corrade Nucleus Fonts -->
17 <link href="/css/nucleus/fonts.css" rel="stylesheet" type="text/css">
18 <!-- Customized bootstrap style. -->
19 <link href="/css/nucleus/nucleus.css" rel="stylesheet" type="text/css">
20  
21 <!-- jsTree style -->
22 <link href="/pack-rat/bower_components/jstree/dist/themes/default/style.min.css" rel="stylesheet" type="text/css">
17 office 23 <!-- Bootstrap table -->
24 <link href="/pack-rat/bower_components/bootstrap-table/dist/bootstrap-table.min.css" rel="stylesheet" type="text/css">
10 office 25 </script>
26 </head>
27  
28 <body>
29 <!-- Bootstrap Modal -->
30 <div id="popup" class="modal fade bs-example-modal-lg" role="dialog">
31 <div class="modal-dialog modal-lg">
32 <!-- Modal content-->
33  
34 <div class="modal-content">
35 <div class="modal-header">
36 <button type="button" class="close" data-dismiss="modal">&times;</button>
37  
38 <h1 id="title" class="modal-title"></h1>
39 </div>
40  
41 <div id="content" class="modal-body">
17 office 42 <table id="info" data-height="460">
43 <thead>
44 <tr>
45 <th data-field="AssetUUID">Asset UUID</th>
46 <th data-field="CreationDate">Creation Date</th>
47 <th data-field="Description">Description</th>
48 <th data-field="Permissions">Permissions</th>
49 <th data-field="UUID">Inventory UUID</th>
50 </tr>
51 </thead>
52 </table>
10 office 53 </div>
17 office 54 <div class="modal-footer">
55 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
56 </div>
10 office 57 </div>
58 </div>
59 </div>
60  
61 <div class="container">
62 <div class="jumbotron">
63 <h1>Corrade Pack Rat</h1>
64 <p class="lead">Pack Rat is an inventory manager for Corrade Nucleus that allows you to sort your inventory and perform other management operations.</p>
65 <img src="/pack-rat/img/pack-rat.png"></div>
66  
67 <!-- Will hold the inventory tree (completed dynamically). -->
68 <div id="tree">
69 </div>
70  
71 <footer class="footer">
72 <p>&copy; 2017 Wizardry and Steamworks</p>
73 </footer>
74 </div>
75 <!-- jQuery -->
76 <script src="/bower_components/jquery/dist/jquery.min.js" type="text/javascript"></script>
77 <!-- Wizardry and Steamworks JavaScript Includes -->
78 <script src="/bower_components/was/dist/was.min.js" type="text/javascript"></script>
79 <!-- Bootstrap Javascript -->
80 <script type="text/javascript" src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
17 office 81 <script type="text/javascript" src="/pack-rat/bower_components/bootstrap-table/dist/bootstrap-table.min.js"></script>
10 office 82 <!-- Bootstrap Form Validator -->
83 <script src="/pack-rat/bower_components/bootstrap-validator/dist/validator.min.js" type="text/javascript"></script>
84 <!-- XML <-> JSON -->
85 <!-- <script src="/bootstrap/bower_components/x2js/xml2json.min.js" type="text/javascript"></script> -->
86 <!-- CryptoJS -->
87 <script src="/bower_components/cryptojslib/components/core.js" type="text/javascript"></script>
88 <script src="/bower_components/cryptojslib/rollups/md5.js" type="text/javascript"></script>
89 <!-- Form To Object -->
90 <!-- <script src="/bootstrap/node_modules/form_to_object/dist/formToObject.min.js" type="text/javascript"></script> -->
91 <!-- Load form processor. -->
92 <!-- <script src="/bootstrap/js/corrade-bootstrap-processor.js" type="text/javascript"></script> -->
93 <!-- Moment JS -->
94 <script src="/pack-rat/bower_components/moment/min/moment.min.js" type="text/javascript"></script>
95 <!-- JsTree -->
96 <script src="/pack-rat/bower_components/jstree/dist/jstree.min.js" type="text/javascript"></script>
97 <!-- JSON to Table -->
98 <script src="/pack-rat/bower_components/json-to-table/json-to-table.js" type="text/javascript"></script>
99 <!-- Main script -->
100 <script type="text/javascript">
101 $(function() {
102 function customMenu(node) {
103 // The default set of menu items for all types
104 var items = {
105 // Grab information about the item.
106 infoItem: {
107 label: "Get Info",
108 action: function(obj) {
109 $.ajax({
17 office 110 //async: false,
10 office 111 type: 'POST',
112 url: '/',
113 dataType: 'json',
114 data: {
115 command: 'getinventorydata',
17 office 116 item: node.id,
117 data: wasArrayToCSV([
10 office 118 'AssetUUID',
119 'CreationDate',
120 'Description',
121 'Permissions',
122 'UUID' // part of InventoryBase
17 office 123 ])
10 office 124 }
17 office 125 $('#info').bootstrapTable({
126 data: [ wasKeyValueObjectify(wasCSVToArray(response.data)) ]
127 });
128 $('#popup').modal('show');
10 office 129 });
130 }
131 }
132 };
133  
134 // Give inventory items menu for anything but folders.
135 // They could be supported too but would require first
136 // counting the number of items inside the folder and
137 // only accepting to send if the number is below max.
138 if (node.data.type != "folder") {
139 $.extend(items, {
140 giveItem: {
141 label: "Give",
142 action: function(obj) {
143 $("#content").html('<form><fieldset class="ui-helper-reset"><label for="firstname">Firstname</label><input type="text" name="firstname" id="firstname" value="" class="ui-widget-content ui-corner-all"><br/><label for="lastname">Lastname</label><input type="text" name="lastname" id="lastname" value="" class="ui-widget-content ui-corner-all"></fieldset></form>');
144 $("#popup").dialog({
145 width: 320,
146 height: 180,
147 modal: true,
148 resizable: false,
149 buttons: {
150 Select: function() {
151 if ($.trim($("#firstname").val()) == '' ||
152 $.trim($("#lastname").val()) == '')
153 return;
154 var firstName = $("#firstname").val();
155 var lastName = $("#lastname").val();
156 $.ajax({
157 type: 'POST',
158 url: "giveInventoryItem.php?t=" + Math.random(),
159 data: {
160 uuid: node.id.split(/[\/]+/).pop(),
161 firstname: firstName,
162 lastname: lastName
163 }
164 }).done(function(data) {
165 $("#popup").dialog("close");
166 if ($.trim(data) != '')
167 alert(data);
168 });
169 },
170 Cancel: function() {
171 $("#popup").dialog("close");
172 }
173 }
174 }).on('dialogclose', function(event) {
175 $('#content').html('');
176 $('#popup').dialog('option', 'buttons', {});
177 });
178 }
179 }
180 });
181 }
182  
183 // The "download" menu item for textures.
184 if (node.data.type == "texture" || node.data.type == "snapshot") {
185 $.extend(items, {
186 downloadItem: {
187 label: "Download",
188 "action": function(obj) {
189 $('#texture').attr('src', 'images/loader.gif');
190 $('#popup').dialog({
191 width: 800,
192 height: 600,
193 modal: true,
194 resizable: false,
195 dialogClass: 'no-close texture-dialog'
196 }).on('dialogclose', function(event) {
197 $('#content').html('');
198 });
199 $.ajax({
200 type: 'POST',
201 url: "downloadTexture.php?t=" + Math.random(),
202 data: {
203 uuid: node.id.split(/[\/]+/).pop()
204 }
205 }).done(function(data) {
206 $('#content').html('<img src="" align="middle" id="texture">');
207 $('#texture').attr('src', "data:image/png;base64," + data);
208 });
209 }
210 }
211 });
212 }
213  
214 // The "download" menu item for notecards.
215 if (node.data.type == "notecard") {
216 $.extend(items, {
217 downloadItem: {
218 label: "Download",
219 "action": function(obj) {
220 $('#texture').attr('src', 'images/loader.gif');
221 $('#popup').dialog({
222 width: 800,
223 height: 600,
224 modal: true,
225 resizable: false,
226 dialogClass: 'no-close texture-dialog'
227 }).on('dialogclose', function(event) {
228 $('#content').html('');
229 });
230 $.ajax({
231 type: 'POST',
232 url: "downloadNotecard.php?t=" + Math.random(),
233 data: {
234 uuid: node.id.split(/[\/]+/).pop()
235 }
236 }).done(function(data) {
237 $.base64.utf8decode = true;
238 $('#content').html('<pre>' + $.base64.atob(data) + '</pre>');
239 });
240 }
241 }
242 });
243 }
244  
245 // The "download" menu item for sounds.
246 if (node.data.type == "sound") {
247 $.extend(items, {
248 downloadItem: {
249 label: "Download",
250 "action": function(obj) {
251 $('#texture').attr('src', 'images/loader.gif');
252 $('#popup').dialog({
253 width: 800,
254 height: 600,
255 modal: true,
256 resizable: false,
257 dialogClass: 'no-close texture-dialog'
258 }).on('dialogclose', function(event) {
259 $('#content').html('');
260 });
261 $.ajax({
262 type: 'POST',
263 url: "downloadSound.php?t=" + Math.random(),
264 data: {
265 uuid: node.id.split(/[\/]+/).pop()
266 }
267 }).done(function(data) {
268 $('#content').html('<audio controls="controls"><source id="source" src="" type="audio/mp3"></source></audio>');
269 $('#source').attr('src', "data:audio/mp3;base64," + data);
270 });
271 }
272 }
273 });
274 }
275  
276 return items;
277 }
278  
279 $("#tree").jstree({
280 // - sort will sort items by date
281 // - state will store the open / closed state of the jstree
282 'plugins': ["themes", "json_data", "ui", "contextmenu", "sort", "dnd", "state"],
15 office 283 'contextmenu': {
10 office 284 "items": function(node) {
285 return customMenu(node);
286 }
15 office 287 },
10 office 288 'dnd': {
289 // Do not copy items.
290 'copy': false,
291 // Do not execute the check callback whilst dragging.
16 office 292 'check_while_dragging': true
10 office 293 },
294 'sort': function(a, b) {
16 office 295 return this.get_node(a).data.time < this.get_node(b).data.time ? 1 : -1;
10 office 296 },
297 'core': {
15 office 298 'check_callback': function(operation, node, parent, position, more) {
16 office 299 // Only allow move operations
300 if (operation !== 'move_node' ||
301 // Do not move system folders.
302 node.data.system !== false ||
303 // Do not allow moves above the root node.
304 parent.id === "#" ||
305 // Do not allow moving an item over another item.
306 (node.data.type !== 'folder' && parent.data.type !== 'folder'))
10 office 307 return false;
15 office 308  
309 var source = node.id;
310 var target = parent.id;
311  
312 // Normalize source and target.
313 if(source === '#')
314 source = '/';
315  
316 if(target === '#')
317 target = '/';
318  
319 if(source == '/' && target == '/')
16 office 320 return false;
15 office 321  
322 // Check if source path is sane.
323 if(source.split('/').some(
324 function(part) {
325 return /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/.test(part);
326 })) {
16 office 327 return false;
15 office 328 }
329  
330 // Check if target path is sane.
331 if(target.split('/').some(
332 function(part) {
333 return /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/.test(part);
334 })) {
16 office 335 return false;
15 office 336 }
337  
16 office 338 return true;
15 office 339 },
10 office 340 data: function(node, callback) {
341 if(node.id === '#') {
342 callback.call(this, [
343 {
344 "id" : "/My Inventory",
345 "parent" : "#",
346 "text" : "My Inventory",
347 "data" : {
16 office 348 "type" : "folder",
349 'time' : Date.now(),
350 'system' : true
10 office 351 },
352 "children" : true,
353 "opened" : false
354 },
355 {
356 "id" : "/Library",
357 "parent" : "#",
358 "text" : "Library",
359 "data" : {
16 office 360 "type" : "folder",
361 'time' : Date.now(),
362 'system' : true
10 office 363 },
364 "children" : true,
365 "opened" : false
366 }
367 ]);
368 return;
369 }
370 $.ajax({
371 //async: false,
372 type: 'POST',
373 url: '/',
374 dataType: 'json',
375 data: {
376 command: 'inventory',
377 action: 'ls',
378 path: node.id
379 }
380 }).done(function(response) {
14 office 381 var list = [];
382 $.each(wasCSVToArray(response.data)
16 office 383 .chunk(10),
384 function(i, e) {
385 e = wasKeyValueObjectify(e);
386 //alert(node.id + " to " + JSON.stringify(e, 4, null));
387 list.push({
388 'id' : node.id === '/' ? '/' + e['item'] : node.id + '/' + e['item'],
389 'parent' : node.id,
390 'data' : {
391 'type' : e['type'],
392 'time' : Date.parse(e['time']),
393 // Check if this folder is a system folder.
394 'system' : node.id === '/My Inventory' && (
395 e['name'] === 'Trash' ||
396 e['name'] === 'Notecards' ||
397 e['name'] === 'Scripts' ||
398 e['name'] === 'Lost And Found' ||
399 e['name'] === 'Landmarks' ||
400 e['name'] === 'Current Outfit' ||
401 e['name'] === 'Calling Cards' ||
402 e['name'] === 'Textures' ||
403 e['name'] === 'Objects' ||
404 e['name'] === 'My Outfits' ||
405 e['name'] === 'Clothing' ||
406 e['name'] === 'Body Parts' ||
407 e['name'] === 'Photo Album' ||
408 e['name'] === 'Favorites' ||
409 e['name'] === 'Gestures' ||
410 e['name'] === 'Animations'
411 )
412 },
413 'text' : e['name'],
414 'children' : e['type'] === 'folder',
415 'icon' : '/pack-rat/img/icons/' + e['type'] + '.gif',
416 'opened' : 'false'
14 office 417 });
13 office 418 });
14 office 419 callback.call(this, list);
10 office 420 });
421 }
422 }
423 }).bind('move_node.jstree', function(e, data) {
16 office 424 $.ajax({
425 //async: false,
426 type: 'POST',
427 url: '/',
428 dataType: 'json',
429 data: {
430 command: 'inventory',
431 action: 'mv',
432 source: data.node.id,
433 target: data.parent
434 }
435 }).done(function(response) {
436 if(response.success !== 'True') {
437 alert('Error moving item: ' + response.error);
438 }
439 });
10 office 440 // Once the node is moved, update the node ID to reflect the path change.
441 var parentPath = data.parent != '/' ? data.parent : "";
442 var item = data.node.id.split(/[\/]+/).pop();
443 data.instance.set_id(data.node, parentPath + '/' + item);
444 });
445 });
446 </script>
447 </body>
448 </html>