mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
update client sync
This commit is contained in:
parent
c13fc2c4cc
commit
3c190041f2
10 changed files with 347 additions and 48 deletions
|
@ -3449,6 +3449,56 @@
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
self.reportOfflineActions = function (actions) {
|
||||||
|
|
||||||
|
if (!actions) {
|
||||||
|
throw new Error("null actions");
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = self.getUrl("Sync/OfflineActions");
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "POST",
|
||||||
|
data: JSON.stringify(actions),
|
||||||
|
contentType: "application/json",
|
||||||
|
url: url
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.syncData = function (data) {
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
throw new Error("null data");
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = self.getUrl("Sync/Data");
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "POST",
|
||||||
|
data: JSON.stringify(data),
|
||||||
|
contentType: "application/json",
|
||||||
|
url: url,
|
||||||
|
dataType: "json"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
self.getReadySyncItems = function (deviceId) {
|
||||||
|
|
||||||
|
if (!deviceId) {
|
||||||
|
throw new Error("null deviceId");
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = self.getUrl("Sync/Items/Ready", {
|
||||||
|
TargetId: deviceId
|
||||||
|
});
|
||||||
|
|
||||||
|
return self.ajax({
|
||||||
|
type: "GET",
|
||||||
|
url: url,
|
||||||
|
dataType: "json"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reports a user has stopped playing an item
|
* Reports a user has stopped playing an item
|
||||||
* @param {String} userId
|
* @param {String} userId
|
||||||
|
|
|
@ -16,10 +16,45 @@
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getOfflineActions(serverId) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolveWith(null, [[]]);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getServerItemIds(serverId) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolveWith(null, [[]]);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeLocalItem(itemId, serverId) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolveWith(null, []);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocalItem(itemId, serverId) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolveWith(null, []);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addOrUpdateLocalItem(localItem) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolveWith(null, []);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
window.LocalAssetManager = {
|
window.LocalAssetManager = {
|
||||||
getLocalMediaSource: getLocalMediaSource,
|
getLocalMediaSource: getLocalMediaSource,
|
||||||
saveOfflineUser: saveOfflineUser,
|
saveOfflineUser: saveOfflineUser,
|
||||||
getCameraPhotos: getCameraPhotos
|
getCameraPhotos: getCameraPhotos,
|
||||||
|
getOfflineActions: getOfflineActions,
|
||||||
|
getServerItemIds: getServerItemIds,
|
||||||
|
removeLocalItem: removeLocalItem,
|
||||||
|
getLocalItem: getLocalItem,
|
||||||
|
addOrUpdateLocalItem: addOrUpdateLocalItem
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
|
@ -4,20 +4,20 @@
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.sync = function (apiClient) {
|
self.sync = function (apiClient, serverInfo) {
|
||||||
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
reportOfflineActions(apiClient).done(function () {
|
reportOfflineActions(apiClient, serverInfo).done(function () {
|
||||||
|
|
||||||
// Do the first data sync
|
// Do the first data sync
|
||||||
syncData(apiClient, false).done(function () {
|
syncData(apiClient, serverInfo, false).done(function () {
|
||||||
|
|
||||||
// Download new content
|
// Download new content
|
||||||
getNewMedia(apiClient).done(function () {
|
getNewMedia(apiClient).done(function () {
|
||||||
|
|
||||||
// Do the second data sync
|
// Do the second data sync
|
||||||
syncData(apiClient, false).done(function () {
|
syncData(apiClient, serverInfo, false).done(function () {
|
||||||
|
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
|
||||||
|
@ -32,29 +32,227 @@
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
};
|
};
|
||||||
|
|
||||||
function reportOfflineActions(apiClient) {
|
function reportOfflineActions(apiClient, serverInfo) {
|
||||||
|
|
||||||
|
Logger.log('Begin reportOfflineActions');
|
||||||
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
deferred.resolve();
|
require(['localassetmanager'], function () {
|
||||||
|
|
||||||
|
LocalAssetManager.getOfflineActions(serverInfo.Id).done(function (actions) {
|
||||||
|
|
||||||
|
if (!actions.length) {
|
||||||
|
deferred.resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
apiClient.reportOfflineActions(actions).done(function () {
|
||||||
|
|
||||||
|
deferred.resolve();
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
function syncData(apiClient, syncUserItemAccess) {
|
function syncData(apiClient, serverInfo, syncUserItemAccess) {
|
||||||
|
|
||||||
|
Logger.log('Begin syncData');
|
||||||
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
require(['localassetmanager'], function () {
|
||||||
|
|
||||||
|
LocalAssetManager.getServerItemIds(serverInfo.Id).done(function (localIds) {
|
||||||
|
|
||||||
|
var request = {
|
||||||
|
TargetId: apiClient.deviceId(),
|
||||||
|
LocalItemIds: localIds,
|
||||||
|
OfflineUserIds: (serverInfo.Users || []).map(function (u) { return u.Id; })
|
||||||
|
};
|
||||||
|
|
||||||
|
apiClient.syncData(request).done(function (result) {
|
||||||
|
|
||||||
|
afterSyncData(apiClient, serverInfo, syncUserItemAccess, result, deferred);
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
});
|
||||||
|
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function afterSyncData(apiClient, serverInfo, enableSyncUserItemAccess, syncDataResult, deferred) {
|
||||||
|
|
||||||
|
Logger.log('Begin afterSyncData');
|
||||||
|
|
||||||
|
removeLocalItems(syncDataResult, serverInfo.Id).done(function (result) {
|
||||||
|
|
||||||
|
if (enableSyncUserItemAccess) {
|
||||||
|
syncUserItemAccess(syncDataResult, serverInfo.Id).done(function () {
|
||||||
|
|
||||||
|
deferred.resolve();
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeLocalItems(syncDataResult, serverId) {
|
||||||
|
|
||||||
|
Logger.log('Begin removeLocalItems');
|
||||||
|
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
removeNextLocalItem(syncDataResult.ItemIdsToRemove, 0, serverId, deferred);
|
||||||
|
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeNextLocalItem(itemIdsToRemove, index, serverId, deferred) {
|
||||||
|
|
||||||
|
var length = itemIdsToRemove.length;
|
||||||
|
|
||||||
|
if (index >= length) {
|
||||||
|
|
||||||
|
deferred.resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeLocalItem(itemIdsToRemove[index], serverId).done(function () {
|
||||||
|
|
||||||
|
removeNextLocalItem(itemIdsToRemove, index + 1, serverId, deferred);
|
||||||
|
}).fail(function () {
|
||||||
|
removeNextLocalItem(itemIdsToRemove, index + 1, serverId, deferred);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeLocalItem(itemId, serverId) {
|
||||||
|
|
||||||
|
Logger.log('Begin removeLocalItem');
|
||||||
|
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
require(['localassetmanager'], function () {
|
||||||
|
|
||||||
|
LocalAssetManager.removeLocalItem(itemId, serverId).done(function (localIds) {
|
||||||
|
|
||||||
|
deferred.resolve();
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNewMedia(apiClient) {
|
function getNewMedia(apiClient) {
|
||||||
|
|
||||||
|
Logger.log('Begin getNewMedia');
|
||||||
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
apiClient.getReadySyncItems(apiClient.deviceId()).done(function (jobItems) {
|
||||||
|
|
||||||
|
getNextNewItem(jobItems, 0, apiClient, deferred);
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNextNewItem(jobItems, index, apiClient, deferred) {
|
||||||
|
|
||||||
|
var length = jobItems.length;
|
||||||
|
|
||||||
|
if (index >= length) {
|
||||||
|
|
||||||
|
deferred.resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
getNewItem(jobItems[index], apiClient).done(function () {
|
||||||
|
|
||||||
|
getNextNewItem(jobItems, index + 1, apiClient, deferred);
|
||||||
|
}).fail(function () {
|
||||||
|
getNextNewItem(jobItems, index + 1, apiClient, deferred);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNewItem(jobItem, apiClient) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncUserItemAccess(syncDataResult, serverId) {
|
||||||
|
Logger.log('Begin syncUserItemAccess');
|
||||||
|
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
var itemIds = [];
|
||||||
|
for (var id in syncDataResult.ItemUserAccess) {
|
||||||
|
itemIds.push(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
syncNextUserAccessForItem(itemIds, 0, syncDataResult, serverId, deferred);
|
||||||
|
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncNextUserAccessForItem(itemIds, index, syncDataResult, serverId, deferred) {
|
||||||
|
|
||||||
|
var length = itemIds.length;
|
||||||
|
|
||||||
|
if (index >= length) {
|
||||||
|
|
||||||
|
deferred.resolve();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
syncUserAccessForItem(itemIds[index], syncDataResult).done(function () {
|
||||||
|
|
||||||
|
syncNextUserAccessForItem(itemIds, index + 1, syncDataResult, serverId, deferred);
|
||||||
|
}).fail(function () {
|
||||||
|
syncNextUserAccessForItem(itemIds, index + 1, syncDataResult, serverId, deferred);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncUserAccessForItem(itemId, syncDataResult) {
|
||||||
|
Logger.log('Begin syncUserAccessForItem');
|
||||||
|
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
|
||||||
|
require(['localassetmanager'], function () {
|
||||||
|
|
||||||
|
LocalAssetManager.getLocalItem(itemId, serverId).done(function (localItem) {
|
||||||
|
|
||||||
|
var userIdsWithAccess = syncDataResult.ItemUserAccess[itemId];
|
||||||
|
|
||||||
|
if (userIdsWithAccess.join(',') == localItem.UserIdsWithAccess.join(',')) {
|
||||||
|
// Hasn't changed, nothing to do
|
||||||
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
localItem.UserIdsWithAccess = userIdsWithAccess;
|
||||||
|
localAssetManager.addOrUpdateLocalItem(localItem).done(function () {
|
||||||
|
deferred.resolve();
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
}
|
||||||
|
|
||||||
|
}).fail(getOnFail(deferred));
|
||||||
|
});
|
||||||
|
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@
|
||||||
|
|
||||||
var apiClient = connectionManager.getApiClient(server.Id);
|
var apiClient = connectionManager.getApiClient(server.Id);
|
||||||
|
|
||||||
new MediaBrowser.MediaSync().sync(apiClient).done(function () {
|
new MediaBrowser.MediaSync().sync(apiClient, server).done(function () {
|
||||||
|
|
||||||
Logger.log("MediaSync succeeded to server: " + server.Id);
|
Logger.log("MediaSync succeeded to server: " + server.Id);
|
||||||
|
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
(function () {
|
|
||||||
|
|
||||||
function getLocalMediaSource(serverId, itemId) {
|
|
||||||
var json = ApiClientBridge.getLocalMediaSource(serverId, itemId);
|
|
||||||
|
|
||||||
if (json) {
|
|
||||||
return JSON.parse(json);
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
function saveOfflineUser(user) {
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
|
||||||
deferred.resolve();
|
|
||||||
return deferred.promise();
|
|
||||||
}
|
|
||||||
|
|
||||||
function getCameraPhotos() {
|
|
||||||
var deferred = DeferredBuilder.Deferred();
|
|
||||||
deferred.resolveWith(null, [[]]);
|
|
||||||
return deferred.promise();
|
|
||||||
}
|
|
||||||
|
|
||||||
window.LocalAssetManager = {
|
|
||||||
getLocalMediaSource: getLocalMediaSource,
|
|
||||||
saveOfflineUser: saveOfflineUser,
|
|
||||||
getCameraPhotos: getCameraPhotos
|
|
||||||
};
|
|
||||||
|
|
||||||
})();
|
|
47
dashboard-ui/cordova/localassetmanager.js
vendored
47
dashboard-ui/cordova/localassetmanager.js
vendored
|
@ -1,6 +1,16 @@
|
||||||
(function () {
|
(function () {
|
||||||
|
|
||||||
function getLocalMediaSource(serverId, itemId) {
|
function getLocalMediaSource(serverId, itemId) {
|
||||||
|
|
||||||
|
// android
|
||||||
|
if (window.ApiClientBridge) {
|
||||||
|
var json = ApiClientBridge.getLocalMediaSource(serverId, itemId);
|
||||||
|
|
||||||
|
if (json) {
|
||||||
|
return JSON.parse(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,10 +46,45 @@
|
||||||
return deferred.promise();
|
return deferred.promise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getOfflineActions(serverId) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolveWith(null, [[]]);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getServerItemIds(serverId) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolveWith(null, [[]]);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeLocalItem(itemId, serverId) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolveWith(null, []);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocalItem(itemId, serverId) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolveWith(null, []);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addOrUpdateLocalItem(localItem) {
|
||||||
|
var deferred = DeferredBuilder.Deferred();
|
||||||
|
deferred.resolveWith(null, []);
|
||||||
|
return deferred.promise();
|
||||||
|
}
|
||||||
|
|
||||||
window.LocalAssetManager = {
|
window.LocalAssetManager = {
|
||||||
getLocalMediaSource: getLocalMediaSource,
|
getLocalMediaSource: getLocalMediaSource,
|
||||||
saveOfflineUser: saveOfflineUser,
|
saveOfflineUser: saveOfflineUser,
|
||||||
getCameraPhotos: getCameraPhotos
|
getCameraPhotos: getCameraPhotos,
|
||||||
|
getOfflineActions: getOfflineActions,
|
||||||
|
getServerItemIds: getServerItemIds,
|
||||||
|
removeLocalItem: removeLocalItem,
|
||||||
|
getLocalItem: getLocalItem,
|
||||||
|
addOrUpdateLocalItem: addOrUpdateLocalItem
|
||||||
};
|
};
|
||||||
|
|
||||||
})();
|
})();
|
|
@ -1103,7 +1103,12 @@
|
||||||
|
|
||||||
outerHtml += '</div>';
|
outerHtml += '</div>';
|
||||||
|
|
||||||
html += '<h1>';
|
if (index == 0) {
|
||||||
|
html += '<h1>';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
html += '<h1 style="margin-top:2em;">';
|
||||||
|
}
|
||||||
html += itemGroupTitle;
|
html += itemGroupTitle;
|
||||||
html += '</h1>';
|
html += '</h1>';
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,6 @@
|
||||||
var html = '';
|
var html = '';
|
||||||
|
|
||||||
var href = plugin.externalUrl ? plugin.externalUrl : "addplugin.html?name=" + encodeURIComponent(plugin.name) + "&guid=" + plugin.guid;
|
var href = plugin.externalUrl ? plugin.externalUrl : "addplugin.html?name=" + encodeURIComponent(plugin.name) + "&guid=" + plugin.guid;
|
||||||
|
|
||||||
if (options.context) {
|
if (options.context) {
|
||||||
href += "&context=" + options.context;
|
href += "&context=" + options.context;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2008,9 +2008,7 @@ var AppInfo = {};
|
||||||
define("wakeonlan", ["apiclient/wakeonlan"]);
|
define("wakeonlan", ["apiclient/wakeonlan"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Dashboard.isRunningInCordova() && $.browser.android) {
|
if (Dashboard.isRunningInCordova()) {
|
||||||
define("localassetmanager", ["cordova/android/localassetmanager"]);
|
|
||||||
} else if (Dashboard.isRunningInCordova()) {
|
|
||||||
define("localassetmanager", ["cordova/localassetmanager"]);
|
define("localassetmanager", ["cordova/localassetmanager"]);
|
||||||
} else {
|
} else {
|
||||||
define("localassetmanager", ["apiclient/localassetmanager"]);
|
define("localassetmanager", ["apiclient/localassetmanager"]);
|
||||||
|
|
|
@ -260,8 +260,8 @@
|
||||||
$('#txtSyncJobName', page).val(job.Name);
|
$('#txtSyncJobName', page).val(job.Name);
|
||||||
$('#selectProfile', page).val(job.Profile || '').trigger('change');
|
$('#selectProfile', page).val(job.Profile || '').trigger('change');
|
||||||
$('#selectQuality', page).val(job.Quality || '').trigger('change');
|
$('#selectQuality', page).val(job.Quality || '').trigger('change');
|
||||||
$('#chkUnwatchedOnly', page).checked(job.UnwatchedOnly).checkboxradio('refresh');
|
$('#chkUnwatchedOnly', page).checked(job.UnwatchedOnly);
|
||||||
$('#chkSyncNewContent', page).checked(job.SyncNewContent).checkboxradio('refresh');
|
$('#chkSyncNewContent', page).checked(job.SyncNewContent);
|
||||||
$('#txtItemLimit', page).val(job.ItemLimit);
|
$('#txtItemLimit', page).val(job.ItemLimit);
|
||||||
|
|
||||||
if (job.Bitrate) {
|
if (job.Bitrate) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue