blob: 916b0924337d45529113ed3cffedf5c6cedb7e55 [file] [log] [blame]
Alexander Afanasyeve16ed212016-12-25 18:09:44 -08001info_actions_collection = [];
2info_actions_counter = 0;
3info_files_collection = [];
4info_files_counter = 0;
5lastSegmentRequested = -1;
6file_data = "";
7file_segments = 0;
8file_callback = file_onData;
9restore_callback = file_onData;
10
11face = null;
12
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080013$.Class("ChronoShare", {}, {
14 init: function(username, foldername) {
15 $("#folder-name").text(foldername);
16 $("#user-name").text(username);
Alexander Afanasyev46bd8062013-02-27 23:59:15 -080017
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080018 this.username = new Name(username);
Alexander Afanasyeve16ed212016-12-25 18:09:44 -080019 this.files = new Name("/localhop")
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080020 .add(this.username)
21 .add("chronoshare")
22 .add(foldername)
23 .add("info")
24 .add("files")
25 .add("folder");
Alexander Afanasyev46bd8062013-02-27 23:59:15 -080026
Alexander Afanasyeve16ed212016-12-25 18:09:44 -080027 this.actions = new Name("/localhop")
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080028 .add(this.username)
29 .add("chronoshare")
30 .add(foldername)
31 .add("info")
32 .add("actions");
Alexander Afanasyev46bd8062013-02-27 23:59:15 -080033
Alexander Afanasyeve16ed212016-12-25 18:09:44 -080034 this.restore = new Name("/localhop")
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080035 .add(this.username)
36 .add("chronoshare")
37 .add(foldername)
38 .add("cmd")
39 .add("restore")
40 .add("file");
Alexander Afanasyev46bd8062013-02-27 23:59:15 -080041
Alexander Afanasyeve16ed212016-12-25 18:09:44 -080042
43 $("#json").empty();
44
45 if (face == null) {
46 var host = "localhost";
47 // Connect to the forwarder with a WebSocket.
48 face = new Face({host: host});
49 console.log("Init Face OK!");
50 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080051 },
Alexander Afanasyev46bd8062013-02-27 23:59:15 -080052
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080053 run: function() {
54 console.log("RUN page: " + PAGE);
55 $("#loader").fadeIn(500);
56 $("#error").addClass("hidden");
Alexander Afanasyev46bd8062013-02-27 23:59:15 -080057
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080058 cmd = {};
59 if (PAGE == "fileList") {
Alexander Afanasyeve16ed212016-12-25 18:09:44 -080060 info_files_collection = [];
61 info_files_counter = 0;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080062 cmd = this.info_files(PARAMS.item);
63 }
64 else if (PAGE == "folderHistory") {
Alexander Afanasyeve16ed212016-12-25 18:09:44 -080065 info_actions_collection = [];
66 info_actions_counter = 0;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080067 cmd = this.info_actions("folder", PARAMS.item);
68 }
69 else if (PAGE == "fileHistory") {
Alexander Afanasyeve16ed212016-12-25 18:09:44 -080070 info_actions_collection = [];
71 info_actions_counter = 0;
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080072 cmd = this.info_actions("file", PARAMS.item);
73 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080074 },
Alexander Afanasyevf63a5142013-02-28 02:21:42 -080075
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080076 info_files: function(folder) {
77 request = new Name()
78 .add(this.files)
79 ./*add (folder_in_question).*/ addSegment(
80 PARAMS.offset ? PARAMS.offset : 0);
Alexander Afanasyeve16ed212016-12-25 18:09:44 -080081 face.expressInterest(request, info_files_onData, on_Timeout);
82 console.log("Express OK: " + request.to_uri());
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080083 },
Alexander Afanasyevf63a5142013-02-28 02:21:42 -080084
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080085 info_actions: function(type /*"file" or "folder"*/,
86 fileOrFolder /*file or folder name*/) {
87 if (type == "file" && !fileOrFolder) {
88 return {error: "info_actions: fileOrFolder parameter is missing"};
89 }
Alexander Afanasyevf63a5142013-02-28 02:21:42 -080090
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080091 request = new Name().add(this.actions).add(type);
92 if (fileOrFolder) {
93 request.add(fileOrFolder);
94 }
95 request.addSegment(PARAMS.offset ? PARAMS.offset : 0);
Alexander Afanasyeve16ed212016-12-25 18:09:44 -080096
97 face.expressInterest(request, info_actions_onData, on_Timeout);
98 console.log("Express OK: " + request.to_uri());
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -080099 },
Alexander Afanasyev46bd8062013-02-27 23:59:15 -0800100
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800101 cmd_restore_file:
102 function(filename, version, hash,
103 callback /*function (bool <- data received, status <- returned status)*/) {
104 request =
105 new Name().add(this.restore).add(filename).addSegment(version).add(hash);
106 console.log(request.to_uri());
Alexander Afanasyeve16ed212016-12-25 18:09:44 -0800107
108 restore_callback = callback;
109 face.expressInterest(request, restore_onData, on_Timeout);
Alexander Afanasyev4c17b482013-03-02 01:32:35 -0800110 },
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800111
112 get_file:
113 function(modifiedBy, hash, segments,
114 callback /*function (bool <- data received, data <- returned data)*/) {
115 baseName = new Name(modifiedBy).add("chronoshare").add("file").add(hash);
116
Alexander Afanasyeve16ed212016-12-25 18:09:44 -0800117 lastSegmentRequested = 0;
118 file_data = "";
119 file_segments = segments;
120 file_callback = callback;
121
122 request = new Name().add(baseName).addSegment(lastSegmentRequested);
123 console.log("Express get_file Name: ", request.to_uri());
124 console.log("Total Segments: ", file_segments);
125 face.expressInterest(request, file_onData, on_Timeout);
126
127 },
128
Alexander Afanasyev4c17b482013-03-02 01:32:35 -0800129});
130
Alexander Afanasyeve16ed212016-12-25 18:09:44 -0800131function restore_onData(interest, upcallInfo)
132{
133 convertedData = upcallInfo.getContent().buf().toString('binary');
134 console.log("restore_onData");
135 console.log(convertedData);
136 restore_callback(true, convertedData);
137};
138
139function file_onData(interest, upcallInfo)
140{
141 convertedData = upcallInfo.getContent().buf().toString('binary');
142 console.log("file_onData");
143 console.log(convertedData);
144 file_data += convertedData;
145 if (lastSegmentRequested + 1 == file_segments) {
146 file_callback(true, file_data);
147 }
148 else {
149 lastSegmentRequested++;
150 nextSegment =
151 interest.getName().getPrefix(-1).addSegment(lastSegmentRequested);
152 face.expressInterest(nextSegment, file_onData, on_Timeout);
153 }
154};
155
156function info_actions_onData(interest, upcallInfo)
157{
158 convertedData = upcallInfo.getContent().buf().toString(
159 'binary'); //DataUtils.toString (upcallInfo.contentObject.content);
160 console.log(convertedData);
161 moreName = "more";
162 collectionName = "actions";
163
164 if (PARAMS.debug) {
165 $("#json").append($(document.createTextNode(convertedData)));
166 $("#json").removeClass("hidden");
167 }
168
169 console.log("Prefix");
170 console.log(interest.getName().getPrefix(-1).to_uri());
171
172 data = JSON.parse(convertedData);
173 console.log(data);
174 console.log(data[collectionName]);
175 var collection = data[collectionName];
176 info_actions_collection = info_actions_collection.concat(data[collectionName]);
177
178 console.log(info_actions_collection);
179
180 if (data[moreName] !== undefined) {
181 nextSegment = interest.getName().getPrefix(-1).addSegment(data[moreName]);
182 info_actions_counter++;
183
184 if (info_actions_counter < 5) {
185 console.log("MORE: " + nextSegment.to_uri());
186 face.expressInterest(nextSegment, info_actions_onData, on_Timeout);
187 }
188 else {
189 $("#loader").fadeOut(500); // ("hidden");
190 var HD = new HistoryDisplay(CHRONOSHARE);
191 HD.onData(info_actions_collection, data[moreName]);
192 }
193 }
194 else {
195 $("#loader").fadeOut(500); // ("hidden");
196 console.log("I'm triggered more undefined~");
197 var HD = new HistoryDisplay(CHRONOSHARE);
198 HD.onData(info_actions_collection, undefined);
199 }
200};
201
202function info_files_onData(interest, upcallInfo)
203{
204 convertedData = upcallInfo.getContent().buf().toString(
205 'binary'); //DataUtils.toString (upcallInfo.contentObject.content);
206 console.log(convertedData);
207 moreName = "more";
208 collectionName = "files";
209
210 if (PARAMS.debug) {
211 $("#json").append($(document.createTextNode(convertedData)));
212 $("#json").removeClass("hidden");
213 }
214
215 console.log("Prefix");
216 console.log(interest.getName().getPrefix(-1).to_uri());
217
218 data = JSON.parse(convertedData);
219 console.log(data);
220 console.log(data[collectionName]);
221 var collection = data[collectionName];
222 info_files_collection = info_files_collection.concat(data[collectionName]);
223
224 console.log(info_files_collection);
225
226 if (data[moreName] !== undefined) {
227 nextSegment = interest.getName().getPrefix(-1).addSegment(data[moreName]);
228 info_files_counter++;
229
230 if (info_files_counter < 5) {
231 console.log("MORE: " + nextSegment.to_uri());
232 face.expressInterest(nextSegment, info_files_onData, on_Timeout);
233 }
234 else {
235 $("#loader").fadeOut(500); // ("hidden");
236 var HD = new FilesDisplay(CHRONOSHARE);
237 HD.onData(info_files_collection, data[moreName]);
238 }
239 }
240 else {
241 $("#loader").fadeOut(500); // ("hidden");
242 console.log("I'm triggered more undefined~");
243 var HD = new FilesDisplay(CHRONOSHARE);
244 HD.onData(info_files_collection, undefined);
245 }
246};
247
248
249function on_Timeout(interest)
250{
251 $("#error").html("Ha Ha Interest time out");
252 $("#error").removeClass("hidden");
253}
254
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800255$.Class("CmdRestoreFileClosure", {}, {
256 init: function(chronoshare, callback) {
257 this.chronoshare = chronoshare;
258 this.callback = callback;
259 },
260 upcall: function(kind, upcallInfo) {
261 if (kind == Closure.UPCALL_CONTENT ||
Alexander Afanasyeve16ed212016-12-25 18:09:44 -0800262 kind == Closure.UPCALL_CONTENT_UNVERIFIED) { //disable content verification
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800263 convertedData = DataUtils.toString(upcallInfo.contentObject.content);
264 this.callback(true, convertedData);
Alexander Afanasyevc24db642013-03-09 16:41:02 -0800265 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800266 else if (kind == Closure.UPCALL_INTEREST_TIMED_OUT) {
Alexander Afanasyeve16ed212016-12-25 18:09:44 -0800267 this.callback(false, "Interest timed out 99");
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800268 }
269 else {
270 this.callback(false, "Unknown error happened");
271 }
272 }
Alexander Afanasyevc24db642013-03-09 16:41:02 -0800273});
274
Alexander Afanasyev1663a412013-03-02 13:52:00 -0800275
Alexander Afanasyeve16ed212016-12-25 18:09:44 -0800276$.Class("HistoryDisplay", {}, {
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800277 init: function(chronoshare) {
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800278 this.chronoshare = chronoshare;
279 },
Alexander Afanasyevfd5e6272013-02-27 20:25:20 -0800280
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800281 previewFile: function(file) {
282 if (fileExtension(file.attr("filename")) == "txt") {
283 CHRONOSHARE.get_file(file.attr("file_modified_by"),
284 DataUtils.toNumbers(file.attr("file_hash")),
Alexander Afanasyeve16ed212016-12-25 18:09:44 -0800285 file.attr("file_seg_num"),
286 function(status, data) {
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800287 $("<div />", {
288 "title": "Preview of " + file.attr("filename") +
289 " version " + file.attr("file_version")
290 })
291 .append($("<pre />").text(data))
292 .dialog({
293 resizable: true,
294 width: $(window).width() * 0.8,
295 maxHeight: $(window).height() * 0.8,
296 show: "blind",
297 hide: "fold",
298 modal: true,
299 });
300 });
Alexander Afanasyevf63a5142013-02-28 02:21:42 -0800301 }
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800302 else {
303 custom_alert("Preview is not support for this type of file");
304 }
305 },
306
307 onData: function(data, more) {
308 tbody = $("<tbody />", {"id": "history-list-actions"});
309
310 /// @todo Eventually set title for other pages
311 $("title").text("ChronoShare - Recent actions" +
312 (PARAMS.item ? " - " + PARAMS.item : ""));
313
314 newcontent =
315 $("<div />", {"id": "content"})
316 .append($("<h2 />").append($(document.createTextNode("Recent actions ")),
317 $("<green />").text(PARAMS.item)),
318 $("<table />", {"class": "item-list"})
319 .append(
320 $("<thead />")
321 .append($("<tr />")
322 .append($("<th />", {
323 "class": "filename border-left",
324 "scope": "col"
325 }).text("Filename"))
326 .append($("<th />",
327 {"class": "version", "scope": "col"})
328 .text("Version"))
329 .append($("<th />",
330 {"class": "size", "scope": "col"})
331 .text("Size"))
332 .append($("<th />", {
333 "class": "modified",
334 "scope": "col"
335 }).text("Modified"))
336 .append($("<th />", {
337 "class": "modified-by border-right",
338 "scope": "col"
339 }).text("Modified By"))))
340 .append(tbody)
341 .append($("<tfoot />").append($("<tr />").append($("<td />", {
342 "colspan": "5",
343 "class": "border-right border-left"
344 })))));
345
346 for (var i = 0; i < data.length; i++) {
347 action = data[i];
348
349 row = $("<tr />");
350 if (i % 2) {
351 row.addClass("odd");
352 }
353 if (action.action == "DELETE") {
354 row.addClass("delete");
355 }
356 else {
357 row.addClass("with-context-menu");
358 row.attr("file_version", action.version);
359 row.attr("file_hash", action.update.hash);
360 row.attr("file_seg_num", action.update.segNum);
361 row.attr("file_modified_by", action.id.userName);
362 }
363
364 row.attr("filename", action.filename);
365
366 self = this;
367 if (PARAMS.item != action.filename) {
368 row.bind('click', function(e) {
369 openHistoryForItem($(this).attr("filename"))
370 });
371 }
372 else {
373 row.bind('click', function(e) {
374 self.previewFile($(this));
375 });
376 }
377
378 row.bind('mouseenter mouseleave', function() {
379 $(this).toggleClass('highlighted');
380 });
381
382 row.append(
383 $("<td />", {"class": "filename border-left"})
384 .text(action.filename)
385 .prepend($("<img />",
386 {"src": imgFullPath(fileExtension(action.filename))})));
387 row.append($("<td />", {"class": "version"}).text(action.version));
388 row.append(
389 $("<td />", {
390 "class": "size"
391 }).text(action.update ? SegNumToFileSize(action.update.segNum) : ""));
Alexander Afanasyeve16ed212016-12-25 18:09:44 -0800392 row.append(
393 $("<td />", {"class": "timestamp"})
394 .text(new Date(
395 action.timestamp +
396 "+00:00"))); // conversion from UTC timezone (we store action time in UTC)
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800397 row.append($("<td />", {"class": "modified-by border-right"})
398 .append($("<userName />").text(action.id.userName))
399 .append($("<seqNo> /").text(action.id.seqNo)));
400
401 tbody = tbody.append(row);
402 }
403
404 displayContent(newcontent, more, this.base_url(PAGE));
405
406 self = this;
407 $.contextMenu('destroy', ".with-context-menu"); // cleanup
408 $.contextMenu({
409 selector: ".with-context-menu",
410 items: {
411 "sep1": "---------",
412 preview: {
413 name: "Preview revision",
414 icon: "edit", // ned a better icon
415 callback: function(key, opt) {
416 self.previewFile(opt.$trigger);
417 }
418 },
419 "sep3": "---------",
420 restore: {
421 name: "Restore this revision",
422 icon: "cut", // need a better icon
423 callback: function(key, opt) {
424 filename = opt.$trigger.attr("filename");
425 version = opt.$trigger.attr("file_version");
426 hash = DataUtils.toNumbers(opt.$trigger.attr("file_hash"));
427 console.log(hash);
428 modified_by = opt.$trigger.attr("file_modified_by");
429
430 $("<div />", {"title": "Restore version " + version + "?"})
431 .append(
432 $("<p />").append($("<span />", {
433 "class": "ui-icon ui-icon-alert",
434 "style": "float: left; margin: 0 7px 50px 0;"
435 }),
436 $(document.createTextNode(
437 "Are you sure you want restore version ")),
438 $("<green/>").text(version),
439 $(document.createTextNode(" by ")),
440 $("<green/>").text(modified_by)))
441 .dialog({
442 resizable: true,
443 height: 200,
444 width: 300,
445 modal: true,
446 show: "blind",
447 hide: "fold",
448 buttons: {
449 "Restore": function() {
450 self = $(this);
451 CHRONOSHARE.cmd_restore_file(filename, version, hash,
452 function(didGetData, response) {
453 if (!didGetData ||
454 response != "OK") {
455 custom_alert(response);
456 }
Alexander Afanasyeve16ed212016-12-25 18:09:44 -0800457
458 custom_alert(
459 "Restore Succeed!");
460
Alexander Afanasyeveda3b7a2016-12-25 11:26:40 -0800461 console.log(response);
462 self.dialog("close");
463
464 $.timer(function() {
465 CHRONOSHARE.run();
466 })
467 .once(1000);
468 });
469 },
470 Cancel: function() {
471 $(this).dialog("close");
472 }
473 }
474 });
475 // openHistoryForItem (opt.$trigger.attr ("filename"));
476 }
477 },
478 "sep2": "---------",
479 }
480 });
481 },
482
483 base_no_item_url: function(page) {
484 url = "#" + page + "&user=" +
485 encodeURIComponent(encodeURIComponent(PARAMS.user)) + "&folder=" +
486 encodeURIComponent(encodeURIComponent(PARAMS.folder));
487 return url;
488 },
489
490 base_url: function(page) {
491 url = "#" + page + "&user=" +
492 encodeURIComponent(encodeURIComponent(PARAMS.user)) + "&folder=" +
493 encodeURIComponent(encodeURIComponent(PARAMS.folder));
494 if (PARAMS.item !== undefined) {
495 url += "&item=" + encodeURIComponent(encodeURIComponent(PARAMS.item));
496 }
497 return url;
498 }
Alexander Afanasyevf63a5142013-02-28 02:21:42 -0800499});
Alexander Afanasyeve16ed212016-12-25 18:09:44 -0800500
501$.Class("FilesDisplay", {}, {
502 init: function(chronoshare) {
503 this.chronoshare = chronoshare;
504 },
505
506 onData: function(data, more) {
507 tbody = $("<tbody />", {"id": "file-list-files"});
508
509 /// @todo Eventually set title for other pages
510 $("title").text("ChronoShare - List of files" +
511 (PARAMS.item ? " - " + PARAMS.item : ""));
512
513 // error handling?
514 newcontent =
515 $("<div />", {"id": "content"})
516 .append($("<h2 />").append($(document.createTextNode("List of files ")),
517 $("<green />").text(PARAMS.item)),
518 $("<table />", {"class": "item-list"})
519 .append(
520 $("<thead />")
521 .append($("<tr />")
522 .append($("<th />", {
523 "class": "filename border-left",
524 "scope": "col"
525 }).text("Filename"))
526 .append($("<th />",
527 {"class": "version", "scope": "col"})
528 .text("Version"))
529 .append($("<th />",
530 {"class": "size", "scope": "col"})
531 .text("Size"))
532 .append($("<th />", {
533 "class": "modified",
534 "scope": "col"
535 }).text("Modified"))
536 .append($("<th />", {
537 "class": "modified-by border-right",
538 "scope": "col"
539 }).text("Modified By"))))
540 .append(tbody)
541 .append($("<tfoot />").append($("<tr />").append($("<td />", {
542 "colspan": "5",
543 "class": "border-right border-left"
544 })))));
545 newcontent.hide();
546
547 for (var i = 0; i < data.length; i++) {
548 file = data[i];
549
550 row = $("<tr />", {"class": "with-context-menu"});
551 if (i % 2) {
552 row.addClass("odd");
553 }
554
555 row.bind('mouseenter mouseleave', function() {
556 $(this).toggleClass('highlighted');
557 });
558
559 row.attr("filename",
560 file.filename); //encodeURIComponent(encodeURIComponent(file.filename)));
561 row.bind('click', function(e) {
562 openHistoryForItem($(this).attr("filename"))
563 });
564
565 row.append(
566 $("<td />", {"class": "filename border-left"})
567 .text(file.filename)
568 .prepend(
569 $("<img />", {"src": imgFullPath(fileExtension(file.filename))})));
570 row.append($("<td />", {"class": "version"}).text(file.version));
571 row.append(
572 $("<td />", {"class": "size"}).text(SegNumToFileSize(file.segNum)));
573 row.append($("<td />", {
574 "class": "modified"
575 }).text(new Date(file.timestamp + "+00:00"))); // convert from UTC
576 row.append($("<td />", {"class": "modified-by border-right"})
577 .append($("<userName />").text(file.owner.userName))
578 .append($("<seqNo> /").text(file.owner.seqNo)));
579
580 tbody = tbody.append(row);
581 }
582
583 displayContent(newcontent, more, this.base_url());
584
585 $.contextMenu('destroy', ".with-context-menu"); // cleanup
586 $.contextMenu({
587 selector: ".with-context-menu",
588 items: {
589 "info": {name: "x", type: "html", html: "<b>File operations</b>"},
590 "sep1": "---------",
591 history: {
592 name: "View file history",
593 icon: "quit", // need a better icon
594 callback: function(key, opt) {
595 openHistoryForItem(opt.$trigger.attr("filename"));
596 }
597 },
598 }
599 });
600 },
601
602 base_url: function() {
603 url = "#fileList" +
604 "&user=" + encodeURIComponent(encodeURIComponent(PARAMS.user)) +
605 "&folder=" + encodeURIComponent(encodeURIComponent(PARAMS.folder));
606 if (PARAMS.item !== undefined) {
607 url += "&item=" + encodeURIComponent(encodeURIComponent(PARAMS.item));
608 }
609 return url;
610 }
611});