working on category browser

This commit is contained in:
Jonas Heinrich 2019-05-11 17:03:20 +02:00
parent 2af0acf591
commit 386036fc4c
5 changed files with 169 additions and 208 deletions

View File

@ -1,4 +1,12 @@
## 0.6.4 2018-XX ## 0.6.5 - 2019-05
### Added
- Smooth audio fade-in/out when changing stations
[#80](https://git.project-insanity.org/onny/nextcloud-app-radio/issues/80) @onny
### Fixed
- Prevent list from jumping back to top when adding station to favorites
[#85](https://git.project-insanity.org/onny/nextcloud-app-radio/issues/85) @onny
## 0.6.4 2019-01
### Added ### Added
- Support for Nextcloud 15 - Support for Nextcloud 15
[#82](https://git.project-insanity.org/onny/nextcloud-app-radio/issues/82) @onny [#82](https://git.project-insanity.org/onny/nextcloud-app-radio/issues/82) @onny

View File

@ -1,9 +1,12 @@
var MODULE = (function (radio) { var MODULE = (function (radio) {
var version = "0.6.3"
$(document).ready(function () { $(document).ready(function () {
var version = "0.6.5";
var current_stationid = "";
var searchTimeout = null;
var scheduled = false;
// Scroll event handler // Scroll event handler
$(window).scroll(function(){ $(window).scroll(function(){
var station_list = $("#app-content-files"); var station_list = $("#app-content-files");
@ -30,49 +33,15 @@ var MODULE = (function (radio) {
}); });
searchTimeout = null;
var scheduled;
/* ==============
// EVENTS //
/===============*/
/* Click on a radio station (table entry) and play it */
$('body').on('click', '.filename', function(e) {
e.preventDefault();
$('#playbutton').attr("class", "buffering");
var stationid = $(this).parent().attr('data-id');
var stationname = $(this).parent().find('.nametext').text();
radio.action_play(stationid);
$('#player').attr('data-id',stationid);
$("#station_metadata").html("Playing: "+stationname);
/* dirty fix missing background color for first td */
$('tbody tr').css("background-color", "white");
$(this).parent().css("background-color", "#f8f8f8");
var element = document.getElementById('station_metadata');
if (radio.isElementOverflowing(element)) {
radio.wrapContentsInMarquee(element);
};
if (!scheduled){
radio.schedule_get_metadata(stationid);
};
});
/* Save station to favorites */
$('body').on('click', '.favorite', function() {
var stationid = $(this).parent().parent().attr('data-id');
radio.action_favorite(stationid);
});
/* ============== /* ==============
// ACTIONS // // ACTIONS //
/===============*/ /===============*/
radio.schedule_get_metadata = function(stationid){ radio.schedule_get_metadata = function(stationid){
scheduled = true; radio.scheduled = true;
var stationid = $('#player').attr('data-id'); var stationid = radio.current_stationid;
req = $.get('https://onny.project-insanity.org/getmetadata/'+stationid, function(data) { req = $.get('https://onny.project-insanity.org/getmetadata/'+stationid, function(data) {
if (data.hasOwnProperty('metadata')) { if (data.hasOwnProperty('metadata')) {
var metadata = data['metadata'].toString(); var metadata = data['metadata'].toString();
@ -85,34 +54,30 @@ var MODULE = (function (radio) {
}; };
setTimeout(function(){radio.schedule_get_metadata(stationid);}, 10000); setTimeout(function(){radio.schedule_get_metadata(stationid);}, 10000);
} else { } else {
scheduled = false; radio.scheduled = false;
}; };
}).fail(function(){ }).fail(function(){
scheduled = false; radio.scheduled = false;
}); });
}; };
radio.action_favorite = function(stationid){ radio.action_favorite = function(stationid){
var exists = false;
var removed = false;
var stations = [];
var baseUrl = OC.generateUrl('/apps/radio'); var baseUrl = OC.generateUrl('/apps/radio');
$.get(baseUrl + '/stations', function ( data ) { $.get(baseUrl + '/stations', function ( data ) {
for (var station in data) { for (var station in data) {
if (data[station]["stationid"] == stationid){ if (data[station]["stationid"] == stationid){
removed = true; exists = true;
};
};
if (exists == true) {
$.ajax({ $.ajax({
url: baseUrl + '/stations/' + data[station]["id"], url: baseUrl + '/stations/' + data[station]["id"],
method: 'DELETE' method: 'DELETE'
}).done(function(){ }).done(function(){
$( "tr[data-id='" + stationid + "']" ).find('.icon-stationfav').removeClass('starred'); console.log("delete ", stationid);
$( "tr[data-src='#station/"+stationid+"']").find('.icon-stationfav').removeClass('starred');
}); });
};
};
if (removed == true) {
return true;
} else { } else {
var station = { var station = {
"stationid": stationid "stationid": stationid
@ -123,13 +88,13 @@ var MODULE = (function (radio) {
contentType: 'application/json', contentType: 'application/json',
data: JSON.stringify(station) data: JSON.stringify(station)
}).done(function(){ }).done(function(){
$( "tr[data-id='"+stationid+"']" ).find('.icon-stationfav').addClass('starred'); $( "tr[data-src='#station/"+stationid+"']" ).find('.icon-stationfav').addClass('starred');
}); });
}; };
}); });
}; };
radio.render_results = function(data){ radio.parse_results = function(data){
var baseUrl = OC.generateUrl('/apps/radio'); var baseUrl = OC.generateUrl('/apps/radio');
$.get(baseUrl + '/stations', function ( fav_stations ) { $.get(baseUrl + '/stations', function ( fav_stations ) {
@ -147,32 +112,14 @@ var MODULE = (function (radio) {
}; };
$.each(data, function(i, station) { $.each(data, function(i, station) {
var isstarred = false;
var isstarred = ""
for (var fav_station in fav_stations) { for (var fav_station in fav_stations) {
if (fav_stations[fav_station]["stationid"] == station['id']) { if (fav_stations[fav_station]["stationid"] == station['id']) {
isstarred = "starred"; isstarred = true;
break; break;
} }
}; };
radio.render_entry("station", isstarred, '#station/'+station['id'], station['favicon'], station['name']);
$('tbody').append('<tr data-src="'+station['url']+'" data-id="'+station['id']+'">\
<td class="favcolumn">\
<a href="#" class="favorite">\
<span class="icon-stationfav ' + isstarred + '"></span>\
<span class="hidden-visually">Favorite</span>\
</a>\
</td>\
<td class="filename">\
<label for="select-files-3">\
<div class="thumbnail" style="background-image:url('+station['favicon']+'); background-size: 32px;"></div>\
</label>\
<a class="name" href="#">\
<span class="nametext"><span class="innernametext">'+station['name']+'</span></span>\
</a>\
</td>\
</tr>');
}); });
}); });
@ -203,7 +150,7 @@ var MODULE = (function (radio) {
station_ids.forEach(function (station_id, idx) { station_ids.forEach(function (station_id, idx) {
var url = "https://www.radio-browser.info/webservice/json/stations/byid/"+station_ids[idx]; var url = "https://www.radio-browser.info/webservice/json/stations/byid/"+station_ids[idx];
$.getJSON( url , {"User-Agent": "Nextcloud Radio/"+version }, function( data ) { $.getJSON( url , {"User-Agent": "Nextcloud Radio/"+radio.version }, function( data ) {
if (data.length === 0) { if (data.length === 0) {
station_array = station_array.concat([{'id': station_id, 'name': 'Broken radio station entry :(', 'favicon': '', 'url': ''}]) station_array = station_array.concat([{'id': station_id, 'name': 'Broken radio station entry :(', 'favicon': '', 'url': ''}])
@ -222,7 +169,7 @@ var MODULE = (function (radio) {
}); });
}); });
radio.render_results(station_array_new); radio.parse_results(station_array_new);
}; };
}); });
@ -230,31 +177,48 @@ var MODULE = (function (radio) {
}; };
radio.radio_query = function(type, query){ radio.radio_query = function(hashurl){
console.log(hashurl);
var offset = $('tbody > tr').length; var offset = $('tbody > tr').length;
switch (type) { var query = "";
case 0: var api_baseurl = "https://www.radio-browser.info/webservice/json/";
var url = "https://www.radio-browser.info/webservice/json/stations/search"; switch (hashurl) {
case "#top":
var query_url = "stations/topclick";
break; break;
case 1: case "#recent":
var url = "https://www.radio-browser.info/webservice/json/stations/topclick"; var query_url = "stations/lastchange";
break; break;
case 2: case "#categories/countries":
var url = "https://www.radio-browser.info/webservice/json/stations/lastchange"; var query_url = "countries";
break;
case "#categories/states":
var query_url = "states";
break;
case "#categories/languages":
var query_url = "languages";
break;
case "#categories/tags":
var query_url = "tags";
break;
case (hashurl.match(/^#search/) || {}).input:
var query_url = "stations/search";
var query = hashurl.substring(8);
break; break;
}; };
console.log(api_baseurl + query_url, query);
$.ajax({ $.ajax({
method: "POST", method: "POST",
url: url, url: api_baseurl + query_url,
data: { data: {
name: query, name: query,
limit: 20, limit: 20,
"User-Agent": "Nextcloud Radio/"+version, "User-Agent": "Nextcloud Radio/"+radio.version,
offset: offset offset: offset
}, },
dataType: 'json', dataType: 'json',
}).success( function(data){ }).success( function(data){
radio.render_results(data); radio.parse_results(data);
}); });
}; };
@ -262,80 +226,68 @@ var MODULE = (function (radio) {
new OCA.Search(function (query) { new OCA.Search(function (query) {
$('#app-navigation').find('li').removeClass("active"); $('#app-navigation').find('li').removeClass("active");
$("tbody > tr").remove(); $("tbody > tr").remove();
radio.radio_query(0, query); radio.radio_query("#search/"+query);
}, function (arg) { }, function (arg) {
radio.switch_menu(0); radio.switch_menu(0);
}); });
radio.render_entry = function(entry_type, starred, hashurl, iconurl, title){
if (entry_type == "folder") {
var icon_class = "icon-stationfav-disabled";
var icon = "icon-filetype-folder";
} else {
var icon_class = "icon-stationfav";
var icon = '" style="background-image:url('+iconurl+'); background-size: 32px;';
}
if (starred) {
var starred = "starred";
} else {
var starred = "";
}
$('tbody').append('<tr data-src="'+hashurl+'">\
<td class="favcolumn">\
<a href="#" class="favorite">\
<span class="'+icon_class+' '+starred+'"></span>\
<span class="hidden-visually">Favorite</span>\
</a>\
</td>\
<td class="filename">\
<label for="select-files-3">\
<div class="thumbnail '+icon+'"></div>\
</label>\
<a class="name" href="#">\
<span class="nametext"><span class="innernametext">'+title+'</span></span>\
</a>\
</td>\
</tr>')
}
radio.action_load_categories = function (){ radio.action_load_categories = function (){
$('#emptycontent').addClass('hidden'); $('#emptycontent').addClass('hidden');
$('#filestable').show(); $('#filestable').show();
$('.nofilterresults').addClass('hidden'); $('.nofilterresults').addClass('hidden');
$('.loading').addClass('hidden'); $('.loading').addClass('hidden');
$('tbody').append('<tr>\
<td class="favcolumn">\ var categories = [{
<a href="#" class="favorite">\ 'hashurl': '#categories/countries',
<span class="icon-stationfav-disabled"></span>\ 'name': 'Countires'
<span class="hidden-visually">Favorite</span>\ },{
</a>\ 'hashurl': '#categories/states',
</td>\ 'name': 'States'
<td class="filename">\ },{
<label for="select-files-3">\ 'hashurl': '#categories/languages',
<div class="thumbnail icon-filetype-folder" background-size: 32px;"></div>\ 'name': 'Languages'
</label>\ },{
<a class="name" href="#">\ 'hashurl': '#categories/tags',
<span class="nametext"><span class="innernametext">Countries</span></span>\ 'name': 'Tags'
</a>\ }];
</td>\
</tr>\ categories.forEach(function(category_entry) {
<tr>\ radio.render_entry("folder", false, category_entry["hashurl"], false, category_entry["name"]);
<td class="favcolumn">\ })
<a href="#" class="favorite">\
<span class="icon-stationfav-disabled"></span>\ }
<span class="hidden-visually">Favorite</span>\
</a>\
</td>\
<td class="filename">\
<label for="select-files-3">\
<div class="thumbnail icon-filetype-folder"); background-size: 32px;"></div>\
</label>\
<a class="name" href="#">\
<span class="nametext"><span class="innernametext">States</span></span>\
</a>\
</td>\
</tr>\
<tr>\
<td class="favcolumn">\
<a href="#" class="favorite">\
<span class="icon-stationfav-disabled"></span>\
<span class="hidden-visually">Favorite</span>\
</a>\
</td>\
<td class="filename">\
<label for="select-files-3">\
<div class="thumbnail icon-filetype-folder"); background-size: 32px;"></div>\
</label>\
<a class="name" href="#">\
<span class="nametext"><span class="innernametext">Languages</span></span>\
</a>\
</td>\
</tr>\
<td class="favcolumn">\
<a href="#" class="favorite">\
<span class="icon-stationfav-disabled"></span>\
<span class="hidden-visually">Favorite</span>\
</a>\
</td>\
<td class="filename">\
<label for="select-files-3">\
<div class="thumbnail icon-filetype-folder"); background-size: 32px;"></div>\
</label>\
<a class="name" href="#">\
<span class="nametext"><span class="innernametext">Tags</span></span>\
</a>\
</td>\
</tr>');
};
return radio; return radio;
}(MODULE || {})); }(MODULE || {}));

View File

@ -1,42 +1,47 @@
var MODULE = (function (radio) { var MODULE = (function (radio) {
/* Click on menus */ /* Click on menus */
$('a.nav-icon-files').click(function(e) { $('#app-navigation ul a').click(function(e) {
e.preventDefault(); e.preventDefault();
radio.switch_menu(0); radio.action_navigate($(this).attr('href'));
}); });
$('a.nav-icon-recent').click(function(e) { /* Click on a radio station (table entry) and play it */
$('body').on('click', '.filename', function(e) {
e.preventDefault(); e.preventDefault();
radio.switch_menu(1); var entry_src = $(this).parent().attr('data-src');
if (entry_src.substring(0,9) == "#station/") {
var stationid = entry_src.substring(9);
var stationname = $(this).parent().find('.nametext').text();
radio.action_play(stationid, stationname);
} else {
radio.action_navigate(entry_src);
}
}); });
$('a.nav-icon-favorites').click(function(e) { /* Save station to favorites */
$('body').on('click', '.favorite', function(e) {
e.preventDefault(); e.preventDefault();
radio.switch_menu(2); var entry_src = $(this).parent().parent().attr('data-src');
var stationid = entry_src.substring(9);
radio.action_favorite(stationid);
}); });
$('a.nav-icon-systemtagsfilter').click(function(e) { radio.action_load_menu_state = function() {
e.preventDefault();
radio.switch_menu(3);
});
radio.load_menu_state = function() {
var menu_state = 0;
var baseUrl = OC.generateUrl('/apps/radio/getMenuState'); var baseUrl = OC.generateUrl('/apps/radio/getMenuState');
$.get(baseUrl, function ( data ) { $.get(baseUrl, function ( data ) {
if ("menu_state" in data) { if ("menu_state" in data) {
menu_state = data["menu_state"]; var hashurl = data["menu_state"];
} }
radio.switch_menu(menu_state); radio.action_navigate(hashurl);
return true; return true;
}); });
} }
radio.save_menu_state = function(menu_state) { radio.action_save_menu_state = function(hashurl) {
var baseUrl = OC.generateUrl('/apps/radio/saveMenuState'); var baseUrl = OC.generateUrl('/apps/radio/saveMenuState');
var settings = { var settings = {
"menu_state": menu_state "menu_state": hashurl
}; };
$.ajax({ $.ajax({
url: baseUrl, url: baseUrl,
@ -48,67 +53,50 @@ var MODULE = (function (radio) {
}); });
} }
radio.switch_menu = function(type) { radio.action_navigate = function(hashurl) {
var state = Number(type);
$('#filestable').hide(); $('#filestable').hide();
$('#emptycontent').addClass('hidden'); $('#emptycontent').addClass('hidden');
$('.nofilterresults').addClass('hidden'); $('.nofilterresults').addClass('hidden');
$('.loading').removeClass('hidden'); $('.loading').removeClass('hidden');
clearTimeout(searchTimeout);
searchTimeout = setTimeout(function(){
$('#app-navigation').find('li').removeClass("active"); $('#app-navigation').find('li').removeClass("active");
$("tbody > tr").remove(); $("tbody > tr").remove();
radio.save_menu_state(state)
switch (state) { history.pushState("", "", hashurl);
case 0: radio.action_save_menu_state(hashurl)
history.pushState("", "", "#top");
clearTimeout(radio.searchTimeout);
radio.searchTimeout = setTimeout(function(){
switch (hashurl) {
case "#top":
$('li.nav-files').addClass('active'); $('li.nav-files').addClass('active');
radio.radio_query(1); radio.radio_query(hashurl);
break; break;
case 1: case "#recent":
history.pushState("", "", "#recent");
$('li.nav-recent').addClass('active'); $('li.nav-recent').addClass('active');
radio.radio_query(2); radio.radio_query(hashurl);
break; break;
case 2: case "#favorites":
history.pushState("", "", "#favorites");
$('li.nav-favorites').addClass('active'); $('li.nav-favorites').addClass('active');
radio.action_load_favorites(); radio.action_load_favorites();
break; break;
case 3: case "#categories":
history.pushState("", "", "#categories");
$('li.nav-categories').addClass('active'); $('li.nav-categories').addClass('active');
radio.action_load_categories(); radio.action_load_categories();
break; break;
case (hashurl.match(/^#categories/) || {}).input:
$('li.nav-categories').addClass('active');
radio.radio_query(hashurl);
break;
} }
}, 500); }, 500);
}; };
// On app start, load top list // On app start, load top list
if(window.location.hash) { if(window.location.hash) {
var hash = String(window.location.hash.replace('#','')); var hashurl = window.location.hash;
switch(hash) { radio.action_navigate(hashurl);
case "top":
radio.switch_menu(0);
break;
case "recent":
radio.switch_menu(1);
break;
case "favorites":
radio.switch_menu(2);
break;
case "categories":
radio.switch_menu(3);
break;
default:
radio.switch_menu(0);
break;
}
} else { } else {
radio.load_menu_state(); radio.action_load_menu_state();
}; };
return radio; return radio;

View File

@ -35,7 +35,21 @@ var MODULE = (function (radio) {
}; };
}); });
radio.action_play = function(stationid){ radio.action_play = function(stationid, stationname){
$('#playbutton').attr("class", "buffering");
$('#player').attr('data-id',stationid);
$("#station_metadata").html("Playing: "+stationname);
/* dirty fix missing background color for first td */
$('tbody tr').css("background-color", "white");
$(this).parent().css("background-color", "#f8f8f8");
var element = document.getElementById('station_metadata');
if (radio.isElementOverflowing(element)) {
radio.wrapContentsInMarquee(element);
};
if (!radio.scheduled){
radio.schedule_get_metadata(stationid);
};
if (typeof radio.sound !== "undefined") { if (typeof radio.sound !== "undefined") {
var volume_state = $('#volumeslider').slider('value'); var volume_state = $('#volumeslider').slider('value');
radio.sound.fade(volume_state, 0, 500); radio.sound.fade(volume_state, 0, 500);

View File

@ -31,7 +31,6 @@
</li> </li>
</ul> </ul>
<div id="app-settings"> <div id="app-settings">
<audio id="player" src=""></audio>
<button id="playbutton" class="play"></button> <button id="playbutton" class="play"></button>
<div id="volumeicon" class="full"></div> <div id="volumeicon" class="full"></div>
<div id="volumeslider"></div> <div id="volumeslider"></div>