textcircle.js 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. // This collection stores all the documents.
  2. // Note: not Documents, but this.Documents, because of the editing package (?)
  3. this.Documents = new Mongo.Collection("documents");
  4. // This collection stores sets of users that are editing documents.
  5. EditingUsers = new Mongo.Collection("editingUsers");
  6. if (Meteor.isClient) {
  7. Template.editor.helpers({
  8. // Return the id of the first document you can find.
  9. docid: function () {
  10. setupCurrentDocument();
  11. return Session.get("docid");
  12. },
  13. // Configure the CodeMirror editor.
  14. config: function () {
  15. return function (editor) {
  16. editor.setOption("lineNumbers", true);
  17. editor.setOption("theme", "cobalt");
  18. editor.setOption("mode", "html");
  19. // Set a callback that gets triggered whenever the user
  20. // makes a change in the code editing window.
  21. editor.on("change", function (cmEditor /* , info */) {
  22. let $preview = $("#viewer_iframe");
  23. // Send the current code over to the iframe for rendering.
  24. $preview.contents().find("html").html(cmEditor.getValue());
  25. Meteor.call("addEditingUser");
  26. });
  27. };
  28. }
  29. });
  30. Template.editingUsers.helpers({
  31. // Retrieve a set of users that are editing this document.
  32. users: function () {
  33. let doc = Documents.findOne();
  34. if (!doc) {
  35. // Give up.
  36. return null;
  37. }
  38. let eUsers = EditingUsers.findOne({ docId: doc._id });
  39. if (!eUsers) {
  40. // Give up.
  41. return null;
  42. }
  43. let users = new Array();
  44. let i = 0;
  45. for (let userId in eUsers.users) {
  46. users[i] = fixObjectsKeys(eUsers.users[userId]);
  47. users[i]._id = userId;
  48. i++;
  49. }
  50. return users;
  51. }
  52. });
  53. Template.navbar.helpers({
  54. documents: function () {
  55. return Documents.find();
  56. }
  57. });
  58. Template.docMeta.helpers({
  59. document: function () {
  60. return Documents.findOne({ _id: Session.get("docid") });
  61. }
  62. });
  63. Template.editableText.helpers({
  64. userCanEdit: function (doc, collection) {
  65. Meteor._debug("userCanEdit", doc, collection);
  66. // Can edit if the document is owned by me.
  67. doc = Documents.findOne({
  68. _id: Session.get("docid"),
  69. owner: Meteor.userId()
  70. });
  71. return !!doc;
  72. }
  73. });
  74. Template.navbar.events({
  75. "click .js-add-doc": function (event) {
  76. event.preventDefault();
  77. // User not available.
  78. if (!Meteor.user()) {
  79. alert("You need to login first.");
  80. }
  81. else {
  82. Meteor.call("addDoc", function (err, res) {
  83. if (!err) {
  84. console.log("addDoc res", res);
  85. Session.set("docid", res);
  86. }
  87. });
  88. }
  89. },
  90. "click .js-load-doc": function (event) {
  91. // This contains a complete document.
  92. Session.set("docid", this._id);
  93. }
  94. });
  95. Template.docMeta.events({
  96. "click .js-tog-private": function (event) {
  97. const docid = Session.get("docid");
  98. if (docid) {
  99. const doc = { _id: docid, isPrivate: event.target.checked };
  100. Meteor.call("updateDocPrivacy", doc);
  101. }
  102. }
  103. });
  104. } // end isClient...
  105. if (Meteor.isServer) {
  106. Meteor.startup(function () {
  107. // Insert a document if there isn't one already.
  108. if (!Documents.findOne()) {
  109. Documents.insert({ title: "my new document" });
  110. }
  111. });
  112. }
  113. // Methods that provide write access to the data.
  114. Meteor.methods({
  115. addDoc: function () {
  116. Meteor._debug("addDoc, this", this);
  117. // Not logged-in.
  118. if (!this.userId) {
  119. return;
  120. }
  121. else {
  122. let doc = {
  123. owner: this.userId,
  124. createdOn: new Date(),
  125. title: "my new doc"
  126. };
  127. const docid = Documents.insert(doc);
  128. return docid;
  129. }
  130. },
  131. updateDocPrivacy: function (doc) {
  132. Meteor._debug("updatedocPrivacy", this.userId, doc)
  133. if (!this.userId) {
  134. return;
  135. }
  136. let res = Documents.update({ _id: doc._id, owner: this.userId }, { $set: { private: doc.isPrivate } });
  137. Meteor._debug("update", res);
  138. },
  139. addEditingUser: function () {
  140. let doc = Documents.findOne();
  141. if (!doc) {
  142. // No doc: give up.
  143. return;
  144. }
  145. if (!this.userId) {
  146. // No logged-in user: give up.
  147. return;
  148. }
  149. // Now I have a doc and possibly a user.
  150. let user = Meteor.user().profile;
  151. let eUsers = EditingUsers.findOne({ docId: doc._id });
  152. // No editing users have been stored yet.
  153. if (!eUsers) {
  154. eUsers = {
  155. docId: doc._id,
  156. users: {}
  157. };
  158. }
  159. user.lastEdit = new Date();
  160. eUsers.users[this.userId] = user;
  161. // Upsert: insert or update if filter matches.
  162. EditingUsers.upsert({ _id: eUsers._id }, eUsers);
  163. }
  164. });
  165. function setupCurrentDocument() {
  166. let doc;
  167. // No docid set yet.
  168. if (!Session.get("docid")) {
  169. doc = Documents.findOne();
  170. if (doc) {
  171. Session.set("docid", doc._id);
  172. }
  173. }
  174. }
  175. // This renames object keys by removing hyphens to make them compatible
  176. // with spacebars.
  177. function fixObjectsKeys(obj) {
  178. let newObj = {};
  179. for (let key in obj) {
  180. if (obj.hasOwnProperty(key)) {
  181. const key2 = key.replace("-", "");
  182. newObj[key2] = obj[key];
  183. }
  184. }
  185. return newObj;
  186. }