corrade-nucleus-nucleons – Blame information for rev 20

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 -->
20 office 15 <link href="/node_modules/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" type="text/css">
10 office 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 -->
20 office 22 <link href="/pack-rat/node_modules/jstree/dist/themes/default/style.min.css" rel="stylesheet" type="text/css">
17 office 23 <!-- Bootstrap table -->
20 office 24 <link href="/pack-rat/node_modules/bootstrap-table/dist/bootstrap-table.min.css" rel="stylesheet" type="text/css">
10 office 25 </script>
26 </head>
27  
28 <body>
29 <!-- Bootstrap Modal -->
18 office 30 <div id="item-info-modal" class="modal fade bs-example-modal-lg" role="dialog">
10 office 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>
18 office 60  
61 <!-- Give Inventory Item Destination Dialog -->
62 <div id="avatar-select-modal" class="modal fade bs-example-modal-lg" role="dialog">
63 <div class="modal-dialog modal-lg">
64 <!-- Modal content-->
10 office 65  
18 office 66 <div class="modal-content">
67 <div class="modal-header">
68 <button type="button" class="close" data-dismiss="modal">&times;</button>
69  
70 <h1 id="title" class="modal-title">Avatar Selection</h1>
71 </div>
72  
73 <form id="avatar-select-form" class="form-inline" data-toggle="validator" onSubmit="event.preventDefault();">
74 <div id="content" class="modal-body">
75 <p>Please enter the avatar firstname and lastname to send the script to.</p>
76 <div class="form-group has-feedback">
77 <label for="avatar-firstname">First Name</label>
78 <input id="avatar-firstname" type="text" class="form-control" aria-describedby="basic-addon1" required>
79 <label for="avatar-lastname">Last Name</label>
80 <input id="avatar-lastname" type="text" class="form-control" aria-describedby="basic-addon1" required>
81 </div>
82 </div>
83 <div class="modal-footer">
84 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
85 <button id="send-script" type="submit" class="btn btn-primary">Confirm</button>
86 </div>
87 </form>
88 </div>
89 </div>
90 </div>
91  
92 <!-- Texture Download Dialog -->
93 <div id="texture-download-modal" class="modal fade bs-example-modal-lg" role="dialog">
94 <div class="modal-dialog modal-lg">
95 <!-- Modal content-->
96  
97 <div class="modal-content">
98 <div class="modal-header">
99 <button type="button" class="close" data-dismiss="modal">&times;</button>
100  
101 <h1 id="title" class="modal-title">Avatar Selection</h1>
102 </div>
103  
104 <div id="content" class="modal-body">
105 <img src="" align="middle" id="texture">
106 </div>
107  
108 <div class="modal-footer">
109 <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
110 </div>
111 </div>
112 </div>
113 </div>
114  
10 office 115 <div class="container">
116 <div class="jumbotron">
117 <h1>Corrade Pack Rat</h1>
118 <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>
119 <img src="/pack-rat/img/pack-rat.png"></div>
120  
121 <!-- Will hold the inventory tree (completed dynamically). -->
122 <div id="tree">
123 </div>
124  
125 <footer class="footer">
126 <p>&copy; 2017 Wizardry and Steamworks</p>
127 </footer>
128 </div>
129 <!-- jQuery -->
20 office 130 <script src="/node_modules/jquery/dist/jquery.min.js" type="text/javascript"></script>
10 office 131 <!-- Wizardry and Steamworks JavaScript Includes -->
20 office 132 <script src="/node_modules/was/dist/was.min.js" type="text/javascript"></script>
10 office 133 <!-- Bootstrap Javascript -->
20 office 134 <script src="/node_modules/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
135 <script src="/pack-rat/node_modules/bootstrap-table/dist/bootstrap-table.min.js" type="text/javascript"></script>
10 office 136 <!-- Bootstrap Form Validator -->
20 office 137 <script src="/node_modules/bootstrap-validator/dist/validator.min.js" type="text/javascript"></script>
138 <!-- CryptoJS -->
139 <script src="/node_modules/cryptojslib/lib/Crypto.js" type="text/javascript"></script>
140 <script src="/node_modules/cryptojslib/lib/MD5.js" type="text/javascript"></script>
141 <!-- Moment JS -->
142 <script src="/pack-rat/node_modules/moment/min/moment.min.js" type="text/javascript"></script>
10 office 143 <!-- JsTree -->
20 office 144 <script src="/pack-rat/node_modules/jstree/dist/jstree.min.js" type="text/javascript"></script>
10 office 145 <!-- JSON to Table -->
20 office 146 <script src="/pack-rat/node_modules/json-to-table/json-to-table.js" type="text/javascript"></script>
10 office 147 <!-- Main script -->
148 <script type="text/javascript">
149 $(function() {
150 function customMenu(node) {
151 // The default set of menu items for all types
152 var items = {
153 // Grab information about the item.
154 infoItem: {
155 label: "Get Info",
156 action: function(obj) {
157 $.ajax({
17 office 158 //async: false,
10 office 159 type: 'POST',
160 url: '/',
161 dataType: 'json',
162 data: {
163 command: 'getinventorydata',
17 office 164 item: node.id,
165 data: wasArrayToCSV([
10 office 166 'AssetUUID',
167 'CreationDate',
168 'Description',
169 'Permissions',
170 'UUID' // part of InventoryBase
17 office 171 ])
10 office 172 }
18 office 173 }).done(function(response) {
174 if(response.success !== 'True') {
175 alert('Error moving item: ' + response.error);
176 return;
177 }
17 office 178 $('#info').bootstrapTable({
179 data: [ wasKeyValueObjectify(wasCSVToArray(response.data)) ]
180 });
18 office 181 $('#item-info-modal').modal('show');
10 office 182 });
183 }
184 }
185 };
186  
187 // Give inventory items menu for anything but folders.
188 // They could be supported too but would require first
189 // counting the number of items inside the folder and
190 // only accepting to send if the number is below max.
191 if (node.data.type != "folder") {
192 $.extend(items, {
193 giveItem: {
194 label: "Give",
195 action: function(obj) {
18 office 196 $('#avatar-select-modal')
197 .modal('show')
198 .on('click', '#send-script', function(e) {
199 $('#avatar-select-modal').modal('hide');
200 $.ajax({
201 type: 'POST',
202 url: '/',
203 data: {
204 command: 'give',
205 entity: 'avatar',
206 item: node.id,
207 firstname: $('#avatar-firstname').val(),
208 lastname: $('#avatar-lastname').val()
209 },
210 dataType: 'json'
211 }).done(function(response) {
212 if(response.success !== 'True') {
213 alert('Error sending item: ' + response.error);
10 office 214 return;
18 office 215 }
216 });
217 });
10 office 218 }
219 }
220 });
221 }
222  
223 // The "download" menu item for textures.
224 if (node.data.type == "texture" || node.data.type == "snapshot") {
225 $.extend(items, {
226 downloadItem: {
227 label: "Download",
228 "action": function(obj) {
18 office 229 $('#texture').attr('src', '/pack-rat/img/loader.gif');
230 $('#texture-download-modal').modal('show');
10 office 231 $.ajax({
232 type: 'POST',
18 office 233 url: '/',
10 office 234 data: {
18 office 235 command: 'download',
236 item: node.id,
237 format: 'Png',
238 type: 'Texture'
239 },
240 dataType: 'json'
241 }).done(function(response) {
242 $('#texture').attr('src', "data:image/png;base64," + response.data);
10 office 243 });
244 }
245 }
246 });
247 }
248  
249 // The "download" menu item for notecards.
250 if (node.data.type == "notecard") {
251 $.extend(items, {
252 downloadItem: {
253 label: "Download",
254 "action": function(obj) {
255 $('#texture').attr('src', 'images/loader.gif');
256 $('#popup').dialog({
257 width: 800,
258 height: 600,
259 modal: true,
260 resizable: false,
261 dialogClass: 'no-close texture-dialog'
262 }).on('dialogclose', function(event) {
263 $('#content').html('');
264 });
265 $.ajax({
266 type: 'POST',
267 url: "downloadNotecard.php?t=" + Math.random(),
268 data: {
269 uuid: node.id.split(/[\/]+/).pop()
270 }
271 }).done(function(data) {
272 $.base64.utf8decode = true;
273 $('#content').html('<pre>' + $.base64.atob(data) + '</pre>');
274 });
275 }
276 }
277 });
278 }
279  
280 // The "download" menu item for sounds.
281 if (node.data.type == "sound") {
282 $.extend(items, {
283 downloadItem: {
284 label: "Download",
285 "action": function(obj) {
286 $('#texture').attr('src', 'images/loader.gif');
287 $('#popup').dialog({
288 width: 800,
289 height: 600,
290 modal: true,
291 resizable: false,
292 dialogClass: 'no-close texture-dialog'
293 }).on('dialogclose', function(event) {
294 $('#content').html('');
295 });
296 $.ajax({
297 type: 'POST',
298 url: "downloadSound.php?t=" + Math.random(),
299 data: {
300 uuid: node.id.split(/[\/]+/).pop()
301 }
302 }).done(function(data) {
303 $('#content').html('<audio controls="controls"><source id="source" src="" type="audio/mp3"></source></audio>');
304 $('#source').attr('src', "data:audio/mp3;base64," + data);
305 });
306 }
307 }
308 });
309 }
310  
311 return items;
312 }
313  
314 $("#tree").jstree({
315 // - sort will sort items by date
316 // - state will store the open / closed state of the jstree
317 'plugins': ["themes", "json_data", "ui", "contextmenu", "sort", "dnd", "state"],
15 office 318 'contextmenu': {
10 office 319 "items": function(node) {
320 return customMenu(node);
321 }
15 office 322 },
10 office 323 'dnd': {
324 // Do not copy items.
325 'copy': false,
326 // Do not execute the check callback whilst dragging.
16 office 327 'check_while_dragging': true
10 office 328 },
329 'sort': function(a, b) {
16 office 330 return this.get_node(a).data.time < this.get_node(b).data.time ? 1 : -1;
10 office 331 },
332 'core': {
15 office 333 'check_callback': function(operation, node, parent, position, more) {
16 office 334 // Only allow move operations
335 if (operation !== 'move_node' ||
336 // Do not move system folders.
337 node.data.system !== false ||
338 // Do not allow moves above the root node.
339 parent.id === "#" ||
340 // Do not allow moving an item over another item.
341 (node.data.type !== 'folder' && parent.data.type !== 'folder'))
10 office 342 return false;
15 office 343  
344 var source = node.id;
345 var target = parent.id;
346  
347 // Normalize source and target.
348 if(source === '#')
349 source = '/';
350  
351 if(target === '#')
352 target = '/';
353  
354 if(source == '/' && target == '/')
16 office 355 return false;
15 office 356  
357 // Check if source path is sane.
358 if(source.split('/').some(
359 function(part) {
360 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);
361 })) {
16 office 362 return false;
15 office 363 }
364  
365 // Check if target path is sane.
366 if(target.split('/').some(
367 function(part) {
368 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);
369 })) {
16 office 370 return false;
15 office 371 }
372  
16 office 373 return true;
15 office 374 },
10 office 375 data: function(node, callback) {
376 if(node.id === '#') {
377 callback.call(this, [
378 {
379 "id" : "/My Inventory",
380 "parent" : "#",
381 "text" : "My Inventory",
382 "data" : {
16 office 383 "type" : "folder",
384 'time' : Date.now(),
385 'system' : true
10 office 386 },
387 "children" : true,
388 "opened" : false
389 },
390 {
391 "id" : "/Library",
392 "parent" : "#",
393 "text" : "Library",
394 "data" : {
16 office 395 "type" : "folder",
396 'time' : Date.now(),
397 'system' : true
10 office 398 },
399 "children" : true,
400 "opened" : false
401 }
402 ]);
403 return;
404 }
405 $.ajax({
406 //async: false,
407 type: 'POST',
408 url: '/',
409 dataType: 'json',
410 data: {
411 command: 'inventory',
412 action: 'ls',
413 path: node.id
414 }
415 }).done(function(response) {
14 office 416 var list = [];
417 $.each(wasCSVToArray(response.data)
16 office 418 .chunk(10),
419 function(i, e) {
420 e = wasKeyValueObjectify(e);
421 //alert(node.id + " to " + JSON.stringify(e, 4, null));
422 list.push({
423 'id' : node.id === '/' ? '/' + e['item'] : node.id + '/' + e['item'],
424 'parent' : node.id,
425 'data' : {
426 'type' : e['type'],
427 'time' : Date.parse(e['time']),
428 // Check if this folder is a system folder.
429 'system' : node.id === '/My Inventory' && (
430 e['name'] === 'Trash' ||
431 e['name'] === 'Notecards' ||
432 e['name'] === 'Scripts' ||
433 e['name'] === 'Lost And Found' ||
434 e['name'] === 'Landmarks' ||
435 e['name'] === 'Current Outfit' ||
436 e['name'] === 'Calling Cards' ||
437 e['name'] === 'Textures' ||
438 e['name'] === 'Objects' ||
439 e['name'] === 'My Outfits' ||
440 e['name'] === 'Clothing' ||
441 e['name'] === 'Body Parts' ||
442 e['name'] === 'Photo Album' ||
443 e['name'] === 'Favorites' ||
444 e['name'] === 'Gestures' ||
445 e['name'] === 'Animations'
446 )
447 },
448 'text' : e['name'],
449 'children' : e['type'] === 'folder',
450 'icon' : '/pack-rat/img/icons/' + e['type'] + '.gif',
451 'opened' : 'false'
14 office 452 });
13 office 453 });
14 office 454 callback.call(this, list);
10 office 455 });
456 }
457 }
458 }).bind('move_node.jstree', function(e, data) {
16 office 459 $.ajax({
460 //async: false,
461 type: 'POST',
462 url: '/',
463 dataType: 'json',
464 data: {
465 command: 'inventory',
466 action: 'mv',
467 source: data.node.id,
468 target: data.parent
469 }
470 }).done(function(response) {
471 if(response.success !== 'True') {
472 alert('Error moving item: ' + response.error);
473 }
474 });
10 office 475 // Once the node is moved, update the node ID to reflect the path change.
476 var parentPath = data.parent != '/' ? data.parent : "";
477 var item = data.node.id.split(/[\/]+/).pop();
478 data.instance.set_id(data.node, parentPath + '/' + item);
479 });
480 });
481 </script>
482 </body>
483 </html>