app.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. History = new Mongo.Collection("history");
  2. Playlists = new Mongo.Collection("playlists");
  3. if (Meteor.isClient) {
  4. Meteor.startup(function() {
  5. reCAPTCHA.config({
  6. publickey: '6LcVxg0TAAAAAE18vBiH00UAyaJggsmLm890SjZl'
  7. });
  8. });
  9. var hpSound = undefined;
  10. var songsArr = [];
  11. var ytArr = [];
  12. var _sound = undefined;
  13. Template.register.events({
  14. "submit form": function(e){
  15. e.preventDefault();
  16. var username = e.target.registerUsername.value;
  17. var email = e.target.registerEmail.value;
  18. var password = e.target.registerPassword.value;
  19. var captchaData = grecaptcha.getResponse();
  20. Meteor.call("createUserMethod", {username: username, email: email, password: password}, captchaData, function(err, res) {
  21. grecaptcha.reset();
  22. if (err) {
  23. console.log(err);
  24. } else {
  25. Meteor.loginWithPassword(username, password);
  26. }
  27. });
  28. },
  29. "click #facebook-login": function(){
  30. Meteor.loginWithFacebook()
  31. },
  32. "click #github-login": function(){
  33. Meteor.loginWithGithub()
  34. },
  35. "click #login": function(){
  36. $("#register-view").hide();
  37. $("#login-view").show();
  38. }
  39. });
  40. Template.login.events({
  41. "submit form": function(e){
  42. e.preventDefault();
  43. var username = e.target.loginUsername.value;
  44. var password = e.target.loginPassword.value;
  45. Meteor.loginWithPassword(username, password);
  46. Accounts.onLoginFailure(function(){
  47. $("input").css("background-color","indianred").addClass("animated shake");
  48. $("input").on("click",function(){
  49. $("input").css({
  50. "background-color": "transparent",
  51. "width": "250px"
  52. });
  53. })
  54. });
  55. },
  56. "click #facebook-login": function(){
  57. Meteor.loginWithFacebook()
  58. },
  59. "click #github-login": function(){
  60. Meteor.loginWithGithub()
  61. },
  62. "click #register": function(){
  63. $("#login-view").hide();
  64. $("#register-view").show();
  65. }
  66. });
  67. Template.dashboard.events({
  68. "click .logout": function(e){
  69. e.preventDefault();
  70. Meteor.logout();
  71. if (hpSound !== undefined) {
  72. hpSound.stop();
  73. }
  74. },
  75. "click .button-tunein": function(){
  76. SC.stream("/tracks/172055891/", function(sound){
  77. sound._player._volume = 0.3;
  78. sound.play();
  79. });
  80. },
  81. "click #play": function(){
  82. $("#play").hide();
  83. SC.stream("/tracks/172055891/", function(sound){
  84. hpSound = sound;
  85. sound._player._volume = 0.3;
  86. sound.play();
  87. $("#stop").on("click", function(){
  88. $("#stop").hide();
  89. $("#play").show();
  90. sound._player.pause();
  91. })
  92. });
  93. $("#stop").show();
  94. }
  95. });
  96. Template.room.events({
  97. "click #search-song": function(){
  98. $("#song-results").empty()
  99. $.ajax({
  100. type: "GET",
  101. url: "https://www.googleapis.com/youtube/v3/search?part=snippet&q=" + $("#song-input").val() + "&key=AIzaSyAgBdacEWrHCHVPPM4k-AFM7uXg-Q__YXY",
  102. applicationType: "application/json",
  103. contentType: "json",
  104. success: function(data){
  105. console.log(data);
  106. for(var i in data.items){
  107. $("#song-results").append("<p>" + data.items[i].snippet.title + "</p>")
  108. ytArr.push({title: data.items[i].snippet.title, id: data.items[i].id.videoId});
  109. }
  110. console.log(ytArr);
  111. $("#song-results p").click(function(){
  112. var title = $(this).text();
  113. for(var i in ytArr){
  114. if(ytArr[i].title === title){
  115. console.log(ytArr[i].title)
  116. var songObj = {
  117. id: ytArr[i].id,
  118. title: ytArr[i].title,
  119. type: "youtube"
  120. }
  121. Meteor.call("addToPlaylist", songObj, function(err,res){
  122. console.log(res);
  123. })
  124. }
  125. }
  126. })
  127. }
  128. })
  129. SC.get('/tracks', { q: $("#song-input").val()}, function(tracks) {
  130. console.log(tracks);
  131. for(var i in tracks){
  132. $("#song-results").append("<p>" + tracks[i].title + "</p>")
  133. songsArr.push({title: tracks[i].title, id: tracks[i].id, duration: tracks[i].duration / 1000});
  134. }
  135. $("#song-results p").click(function(){
  136. var title = $(this).text();
  137. for(var i in songsArr){
  138. if(songsArr[i].title === title){
  139. var id = songsArr[i].id;
  140. var duration = songsArr[i].duration;
  141. var songObj = {
  142. title: songsArr[i].title,
  143. id: id,
  144. duration: duration,
  145. type: "soundcloud"
  146. }
  147. }
  148. }
  149. console.log(id);
  150. Meteor.call("addToPlaylist", songObj, function(err,res){
  151. return true;
  152. });
  153. // if (_sound !== undefined)_sound.stop();
  154. // SC.stream("/tracks/" + id, function(sound){
  155. // _sound = sound;
  156. // sound._player._volume = 0.3;
  157. // sound.play()
  158. // });
  159. })
  160. });
  161. }
  162. });
  163. Template.room.helpers({
  164. type: function() {
  165. var parts = location.href.split('/');
  166. var id = parts.pop();
  167. return id.toUpperCase();
  168. },
  169. title: function(){
  170. return Session.get("title");
  171. },
  172. artist: function(){
  173. return Session.get("artist");
  174. }
  175. });
  176. Template.playlist.helpers({
  177. playlist_songs: function() {
  178. console.log(Playlists.find({type: "edm"}).fetch());
  179. return Playlists.find({type: "edm"}).fetch()[0].songs;
  180. }
  181. });
  182. Template.room.onCreated(function () {
  183. var tag = document.createElement("script");
  184. tag.src = "https://www.youtube.com/iframe_api";
  185. var firstScriptTag = document.getElementsByTagName('script')[0];
  186. firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  187. var currentSong = undefined;
  188. var _sound = undefined;
  189. var yt_player = undefined;
  190. var size = 0;
  191. var artistStr;
  192. var temp = "";
  193. function getTimeElapsed() {
  194. if (currentSong !== undefined) {
  195. return Date.now() - currentSong.started;
  196. }
  197. return 0;
  198. }
  199. function getSongInfo(query, type){
  200. query = query.toLowerCase().split(" ").join("%20");
  201. $.ajax({
  202. type: "GET",
  203. url: 'https://api.spotify.com/v1/search?q=' + query + '&type=track',
  204. applicationType: "application/json",
  205. contentType: "json",
  206. success: function(data){
  207. console.log(data);
  208. for(var i in data){
  209. Session.set("title", data[i].items[0].name);
  210. if(type === "youtube"){
  211. Session.set("duration", data[i].items[0].duration_ms / 1000)
  212. }
  213. Meteor.call("setDuration", Session.get("duration"))
  214. temp = "";
  215. if(data[i].items[0].artists.length >= 2){
  216. for(var j in data[i].items[0].artists){
  217. temp = temp + data[i].items[0].artists[j].name + ", ";
  218. }
  219. } else{
  220. for(var j in data[i].items[0].artists){
  221. temp = temp + data[i].items[0].artists[j].name;
  222. }
  223. }
  224. if(temp[temp.length-2] === ","){
  225. artistStr = temp.substr(0,temp.length-2);
  226. } else{
  227. artistStr = temp;
  228. }
  229. Session.set("artist", artistStr);
  230. $("#albumart").remove();
  231. $(".room-title").before("<img id='albumart' src='" + data[i].items[0].album.images[1].url + "' />")
  232. }
  233. }
  234. })
  235. }
  236. function resizeSeekerbar() {
  237. $("#seeker-bar").width(((getTimeElapsed() / 1000) / Session.get("duration") * 100) + "%");
  238. }
  239. function startSong() {
  240. if (currentSong !== undefined) {
  241. if (_sound !== undefined) _sound.stop();
  242. if (yt_player !== undefined && yt_player.stopVideo !== undefined) yt_player.stopVideo();
  243. if (currentSong.song.type === "soundcloud") {
  244. $("#player").attr("src", "")
  245. getSongInfo(currentSong.song.title);
  246. SC.stream("/tracks/" + currentSong.song.id + "#t=20s", function(sound){
  247. console.log(sound);
  248. _sound = sound;
  249. sound._player._volume = 0.3;
  250. sound.play();
  251. console.log(getTimeElapsed());
  252. var interval = setInterval(function() {
  253. if (sound.getState() === "playing") {
  254. sound.seek(getTimeElapsed());
  255. window.clearInterval(interval);
  256. }
  257. }, 200);
  258. // Session.set("title", currentSong.song.title || "Title");
  259. // Session.set("artist", currentSong.song.artist || "Artist");
  260. Session.set("duration", currentSong.song.duration);
  261. resizeSeekerbar();
  262. });
  263. } else {
  264. if (yt_player === undefined) {
  265. yt_player = new YT.Player("player", {
  266. height: 540,
  267. width: 960,
  268. videoId: currentSong.song.id,
  269. events: {
  270. 'onReady': function(event) {
  271. event.target.seekTo(getTimeElapsed() / 1000);
  272. event.target.playVideo();
  273. resizeSeekerbar();
  274. },
  275. 'onStateChange': function(event){
  276. if (event.data == YT.PlayerState.PAUSED) {
  277. event.target.seekTo(getTimeElapsed() / 1000);
  278. event.target.playVideo();
  279. }
  280. }
  281. }
  282. });
  283. } else {
  284. yt_player.loadVideoById(currentSong.song.id);
  285. }
  286. // Session.set("title", currentSong.song.title || "Title");
  287. // Session.set("artist", currentSong.song.artist || "Artist");
  288. getSongInfo(currentSong.song.title, "youtube");
  289. //Session.set("duration", currentSong.song.duration);
  290. }
  291. }
  292. }
  293. Meteor.subscribe("history");
  294. Meteor.subscribe("playlists");
  295. Meteor.setInterval(function() {
  296. var data = undefined;
  297. var dataCursor = History.find({type: "edm"});
  298. dataCursor.map(function(doc) {
  299. if (data === undefined) {
  300. data = doc;
  301. }
  302. });
  303. if (data.history.length > size) {
  304. currentSong = data.history[data.history.length-1];
  305. size = data.history.length;
  306. startSong();
  307. }
  308. }, 1000);
  309. Meteor.setInterval(function() {
  310. resizeSeekerbar();
  311. }, 50);
  312. });
  313. }
  314. if (Meteor.isServer) {
  315. Meteor.startup(function() {
  316. reCAPTCHA.config({
  317. privatekey: '6LcVxg0TAAAAAI2fgIEEWHFxwNXeVIs8mzq5cfRM'
  318. });
  319. });
  320. if (Playlists.find({type: "edm"}).fetch().length === 0) {
  321. Playlists.insert({type: "edm", songs: [{id: "aE2GCa-_nyU", title: "Radioactive - Lindsey Stirling and Pentatonix", duration: 264, type: "youtube"}, {id: "aHjpOzsQ9YI", title: "Crystallize", artist: "Linsdey Stirling", duration: 300, type: "youtube"}]});
  322. }
  323. var duration = 226440;
  324. Meteor.users.deny({update: function () { return true; }});
  325. Meteor.users.deny({insert: function () { return true; }});
  326. Meteor.users.deny({remove: function () { return true; }});
  327. var startedAt = Date.now();
  328. var songs = Playlists.find({type: "edm"}).fetch()[0].songs;
  329. var currentSong = 0;
  330. addToHistory(songs[currentSong], startedAt);
  331. function addToHistory(song, startedAt) {
  332. History.update({type: "edm"}, {$push: {history: {song: song, started: startedAt}}});
  333. }
  334. function skipSong() {
  335. if (currentSong < (songs.length - 1)) {
  336. currentSong++;
  337. } else currentSong = 0;
  338. songTimer();
  339. addToHistory(songs[currentSong], startedAt);
  340. }
  341. function songTimer() {
  342. startedAt = Date.now();
  343. Meteor.setTimeout(function() {
  344. skipSong();
  345. }, duration);
  346. }
  347. ServiceConfiguration.configurations.remove({
  348. service: "facebook"
  349. });
  350. ServiceConfiguration.configurations.insert({
  351. service: "facebook",
  352. appId: "1496014310695890",
  353. secret: "9a039f254a08a1488c08bb0737dbd2a6"
  354. });
  355. ServiceConfiguration.configurations.remove({
  356. service: "github"
  357. });
  358. ServiceConfiguration.configurations.insert({
  359. service: "github",
  360. clientId: "dcecd720f47c0e4001f7",
  361. secret: "375939d001ef1a0ca67c11dbf8fb9aeaa551e01b"
  362. });
  363. songTimer();
  364. Meteor.publish("history", function() {
  365. return History.find({type: "edm"})
  366. });
  367. Meteor.publish("playlists", function() {
  368. return Playlists.find({type: "edm"})
  369. });
  370. Meteor.methods({
  371. createUserMethod: function(formData, captchaData) {
  372. var verifyCaptchaResponse = reCAPTCHA.verifyCaptcha(this.connection.clientAddress, captchaData);
  373. if (!verifyCaptchaResponse.success) {
  374. console.log('reCAPTCHA check failed!', verifyCaptchaResponse);
  375. throw new Meteor.Error(422, 'reCAPTCHA Failed: ' + verifyCaptchaResponse.error);
  376. } else {
  377. console.log('reCAPTCHA verification passed!');
  378. Accounts.createUser({
  379. username: formData.username,
  380. email: formData.email,
  381. password: formData.password
  382. });
  383. }
  384. return true;
  385. },
  386. addToPlaylist: function(songObj){
  387. songs.push(songObj);
  388. return songs;
  389. },
  390. setDuration: function(d){
  391. duration = d * 1000;
  392. console.log(duration);
  393. }
  394. });
  395. }
  396. Router.route("/", {
  397. template: "home"
  398. });
  399. Router.route("/:type", {
  400. template: "room"
  401. });