diff --git a/build.gradle b/build.gradle index 3ed489b..cc7594a 100644 --- a/build.gradle +++ b/build.gradle @@ -52,7 +52,7 @@ dependencies { exclude group:"org.springframework.boot", module: "spring-boot-starter-logging" } compile("org.springframework.boot:spring-boot-starter-log4j2") - compile("com.sedmelluq:lavaplayer:1.2.49") + compile("com.sedmelluq:lavaplayer:1.3.10") compile 'net.dv8tion:JDA:3.6.0_354' compile group: 'org.json', name: 'json', version: '20160810' compile 'org.springframework.security:spring-security-web:5.0.1.RELEASE' diff --git a/src/main/java/net/Broken/Commands/YtSearch.java b/src/main/java/net/Broken/Commands/YtSearch.java index 9c6232c..c009c35 100644 --- a/src/main/java/net/Broken/Commands/YtSearch.java +++ b/src/main/java/net/Broken/Commands/YtSearch.java @@ -31,7 +31,7 @@ public class YtSearch implements Commande { new MessageTimeOut(MainBot.messageTimeOut, message, event.getMessage()).start(); }else { try { - ArrayList result = youtubeT.search(args[0], 5); + ArrayList result = youtubeT.search(args[0], 5, false); for(SearchResult item : result){ event.getChannel().sendMessage(EmbedMessageUtils.searchResult(item)).queue(); } diff --git a/src/main/java/net/Broken/RestApi/Data/AllMusicInfoData.java b/src/main/java/net/Broken/RestApi/Data/AllMusicInfoData.java new file mode 100644 index 0000000..4932304 --- /dev/null +++ b/src/main/java/net/Broken/RestApi/Data/AllMusicInfoData.java @@ -0,0 +1,11 @@ +package net.Broken.RestApi.Data; + +public class AllMusicInfoData { + public CurrentMusicData currentMusic; + public PlaylistData playlist; + + public AllMusicInfoData(CurrentMusicData currentMusic, PlaylistData playlist) { + this.currentMusic = currentMusic; + this.playlist = playlist; + } +} diff --git a/src/main/java/net/Broken/RestApi/MusicWebAPIController.java b/src/main/java/net/Broken/RestApi/MusicWebAPIController.java index 88fbe5e..1a11f43 100644 --- a/src/main/java/net/Broken/RestApi/MusicWebAPIController.java +++ b/src/main/java/net/Broken/RestApi/MusicWebAPIController.java @@ -17,6 +17,7 @@ import net.Broken.audio.Youtube.SearchResult; import net.Broken.audio.Youtube.YoutubeTools; import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.VoiceChannel; +import org.apache.http.HttpResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; @@ -59,7 +60,6 @@ public class MusicWebAPIController { logger.trace("currentMusicInfo for " + guild.getName()); } - Music musicCommande = (Music) MainBot.commandes.get("music"); if(guild.getAudioManager().isConnected()){ AudioPlayer player = AudioM.getInstance(guild).getGuildMusicManager().player; @@ -92,7 +92,58 @@ public class MusicWebAPIController { return new ResponseEntity<>(new PlaylistData(list), HttpStatus.OK); } -// TODO change token to cookie + + + + @RequestMapping("/getAllInfo") + public ResponseEntity getAllInfo(@RequestParam(value = "guild") String guildId, @CookieValue("token") String token){ + if(token != null) { + Guild guild = MainBot.jda.getGuildById(guildId); + if(guild == null ){ + + logger.warn("All info without guild!"); + return new ResponseEntity<>(HttpStatus.BAD_REQUEST); + } + + try { + UserEntity user = userUtils.getUserWithApiToken(userRepository, token); + logger.trace("All info from USER: " + user.getName() + " GUILD: " + guild.getName()); + + PlaylistData list = new PlaylistData(AudioM.getInstance(guild).getGuildMusicManager().scheduler.getList()); + CurrentMusicData musicData; + if(guild.getAudioManager().isConnected()){ + AudioPlayer player = AudioM.getInstance(guild).getGuildMusicManager().player; + AudioTrack currentTrack = player.getPlayingTrack(); + if(currentTrack == null) + { + musicData = new CurrentMusicData(null,0, "STOP",false, AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()); + } + else{ + UserAudioTrackData uat = new UserAudioTrackData(AudioM.getInstance(guild).getGuildMusicManager().scheduler.getCurrentPlayingTrack()); + musicData = new CurrentMusicData(uat, currentTrack.getPosition(), currentTrack.getState().toString(), player.isPaused(), AudioM.getInstance(guild).getGuildMusicManager().scheduler.isAutoFlow()); + } + + }else + { + musicData = new CurrentMusicData(null,0, "DISCONNECTED",false, false); + } + return new ResponseEntity<>(new AllMusicInfoData(musicData, list),HttpStatus.OK); + + + } catch (UnknownTokenException e) { + logger.warn("All info with unknown token"); + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + + } + + } + else{ + logger.warn("All Info without token!"); + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + + } + } + @RequestMapping(value = "/command", method = RequestMethod.POST) public ResponseEntity command(@RequestBody CommandPostData data, HttpServletRequest request, @RequestParam(value = "guild") String guildId, @CookieValue("token") String token){ @@ -149,12 +200,12 @@ public class MusicWebAPIController { } @RequestMapping(value = "/search", method = RequestMethod.GET) - public ResponseEntity> search(@CookieValue("token") String token, @RequestParam(value = "query") String query ){ + public ResponseEntity> search(@CookieValue("token") String token, @RequestParam(value = "query") String query, @RequestParam(value = "playlist") boolean playlist ){ if(token != null) { try { UserEntity user = userUtils.getUserWithApiToken(userRepository, token); YoutubeTools youtubeTools = YoutubeTools.getInstance(); - ArrayList result = youtubeTools.search(query, 25); + ArrayList result = youtubeTools.search(query, 25, playlist); return new ResponseEntity<>(result, HttpStatus.OK); }catch (UnknownTokenException e){ diff --git a/src/main/java/net/Broken/audio/AudioPlayerSendHandler.java b/src/main/java/net/Broken/audio/AudioPlayerSendHandler.java index 29221dc..89fe125 100644 --- a/src/main/java/net/Broken/audio/AudioPlayerSendHandler.java +++ b/src/main/java/net/Broken/audio/AudioPlayerSendHandler.java @@ -37,7 +37,7 @@ public class AudioPlayerSendHandler implements AudioSendHandler { lastFrame = audioPlayer.provide(); } - byte[] data = lastFrame != null ? lastFrame.data : null; + byte[] data = lastFrame != null ? lastFrame.getData() : null; lastFrame = null; return data; diff --git a/src/main/java/net/Broken/audio/Youtube/SearchResult.java b/src/main/java/net/Broken/audio/Youtube/SearchResult.java index 1a36538..7aa75aa 100644 --- a/src/main/java/net/Broken/audio/Youtube/SearchResult.java +++ b/src/main/java/net/Broken/audio/Youtube/SearchResult.java @@ -11,7 +11,10 @@ public class SearchResult { public String duration; public SearchResult(com.google.api.services.youtube.model.SearchResult result, String duration){ - id = result.getId().getVideoId(); + if(result.getId().getVideoId() == null) + id = result.getId().getPlaylistId(); + else + id = result.getId().getVideoId(); title = result.getSnippet().getTitle(); description = result.getSnippet().getDescription(); publishedAt = result.getSnippet().getPublishedAt().toString(); diff --git a/src/main/java/net/Broken/audio/Youtube/YoutubeTools.java b/src/main/java/net/Broken/audio/Youtube/YoutubeTools.java index 369365e..469fbf3 100644 --- a/src/main/java/net/Broken/audio/Youtube/YoutubeTools.java +++ b/src/main/java/net/Broken/audio/Youtube/YoutubeTools.java @@ -3,10 +3,8 @@ package net.Broken.audio.Youtube; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.jackson2.JacksonFactory; import com.google.api.services.youtube.YouTube; -import com.google.api.services.youtube.model.SearchListResponse; +import com.google.api.services.youtube.model.*; import com.google.api.services.youtube.model.SearchResult; -import com.google.api.services.youtube.model.Video; -import com.google.api.services.youtube.model.VideoListResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -81,10 +79,13 @@ public class YoutubeTools { } - public ArrayList search(String query, long max) throws IOException { + public ArrayList search(String query, long max, boolean playlist) throws IOException { YouTube youTube = getYoutubeService(); YouTube.Search.List searchList = youTube.search().list("snippet"); - searchList.setType("video"); + if(playlist) + searchList.setType("playlist"); + else + searchList.setType("video"); searchList.setSafeSearch("none"); searchList.setMaxResults(max); searchList.setQ(query); @@ -94,30 +95,55 @@ public class YoutubeTools { SearchListResponse response = searchList.execute(); StringBuilder idString = new StringBuilder(); - for(SearchResult item : response.getItems()){ - idString.append(item.getId().getVideoId()).append(","); - } - HashMap videoHashMap = new HashMap<>(); - YouTube.Videos.List video = youTube.videos().list("contentDetails"); - video.setId(idString.toString()); - video.setKey(apiKey); - VideoListResponse videoResponse = video.execute(); - for(Video item : videoResponse.getItems()){ - videoHashMap.put(item.getId(), item); + if(playlist){ + for(SearchResult item : response.getItems()){ + idString.append(item.getId().getPlaylistId()).append(","); + } + HashMap playlistHashMap = new HashMap<>(); + YouTube.Playlists.List list = youTube.playlists().list("contentDetails"); + list.setId(idString.toString()); + list.setKey(apiKey); + PlaylistListResponse playlistResponse = list.execute(); + for( Playlist item : playlistResponse.getItems()){ + playlistHashMap.put(item.getId(), item); + } + ArrayList finalResult = new ArrayList<>(); + for(SearchResult item : response.getItems()){ + logger.trace(item.getSnippet().getTitle()); + finalResult.add(new net.Broken.audio.Youtube.SearchResult(item, playlistHashMap.get(item.getId().getPlaylistId()).getContentDetails().getItemCount().toString()+ " Video(s)")); + + } + return finalResult; } - ArrayList finalResult = new ArrayList<>(); - for(SearchResult item : response.getItems()){ - logger.trace(item.getSnippet().getTitle()); - finalResult.add(new net.Broken.audio.Youtube.SearchResult(item, videoHashMap.get(item.getId().getVideoId()).getContentDetails().getDuration())); + else{ + for(SearchResult item : response.getItems()){ + idString.append(item.getId().getVideoId()).append(","); + } + HashMap videoHashMap = new HashMap<>(); + YouTube.Videos.List video = youTube.videos().list("contentDetails"); + video.setId(idString.toString()); + video.setKey(apiKey); + VideoListResponse videoResponse = video.execute(); + for(Video item : videoResponse.getItems()){ + videoHashMap.put(item.getId(), item); + } + ArrayList finalResult = new ArrayList<>(); + for(SearchResult item : response.getItems()){ + logger.trace(item.getSnippet().getTitle()); + finalResult.add(new net.Broken.audio.Youtube.SearchResult(item, videoHashMap.get(item.getId().getVideoId()).getContentDetails().getDuration())); + } + return finalResult; } - return finalResult; + + + } diff --git a/src/main/resources/static/css/materialize.css b/src/main/resources/static/css/materialize.css index 416777f..bc6c1fe 100644 --- a/src/main/resources/static/css/materialize.css +++ b/src/main/resources/static/css/materialize.css @@ -1,5 +1,5 @@ /*! - * Materialize v1.0.0-rc.2 (http://materializecss.com) + * Materialize v1.0.0 (http://materializecss.com) * Copyright 2014-2017 Materialize * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) */ @@ -6551,7 +6551,7 @@ textarea.materialize-textarea + label:after, .select-wrapper + label:after { transform-origin: 0 0; } -.input-field > input[type]:-webkit-autofill:not(.browser-default) + label, +.input-field > input[type]:-webkit-autofill:not(.browser-default):not([type="search"]) + label, .input-field > input[type=date]:not(.browser-default) + label, .input-field > input[type=time]:not(.browser-default) + label { -webkit-transform: translateY(-14px) scale(0.8); diff --git a/src/main/resources/static/js/materialize.js b/src/main/resources/static/js/materialize.js index 7e218e6..1e18382 100644 --- a/src/main/resources/static/js/materialize.js +++ b/src/main/resources/static/js/materialize.js @@ -1,5 +1,5 @@ /*! - * Materialize v1.0.0-rc.2 (http://materializecss.com) + * Materialize v1.0.0 (http://materializecss.com) * Copyright 2014-2017 Materialize * MIT License (https://raw.githubusercontent.com/Dogfalo/materialize/master/LICENSE) */ @@ -1084,6 +1084,8 @@ if (typeof define === 'function' && define.amd) { exports.default = M; } +M.version = '1.0.0'; + M.keys = { TAB: 9, ENTER: 13, @@ -2507,7 +2509,11 @@ $jscomp.polyfill = function (e, r, p, m) { var $activatableElement = $(focusedElement).find('a, button').first(); // Click a or button tag if exists, otherwise click li tag - !!$activatableElement.length ? $activatableElement[0].click() : focusedElement.click(); + if (!!$activatableElement.length) { + $activatableElement[0].click(); + } else if (!!focusedElement) { + focusedElement.click(); + } // Close dropdown on ESC } else if (e.which === M.keys.ESC && this.isOpen) { @@ -2687,8 +2693,7 @@ $jscomp.polyfill = function (e, r, p, m) { // onOpenEnd callback if (typeof _this11.options.onOpenEnd === 'function') { - var elem = anim.animatables[0].target; - _this11.options.onOpenEnd.call(elem, _this11.el); + _this11.options.onOpenEnd.call(_this11, _this11.el); } } }); @@ -2719,7 +2724,6 @@ $jscomp.polyfill = function (e, r, p, m) { // onCloseEnd callback if (typeof _this12.options.onCloseEnd === 'function') { - var elem = anim.animatables[0].target; _this12.options.onCloseEnd.call(_this12, _this12.el); } } @@ -2849,7 +2853,7 @@ $jscomp.polyfill = function (e, r, p, m) { Dropdown._dropdowns = []; - window.M.Dropdown = Dropdown; + M.Dropdown = Dropdown; if (M.jQueryLoaded) { M.initializeJqueryWrapper(Dropdown, 'dropdown', 'M_Dropdown'); @@ -4420,7 +4424,7 @@ $jscomp.polyfill = function (e, r, p, m) { return Tabs; }(Component); - window.M.Tabs = Tabs; + M.Tabs = Tabs; if (M.jQueryLoaded) { M.initializeJqueryWrapper(Tabs, 'tabs', 'M_Tabs'); @@ -6090,7 +6094,7 @@ $jscomp.polyfill = function (e, r, p, m) { Sidenav._sidenavs = []; - window.M.Sidenav = Sidenav; + M.Sidenav = Sidenav; if (M.jQueryLoaded) { M.initializeJqueryWrapper(Sidenav, 'sidenav', 'M_Sidenav'); @@ -11833,10 +11837,20 @@ $jscomp.polyfill = function (e, r, p, m) { // Add callback for centering selected option when dropdown content is scrollable dropdownOptions.onOpenEnd = function (el) { var selectedOption = $(_this71.dropdownOptions).find('.selected').first(); - if (_this71.dropdown.isScrollable && selectedOption.length) { - var scrollOffset = selectedOption[0].getBoundingClientRect().top - _this71.dropdownOptions.getBoundingClientRect().top; // scroll to selected option - scrollOffset -= _this71.dropdownOptions.clientHeight / 2; // center in dropdown - _this71.dropdownOptions.scrollTop = scrollOffset; + + if (selectedOption.length) { + // Focus selected option in dropdown + M.keyDown = true; + _this71.dropdown.focusedIndex = selectedOption.index(); + _this71.dropdown._focusFocusedItem(); + M.keyDown = false; + + // Handle scrolling to selected option + if (_this71.dropdown.isScrollable) { + var scrollOffset = selectedOption[0].getBoundingClientRect().top - _this71.dropdownOptions.getBoundingClientRect().top; // scroll to selected option + scrollOffset -= _this71.dropdownOptions.clientHeight / 2; // center in dropdown + _this71.dropdownOptions.scrollTop = scrollOffset; + } } }; diff --git a/src/main/resources/static/js/music.js b/src/main/resources/static/js/music.js index b43098c..6e2eb1b 100644 --- a/src/main/resources/static/js/music.js +++ b/src/main/resources/static/js/music.js @@ -1,5 +1,3 @@ -//import * as M from "./materialize"; - let savedPlaylist; let error = false; let state; @@ -14,6 +12,7 @@ let btn_flush; let btn_add; let switchAutoFlow; let loadingFlag = true; +let musicLoadFlag = false; let guild; let interval; @@ -31,7 +30,6 @@ $(document).ready(function () { switchAutoFlow = $("#autoflow"); - M.Modal.init($('#modalAdd').get(0)); $('#modal_current_info').modal(); @@ -43,7 +41,7 @@ $(document).ready(function () { modal_loading = M.Modal.init($('#modal_loading').get(0), {dismissible: false}); modal_loading.open(); - + $('#tabs-swipe-demo').tabs(); $('.dropdown-button').dropdown({ @@ -58,27 +56,29 @@ $(document).ready(function () { }); listeners(); + getCurentMusic(); interval = setInterval("getCurentMusic()", 1000); } }); function getCurentMusic() { - $.get("api/music/currentMusicInfo?guild=" + guild, function (data) { + $.get("api/music/getAllInfo?guild=" + guild, function (data) { }).done(function (data) { + if (error) { error = false; M.Toast.dismissAll(); } - state = data.state; - switch (data.state) { + state = data.currentMusic.state; + switch (data.currentMusic.state) { case "STOP": disconected = false; $('#modalChanels').modal('close'); $('#music_text').text("Connected on Vocal Channel"); - if (!$('#btn_info').hasClass("indeterminate")) { - $('#btn_info').addClass("determinate").removeClass("indeterminate"); + if (!$('#music_progress').hasClass("determinate")) { + $('#music_progress').addClass("determinate").removeClass("indeterminate"); } $('#music_progress').width("0%"); if (Cookies.get('token') !== undefined) { @@ -105,6 +105,10 @@ function getCurentMusic() { $('#current_time').text("00:00"); btn_play.removeClass("amber"); btn_play.addClass("green"); + if (savedPlaylist != null) { + $('#playlist_list').empty(); + savedPlaylist = null; + } break; @@ -114,7 +118,7 @@ function getCurentMusic() { btn_play.children().text("pause"); btn_play.removeClass("green"); btn_play.addClass("amber"); - updateControl(data); + updateControl(data.currentMusic); break; @@ -125,22 +129,28 @@ function getCurentMusic() { btn_play.removeClass("amber"); btn_play.addClass("green"); btn_play.addClass("green"); - updateControl(data); + updateControl(data.currentMusic); break; case "LOADING": disconected = false; $('#modalChanels').modal('close'); - if (!$('#btn_info').hasClass("determinate")) { - $('#btn_info').addClass("indeterminate").removeClass("determinate"); + updateControl(data.currentMusic); + if ($('#music_progress').hasClass("determinate")) { + $('#music_progress').addClass("indeterminate").removeClass("determinate"); + } + if(!musicLoadFlag){ + clearInterval(interval); + interval = setInterval("getCurentMusic()", 200); + musicLoadFlag = true; } break; case "DISCONNECTED": $('#music_text').text("Disconnected from Vocal"); - if (!$('#btn_info').hasClass("indeterminate")) { - $('#btn_info').addClass("determinate").removeClass("indeterminate"); + if (!$('#music_progress').hasClass("determinate")) { + $('#music_progress').addClass("determinate").removeClass("indeterminate"); } $('#music_progress').width("0%"); @@ -162,98 +172,98 @@ function getCurentMusic() { } } - clearInterval(interval); + if (savedPlaylist != null) { + $('#playlist_list').empty(); + savedPlaylist = null; + } break; } - if (switchAutoFlow.is(':checked') != data.autoflow) - switchAutoFlow.prop('checked', data.autoflow); - if(data.state !== "DISCONNECTED" && data.state !== "STOP") - getPlayList(); - else{ + if (switchAutoFlow.is(':checked') !== data.currentMusic.autoflow) + switchAutoFlow.prop('checked', data.currentMusic.autoflow); + if (data.currentMusic.state !== "DISCONNECTED" && data.currentMusic.state !== "STOP"){ + getPlayList(data.playlist.list); + if(data.currentMusic.state !== "LOADING"){ + $(".ctl-btn").removeClass("disabled"); + if(musicLoadFlag){ + clearInterval(interval); + interval = setInterval("getCurentMusic()", 1000); + musicLoadFlag = false; + } + } + } + + else { if (loadingFlag) { modal_loading.close(); loadingFlag = false; } - } - - }) - .fail(function (data) { - if (!error) { - error = true; - console.error("Connection lost, I keep trying to refresh!"); - M.toast({ - html: " warning Connection Lost!", - classes: 'red', - displayLength: 99999999 - }); - - } - - }) -} - -function getPlayList() { - $.get("api/music/getPlaylist?guild=" + guild, function (data) { - }).done(function (data) { - data = data.list; - if (data != null && data.length != 0) { - var noUpdate = comparePlaylist(data, savedPlaylist); - if (!noUpdate) { - savedPlaylist = data; - $('#playlist_list').empty(); - - data.forEach(function (element) { - var template = $('#playlist_template').clone(); - template.removeAttr("id"); - template.removeAttr("style"); - var content = template.html(); - content = content.replace("@title", element.audioTrackInfo.title); - content = content.replace("@author", element.audioTrackInfo.author); - content = content.replace("@lenght", msToTime(element.audioTrackInfo.length)); - content = content.replace(/@url/g, element.audioTrackInfo.uri); - content = content.replace(/@user/g, element.user); - template.html(content); - - $('#playlist_list').append(template); - $('.collapsible').collapsible(); - - }); - $(".btn_dell_playlist").click(function () { - var command = { - command: "DELL", - url: $(this).attr("data_url") - }; - sendCommand(command, true); - - - }); + $(".ctl-btn").removeClass("disabled"); + if(musicLoadFlag){ + clearInterval(interval); + interval = setInterval("getCurentMusic()", 1000); + musicLoadFlag = false; } } - else { - $('#playlist_list').empty(); - savedPlaylist = {}; - } - if (loadingFlag) { - modal_loading.close(); - loadingFlag = false; - } - }).fail(function (data) { if (!error) { + error = true; + console.error("Connection lost, I keep trying to refresh!"); M.toast({ html: " warning Connection Lost!", classes: 'red', displayLength: 99999999 }); - error = true; - } - if (loadingFlag) { - modal_loading.close(); - loadingFlag = false; + } - }); + }) +} + +function getPlayList(data) { + + if (data != null && data.length != 0) { + var noUpdate = comparePlaylist(data, savedPlaylist); + if (!noUpdate) { + savedPlaylist = data; + $('#playlist_list').empty(); + + data.forEach(function (element) { + var template = $('#playlist_template').clone(); + template.removeAttr("id"); + template.removeAttr("style"); + var content = template.html(); + content = content.replace("@title", element.audioTrackInfo.title); + content = content.replace("@author", element.audioTrackInfo.author); + content = content.replace("@lenght", msToTime(element.audioTrackInfo.length)); + content = content.replace(/@url/g, element.audioTrackInfo.uri); + content = content.replace(/@user/g, element.user); + template.html(content); + + $('#playlist_list').append(template); + $('.collapsible').collapsible(); + + }); + $(".btn_dell_playlist").click(function () { + var command = { + command: "DELL", + url: $(this).attr("data_url") + }; + sendCommand(command, true); + }); + } + } + else { + $('#playlist_list').empty(); + savedPlaylist = {}; + } + if (loadingFlag) { + modal_loading.close(); + loadingFlag = false; + } + + + } @@ -302,45 +312,54 @@ function updateModal(data) { } function updateControl(data) { - $('#music_text').text(data.info.audioTrackInfo.title); - var percent = (data.currentPos / data.info.audioTrackInfo.length) * 100; - if (!$('#music_progress').hasClass("indeterminate")) { - $('#music_progress').addClass("determinate").removeClass("indeterminate"); + + if($('#music_text').text() !== data.info.audioTrackInfo.title){ + $('#music_text').text(data.info.audioTrackInfo.title); } + var percent = (data.currentPos / data.info.audioTrackInfo.length) * 100; + $('#music_progress').width(percent + "%"); - if (Cookies.get('token') !== undefined) { - enableBtn(btn_play); - enableBtn(btn_stop); - enableBtn(btn_info); - enableBtn(btn_add); - enableBtn(btn_flush); - enableBtn(btn_next); - enableBtn(btn_disconnect_music); - } - else { - disableBtn(btn_play); - disableBtn(btn_stop); - disableBtn(btn_info); - disableBtn(btn_add); - disableBtn(btn_flush); - disableBtn(btn_next); - disableBtn(btn_disconnect_music); + if(data.state !== "LOADING"){ + if (Cookies.get('token') !== undefined) { + enableBtn(btn_play); + enableBtn(btn_stop); + enableBtn(btn_info); + enableBtn(btn_add); + enableBtn(btn_flush); + enableBtn(btn_next); + enableBtn(btn_disconnect_music); + } + else { + disableBtn(btn_play); + disableBtn(btn_stop); + disableBtn(btn_info); + disableBtn(btn_add); + disableBtn(btn_flush); + disableBtn(btn_next); + disableBtn(btn_disconnect_music); + } + if (!$('#music_progress').hasClass("determinate")) { + $('#music_progress').addClass("determinate").removeClass("indeterminate"); + } } + $('#music_img').attr("src", "https://img.youtube.com/vi/" + data.info.audioTrackInfo.identifier + "/hqdefault.jpg"); $('#total_time').text(msToTime(data.info.audioTrackInfo.length)); $('#current_time').text(msToTime(data.currentPos)); updateModal(data); } -function sendCommand(command, stopRefresh) { - if(stopRefresh){ - clearInterval(interval); +function sendCommand(command, modal) { + clearInterval(interval); + interval = null; + if (modal) { modal_loading.open(); } + $(".ctl-btn").addClass("disabled"); $.ajax({ type: "POST", @@ -350,9 +369,12 @@ function sendCommand(command, stopRefresh) { data: JSON.stringify(command), success: function (data) { loadingFlag = true; - if(stopRefresh) - interval = setInterval("getCurentMusic()", 1000); - if(command.command === "ADD"){ + getCurentMusic(); + if(interval != null) + clearInterval(interval); + interval = setInterval("getCurentMusic()", 1000); + + if (command.command === "ADD") { M.toast({ html: " check_circle Video added to playlist!", classes: 'green', @@ -360,6 +382,7 @@ function sendCommand(command, stopRefresh) { }); } + } }).fail(function (data) { @@ -370,13 +393,14 @@ function sendCommand(command, stopRefresh) { Cookies.remove('name'); location.reload(); } - else{ + else { M.toast({ html: " warning Command fail!", classes: 'red', displayLength: 99999999 }); } + $(".ctl-btn").removeClass("disabled"); }); } @@ -397,7 +421,6 @@ function comparePlaylist(list1, list2) { } - function search() { let input_search = $('#input_search'); let list = $("#search_result"); @@ -408,22 +431,28 @@ function search() { load.removeClass("hide"); load.addClass("scale-in"); - $.get("/api/music/search?query=" + input_search.val(), (data) => { + $.get("/api/music/search?query=" + input_search.val() + "&playlist=" + $("#playlistSearch").is(':checked'), (data) => { list.empty(); - data.forEach((item)=>{ + let url; + if($("#playlistSearch").is(':checked')){ + url = "https://www.youtube.com/playlist?list=" + } + else + url = "https://youtube.com/watch?v="; + + data.forEach((item) => { let html = "
  • " + - " \"\"" + - " "+item["title"]+"" + - "

    "+item["channelTittle"]+ " ║ "+ item["publishedAt"].substr(0, item["publishedAt"].indexOf('T'))+"
    " + ytTimeToTime(item["duration"]) + + " \"\"" + + " " + item["title"] + "" + + "

    " + item["channelTittle"] + " ║ " + item["publishedAt"].substr(0, item["publishedAt"].indexOf('T')) + "
    " + ytTimeToTime(item["duration"]) + "

    " + - " add_circle_outline" + + " add_circle_outline" + " " + "
  • "; - list.append(html) }); @@ -435,17 +464,15 @@ function search() { list.addClass("scale-in"); enableBtn($('#btn_search')); input_search.removeAttr("disabled"); - input_search.focus(); - - }).fail( (data)=>{ - if(data.status === 401){ + }).fail((data) => { + if (data.status === 401) { M.toast({ html: " warning Unauthorized, please re-login.", classes: 'red', displayLength: 99999999 }); - }else{ + } else { M.toast({ html: " warningInternal server error, please contact dev.", classes: 'red', @@ -463,9 +490,9 @@ function search() { } -function addListClick(event){ +function addListClick(event) { let button; - if(event.target.nodeName === "I"){ + if (event.target.nodeName === "I") { button = event.target.parentNode; } else @@ -475,7 +502,7 @@ function addListClick(event){ let command = { command: "ADD", url: button.id, - playlistLimit: $('#limit_range').val(), + playlistLimit: "300", onHead: !$('#bottom').is(':checked') }; sendCommand(command, false); @@ -485,20 +512,22 @@ function ytTimeToTime(duration) { let hours; let minutes; let seconds; - if(duration === "PT0S") + if (duration === "PT0S") return "🔴 LIVE"; - if(duration.includes("H")) - hours = parseInt(duration.match(/\d*H/)[0].replace("H",""), 10); + if(duration.endsWith("Video(s)")) + return duration; + if (duration.includes("H")) + hours = parseInt(duration.match(/\d*H/)[0].replace("H", ""), 10); else hours = 0; - if(duration.includes("M")) - minutes = parseInt(duration.match(/\d*M/)[0].replace("M",""), 10); + if (duration.includes("M")) + minutes = parseInt(duration.match(/\d*M/)[0].replace("M", ""), 10); else minutes = 0; - if(duration.includes("S")) - seconds = parseInt(duration.match(/\d*S/)[0].replace("S",""), 10); + if (duration.includes("S")) + seconds = parseInt(duration.match(/\d*S/)[0].replace("S", ""), 10); else seconds = 0; @@ -512,8 +541,6 @@ function ytTimeToTime(duration) { } - - function msToTime(duration) { var milliseconds = parseInt((duration % 1000) / 100) , seconds = parseInt((duration / 1000) % 60) @@ -542,23 +569,23 @@ function listeners() { sendCommand({command: "PLAY"}, true); break; default: - sendCommand({command: "PLAY"},true); + sendCommand({command: "PLAY"}, true); } }); $('#btn_search').click(search); - $("form").submit(function(e) { + $("form").submit(function (e) { e.preventDefault(); search(); }); $('#btn_next').click(function () { - sendCommand({command: "NEXT"},true); - }); + sendCommand({command: "NEXT"}, false); + }) $('#btn_stop').click(function () { - sendCommand({command: "STOP"}, true); + sendCommand({command: "STOP"}, false); }); @@ -572,8 +599,6 @@ function listeners() { }); - - $('#modalChanels').change(function () { if ($('#btn_ok_channel').hasClass("disabled")) { $('#btn_ok_channel').removeClass("disabled"); @@ -584,7 +609,7 @@ function listeners() { var command = { command: "FLUSH" }; - sendCommand(command, true); + sendCommand(command, false); }); $('#btn_ok_channel').click(function () { diff --git a/src/main/resources/templates/music.html b/src/main/resources/templates/music.html index 8cd26c3..8d4d2fc 100644 --- a/src/main/resources/templates/music.html +++ b/src/main/resources/templates/music.html @@ -16,22 +16,23 @@