corkboard.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. const editMode = window.location.hash == "#edit";
  2. console.log(editMode);
  3. class Note {
  4. constructor(id, text, x, y, width, height, deleted) {
  5. this.id = id;
  6. this.text = text;
  7. this.x = x;
  8. this.y = y;
  9. this.width = width;
  10. this.height = height;
  11. this.deleted = deleted;
  12. // some UI state, too
  13. this.editable = false;
  14. this.deleteConfirm = false;
  15. }
  16. draw() {
  17. if (this.deleted) {
  18. return;
  19. }
  20. const id = `n_${this.id}`;
  21. const note = $(`<div class="note" id="${id}"></div>`);
  22. const text = $(`<div class="text">${this.text}</div>`);
  23. const tools = $("<div class=\"tools\"></div>");
  24. const edit = $("<a class=\"edit\">edit</a>");
  25. const del = $("<a class=\"delete\">delete</a>");
  26. const confirm = $("<a class=\"confirm\">do it</a>");
  27. edit.on("click", event => {
  28. if (this.editable) {
  29. this.text = text.text();
  30. this.save();
  31. text.attr("contentEditable", false);
  32. edit.text("edit");
  33. } else {
  34. text.attr("contentEditable", true);
  35. edit.text("save");
  36. }
  37. this.editable = !this.editable;
  38. });
  39. tools.append(edit);
  40. del.on("click", event => {
  41. if (this.deleteConfirm) {
  42. del.text("delete");
  43. confirm.css({'display': 'none'});
  44. } else {
  45. del.text("nevermind");
  46. confirm.css({'display': 'inline'});
  47. }
  48. this.deleteConfirm = !this.deleteConfirm;
  49. });
  50. tools.append(del);
  51. confirm.css({'display': 'none'});
  52. confirm.on("click", event => {
  53. this.deleted = true;
  54. note.css({'display': 'none'});
  55. this.save();
  56. });
  57. tools.append(confirm);
  58. if (!editMode) {
  59. tools.css({'display': 'none'});
  60. }
  61. note.append(text);
  62. note.append(tools);
  63. $("#board").append(note);
  64. note.css({
  65. 'position': 'absolute',
  66. 'left': this.x,
  67. 'top': this.y,
  68. 'width': this.width,
  69. 'height': this.height,
  70. });
  71. if (editMode) {
  72. note.draggable();
  73. note.on("dragstop", (event, ui) => {
  74. this.y = ui.offset.top;
  75. this.x = ui.offset.left;
  76. this.save();
  77. });
  78. note.resizable();
  79. note.on("resizestop", (event, ui) => {
  80. this.width = ui.size.width;
  81. this.height = ui.size.height;
  82. this.save();
  83. });
  84. }
  85. }
  86. save() {
  87. fetch("/note", {
  88. method: "POST",
  89. headers: {
  90. "Content-Type": "application/json",
  91. },
  92. body: this.json,
  93. }).then(response => console.log(`Saved note ${this.id}: ${this.json}`));
  94. }
  95. static allNotes = [];
  96. get json() {
  97. return JSON.stringify({
  98. "id": this.id,
  99. "text": this.text,
  100. "x": this.x,
  101. "y": this.y,
  102. "width": this.width,
  103. "height": this.height,
  104. "deleted": this.deleted,
  105. });
  106. }
  107. static make(id, text, x, y, width, height, deleted) {
  108. const n = new Note(id, text, x, y, width, height, deleted);
  109. n.draw();
  110. this.allNotes.push(n);
  111. return n;
  112. }
  113. static new() {
  114. const new_id = this.allNotes.length;
  115. const n = this.make(new_id, "new note!", 100.0, 100.0, 220.0, 220.0, false);
  116. n.save();
  117. }
  118. }
  119. $(document).ready(() => {
  120. const add = $("#add");
  121. add.on("click", event => {
  122. Note.new();
  123. });
  124. if (!editMode) {
  125. add.css({'display': 'none'});
  126. }
  127. fetch('/note')
  128. .then(response => response.json())
  129. .then(data => data.forEach(d => {
  130. Note.make(d["id"], d["text"], d["x"], d["y"], d["width"] || 220.0, d["height"] || 220.0, d["deleted"] == true);
  131. }));
  132. });