diff --git a/package-lock.json b/package-lock.json index 2d163bc4..1fe7d646 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2204,7 +2204,7 @@ "dependencies": { "combined-stream": { "version": "1.0.6", - "resolved": "http://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "requires": { "delayed-stream": "~1.0.0" @@ -3863,6 +3863,11 @@ } } }, + "mongojs-paginate": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mongojs-paginate/-/mongojs-paginate-1.2.0.tgz", + "integrity": "sha1-Z3YjmDlByAOPyBz88lw+425iO4s=" + }, "mongoose": { "version": "5.0.16", "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.0.16.tgz", diff --git a/package.json b/package.json index b9e6e168..795f6b6a 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "jimp": "^0.2.28", "mongodb": "^2.2.35", "mongojs": "^2.5.0", + "mongojs-paginate": "^1.2.0", "mongoose": "^5.0.16", "mpromise": "^0.5.5", "nodemailer": "^4.6.4", diff --git a/server/apps/client.js b/server/apps/client.js index 8861f99f..4e448e43 100755 --- a/server/apps/client.js +++ b/server/apps/client.js @@ -72,7 +72,7 @@ app.use(bodyParser.urlencoded({ // to support URL-encoded bodies extended: true })); app.use(cookieParser()); -app.set('json spaces', 2); +//app.set('json spaces', 2); io = require('socket.io')({ pingTimeout: 25000, diff --git a/server/apps/genre_generator.js b/server/apps/genre_generator.js new file mode 100644 index 00000000..292758cd --- /dev/null +++ b/server/apps/genre_generator.js @@ -0,0 +1,74 @@ +var path = require('path'); +var publicPath = path.join(__dirname, 'public'); +var pathThumbnail = __dirname; +pathThumbnails = __dirname + "/../"; +var time_regex = /P((([0-9]*\.?[0-9]*)Y)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)W)?(([0-9]*\.?[0-9]*)D)?)?(T(([0-9]*\.?[0-9]*)H)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*)S)?)?/; +try { + var keys = require(path.join(__dirname, '../config/api_key.js')); + var key = keys.youtube; + var soundcloudKey = keys.soundcloud; +} catch(e) { + console.log("Error - missing file"); + console.log("Seems you forgot to create the file api_key.js in /server/config/. Have a look at api_key.example.js."); + process.exit(1); +} +var Search = require(pathThumbnail + '/../handlers/search.js'); +var request = require('request'); +var db = require(pathThumbnail + '/../handlers/db.js'); +var currentList = 0; +var listNames = []; +db.getCollectionNames(function(e, d) { + for(var i = 0; i < d.length; i++) { + if(d[i].indexOf("_") < 0) { + if(d[i].length > 0) { + if(d[i].substring(0, 1) == "." || d[i].substring(d[i].length - 1) == ".") continue; + } + listNames.push(d[i]); + } + } + console.log("Number of lists is " + listNames.length); + /*for(var i = 0; i < listNames.length; i++) { + getListItems(d[i]); + if(i > 1000) return; + }*/ + recursivifyListLooping(listNames, 0); +}); + +function filterFunction(el) { + return el != null && + el != "" && + el != undefined && + el.trim() != '' +} + +function recursivifyListLooping(listNames, i) { + if(i > listNames.length) { + console.log("Done"); + return; + } + console.log("List " + i + " of " + listNames.length); + getListItems(listNames, 0, function() { + console.log("done"); + }); +} + +function getListItems(arr, i, callback) { + console.log("List " + i + " of " + listNames.length + " - " + arr[i]); + if(i >= arr.length) { + if(typeof(callback) == "function") callback(); + return; + } + try { + db.collection(arr[i]).find(function(e, d) { + if(d.length > 0) { + Search.get_genres_list_recursive(d, arr[i], function(){ + getListItems(arr, i + 1, callback); + }); + } else { + getListItems(arr, i + 1, callback); + } + }); + } catch(e) { + getListItems(arr, i + 1, callback); + } +} diff --git a/server/handlers/aggregates.js b/server/handlers/aggregates.js index 40e2e472..2c16bdd3 100644 --- a/server/handlers/aggregates.js +++ b/server/handlers/aggregates.js @@ -35,7 +35,8 @@ var project_object = { $ifNull: [ "$thumbnail", { $concat : [ "https://img.youtube.com/vi/", "$id", "/mqdefault.jpg"] } ] - } + }, + "tags": { $ifNull: [ "$tags", [] ] }, }; var toShowChannel = { @@ -48,6 +49,7 @@ var toShowChannel = { duration: 1, type: 1, _id: 0, + tags: 1, now_playing: 1, type: 1, source: 1, diff --git a/server/handlers/list_change.js b/server/handlers/list_change.js index b707a51d..83561b32 100644 --- a/server/handlers/list_change.js +++ b/server/handlers/list_change.js @@ -70,7 +70,8 @@ function addFromOtherList(arr, guid, offline, socket) { "end": 1, "type": 1, "source": 1, - "thumbnail": 1 + "thumbnail": 1, + "tags": 1 }; var to_set_np = true; if(np.length > 0) { @@ -241,6 +242,7 @@ function addPlaylist(arr, guid, offline, socket) { this_element.start = parseInt(this_element.start); this_element.end = parseInt(this_element.end); this_element.type = "video"; + if(this_element.tags == undefined) this_element.tags = []; this_element.duration = parseInt(this_element.duration); if(this_element.start > this_element.end) { this_element.start = 0; @@ -291,6 +293,7 @@ function addPlaylist(arr, guid, offline, socket) { _db.close(); }) } + Search.get_genres_list_recursive(arr.songs, channel); }); }); }); @@ -428,6 +431,7 @@ function add_function(arr, coll, guid, offline, socket) { var hash = arr.adminpass; var duration = parseInt(arr.duration); var source = arr.source; + var tags = arr.tags; conf = docs; if(docs !== null && docs.length !== 0 && ((docs[0].addsongs === true && (hash == docs[0].adminpass || docs[0].adminpass === "")) || docs[0].addsongs === false)) { @@ -442,7 +446,7 @@ function add_function(arr, coll, guid, offline, socket) { } else { np = false; } - var new_song = {"added": added,"guids":guids,"id":id,"now_playing":np,"title":title,"votes":votes, "duration":duration, "start": parseInt(start), "end": parseInt(end), "type": "video", "source": source}; + var new_song = {"added": added,"guids":guids,"id":id,"now_playing":np,"title":title,"tags":tags,"votes":votes, "duration":duration, "start": parseInt(start), "end": parseInt(end), "type": "video", "source": source}; if(source == "soundcloud") { if(arr.thumbnail.indexOf("https://i1.sndcdn.com") > -1 || arr.thumbnail.indexOf("https://w1.sndcdn.com") > -1) { new_song.thumbnail = arr.thumbnail; @@ -459,9 +463,11 @@ function add_function(arr, coll, guid, offline, socket) { var thumbnail = arr.thumbnail != undefined ? arr.thumbnail : undefined; Frontpage.update_frontpage(coll, id, title, thumbnail, arr.source); if(source != "soundcloud") Search.get_correct_info(new_song, coll, false); + else if(source == "soundcloud") Search.get_genres_soundcloud(new_song, coll); } else { io.to(coll).emit("channel", {type: "added", value: new_song}); if(source != "soundcloud") Search.get_correct_info(new_song, coll, true); + else if(source == "soundcloud") Search.get_genres_soundcloud(new_song, coll); } db.collection("frontpage_lists").update({_id:coll}, {$inc:{count:1}, $set:{accessed: Functions.get_time()}}, {upsert:true}, function(err, docs){}); List.getNextSong(coll, undefined); @@ -485,7 +491,8 @@ function add_function(arr, coll, guid, offline, socket) { "duration":duration, "start": start, "end": end, - "type":"suggested" + "type":"suggested", + "tags":tags }; var source = arr.source; if(source == "soundcloud") { diff --git a/server/handlers/search.js b/server/handlers/search.js index c9651fea..c75c195a 100644 --- a/server/handlers/search.js +++ b/server/handlers/search.js @@ -3,6 +3,7 @@ var time_regex = /P((([0-9]*\.?[0-9]*)Y)?(([0-9]*\.?[0-9]*)M)?(([0-9]*\.?[0-9]*) try { var keys = require(path.join(__dirname, '../config/api_key.js')); var key = keys.youtube; + var soundcloudKey = keys.soundcloud; } catch(e) { console.log("Error - missing file"); console.log("Seems you forgot to create the file api_key.js in /server/config/. Have a look at api_key.example.js."); @@ -11,11 +12,229 @@ try { var request = require('request'); var db = require(pathThumbnails + '/handlers/db.js'); +function filterFunction(el) { + return el != null && + el != "" && + el != undefined && + el.trim() != '' +} + +function get_genres_soundcloud(song, channel) { + request("http://api.soundcloud.com/tracks/" + song.id + "?client_id=" + soundcloudKey, function(err, response, body) { + if(err) { + console.log("error start", err, song, "error end"); + return; + } + try { + var object = JSON.parse(body); + if(!object.hasOwnProperty("genre") || !object.hasOwnProperty("tag_list")) return; + var genre = object.genre + ","; + genre = genre.toLowerCase().split(",").concat(object.tag_list.toLowerCase().split('"')); + genre = genre.filter(filterFunction); + + db.collection(channel).update({"id": song.id}, { + $set: { + "tags": genre + } + }, function(e,d) { + + }); + } catch(e) { + console.log("errored 2", e); + } + }); +} + +function get_genres_list(list, channel) { + var youtube_array = ""; + var i = 0; + try { + for(var i = 0; i < list.length; i++) { + + if(!list[i].hasOwnProperty("id")) continue; + if(list[i].source == undefined || list[i].source == "youtube") { + youtube_array += list[i].id + ","; + } + else if(list[i].source != undefined && list[i].source == "soundcloud") { + get_genres_soundcloud(list[i], channel); + } + } + if(youtube_array.length > 0) { + if(youtube_array > 49) { + var subList = []; + for(var i = 0; i < youtube_array.length; i++) { + subList.push(youtube_array[i]); + if(subList.length > 49) { + get_genres_youtube(subList.join(","), channel); + subList = []; + } + } + get_genres_youtube(subList.join(","), channel); + subList = []; + } else { + get_genres_youtube(youtube_array, channel); + } + } + } catch(e) { + console.log("errored", e); + return; + } +} + + +function start_soundcloud_get(arr, channel, callback) { + get_genres_soundcloud_recursive(arr, channel, 0, callback); +} + +function get_genres_soundcloud_recursive(arr, channel, i, callback) { + if(i >= arr.length) { + if(typeof(callback) == "function") callback(); + return; + } + var song = arr[i]; + request("http://api.soundcloud.com/tracks/" + song.id + "?client_id=" + soundcloudKey, function(err, response, body) { + if(err) { + console.log("error start", err, song, "error end"); + get_genres_soundcloud_recursive(arr, channel, i + 1, callback); + return; + } + try { + var object = JSON.parse(body); + if(!object.hasOwnProperty("genre") || !object.hasOwnProperty("tag_list")) { + get_genres_soundcloud_recursive(arr, channel, i + 1, callback); + return; + } + var genre = object.genre + ","; + genre = genre.toLowerCase().split(",").concat(object.tag_list.toLowerCase().split('"')); + genre = genre.filter(filterFunction); + + db.collection(channel).update({"id": song.id}, { + $set: { + "tags": genre + } + }, function(e,d) { + get_genres_soundcloud_recursive(arr, channel, i + 1, callback); + }); + } catch(e) { + console.log("errored 2", e); + get_genres_soundcloud_recursive(arr, channel, i + 1, callback); + } + }); +} + +function get_genres_list_recursive(list, channel, callback) { + var youtube_array = []; + var soundcloud_array = []; + for(var i = 0; i < list.length; i++) { + if(!list[i].hasOwnProperty("id")) continue; + if(list[i].source == undefined || list[i].source == "youtube") { + youtube_array.push(list[i]); + } + else if(list[i].source != undefined && list[i].source == "soundcloud") { + soundcloud_array.push(list[i]); + } + } + start_youtube_get(youtube_array, channel, function() { + start_soundcloud_get(soundcloud_array, channel, function() { + if(typeof(callback) == "function") callback(); + }) + }) +} + +function start_youtube_get(arr, channel, callback) { + get_genres_youtube_recursive(arr, channel, 0, callback) +} + +function get_genres_youtube_recursive(arr, channel, i, callback) { + if(i >= arr.length) { + if(typeof(callback) == "function") callback(); + return; + } + var ids = []; + for(var y = i; y < arr.length; y++) { + if(ids.length >= 48) { + break; + } + ids.push(arr[y].id); + } + request({ + type: "GET", + url: "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id,topicDetails&key="+key+"&id=" + ids.join(","), + }, function(error, response, body) { + if(error) { + console.log(arr, channel, i, arr[i]); + console.log("error start 1", error, ids, "error end"); + get_genres_youtube_recursive(arr, channel, i + ids.length, callback); + return; + } + var resp = JSON.parse(body); + if(!resp.hasOwnProperty("items")) { + console.log("error start 2", resp, ids, "error end"); + get_genres_youtube_recursive(arr, channel, i + ids.length, callback); + return; + } + if(resp.items.length > 0) { + for(var z = 0; z < resp.items.length; z++) { + if(!resp.items[z].hasOwnProperty("topicDetails")) continue; + var genre = resp.items[z].topicDetails.topicCategories; + genre = genre.join(","); + genre = genre.replace(new RegExp("https://en.wikipedia.org/wiki/", "g"), ""); + genre = genre.replace(/_/g, " ").toLowerCase().split(","); + genre = genre.filter(filterFunction); + //console.log(resp.items[i].id + " - ", genre); + db.collection(channel).update({"id": resp.items[z].id}, { + $set: { + "tags": genre + } + }, function(e, d) { + }); + } + get_genres_youtube_recursive(arr, channel, i + ids.length, callback); + } else { + get_genres_youtube_recursive(arr, channel, i + ids.length, callback); + } + }); +} + + +function get_genres_youtube(ids, channel) { + request({ + type: "GET", + url: "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id,topicDetails&key="+key+"&id=" + ids, + }, function(error, response, body) { + if(error) { + console.log("error start", error, ids, "error end"); + return; + } + var resp = JSON.parse(body); + if(!resp.hasOwnProperty("items")) { + console.log("error start", resp, ids, "error end"); + return; + } + if(resp.items.length > 0) { + for(var i = 0; i < resp.items.length; i++) { + if(!resp.items[i].hasOwnProperty("topicDetails")) continue; + var genre = resp.items[i].topicDetails.topicCategories; + genre = genre.join(","); + genre = genre.replace(new RegExp("https://en.wikipedia.org/wiki/", "g"), ""); + genre = genre.replace(/_/g, " ").toLowerCase().split(","); + genre = genre.filter(filterFunction); + //console.log(resp.items[i].id + " - ", genre); + db.collection(channel).update({"id": resp.items[i].id}, { + $set: { + "tags": genre + } + }, function(e, d) {}); + } + } + }); +} + function get_correct_info(song_generated, channel, broadcast, callback) { //channel = channel.replace(/ /g,''); request({ - type: "GET", - url: "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id&key="+key+"&id=" + song_generated.id, + type: "GET", + url: "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id,topicDetails&key="+key+"&id=" + song_generated.id, }, function(error, response, body) { try { @@ -23,6 +242,12 @@ function get_correct_info(song_generated, channel, broadcast, callback) { if(resp.items.length == 1) { var duration = parseInt(durationToSeconds(resp.items[0].contentDetails.duration)); var title = resp.items[0].snippet.localized.title; + var genre = resp.items[0].topicDetails.topicCategories; + genre = genre.join(","); + genre = genre.replace(new RegExp("https://en.wikipedia.org/wiki/", "g"), ""); + genre = genre.replace(/_/g, " ").toLowerCase().split(","); + genre = genre.filter(filterFunction); + //console.log(genre + " - ", song_generated.id); if(title != song_generated.title || duration < parseInt(song_generated.duration)) { if(title != song_generated.title) { song_generated.title = title; @@ -38,6 +263,7 @@ function get_correct_info(song_generated, channel, broadcast, callback) { "start": song_generated.start, "end": song_generated.end, "title": song_generated.title, + "tags": genre } }, function(err, docs) { if(broadcast && docs.nModified == 1) { @@ -55,9 +281,15 @@ function get_correct_info(song_generated, channel, broadcast, callback) { } }); } else { - if(typeof(callback) == "function") { - callback(song_generated, true); - } + db.collection(channel).update({"id": song_generated.id}, { + $set: { + "tags": genre + } + }, function(e,d) { + if(typeof(callback) == "function") { + callback(song_generated, true); + } + }); } } else { findSimilar(song_generated, channel, broadcast, callback) @@ -72,24 +304,24 @@ function get_correct_info(song_generated, channel, broadcast, callback) { function check_error_video(msg, channel) { if(!msg.hasOwnProperty("id") || !msg.hasOwnProperty("title") || - typeof(msg.id) != "string" || typeof(msg.title) != "string") { - var result = { - id: { - expected: "string", - got: msg.hasOwnProperty("id") ? typeof(msg.id) : undefined, - }, - title: { - expected: "string", - got: msg.hasOwnProperty("title") ? typeof(msg.title) : undefined, - }, - }; + typeof(msg.id) != "string" || typeof(msg.title) != "string") { + var result = { + id: { + expected: "string", + got: msg.hasOwnProperty("id") ? typeof(msg.id) : undefined, + }, + title: { + expected: "string", + got: msg.hasOwnProperty("title") ? typeof(msg.title) : undefined, + }, + }; return; } if(msg.source == "soundcloud") return; //channel = channel.replace(/ /g,''); request({ - type: "GET", - url: "https://www.googleapis.com/youtube/v3/videos?part=id&key="+key+"&id=" + msg.id, + type: "GET", + url: "https://www.googleapis.com/youtube/v3/videos?part=id&key="+key+"&id=" + msg.id, }, function(error, response, body) { try { @@ -117,8 +349,8 @@ function findSimilar(msg, channel, broadcast, callback) { vid_url += resp.items[i].id.videoId + ","; } request({ - type: "GET", - url: vid_url + type: "GET", + url: vid_url }, function(error, response, body) { var resp = JSON.parse(body); var found = false; @@ -165,44 +397,44 @@ function findSimilar(msg, channel, broadcast, callback) { } function similarity(s1, s2) { - var longer = s1; - var shorter = s2; - if (s1.length < s2.length) { - longer = s2; - shorter = s1; - } - var longerLength = longer.length; - if (longerLength == 0) { - return 1.0; - } - return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength); + var longer = s1; + var shorter = s2; + if (s1.length < s2.length) { + longer = s2; + shorter = s1; + } + var longerLength = longer.length; + if (longerLength == 0) { + return 1.0; + } + return (longerLength - editDistance(longer, shorter)) / parseFloat(longerLength); } function editDistance(s1, s2) { - s1 = s1.toLowerCase(); - s2 = s2.toLowerCase(); + s1 = s1.toLowerCase(); + s2 = s2.toLowerCase(); - var costs = new Array(); - for (var i = 0; i <= s1.length; i++) { - var lastValue = i; - for (var j = 0; j <= s2.length; j++) { - if (i == 0) - costs[j] = j; - else { - if (j > 0) { - var newValue = costs[j - 1]; - if (s1.charAt(i - 1) != s2.charAt(j - 1)) - newValue = Math.min(Math.min(newValue, lastValue), - costs[j]) + 1; - costs[j - 1] = lastValue; - lastValue = newValue; + var costs = new Array(); + for (var i = 0; i <= s1.length; i++) { + var lastValue = i; + for (var j = 0; j <= s2.length; j++) { + if (i == 0) + costs[j] = j; + else { + if (j > 0) { + var newValue = costs[j - 1]; + if (s1.charAt(i - 1) != s2.charAt(j - 1)) + newValue = Math.min(Math.min(newValue, lastValue), + costs[j]) + 1; + costs[j - 1] = lastValue; + lastValue = newValue; + } + } } - } + if (i > 0) + costs[s2.length] = lastValue; } - if (i > 0) - costs[s2.length] = lastValue; - } - return costs[s2.length]; + return costs[s2.length]; } function durationToSeconds(duration) { @@ -213,5 +445,9 @@ function durationToSeconds(duration) { return hours*60*60+minutes*60+seconds; } +module.exports.get_genres_list_recursive = get_genres_list_recursive; +module.exports.get_genres_soundcloud = get_genres_soundcloud; +module.exports.get_genres_youtube = get_genres_youtube; +module.exports.get_genres_list = get_genres_list; module.exports.check_error_video = check_error_video; module.exports.get_correct_info = get_correct_info; diff --git a/server/public/assets/css/style.css b/server/public/assets/css/style.css index 499519a1..cc57cf3f 100755 --- a/server/public/assets/css/style.css +++ b/server/public/assets/css/style.css @@ -376,8 +376,26 @@ li.disabled span { display: flex; justify-content: center; align-items: center; - color: white; + color: #fff; cursor: pointer; + padding-right: 7px; + margin-left: -7px; + margin-top: 5px; +} + +.filter-pagination-container { + display: flex; + justify-content: space-evenly; + width: 50%; + margin: auto; +} + +.bottom-filter-container { + padding-top: 15px; +} + +.top-filter-container { + padding-bottom: 15px; } .extra-button{ @@ -1180,7 +1198,7 @@ margin:-1px; padding-left: 8px; } -#close_find_form_button { +#close_find_form_button, #open_advanced_filter { display: flex; align-self: center; padding-left: 10px; @@ -2109,6 +2127,10 @@ nav ul li:hover, nav ul li.active { height:66px; margin: 2.5px 0 2.5px -1px !important; } +.filtered-search-element { + background-color: #2d2d2d; + display: flex; +} .card:hover{ box-shadow: 0 5px 5px 0 rgba(0,0,0,0.16), 0 5px 10px 0 rgba(0,0,0,0.12); } diff --git a/server/public/assets/js/channel.js b/server/public/assets/js/channel.js index 0cdd6502..b2d17303 100644 --- a/server/public/assets/js/channel.js +++ b/server/public/assets/js/channel.js @@ -143,6 +143,16 @@ var Channel = { Helper.removeElement(".embed-button-footer"); Helper.removeElement(".tabs"); } + M.Modal.init(document.getElementById("advanced_filter"), { + onCloseEnd: function() { + document.querySelector(".filter-results").innerHTML = ""; + document.getElementById("filtersearch_input").value = ""; + document.getElementById("filtersearch_input").blur(); + }, + onOpenEnd: function() { + document.getElementById("filtersearch_input").focus(); + } + }); M.Modal.init(document.getElementById("help")); M.Modal.init(document.getElementById("contact")); M.Modal.init(document.getElementById("channel-share-modal")); diff --git a/server/public/assets/js/functions.js b/server/public/assets/js/functions.js index 5db9d648..d5f52a13 100644 --- a/server/public/assets/js/functions.js +++ b/server/public/assets/js/functions.js @@ -21,6 +21,56 @@ function removeAllListeners() { socket.removeEventListener(id); } +function filterPlaylistElements(page) { + Helper.ajax({ + type: "POST", + headers: { + "Content-Type": "application/json" + }, + url: "/api/search/" + chan.toLowerCase(), + data: { + searchQuery: document.getElementById("filtersearch_input").value, + token: zoff_api_token, + page: page + }, + success: function(data){ + var json = JSON.parse(data); + document.querySelector(".filter-results").innerHTML = ""; + if(json.results.search_results.length > 0) { + addFilterButtons("top", json); + for(var i = 0; i < json.results.search_results.length; i++) { + document.querySelector(".filter-results").innerHTML += List.generateSong(json.results.search_results[i], false, false, true, false, "block", false, true);; + } + addFilterButtons("bottom", json); + } else { + toast("Couldn't find any items with those tags..", "red"); + document.querySelector(".filter-results").innerHTML = "Couldn't find any items with those tags.."; + } + }, + error: function() { + toast("Couldn't find any items with those tags..", "red"); + + document.querySelector(".filter-results").innerHTML = "Couldn't find any items with those tags.."; + } + }); +} + +function addFilterButtons(position, json) { + if(json.results.next != undefined || json.results.prev != undefined) { + document.querySelector(".filter-results").innerHTML += "
" + if(json.results.prev != undefined) { + document.querySelector("." + position + "-filter-container").innerHTML += "Prev"; + } else { + document.querySelector("." + position + "-filter-container").innerHTML += "Prev"; + } + if(json.results.next != undefined) { + document.querySelector("." + position + "-filter-container").innerHTML += "Next"; + } else { + document.querySelector("." + position + "-filter-container").innerHTML += "Next"; + } + } +} + function say_updated() { setTimeout(function() { before_toast(); diff --git a/server/public/assets/js/list.js b/server/public/assets/js/list.js index de7cd5a3..480ed675 100755 --- a/server/public/assets/js/list.js +++ b/server/public/assets/js/list.js @@ -1242,7 +1242,7 @@ var List = { } }, - generateSong: function(_song_info, transition, lazy, list, user, display, initial) { + generateSong: function(_song_info, transition, lazy, list, user, display, initial, filtered) { if(list_html === undefined) list_html = Helper.html("#list-song-html"); var video_id = _song_info.id; var video_title = _song_info.title; @@ -1275,8 +1275,8 @@ var List = { } song.querySelector(".list-image").setAttribute(image_attr,video_thumb); - if(list){ - song.querySelector("#list-song") + if(list && !filtered){ + //song.querySelector("#list-song") song.querySelector(".list-votes").innerText = video_votes; song.querySelector("#list-song").setAttribute("data-video-id", video_id); song.querySelector("#list-song").setAttribute("data-video-type", "song"); @@ -1292,7 +1292,7 @@ var List = { var _temp_duration = Helper.secondsToOther(_song_info.duration); song.querySelector(".card-duration").innerText = Helper.pad(_temp_duration[0]) + ":" + Helper.pad(_temp_duration[1]); - }else if(!list){ + }else if(!list && !filtered){ //song.querySelector(".card-duration").remove(); //song.querySelector(".list-song").removeClass("playlist-element"); @@ -1329,6 +1329,22 @@ var List = { list_image.classList.remove("list-image"); list_image.className += " list-suggested-image"; //song.querySelector(".list-image").setAttribute("class", song.querySelector(".list-image").getAttribute("class").replace("list-image", "list-suggested-image")); + } else if(filtered) { + song.querySelector("#list-song").className += " filtered-search-element"; + song.querySelector(".list-votes").innerText = _song_info.tags.join(", "); + song.querySelector(".vote-text").remove(); + song.querySelector("#list-song").setAttribute("data-video-id", video_id); + song.querySelector("#list-song").setAttribute("data-video-type", "song"); + song.querySelector("#list-song").setAttribute("data-video-source", _song_info.source); + song.querySelector("#list-song").setAttribute("id", "filtered-" + video_id); + song.classList.remove("hide"); + song.className += " filtered-search-element"; + song.querySelector(".vote-container").setAttribute("title", video_title); + attr = ".vote-container"; + del_attr = "delete_button"; + + var _temp_duration = Helper.secondsToOther(_song_info.duration); + song.querySelector(".card-duration").innerText = Helper.pad(_temp_duration[0]) + ":" + Helper.pad(_temp_duration[1]); } if(!embed) { song.querySelector(".mobile-delete").remove(); diff --git a/server/public/assets/js/listeners.js b/server/public/assets/js/listeners.js index 400a789a..4b053423 100755 --- a/server/public/assets/js/listeners.js +++ b/server/public/assets/js/listeners.js @@ -682,13 +682,51 @@ function addDynamicListeners() { this.preventDefault(); Helper.toggleClass("#find_div", "hide"); document.getElementById("find_input").value = ""; - document.getElementById("find_input").blur(); + document.getElementById("find_input").focus(); Helper.removeClass(".highlight", "highlight"); found_array = []; found_array_index = 0; find_word = ""; }); + addListener("click", "#open_advanced_filter", function(e) { + this.preventDefault(); + M.Modal.getInstance(document.getElementById("advanced_filter")).open(); + ga('send', 'event', "button-click", "advanced_filter"); + }); + + addListener("submit", "#filter-form", function(e) { + this.preventDefault(); + filterPlaylistElements(1); + }); + + addListener("click", ".submit-filter-search", function(e) { + this.preventDefault(); + filterPlaylistElements(1); + }); + + addListener("click", ".next-filter", function(e) { + this.preventDefault(); + var page = e.getAttribute("data-page"); + page = parseInt(page); + if(page == undefined || isNaN(page)) return; + e.classList.remove("next-filter"); + e.classList.remove("orange"); + e.className += " disabled"; + filterPlaylistElements(page); + }); + + addListener("click", ".prev-filter", function(e) { + this.preventDefault(); + var page = e.getAttribute("data-page"); + page = parseInt(page); + if(page == undefined || isNaN(page)) return; + e.classList.remove("prev-filter"); + e.classList.remove("orange"); + e.className += " disabled"; + filterPlaylistElements(page); + }); + addListener("click", ".delete-context-menu", function(e) { var that = e; if(that.classList.contains("context-menu-disabled")) { @@ -1600,9 +1638,9 @@ function addDynamicListeners() { this.stopPropagation(); var id = e.getAttribute("data-video-id"); var title = e.getAttribute("data-video-title"); + var original_length = e.getAttribute("data-video-length"); var parent = e.parentElement.parentElement; - var start = parseInt(parent.querySelectorAll(".result-start")[0].value); var end = parseInt(parent.querySelectorAll(".result-end")[0].value); if(end > original_length) { diff --git a/server/public/assets/js/search.js b/server/public/assets/js/search.js index 465c0cc2..5b4361cb 100755 --- a/server/public/assets/js/search.js +++ b/server/public/assets/js/search.js @@ -48,11 +48,12 @@ var Search = { yt_url+="&q="+keyword; if(music)yt_url+="&videoCategoryId=10"; if(pagination) yt_url += "&pageToken=" + pagination; - var vid_url = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id&key="+api_key.youtube+"&id="; + var vid_url = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id&fields=pageInfo,items(id,contentDetails,snippet(categoryId,channelTitle,publishedAt,title,description,thumbnails))&key="+api_key.youtube+"&id="; if(related) { var yt_url = "https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=25&relatedToVideoId="+keyword+"&type=video&key="+api_key.youtube; var vid_url = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id&key="+api_key.youtube+"&id="; } + //https://www.googleapis.com/youtube/v3/videos?key={API-key}&fields=items(snippet(title,description))&part=snippet&id={video_id} Helper.addClass(document.querySelector("#search-btn .material-icons"), "hide"); Helper.removeClass("#search_loader", "hide"); @@ -90,6 +91,7 @@ var Search = { dataType:"jsonp", success: function(response){ response = JSON.parse(response); + console.log(response); var output = ""; var pre_result = document.createElement("div"); pre_result.innerHTML = result_html.outerHTML; @@ -106,7 +108,6 @@ var Search = { var id=song.id; duration = duration.replace("PT","").replace("H","h ").replace("M","m ").replace("S","s"); var thumb=song.snippet.thumbnails.medium.url; - //$("#results").append(result_html); var songs = pre_result.cloneNode(true); songs.querySelector(".search-title").innerText = title; @@ -208,7 +209,7 @@ var Search = { }).then(function(tracks) { var pre_result = document.createElement("div"); pre_result.innerHTML = result_html.outerHTML; - + console.log(tracks); //$("#results").append(result_html); //Helper.css(document.querySelector(".search_results .col.s12"), "display", "block"); var output = ""; @@ -655,14 +656,36 @@ submit: function(id,title,duration, playlist, num, full_num, start, end, source, if(full_playlist[i].id == id) found_array.push(i); } if(found_array.length == 0){ - List.channel_function({type: "added", start: start, end: end, value: {added: (new Date).getTime()/1000, guids: [1], id: id, title: title, duration: duration, now_playing: false, votes: 1}}); + List.channel_function({ + type: "added", + start: start, + end: end, + value: { + added: (new Date).getTime()/1000, + guids: [1], + id: id, + title: title, + duration: duration, + now_playing: false, + votes: 1 + } + }); } else { List.vote(id, "pos"); } } else { /*var u = Crypt.crypt_pass(Crypt.get_userpass(chan.toLowerCase()), true); if(u == undefined) u = "";*/ - emit("add", {id: id, start: start, end: end, title: title, list: chan.toLowerCase(), duration: duration, source: source, thumbnail: thumbnail}); + emit("add", { + id: id, + start: start, + end: end, + title: title, + list: chan.toLowerCase(), + duration: duration, + source: source, + thumbnail: thumbnail + }); }//[id, decodeURIComponent(title), adminpass, duration, playlist]); }, diff --git a/server/public/assets/js/suggestions.js b/server/public/assets/js/suggestions.js index d24d6de7..f76f58d4 100755 --- a/server/public/assets/js/suggestions.js +++ b/server/public/assets/js/suggestions.js @@ -63,7 +63,7 @@ var Suggestions = { Helper.removeClass("#suggest-song-html", "hide"); } var get_url = "https://www.googleapis.com/youtube/v3/search?part=snippet&relatedToVideoId="+id+"&type=video&key="+api_key.youtube; - var video_urls = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id,statistics&key="+api_key.youtube+"&id="; + var video_urls = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails,snippet,id,statistics&fields=pageInfo,items(id,contentDetails,snippet(categoryId,channelTitle,publishedAt,title,description,thumbnails))&key="+api_key.youtube+"&id="; Helper.ajax({ type: "GET", diff --git a/server/public/partials/channel/modal.handlebars b/server/public/partials/channel/modal.handlebars index da115d46..a7662c23 100644 --- a/server/public/partials/channel/modal.handlebars +++ b/server/public/partials/channel/modal.handlebars @@ -39,6 +39,23 @@ {{/unless}} +