mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
rework collection editor
This commit is contained in:
parent
39d4daa2fb
commit
0e1c7cbb7a
21 changed files with 436 additions and 402 deletions
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.upload = function (file, mimeType, name, url) {
|
self.upload = function (file, name, url) {
|
||||||
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,12 @@
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteOfflineUser(id) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolve();
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
function getCameraPhotos() {
|
function getCameraPhotos() {
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
deferred.resolveWith(null, [[]]);
|
deferred.resolveWith(null, [[]]);
|
||||||
|
@ -24,6 +30,12 @@
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteOfflineActions(actions) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolveWith(null, [[]]);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
function getServerItemIds(serverId) {
|
function getServerItemIds(serverId) {
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
deferred.resolveWith(null, [[]]);
|
deferred.resolveWith(null, [[]]);
|
||||||
|
@ -86,8 +98,10 @@
|
||||||
window.LocalAssetManager = {
|
window.LocalAssetManager = {
|
||||||
getLocalMediaSource: getLocalMediaSource,
|
getLocalMediaSource: getLocalMediaSource,
|
||||||
saveOfflineUser: saveOfflineUser,
|
saveOfflineUser: saveOfflineUser,
|
||||||
|
deleteOfflineUser: deleteOfflineUser,
|
||||||
getCameraPhotos: getCameraPhotos,
|
getCameraPhotos: getCameraPhotos,
|
||||||
getOfflineActions: getOfflineActions,
|
getOfflineActions: getOfflineActions,
|
||||||
|
deleteOfflineActions: deleteOfflineActions,
|
||||||
getServerItemIds: getServerItemIds,
|
getServerItemIds: getServerItemIds,
|
||||||
removeLocalItem: removeLocalItem,
|
removeLocalItem: removeLocalItem,
|
||||||
getLocalItem: getLocalItem,
|
getLocalItem: getLocalItem,
|
||||||
|
|
|
@ -113,10 +113,7 @@
|
||||||
|
|
||||||
Logger.log('Uploading file to ' + url);
|
Logger.log('Uploading file to ' + url);
|
||||||
|
|
||||||
// TODO: Need to get this from cordova file api instead of trying to infer the content type from the path
|
new MediaBrowser.FileUpload().upload(file, name, url).done(function () {
|
||||||
var mimeType = file.toLowerCase().indexOf('mp4') != -1 || file.toLowerCase().indexOf('m4v') != -1 ? 'video/mp4' : (file.toLowerCase().indexOf('png') != -1 ? 'image/png' : 'image/jpg');
|
|
||||||
|
|
||||||
new MediaBrowser.FileUpload().upload(file, mimeType, name, url).done(function () {
|
|
||||||
|
|
||||||
Logger.log('File upload succeeded');
|
Logger.log('File upload succeeded');
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
|
|
@ -49,11 +49,15 @@
|
||||||
|
|
||||||
apiClient.reportOfflineActions(actions).done(function () {
|
apiClient.reportOfflineActions(actions).done(function () {
|
||||||
|
|
||||||
|
LocalAssetManager.deleteOfflineActions(actions).done(function () {
|
||||||
|
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
|
||||||
}).fail(getOnFail(deferred));
|
}).fail(getOnFail(deferred));
|
||||||
|
|
||||||
}).fail(getOnFail(deferred));
|
}).fail(getOnFail(deferred));
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
|
@ -235,9 +239,9 @@
|
||||||
|
|
||||||
Logger.log('Downloading media. Url: ' + url + '. Local path: ' + localPath);
|
Logger.log('Downloading media. Url: ' + url + '. Local path: ' + localPath);
|
||||||
|
|
||||||
localAssetManager.downloadFile(url, localPath).done(function () {
|
LocalAssetManager.downloadFile(url, localPath).done(function () {
|
||||||
|
|
||||||
localAssetManager.addOrUpdateLocalItem(localItem).done(function () {
|
LocalAssetManager.addOrUpdateLocalItem(localItem).done(function () {
|
||||||
|
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
|
||||||
|
@ -324,7 +328,7 @@
|
||||||
|
|
||||||
require(['localassetmanager'], function () {
|
require(['localassetmanager'], function () {
|
||||||
|
|
||||||
localAssetManager.hasImage(serverId, itemId, imageTag).done(function (hasImage) {
|
LocalAssetManager.hasImage(serverId, itemId, imageTag).done(function (hasImage) {
|
||||||
|
|
||||||
if (hasImage) {
|
if (hasImage) {
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
@ -336,7 +340,7 @@
|
||||||
ImageType: imageType
|
ImageType: imageType
|
||||||
});
|
});
|
||||||
|
|
||||||
localAssetManager.downloadImage(imageUrl, serverId, itemId, imageTag).done(function () {
|
LocalAssetManager.downloadImage(imageUrl, serverId, itemId, imageTag).done(function () {
|
||||||
|
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
|
||||||
|
@ -418,7 +422,7 @@
|
||||||
LocalAssetManager.downloadSubtitles(url, localItem, subtitleStream).done(function (subtitlePath) {
|
LocalAssetManager.downloadSubtitles(url, localItem, subtitleStream).done(function (subtitlePath) {
|
||||||
|
|
||||||
subtitleStream.Path = subtitlePath;
|
subtitleStream.Path = subtitlePath;
|
||||||
localAssetManager.addOrUpdateLocalItem(localItem).done(function () {
|
LocalAssetManager.addOrUpdateLocalItem(localItem).done(function () {
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
}).fail(getOnFail(deferred));
|
}).fail(getOnFail(deferred));
|
||||||
|
|
||||||
|
@ -479,7 +483,7 @@
|
||||||
else {
|
else {
|
||||||
|
|
||||||
localItem.UserIdsWithAccess = userIdsWithAccess;
|
localItem.UserIdsWithAccess = userIdsWithAccess;
|
||||||
localAssetManager.addOrUpdateLocalItem(localItem).done(function () {
|
LocalAssetManager.addOrUpdateLocalItem(localItem).done(function () {
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
}).fail(getOnFail(deferred));
|
}).fail(getOnFail(deferred));
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,17 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
}).fail(function () {
|
}).fail(function () {
|
||||||
deferred.reject();
|
|
||||||
|
// TODO: We should only delete if there's a 401 response
|
||||||
|
|
||||||
|
require(['localassetmanager'], function () {
|
||||||
|
|
||||||
|
LocalAssetManager.deleteOfflineUser(user.Id).done(function () {
|
||||||
|
deferred.resolve();
|
||||||
|
}).fail(function () {
|
||||||
|
deferred.resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
ApiClientBridge.init(AppInfo.appName, AppInfo.appVersion, AppInfo.deviceId, AppInfo.deviceName, JSON.stringify(capabilities));
|
ApiClientBridge.init(AppInfo.appName, AppInfo.appVersion, AppInfo.deviceId, AppInfo.deviceName, JSON.stringify(capabilities));
|
||||||
|
|
||||||
initAjax();
|
//initAjax();
|
||||||
}
|
}
|
||||||
|
|
||||||
var baseAjaxMethod;
|
var baseAjaxMethod;
|
||||||
|
|
21
dashboard-ui/cordova/fileupload.js
vendored
21
dashboard-ui/cordova/fileupload.js
vendored
|
@ -4,10 +4,18 @@
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.upload = function (file, mimeType, name, url) {
|
self.upload = function (path, name, url) {
|
||||||
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
resolveLocalFileSystemURL(path, function (fileEntry) {
|
||||||
|
|
||||||
|
fileEntry.file(function (file) {
|
||||||
|
|
||||||
|
var mimeType = file.type;
|
||||||
|
|
||||||
|
Logger.log('mimeType for file ' + path + ' is ' + file);
|
||||||
|
|
||||||
var onSuccess = function (r) {
|
var onSuccess = function (r) {
|
||||||
console.log("Code = " + r.responseCode);
|
console.log("Code = " + r.responseCode);
|
||||||
console.log("Response = " + r.response);
|
console.log("Response = " + r.response);
|
||||||
|
@ -31,6 +39,17 @@
|
||||||
|
|
||||||
new FileTransfer().upload(file, url, onSuccess, onFail, options);
|
new FileTransfer().upload(file, url, onSuccess, onFail, options);
|
||||||
|
|
||||||
|
}, function () {
|
||||||
|
Logger.log('File upload failed. fileEntry.file returned an error');
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
|
||||||
|
}, function () {
|
||||||
|
|
||||||
|
Logger.log('File upload failed. resolveLocalFileSystemURL returned an error');
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
7
dashboard-ui/cordova/ios/vlcplayer.js
vendored
7
dashboard-ui/cordova/ios/vlcplayer.js
vendored
|
@ -110,12 +110,13 @@
|
||||||
return self.playerState.volume;
|
return self.playerState.volume;
|
||||||
};
|
};
|
||||||
|
|
||||||
self.setCurrentSrc = function (val, item, mediaSource, tracks) {
|
self.setCurrentSrc = function (streamInfo, item, mediaSource, tracks) {
|
||||||
|
|
||||||
if (!val) {
|
if (!streamInfo) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var val = streamInfo.url;
|
||||||
var tIndex = val.indexOf('#t=');
|
var tIndex = val.indexOf('#t=');
|
||||||
var startPosMs = 0;
|
var startPosMs = 0;
|
||||||
|
|
||||||
|
@ -127,8 +128,6 @@
|
||||||
|
|
||||||
if (options.type == 'audio') {
|
if (options.type == 'audio') {
|
||||||
|
|
||||||
// TODO
|
|
||||||
|
|
||||||
//AndroidVlcPlayer.playAudioVlc(val, JSON.stringify(item), JSON.stringify(mediaSource), options.poster);
|
//AndroidVlcPlayer.playAudioVlc(val, JSON.stringify(item), JSON.stringify(mediaSource), options.poster);
|
||||||
var artist = item.ArtistItems && item.ArtistItems.length ? item.ArtistItems[0].Name : null;
|
var artist = item.ArtistItems && item.ArtistItems.length ? item.ArtistItems[0].Name : null;
|
||||||
window.audioplayer.playstream(successHandler, function () {
|
window.audioplayer.playstream(successHandler, function () {
|
||||||
|
|
312
dashboard-ui/cordova/localassetmanager.js
vendored
312
dashboard-ui/cordova/localassetmanager.js
vendored
|
@ -68,46 +68,300 @@
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var offlineUserDatabase;
|
||||||
|
function getOfflineUserdb(callback) {
|
||||||
|
|
||||||
|
if (offlineUserDatabase) {
|
||||||
|
callback(offlineUserDatabase);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create/open database
|
||||||
|
offlineUserDatabase = window.sqlitePlugin.openDatabase({ name: "offlineusers.db" });
|
||||||
|
|
||||||
|
offlineUserDatabase.transaction(function (tx) {
|
||||||
|
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS users (id text primary key, data text)');
|
||||||
|
tx.executeSql('create index if not exists idx_users on users(id)');
|
||||||
|
|
||||||
|
callback(offlineUserDatabase);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function saveOfflineUser(user) {
|
function saveOfflineUser(user) {
|
||||||
|
|
||||||
// TODO
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
getOfflineUserdb(function (db) {
|
||||||
|
|
||||||
|
db.transaction(function (tx) {
|
||||||
|
|
||||||
|
tx.executeSql("REPLACE INTO offlineusers (id, data) VALUES (?,?)", [user.Id, JSON.stringify(user)], function (tx, res) {
|
||||||
|
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
}, function (e) {
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteOfflineUser(id) {
|
||||||
|
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
getOfflineUserdb(function (db) {
|
||||||
|
|
||||||
|
db.transaction(function (tx) {
|
||||||
|
|
||||||
|
tx.executeSql("DELETE from offlineusers where id=?", [user.Id], function (tx, res) {
|
||||||
|
|
||||||
|
deferred.resolve();
|
||||||
|
}, function (e) {
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
var offlineActionsDatabase;
|
||||||
|
function getOfflineActionsDb(callback) {
|
||||||
|
|
||||||
|
if (offlineActionsDatabase) {
|
||||||
|
callback(offlineActionsDatabase);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create/open database
|
||||||
|
offlineActionsDatabase = window.sqlitePlugin.openDatabase({ name: "offlineactions.db" });
|
||||||
|
|
||||||
|
offlineActionsDatabase.transaction(function (tx) {
|
||||||
|
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS offlineactions (Id text primary key, ServerId text not null, Json text not null)');
|
||||||
|
tx.executeSql('create index if not exists idx_offlineactions on offlineactions(id)');
|
||||||
|
|
||||||
|
callback(offlineActionsDatabase);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getOfflineActions(serverId) {
|
function getOfflineActions(serverId) {
|
||||||
// TODO
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
deferred.resolveWith(null, [[]]);
|
|
||||||
|
getOfflineActionsDb(function (db) {
|
||||||
|
|
||||||
|
db.transaction(function (tx) {
|
||||||
|
|
||||||
|
tx.executeSql("SELECT json from offlineactions where ServerId=?", [serverId], function (tx, res) {
|
||||||
|
|
||||||
|
var actions = [];
|
||||||
|
for (var i = 0, length = res.rows.length; i < length; i++) {
|
||||||
|
actions.push(JSON.parse(res.rows.item(i).json));
|
||||||
|
}
|
||||||
|
|
||||||
|
deferred.resolveWith(null, [actions]);
|
||||||
|
|
||||||
|
}, function (e) {
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteOfflineActions(actions) {
|
||||||
|
|
||||||
|
var ids = actions.map(function (a) { return "'" + a.Id + "'"; }).join(',');
|
||||||
|
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
getOfflineActionsDb(function (db) {
|
||||||
|
|
||||||
|
db.transaction(function (tx) {
|
||||||
|
|
||||||
|
tx.executeSql("DELETE from offlineactions where Id in (" + ids + ")", [], function (tx, res) {
|
||||||
|
|
||||||
|
deferred.resolve();
|
||||||
|
|
||||||
|
}, function (e) {
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
var offlineItemsDatabase;
|
||||||
|
function getOfflineItemsDb(callback) {
|
||||||
|
|
||||||
|
if (offlineItemsDatabase) {
|
||||||
|
callback(offlineItemsDatabase);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create/open database
|
||||||
|
offlineItemsDatabase = window.sqlitePlugin.openDatabase({ name: "offlineitems.db" });
|
||||||
|
|
||||||
|
offlineItemsDatabase.transaction(function (tx) {
|
||||||
|
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS Items ( Id text primary key, ItemId text not null, ItemType text not null, MediaType text, ServerId text not null, LocalPath text not null, UserIdsWithAccess text, AlbumId text, AlbumName text, SeriesId text, SeriesName text, Json text not null)');
|
||||||
|
tx.executeSql('create index if not exists idx_items on Items(Id)');
|
||||||
|
|
||||||
|
tx.executeSql('CREATE TABLE IF NOT EXISTS AlbumArtists ( Id text not null, Name text not null, ItemId text not null)');
|
||||||
|
tx.executeSql('create index if not exists idx_AlbumArtists on AlbumArtists(id)');
|
||||||
|
|
||||||
|
callback(offlineItemsDatabase);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function getServerItemIds(serverId) {
|
function getServerItemIds(serverId) {
|
||||||
// TODO
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
deferred.resolveWith(null, [[]]);
|
|
||||||
return deferred.promise();
|
getOfflineItemsDb(function (db) {
|
||||||
|
|
||||||
|
db.transaction(function (tx) {
|
||||||
|
|
||||||
|
tx.executeSql("SELECT ItemId from Items where ServerId=?", [serverId], function (tx, res) {
|
||||||
|
|
||||||
|
var itemIds = [];
|
||||||
|
for (var i = 0, length = res.rows.length; i < length; i++) {
|
||||||
|
itemIds.push(res.rows.item(i).ItemId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeLocalItem(itemId, serverId) {
|
deferred.resolveWith(null, [itemIds]);
|
||||||
// TODO
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
}, function (e) {
|
||||||
deferred.resolveWith(null, []);
|
deferred.reject();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLocalItem(itemId, serverId) {
|
function getLocalItem(itemId, serverId) {
|
||||||
// TODO
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
deferred.resolveWith(null, []);
|
|
||||||
|
getOfflineItemsDb(function (db) {
|
||||||
|
|
||||||
|
db.transaction(function (tx) {
|
||||||
|
|
||||||
|
tx.executeSql("SELECT Json from Items where itemId=? AND serverId=?", [itemId, serverId], function (tx, res) {
|
||||||
|
|
||||||
|
if (res.rows.length) {
|
||||||
|
|
||||||
|
var localItem = JSON.parse(res.rows.item(0).Json);
|
||||||
|
|
||||||
|
deferred.resolveWith(null, [item]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deferred.resolveWith(null, [null]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}, function (e) {
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
function addOrUpdateLocalItem(localItem) {
|
function addOrUpdateLocalItem(item) {
|
||||||
// TODO
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
deferred.resolveWith(null, [null]);
|
|
||||||
|
getOfflineItemsDb(function (db) {
|
||||||
|
|
||||||
|
db.transaction(function (tx) {
|
||||||
|
|
||||||
|
var values = [item.Id, item.ItemId, item.Item.Type, item.Item.MediaType, item.ServerId, item.LocalPath, item.UserIdsWithAccess.join(','), item.Item.AlbumId, item.Item.AlbumName, item.Item.SeriesId, item.Item.SeriesName, JSON.stringify(item)];
|
||||||
|
tx.executeSql("REPLACE INTO Items (Id, ItemId, ItemType, MediaType, ServerId, LocalPath, UserIdsWithAccess, AlbumId, AlbumName, SeriesId, SeriesName, Json) VALUES (?,?,?,?,?,?,?,?,?,?,?,?)", values);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeLocalItem(itemId, serverId) {
|
||||||
|
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
getLocalItem(itemId, serverId).done(function (item) {
|
||||||
|
|
||||||
|
getOfflineItemsDb(function (db) {
|
||||||
|
|
||||||
|
db.transaction(function (tx) {
|
||||||
|
|
||||||
|
tx.executeSql("DELETE from Items where itemId=? AND serverId=?", [itemId, serverId]);
|
||||||
|
|
||||||
|
var files = item.AdditionalFiles || [];
|
||||||
|
files.push(item.LocalPath);
|
||||||
|
|
||||||
|
deleteFiles(files).done(function () {
|
||||||
|
|
||||||
|
deferred.resolve();
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteFiles(files) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deleteNextFile(files, 0, deferred);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteNextFile(files, index, deferred) {
|
||||||
|
|
||||||
|
if (index >= files.length) {
|
||||||
|
deferred.resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteFile(file).done(function () {
|
||||||
|
deleteNextFile(files, index + 1, deferred);
|
||||||
|
}).fail(function () {
|
||||||
|
deleteNextFile(files, index + 1, deferred);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function deleteFile(path) {
|
||||||
|
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
Logger.log('Deleting ' + path);
|
||||||
|
resolveLocalFileSystemURL(path, function (fileEntry) {
|
||||||
|
|
||||||
|
fileEntry.remove(function () {
|
||||||
|
Logger.log('Deleted ' + path);
|
||||||
|
deferred.resolve();
|
||||||
|
}, function () {
|
||||||
|
|
||||||
|
Logger.log('Error deleting ' + path);
|
||||||
|
deferred.reject();
|
||||||
|
});
|
||||||
|
|
||||||
|
}, function () {
|
||||||
|
|
||||||
|
Logger.log('Skipping deletion because file does not exist: ' + path);
|
||||||
|
deferred.resolve();
|
||||||
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,15 +376,15 @@
|
||||||
|
|
||||||
getFileSystem().done(function (fileSystem) {
|
getFileSystem().done(function (fileSystem) {
|
||||||
|
|
||||||
var localPath = fileSystem.root.toURL() + "/" + path.join('/');
|
var localPath = trimEnd(fileSystem.root.toURL()) + "/" + path.join('/');
|
||||||
|
|
||||||
item.LocalPath = localPath;
|
item.LocalPath = localPath;
|
||||||
|
|
||||||
for (var i = 0, length = libraryItem.MediaSources.length; i < length; i++) {
|
for (var i = 0, length = libraryItem.MediaSources.length; i < length; i++) {
|
||||||
|
|
||||||
var mediaSource = libraryItem.MediaSources[i];
|
var mediaSource = libraryItem.MediaSources[i];
|
||||||
mediaSource.setPath(localPath);
|
mediaSource.Path = localPath;
|
||||||
mediaSource.setProtocol(MediaProtocol.File);
|
mediaSource.Protocol = 'File';
|
||||||
}
|
}
|
||||||
|
|
||||||
item.ServerId = serverInfo.Id;
|
item.ServerId = serverInfo.Id;
|
||||||
|
@ -143,9 +397,23 @@
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDirectoryPath(item, serverInfo) {
|
function trimEnd(str) {
|
||||||
|
|
||||||
|
var charEnd = '/';
|
||||||
|
|
||||||
|
if (str.charAt(str.length - 1) == charEnd) {
|
||||||
|
|
||||||
|
str = str.substring(0, str.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDirectoryPath(item, server) {
|
||||||
|
|
||||||
var parts = [];
|
var parts = [];
|
||||||
|
parts.push("emby");
|
||||||
|
parts.push("sync");
|
||||||
parts.push(server.Name);
|
parts.push(server.Name);
|
||||||
|
|
||||||
if (item.Type == "Episode") {
|
if (item.Type == "Episode") {
|
||||||
|
@ -186,7 +454,7 @@
|
||||||
|
|
||||||
var filename = originalFileName || libraryItem.Name;
|
var filename = originalFileName || libraryItem.Name;
|
||||||
|
|
||||||
return fileRepository.getValidFileName(filename);
|
return getValidFileName(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getValidFileName(filename) {
|
function getValidFileName(filename) {
|
||||||
|
@ -306,7 +574,7 @@
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
getFileSystem().done(function (fileSystem) {
|
getFileSystem().done(function (fileSystem) {
|
||||||
var path = fileSystem.root.toURL() + "/emby/images/" + serverId + "/" + itemId + "/" + imageTag;
|
var path = trimEnd(fileSystem.root.toURL()) + "/emby/images/" + serverId + "/" + itemId + "/" + imageTag;
|
||||||
|
|
||||||
deferred.resolveWith(null, [path]);
|
deferred.resolveWith(null, [path]);
|
||||||
});
|
});
|
||||||
|
@ -357,8 +625,10 @@
|
||||||
window.LocalAssetManager = {
|
window.LocalAssetManager = {
|
||||||
getLocalMediaSource: getLocalMediaSource,
|
getLocalMediaSource: getLocalMediaSource,
|
||||||
saveOfflineUser: saveOfflineUser,
|
saveOfflineUser: saveOfflineUser,
|
||||||
|
deleteOfflineUser: deleteOfflineUser,
|
||||||
getCameraPhotos: getCameraPhotos,
|
getCameraPhotos: getCameraPhotos,
|
||||||
getOfflineActions: getOfflineActions,
|
getOfflineActions: getOfflineActions,
|
||||||
|
deleteOfflineActions: deleteOfflineActions,
|
||||||
getServerItemIds: getServerItemIds,
|
getServerItemIds: getServerItemIds,
|
||||||
removeLocalItem: removeLocalItem,
|
removeLocalItem: removeLocalItem,
|
||||||
getLocalItem: getLocalItem,
|
getLocalItem: getLocalItem,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<title>Emby</title>
|
<title>Emby</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="editItemMetadataPage" data-role="page" class="page libraryPage metadataEditorPage noSecondaryNavPage" data-contextname="${HeaderMetadataManager}" data-require="jqmcheckbox,jqmcollapsible,jqmlistview,jqmpopup,scripts/editorsidebar,scripts/edititemmetadata,scripts/edititemsubtitles,scripts/editcollectionitems,scripts/edititemimages">
|
<div id="editItemMetadataPage" data-role="page" class="page libraryPage metadataEditorPage noSecondaryNavPage" data-contextname="${HeaderMetadataManager}" data-require="jqmcheckbox,jqmcollapsible,jqmlistview,jqmpopup,scripts/editorsidebar,scripts/edititemmetadata,scripts/edititemsubtitles,scripts/edititemimages">
|
||||||
<div>
|
<div>
|
||||||
<div class="editPageSidebar" style="overflow:auto;">
|
<div class="editPageSidebar" style="overflow:auto;">
|
||||||
<div class="libraryTree">
|
<div class="libraryTree">
|
||||||
|
@ -17,7 +17,6 @@
|
||||||
<paper-tabs hidescrollbuttons>
|
<paper-tabs hidescrollbuttons>
|
||||||
<paper-tab class="metadataTabButton">${TabMetadata}</paper-tab>
|
<paper-tab class="metadataTabButton">${TabMetadata}</paper-tab>
|
||||||
<paper-tab class="subtitleTabButton hide">${TabSubtitles}</paper-tab>
|
<paper-tab class="subtitleTabButton hide">${TabSubtitles}</paper-tab>
|
||||||
<paper-tab class="collectionItemsTabButton hide">${TabCollectionTitles}</paper-tab>
|
|
||||||
<paper-tab class="imagesTabButton">${TabImages}</paper-tab>
|
<paper-tab class="imagesTabButton">${TabImages}</paper-tab>
|
||||||
</paper-tabs>
|
</paper-tabs>
|
||||||
|
|
||||||
|
@ -367,18 +366,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="editorTab collectionItemsTabContent">
|
|
||||||
<p style="margin:1.5em 0;">
|
|
||||||
${EditCollectionItemsHelp}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<button type="button" id="btnAddItem" data-icon="plus" data-inline="true" data-mini="true">${ButtonAdd}</button>
|
|
||||||
<button type="button" id="btnRemoveItems" data-icon="delete" data-inline="true" data-mini="true" disabled="disabled">${ButtonRemove}</button>
|
|
||||||
</div>
|
|
||||||
<br />
|
|
||||||
<div class="collectionItems"></div>
|
|
||||||
</div>
|
|
||||||
<div class="editorTab imageEditorTab">
|
<div class="editorTab imageEditorTab">
|
||||||
<div style="margin:2em 0 .5em;text-align:center;">
|
<div style="margin:2em 0 .5em;text-align:center;">
|
||||||
|
|
||||||
|
@ -568,41 +555,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div data-role="popup" class="popupIdentifyCollection popup popupIdentify" data-theme="a">
|
|
||||||
|
|
||||||
<div class="ui-bar-a" style="text-align: center; padding: 0 20px;">
|
|
||||||
<h3>
|
|
||||||
${HeaderAddTitles}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div data-role="content">
|
|
||||||
|
|
||||||
<form class="collectionItemSearchForm" style="max-width: initial;">
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="txtLookupName">${LabelName}</label>
|
|
||||||
|
|
||||||
<div style="display: inline-block; width: 75%;">
|
|
||||||
<input type="text" id="txtLookupName" required="required" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button type="submit" class="clearButton" style="width:auto;">
|
|
||||||
<paper-icon-button icon="search" title="${ButtonSearch}"></paper-icon-button>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="collectionItemSearchResults">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button id="btnAddItems" type="button" data-icon="plus" data-mini="true">
|
|
||||||
${ButtonAdd}
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div data-role="popup" id="popupUpload" data-theme="a">
|
<div data-role="popup" id="popupUpload" data-theme="a">
|
||||||
<form class="uploadItemImageForm" style="max-width: 100%; margin: 0 1.5em 1.5em;">
|
<form class="uploadItemImageForm" style="max-width: 100%; margin: 0 1.5em 1.5em;">
|
||||||
<h2>${HeaderAddUpdateImage}</h2>
|
<h2>${HeaderAddUpdateImage}</h2>
|
||||||
|
|
|
@ -214,7 +214,7 @@
|
||||||
|
|
||||||
var invalidTypes = ['Person', 'Genre', 'MusicGenre', 'Studio', 'GameGenre', 'BoxSet', 'Playlist', 'UserView', 'CollectionFolder', 'Audio', 'Episode'];
|
var invalidTypes = ['Person', 'Genre', 'MusicGenre', 'Studio', 'GameGenre', 'BoxSet', 'Playlist', 'UserView', 'CollectionFolder', 'Audio', 'Episode'];
|
||||||
|
|
||||||
return item.LocationType == 'FileSystem' && !item.CollectionType && invalidTypes.indexOf(item.Type) == -1 && item.MediaType != 'Photo';
|
return !item.CollectionType && invalidTypes.indexOf(item.Type) == -1 && item.MediaType != 'Photo';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,267 +0,0 @@
|
||||||
(function ($, document, window, FileReader, escape) {
|
|
||||||
|
|
||||||
var currentItem;
|
|
||||||
|
|
||||||
function reload(page) {
|
|
||||||
|
|
||||||
Dashboard.showLoadingMsg();
|
|
||||||
|
|
||||||
$('#btnRemoveItems', page).buttonEnabled(false);
|
|
||||||
|
|
||||||
MetadataEditor.getItemPromise().done(function (item) {
|
|
||||||
|
|
||||||
currentItem = item;
|
|
||||||
|
|
||||||
LibraryBrowser.renderName(item, $('.itemName', page), true);
|
|
||||||
|
|
||||||
reloadTitles(page, item);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function getTitleHtml(item) {
|
|
||||||
|
|
||||||
var html = '<div style="display:inline-block;margin:5px;vertical-align:top;">';
|
|
||||||
|
|
||||||
html += '<div style="width:120px;height:180px;">';
|
|
||||||
if (item.ImageTags.Primary) {
|
|
||||||
|
|
||||||
var imgUrl = ApiClient.getScaledImageUrl(item.Id, {
|
|
||||||
type: "Primary",
|
|
||||||
maxWidth: 120,
|
|
||||||
maxHeight: 180,
|
|
||||||
tag: item.ImageTags.Primary
|
|
||||||
});
|
|
||||||
|
|
||||||
html += '<img src="' + imgUrl + '" style="max-width:120px;max-height:180px;" />';
|
|
||||||
|
|
||||||
}
|
|
||||||
html += '</div>';
|
|
||||||
|
|
||||||
html += '<div style="text-align:center;margin-top:4px;max-width:100px;overflow:hidden;height: 32px;">' + item.Name + '</div>';
|
|
||||||
|
|
||||||
if (item.ParentId != currentItem.Id) {
|
|
||||||
html += '<label for="chkRemove' + item.Id + '">' + Globalize.translate("ButtonRemove") + '</label><input id="chkRemove' + item.Id + '" class="chkRemoveItem" type="checkbox" data-itemid="' + item.Id + '" data-mini="true" />';
|
|
||||||
}
|
|
||||||
|
|
||||||
html += '</div>';
|
|
||||||
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getSearchResultHtml(item) {
|
|
||||||
|
|
||||||
var html = '<div style="display:inline-block;margin:3px;vertical-align:top;">';
|
|
||||||
|
|
||||||
html += '<div style="width:100px;height:150px;">';
|
|
||||||
|
|
||||||
if (item.PrimaryImageTag) {
|
|
||||||
|
|
||||||
var imgUrl = ApiClient.getScaledImageUrl(item.ItemId, {
|
|
||||||
type: "Primary",
|
|
||||||
maxWidth: 100,
|
|
||||||
maxHeight: 150,
|
|
||||||
tag: item.PrimaryImageTag
|
|
||||||
});
|
|
||||||
|
|
||||||
html += '<img src="' + imgUrl + '" style="max-width:100px;max-height:150px;" />';
|
|
||||||
|
|
||||||
}
|
|
||||||
html += '</div>';
|
|
||||||
|
|
||||||
html += '<div style="text-align:center;margin-top:4px;max-width:100px;overflow:hidden;height: 32px;">' + item.Name + '</div>';
|
|
||||||
|
|
||||||
html += '<label for="chkAdd' + item.ItemId + '">' + Globalize.translate("ButtonAdd") + '</label><input id="chkAdd' + item.ItemId + '" class="chkAddItem" type="checkbox" data-itemid="' + item.ItemId + '" data-mini="true" />';
|
|
||||||
|
|
||||||
html += '</div>';
|
|
||||||
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
||||||
function reloadTitles(page, item) {
|
|
||||||
|
|
||||||
ApiClient.getItems(Dashboard.getCurrentUserId(), {
|
|
||||||
|
|
||||||
ParentId: item.Id
|
|
||||||
|
|
||||||
}).done(function (result) {
|
|
||||||
|
|
||||||
// Scroll back up so they can see the results from the beginning
|
|
||||||
window.scrollTo(0, 0);
|
|
||||||
|
|
||||||
var html = result.Items.map(getTitleHtml).join('');
|
|
||||||
|
|
||||||
var elem = $('.collectionItems', page).html(html).trigger('create');
|
|
||||||
|
|
||||||
$('.chkRemoveItem', elem).on('change', function () {
|
|
||||||
|
|
||||||
if ($('.chkRemoveItem:checked', elem).length) {
|
|
||||||
$('#btnRemoveItems', page).buttonEnabled(true);
|
|
||||||
} else {
|
|
||||||
$('#btnRemoveItems', page).buttonEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
Dashboard.hideLoadingMsg();
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function showSearchResults(page, searchTerm) {
|
|
||||||
|
|
||||||
ApiClient.getSearchHints({
|
|
||||||
|
|
||||||
userId: Dashboard.getCurrentUserId(),
|
|
||||||
searchTerm: searchTerm,
|
|
||||||
limit: 30,
|
|
||||||
|
|
||||||
includePeople: false,
|
|
||||||
includeGenres: false,
|
|
||||||
includeStudios: false,
|
|
||||||
includeArtists: false,
|
|
||||||
|
|
||||||
IncludeItemTypes: "Movie,Series,Game,MusicAlbum,Book"
|
|
||||||
|
|
||||||
}).done(function (result) {
|
|
||||||
|
|
||||||
renderSearchResults(page, result.SearchHints);
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderSearchResults(page, items) {
|
|
||||||
|
|
||||||
var existingIds = $('.chkRemoveItem', page).get().map(function (c) {
|
|
||||||
return c.getAttribute('data-itemid');
|
|
||||||
});
|
|
||||||
|
|
||||||
var html = items.filter(function (i) {
|
|
||||||
|
|
||||||
return existingIds.indexOf(i.ItemId) == -1;
|
|
||||||
|
|
||||||
}).map(getSearchResultHtml).join('');
|
|
||||||
|
|
||||||
var elem = $('.collectionItemSearchResults', page).html(html).trigger('create');
|
|
||||||
|
|
||||||
$('.chkAddItem', elem).on('change', function () {
|
|
||||||
|
|
||||||
if ($('.chkAddItem:checked', elem).length) {
|
|
||||||
$('#btnAddItems', page).buttonEnabled(true);
|
|
||||||
} else {
|
|
||||||
$('#btnAddItems', page).buttonEnabled(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function addItemsToCollection(page) {
|
|
||||||
|
|
||||||
var items = $('.chkAddItem:checked', page).get().map(function (c) {
|
|
||||||
|
|
||||||
return c.getAttribute('data-itemid');
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!items.length) {
|
|
||||||
Dashboard.alert(Globalize.translate("MessagePleaseSelectOneItem"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = ApiClient.getUrl("Collections/" + currentItem.Id + "/Items", {
|
|
||||||
|
|
||||||
Ids: items.join(',')
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
ApiClient.ajax({
|
|
||||||
type: "POST",
|
|
||||||
url: url
|
|
||||||
|
|
||||||
}).done(function () {
|
|
||||||
|
|
||||||
Dashboard.hideLoadingMsg();
|
|
||||||
|
|
||||||
$('.popupIdentifyCollection', page).popup('close');
|
|
||||||
|
|
||||||
reload(page);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeItemsFromCollection(page) {
|
|
||||||
var items = $('.chkRemoveItem:checked', page).get().map(function (c) {
|
|
||||||
|
|
||||||
return c.getAttribute('data-itemid');
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!items.length) {
|
|
||||||
Dashboard.alert(Globalize.translate("MessagePleaseSelectOneItem"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var url = ApiClient.getUrl("Collections/" + currentItem.Id + "/Items", {
|
|
||||||
|
|
||||||
Ids: items.join(',')
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
ApiClient.ajax({
|
|
||||||
type: "DELETE",
|
|
||||||
url: url
|
|
||||||
|
|
||||||
}).done(function () {
|
|
||||||
|
|
||||||
Dashboard.hideLoadingMsg();
|
|
||||||
|
|
||||||
reload(page);
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSearchFormSubmit() {
|
|
||||||
var page = $(this).parents('.page');
|
|
||||||
|
|
||||||
showSearchResults(page, $('#txtLookupName', this).val());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).on('pageinit', "#editItemMetadataPage", function () {
|
|
||||||
|
|
||||||
var page = this;
|
|
||||||
|
|
||||||
$('#btnAddItem', page).on('click', function () {
|
|
||||||
|
|
||||||
|
|
||||||
var popup = $('.popupIdentifyCollection', page).popup('open');
|
|
||||||
|
|
||||||
$('#txtLookupName', popup).val('');
|
|
||||||
$('.collectionItemSearchResults', popup).empty();
|
|
||||||
$('#btnAddItems', popup).buttonEnabled(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#btnAddItems', page).on('click', function () {
|
|
||||||
|
|
||||||
addItemsToCollection(page);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#btnRemoveItems', page).on('click', function () {
|
|
||||||
|
|
||||||
|
|
||||||
removeItemsFromCollection(page);
|
|
||||||
});
|
|
||||||
|
|
||||||
$('.collectionItemSearchForm').off('submit', onSearchFormSubmit).on('submit', onSearchFormSubmit);
|
|
||||||
|
|
||||||
$(page.querySelector('paper-tabs')).on('tabchange', function () {
|
|
||||||
|
|
||||||
if (parseInt(this.selected) == 2) {
|
|
||||||
var tabContent = page.querySelector('.collectionItemsTabContent');
|
|
||||||
|
|
||||||
reload(tabContent);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
})(jQuery, document, window, window.FileReader, escape);
|
|
|
@ -566,7 +566,7 @@
|
||||||
|
|
||||||
$(page.querySelector('paper-tabs')).on('tabchange', function () {
|
$(page.querySelector('paper-tabs')).on('tabchange', function () {
|
||||||
|
|
||||||
if (parseInt(this.selected) == 3) {
|
if (parseInt(this.selected) == 2) {
|
||||||
var tabContent = page.querySelector('.imageEditorTab');
|
var tabContent = page.querySelector('.imageEditorTab');
|
||||||
|
|
||||||
reload(tabContent);
|
reload(tabContent);
|
||||||
|
|
|
@ -46,12 +46,6 @@
|
||||||
setFieldVisibilities(page, item);
|
setFieldVisibilities(page, item);
|
||||||
fillItemInfo(page, item, metadataEditorInfo.ParentalRatingOptions);
|
fillItemInfo(page, item, metadataEditorInfo.ParentalRatingOptions);
|
||||||
|
|
||||||
if (item.Type == "BoxSet") {
|
|
||||||
page.querySelector('.collectionItemsTabButton').classList.remove('hide');
|
|
||||||
} else {
|
|
||||||
page.querySelector('.collectionItemsTabButton').classList.add('hide');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.MediaType == "Video" && item.LocationType == "FileSystem" && item.Type !== 'TvChannel') {
|
if (item.MediaType == "Video" && item.LocationType == "FileSystem" && item.Type !== 'TvChannel') {
|
||||||
page.querySelector('.subtitleTabButton').classList.remove('hide');
|
page.querySelector('.subtitleTabButton').classList.remove('hide');
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -90,7 +90,6 @@ if (!Array.prototype.filter) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: There should be notification services, where each defines what it supports and the best service is chosen based on params
|
|
||||||
var WebNotifications = {
|
var WebNotifications = {
|
||||||
|
|
||||||
show: function (data) {
|
show: function (data) {
|
||||||
|
|
|
@ -893,7 +893,7 @@
|
||||||
{ name: Globalize.translate('HeaderBooks'), type: 'Book' }
|
{ name: Globalize.translate('HeaderBooks'), type: 'Book' }
|
||||||
];
|
];
|
||||||
|
|
||||||
renderCollectionItems(page, collectionItemTypes, result.Items, user, context);
|
renderCollectionItems(page, item, collectionItemTypes, result.Items, user, context);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -947,7 +947,10 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderCollectionItems(page, types, items, user) {
|
function renderCollectionItems(page, parentItem, types, items, user) {
|
||||||
|
|
||||||
|
// First empty out existing content
|
||||||
|
page.querySelector('.collectionItems').innerHTML = '';
|
||||||
|
|
||||||
for (var i = 0, length = types.length; i < length; i++) {
|
for (var i = 0, length = types.length; i < length; i++) {
|
||||||
|
|
||||||
|
@ -960,7 +963,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
if (typeItems.length) {
|
if (typeItems.length) {
|
||||||
renderCollectionItemType(page, type, typeItems, user);
|
renderCollectionItemType(page, parentItem, type, typeItems, user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -977,17 +980,17 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
if (otherTypeItems.length) {
|
if (otherTypeItems.length) {
|
||||||
renderCollectionItemType(page, otherType, otherTypeItems, user);
|
renderCollectionItemType(page, parentItem, otherType, otherTypeItems, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!items.length) {
|
if (!items.length) {
|
||||||
renderCollectionItemType(page, { name: Globalize.translate('HeaderItems') }, items, user);
|
renderCollectionItemType(page, parentItem, { name: Globalize.translate('HeaderItems') }, items, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
$('.collectionItems', page).createCardMenus();
|
$('.collectionItems', page).createCardMenus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderCollectionItemType(page, type, items, user, context) {
|
function renderCollectionItemType(page, parentItem, type, items, user, context) {
|
||||||
|
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
|
@ -996,10 +999,6 @@
|
||||||
html += '<h1>';
|
html += '<h1>';
|
||||||
html += '<span>' + type.name + '</span>';
|
html += '<span>' + type.name + '</span>';
|
||||||
|
|
||||||
if (user.Policy.IsAdministrator) {
|
|
||||||
html += '<a class="detailSectionHeaderButton clearLink" style="margin-top:-8px;display:inline-block;" href="edititemmetadata.html?tab=2&id=' + currentItem.Id + '" title="' + Globalize.translate('ButtonEdit') + '" style="display:none;"><paper-icon-button icon="mode-edit"></paper-icon-button></a>';
|
|
||||||
}
|
|
||||||
|
|
||||||
html += '</h1>';
|
html += '</h1>';
|
||||||
|
|
||||||
html += '<div class="detailSectionContent">';
|
html += '<div class="detailSectionContent">';
|
||||||
|
@ -1013,7 +1012,10 @@
|
||||||
centerText: true,
|
centerText: true,
|
||||||
context: context,
|
context: context,
|
||||||
lazy: true,
|
lazy: true,
|
||||||
showDetailsMenu: true
|
showDetailsMenu: true,
|
||||||
|
overlayMoreButton: true,
|
||||||
|
showAddToCollection: false,
|
||||||
|
showRemoveFromCollection: true
|
||||||
});
|
});
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
|
@ -1022,6 +1024,31 @@
|
||||||
var collectionItems = page.querySelector('.collectionItems');
|
var collectionItems = page.querySelector('.collectionItems');
|
||||||
$(collectionItems).append(html);
|
$(collectionItems).append(html);
|
||||||
ImageLoader.lazyChildren(collectionItems);
|
ImageLoader.lazyChildren(collectionItems);
|
||||||
|
|
||||||
|
$(collectionItems).off('removefromcollection').on('removefromcollection', function (e, itemId) {
|
||||||
|
|
||||||
|
removeFromCollection(page, parentItem, [itemId], user, context);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeFromCollection(page, parentItem, itemIds, user, context) {
|
||||||
|
|
||||||
|
Dashboard.showLoadingMsg();
|
||||||
|
|
||||||
|
var url = ApiClient.getUrl("Collections/" + parentItem.Id + "/Items", {
|
||||||
|
|
||||||
|
Ids: itemIds.join(',')
|
||||||
|
});
|
||||||
|
|
||||||
|
ApiClient.ajax({
|
||||||
|
type: "DELETE",
|
||||||
|
url: url
|
||||||
|
|
||||||
|
}).done(function () {
|
||||||
|
|
||||||
|
renderChildren(page, parentItem, user, context);
|
||||||
|
Dashboard.hideLoadingMsg();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderUserDataIcons(page, item) {
|
function renderUserDataIcons(page, item) {
|
||||||
|
|
|
@ -1375,9 +1375,15 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options.showAddToCollection !== false) {
|
||||||
if (BoxSetEditor.supportsAddingToCollection(item)) {
|
if (BoxSetEditor.supportsAddingToCollection(item)) {
|
||||||
itemCommands.push('addtocollection');
|
itemCommands.push('addtocollection');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.showRemoveFromCollection) {
|
||||||
|
itemCommands.push('removefromcollection');
|
||||||
|
}
|
||||||
|
|
||||||
if (options.playFromHere) {
|
if (options.playFromHere) {
|
||||||
itemCommands.push('playfromhere');
|
itemCommands.push('playfromhere');
|
||||||
|
|
|
@ -327,6 +327,14 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (commands.indexOf('removefromcollection') != -1) {
|
||||||
|
items.push({
|
||||||
|
name: Globalize.translate('ButtonRemoveFromCollection'),
|
||||||
|
id: 'removefromcollection',
|
||||||
|
ironIcon: 'remove'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (commands.indexOf('removefromplaylist') != -1) {
|
if (commands.indexOf('removefromplaylist') != -1) {
|
||||||
items.push({
|
items.push({
|
||||||
name: Globalize.translate('ButtonRemoveFromPlaylist'),
|
name: Globalize.translate('ButtonRemoveFromPlaylist'),
|
||||||
|
@ -476,6 +484,9 @@
|
||||||
case 'removefromplaylist':
|
case 'removefromplaylist':
|
||||||
$(card).parents('.itemsContainer').trigger('removefromplaylist', [playlistItemId]);
|
$(card).parents('.itemsContainer').trigger('removefromplaylist', [playlistItemId]);
|
||||||
break;
|
break;
|
||||||
|
case 'removefromcollection':
|
||||||
|
$(card).parents('.collectionItems').trigger('removefromcollection', [itemId]);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -860,7 +860,6 @@
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Need to verify the host is going to be reachable
|
|
||||||
return mediaSource.Path.toLowerCase().replace('https:', 'http').indexOf(ApiClient.serverAddress().toLowerCase().replace('https:', 'http').substring(0, 14)) == 0;
|
return mediaSource.Path.toLowerCase().replace('https:', 'http').indexOf(ApiClient.serverAddress().toLowerCase().replace('https:', 'http').substring(0, 14)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// TODO: Deprecated in 1.9
|
|
||||||
$.support.cors = true;
|
$.support.cors = true;
|
||||||
|
|
||||||
$(document).one('click', WebNotifications.requestPermission);
|
$(document).one('click', WebNotifications.requestPermission);
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
"ButtonDonate": "Donate",
|
"ButtonDonate": "Donate",
|
||||||
"LabelRecurringDonationCanBeCancelledHelp": "Recurring donations can be cancelled at any time from within your PayPal account.",
|
"LabelRecurringDonationCanBeCancelledHelp": "Recurring donations can be cancelled at any time from within your PayPal account.",
|
||||||
"HeaderMyMedia": "My Media",
|
"HeaderMyMedia": "My Media",
|
||||||
|
"ButtonRemoveFromCollection": "Remove from Collection",
|
||||||
"LabelAutomaticUpdateLevel": "Automatic update level:",
|
"LabelAutomaticUpdateLevel": "Automatic update level:",
|
||||||
"LabelAutomaticUpdateLevelForPlugins": "Automatic update level for plugins:",
|
"LabelAutomaticUpdateLevelForPlugins": "Automatic update level for plugins:",
|
||||||
"TitleNotifications": "Notifications",
|
"TitleNotifications": "Notifications",
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue