Implemented music search from web panel
This commit is contained in:
parent
f3d725c890
commit
decadee00a
6 changed files with 607 additions and 136 deletions
|
@ -20,6 +20,43 @@ header {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.modal {
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
z-index: 999;
|
||||
background-color: rgba(10,10,10,0.85);
|
||||
font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
}
|
||||
|
||||
.modal-container {
|
||||
margin: 5% auto auto auto;
|
||||
width: 70%;
|
||||
background: white;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
border-bottom: 1px solid #ccc;
|
||||
margin: 0.5rem auto;
|
||||
padding: 0.5rem;
|
||||
text-align: center;
|
||||
background-color: #f0f0f0;
|
||||
border-radius: 10px 10px 0 0;
|
||||
text-transform: uppercase;
|
||||
font-weight: 400px;
|
||||
letter-spacing: .1rem;
|
||||
line-height: 38px;
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: 2.5rem 2rem 1.5rem 2rem;
|
||||
}
|
||||
|
||||
#date-time {
|
||||
text-align: right;
|
||||
padding-right: 30px;
|
||||
|
@ -56,138 +93,10 @@ button[disabled] {
|
|||
border: 1px solid;
|
||||
}
|
||||
|
||||
.playback-controls {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #e8eaf0;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.playback-controls * > button.enabled {
|
||||
color: #59df3e;
|
||||
}
|
||||
|
||||
.button[disabled] {
|
||||
background: rgba(240,240,240,1)
|
||||
}
|
||||
|
||||
.track-info {
|
||||
text-align: center;
|
||||
margin: -20px -20px 0 -20px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.track-info > .artist {
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#player-left-side {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
#player-right-side {
|
||||
margin-left: 0;
|
||||
width: 78%;
|
||||
}
|
||||
|
||||
#playlist-controls, #browser-controls {
|
||||
margin-bottom: 7.5px;
|
||||
padding-bottom: 7.5px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
height: 3.8rem;
|
||||
}
|
||||
|
||||
#playlist-controls {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#playlist-content, #music-browser {
|
||||
height: 27.2rem;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
#music-browser {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#browser-filter {
|
||||
width: 95%;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
#playlist-filter-container {
|
||||
height: 5rem;
|
||||
}
|
||||
|
||||
#playlist-filter {
|
||||
width: 100%;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.music-pane {
|
||||
height: 40rem;
|
||||
padding: 15px 15px 0 5px;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.music-item {
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.music-item.selected {
|
||||
background-color: #c8ffd0 !important;
|
||||
}
|
||||
|
||||
.music-item:hover {
|
||||
background-color: #daf8e2 !important;
|
||||
}
|
||||
|
||||
.music-item:nth-child(odd) {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
.playlist-track.active {
|
||||
height: 4rem;
|
||||
padding-top: 1.5rem;
|
||||
font-size: 1.7rem;
|
||||
border-radius: 10px;
|
||||
animation: active-track 5s;
|
||||
-moz-animation: active-track 5s infinite;
|
||||
-webkit-animation: active-track 5s infinite;
|
||||
}
|
||||
|
||||
@keyframes active-track {
|
||||
0% { background: #d4ffe3; }
|
||||
50% { background: #9cdfb0; }
|
||||
100% { background: #d4ffe3; }
|
||||
}
|
||||
|
||||
@-moz-keyframes active-track {
|
||||
0% { background: #d4ffe3; }
|
||||
50% { background: #9cdfb0; }
|
||||
100% { background: #d4ffe3; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes active-track {
|
||||
0% { background: #d4ffe3; }
|
||||
50% { background: #9cdfb0; }
|
||||
100% { background: #d4ffe3; }
|
||||
}
|
||||
|
||||
.playlist-track > .track-time {
|
||||
text-align: right;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#track-seeker-container {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#volume-ctrl-container {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.slider {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
|
@ -226,3 +135,12 @@ button[disabled] {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #d8ffe0 !important;
|
||||
border: 1px solid #98efb0 !important;
|
||||
}
|
||||
|
||||
.right-side {
|
||||
text-align: right !important;
|
||||
}
|
||||
|
||||
|
|
173
platypush/backend/http/static/css/music.mpd.css
Normal file
173
platypush/backend/http/static/css/music.mpd.css
Normal file
|
@ -0,0 +1,173 @@
|
|||
#player-left-side {
|
||||
overflow-y: hidden;
|
||||
}
|
||||
|
||||
#player-right-side {
|
||||
margin-left: 0;
|
||||
width: 78%;
|
||||
}
|
||||
|
||||
.playback-controls {
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #e8eaf0;
|
||||
padding-bottom: 12px;
|
||||
}
|
||||
|
||||
.playback-controls * > button.enabled {
|
||||
color: #59df3e;
|
||||
}
|
||||
|
||||
|
||||
.track-info {
|
||||
text-align: center;
|
||||
margin: -20px -20px 0 -20px;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
.track-info > .artist {
|
||||
font-weight: bold;
|
||||
display: block;
|
||||
}
|
||||
|
||||
#playlist-controls, #browser-controls {
|
||||
margin-bottom: 7.5px;
|
||||
padding-bottom: 7.5px;
|
||||
border-bottom: 1px solid #ddd;
|
||||
height: 3.8rem;
|
||||
}
|
||||
|
||||
#playlist-controls {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#playlist-content, #music-browser {
|
||||
height: 27.2rem;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
#music-browser {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
#browser-filter {
|
||||
width: 95%;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
#playlist-filter-container {
|
||||
height: 5rem;
|
||||
}
|
||||
|
||||
#playlist-filter {
|
||||
width: 100%;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.music-pane {
|
||||
height: 40rem;
|
||||
padding: 15px 15px 0 5px;
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.music-item {
|
||||
padding: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.music-item.selected {
|
||||
background-color: #c8ffd0 !important;
|
||||
}
|
||||
|
||||
.music-item:hover {
|
||||
background-color: #daf8e2 !important;
|
||||
}
|
||||
|
||||
.music-item:nth-child(odd) {
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
.playlist-track.active {
|
||||
height: 4rem;
|
||||
padding-top: 1.5rem;
|
||||
font-size: 1.7rem;
|
||||
border-radius: 10px;
|
||||
animation: active-track 5s;
|
||||
-moz-animation: active-track 5s infinite;
|
||||
-webkit-animation: active-track 5s infinite;
|
||||
}
|
||||
|
||||
@keyframes active-track {
|
||||
0% { background: #d4ffe3; }
|
||||
50% { background: #9cdfb0; }
|
||||
100% { background: #d4ffe3; }
|
||||
}
|
||||
|
||||
@-moz-keyframes active-track {
|
||||
0% { background: #d4ffe3; }
|
||||
50% { background: #9cdfb0; }
|
||||
100% { background: #d4ffe3; }
|
||||
}
|
||||
|
||||
@-webkit-keyframes active-track {
|
||||
0% { background: #d4ffe3; }
|
||||
50% { background: #9cdfb0; }
|
||||
100% { background: #d4ffe3; }
|
||||
}
|
||||
|
||||
.playlist-track > .track-time {
|
||||
text-align: right;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
#track-seeker-container {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
#volume-ctrl-container {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
#music-search-form {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
#music-search-form * > input[type=text] {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#music-search-form > .row {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.music-form-bottom {
|
||||
text-align: right;
|
||||
margin-top: 2rem;
|
||||
border-top: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.music-form-bottom input {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
#music-search-results-form {
|
||||
display: none;
|
||||
margin-top: -2rem;
|
||||
}
|
||||
|
||||
#music-search-results-container {
|
||||
display: none;
|
||||
max-height: 50rem;
|
||||
margin-top: -1.4rem;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
#music-search-results-head {
|
||||
padding: 0.5rem 1rem;
|
||||
background-color: #eaeaea;
|
||||
border-radius: 5px 5px 0 0;
|
||||
border-bottom: 1px solid #bbb;
|
||||
letter-spacing: .1rem;
|
||||
line-height: 3.5rem;
|
||||
}
|
||||
|
|
@ -144,10 +144,32 @@ $(document).ready(function() {
|
|||
});
|
||||
};
|
||||
|
||||
var initModalOpenBindings = function() {
|
||||
$('body').on('click touch', '[data-modal]', function(event) {
|
||||
var $source = $(event.target);
|
||||
var $modal = $($source.data('modal'));
|
||||
$modal.fadeIn();
|
||||
});
|
||||
};
|
||||
|
||||
var initModalCloseBindings = function() {
|
||||
$('body').on('click touch', '[data-dismiss-modal]', function(event) {
|
||||
var $source = $(event.target);
|
||||
var $modal = $($source.data('dismiss-modal'));
|
||||
$modal.fadeOut();
|
||||
});
|
||||
};
|
||||
|
||||
var initModals = function() {
|
||||
initModalOpenBindings();
|
||||
initModalCloseBindings();
|
||||
};
|
||||
|
||||
var init = function() {
|
||||
initWebsocket();
|
||||
initElements();
|
||||
initDateTime();
|
||||
initModals();
|
||||
};
|
||||
|
||||
window.registerEventListener = registerEventListener;
|
||||
|
|
|
@ -6,7 +6,16 @@ $(document).ready(function() {
|
|||
curTrackElapsed = {
|
||||
timestamp: null,
|
||||
elapsed: null,
|
||||
};
|
||||
},
|
||||
|
||||
$musicSearchForm = $('#music-search-form'),
|
||||
$musicSearchResults = $('#music-search-results'),
|
||||
$musicSearchResultsContainer = $('#music-search-results-container'),
|
||||
$musicSearchResultsForm = $('#music-search-results-form'),
|
||||
$musicResultsAddBtn = $('#music-results-add'),
|
||||
$musicResultsPlayBtn = $('#music-results-play'),
|
||||
$resetSearchBtn = $('#music-search-reset');
|
||||
$doSearchBtns = $('.do-search-btns');
|
||||
|
||||
var execute = function(request, onSuccess, onError, onComplete) {
|
||||
request['target'] = 'localhost';
|
||||
|
@ -39,6 +48,24 @@ $(document).ready(function() {
|
|||
});
|
||||
};
|
||||
|
||||
var formatMinutes = function(time) {
|
||||
if (typeof time === 'string') {
|
||||
time = parseInt(time);
|
||||
} else if (isNaN(time)) {
|
||||
console.warn('Unexpected non-numeric value in formatMinutes');
|
||||
console.log(time);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!time) {
|
||||
return '-:--';
|
||||
}
|
||||
|
||||
var minutes = parseInt(time/60);
|
||||
var seconds = time%60;
|
||||
return (minutes < 10 ? '0' : '') + minutes + ':' + (seconds < 10 ? '0' : '') + seconds;
|
||||
};
|
||||
|
||||
var updateControls = function(status, track) {
|
||||
var $playbackControls = $('.playback-controls');
|
||||
var $playlistContent = $('#playlist-content');
|
||||
|
@ -80,7 +107,7 @@ $(document).ready(function() {
|
|||
$curTrack.find('.track').hide();
|
||||
$curTrack.find('.no-track').show();
|
||||
|
||||
$trackSeeker.attr('disabled', true);
|
||||
$trackSeeker.prop('disabled', true);
|
||||
$('.seek-time').text('-:--');
|
||||
break;
|
||||
|
||||
|
@ -91,7 +118,7 @@ $(document).ready(function() {
|
|||
$curTrack.find('.track').show();
|
||||
$curTrack.find('.no-track').hide();
|
||||
|
||||
$trackSeeker.removeAttr('disabled');
|
||||
$trackSeeker.prop('disabled', false);
|
||||
$('#seek-time-elapsed').text(elapsed ? elapsed : '-:--');
|
||||
$('#seek-time-length').text(length ? length : '-:--');
|
||||
break;
|
||||
|
@ -103,7 +130,7 @@ $(document).ready(function() {
|
|||
$curTrack.find('.track').show();
|
||||
$curTrack.find('.no-track').hide();
|
||||
|
||||
$trackSeeker.removeAttr('disabled');
|
||||
$trackSeeker.prop('disabled', false);
|
||||
$('#seek-time-elapsed').text(elapsed ? elapsed : '-:--');
|
||||
$('#seek-time-length').text(length ? length : '-:--');
|
||||
|
||||
|
@ -424,9 +451,9 @@ $(document).ready(function() {
|
|||
|
||||
$parentElement.on('click touch', onDirectorySelect);
|
||||
$parentElement.appendTo($browserContent);
|
||||
$addButton.removeAttr('disabled');
|
||||
$addButton.prop('disabled', false);
|
||||
} else {
|
||||
$addButton.attr('disabled', 'disabled');
|
||||
$addButton.prop('disabled', true);
|
||||
}
|
||||
|
||||
for (var directory of directories.sort()) {
|
||||
|
@ -506,7 +533,7 @@ $(document).ready(function() {
|
|||
$playbackControls.on('click', function(evt) {
|
||||
var action = $(this).data('action');
|
||||
var $btn = $(this);
|
||||
$btn.attr('disabled', true);
|
||||
$btn.prop('disabled', true);
|
||||
|
||||
execute(
|
||||
{
|
||||
|
@ -520,7 +547,7 @@ $(document).ready(function() {
|
|||
|
||||
onError=undefined,
|
||||
onComplete = function() {
|
||||
$btn.removeAttr('disabled');
|
||||
$btn.prop('disabled', false);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
@ -618,10 +645,237 @@ $(document).ready(function() {
|
|||
});
|
||||
};
|
||||
|
||||
var initSearch = function() {
|
||||
$musicSearchForm.on('submit', function(event) {
|
||||
var searchData = $(this).serializeArray().reduce(function(obj, item) {
|
||||
var value = item.value.trim();
|
||||
if (value.length > 0) {
|
||||
obj[item.name] = item.value;
|
||||
}
|
||||
|
||||
return obj;
|
||||
}, {});
|
||||
|
||||
var args = {};
|
||||
var searchFilters = {};
|
||||
|
||||
if ('any' in searchData) {
|
||||
args = {
|
||||
type: 'any',
|
||||
filter: searchData.any
|
||||
};
|
||||
|
||||
searchFilters.any = searchData.any;
|
||||
} else {
|
||||
if ('albumartist' in searchData) {
|
||||
args = {
|
||||
type: 'albumartist',
|
||||
filter: searchData.albumartist
|
||||
};
|
||||
|
||||
searchFilters.albumartist = searchData.albumartist;
|
||||
}
|
||||
|
||||
if ('album' in searchData) {
|
||||
args = {
|
||||
type: 'album',
|
||||
filter: searchData.album
|
||||
};
|
||||
|
||||
searchFilters.album = searchData.album;
|
||||
}
|
||||
|
||||
if ('title' in searchData) {
|
||||
args = {
|
||||
type: 'title',
|
||||
filter: searchData.title
|
||||
};
|
||||
|
||||
searchFilters.title = searchData.title;
|
||||
}
|
||||
}
|
||||
|
||||
$(this).find('input').prop('disabled', true);
|
||||
|
||||
execute(
|
||||
{
|
||||
type: 'request',
|
||||
action: 'music.mpd.search',
|
||||
args: args
|
||||
},
|
||||
|
||||
onSuccess = function(response) {
|
||||
var results = response.response.output;
|
||||
if (!results) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Object.keys(searchFilters).length > 1) {
|
||||
results = results.filter(function(item) {
|
||||
return (
|
||||
('title' in searchFilters && 'title' in item
|
||||
? item.title.toLowerCase().indexOf(
|
||||
searchFilters.title.toLowerCase()) >= 0 : true) &&
|
||||
('album' in searchFilters && 'album' in item
|
||||
? item.album.toLowerCase().indexOf(
|
||||
searchFilters.album.toLowerCase()) >= 0 : true) &&
|
||||
('albumartist' in searchFilters && 'artist' in item
|
||||
? item.artist.toLowerCase().indexOf(
|
||||
searchFilters.albumartist.toLowerCase()) >= 0 : true)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
for (var item of results) {
|
||||
var $item = $('<div></div>')
|
||||
.addClass('row').addClass('music-item')
|
||||
.addClass('music-search-item')
|
||||
.data('file', item.file);
|
||||
|
||||
var $artist = $('<div></div>')
|
||||
.addClass('three columns').addClass('artist')
|
||||
.addClass('music-search-item-artist')
|
||||
|
||||
if ('artist' in item) {
|
||||
$artist.text(item.artist);
|
||||
} else {
|
||||
$artist.html(' ');
|
||||
}
|
||||
|
||||
var $title = $('<div></div>')
|
||||
.addClass('four columns').addClass('title')
|
||||
.addClass('music-search-item-title');
|
||||
|
||||
if ('title' in item) {
|
||||
$title.text(item.title);
|
||||
} else {
|
||||
$title.html(' ');
|
||||
}
|
||||
|
||||
var $album = $('<div></div>')
|
||||
.addClass('four columns').addClass('album')
|
||||
.addClass('music-search-item-album');
|
||||
|
||||
if ('album' in item) {
|
||||
$album.text(item.album);
|
||||
} else {
|
||||
$album.html(' ');
|
||||
}
|
||||
|
||||
var $time = $('<div></div>')
|
||||
.addClass('one column').addClass('time')
|
||||
.addClass('music-search-item-time')
|
||||
.text('time' in item ? formatMinutes(item.time) : '-:--');
|
||||
|
||||
$artist.appendTo($item);
|
||||
$title.appendTo($item);
|
||||
$album.appendTo($item);
|
||||
$time.appendTo($item);
|
||||
$item.appendTo($musicSearchResults);
|
||||
}
|
||||
},
|
||||
|
||||
onError = function(xhr, status, error) {
|
||||
console.error(error);
|
||||
},
|
||||
|
||||
onComplete = function() {
|
||||
$musicSearchForm.find('input').prop('disabled', false);
|
||||
$musicSearchForm.hide();
|
||||
$musicSearchResultsContainer.show();
|
||||
$musicSearchResultsForm.show();
|
||||
}
|
||||
);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
$resetSearchBtn.on('click', function(event) {
|
||||
$musicSearchResultsForm.hide();
|
||||
$musicSearchResultsContainer.hide();
|
||||
$musicSearchResults.html('');
|
||||
$musicSearchForm.show();
|
||||
|
||||
$musicResultsAddBtn.removeData('file');
|
||||
$musicResultsAddBtn.prop('disabled', true);
|
||||
$musicResultsPlayBtn.removeData('file');
|
||||
$musicResultsPlayBtn.prop('disabled', true);
|
||||
});
|
||||
|
||||
$musicSearchResults.on('click', '.music-search-item', function(event) {
|
||||
var isCurrentlySelected = $(this).hasClass('selected');
|
||||
$('.music-search-item').removeClass('selected');
|
||||
|
||||
if (isCurrentlySelected) {
|
||||
$musicResultsAddBtn.removeData('file');
|
||||
$musicResultsAddBtn.prop('disabled', true);
|
||||
$musicResultsPlayBtn.removeData('file');
|
||||
$musicResultsPlayBtn.prop('disabled', true);
|
||||
|
||||
$(this).removeClass('selected');
|
||||
} else {
|
||||
var file = $(this).data('file');
|
||||
|
||||
$musicResultsAddBtn.data('file', file);
|
||||
$musicResultsAddBtn.prop('disabled', false);
|
||||
$musicResultsPlayBtn.data('file', file);
|
||||
$musicResultsPlayBtn.prop('disabled', false);
|
||||
$(this).addClass('selected');
|
||||
}
|
||||
});
|
||||
|
||||
$musicSearchResultsForm.on('submit', function(event) {
|
||||
return false;
|
||||
});
|
||||
|
||||
$musicResultsAddBtn.on('click', function(event) {
|
||||
var file = $(this).data('file');
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
execute(
|
||||
{
|
||||
type: 'request',
|
||||
action: 'music.mpd.add',
|
||||
args: {
|
||||
resource: file
|
||||
}
|
||||
},
|
||||
|
||||
onSuccess = function(response) {
|
||||
initPlaylist();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
$musicResultsPlayBtn.on('click', function(event) {
|
||||
var file = $(this).data('file');
|
||||
if (!file) {
|
||||
return false;
|
||||
}
|
||||
|
||||
execute(
|
||||
{
|
||||
type: 'request',
|
||||
action: 'music.mpd.play',
|
||||
args: {
|
||||
resource: file
|
||||
}
|
||||
},
|
||||
|
||||
onSuccess = function(response) {
|
||||
initPlaylist();
|
||||
}
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
var init = function() {
|
||||
initStatus();
|
||||
initPlaylist();
|
||||
initBrowser();
|
||||
initSearch();
|
||||
initBindings();
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,90 @@
|
|||
<script type="text/javascript" src="{{ url_for('static', filename='js/music.mpd.js') }}"></script>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/music.mpd.css') }}"></script>
|
||||
|
||||
<div id="music-search-modal" class="modal">
|
||||
<div class="modal-container">
|
||||
<div class="modal-header">
|
||||
Search For Music
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
<form id="music-search-form" action="#">
|
||||
<div class="row form-row">
|
||||
<div class="two columns">
|
||||
<label for="music-search-any">Any</label>
|
||||
</div>
|
||||
<div class="ten columns">
|
||||
<input type="text" name="any">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-row">
|
||||
<div class="two columns">
|
||||
<label for="music-search-artist">Artist</label>
|
||||
</div>
|
||||
<div class="ten columns">
|
||||
<input type="text" name="albumartist">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-row">
|
||||
<div class="two columns">
|
||||
<label for="music-search-title">Title</label>
|
||||
</div>
|
||||
<div class="ten columns">
|
||||
<input type="text" name="title">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row form-row">
|
||||
<div class="two columns">
|
||||
<label for="music-search-album">Album</label>
|
||||
</div>
|
||||
<div class="ten columns">
|
||||
<input type="text" name="album">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row music-form-bottom">
|
||||
<div class="six columns offset-by-six do-search-btns">
|
||||
<input type="button" class="btn-default" data-dismiss-modal="#music-search-modal"
|
||||
value="Close">
|
||||
<input type="submit" class="btn-primary" value="Search">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form class="row" id="music-search-results-form">
|
||||
<div class="six columns">
|
||||
<button class="btn-default" id="music-results-add" disabled="disabled">
|
||||
<i class="fa fa-plus"></i>
|
||||
</button>
|
||||
<button class="btn-default" id="music-results-play" disabled="disabled">
|
||||
<i class="fa fa-play"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="six columns right-side">
|
||||
<input type="button" class="btn-default"
|
||||
data-dismiss-modal="#music-search-modal" value="Close">
|
||||
<input type="button" class="btn-primary"
|
||||
id="music-search-reset" value="Reset">
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="music-search-results-container" class="row">
|
||||
<div id="music-search-results-head" class="row">
|
||||
<div class="three columns">Artist</div>
|
||||
<div class="four columns">Title</div>
|
||||
<div class="four columns">Album</div>
|
||||
<div class="one column">Time</div>
|
||||
</div>
|
||||
|
||||
<div id="music-search-results" class="row"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row track-info">
|
||||
<span class="no-track">No media is being played</span>
|
||||
|
@ -63,6 +149,9 @@
|
|||
<button data-action="add">
|
||||
<i class="fa fa-plus"></i>
|
||||
</button>
|
||||
<button data-action="search" data-modal="#music-search-modal">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div id="browser-filter-container">
|
||||
|
|
|
@ -121,6 +121,21 @@ class MusicMpdPlugin(MusicPlugin):
|
|||
def plchanges(self, version):
|
||||
return Response(output=self.client.plchanges(version))
|
||||
|
||||
def find(self, type, filter, *args, **kwargs):
|
||||
return Response(
|
||||
output=self.client.find(type, filter, *args, **kwargs))
|
||||
|
||||
def findadd(self, type, filter, *args, **kwargs):
|
||||
return Response(
|
||||
output=self.client.findadd(type, filter, *args, **kwargs))
|
||||
|
||||
def search(self, type, filter, *args, **kwargs):
|
||||
return Response(
|
||||
output=self.client.search(type, filter, *args, **kwargs))
|
||||
|
||||
def searchadd(self, type, filter, *args, **kwargs):
|
||||
return Response(
|
||||
output=self.client.searchadd(type, filter, *args, **kwargs))
|
||||
|
||||
# vim:sw=4:ts=4:et:
|
||||
|
||||
|
|
Loading…
Reference in a new issue