From 35aa21a0baa3a9236fab8ee0c640d29c44617e7c Mon Sep 17 00:00:00 2001 From: J S Diaz Date: Fri, 7 Aug 2015 14:35:45 -0400 Subject: [PATCH 01/29] first pass on credits language --- client/views/credits/credits.html | 53 ++++++++++--------------------- 1 file changed, 16 insertions(+), 37 deletions(-) diff --git a/client/views/credits/credits.html b/client/views/credits/credits.html index 03a2b836..ed1004f6 100644 --- a/client/views/credits/credits.html +++ b/client/views/credits/credits.html @@ -7,70 +7,49 @@

About Question Tool

Version:
- 1.6 + 0.4

Source:
- Github Repository + Github Repository

Thanks to:
- Dan Collis-Puro - First Lead Developer + Nick Rubin - JS version Developer
- Justin Clark - Second Lead Developer + Dan Cohen - PHP version Developer
- Tomas Reimers - Developer + David Russcol - PHP version Developer
- Brian 'Phunk' Gadoury - Developer + Jonathan Zittrain - Father of the Question Tool +
+ The Berkman Center for Internet & Society - Hosting, Funding and Support +
+ HLS ITS - Support

Bugs
- Please report them to the github issue tracker. + Please report them to the github issue tracker.

Administrative Copyright
- © 2011 - 2015 President and Fellows of Harvard College + © 2015 President and Fellows of Harvard College

