textcircle.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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. canEdit: function () {
  65. let doc = Documents.findOne({ _id: Session.get("docid") });
  66. return doc && doc.owner === Meteor.userId();
  67. }
  68. });
  69. Template.editableText.helpers({
  70. userCanEdit: function (doc, collection) {
  71. Meteor._debug("userCanEdit", doc, collection);
  72. // Can edit if the document is owned by me.
  73. doc = Documents.findOne({
  74. _id: Session.get("docid"),
  75. owner: Meteor.userId()
  76. });
  77. return !!doc;
  78. }
  79. });
  80. Template.navbar.events({
  81. "click .js-add-doc": function (event) {
  82. event.preventDefault();
  83. // User not available.
  84. if (!Meteor.user()) {
  85. alert("You need to login first.");
  86. }
  87. else {
  88. Meteor.call("addDoc", function (err, res) {
  89. if (!err) {
  90. console.log("addDoc res", res);
  91. Session.set("docid", res);
  92. }
  93. });
  94. }
  95. },
  96. "click .js-load-doc": function (event) {
  97. // This contains a complete document.
  98. Session.set("docid", this._id);
  99. }
  100. });
  101. Template.docMeta.events({
  102. "click .js-tog-private": function (event) {
  103. const docid = Session.get("docid");
  104. if (docid) {
  105. const doc = { _id: docid, isPrivate: event.target.checked };
  106. Meteor.call("updateDocPrivacy", doc);
  107. }
  108. }
  109. });
  110. } // end isClient...
  111. if (Meteor.isServer) {
  112. Meteor.publish("documents", function () {
  113. Meteor._debug("Publishing documents");
  114. return Documents.find({
  115. $or: [
  116. { isPrivate: false },
  117. { owner: this.userId }
  118. ]
  119. });
  120. });
  121. Meteor.publish("editingUsers", function () {
  122. Meteor._debug("Publishing all editingUsers");
  123. return EditingUsers.find();
  124. });
  125. Meteor.startup(function () {
  126. // Insert a document if there isn't one already.
  127. if (!Documents.findOne()) {
  128. Documents.insert({ title: "my new document" });
  129. }
  130. });
  131. }
  132. // Methods that provide write access to the data.
  133. Meteor.methods({
  134. addDoc: function () {
  135. Meteor._debug("addDoc, this", this);
  136. // Not logged-in.
  137. if (!this.userId) {
  138. return;
  139. }
  140. else {
  141. let doc = {
  142. owner: this.userId,
  143. createdOn: new Date(),
  144. title: "my new doc"
  145. };
  146. const docid = Documents.insert(doc);
  147. return docid;
  148. }
  149. },
  150. updateDocPrivacy: function (doc) {
  151. Meteor._debug("updatedocPrivacy", this.userId, doc)
  152. if (!this.userId) {
  153. return;
  154. }
  155. let res = Documents.update({ _id: doc._id, owner: this.userId }, { $set: { isPrivate: doc.isPrivate } });
  156. Meteor._debug("update", res);
  157. },
  158. addEditingUser: function () {
  159. let doc = Documents.findOne();
  160. if (!doc) {
  161. // No doc: give up.
  162. return;
  163. }
  164. if (!this.userId) {
  165. // No logged-in user: give up.
  166. return;
  167. }
  168. // Now I have a doc and possibly a user.
  169. let user = Meteor.user().profile;
  170. let eUsers = EditingUsers.findOne({ docId: doc._id });
  171. // No editing users have been stored yet.
  172. if (!eUsers) {
  173. eUsers = {
  174. docId: doc._id,
  175. users: {}
  176. };
  177. }
  178. user.lastEdit = new Date();
  179. eUsers.users[this.userId] = user;
  180. // Upsert: insert or update if filter matches.
  181. EditingUsers.upsert({ _id: eUsers._id }, eUsers);
  182. }
  183. });
  184. function setupCurrentDocument() {
  185. let doc;
  186. // No docid set yet.
  187. if (!Session.get("docid")) {
  188. doc = Documents.findOne();
  189. if (doc) {
  190. Session.set("docid", doc._id);
  191. }
  192. }
  193. }
  194. // This renames object keys by removing hyphens to make them compatible
  195. // with spacebars.
  196. function fixObjectsKeys(obj) {
  197. let newObj = {};
  198. for (let key in obj) {
  199. if (obj.hasOwnProperty(key)) {
  200. const key2 = key.replace("-", "");
  201. newObj[key2] = obj[key];
  202. }
  203. }
  204. return newObj;
  205. }