tag editing: support per track mode and access keys
This commit is contained in:
parent
2b3aff220f
commit
7d0ac9dfd4
3 changed files with 162 additions and 44 deletions
|
|
@ -1691,27 +1691,72 @@ function onDeleteContextMenu() {
|
|||
return false;
|
||||
}
|
||||
var editTagsTrackKeys = null;
|
||||
var editTagsTrackIndex = null;
|
||||
function onEditTagsContextMenu() {
|
||||
if (!permissions.admin) return false;
|
||||
removeContextMenu();
|
||||
editTagsTrackKeys = selection.toTrackKeys();
|
||||
editTagsTrackIndex = 0;
|
||||
showEditTags();
|
||||
return false;
|
||||
}
|
||||
var EDITABLE_PROPS = {
|
||||
name: 'string',
|
||||
artistName: 'string',
|
||||
albumArtistName: 'string',
|
||||
albumName: 'string',
|
||||
compilation: 'boolean',
|
||||
track: 'integer',
|
||||
trackCount: 'integer',
|
||||
disc: 'integer',
|
||||
discCount: 'integer',
|
||||
year: 'integer',
|
||||
genre: 'string',
|
||||
composerName: 'string',
|
||||
performerName: 'string',
|
||||
name: {
|
||||
type: 'string',
|
||||
write: true,
|
||||
},
|
||||
artistName: {
|
||||
type: 'string',
|
||||
write: true,
|
||||
},
|
||||
albumArtistName: {
|
||||
type: 'string',
|
||||
write: true,
|
||||
},
|
||||
albumName: {
|
||||
type: 'string',
|
||||
write: true,
|
||||
},
|
||||
compilation: {
|
||||
type: 'boolean',
|
||||
write: true,
|
||||
},
|
||||
track: {
|
||||
type: 'integer',
|
||||
write: true,
|
||||
},
|
||||
trackCount: {
|
||||
type: 'integer',
|
||||
write: true,
|
||||
},
|
||||
disc: {
|
||||
type: 'integer',
|
||||
write: true,
|
||||
},
|
||||
discCount: {
|
||||
type: 'integer',
|
||||
write: true,
|
||||
},
|
||||
year: {
|
||||
type: 'integer',
|
||||
write: true,
|
||||
},
|
||||
genre: {
|
||||
type: 'string',
|
||||
write: true,
|
||||
},
|
||||
composerName: {
|
||||
type: 'string',
|
||||
write: true,
|
||||
},
|
||||
performerName: {
|
||||
type: 'string',
|
||||
write: true,
|
||||
},
|
||||
file: {
|
||||
type: 'string',
|
||||
write: false,
|
||||
},
|
||||
};
|
||||
var EDIT_TAG_TYPES = {
|
||||
'string': {
|
||||
|
|
@ -1741,27 +1786,34 @@ var EDIT_TAG_TYPES = {
|
|||
},
|
||||
},
|
||||
};
|
||||
function showEditTags() {
|
||||
$editTagsDialog.dialog({
|
||||
modal: true,
|
||||
title: "Edit Tags",
|
||||
minWidth: 800,
|
||||
height: $document.height() - 40,
|
||||
});
|
||||
var perDom = document.getElementById('edit-tags-per');
|
||||
var perLabelDom = document.getElementById('edit-tags-per-label');
|
||||
var prevDom = document.getElementById('edit-tags-prev');
|
||||
var nextDom = document.getElementById('edit-tags-next');
|
||||
function updateEditTagsUi() {
|
||||
var multiple = editTagsTrackKeys.length > 1;
|
||||
prevDom.disabled = !perDom.checked || editTagsTrackIndex === 0;
|
||||
nextDom.disabled = !perDom.checked || (editTagsTrackIndex === editTagsTrackKeys.length - 1);
|
||||
prevDom.style.visibility = multiple ? 'visible' : 'hidden';
|
||||
nextDom.style.visibility = multiple ? 'visible' : 'hidden';
|
||||
perLabelDom.style.visibility = multiple ? 'visible' : 'hidden';
|
||||
var multiCheckBoxVisible = multiple && !perDom.checked;
|
||||
var trackKeysToUse = perDom.checked ? [editTagsTrackKeys[editTagsTrackIndex]] : editTagsTrackKeys;
|
||||
|
||||
for (var propName in EDITABLE_PROPS) {
|
||||
var type = EDITABLE_PROPS[propName];
|
||||
var propInfo = EDITABLE_PROPS[propName];
|
||||
var type = propInfo.type;
|
||||
var setter = EDIT_TAG_TYPES[type].set;
|
||||
var domItem = document.getElementById('edit-tag-' + propName);
|
||||
domItem.disabled = !propInfo.write;
|
||||
var multiCheckBoxDom = document.getElementById('edit-tag-multi-' + propName);
|
||||
multiCheckBoxDom.style.visibility = (multiCheckBoxVisible && propInfo.write) ? 'visible' : 'hidden';
|
||||
var commonValue = null;
|
||||
var consistent = true;
|
||||
for (var i = 0; i < editTagsTrackKeys.length; i += 1) {
|
||||
var key = editTagsTrackKeys[i];
|
||||
for (var i = 0; i < trackKeysToUse.length; i += 1) {
|
||||
var key = trackKeysToUse[i];
|
||||
var track = player.library.trackTable[key];
|
||||
var value = track[propName];
|
||||
if (propName === 'genre') {
|
||||
console.log("genre", JSON.stringify(value));
|
||||
}
|
||||
if (commonValue == null) {
|
||||
commonValue = value;
|
||||
} else if (commonValue !== value) {
|
||||
|
|
@ -1773,7 +1825,18 @@ function showEditTags() {
|
|||
setter(domItem, consistent ? commonValue : null);
|
||||
}
|
||||
}
|
||||
function showEditTags() {
|
||||
$editTagsDialog.dialog({
|
||||
modal: true,
|
||||
title: "Edit Tags",
|
||||
minWidth: 800,
|
||||
height: $document.height() - 40,
|
||||
});
|
||||
perDom.checked = false;
|
||||
updateEditTagsUi();
|
||||
}
|
||||
|
||||
var editTagsFocusDom = document.getElementById('edit-tag-name');
|
||||
function setUpEditTagsUi() {
|
||||
$editTagsDialog.find("input").on("keydown", function(event) {
|
||||
event.stopPropagation();
|
||||
|
|
@ -1783,25 +1846,68 @@ function setUpEditTagsUi() {
|
|||
onTagsOk();
|
||||
}
|
||||
});
|
||||
$("#edit-tags-ok").on('click', onTagsOk);
|
||||
for (var propName in EDITABLE_PROPS) {
|
||||
var domItem = document.getElementById('edit-tag-' + propName);
|
||||
var multiCheckBoxDom = document.getElementById('edit-tag-multi-' + propName);
|
||||
var listener = createChangeListener(multiCheckBoxDom);
|
||||
domItem.addEventListener('change', listener, false);
|
||||
domItem.addEventListener('keypress', listener, false);
|
||||
domItem.addEventListener('focus', onFocus, false);
|
||||
}
|
||||
|
||||
function onTagsOk() {
|
||||
function onFocus(event) {
|
||||
editTagsFocusDom = event.target;
|
||||
}
|
||||
|
||||
function createChangeListener(multiCheckBoxDom) {
|
||||
return function() {
|
||||
multiCheckBoxDom.checked = true;
|
||||
};
|
||||
}
|
||||
$("#edit-tags-ok").on('click', onTagsOk);
|
||||
perDom.addEventListener('click', updateEditTagsUi, false);
|
||||
nextDom.addEventListener('click', saveAndNext, false);
|
||||
prevDom.addEventListener('click', saveAndPrev, false);
|
||||
|
||||
function saveAndMoveOn(dir) {
|
||||
save();
|
||||
editTagsTrackIndex += dir;
|
||||
updateEditTagsUi();
|
||||
editTagsFocusDom.focus();
|
||||
editTagsFocusDom.select();
|
||||
}
|
||||
|
||||
function saveAndNext() {
|
||||
saveAndMoveOn(1);
|
||||
}
|
||||
|
||||
function saveAndPrev() {
|
||||
saveAndMoveOn(-1);
|
||||
}
|
||||
|
||||
function save() {
|
||||
var trackKeysToUse = perDom.checked ? [editTagsTrackKeys[editTagsTrackIndex]] : editTagsTrackKeys;
|
||||
var cmd = {};
|
||||
for (var i = 0; i < editTagsTrackKeys.length; i += 1) {
|
||||
var key = editTagsTrackKeys[i];
|
||||
for (var i = 0; i < trackKeysToUse.length; i += 1) {
|
||||
var key = trackKeysToUse[i];
|
||||
var track = player.library.trackTable[key];
|
||||
var props = cmd[track.key] = {};
|
||||
for (var propName in EDITABLE_PROPS) {
|
||||
var type = EDITABLE_PROPS[propName];
|
||||
var propInfo = EDITABLE_PROPS[propName];
|
||||
var type = propInfo.type;
|
||||
var getter = EDIT_TAG_TYPES[type].get;
|
||||
var domItem = document.getElementById('edit-tag-' + propName);
|
||||
var multiCheckBoxDom = document.getElementById('edit-tag-multi-' + propName);
|
||||
if (multiCheckBoxDom.checked) {
|
||||
if (multiCheckBoxDom.checked && propInfo.write) {
|
||||
props[propName] = getter(domItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
player.sendCommand('updateTags', cmd);
|
||||
}
|
||||
|
||||
function onTagsOk() {
|
||||
save();
|
||||
$editTagsDialog.dialog('close');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -306,3 +306,6 @@ body
|
|||
font-size .9em
|
||||
li:before
|
||||
content "\2713"
|
||||
|
||||
.accesskey
|
||||
text-decoration: underline
|
||||
|
|
|
|||
|
|
@ -291,48 +291,57 @@
|
|||
</div>
|
||||
<div id="edit-tags" style="display: none">
|
||||
<input type="checkbox" id="edit-tag-multi-name">
|
||||
<label>Title: <input id="edit-tag-name"></label><br>
|
||||
<label accesskey="i">T<span class="accesskey">i</span>tle: <input id="edit-tag-name"></label><br>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-track">
|
||||
<label>Track Number: <input id="edit-tag-track"></label><br>
|
||||
<label accesskey="k">Trac<span class="accesskey">k</span> Number: <input id="edit-tag-track"></label><br>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-file">
|
||||
<label>Filename: <input id="edit-tag-file"></label><br>
|
||||
<hr>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-artistName">
|
||||
<label>Artist: <input id="edit-tag-artistName"></label><br>
|
||||
<label accesskey="a"><span class="accesskey">A</span>rtist: <input id="edit-tag-artistName"></label><br>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-composerName">
|
||||
<label>Composer: <input id="edit-tag-composerName"></label><br>
|
||||
<label accesskey="c"><span class="accesskey">C</span>omposer: <input id="edit-tag-composerName"></label><br>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-performerName">
|
||||
<label>Performer: <input id="edit-tag-performerName"></label><br>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-genre">
|
||||
<label>Genre: <input id="edit-tag-genre"></label><br>
|
||||
<label accesskey="g"><span class="accesskey">G</span>enre: <input id="edit-tag-genre"></label><br>
|
||||
<hr>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-albumName">
|
||||
<label>Album: <input id="edit-tag-albumName"></label><br>
|
||||
<label accesskey="b">Al<span class="accesskey">b</span>um: <input id="edit-tag-albumName"></label><br>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-albumArtistName">
|
||||
<label>Album Artist: <input id="edit-tag-albumArtistName"></label><br>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-trackCount">
|
||||
<label>Track Count: <input id="edit-tag-trackCount"</label><br>
|
||||
<label>Track Count: <input id="edit-tag-trackCount"></label><br>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-year">
|
||||
<label>Year: <input id="edit-tag-year"</label><br>
|
||||
<label accesskey="y"><span class="accesskey">Y</span>ear: <input id="edit-tag-year"></label><br>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-disc">
|
||||
<label>Disc Number: <input id="edit-tag-disc"</label><br>
|
||||
<label accesskey="d"><span class="accesskey">D</span>isc Number: <input id="edit-tag-disc"></label><br>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-discCount">
|
||||
<label>Disc Count: <input id="edit-tag-discCount"</label><br>
|
||||
<label>Disc Count: <input id="edit-tag-discCount"></label><br>
|
||||
|
||||
<input type="checkbox" id="edit-tag-multi-compilation">
|
||||
<label>Compilation: <input type="checkbox" id="edit-tag-compilation"></label><br>
|
||||
<label accesskey="m">Co<span class="accesskey">m</span>pilation: <input type="checkbox" id="edit-tag-compilation"></label><br>
|
||||
<hr>
|
||||
|
||||
<input id="edit-tags-ok" type="button" value="OK">
|
||||
<div style="float: right">
|
||||
<button id="edit-tags-ok" accesskey="v">Sa<span class="accesskey">v</span>e & Close</button>
|
||||
<button id="edit-tags-cancel">Cancel</button>
|
||||
</div>
|
||||
<button id="edit-tags-prev" type="button" accesskey="p"><span class="accesskey">P</span>revious</button>
|
||||
<button id="edit-tags-next" type="button" accesskey="n"><span class="accesskey">N</span>ext</button>
|
||||
<label accesskey="r" id="edit-tags-per-label"><input id="edit-tags-per" type="checkbox">Pe<span class="accesskey">r</span> Track</label>
|
||||
</div>
|
||||
<ul id="menu-playlist" style="display: none">
|
||||
<li><a href="#" class="remove">Remove</a></li>
|
||||
|
|
|
|||
Loading…
Reference in a new issue