License
- Question Tool is licensed under the... -
+ Question Tool is licensed under the GNU General Public License. +
- - From 0f9f32af1705ba95c72b8b4d9bbfd393719cdea6 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Fri, 18 Sep 2015 14:00:36 -0400 Subject: [PATCH 02/29] Fixed to display errors if instance name is not input properly. --- client/views/create/create.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/client/views/create/create.js b/client/views/create/create.js index dce8930c..835d9e0e 100644 --- a/client/views/create/create.js +++ b/client/views/create/create.js @@ -57,10 +57,11 @@ Template.create.events({ return false; } var anonElement = document.getElementById("allowanoncheck"); + var anonymous; if(anonElement.style.display) { - var anonymous = (anonElement.style.display != "none"); + anonymous = (anonElement.style.display != "none"); } else { - var anonymous = false; + anonymous = false; } // Retrieve data from the form var tablename = document.getElementById("instancenameinput").value; @@ -111,7 +112,7 @@ Template.create.events({ "description": "Please enter a valid description under 255 characters.", "modlength": "You have entered too many moderators. Please try again."/*, "password": "Please enter a valid password using letters, numbers, *, #, @, and between 4 and 10 characters."*/ - } + }; // Alert the error showCreateError(errorCodes[result[0].name]); return false; @@ -140,4 +141,13 @@ Template.create.events({ last.previousSibling.focus(); } } -}); \ No newline at end of file +}); + +function showCreateError(reason) { + if(typeof currentError != "undefined") { + Blaze.remove(currentError); + } + var parentNode = document.getElementById("creatediv"); + var nextNode = document.getElementById("instancebottominputcontainer"); + currentError = Blaze.renderWithData(Template.form_error, reason, parentNode, nextNode); +} \ No newline at end of file From cea747c5662b934dcf435a9ae9e8d3dc8d92d7e7 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Mon, 21 Sep 2015 15:55:33 -0400 Subject: [PATCH 03/29] Removed display of name and e-mail when replying to question while logged in. --- client/views/helpers/chunks/question_div/question_div.css | 1 - client/views/helpers/chunks/question_div/question_div.html | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/client/views/helpers/chunks/question_div/question_div.css b/client/views/helpers/chunks/question_div/question_div.css index 75906648..0523d00a 100644 --- a/client/views/helpers/chunks/question_div/question_div.css +++ b/client/views/helpers/chunks/question_div/question_div.css @@ -278,7 +278,6 @@ .replybottom { width:340px; - height:158px; display:none; margin:0px auto; margin-top:55px; diff --git a/client/views/helpers/chunks/question_div/question_div.html b/client/views/helpers/chunks/question_div/question_div.html index 537bbaa6..8a85cda6 100644 --- a/client/views/helpers/chunks/question_div/question_div.html +++ b/client/views/helpers/chunks/question_div/question_div.html @@ -101,7 +101,7 @@
-
+
{{#if currentUser}} @@ -111,7 +111,7 @@ {{/if}}
-
+
From c193a47a06490003756a2ed7936decb0daf7ec76 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Thu, 24 Sep 2015 10:51:50 -0400 Subject: [PATCH 04/29] Update to use instance ids instead of table name to add and query questions from instances. --- client/views/list/list.js | 4 ++-- client/views/propose/propose.js | 2 +- lib/common.js | 5 +++++ server/methods.js | 9 ++++++--- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/client/views/list/list.js b/client/views/list/list.js index 38dae455..2acac739 100644 --- a/client/views/list/list.js +++ b/client/views/list/list.js @@ -69,12 +69,12 @@ Template.list.helpers({ if(Session.get("search") == "all") { //console.log(Session.get("tablename")); var questions = Questions.find({ - tablename: Session.get("tablename") + instanceid: Session.get("id") }).fetch(); } else { var re = new RegExp(Session.get("search"), "i"); var questions = Questions.find({ - tablename: Session.get("tablename"), + instanceid: Session.get("id"), "$or": [{ text: { $regex: re diff --git a/client/views/propose/propose.js b/client/views/propose/propose.js index 882f3372..83d69dd7 100644 --- a/client/views/propose/propose.js +++ b/client/views/propose/propose.js @@ -193,7 +193,7 @@ Template.propose.events({ Meteor.call('getIP', function (error, result) { if (!error) { // Calls server-side "propose" method to add question to DB - Meteor.call('propose', Session.get("tablename"), question, posterName, posterEmail, result, function (error, result) { + Meteor.call('propose', Session.get("id"), Session.get("tablename"), question, posterName, posterEmail, result, function (error, result) { // If returns an object, there was an error if(typeof result === 'object') { // Store an object of the error names and codes diff --git a/lib/common.js b/lib/common.js index c5b1671d..28b143f5 100644 --- a/lib/common.js +++ b/lib/common.js @@ -74,6 +74,11 @@ Schemas.Instance = new SimpleSchema({ }); Schemas.Question = new SimpleSchema({ + instanceid: { + type: String, + max: 30 + }, + tablename: { type: String, regEx: /^[a-zA-Z0-9]{4,30}$/ diff --git a/server/methods.js b/server/methods.js index 8f08383d..33b5b52d 100644 --- a/server/methods.js +++ b/server/methods.js @@ -131,7 +131,7 @@ Meteor.methods({ max_response: maxResponse, anonymous: anonymous, hidden: isHidden, - author: author + author: author, }, function(error, id) { // If error, set keys to the error object if(error) { @@ -139,6 +139,7 @@ Meteor.methods({ } else { // If successful, add the "starter" question to the questions database Questions.insert({ + instanceid: id, tablename: tablename, text: "Welcome to the live question tool. Feel free to post questions. Vote by clicking on the 'vote' button. To reply, press the button in the bottom-right.", poster: "the system", @@ -149,6 +150,7 @@ Meteor.methods({ }, function(error, id) { // If error, set keys to the error object if(error) { + console.log("Second error " + error); keys = error.invalidKeys; } }); @@ -337,18 +339,19 @@ Meteor.methods({ }); }, // Method that adds a new question to the database - propose: function(tablename, question, posterName, posterEmail, ip) { + propose: function(instanceid, tablename, question, posterName, posterEmail, ip) { var keys; question.replace(/<(?:.|\n)*?>/gm, ''); // Gets the current table var table = Instances.findOne({ - tablename: tablename + _id: instanceid }); if(table == null) { return false; } else { // Update the lasttouch of the Instance Questions.insert({ + instanceid: instanceid, tablename: tablename, text: question, poster: posterName, From 691c81259b0bca8ce5ee688bca672f510fb2688b Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Wed, 14 Oct 2015 14:58:43 -0400 Subject: [PATCH 05/29] Removed unnecessary comma. --- server/methods.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/methods.js b/server/methods.js index 33b5b52d..509ac4d3 100644 --- a/server/methods.js +++ b/server/methods.js @@ -131,7 +131,7 @@ Meteor.methods({ max_response: maxResponse, anonymous: anonymous, hidden: isHidden, - author: author, + author: author }, function(error, id) { // If error, set keys to the error object if(error) { From 050ef73555abf78c28caca857cf5e59b377d07f9 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Wed, 14 Oct 2015 15:34:17 -0400 Subject: [PATCH 06/29] Update adminCheck function to use id instead of tablename. --- client/views/list/list.js | 2 +- server/methods.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/client/views/list/list.js b/client/views/list/list.js index 2acac739..9bdf8d6b 100644 --- a/client/views/list/list.js +++ b/client/views/list/list.js @@ -614,7 +614,7 @@ function timeSince(date) { }; function enableDragging() { - Meteor.call('adminCheck', Session.get("tablename"), function(error, result) { + Meteor.call('adminCheck', Session.get("id"), function(error, result) { // If yes, enable draggable question divs if(result) { interact('.question') diff --git a/server/methods.js b/server/methods.js index 509ac4d3..d754f3ef 100644 --- a/server/methods.js +++ b/server/methods.js @@ -33,14 +33,14 @@ Meteor.methods({ } }, // A method that checks whether the email matches the admin of the supplied tablename - adminCheck: function(tablename) { + adminCheck: function(instanceid) { if(Meteor.user()) { var user = Meteor.user().emails[0].address; } else { return false; } var table = Instances.findOne({ - tablename: tablename + _id: instanceid }); if(((user == table.admin) || (table.moderators.indexOf(user) != -1)) && (user && table.admin)) { return true; From 0048a139c89ea4dbfcf84f5d2f1f98adcf472eb3 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Fri, 16 Oct 2015 14:57:27 -0400 Subject: [PATCH 07/29] Migrated to using ids for instances instead of tablename. Mostly working but not fully tested. --- client/views/list/list.js | 4 ++-- client/views/main/main.js | 2 +- lib/common.js | 4 ++-- lib/routes.js | 10 +++++----- server/methods.js | 6 +++--- server/publish.js | 12 ++++-------- 6 files changed, 17 insertions(+), 21 deletions(-) diff --git a/client/views/list/list.js b/client/views/list/list.js index 9bdf8d6b..f7f827ab 100644 --- a/client/views/list/list.js +++ b/client/views/list/list.js @@ -398,7 +398,7 @@ Template.list.events({ posterName = "Anonymous"; } // Calls a server-side method to answer a question and update DBs - Meteor.call('answer', Session.get("tablename"), answer, posterName, email, result, theID, function (error, result) { + Meteor.call('answer', Session.get("id"), answer, posterName, email, result, theID, function (error, result) { // If the result is an object, there was an error if(typeof result === 'object') { // Store an object of the error names and codes @@ -407,7 +407,7 @@ Template.list.events({ "poster": "Please enter a valid name.", "email": "Please enter a valid email address.", "ip": "There was an error with your IP address. Try again.", - "tablename": "There was an error with the table name. Try again.", + "instanceid": "There was an error with the instance id. Try again.", "qid": "There was an error with the question ID." } // Alert the error diff --git a/client/views/main/main.js b/client/views/main/main.js index 7f02ceb4..152d8611 100644 --- a/client/views/main/main.js +++ b/client/views/main/main.js @@ -161,7 +161,7 @@ Template.home.events({ //var selectedInstance = instances.options[instances.selectedIndex].text; //Cookie.set('tablename', theInstance.tablename); // Redirects to the list - window.location.href = "/list/" + theInstance.tablename; + window.location.href = "/list/" + theID; //Router.go('/list'); }, "keyup #searchbar": function(event, template) { diff --git a/lib/common.js b/lib/common.js index 28b143f5..a2fa3aa8 100644 --- a/lib/common.js +++ b/lib/common.js @@ -140,9 +140,9 @@ Schemas.Answer = new SimpleSchema({ type: String, regEx: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ }, - tablename: { + instanceid: { type: String, - regEx: /^[a-zA-Z0-9]{4,30}$/ + max: 30 }, qid: { type: String, diff --git a/lib/routes.js b/lib/routes.js index 82b509ef..14c6cc67 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -89,17 +89,17 @@ Router.route('', { // When the user visits /list/tablename, set cookie to tablename and display list Router.route('listlink', { - path: '/list/:tablename', + path: '/list/:_id', waitOn: function() { return [ - Meteor.subscribe('questions', this.params.tablename), - Meteor.subscribe('answers', this.params.tablename), - Meteor.subscribe('votes', this.params.tablename) + Meteor.subscribe('questions', this.params._id), + Meteor.subscribe('answers', this.params._id), + Meteor.subscribe('votes', this.params._id) ]; }, onBeforeAction: function() { var instance = Instances.findOne({ - tablename: this.params.tablename + _id: this.params._id }); if(instance) { this.render('list', { diff --git a/server/methods.js b/server/methods.js index d754f3ef..ea86f840 100644 --- a/server/methods.js +++ b/server/methods.js @@ -49,7 +49,7 @@ Meteor.methods({ } }, // A method that adds an answer to the databases - answer: function(tablename, answer, posterName, email, result, currentURL) { + answer: function(instanceid, answer, posterName, email, result, currentURL) { var keys = ""; answer.replace(/<(?:.|\n)*?>/gm, ''); // Retrieves the current quesetion from the DB (if one exists) @@ -65,7 +65,7 @@ Meteor.methods({ poster: posterName, email: email, ip: result, - tablename: tablename, + instanceid: instanceid, qid: currentURL }, function(error, id) { // If error, set keys to the error object @@ -84,7 +84,7 @@ Meteor.methods({ return false; } else { Instances.update({ - tablename: tablename + instanceid: instanceid }, { $set: { lasttouch: new Date().getTime() - 1000 diff --git a/server/publish.js b/server/publish.js index 193c59ef..19e6d978 100644 --- a/server/publish.js +++ b/server/publish.js @@ -12,11 +12,9 @@ Meteor.publish('instances', function() { }); // Only publishes to the user the questions that are associated with the selected table and are not disabled -Meteor.publish('questions', function(table) { +Meteor.publish('questions', function(instanceid) { return Questions.find({ - tablename: { - $regex: new RegExp("^" + table, "i") - }, + instanceid: instanceid, state: { $ne : 'disabled' } @@ -24,11 +22,9 @@ Meteor.publish('questions', function(table) { }); // Only publishes to the user the answers that are associated with the selected table -Meteor.publish('answers', function(table) { +Meteor.publish('answers', function(instanceid) { return Answers.find({ - tablename: { - $regex: new RegExp("^" + table, "i") - } + instanceid: instanceid, }); }); From 55ecc597d911677471a1997a41a0fc977cbacdec Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Mon, 19 Oct 2015 13:10:01 -0400 Subject: [PATCH 08/29] Fix admin check for adding moderators. --- client/views/add/add.js | 4 ++-- server/methods.js | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/client/views/add/add.js b/client/views/add/add.js index 5f3f37f2..27bc8908 100644 --- a/client/views/add/add.js +++ b/client/views/add/add.js @@ -1,11 +1,11 @@ Template.add.onCreated(function () { // Checks whether the user has a valid table cookie - Meteor.call('listCookieCheck', Session.get("tablename"), function (error, result) { + Meteor.call('listCookieCheck', Session.get("id"), function (error, result) { if(!result) { // If not, return the user to the chooser page window.location.href = "/"; } else { - Meteor.call('adminCheck', Session.get("tablename"), function (error, result) { + Meteor.call('adminCheck', Session.get("id"), function (error, result) { if(!result) { // If not, return the user to the chooser page window.location.href = "/"; diff --git a/server/methods.js b/server/methods.js index ea86f840..3e0bc7b3 100644 --- a/server/methods.js +++ b/server/methods.js @@ -20,11 +20,9 @@ Meteor.methods({ }); }, // A method that checks whether a table exists with parameter tablename - listCookieCheck: function(table) { + listCookieCheck: function(instanceid) { var table = Instances.findOne({ - tablename: { - $regex: new RegExp("^" + table, "i") - } + _id: instanceid }); if(table == null) { return false; From d6e1245418c7f39a229cde5639ea993adb832ecc Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Mon, 19 Oct 2015 14:06:46 -0400 Subject: [PATCH 09/29] Fix broken rename redirect. --- client/views/rename/rename.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/views/rename/rename.js b/client/views/rename/rename.js index d0afe5c2..575e4bcf 100644 --- a/client/views/rename/rename.js +++ b/client/views/rename/rename.js @@ -11,7 +11,7 @@ Template.rename.helpers({ renameid: function() { return Template.instance().data.id; } -}) +}); Template.rename.events({ // When the submit button is clicked... @@ -28,7 +28,7 @@ Template.rename.events({ showRenameError("Name is already taken."); } else { if(template.data.isList) { - window.location.href = "/list/" + newName; + window.location.href = "/list/" + Session.get("id"); } } }); From fa0cec51b6b5283ab72ae3264714b1c4b8ae9033 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Tue, 20 Oct 2015 10:28:14 -0400 Subject: [PATCH 10/29] Fix sharing URLs. --- client/views/list/list.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/views/list/list.js b/client/views/list/list.js index f7f827ab..17675ea6 100644 --- a/client/views/list/list.js +++ b/client/views/list/list.js @@ -468,7 +468,7 @@ Template.list.events({ Session.set("replyCount", total); }, "click .facebookbutton": function(event, template) { - popupwindow("https://www.facebook.com/sharer/sharer.php?u=" + encodeURIComponent(window.location.origin + "/list/" + Session.get("tablename")), "Share Question Tool!", 600, 400); + popupwindow("https://www.facebook.com/sharer/sharer.php?u=" + encodeURIComponent(window.location.origin + "/list/" + Session.get("id")), "Share Question Tool!", 600, 400); }, "click .twitterbutton": function(event, template) { var questionDiv = event.target.parentElement.parentElement; @@ -476,7 +476,7 @@ Template.list.events({ if(questionText.length > 35) { questionText = questionText.substring(0, 34); } - var tweetText = 'Check out this question: "' + questionText + '..." on Question Tool by @berkmancenter ' + window.location.origin + "/list/" + Session.get("tablename"); + var tweetText = 'Check out this question: "' + questionText + '..." on Question Tool by @berkmancenter ' + window.location.origin + "/list/" + Session.get("id"); popupwindow("https://twitter.com/intent/tweet?text=" + encodeURIComponent(tweetText), "Share Question Tool!", 600, 400); }, "click #modbutton": function(event, template) { From e9e50c01f6467ae3d5932cba54c6825359c11cc5 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Mon, 26 Oct 2015 15:13:57 -0400 Subject: [PATCH 11/29] update admin functions to use ids. --- client/views/add/add.js | 4 +-- client/views/combine/combine.js | 2 +- client/views/list/list.js | 2 +- client/views/modify/modify.js | 2 +- lib/routes.js | 8 +++--- server/methods.js | 48 ++++++++++++++++----------------- 6 files changed, 33 insertions(+), 33 deletions(-) diff --git a/client/views/add/add.js b/client/views/add/add.js index 27bc8908..9bab7fc0 100644 --- a/client/views/add/add.js +++ b/client/views/add/add.js @@ -66,7 +66,7 @@ Template.add.events({ }, "click .removebutton": function(event, template) { var mod = event.currentTarget.previousElementSibling.value; - Meteor.call('removeMods', mod, Session.get("tablename")); + Meteor.call('removeMods', mod, Session.get("id")); }, // When the submit button is clicked... "click #modsdonebutton": function(event, template) { @@ -78,7 +78,7 @@ Template.add.events({ mods.push(modsInput[m].value); } } - Meteor.call('addMods', mods, Session.get("tablename"), function(error, result) { + Meteor.call('addMods', mods, Session.get("id"), function(error, result) { // If the result is an object, there was an error if(typeof result === 'object') { // Alert the error diff --git a/client/views/combine/combine.js b/client/views/combine/combine.js index 10700d96..918c9be8 100644 --- a/client/views/combine/combine.js +++ b/client/views/combine/combine.js @@ -44,7 +44,7 @@ Template.combine.events({ // Calls the combine function on the server to update the DBs var id2 = Template.instance().data.second; var id1 = Template.instance().data.first; - Meteor.call('combine', question, id1, id2, Session.get("tablename"), function (error, result) { + Meteor.call('combine', question, id1, id2, Session.get("id"), function (error, result) { // If successful if(!error) { // Hides the second question (combined -> first) diff --git a/client/views/list/list.js b/client/views/list/list.js index 17675ea6..543e7be3 100644 --- a/client/views/list/list.js +++ b/client/views/list/list.js @@ -309,7 +309,7 @@ Template.list.events({ // When the admin unhide button is clicked... "click #unhidebutton": function(event, template) { // Call the server-side unhide method to unhide all questions - Meteor.call('unhide', Session.get("tablename")); + Meteor.call('unhide', Session.get("id")); }, "click .deletebutton": function(event, template) { var check = confirm("Are you sure you would like to delete the instance?"); diff --git a/client/views/modify/modify.js b/client/views/modify/modify.js index 1fb0514d..2dc6773b 100644 --- a/client/views/modify/modify.js +++ b/client/views/modify/modify.js @@ -43,7 +43,7 @@ Template.modify.events({ return false; } // Calls the server-side "modify" method to update the DBs - Meteor.call('modify', question, event.currentTarget.id, Session.get("tablename"), function (error, result) { + Meteor.call('modify', question, event.currentTarget.id, Session.get("id"), function (error, result) { if(result) { // If successful, redirect back to the list page //window.location.href = "/list"; diff --git a/lib/routes.js b/lib/routes.js index 14c6cc67..69d33769 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -104,7 +104,7 @@ Router.route('listlink', { if(instance) { this.render('list', { data: function() { - return instance + return instance; } }); } else { @@ -142,17 +142,17 @@ Router.route('/rss/:tablename', { // Retrieves table and question data for the tablename parameter var table = Instances.findOne({ - tablename: this.params.tablename + _id: this.params._id }); var questions = Questions.find({ - tablename: this.params.tablename + instanceid: this.params._id }).fetch(); // Creates XML header var xmlData = ' '; xmlData += "" + table.tablename + ""; - xmlData += "http://cyber.law.harvard.edu/questions/list/" + table.tablename + ""; + xmlData += "http://cyber.law.harvard.edu/questions/list/" + table._id + ""; xmlData += "Questions and answers submitted during class"; xmlData += "en-US"; xmlData += "Copyright 2006 The President and Fellows of Harvard College."; diff --git a/server/methods.js b/server/methods.js index 3e0bc7b3..473a162b 100644 --- a/server/methods.js +++ b/server/methods.js @@ -163,19 +163,19 @@ Meteor.methods({ } }, // Method that unhides every question in a given table - unhide: function(table) { + unhide: function(instanceid) { if(Meteor.user()) { var email = Meteor.user().emails[0].address; } else { return false; } var instance = Instances.findOne({ - tablename: table + _id: instanceid }); if(email === instance.admin) { // Sets state to normal for every question with tablename table Questions.update({ - tablename: table + instanceid: instanceid }, { $set: { state: "normal" @@ -189,7 +189,7 @@ Meteor.methods({ }); } }, - addMods: function(mods, table) { + addMods: function(mods, instanceid) { if(Meteor.user()) { var email = Meteor.user().emails[0].address; } else { @@ -197,11 +197,11 @@ Meteor.methods({ } var keys; var instance = Instances.findOne({ - tablename: table + _id: instanceid }); if(email === instance.admin) { Instances.update({ - tablename: table + _id: instanceid }, { $push: { moderators: { @@ -222,18 +222,18 @@ Meteor.methods({ return true; } }, - removeMods: function(mod, table) { + removeMods: function(mod, instanceid) { if(Meteor.user()) { var email = Meteor.user().emails[0].address; } else { return false; } var instance = Instances.findOne({ - tablename: table + _id: instanceid }); if(email === instance.admin) { Instances.update({ - tablename: table + _id: instanceid }, { $pull: { moderators: mod @@ -249,7 +249,7 @@ Meteor.methods({ return true; }, // Method that modifies a question - modify: function(question, id, table) { + modify: function(question, id, instanceid) { if(Meteor.user()) { var email = Meteor.user().emails[0].address; } else { @@ -257,7 +257,7 @@ Meteor.methods({ } // Checks whether the user has the proper admin privileges var instance = Instances.findOne({ - tablename: table + _id: instanceid }); if(email || instance.admin) { if(email != instance.admin) { @@ -284,7 +284,7 @@ Meteor.methods({ return true; }, // Method that combines two questions and answers - combine: function(question, id1, id2, table) { + combine: function(question, id1, id2, instanceid) { if(Meteor.user()) { var email = Meteor.user().emails[0].address; } else { @@ -292,7 +292,7 @@ Meteor.methods({ } // Checks whether the user has proper admin privileges var instance = Instances.findOne({ - tablename: table + _id: instanceid }); if(email !== instance.admin) { if(instance.moderators) { @@ -414,7 +414,7 @@ Meteor.methods({ return keys; }, // Method that removes a table from the database - remove: function(table) { + remove: function(instanceid) { if(Meteor.user()) { var email = Meteor.user().emails[0].address; } else { @@ -422,28 +422,28 @@ Meteor.methods({ } // Ensures that the user has proper admin privileges var instance = Instances.findOne({ - tablename: table + _id: instanceid }); // Removes all questions with the given tablename if(email !== instance.admin) { return false; } Questions.remove({ - tablename: table + instanceid: instanceid }, function(error) { if(error) { alert(error); } else { // If successful, removes all answers with the given tablename Answers.remove({ - tablename: table + instanceid: instanceid }, function(error) { if(error) { alert(error); } else { // If successful, remove the instance with the given tablename Instances.remove({ - tablename: table + _id: instanceid }, function(error) { if(error) { alert(error); @@ -465,7 +465,7 @@ Meteor.methods({ } }); }, - adminRemove: function(id) { + adminRemove: function(instanceid) { // Ensures that the user has proper admin privileges var result; var hasAccess = false; @@ -475,7 +475,7 @@ Meteor.methods({ return false; } var table = Instances.findOne({ - _id: id + _id: instanceid }); if(email) { if(email === table.admin) { @@ -487,21 +487,21 @@ Meteor.methods({ if(hasAccess) { //Removes all of the questions with the given table ID Questions.remove({ - q: table.tablename + instanceid: instanceid }, function(error) { if(error) { alert(error); } else { // If successful, removes all answers with the given tablename Answers.remove({ - tablename: table.tablename + instanceid: instanceid }, function(error) { if(error) { alert(error); } else { // If successful, remove the instance with the given tablename Instances.remove({ - tablename: table.tablename + instanceid: instanceid }, function(error) { if(error) { alert(error); @@ -655,7 +655,7 @@ Meteor.methods({ _id: id }); var table = Instances.findOne({ - tablename: question.tablename + _id: question.instanceid }); if(email !== table.admin) { if(table.moderators) { From 8a8f6d4ca2efdfe6b465b2eceed05d4298df96ae Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Mon, 26 Oct 2015 16:23:36 -0400 Subject: [PATCH 12/29] Fix admin methods. --- server/methods.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/methods.js b/server/methods.js index 473a162b..dfae19cd 100644 --- a/server/methods.js +++ b/server/methods.js @@ -501,7 +501,7 @@ Meteor.methods({ } else { // If successful, remove the instance with the given tablename Instances.remove({ - instanceid: instanceid + _id: instanceid }, function(error) { if(error) { alert(error); From b45c2f4079c2c15aad1d17cf82298d4d0dc281f4 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Fri, 6 Nov 2015 13:51:03 -0500 Subject: [PATCH 13/29] Update vote to use instance IDs. --- client/views/combine/combine.js | 2 +- client/views/create/create.js | 1 - client/views/list/list.js | 2 +- client/views/modify/modify.js | 2 +- client/views/propose/propose.js | 2 +- lib/common.js | 5 ++-- server/methods.js | 46 +++++---------------------------- server/publish.js | 8 +++--- 8 files changed, 15 insertions(+), 53 deletions(-) diff --git a/client/views/combine/combine.js b/client/views/combine/combine.js index 918c9be8..52057a54 100644 --- a/client/views/combine/combine.js +++ b/client/views/combine/combine.js @@ -6,7 +6,7 @@ Template.combine.onCreated(function () { window.location.href = "/"; } else { // Checks whether the current user has admin privileges - Meteor.call('adminCheck', Session.get("tablename"), function (error, result) { + Meteor.call('adminCheck', Session.get("id"), function (error, result) { if(!result) { // If not, redirects back to the list page window.location.href = "/list"; diff --git a/client/views/create/create.js b/client/views/create/create.js index dce8930c..744920ad 100644 --- a/client/views/create/create.js +++ b/client/views/create/create.js @@ -118,7 +118,6 @@ Template.create.events({ } else { // Redirects to the newly-created table's list page Blaze.remove(dropDownTemplate); - Router.go("/list/" + result); } }); }, diff --git a/client/views/list/list.js b/client/views/list/list.js index 543e7be3..1da5e1d1 100644 --- a/client/views/list/list.js +++ b/client/views/list/list.js @@ -283,7 +283,7 @@ Template.list.events({ var ip = result; if (!error) { // Calls server-side "vote" method to update the Questions and Vote DBs - Meteor.call('vote', event.currentTarget.id, ip, Session.get("tablename"), function(error, result) { + Meteor.call('vote', event.currentTarget.id, ip, Session.get("id"), function(error, result) { // If the result is an object, there was an error if(typeof result === 'object') { // Store an object of the error names and codes diff --git a/client/views/modify/modify.js b/client/views/modify/modify.js index 2dc6773b..965060fc 100644 --- a/client/views/modify/modify.js +++ b/client/views/modify/modify.js @@ -6,7 +6,7 @@ Template.modify.onCreated(function () { window.location.href = "/"; } else { // Checks whether the user has proper admin privileges - Meteor.call('adminCheck', Session.get("tablename"), function (error, result) { + Meteor.call('adminCheck', Session.get("id"), function (error, result) { if(!result) { // If not, redirects back to the list page window.location.href = "/list"; diff --git a/client/views/propose/propose.js b/client/views/propose/propose.js index 83d69dd7..f924bd27 100644 --- a/client/views/propose/propose.js +++ b/client/views/propose/propose.js @@ -213,7 +213,7 @@ Template.propose.events({ return false; } else { // If successful, redirect back to the list page - // Router.go("/list"); + //Router.go("/list"); if(typeof currentError != "undefined") { Blaze.remove(currentError); } diff --git a/lib/common.js b/lib/common.js index a2fa3aa8..c1411565 100644 --- a/lib/common.js +++ b/lib/common.js @@ -159,10 +159,9 @@ Schemas.Vote = new SimpleSchema({ type: String, regEx: /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/, }, - tablename: { + instanceid: { type: String, - regEx: /^[a-zA-Z0-9]{4,30}$/, - optional: true + max: 30 } }); diff --git a/server/methods.js b/server/methods.js index dfae19cd..ed6331ce 100644 --- a/server/methods.js +++ b/server/methods.js @@ -534,12 +534,6 @@ Meteor.methods({ return false; } var result; - var existsInstance = Instances.findOne({ - tablename: name - }); - if(existsInstance) { - return 1; - } var originalInstance = Instances.findOne({ _id: id }); @@ -562,41 +556,13 @@ Meteor.methods({ }, function(error, count, status) { if(!error) { Questions.update({ - tablename: originalName + instanceid: id }, { $set: { tablename: name } }, { multi: true - }, function(error, count, status) { - if(!error) { - Answers.update({ - tablename: originalName - }, { - $set: { - tablename: name - } - }, { - multi: true - }, function(error, count, status) { - if(!error) { - Votes.update({ - tablename: originalName - }, { - $set: { - tablename: name - } - }, { - multi: true - }, function(error, count, status) { - if(!error) { - return 3; - } - }); - } - }); - } }); } }); @@ -605,17 +571,17 @@ Meteor.methods({ } }, // Method that registers a vote on a question - vote: function(id, ip, tablename) { + vote: function(questionid, ip, instanceid) { var keys = ""; // Ensures that the user hasn't already voted from their IP address var votes = Votes.find({ - qid: id, + qid: questionid, ip: ip }); if(votes.fetch().length == 0) { // If they haven't voted, increment the given quesiton's vote # by 1 and update the lasttouch Questions.update({ - _id: id + _id: questionid }, { $set: { lasttouch: new Date().getTime() - 1000 @@ -630,9 +596,9 @@ Meteor.methods({ } else { // If successful, insert vote into the votes DB Votes.insert({ - qid: id, + qid: questionid, ip: ip, - tablename: tablename, + instanceid: instanceid, }, function(error, id) { if(error) { // If error, set keys to the error object diff --git a/server/publish.js b/server/publish.js index 19e6d978..d77156fe 100644 --- a/server/publish.js +++ b/server/publish.js @@ -24,15 +24,13 @@ Meteor.publish('questions', function(instanceid) { // Only publishes to the user the answers that are associated with the selected table Meteor.publish('answers', function(instanceid) { return Answers.find({ - instanceid: instanceid, + instanceid: instanceid }); }); // Only publishes to the user the votes that are associated with the selected table -Meteor.publish('votes', function(table) { +Meteor.publish('votes', function(instanceid) { return Votes.find({ - tablename: { - $regex: new RegExp("^" + table, "i") - } + instanceid: instanceid }); }); \ No newline at end of file From 9e82776ea887ac0dfc2dc12bc5370e46d05c5a8c Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Fri, 13 Nov 2015 16:11:58 -0500 Subject: [PATCH 14/29] Fix syntax errors and add ability to make anonymous replies. --- .../chunks/question_div/question_div.html | 11 ++++++++++ .../chunks/question_div/question_div.js | 2 +- client/views/list/list.js | 22 +++++++++++++++++++ client/views/propose/propose.js | 2 +- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/client/views/helpers/chunks/question_div/question_div.html b/client/views/helpers/chunks/question_div/question_div.html index 537bbaa6..4b214a76 100644 --- a/client/views/helpers/chunks/question_div/question_div.html +++ b/client/views/helpers/chunks/question_div/question_div.html @@ -105,6 +105,17 @@ {{#if currentUser}} +
+
+
+
+
+
+
+
+

Post as anonymous?

+
+
{{else}} diff --git a/client/views/helpers/chunks/question_div/question_div.js b/client/views/helpers/chunks/question_div/question_div.js index 86c14be5..ead514c5 100644 --- a/client/views/helpers/chunks/question_div/question_div.js +++ b/client/views/helpers/chunks/question_div/question_div.js @@ -9,4 +9,4 @@ Template.question_div.helpers({ return 150; } }, -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/client/views/list/list.js b/client/views/list/list.js index 38dae455..5e4b4ff0 100644 --- a/client/views/list/list.js +++ b/client/views/list/list.js @@ -361,6 +361,28 @@ Template.list.events({ $("#down" + theID).slideUp(); } }, + "click .checkbox": function(event, template) { + var checked = event.target.firstElementChild; + if(checked.style.display == "none" || !checked.style.display) { + checked.style.display = "block"; + if(Meteor.user()) { + $(".replyname").val("Anonymous"); + $(".replyemail").val(""); + } + } + }, + "click .checked": function(event, template) { + //console.log(event); + //return false; + var checked = event.target; + if(checked.style.display == "block") { + if(Meteor.user()) { + $(".replyname").val(Meteor.user().profile.name); + $(".replyemail").val(Meteor.user().emails[0].address); + } + checked.style.display = "none"; + } + }, "click .replybottombutton": function(event, template) { // Retrieves data from form var theID = event.target.id; diff --git a/client/views/propose/propose.js b/client/views/propose/propose.js index 882f3372..7752e46f 100644 --- a/client/views/propose/propose.js +++ b/client/views/propose/propose.js @@ -50,7 +50,7 @@ Template.propose.events({ checked.style.display = "none"; if(event.target.id == "savebox") { $("#bottominputcontainer").slideUp(); - $('#topinputcontainer').slideUp() + $('#topinputcontainer').slideUp(); document.getElementById("anoncheck").style.display = "block"; } else if(event.target.id == "anonbox") { if(Meteor.user()) { From 1bda11c3208fe9c2aeb47c89b9d1e75becffd8f2 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Mon, 16 Nov 2015 09:48:57 -0500 Subject: [PATCH 15/29] Disable the instance submit button after clicking it. --- client/views/create/create.js | 1 + 1 file changed, 1 insertion(+) diff --git a/client/views/create/create.js b/client/views/create/create.js index dce8930c..f469436c 100644 --- a/client/views/create/create.js +++ b/client/views/create/create.js @@ -56,6 +56,7 @@ Template.create.events({ if(!Meteor.user()) { return false; } + document.getElementById("buttonarea").disabled = true; var anonElement = document.getElementById("allowanoncheck"); if(anonElement.style.display) { var anonymous = (anonElement.style.display != "none"); From 2c8839bbf27e103c788b8ea1620f87c3de2c53b4 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Mon, 16 Nov 2015 11:10:19 -0500 Subject: [PATCH 16/29] Update CSS to properly show credits. --- client/styles/global.css | 2 +- client/views/credits/credits.css | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/client/styles/global.css b/client/styles/global.css index 768f8522..bbc62aa8 100644 --- a/client/styles/global.css +++ b/client/styles/global.css @@ -156,7 +156,7 @@ div #wrapper { bottom: 0; right:0; left:0; - opacity:.6; + opacity:.9; overflow:hidden; z-index:999999999999999; cursor:pointer; diff --git a/client/views/credits/credits.css b/client/views/credits/credits.css index 3add7fa3..5a0ab699 100644 --- a/client/views/credits/credits.css +++ b/client/views/credits/credits.css @@ -14,4 +14,9 @@ #creditstext a { text-decoration:underline; +} + +.creditsformcontainer { + position: relative; + z-index: 99999999999; } \ No newline at end of file From 41248431a3368055eb5fd8939958b022091f96ae Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Tue, 17 Nov 2015 10:24:30 -0500 Subject: [PATCH 17/29] Add error message if search is empty. --- client/views/main/main.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/client/views/main/main.js b/client/views/main/main.js index 7f02ceb4..6749b3ed 100644 --- a/client/views/main/main.js +++ b/client/views/main/main.js @@ -78,6 +78,12 @@ Template.home.helpers({ }] }).fetch(); } + if(instances.length < 1) { + showCreateError("Nothing found."); + } + else { + Blaze.remove(currentError); + } instances.sort(function(a, b) { return b.lasttouch - a.lasttouch; }); @@ -276,13 +282,13 @@ function timeSince(date) { } return interval + ' ' + intervalType; -}; +} function showCreateError(reason) { if(typeof currentError != "undefined") { Blaze.remove(currentError); } - var parentNode = document.getElementById("creatediv"); - var nextNode = document.getElementById("instancetopinputcontainer"); - currentError = Blaze.renderWithData(Template.form_error, reason, parentNode, nextNode); + var parentNode = document.getElementById("recent"); + var nextNode = document.getElementById("footercontainer"); + currentError = Blaze.renderWithData(Template.form_error, reason, parentNode); } \ No newline at end of file From 3432026c13d59b222b57961fd04f6148876d36b9 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Mon, 23 Nov 2015 15:52:24 -0500 Subject: [PATCH 18/29] Fix view to display anonymous replies. --- client/views/helpers/chunks/question_div/question_div.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/views/helpers/chunks/question_div/question_div.html b/client/views/helpers/chunks/question_div/question_div.html index f7b8bf18..05bc50c8 100644 --- a/client/views/helpers/chunks/question_div/question_div.html +++ b/client/views/helpers/chunks/question_div/question_div.html @@ -101,7 +101,7 @@
-
+
{{#if currentUser}} From 3462a03a8ff306d97858872b1ecb0e500d4a8179 Mon Sep 17 00:00:00 2001 From: Matthew Zagaja Date: Tue, 24 Nov 2015 13:22:15 -0500 Subject: [PATCH 19/29] Update credits to be more responsive. --- client/views/create/create.js | 2 +- client/views/credits/credits.css | 46 ++++++++++++++++++++++--------- client/views/credits/credits.html | 2 -- client/views/credits/credits.js | 8 +++++- client/views/footer/footer.js | 6 ---- 5 files changed, 41 insertions(+), 23 deletions(-) diff --git a/client/views/create/create.js b/client/views/create/create.js index 295ce1d7..e425910f 100644 --- a/client/views/create/create.js +++ b/client/views/create/create.js @@ -56,7 +56,7 @@ Template.create.events({ if(!Meteor.user()) { return false; } - document.getElementById("buttonarea").disabled = true; + //document.getElementById("buttonarea").disabled = true; var anonElement = document.getElementById("allowanoncheck"); var anonymous; if(anonElement.style.display) { diff --git a/client/views/credits/credits.css b/client/views/credits/credits.css index 5a0ab699..2ea02430 100644 --- a/client/views/credits/credits.css +++ b/client/views/credits/credits.css @@ -1,15 +1,15 @@ #creditstext { - color:#777777; - font-family:regular; - text-align:center; - font-size:14px; - display:block; - margin:0px auto; - padding:0px; - line-height:1.5em; - width:80%; - margin-top:25px; - margin-bottom:35px; + color: #777777; + font-family: regular; + text-align: center; + font-size: 14px; + display: block; + margin: 0 auto; + padding: 0; + line-height: 1.5em; + width: 80%; + margin-top: 25px; + margin-bottom: 35px; } #creditstext a { @@ -17,6 +17,26 @@ } .creditsformcontainer { - position: relative; - z-index: 99999999999; + position: fixed; + background-color:black; + top: 1%; + left: 30%; + width: 40%; + opacity:.9; + overflow:hidden; + z-index:999999999999999; + cursor:pointer; +} + +@media screen and (max-width: 667px) { + .creditsformcontainer { + background-color:black; + top: 0; + left: 0; + width: 100%; + opacity:.9; + overflow:hidden; + z-index:999999999999999; + cursor:pointer; +} } \ No newline at end of file diff --git a/client/views/credits/credits.html b/client/views/credits/credits.html index ed1004f6..1ad3abbf 100644 --- a/client/views/credits/credits.html +++ b/client/views/credits/credits.html @@ -1,6 +1,4 @@