Jelajahi Sumber

Merge branch 'february_release' of https://github.com/Musare/Musare into february_release

Conflicts:
	app/client/stylesheets/app.css
KrisVos130 9 tahun lalu
induk
melakukan
346805a3d9

+ 2 - 1
app/.meteor/packages

@@ -31,4 +31,5 @@ emojione:emojione
 utilities:avatar
 utilities:avatar
 matb33:collection-hooks
 matb33:collection-hooks
 aldeed:collection2
 aldeed:collection2
-materialize:materialize
+materialize:materialize
+accounts-facebook

+ 2 - 0
app/.meteor/versions

@@ -1,4 +1,5 @@
 accounts-base@1.2.2
 accounts-base@1.2.2
+accounts-facebook@1.0.6
 accounts-github@1.0.6
 accounts-github@1.0.6
 accounts-oauth@1.1.8
 accounts-oauth@1.1.8
 accounts-password@1.1.4
 accounts-password@1.1.4
@@ -32,6 +33,7 @@ ejson@1.0.7
 email@1.0.8
 email@1.0.8
 emojione:emojione@1.5.2
 emojione:emojione@1.5.2
 es5-shim@4.1.14
 es5-shim@4.1.14
+facebook@1.2.2
 fastclick@1.0.7
 fastclick@1.0.7
 geojson-utils@1.0.4
 geojson-utils@1.0.4
 github@1.1.4
 github@1.1.4

+ 28 - 3
app/client/scripts/events.js

@@ -1,3 +1,5 @@
+var feedbackData;
+
 function getSpotifyInfo(title, cb, artist) {
 function getSpotifyInfo(title, cb, artist) {
     var q = "";
     var q = "";
     q = title;
     q = title;
@@ -223,7 +225,29 @@ Template.feedback.events({
         if($("#feedback_message").val().length !== 0){
         if($("#feedback_message").val().length !== 0){
             Meteor.call("sendFeedback", $("#feedback_message").val());
             Meteor.call("sendFeedback", $("#feedback_message").val());
             $("#feedback_message").val("");
             $("#feedback_message").val("");
+            $("#modal1").closeModal()
         }
         }
+    },
+    "click .upvote": function(){
+        var message = $(this).parent("card").prevObject[0].message;
+        Meteor.call("upvoteFeedback", message);
+    },
+    "click #delete": function(){
+        var message = $(this).parent("card").prevObject[0].message;
+        Meteor.call("deleteFeedback", message);
+    },
+    "click #edit": function(){
+        $("#editModal").click()
+        var data = Feedback.findOne({"message": $(this).parent("card").prevObject[0].message});
+        feedbackData = data.message;
+        $("#edit_feedback_message").val(data.message);
+    },
+    "click #edit_feedback_submit": function(){
+        var oldMessage = feedbackData;
+        var newMessage = $("#edit_feedback_message").val()
+        $("#edit_feedback_message").val("")
+        Meteor.call("updateFeedback", oldMessage, newMessage);
+        $("#editFeedback").closeModal();
     }
     }
 });
 });
 
 
