Selaa lähdekoodia

fixed sidebar nav text color

Akira Laine 9 vuotta sitten
vanhempi
sitoutus
a5cba08410

+ 242 - 2
app/client/scripts/events.js

@@ -441,6 +441,8 @@ Template.queues.events({
         $("#dislikes").val(this.dislikes).change();
         $("#dislikes").val(this.dislikes).change();
         $("#duration").val(this.duration).change();
         $("#duration").val(this.duration).change();
         $("#skip-duration").val(this.skipDuration).change();
         $("#skip-duration").val(this.skipDuration).change();
+        $("#genres").val(this.genres).change();
+        $("#genres").material_select();
         $("#previewPlayerContainer").addClass("hide-preview");
         $("#previewPlayerContainer").addClass("hide-preview");
         Session.set("image_url", this.img);
         Session.set("image_url", this.img);
         Session.set("editing", true);
         Session.set("editing", true);
@@ -636,7 +638,7 @@ Template.queues.events({
         newSong.duration = Number($("#duration").val());
         newSong.duration = Number($("#duration").val());
         newSong.skipDuration = $("#skip-duration").val();
         newSong.skipDuration = $("#skip-duration").val();
         newSong.requestedBy = Session.get("song").requestedBy;
         newSong.requestedBy = Session.get("song").requestedBy;
-        newSong.genres = Session.get("song").genres;
+        newSong.genres = $("#genres").val();
         if(newSong.skipDuration === undefined){
         if(newSong.skipDuration === undefined){
             newSong.skipDuration = 0;
             newSong.skipDuration = 0;
         }
         }
@@ -866,7 +868,245 @@ Template.manageStation.events({
         newSong.duration = Number($("#duration").val());
         newSong.duration = Number($("#duration").val());
         newSong.skipDuration = $("#skip-duration").val();
         newSong.skipDuration = $("#skip-duration").val();
         newSong.requestedBy = Session.get("song").requestedBy;
         newSong.requestedBy = Session.get("song").requestedBy;
-        newSong.genres = Session.get("song").genres;
+        newSong.genres = $("#genres").val();
+        Meteor.call("updatePlaylistSong", newSong.mid, newSong, function(err, res) {
+            console.log(err, res);
+            if (err) {
+                var $toastContent = $('<span><strong>Song not saved.</strong> ' + err.reason + '</span>');
+                Materialize.toast($toastContent, 8000);
+            } else {
+                var $toastContent = $('<span><strong>Song saved!</strong> No errors were found.</span>');
+                Materialize.toast($toastContent, 4000);
+                Session.set("song", newSong);
+            }
+        });
+    }
+});
+
+Template.manageSongs.events({
+    /* TODO Add undo delete button */
+    "change #show_genres_cb": function() {
+        var selected = $("#show_genres_cb").is(":checked");
+        Session.set("showGenres", selected);
+    },
+    "change #show_no_genres_cb": function() {
+        var selected = $("#show_no_genres_cb").is(":checked");
+        Session.set("showNoGenres", selected);
+    },
+    "input #id": function() {
+        $("#previewPlayerContainer").addClass("hide-preview");
+    },
+    "input #img": function() {
+        var url = $("#img").val();
+        Session.set("image_url", url);
+    },
+    "click .preview-button": function(e){
+        Session.set("song", this);
+        $("#previewModal").openModal();
+    },
+    "click #previewImageButton": function() {
+        $("#preview-image").attr("src", Session.get("song").img);
+    },
+    "click .edit-song-button": function(e){
+        Session.set("song", this);
+        Session.set("genre", $(e.target).data("genre"));
+        $("#mid").val(this.mid).change();
+        $("#artist").val(this.artist).change();
+        $("#title").val(this.title).change();
+        $("#img").val(this.img).change();
+        $("#id").val(this.id).change();
+        $("#likes").val(this.likes).change();
+        $("#dislikes").val(this.dislikes).change();
+        $("#duration").val(this.duration).change();
+        $("#skip-duration").val(this.skipDuration).change();
+        $("#genres").val(this.genres).change();
+        $("#genres").material_select();
+        $("#previewPlayerContainer").addClass("hide-preview");
+        Session.set("image_url", this.img);
+        Session.set("editing", true);
+        $("#editModal").openModal({
+            complete : function() {
+                Session.set("editing", false);
+                if (YTPlayer !== undefined && YTPlayer.stopVideo !== undefined) {
+                    YTPlayer.stopVideo();
+                }
+            }
+        });
+    },
+    "click .remove-song-button": function(e){
+        var genre = $(e.target).data("genre") || $(e.target).parent().data("genre");
+        Meteor.call("removeSongFromPlaylist", genre, this.mid);
+    },
+    "click #play": function() {
+        var duration = Session.get("song").duration;
+        var d = moment.duration(parseInt(duration), 'seconds');
+        $("#time-total").text(d.minutes() + ":" + ("0" + d.seconds()).slice(-2));
+        $("#previewPlayerContainer").removeClass("hide-preview");
+        var song = Session.get("song");
+        var id = song.id;
+        var volume = localStorage.getItem("volume") || 20;
+        if (song.duration !== 0) {
+            $("#play").attr("disabled", true);
+            $("#stop").attr("disabled", false);
+            $("#pause").attr("disabled", false);
+            $("#forward").attr("disabled", false);
+            if (YTPlayer === undefined) {
+                YTPlayer = new YT.Player("previewPlayer", {
+                    height: 540,
+                    width: 568,
+                    videoId: id,
+                    playerVars: {autoplay: 1, controls: 0, iv_load_policy: 3, showinfo: 0, fs: 0},
+                    events: {
+                        'onReady': function(event) {
+                            event.target.seekTo(Number(song.skipDuration));
+                            event.target.playVideo();
+                            event.target.setVolume(volume);
+                        },
+                        'onStateChange': function(event){
+                            if (event.data == YT.PlayerState.PAUSED) {
+                                if (seekerBarInterval !== undefined) {
+                                    Meteor.clearInterval(seekerBarInterval);
+                                    seekerBarInterval = undefined;
+                                }
+                            }
+                            if (event.data == YT.PlayerState.UNSTARTED) {
+                                if (seekerBarInterval !== undefined) {
+                                    Meteor.clearInterval(seekerBarInterval);
+                                    seekerBarInterval = undefined;
+                                }
+                                $(".seeker-bar").css({width: "0"});
+                                $("#time-elapsed").text("0:00");
+                                $("#previewPlayerContainer").addClass("hide-preview");
+                            }
+                            if (event.data == YT.PlayerState.PLAYING) {
+                                seekerBarInterval = Meteor.setInterval(function() {
+                                    var duration = Session.get("song").duration;
+                                    var timeElapsed = YTPlayer.getCurrentTime();
+                                    var skipDuration = Session.get("song").skipDuration;
+
+                                    if (duration <= (timeElapsed - skipDuration)) {
+                                        YTPlayer.stopVideo();
+                                        $("#play").attr("disabled", false);
+                                        $("#stop").attr("disabled", true);
+                                        $("#pause").attr("disabled", true);
+                                        $("#forward").attr("disabled", true);
+                                        $("#previewPlayerContainer").addClass("hide-preview");
+                                        $(".seeker-bar").css({width: "0"});
+                                        $("#time-elapsed").text("0:00");
+                                        Meteor.clearInterval(seekerBarInterval);
+                                    } else {
+                                        var percentComplete = (timeElapsed - skipDuration) / duration * 100;
+                                        $(".seeker-bar").css({width: percentComplete + "%"});
+                                        var d = moment.duration(timeElapsed - skipDuration, 'seconds');
+                                        $("#time-elapsed").text(d.minutes() + ":" + ("0" + d.seconds()).slice(-2));
+                                    }
+                                }, 100);
+                                $("#play").attr("disabled", true);
+                                $("#stop").attr("disabled", false);
+                                $("#pause").attr("disabled", false);
+                                $("#forward").attr("disabled", false);
+                            } else {
+                                $("#play").attr("disabled", false);
+                                $("#stop").attr("disabled", true);
+                                $("#pause").attr("disabled", true);
+                                $("#forward").attr("disabled", true);
+                            }
+                        }
+                    }
+                });
+            } else {
+                if (YTPlayer.getPlayerState() === 2) {
+                    YTPlayer.playVideo();
+                } else {
+                    console.log(id, song.skipDuration, song.duration);
+                    YTPlayer.loadVideoById(id);
+                    YTPlayer.seekTo(Number(song.skipDuration));
+                }
+            }
+            $("#previewPlayerContainer").removeClass("hide-preview");
+        }
+    },
+    "click #stop": function() {
+        $("#play").attr("disabled", false);
+        $("#stop").attr("disabled", true);
+        $("#pause").attr("disabled", true);
+        $("#forward").attr("disabled", true);
+        if (previewEndSongTimeout !== undefined) {
+            Meteor.clearTimeout(previewEndSongTimeout);
+        }
+        if (YTPlayer !== undefined && YTPlayer.stopVideo !== undefined) {
+            YTPlayer.stopVideo();
+        }
+    },
+    "click #pause": function() {
+        $("#play").attr("disabled", false);
+        $("#stop").attr("disabled", false);
+        $("#pause").attr("disabled", true);
+        $("#forward").attr("disabled", true);
+        if (previewEndSongTimeout !== undefined) {
+            Meteor.clearTimeout(previewEndSongTimeout);
+        }
+        if (YTPlayer !== undefined && YTPlayer.pauseVideo !== undefined) {
+            YTPlayer.pauseVideo();
+        }
+    },
+    "click #forward": function() {
+        var error = false;
+        if (YTPlayer !== undefined) {
+            var duration = Number(Session.get("song").duration) | 0;
+            var skipDuration = Number(Session.get("song").skipDuration) | 0;
+            if (YTPlayer.getDuration() < duration + skipDuration) {
+                var $toastContent = $('<span><strong>Error.</strong> The song duration is longer than the length of the video.</span>');
+                Materialize.toast($toastContent, 8000);
+                error = true;
+            } else {
+                YTPlayer.seekTo(skipDuration + duration - 10);
+            }
+        }
+        if (!error) {
+            if (previewEndSongTimeout !== undefined) {
+                Meteor.clearTimeout(previewEndSongTimeout);
+            }
+            previewEndSongTimeout = Meteor.setTimeout(function() {
+                if (YTPlayer !== undefined) {
+                    YTPlayer.stopVideo();
+                }
+                $("#play").attr("disabled", false);
+                $("#stop").attr("disabled", true);
+                $("#pause").attr("disabled", true);
+                $("#forward").attr("disabled", true);
+                $("#previewPlayerContainer").addClass("hide-preview");
+            }, 10000);
+        }
+    },
+    "click #get-spotify-info": function() {
+        var search = $("#title").val();
+        var artistName = $("#artist").val();
+        getSpotifyInfo(search, function(data) {
+            for(var i in data){
+                for(var j in data[i].items){
+                    if(search.indexOf(data[i].items[j].name) !== -1 && artistName.indexOf(data[i].items[j].artists[0].name) !== -1){
+                        $("#img").val(data[i].items[j].album.images[2].url).change();
+                        $("#duration").val(data[i].items[j].duration_ms / 1000).change();
+                        return;
+                    }
+                }
+            }
+        }, artistName);
+    },
+    "click #save-song-button": function() {
+        var newSong = {};
+        newSong.mid = $("#mid").val();
+        newSong.id = $("#id").val();
+        newSong.likes = Number($("#likes").val());
+        newSong.dislikes = Number($("#dislikes").val());
+        newSong.title = $("#title").val();
+        newSong.artist = $("#artist").val();
+        newSong.img = $("#img").val();
+        newSong.duration = Number($("#duration").val());
+        newSong.skipDuration = $("#skip-duration").val();
+        newSong.requestedBy = Session.get("song").requestedBy;
+        newSong.genres = $("#genres").val() || [];
         Meteor.call("updatePlaylistSong", newSong.mid, newSong, function(err, res) {
         Meteor.call("updatePlaylistSong", newSong.mid, newSong, function(err, res) {
             console.log(err, res);
             console.log(err, res);
             if (err) {
             if (err) {

+ 17 - 2
app/client/scripts/helpers.js

@@ -210,6 +210,23 @@ Template.news.helpers({
     }
     }
 });
 });
 
 
+Template.manageSongs.helpers({
+    songs: function () {
+        var noGenres = Session.get("showNoGenres");
+        var genres = Session.get("showGenres");
+        if (noGenres === true && genres === true) {
+            return Songs.find();
+        } else if (noGenres === true && genres === false) {
+            return Songs.find({genres: []});
+        } else {
+            return Songs.find({$where : "this.genres.length > 0"});
+        }
+    },
+    song_image: function() {
+        return Session.get("image_url");
+    }
+});
+
 Template.manageStation.helpers({
 Template.manageStation.helpers({
     songs: function () {
     songs: function () {
         var parts = location.href.split('/');
         var parts = location.href.split('/');
@@ -221,8 +238,6 @@ Template.manageStation.helpers({
         var songs = [];
         var songs = [];
         if (playlist !== undefined && playlist.songs !== undefined) {
         if (playlist !== undefined && playlist.songs !== undefined) {
             playlist.songs.forEach(function(songMid) {
             playlist.songs.forEach(function(songMid) {
-                console.log(songMid);
-                console.log(Songs.findOne({mid: songMid}));
                 songs.push(Songs.findOne({mid: songMid}));
                 songs.push(Songs.findOne({mid: songMid}));
             });
             });
         }
         }

+ 21 - 0
app/client/scripts/onCreated.js

@@ -33,6 +33,9 @@ Template.home.onCreated(function() {
     if (Session.get("minterval") !== undefined) {
     if (Session.get("minterval") !== undefined) {
         Meteor.clearInterval(Session.get("minterval"));
         Meteor.clearInterval(Session.get("minterval"));
     }
     }
+    if (Session.get("titleScroller") !== undefined) {
+        Meteor.clearInterval(Session.get("titleScroller"));
+    }
     if (resizeSeekerbarInterval !== undefined) {
     if (resizeSeekerbarInterval !== undefined) {
         Meteor.clearInterval(resizeSeekerbarInterval);
         Meteor.clearInterval(resizeSeekerbarInterval);
         resizeSeekerbarInterval = undefined;
         resizeSeekerbarInterval = undefined;
@@ -114,6 +117,24 @@ Template.manageStation.onCreated(function() {
     });
     });
 });
 });
 
 
+Template.manageSongs.onCreated(function() {
+    Session.set("showNoGenres", false);
+    Session.set("showGenres", true);
+    var tag = document.createElement("script");
+    tag.src = "https://www.youtube.com/iframe_api";
+    var firstScriptTag = document.getElementsByTagName('script')[0];
+    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
+    YTPlayer = undefined;
+    $(document).keydown(function(evt){
+        if (evt.keyCode==83 && (evt.ctrlKey)){
+            evt.preventDefault();
+            if (Session.get("editing") === true) {
+                $("#save-song-button").click();
+            }
+        }
+    });
+});
+
 Template.register.onCreated(function() {
 Template.register.onCreated(function() {
     Accounts.onLoginFailure(function() {
     Accounts.onLoginFailure(function() {
         var errAlert = $('<div style="margin-bottom: 0" class="alert alert-danger" role="alert"><strong>Oh Snap!</strong> Something went wrong when trying to register with GitHub. Maybe an account with that username already exists?</div>');
         var errAlert = $('<div style="margin-bottom: 0" class="alert alert-danger" role="alert"><strong>Oh Snap!</strong> Something went wrong when trying to register with GitHub. Maybe an account with that username already exists?</div>');

+ 25 - 2
app/client/scripts/onRendered.js

@@ -50,6 +50,31 @@ Template.manageStation.onRendered(function() {
     });
     });
 });
 });
 
 
+Template.manageSongs.onRendered(function() {
+    $("#previewModal").on("hidden.bs.modal", function() {
+        if (previewEndSongTimeout !== undefined) {
+            Meteor.clearTimeout(previewEndSongTimeout);
+        }
+        $("#play").attr("disabled", false);
+        $("#stop").attr("disabled", true);
+        if (YTPlayer !== undefined) {
+            $("#previewPlayer").hide();
+            YTPlayer.seekTo(0);
+            YTPlayer.stopVideo();
+        }
+    });
+    $(document).ready(function() {
+        var volume = localStorage.getItem("volume") || 20;
+        $("#volume_slider").val(volume).on("input", function() {
+            volume = Number($("#volume_slider").val());
+            localStorage.setItem("volume", volume);
+            if (YTPlayer !== undefined) {
+                YTPlayer.setVolume(volume);
+            }
+        });
+    });
+});
+
 Template.news.onRendered(function() {
 Template.news.onRendered(function() {
     if (rTimeInterval !== undefined) {
     if (rTimeInterval !== undefined) {
         Meteor.clearInterval(rTimeInterval)
         Meteor.clearInterval(rTimeInterval)
@@ -67,9 +92,7 @@ Template.room.onRendered(function() {
         Session.set("time", new Date().getTime());
         Session.set("time", new Date().getTime());
     }, 10000);
     }, 10000);
     window.setTimeout(function(){
     window.setTimeout(function(){
-        console.log("THIS IS ME!")
         var volume = Number(localStorage.getItem("volume")) || 20;
         var volume = Number(localStorage.getItem("volume")) || 20;
         $("#volume_slider").val(volume);
         $("#volume_slider").val(volume);
-        console.log($("#volume_slider").val());
     }, 1000)
     }, 1000)
 });
 });

+ 14 - 0
app/client/scripts/routes.js

@@ -109,6 +109,20 @@ Router.route("/admin", {
     }
     }
 });
 });
 
 
+Router.route("/admin/songs", {
+    waitOn: function() {
+        return [Meteor.subscribe("isModerator", Meteor.userId()), Meteor.subscribe("isAdmin", Meteor.userId())];
+    },
+    action: function() {
+        var user = Meteor.users.findOne({});
+        if (user !== undefined && user.profile !== undefined && (user.profile.rank === "admin" || user.profile.rank === "moderator")) {
+            this.render("manageSongs");
+        } else {
+            this.redirect("/");
+        }
+    }
+});
+
 Router.route("/admin/queues", {
 Router.route("/admin/queues", {
     waitOn: function() {
     waitOn: function() {
         return [Meteor.subscribe("isModerator", Meteor.userId()), Meteor.subscribe("isAdmin", Meteor.userId())];
         return [Meteor.subscribe("isModerator", Meteor.userId()), Meteor.subscribe("isAdmin", Meteor.userId())];

+ 2 - 1
app/client/stylesheets/cardcaption.css

@@ -11,6 +11,7 @@ figcaption {
     filter: alpha(opacity=0);
     filter: alpha(opacity=0);
     opacity: 0;
     opacity: 0;
     position: absolute;
     position: absolute;
+    top: 50%;
     height: 100%;
     height: 100%;
     width: 100%;
     width: 100%;
     background: rgba(0,0,0,.6);
     background: rgba(0,0,0,.6);
@@ -35,4 +36,4 @@ figcaption a{
     width: 100%;
     width: 100%;
     position: absolute !important;
     position: absolute !important;
     bottom: 0;
     bottom: 0;
-}
+}

+ 37 - 35
app/client/templates/faq.html

@@ -1,40 +1,42 @@
 <template name="faq">
 <template name="faq">
     {{> header}}
     {{> header}}
-    <div class="text-center">
-        <h3>FAQ
-            <small class="thin">Frequently Asked Questions</small>
-        </h3>
-        <hr/>
-        <h4>How can I add a song?</h4>
-        <p class="flow-text">You can add a song if you are logged in, by clicking on the Add Song button under the
-            video in
-            the station you want to add your song in. That will open up a modal where you can search search for a song by putting a search query there or by putting a link in there and clicking the Search Song button. You can then
-            edit
-            some more information, like the artist and title. It's helpful for us if you fill those in so we don't
-            have to
-            research every song, but you are not required to. You can also import playlists from YouTube.</p>
-        <h4>Can I skip a song?</h4>
-        <p class="flow-text">Yes, and no. You can vote on skipping a song. You can click the blue skip button. When
-            the
-            counter hits 3, the song will be skipped. Admins and mods can skip songs without needing to vote, but
-            please do
-            not ask us to skip songs.</p>
-        <h4>I added a song but I can't find it in the Playlist, where is it?</h4>
-        <p class="flow-text">When you request a song to be added to a playlist, an admin or moderator first needs to
-            review,
-            edit and then either accept or deny that song.</p>
-        <h4>How do I use emoji's in chat?</h4>
-        <p class="flow-text">In chat, you can see emoji's by typing the ':' in chat and then a keyword or some
-            letters of an
-            emoji. That opens a dropdown box from where you can choose emoji's to put in chat. You can also just
-            type it
-            manually. You can find the full list of emoji's at <a href="http://emoji.codes/"
-                                                                  target="_blank">www.emoji.codes</a></p>
-        <h4>Is there an API?</h4>
-        <p class="flow-text">No, sorry. But we will add one soon&trade;!</p>
-        <h4>Are there chat commands?</h4>
-        <p class="flow-text">Yes! Just type /commands or /help in chat and it will show you all of the available
-            chat commands.</p>
+    <div class="text-center row">
+        <div class="col l6 m6 s12 offset-l3 offset-m3">
+            <h3>FAQ
+                <small class="thin">Frequently Asked Questions</small>
+            </h3>
+            <hr/>
+            <h4>How can I add a song?</h4>
+            <p class="flow-text">You can add a song if you are logged in, by clicking on the Add Song button under the
+                video in
+                the station you want to add your song in. That will open up a modal where you can search search for a song by putting a search query there or by putting a link in there and clicking the Search Song button. You can then
+                edit
+                some more information, like the artist and title. It's helpful for us if you fill those in so we don't
+                have to
+                research every song, but you are not required to. You can also import playlists from YouTube.</p>
+            <h4>Can I skip a song?</h4>
+            <p class="flow-text">Yes, and no. You can vote on skipping a song. You can click the blue skip button. When
+                the
+                counter hits 3, the song will be skipped. Admins and mods can skip songs without needing to vote, but
+                please do
+                not ask us to skip songs.</p>
+            <h4>I added a song but I can't find it in the Playlist, where is it?</h4>
+            <p class="flow-text">When you request a song to be added to a playlist, an admin or moderator first needs to
+                review,
+                edit and then either accept or deny that song.</p>
+            <h4>How do I use emoji's in chat?</h4>
+            <p class="flow-text">In chat, you can see emoji's by typing the ':' in chat and then a keyword or some
+                letters of an
+                emoji. That opens a dropdown box from where you can choose emoji's to put in chat. You can also just
+                type it
+                manually. You can find the full list of emoji's at <a href="http://emoji.codes/"
+                                                                      target="_blank">www.emoji.codes</a>.</p>
+            <h4>Is there an API?</h4>
+            <p class="flow-text">No, sorry. But we will add one soon&trade;!</p>
+            <h4>Are there chat commands?</h4>
+            <p class="flow-text">Yes! Just type /commands or /help in chat and it will show you all of the available
+                chat commands.</p>
+        </div>
     </div>
     </div>
     {{> footer}}
     {{> footer}}
 </template>
 </template>

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

@@ -1,24 +1,24 @@
 <template name="footer">
 <template name="footer">
-    <footer class="page-footer teal accent-4">
+    <footer class="page-footer grey lighten-2">
         <div class="container row">
         <div class="container row">
             <div class="col l6 s12">
             <div class="col l6 s12">
-                <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>
-                <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>
+                <h5 class="grey-text text-darken-2">Stay Connected</h5>
+                <p class="grey-text text-darken-1">Follow us on social media or send us an email!</p>
+                <a href="https://www.facebook.com/MusareMusic" target="_blank"><img src="\FB-f-Logo__blue_57.png" height="24dp" width="24dp" /></a>
+                <a href="https://twitter.com/musareapp" target="_blank"><img src="\TwitterLogo_#55acee.png" height="24dp" width="24dp" /></a>
+                <a href="mailto:musaremusic@gmail.com"><i class="material-icons">email</i></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="grey-text text-darken-2">Links</h5>
                 <ul>
                 <ul>
-                    <li><a class="grey-text text-lighten-3" href="/faq">FAQ</a></li>
-                    <li><a class="grey-text text-lighten-3" href="/terms">Terms</a></li>
-                    <li><a class="grey-text text-lighten-3" href="/privacy">Privacy</a></li>
+                    <li><a class="grey-text text-darken-1" href="/faq">FAQ</a></li>
+                    <li><a class="grey-text text-darken-1" href="/terms">Terms</a></li>
+                    <li><a class="grey-text text-darken-1" href="/privacy">Privacy</a></li>
                 </ul>
                 </ul>
             </div>
             </div>
         </div>
         </div>
         <div class="footer-copyright">
         <div class="footer-copyright">
-            <div class="container">
+            <div class="container grey-text text-darken-1">
                Copyright &copy; 2016 Musare
                Copyright &copy; 2016 Musare
             </div>
             </div>
         </div>
         </div>

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

@@ -2,45 +2,45 @@
     <header>
     <header>
         <!-- Dropdown Structure -->
         <!-- Dropdown Structure -->
         <ul id="contributeDrop" class="dropdown-content">
         <ul id="contributeDrop" class="dropdown-content">
-            <li><a href="https://www.github.com/Musare/Musare" target="_blank">Github</a></li>
-            <li><a href="donate.html">Donate</a></li>
-            <li><a href="/feedback">Feedback</a></li>
+            <li><a href="https://www.github.com/Musare/Musare" target="_blank" class="grey-text text-darken-4">Github</a></li>
+            <li><a href="donate.html" class="grey-text text-darken-4">Donate</a></li>
+            <li><a href="/feedback" class="grey-text text-darken-4">Feedback</a></li>
         </ul>
         </ul>
         <ul id="aboutDrop" class="dropdown-content">
         <ul id="aboutDrop" class="dropdown-content">
-            <li><a href="/project">The Project</a></li>
-            <li><a href="/team">The Team</a></li>
+            <li><a href="/project" class="grey-text text-darken-4">The Project</a></li>
+            <li><a href="/team" class="grey-text text-darken-4">The Team</a></li>
         </ul>
         </ul>
         <ul id="accountDrop" class="dropdown-content">
         <ul id="accountDrop" class="dropdown-content">
             {{#if currentUser}}
             {{#if currentUser}}
-                <li><a href="/u/{{currentUser.profile.username}}">Profile</a></li>
-                <li><a href="/settings">Settings</a></li>
+                <li><a href="/u/{{currentUser.profile.username}}" class="grey-text text-darken-4">Profile</a></li>
+                <li><a href="/settings" class="grey-text text-darken-4">Settings</a></li>
                 <li class="divider"></li>
                 <li class="divider"></li>
-                <li class="logout"><a>Logout</a></li>
+                <li class="logout"><a class="grey-text text-darken-4">Logout</a></li>
             {{else}}
             {{else}}
-                <li><a href="/login">Login</a></li>
-                <li><a href="/register">Register</a></li>
+                <li><a href="/login" class="grey-text text-darken-4">Login</a></li>
+                <li><a href="/register" class="grey-text text-darken-4">Register</a></li>
             {{/if}}
             {{/if}}
         </ul>
         </ul>
         <nav>
         <nav>
-            <div class="nav-wrapper teal accent-4">
-                <a href="/" class="brand-logo light">Musare</a>
-                <a href="#" data-activates="mobile-navi" class="button-collapse"><i class="material-icons">menu</i></a>
+            <div class="nav-wrapper grey darken-4">
+                <a href="/" class="brand-logo light white-text">Musare</a>
+                <a href="#" data-activates="mobile-navi" class="button-collapse white-text"><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">
                   {{#if isModerator}}
                   {{#if isModerator}}
-                    <li><a  class="orange-text" href="/admin"><b>Admin</b></a></li>
+                    <li><a  class="teal-text text-accent-4" href="/admin"><b>Admin</b></a></li>
                   {{/if}}
                   {{/if}}
-                    <li><a href="/news">News</a></li>
-                    <li><a class="dropdown-button" href="#!" data-activates="contributeDrop">Contribute<i
+                    <li><a href="/news" class="white-text">News</a></li>
+                    <li><a class="dropdown-button white-text" href="#!" data-activates="contributeDrop">Contribute<i
                             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="aboutDrop">About<i
+                    <li><a class="dropdown-button white-text" href="#!" data-activates="aboutDrop">About<i
                             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 white-text" href="#!" data-activates="accountDrop">
                         {{#if currentUser}}
                         {{#if currentUser}}
                             {{currentUser.profile.username}}
                             {{currentUser.profile.username}}
                         {{else}}
                         {{else}}
                             Account
                             Account
                         {{/if}}
                         {{/if}}
-                        <i class="material-icons right">arrow_drop_down</i></a></li>
+                        <i class="material-icons right white-text">arrow_drop_down</i></a></li>
                 </ul>
                 </ul>
                 <ul class="side-nav" id="mobile-navi" style="width: 240px;">
                 <ul class="side-nav" id="mobile-navi" style="width: 240px;">
                     <ul class="collapsible" data-collapsible="accordion">
                     <ul class="collapsible" data-collapsible="accordion">

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

@@ -5,14 +5,13 @@
             <div class="row">
             <div class="row">
                 {{#each rooms}}
                 {{#each rooms}}
                     <div class="col s12 m5 l2">
                     <div class="col s12 m5 l2">
-                        <div class="card">
+                        <div class="card hoverable">
                             <div class="card-image waves-effect waves-block waves-light">
                             <div class="card-image waves-effect waves-block waves-light">
                                 <a href=/{{type}}>
                                 <a href=/{{type}}>
                                     <img onerror="this.src='http://static.boredpanda.com/blog/wp-content/uploads/2014/04/amazing-fox-photos-182.jpg'" src={{currentSong.song.img}}>
                                     <img onerror="this.src='http://static.boredpanda.com/blog/wp-content/uploads/2014/04/amazing-fox-photos-182.jpg'" src={{currentSong.song.img}}>
-                                    <figcaption>
-                                        <h5>{{currentSong.song.title}}</h5>
-                                        <h5>{{currentSong.song.artist}}</h5>
-                                        <a href=/{{type}} class="waves-effect waves-light btn">Join Room</a>
+                                    <figcaption class="caption center-align">
+                                      <h5>{{currentSong.song.title}}</h5>
+                                      <h5>{{currentSong.song.artist}}</h5>
                                     </figcaption>
                                     </figcaption>
                                 </a>
                                 </a>
                             </div>
                             </div>
@@ -21,7 +20,7 @@
                                 <p>{{roomDesc}}</p>
                                 <p>{{roomDesc}}</p>
                             </div>
                             </div>
                             <div class="card-action">
                             <div class="card-action">
-                                <a href=/{{type}}>Join Room</a>
+                                <a href=/{{type}} class="teal-text text-accent-4">Join Room</a>
                             </div>
                             </div>
                         </div>
                         </div>
                     </div>
                     </div>

+ 180 - 0
app/client/templates/manageSongs.html

@@ -0,0 +1,180 @@
+<template name="manageSongs">
+    {{> alerts}}
+    <div class="landing">
+        {{> header}}
+        <div class="row">
+            <div class="col m8 s8 l8 offset-l2 offset-m1 offset-s2 admin-playlist-panel card-panel teal accent-3">
+                <div class="card-content white-text">
+                    <h3 class="text-center">Filters</h3>
+                    <p>
+                        <input checked="checked" type="checkbox" id="show_genres_cb" />
+                        <label for="show_genres_cb" class="white-text">Show songs with genres</label>
+                    </p>
+                    <p>
+                        <input type="checkbox" id="show_no_genres_cb" />
+                        <label for="show_no_genres_cb" class="white-text">Show songs without a genre</label>
+                    </p>
+                </div>
+            </div>
+            <div class="col m8 s8 l8 offset-l2 offset-m1 offset-s2 admin-playlist-panel card-panel teal accent-3">
+                <div class="card-content white-text">
+                    <h3 class="text-center">Songs</h3>
+                    <table class="bordered">
+                        <thead>
+                        <tr>
+                            <th>Title</th>
+                            <th>Artist(s)</th>
+                            <th>Id</th>
+                            <th>Mid</th>
+                            <th>Genres</th>
+                            <th>Likes</th>
+                            <th>Dislikes</th>
+                            <th class="table-right-th">Edit</th>
+                            <th class="table-right-th">Remove</th>
+                        </tr>
+                        </thead>
+                        <tbody>
+                        {{#each songs}}
+                            <tr>
+                                <th align="left" scope="row">{{title}}</th>
+                                <td align="left">{{artist}}</td>
+                                <td align="left">{{id}}</td>
+                                <td align="left">{{mid}}</td>
+                                <td align="left">{{genres}}</td>
+                                <td align="left">{{likes}}</td>
+                                <td align="left">{{dislikes}}</td>
+                                <td class="table-right-td">
+                                    <button class="btn edit-song-button"
+                                            data-toggle="modal" data-target="#editModal">Edit
+                                    </button>
+                                </td>
+                                <td class="table-right-td">
+                                    <button class="btn red remove-song-button"><i
+                                            class="material-icons">remove_circle</i></button>
+                                </td>
+                            </tr>
+                        {{/each}}
+                        </tbody>
+                    </table>
+                </div>
+            </div>
+        </div>
+    </div>
+    <div id="editModal" class="modal modal-fixed-footer">
+        <div class="modal-content musare white-text">
+            <div class="row">
+                <h4 class="center-align">Video Preview</h4>
+                <div class="video-container" id="previewPlayerContainer">
+                    <div width="960" height="540" id="previewPlayer"></div>
+                </div>
+                <div class="seeker-bar-container col l10 m10 s10 white" id="preview-progress">
+                    <div class="seeker-bar teal" style="width: 0%"></div>
+                </div>
+            <span class="col l2 m2 s2 center" id="preview-time">
+                <span id="time-elapsed">0:00</span> / <span id="time-total">0:00</span>
+            </span>
+                <button id="play" title="Play video" class="btn green col m1 s1 l1 offset-l3 offset-m3 offset-s3">
+                    <i class="material-icons">play_arrow</i>
+                </button>
+                <button id="stop" title="Stop video" class="btn red col m1 s1 l1" disabled>
+                    <i class="material-icons">stop</i>
+                </button>
+                <button id="pause" title="Pause video" class="btn orange col m1 s1 l1" disabled>
+                    <i class="material-icons">pause</i>
+                </button>
+                <button id="forward" title="Go to the last 10 seconds of the video" class="btn blue col m1 s1 l1"
+                        disabled>
+                    <i class="material-icons">fast_forward</i>
+                </button>
+                <form class="col m2 s2 l2" action="#">
+                    <p class="range-field" style="margin-top: 0">
+                        <input type="range" id="volume_slider" min="0" max="100"/>
+                    </p>
+                </form>
+            </div>
+            <div class="row">
+                <h4 class="center-align">Image Preview</h4>
+                <img id="song-preview"
+                     onerror="this.src='http://static.boredpanda.com/blog/wp-content/uploads/2014/04/amazing-fox-photos-182.jpg'"
+                     class="center-block" src="{{song_image}}"/>
+            </div>
+            <div class="row">
+                <h4 class="center-align">Edit Info</h4>
+                <div class="input-field col l8 m8 s12 offset-l2 offset-m2">
+                    <select multiple id="genres">
+                        <option value="" disabled selected>Select Genre(s):</option>
+                        <option value="edm">EDM</option>
+                        <option value="chill">Chill</option>
+                    </select>
+                    <label class="white-text">Genre(s)</label>
+                </div>
+                <div class="input-field col l8 m8 s12 offset-l2 offset-m2">
+                    <i class="material-icons prefix">vpn_key</i>
+                    <label for="mid" class="white-text">Song MID</label>
+                    <input class="validate" name="mid" id="mid" type="text" pattern=".{6}"/>
+                </div>
+                <div class="input-field col l8 m8 s12 offset-l2 offset-m2">
+                    <i class="material-icons prefix">vpn_key</i>
+                    <label for="mid" class="white-text">Song ID</label>
+                    <input class="validate" name="id" id="id" type="text" pattern=".{11}"/>
+                </div>
+                <div class="input-field col l8 m8 s12 offset-l2 offset-m2">
+                    <i class="material-icons prefix">vpn_key</i>
+                    <label for="mid" class="white-text">Song Genres</label>
+                    <input class="validate" name="genres" id="genres" type="text" disabled/>
+                </div>
+                <div class="input-field col l8 m8 s12 offset-l2 offset-m2">
+                    <i class="material-icons prefix">person</i>
+                    <label for="id" class="white-text">Song Artist</label>
+                    <input class="validate" name="artist" id="artist" aria-required="true" type="text"/>
+                </div>
+                <div class="input-field col l8 m8 s12 offset-l2 offset-m2">
+                    <i class="material-icons prefix">subject</i>
+                    <label for="title" class="white-text">Song Title</label>
+                    <input class="validate required" name="title" id="title" type="text"/>
+                </div>
+                <div class="input-field col l8 m8 s12 offset-l2 offset-m2">
+                    <i class="material-icons prefix">timelapse</i>
+                    <label for="title" class="white-text">Song Duration</label>
+                    <input class="validate" name="duration" id="duration" type="number" step="any" min="0"/>
+                </div>
+                <div class="input-field col l8 m8 s12 offset-l2 offset-m2">
+                    <i class="material-icons prefix">timer_off</i>
+                    <label for="skip-duration" class="white-text">Skip Duration</label>
+                    <input class="validate" id="skip-duration" type="number" step="any" min="0"/>
+                </div>
+                <div class="input-field col l8 m8 s12 offset-l2 offset-m2">
+                    <i class="material-icons prefix">thumb_up</i>
+                    <label for="likes" class="white-text">Likes</label>
+                    <input disabled id="likes" type="number"/>
+                </div>
+                <div class="input-field col l8 m8 s12 offset-l2 offset-m2">
+                    <i class="material-icons prefix">thumb_down</i>
+                    <label for="dislikes" class="white-text">Dislikes</label>
+                    <input disabled id="dislikes" type="number"/>
+                </div>
+                <div class="input-field col l8 m8 s12 offset-l2 offset-m2">
+                    <i class="material-icons prefix">image</i>
+                    <label for="img" class="white-text">Song Image</label>
+                    <input class="validate" name="img" id="img" type="url"/>
+                </div>
+            </div>
+            <div class="row">
+                <button type="button" id="get-spotify-info"
+                        class="btn btn-large col l6 m6 s10 offset-l3 offset-m3 offset-s1 waves-effect waves-light">Get
+                    Spotify Data
+                </button>
+                <button type="button" id="save-song-button"
+                        class="btn btn-large col l6 m6 s10 offset-l3 offset-m3 offset-s1 waves-effect waves-light">Save
+                    Changes
+                </button>
+            </div>
+            <script>
+                $('#genres').material_select();
+            </script>
+        </div>
+        <div class="modal-footer musare white-text">
+            <a href="#!" class="modal-action modal-close waves-effect waves-light btn-flat white">X</a>
+        </div>
+    </div>
+</template>

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

@@ -4,8 +4,8 @@
     {{#if loaded}}
     {{#if loaded}}
         <!--{{> avatar userId=profileUserId shape="circle" class="profile-img" initials=initials}}-->
         <!--{{> avatar userId=profileUserId shape="circle" class="profile-img" initials=initials}}-->
         <h1 id="profile-name" class="center-align black-text thin">{{username}}</h1>
         <h1 id="profile-name" class="center-align black-text thin">{{username}}</h1>
-        <div class="row">
-            <div class="col s12 m6 l4">
+        <div class="row hack-container">
+            <div class="col s12 m4 l4">
                 <div class="card blue-grey darken-1 profile-card">
                 <div class="card blue-grey darken-1 profile-card">
                     <div class="card-content white-text">
                     <div class="card-content white-text">
                         <span class="card-title">User Info</span>
                         <span class="card-title">User Info</span>
@@ -16,7 +16,7 @@
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
-            <div class="col s12 m6 l4">
+            <div class="col s12 m4 l4">
                 <div class="card teal accent-3 profile-card">
                 <div class="card teal accent-3 profile-card">
                     <div class="card-content white-text">
                     <div class="card-content white-text">
                         <span class="card-title">Liked Songs</span>
                         <span class="card-title">Liked Songs</span>
@@ -32,7 +32,7 @@
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
-            <div class="col s12 m6 l4">
+            <div class="col s12 m4 l4">
                 <div class="card red darken-2 profile-card">
                 <div class="card red darken-2 profile-card">
                     <div class="card-content white-text">
                     <div class="card-content white-text">
                         <span class="card-title">Disliked Songs</span>
                         <span class="card-title">Disliked Songs</span>

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

@@ -1,28 +1,30 @@
 <template name="settings">
 <template name="settings">
     {{> header}}
     {{> header}}
-    <div class="row">
-        <h1 id="profile-name" class="black-text thin">Settings</h1>
-        <h4 class="thin">Liked & disliked songs</h4>
-        <p>
-            <input type="checkbox" id="showRating"/>
-            <label for="showRating">Show liked and disliked song on profile?</label>
-        </p>
-        <button class="btn" id="save-settings">Save</button>
-        <h4 class="thin">Change Password</h4>
-        <div class="input-field">
-            <input type="password" id="old-password" class="validate">
-            <label for="old-password">Old Password</label>
+    <div class="row hack-container">
+        <div class="col l6 m6 s12 offset-l3 offset-m3">
+            <h1 id="profile-name" class="black-text thin">Settings</h1>
+            <h4 class="thin">Liked & disliked songs</h4>
+            <p>
+                <input type="checkbox" id="showRating"/>
+                <label for="showRating">Show liked and disliked song on profile?</label>
+            </p>
+            <button class="btn" id="save-settings">Save</button>
+            <h4 class="thin">Change Password</h4>
+            <div class="input-field">
+                <input type="password" id="old-password" class="validate">
+                <label for="old-password">Old Password</label>
+            </div>
+            <div class="input-field">
+                <input type="password" id="new-password" class="validate">
+                <label for="new-password">New Password</label>
+            </div>
+            <div class="input-field">
+                <input type="password" id="confirm-password" class="validate">
+                <label for="confirm-password">Re-enter New Password</label>
+            </div>
+            <button class="btn" id="change-password">Change Password</button>
+            <h4 class="thin">Delete Account</h4>
+            <button class="btn red darken-4" id="delete-account">Delete</button>
         </div>
         </div>
-        <div class="input-field">
-            <input type="password" id="new-password" class="validate">
-            <label for="new-password">New Password</label>
-        </div>
-        <div class="input-field">
-            <input type="password" id="confirm-password" class="validate">
-            <label for="confirm-password">Re-enter New Password</label>
-        </div>
-        <button class="btn" id="change-password">Change Password</button>
-        <h4 class="thin">Delete Account</h4>
-        <button class="btn red darken-4" id="delete-account">Delete</button>
     </div>
     </div>
 </template>
 </template>

BIN
app/public/FB-f-Logo__blue_57.png


BIN
app/public/TwitterLogo_#55acee.png


BIN
app/public/noise.jpg


+ 2 - 1
app/server/server.js

@@ -1052,7 +1052,8 @@ Meteor.methods({
                 "img": newSong.img,
                 "img": newSong.img,
                 "duration": newSong.duration,
                 "duration": newSong.duration,
                 "skipDuration": newSong.skipDuration,
                 "skipDuration": newSong.skipDuration,
-                "approvedBy": Meteor.userId()
+                "approvedBy": Meteor.userId(),
+                "genres": newSong.genres
         }}, function(err) {
         }}, function(err) {
                 console.log(err);
                 console.log(err);
                 if (err) {
                 if (err) {