textcircle.js 5.5 KB

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