@@ -617,10 +641,11 @@ Template.queues.events({
 Template.register.events({
 Template.register.events({
     "submit form": function(e){
     "submit form": function(e){
         e.preventDefault();
         e.preventDefault();
-        var username = e.target.registerUsername.value;
-        var email = e.target.registerEmail.value;
-        var password = e.target.registerPassword.value;
+        var username = $("#username").val()
+        var email = $("#email").val()
+        var password = $("#password").val();
         var captchaData = grecaptcha.getResponse();
         var captchaData = grecaptcha.getResponse();
+        console.log(captchaData)
         Meteor.call("createUserMethod", {username: username, email: email, password: password}, captchaData, function(err, res) {
         Meteor.call("createUserMethod", {username: username, email: email, password: password}, captchaData, function(err, res) {
             grecaptcha.reset();
             grecaptcha.reset();
 
 

+ 91 - 92
app/client/scripts/helpers.js

@@ -1,36 +1,36 @@
 Template.admin.helpers({
 Template.admin.helpers({
-    queueCount: function(display) {
+    queueCount: function (display) {
         var d = display.toLowerCase();
         var d = display.toLowerCase();
         return queues && "songs" in queues ? queues.songs.length : 0;
         return queues && "songs" in queues ? queues.songs.length : 0;
         var queues = Queues.findOne({type: d});
         var queues = Queues.findOne({type: d});
     },
     },
-    queues: function() {
+    queues: function () {
         var queues = Queues.find({}).fetch();
         var queues = Queues.find({}).fetch();
         return queues;
         return queues;
     },
     },
-    usersOnline: function(){
-        Meteor.call("getUserNum", function(err, num){
-            if(err){
+    usersOnline: function () {
+        Meteor.call("getUserNum", function (err, num) {
+            if (err) {
                 console.log(err);
                 console.log(err);
             }
             }
             Session.set("userNum", num);
             Session.set("userNum", num);
         });
         });
         return Session.get("userNum");
         return Session.get("userNum");
     },
     },
-    roomUserNum: function(){
+    roomUserNum: function () {
         var type = this.type;
         var type = this.type;
         var userNum = Rooms.findOne({type: type}).users;
         var userNum = Rooms.findOne({type: type}).users;
         return userNum;
         return userNum;
     },
     },
-    allUsers: function(){
-        Meteor.call("getTotalUsers", function(err, num){
+    allUsers: function () {
+        Meteor.call("getTotalUsers", function (err, num) {
             Session.set("allUsers", num);
             Session.set("allUsers", num);
         })
         })
         return Session.get("allUsers");
         return Session.get("allUsers");
     },
     },
-    playlists: function() {
+    playlists: function () {
         var playlists = Playlists.find({}).fetch();
         var playlists = Playlists.find({}).fetch();
-        playlists.map(function(playlist) {
+        playlists.map(function (playlist) {
             if (Rooms.find({type: playlist.type}).count() !== 1) {
             if (Rooms.find({type: playlist.type}).count() !== 1) {
                 return;
                 return;
             } else {
             } else {
@@ -40,45 +40,45 @@ Template.admin.helpers({
         });
         });
         return playlists;
         return playlists;
     },
     },
-    reportsCount: function(room) {
+    reportsCount: function (room) {
         room = room.toLowerCase();
         room = room.toLowerCase();
-        var reports = Reports.findOne({room:room});
+        var reports = Reports.findOne({room: room});
         return reports && "report" in reports ? reports.report.length : 0;
         return reports && "report" in reports ? reports.report.length : 0;
     }
     }
 });
 });
 
 
 Template.alerts.helpers({
 Template.alerts.helpers({
-    alerts: function() {
+    alerts: function () {
         return Alerts.find({active: true});
         return Alerts.find({active: true});
     }
     }
 });
 });
 
 
 Template.alertsDashboard.helpers({
 Template.alertsDashboard.helpers({
-    "activeAlerts": function() {
+    "activeAlerts": function () {
         return Alerts.find({active: true});
         return Alerts.find({active: true});
     },
     },
-    "inactiveAlerts": function() {
+    "inactiveAlerts": function () {
         return Alerts.find({active: false});
         return Alerts.find({active: false});
     }
     }
 });
 });
 
 
 Template.banned.helpers({
 Template.banned.helpers({
-    bannedAt: function() {
+    bannedAt: function () {
         if (Session.get("ban") !== undefined) {
         if (Session.get("ban") !== undefined) {
             return Session.get("ban").bannedAt;
             return Session.get("ban").bannedAt;
         }
         }
     },
     },
-    bannedBy: function() {
+    bannedBy: function () {
         if (Session.get("ban") !== undefined) {
         if (Session.get("ban") !== undefined) {
             return Session.get("ban").bannedBy;
             return Session.get("ban").bannedBy;
         }
         }
     },
     },
-    bannedUntil: function() {
+    bannedUntil: function () {
         if (Session.get("ban") !== undefined) {
         if (Session.get("ban") !== undefined) {
             return Session.get("ban").bannedUntil;
             return Session.get("ban").bannedUntil;
         }
         }
     },
     },
-    bannedReason: function() {
+    bannedReason: function () {
         if (Session.get("ban") !== undefined) {
         if (Session.get("ban") !== undefined) {
             return Session.get("ban").bannedReason;
             return Session.get("ban").bannedReason;
         }
         }
@@ -86,33 +86,28 @@ Template.banned.helpers({
 });
 });
 
 
 Template.feedback.helpers({
 Template.feedback.helpers({
-    feedback: function(){
-        var data = Feedback.findOne();
-        if(data !== undefined) {
-            return data.messages.reverse();
-        } else{
-            return [];
-        }
+    feedback: function () {
+        return Feedback.find().fetch().reverse();
     }
     }
 })
 })
 
 
 Template.header.helpers({
 Template.header.helpers({
-    userId: function() {
+    userId: function () {
         return Meteor.userId();
         return Meteor.userId();
     }
     }
 });
 });
 
 
 Template.home.helpers({
 Template.home.helpers({
-    currentSong: function(){
+    currentSong: function () {
         var type = this.type;
         var type = this.type;
         var room = Rooms.findOne({type: type});
         var room = Rooms.findOne({type: type});
-        if(room !== undefined){
+        if (room !== undefined) {
             return room.currentSong;
             return room.currentSong;
         } else {
         } else {
             return false;
             return false;
         }
         }
     },
     },
-    userNum: function(){
+    userNum: function () {
         var type = this.type;
         var type = this.type;
         var userNum = Rooms.findOne({type: type}).users;
         var userNum = Rooms.findOne({type: type}).users;
         return userNum;
         return userNum;
@@ -120,13 +115,13 @@ Template.home.helpers({
 });
 });
 
 
 Template.playlist.helpers({
 Template.playlist.helpers({
-    playlist_songs: function() {
+    playlist_songs: function () {
         parts = location.href.split('/');
         parts = location.href.split('/');
         id = parts.pop();
         id = parts.pop();
         type = id.toLowerCase();
         type = id.toLowerCase();
         var data = Playlists.findOne({type: type});
         var data = Playlists.findOne({type: type});
         if (data !== undefined) {
         if (data !== undefined) {
-            data.songs.map(function(song) {
+            data.songs.map(function (song) {
                 if (Session.get("currentSong") !== undefined && song.mid === Session.get("currentSong").mid) {
                 if (Session.get("currentSong") !== undefined && song.mid === Session.get("currentSong").mid) {
                     song.current = true;
                     song.current = true;
                 } else {
                 } else {
@@ -142,28 +137,28 @@ Template.playlist.helpers({
 });
 });
 
 
 Template.profile.helpers({
 Template.profile.helpers({
-    "real_name": function(){
+    "real_name": function () {
         return Session.get("real_name");
         return Session.get("real_name");
     },
     },
-    "username": function() {
+    "username": function () {
         return Session.get("username")
         return Session.get("username")
     },
     },
-    "first_joined": function() {
+    "first_joined": function () {
         return moment(Session.get("first_joined")).format("DD/MM/YYYY HH:mm:ss");
         return moment(Session.get("first_joined")).format("DD/MM/YYYY HH:mm:ss");
     },
     },
-    "rank": function() {
+    "rank": function () {
         return Session.get("rank");
         return Session.get("rank");
     },
     },
-    loaded: function() {
+    loaded: function () {
         return Session.get("loaded");
         return Session.get("loaded");
     },
     },
-    likedSongs: function(){
+    likedSongs: function () {
         var likedArr = [];
         var likedArr = [];
-        Session.get("liked").forEach(function(mid){
-            Rooms.find().forEach(function(room){
-                Playlists.find({type: room.type}).forEach(function(pl){
-                    for(var i in pl.songs){
-                        if(pl.songs[i].mid === mid){
+        Session.get("liked").forEach(function (mid) {
+            Rooms.find().forEach(function (room) {
+                Playlists.find({type: room.type}).forEach(function (pl) {
+                    for (var i in pl.songs) {
+                        if (pl.songs[i].mid === mid) {
                             likedArr.push({title: pl.songs[i].title, artist: pl.songs[i].artist, room: room.display});
                             likedArr.push({title: pl.songs[i].title, artist: pl.songs[i].artist, room: room.display});
                         }
                         }
                     }
                     }
@@ -172,14 +167,18 @@ Template.profile.helpers({
         });
         });
         return likedArr;
         return likedArr;
     },
     },
-    dislikedSongs: function(){
+    dislikedSongs: function () {
         var dislikedArr = [];
         var dislikedArr = [];
-        Session.get("disliked").forEach(function(mid){
-            Rooms.find().forEach(function(room){
-                Playlists.find({type: room.type}).forEach(function(pl){
-                    for(var i in pl.songs){
-                        if(pl.songs[i].mid === mid){
-                            dislikedArr.push({title: pl.songs[i].title, artist: pl.songs[i].artist, room: room.display});
+        Session.get("disliked").forEach(function (mid) {
+            Rooms.find().forEach(function (room) {
+                Playlists.find({type: room.type}).forEach(function (pl) {
+                    for (var i in pl.songs) {
+                        if (pl.songs[i].mid === mid) {
+                            dislikedArr.push({
+                                title: pl.songs[i].title,
+                                artist: pl.songs[i].artist,
+                                room: room.display
+                            });
                         }
                         }
                     }
                     }
                 });
                 });
@@ -187,19 +186,19 @@ Template.profile.helpers({
         });
         });
         return dislikedArr;
         return dislikedArr;
     },
     },
-    isUser: function(){
+    isUser: function () {
         var parts = Router.current().url.split('/');
         var parts = Router.current().url.split('/');
         var username = parts.pop();
         var username = parts.pop();
-        if(username === Meteor.user().profile.username){
+        if (username === Meteor.user().profile.username) {
             return true;
             return true;
         }
         }
     }
     }
 });
 });
 
 
 Template.queues.helpers({
 Template.queues.helpers({
-    queues: function() {
+    queues: function () {
         var queues = Queues.find({}).fetch();
         var queues = Queues.find({}).fetch();
-        queues.map(function(queue) {
+        queues.map(function (queue) {
             if (Rooms.find({type: queue.type}).count() !== 1) {
             if (Rooms.find({type: queue.type}).count() !== 1) {
                 return;
                 return;
             } else {
             } else {
@@ -215,31 +214,31 @@ Template.queues.helpers({
 });
 });
 
 
 Template.room.helpers({
 Template.room.helpers({
-    singleVideo: function() {
+    singleVideo: function () {
         return true;
         return true;
     },
     },
-    chat: function() {
-        Meteor.setTimeout(function() {
+    chat: function () {
+        Meteor.setTimeout(function () {
             var elem = document.getElementById('chat');
             var elem = document.getElementById('chat');
             if (elem !== undefined && elem !== null) {
             if (elem !== undefined && elem !== null) {
                 elem.scrollTop = elem.scrollHeight;
                 elem.scrollTop = elem.scrollHeight;
             }
             }
         }, 100);
         }, 100);
-        return Chat.find({type: Session.get("type")}, {sort: {time: -1}, limit: 50 }).fetch().reverse();
+        return Chat.find({type: Session.get("type")}, {sort: {time: -1}, limit: 50}).fetch().reverse();
     },
     },
-    globalChat: function() {
-        Meteor.setTimeout(function() {
+    globalChat: function () {
+        Meteor.setTimeout(function () {
             var elem = document.getElementById('global-chat');
             var elem = document.getElementById('global-chat');
             if (elem !== undefined && elem !== null) {
             if (elem !== undefined && elem !== null) {
                 elem.scrollTop = elem.scrollHeight;
                 elem.scrollTop = elem.scrollHeight;
             }
             }
         }, 100);
         }, 100);
-        return Chat.find({type: "global"}, {sort: {time: -1}, limit: 50 }).fetch().reverse();
+        return Chat.find({type: "global"}, {sort: {time: -1}, limit: 50}).fetch().reverse();
     },
     },
-    likes: function() {
+    likes: function () {
         var playlist = Playlists.findOne({type: Session.get("type")});
         var playlist = Playlists.findOne({type: Session.get("type")});
         var likes = 0;
         var likes = 0;
-        playlist.songs.forEach(function(song) {
+        playlist.songs.forEach(function (song) {
             if (Session.get("currentSong") && song.mid === Session.get("currentSong").mid) {
             if (Session.get("currentSong") && song.mid === Session.get("currentSong").mid) {
                 likes = song.likes;
                 likes = song.likes;
                 return;
                 return;
@@ -247,10 +246,10 @@ Template.room.helpers({
         });
         });
         return likes;
         return likes;
     },
     },
-    dislikes: function() {
+    dislikes: function () {
         var playlist = Playlists.findOne({type: Session.get("type")});
         var playlist = Playlists.findOne({type: Session.get("type")});
         var dislikes = 0;
         var dislikes = 0;
-        playlist.songs.forEach(function(song) {
+        playlist.songs.forEach(function (song) {
             if (Session.get("currentSong") && song.mid === Session.get("currentSong").mid) {
             if (Session.get("currentSong") && song.mid === Session.get("currentSong").mid) {
                 dislikes = song.dislikes;
                 dislikes = song.dislikes;
                 return;
                 return;
@@ -258,7 +257,7 @@ Template.room.helpers({
         });
         });
         return dislikes;
         return dislikes;
     },
     },
-    liked: function() {
+    liked: function () {
         if (Meteor.userId()) {
         if (Meteor.userId()) {
             var currentSong = Session.get("currentSong");
             var currentSong = Session.get("currentSong");
             if (currentSong && Meteor.user().profile.liked.indexOf(currentSong.mid) !== -1) {
             if (currentSong && Meteor.user().profile.liked.indexOf(currentSong.mid) !== -1) {
@@ -270,7 +269,7 @@ Template.room.helpers({
             "";
             "";
         }
         }
     },
     },
-    disliked: function() {
+    disliked: function () {
         if (Meteor.userId()) {
         if (Meteor.userId()) {
             var currentSong = Session.get("currentSong");
             var currentSong = Session.get("currentSong");
             if (currentSong && Meteor.user().profile.disliked.indexOf(currentSong.mid) !== -1) {
             if (currentSong && Meteor.user().profile.disliked.indexOf(currentSong.mid) !== -1) {
@@ -282,81 +281,81 @@ Template.room.helpers({
             "";
             "";
         }
         }
     },
     },
-    type: function() {
+    type: function () {
         var parts = location.href.split('/');
         var parts = location.href.split('/');
         var id = parts.pop().toLowerCase();
         var id = parts.pop().toLowerCase();
         return Rooms.findOne({type: id}).display;
         return Rooms.findOne({type: id}).display;
     },
     },
-    users: function() {
+    users: function () {
         var parts = location.href.split('/');
         var parts = location.href.split('/');
         var id = parts.pop().toLowerCase();
         var id = parts.pop().toLowerCase();
         return Rooms.findOne({type: id}).users;
         return Rooms.findOne({type: id}).users;
     },
     },
-    title: function(){
+    title: function () {
         return Session.get("title");
         return Session.get("title");
     },
     },
-    artist: function(){
+    artist: function () {
         return Session.get("artist");
         return Session.get("artist");
     },
     },
-    loaded: function() {
+    loaded: function () {
         return Session.get("loaded");
         return Session.get("loaded");
     },
     },
-    paused: function() {
+    paused: function () {
         return Session.get("state") === "paused";
         return Session.get("state") === "paused";
     },
     },
-    private: function() {
+    private: function () {
         return Rooms.findOne({type: Session.get("type")}).private === true;
         return Rooms.findOne({type: Session.get("type")}).private === true;
     },
     },
-    report: function() {
+    report: function () {
         return Session.get("reportObj");
         return Session.get("reportObj");
     },
     },
-    reportSong: function() {
+    reportSong: function () {
         return Session.get("reportSong");
         return Session.get("reportSong");
     },
     },
-    reportTitle: function() {
+    reportTitle: function () {
         return Session.get("reportTitle");
         return Session.get("reportTitle");
     },
     },
-    reportAuthor: function() {
+    reportAuthor: function () {
         return Session.get("reportAuthor");
         return Session.get("reportAuthor");
     },
     },
-    reportDuration: function() {
+    reportDuration: function () {
         return Session.get("reportDuration");
         return Session.get("reportDuration");
     },
     },
-    reportAudio: function() {
+    reportAudio: function () {
         return Session.get("reportAudio");
         return Session.get("reportAudio");
     },
     },
-    reportAlbumart: function() {
+    reportAlbumart: function () {
         return Session.get("reportAlbumart");
         return Session.get("reportAlbumart");
     },
     },
-    reportOther: function() {
+    reportOther: function () {
         return Session.get("reportOther");
         return Session.get("reportOther");
     },
     },
-    currentSong: function() {
+    currentSong: function () {
         return Session.get("currentSong");
         return Session.get("currentSong");
     },
     },
-    previousSong: function() {
+    previousSong: function () {
         return Session.get("previousSong");
         return Session.get("previousSong");
     },
     },
-    currentSongR: function() {
+    currentSongR: function () {
         return Session.get("currentSongR");
         return Session.get("currentSongR");
     },
     },
-    previousSongR: function() {
+    previousSongR: function () {
         return Session.get("previousSongR");
         return Session.get("previousSongR");
     },
     },
-    reportingSong: function() {
+    reportingSong: function () {
         if (Session.get("reportPrevious")) {
         if (Session.get("reportPrevious")) {
             return Session.get("previousSongR");
             return Session.get("previousSongR");
         } else {
         } else {
             return Session.get("currentSongR");
             return Session.get("currentSongR");
         }
         }
     },
     },
-    votes: function(){
+    votes: function () {
         return Rooms.findOne({type: Session.get("type")}).votes;
         return Rooms.findOne({type: Session.get("type")}).votes;
     }
     }
 });
 });
 
 
 Template.settings.helpers({
 Template.settings.helpers({
-    username: function() {
+    username: function () {
         if (Meteor.user() !== undefined) {
         if (Meteor.user() !== undefined) {
             return Meteor.user().profile.username;
             return Meteor.user().profile.username;
         } else {
         } else {
@@ -366,15 +365,15 @@ Template.settings.helpers({
 });
 });
 
 
 Template.stations.helpers({
 Template.stations.helpers({
-    playlist: function() {
+    playlist: function () {
         var query = {type: Session.get("playlistToEdit").toLowerCase()};
         var query = {type: Session.get("playlistToEdit").toLowerCase()};
         var playlists = Playlists.find(query).fetch();
         var playlists = Playlists.find(query).fetch();
         return playlists;
         return playlists;
     },
     },
-    whichStation: function(){
+    whichStation: function () {
         return Session.get("playlistToEdit");
         return Session.get("playlistToEdit");
     },
     },
-    reports: function() {
+    reports: function () {
         var query = {room: Session.get("playlistToEdit").toLowerCase()};
         var query = {room: Session.get("playlistToEdit").toLowerCase()};
         var reports = Reports.find(query).fetch();
         var reports = Reports.find(query).fetch();
         console.log(reports);
         console.log(reports);

+ 72 - 0
app/client/stylesheets/app.css

@@ -9,6 +9,18 @@ main {
     flex: 1 0 auto;
     flex: 1 0 auto;
 }
 }
 
 
+main h3{
+    margin-left: 10px;
+}
+
+main h4.thin{
+    margin-left: 10px;
+}
+
+main p.flow-text{
+    margin-left: 10px;
+}
+
 ::-webkit-scrollbar{
 ::-webkit-scrollbar{
     width: 8px;
     width: 8px;
 }
 }
@@ -22,6 +34,10 @@ main {
     background-color: white;
     background-color: white;
 }
 }
 
 
+textarea{
+    color: white;
+}
+
 .brand-logo {
 .brand-logo {
     margin-left: 10px;
     margin-left: 10px;
 }
 }
@@ -47,6 +63,62 @@ main {
     float: left;
     float: left;
 }
 }
 
 
+.user-num{
+    font-size: 1.6em !important;
+}
+
+.card i{
+    line-height: inherit;
+}
+
+.card-content p i{
+    float: left;
+}
+
+.register{
+    margin: 10px 0 0 0px;
+}
+
+.social{
+    margin: 0px 0 10px 0px;
+    width: 155px;
+}
+
+.login-btn{
+    margin: 10px 0 0 10px;
+}
+
+.upvote{
+    float: right;
+    color: #00C853;
+    cursor: pointer;
+    line-height: initial !important;
+}
+
+.upvote-text{
+    display: inline;
+    float: right;
+    font-size: 1.5em;
+    margin-top: -3px;
+    margin-right: 10px;
+    color: white;
+}
+
+.float-btn{
+    position: initial;
+    float: right;
+    margin-top: -3em;
+    margin-right: -2em;
+}
+
+.character-counter{
+    color: white;
+}
+
+.fixed-action-btn.horizontal ul{
+    right: 45px;
+}
+
 .musare {
 .musare {
     background-color: rgb(107, 197, 164) !important;
     background-color: rgb(107, 197, 164) !important;
 }
 }

+ 27 - 0
app/client/templates/feedback.html

@@ -3,15 +3,32 @@
     <main>
     <main>
         <h3 class="black-text thin text-center">Feedback</h3>
         <h3 class="black-text thin text-center">Feedback</h3>
         <a class="waves-effect waves-light btn modal-trigger feedback-btn" href="#modal1">Send New Feedback</a>
         <a class="waves-effect waves-light btn modal-trigger feedback-btn" href="#modal1">Send New Feedback</a>
+        <a id="editModal" class="modal-trigger" href="#editFeedback" style="display:none"></a>
+
         <div class="row">
         <div class="row">
             {{#each feedback}}
             {{#each feedback}}
                 <div class="col s12 m4">
                 <div class="col s12 m4">
                     <div class="card blue-grey darken-1">
                     <div class="card blue-grey darken-1">
                         <div class="card-content white-text">
                         <div class="card-content white-text">
+                            {{#if isAdmin}}
+                                <div class="fixed-action-btn horizontal float-btn" style="bottom: 45px; right: 24px;">
+                                    <a class="btn-floating btn-large red">
+                                        <i class="large material-icons">more_vert</i>
+                                    </a>
+                                    <ul>
+                                        <li><a id="edit" class="btn-floating green"><i
+                                                class="material-icons">create</i></a></li>
+                                        <li><a id="delete" class="btn-floating red"><i class="material-icons">delete</i></a>
+                                        </li>
+                                    </ul>
+                                </div>
+                            {{/if}}
                             <p>{{message}}</p>
                             <p>{{message}}</p>
                         </div>
                         </div>
                         <div class="card-action">
                         <div class="card-action">
                             <a class="lowercase" href="/u/{{username}}">{{username}}</a>
                             <a class="lowercase" href="/u/{{username}}">{{username}}</a>
+                            <i class="material-icons upvote">thumb_up</i>
+                            <p class="upvote-text">{{upvotes}}</p>
                         </div>
                         </div>
                     </div>
                     </div>
                 </div>
                 </div>
@@ -27,10 +44,20 @@
             <a id="feedback_submit" class="waves-effect waves-light btn">Submit</a>
             <a id="feedback_submit" class="waves-effect waves-light btn">Submit</a>
         </div>
         </div>
     </div>
     </div>
+    <div id="editFeedback" class="modal">
+        <div class="modal-content teal darken-4">
+            <label>Edit Feedback Message</label>
+            <div class="input-field">
+                <textarea id="edit_feedback_message" class="materialize-textarea" length="500"></textarea>
+            </div>
+            <a id="edit_feedback_submit" class="waves-effect waves-light btn">Submit</a>
+        </div>
+    </div>
     {{> footer}}
     {{> footer}}
     <script>
     <script>
         $(document).ready(function () {
         $(document).ready(function () {
             $('#feedback_message').characterCounter();
             $('#feedback_message').characterCounter();
+            $("#edit_feedback_message").characterCounter();
             $('.modal-trigger').leanModal();
             $('.modal-trigger').leanModal();
         });
         });
     </script>
     </script>

+ 3 - 3
app/client/templates/footer.html

@@ -4,9 +4,9 @@
             <div class="col l6 s12">
             <div class="col l6 s12">
                 <h5 class="white-text">Stay Connected</h5>
                 <h5 class="white-text">Stay Connected</h5>
                 <p class="grey-text text-lighten-4">Follow us on social media or send us an email!</p>
                 <p class="grey-text text-lighten-4">Follow us on social media or send us an email!</p>
-                <a href="https://www.facebook.com/MusareMusic" target="_blank" class="waves-effect waves-light btn blue darken-3">Facebook</a>
-                <a href="https://twitter.com/musareapp" target="_blank" class="waves-effect waves-light btn light-blue accent-2">Twitter</a>
-                <a href="mailto:musaremusic@gmail.com" class="waves-effect waves-light btn grey darken-1">Contact Us</a>
+                <a href="https://www.facebook.com/MusareMusic" target="_blank" class="waves-effect waves-light btn blue darken-3 social">Facebook</a>
+                <a href="https://twitter.com/musareapp" target="_blank" class="waves-effect waves-light btn light-blue accent-2 social">Twitter</a>
+                <a href="mailto:musaremusic@gmail.com" class="waves-effect waves-light btn grey darken-1 social">Contact Us</a>
             </div>
             </div>
             <div class="col l4 offset-l2 s12">
             <div class="col l4 offset-l2 s12">
                 <h5 class="white-text">Links</h5>
                 <h5 class="white-text">Links</h5>

+ 4 - 4
app/client/templates/header.html

@@ -12,7 +12,7 @@
         </ul>
         </ul>
         <ul id="accountDrop" class="dropdown-content">
         <ul id="accountDrop" class="dropdown-content">
             {{#if currentUser}}
             {{#if currentUser}}
-                <li><a href="/u/{{currentUser.username}}">Profile</a></li>
+                <li><a href="/u/{{currentUser.profile.username}}">Profile</a></li>
                 <li><a href="/settings">Settings</a></li>
                 <li><a href="/settings">Settings</a></li>
                 <li class="divider"></li>
                 <li class="divider"></li>
                 <li class="logout"><a>Logout</a></li>
                 <li class="logout"><a>Logout</a></li>
@@ -23,7 +23,7 @@
         </ul>
         </ul>
         <nav>
         <nav>
             <div class="nav-wrapper teal accent-4">
             <div class="nav-wrapper teal accent-4">
-                <a href="/" class="brand-logo">Musare</a>
+                <a href="/" class="brand-logo light">Musare</a>
                 <a href="#" data-activates="mobile-navi" class="button-collapse"><i class="material-icons">menu</i></a>
                 <a href="#" data-activates="mobile-navi" class="button-collapse"><i class="material-icons">menu</i></a>
                 <ul class="right hide-on-med-and-down scroll-fix">
                 <ul class="right hide-on-med-and-down scroll-fix">
                     <li><a href="/news">News</a></li>
                     <li><a href="/news">News</a></li>
@@ -33,7 +33,7 @@
                             class="material-icons right">arrow_drop_down</i></a></li>
                             class="material-icons right">arrow_drop_down</i></a></li>
                     <li><a class="dropdown-button" href="#!" data-activates="accountDrop">
                     <li><a class="dropdown-button" href="#!" data-activates="accountDrop">
                         {{#if currentUser}}
                         {{#if currentUser}}
-                            {{currentUser.username}}
+                            {{currentUser.profile.username}}
                         {{else}}
                         {{else}}
                             Account
                             Account
                         {{/if}}
                         {{/if}}
@@ -66,7 +66,7 @@
                         <li>
                         <li>
                             <div class="collapsible-header black-text"><i class="material-icons">arrow_drop_down</i>
                             <div class="collapsible-header black-text"><i class="material-icons">arrow_drop_down</i>
                                 {{#if currentUser}}
                                 {{#if currentUser}}
-                                    {{currentUser.username}}
+                                    {{currentUser.profile.username}}
                                 {{else}}
                                 {{else}}
                                     Account
                                     Account
                                 {{/if}}
                                 {{/if}}

+ 2 - 5
app/client/templates/home.html

@@ -15,11 +15,8 @@
                                 </figcaption>
                                 </figcaption>
                             </div>
                             </div>
                             <div class="card-content">
                             <div class="card-content">
-                            <span class="card-title activator grey-text text-darken-4">{{display}}<i
-                                    class="material-icons right">more_vert</i></span>
-
-                                <p><span class="user-num">{{userNum}}</span> <i class="material-icons">perm_identity</i>
-                                </p>
+                            <span class="card-title activator grey-text text-darken-4">{{display}}<i class="material-icons right">more_vert</i></span>
+                            <p><span class="user-num">{{userNum}}</span> <i class="material-icons">perm_identity</i></p>
                             </div>
                             </div>
                             <div class="card-reveal">
                             <div class="card-reveal">
                                 <span class="card-title grey-text text-darken-4">{{display}}<i
                                 <span class="card-title grey-text text-darken-4">{{display}}<i

+ 1 - 0
app/client/templates/login.html

@@ -20,6 +20,7 @@
                     <i class="material-icons right">send</i>
                     <i class="material-icons right">send</i>
                 </button>
                 </button>
             </form>
             </form>
+            <button id="github-login" class="btn waves-effect waves-light grey login-btn">Login With GitHub</button>
         </div>
         </div>
     </main>
     </main>
     {{> footer}}
     {{> footer}}

+ 34 - 2
app/client/templates/mnews.html

@@ -1,9 +1,41 @@
 <template name="mnews">
 <template name="mnews">
     <div class="landing">
     <div class="landing">
-	    {{> header}}
+        {{> header}}
         <div class="row">
         <div class="row">
             <div class="about col-md-8 col-md-offset-2">
             <div class="about col-md-8 col-md-offset-2">
-              <h1>Manage News Here...</h1>
+                <h1 class="center-align">Add A New Article:</h1>
+                <div class="row">
+                    <form class="col s12">
+                        <div class="row">
+                            <div class="input-field col s6">
+                                <input id="input_text" type="text" length="10">
+                                <label for="input_text">Article Title:</label>
+                            </div>
+                        </div>
+                        <div class="row">
+                            <div class="input-field col s12">
+                                <textarea id="textarea1" class="materialize-textarea" length="120"></textarea>
+                                <label for="textarea1">Article Content:</label>
+                            </div>
+                        </div>
+                        <div class="switch">
+                          <p>Post As "Musare Admin"</p>
+                            <label>
+                                No
+                                <input type="checkbox">
+                                <span class="lever"></span>
+                                Yes
+                            </label>
+                        </div>
+                        <div class="row">
+                            <div class="input-field col s12">
+                                <a class="btn-floating btn-large waves-effect waves-light right red"><i class="material-icons">add</i></a>
+                            </div>
+                        </div>
+                    </form>
+                </div>
+                <hr />
+                <h1 class="center-align">Article List:</h1>
             </div>
             </div>
         </div>
         </div>
     </div>
     </div>

+ 1 - 1
app/client/templates/news.html

@@ -21,7 +21,7 @@
             <hr>
             <hr>
             <p class="news-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla rhoncus magna orci, tristique aliquam arcu ultricies non.
             <p class="news-content">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla rhoncus magna orci, tristique aliquam arcu ultricies non.
               <br />Vivamus iaculis leo lectus. In quis nunc rhoncus nulla hendrerit pellentesque in nec ipsum. Curabitur facilisis enim nulla, sit amet dapibus lacus aliquet ut. Integer lacinia pharetra semper.
               <br />Vivamus iaculis leo lectus. In quis nunc rhoncus nulla hendrerit pellentesque in nec ipsum. Curabitur facilisis enim nulla, sit amet dapibus lacus aliquet ut. Integer lacinia pharetra semper.
-              <br />Duis mattis varius egestas. Cras sit amet venenatis lacus. Curabitur ut maximus urna, vel pulvinar ex. WORKS!</p>
+              <br />Duis mattis varius egestas. Cras sit amet venenatis lacus. Curabitur ut maximus urna, vel pulvinar ex. Do It Work?!</p>
             <p class="news-creator">Posted by: Johand</p>
             <p class="news-creator">Posted by: Johand</p>
             <p class="news-postTime">5days ago. (5/01/2016)</p>
             <p class="news-postTime">5days ago. (5/01/2016)</p>
         </li>
         </li>

+ 3 - 3
app/client/templates/project.html

@@ -20,10 +20,10 @@
             There are essentially 3 main ways in which you can help us:
             There are essentially 3 main ways in which you can help us:
         <ol>
         <ol>
             <li>
             <li>
-                If you are a JavaScript developer, then we can use your help! Out project is open source and all the
+                If you are a JavaScript developer, then we can use your help! Our project is open source and all the
                 source code can be found on GitHub. We would love for you to create new features, add exciting
                 source code can be found on GitHub. We would love for you to create new features, add exciting
                 content or just improve what already is on Musare. Also, if you see a bug or glitch on Musare, then
                 content or just improve what already is on Musare. Also, if you see a bug or glitch on Musare, then
-                create anew
+                create a new
                 "issue" on GitHub and we will fix it as soon as possible. You can also have a try at fixing a
                 "issue" on GitHub and we will fix it as soon as possible. You can also have a try at fixing a
                 bug that you may find!
                 bug that you may find!
             </li>
             </li>
@@ -32,7 +32,7 @@
                 amount of donation is highly appreciated, and will help us maintain server costs.
                 amount of donation is highly appreciated, and will help us maintain server costs.
             </li>
             </li>
             <li>
             <li>
-                Send us feedback! You're comments and/or suggestion are extermely valuable to us. In order to improve
+                Send us feedback! You're comments and/or suggestion are extremely valuable to us. In order to improve
                 we need to know what you like, don't like or what you might want on the app.
                 we need to know what you like, don't like or what you might want on the app.
             </li>
             </li>
         </ol>
         </ol>

+ 25 - 23
app/client/templates/register.html

@@ -1,30 +1,32 @@
 <template name="register">
 <template name="register">
-        {{> header}}
-        <main>
-          <div class="container row">
+    {{> header}}
+    <main>
+        <div class="container row">
             <h1>Register</h1>
             <h1>Register</h1>
             <form class="col s12">
             <form class="col s12">
-              <div class="row">
-                <div class="input-field col s6">
-                  <input id="username" type="text" class="validate">
-                  <label for="first_name">Username</label>
+                <div class="row">
+                    <div class="input-field col s6">
+                        <input id="username" type="text" class="validate">
+                        <label for="username">Username</label>
+                    </div>
+                    <div class="input-field col s6">
+                        <input id="email" type="email" class="validate">
+                        <label for="email">Email</label>
+                    </div>
                 </div>
                 </div>
-                <div class="input-field col s6">
-                  <input id="email" type="email" class="validate">
-                  <label for="last_name">Email</label>
+                <div class="row">
+                    <div class="input-field col s12">
+                        <input id="password" type="password" class="validate">
+                        <label for="password">Password</label>
+                    </div>
                 </div>
                 </div>
-              </div>
-              <div class="row">
-                <div class="input-field col s12">
-                  <input id="password" type="password" class="validate">
-                  <label for="password">Password</label>
-                </div>
-              </div>
+                {{> reCAPTCHA}}
+                <button class="btn waves-effect waves-light register" type="submit" name="action">Submit
+                    <i class="material-icons right">send</i>
+                </button>
             </form>
             </form>
-            <button class="btn waves-effect waves-light" type="submit" name="action" style="margin-left: 10px;">Submit
-              <i class="material-icons right">send</i>
-            </button>
-          </div>
-        </main>
-        {{> footer}}
+            <button id="github-login" class="btn waves-effect waves-light grey login-btn">Login With GitHub</button>
+        </div>
+    </main>
+    {{> footer}}
 </template>
 </template>

+ 16 - 12
app/database/schemas.js

@@ -153,23 +153,27 @@ Schemas.Alert = new SimpleSchema({
 });
 });
 
 
 Schemas.Feedback = new SimpleSchema({
 Schemas.Feedback = new SimpleSchema({
-    messages: {
-        type: Array,
-        label: "Array of feedback messages"
-    },
-    "messages.$": {
-        type: Object,
-        label: "Object for each feedback"
-    },
-    "messages.$.username": {
+    username: {
         type: String,
         type: String,
         label: "Username of user who submitted feedback"
         label: "Username of user who submitted feedback"
     },
     },
-    "messages.$.message": {
+    message: {
         type: String,
         type: String,
         label: "Feedback message"
         label: "Feedback message"
+    },
+    upvotes: {
+        type: Number,
+        label: "Number of upvotes for a feedback"
+    },
+    upvotedBy: {
+        type: Array,
+        label: "Array of usernames of users who upvoted a feedback"
+    },
+    "upvotedBy.$": {
+        type: String,
+        label: "Username of user who upvoted a feedback"
     }
     }
-})
+});
 
 
 Schemas.Room = new SimpleSchema({
 Schemas.Room = new SimpleSchema({
     display: {
     display: {
@@ -267,7 +271,7 @@ Schemas.UserProfile = new SimpleSchema({
         type: String,
         type: String,
         label: "Username",
         label: "Username",
         regEx: /^[a-zA-Z0-9_]+$/,
         regEx: /^[a-zA-Z0-9_]+$/,
-        min: 6,
+        min: 4,
         max: 26
         max: 26
     },
     },
     usernameL: {
     usernameL: {

+ 32 - 1
app/server/server.js

@@ -1160,10 +1160,41 @@ Meteor.methods({
                 if (res.content.indexOf("true") > -1) {
                 if (res.content.indexOf("true") > -1) {
                     return true;
                     return true;
                 } else {
                 } else {
-                    Feedback.update({}, {$push: {messages: {username: Meteor.user().profile.username, message: message}}});
+                    Feedback.insert({
+                        "username": Meteor.user().profile.username,
+                        "message": message,
+                        upvotes: 0,
+                        upvotedBy: []
+                    })
                 }
                 }
             });
             });
         }
         }
+    },
+    upvoteFeedback: function(message){
+        if(Meteor.userId() && !isBanned()){
+            console.log(Feedback.findOne({"message": message}));
+            if(Feedback.findOne({"message": message}).upvotedBy.indexOf(Meteor.user().profile.username) === -1){
+                Feedback.update({"message": message}, {$inc: {"upvotes": 1}});
+                Feedback.update({"message": message}, {$push: {"upvotedBy": Meteor.user().profile.username}});
+            } else{
+                Feedback.update({"message": message}, {$inc: {"upvotes": -1}});
+                Feedback.update({"message": message}, {$pull: {"upvotedBy": Meteor.user().profile.username}});
+            }
+        }
+    },
+    deleteFeedback: function(message){
+        if(isAdmin() && !isBanned()){
+            Feedback.remove({"message": message});
+        } else {
+            throw new Meteor.Error(403, "Invalid permissions.");
+        }
+    },
+    updateFeedback: function(oldMessage, newMessage){
+        if(isAdmin() && !isBanned()){
+            Feedback.update({"message": oldMessage}, {$set: {"message": newMessage}});
+        } else {
+            throw new Meteor.Error(403, "Invalid permissions.");
+        }
     }
     }
 });
 });