update camera upload

This commit is contained in:
Luke Pulverenti 2015-09-10 14:28:22 -04:00
parent 50dc5c4d1b
commit a2d603a31e
19 changed files with 404 additions and 141 deletions

View File

@ -398,7 +398,7 @@
self.openWebSocket = function () { self.openWebSocket = function () {
var accessToken = self.serverInfo().AccessToken; var accessToken = self.accessToken();
if (!accessToken) { if (!accessToken) {
throw new Error("Cannot open web socket without access token."); throw new Error("Cannot open web socket without access token.");
@ -653,7 +653,7 @@
self.setAuthenticationInfo(null, null); self.setAuthenticationInfo(null, null);
}; };
if (self.serverInfo().AccessToken) { if (self.accessToken()) {
var url = self.getUrl("Sessions/Logout"); var url = self.getUrl("Sessions/Logout");
return self.ajax({ return self.ajax({
@ -663,8 +663,9 @@
} }
var deferred = DeferredBuilder.Deferred(); var deferred = DeferredBuilder.Deferred();
done();
deferred.resolveWith(null, []); deferred.resolveWith(null, []);
return deferred.promise().always(done); return deferred.promise();
}; };
function getRemoteImagePrefix(options) { function getRemoteImagePrefix(options) {
@ -2222,6 +2223,25 @@
}); });
}; };
/**
* Gets a user by id
* @param {String} id
*/
self.getOfflineUser = function (id) {
if (!id) {
throw new Error("Must supply a userId");
}
var url = self.getUrl("Users/" + id + "/Offline");
return self.ajax({
type: "GET",
url: url,
dataType: "json"
});
};
/** /**
* Gets a studio * Gets a studio
*/ */

View File

@ -322,12 +322,12 @@
function saveUserInfoIntoCredentials(server, user) { function saveUserInfoIntoCredentials(server, user) {
//ServerUserInfo info = new ServerUserInfo(); var info = new {
//info.setIsSignedInOffline(true); Id: user.Id,
//info.setId(user.getId()); IsSignedInOffline: true
}
//// Record user info here credentialProvider.addOrUpdateUser(server, info);
//server.AddOrUpdate(info);
} }
function afterConnected(apiClient, options) { function afterConnected(apiClient, options) {

View File

@ -108,6 +108,24 @@
return server; return server;
} }
}; };
self.addOrUpdateUser = function (server, user) {
server.Users = server.Users || [];
var existing = server.Users.filter(function (s) {
return s.Id == user.Id;
})[0];
if (existing) {
// Merge the data
existing.IsSignedInOffline = true;
}
else {
server.Users.push(user);
}
};
}; };
})(window, window.JSON); })(window, window.JSON);

View File

@ -0,0 +1,23 @@
(function (globalScope) {
function fileUpload() {
var self = this;
self.upload = function (file, name, url) {
var deferred = DeferredBuilder.Deferred();
deferred.reject();
return deferred.promise();
};
}
if (!globalScope.MediaBrowser) {
globalScope.MediaBrowser = {};
}
globalScope.MediaBrowser.FileUpload = fileUpload;
})(this);

View File

@ -4,8 +4,22 @@
return null; 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 = { window.LocalAssetManager = {
getLocalMediaSource: getLocalMediaSource getLocalMediaSource: getLocalMediaSource,
saveOfflineUser: saveOfflineUser,
getCameraPhotos: getCameraPhotos
}; };
})(); })();

View File

@ -40,11 +40,92 @@
function uploadImagesWithHistory(server, uploadHistory, apiClient, deferred) { function uploadImagesWithHistory(server, uploadHistory, apiClient, deferred) {
require(['localassetmanager'], function () { require(['localassetmanager', "cryptojs-sha1"], function () {
// TODO: Mimic java version of ContentUploader.UploadImagesInternal LocalAssetManager.getCameraPhotos().done(function (photos) {
deferred.resolve();
photos = getFilesToUpload(photos, uploadHistory);
Logger.log('Found ' + photos.length + ' files to upload');
uploadNext(photos, 0, server, apiClient, deferred);
}).fail(function () {
deferred.reject();
}); });
});
}
function getFilesToUpload(files, uploadHistory) {
return files.filter(function (file) {
// Seeing some null entries for some reason
if (!file) {
return false;
}
return uploadHistory.FilesUploaded.filter(function (u) {
return getUploadId(file) == u.Id;
}).length == 0;
});
}
function getUploadId(file) {
return CryptoJS.SHA1(file + "1").toString();
}
function uploadNext(files, index, server, apiClient, deferred) {
var length = files.length;
if (index >= length) {
deferred.resolve();
return;
}
uploadFile(files[index], apiClient).done(function () {
uploadNext(files, index + 1, server, apiClient, deferred);
}).fail(function () {
uploadNext(files, index + 1, server, apiClient, deferred);
});
}
function uploadFile(file, apiClient) {
var deferred = DeferredBuilder.Deferred();
require(['fileupload', "cryptojs-sha1"], function () {
var name = 'camera image ' + new Date().getTime();
var url = apiClient.getUrl('Devices/CameraUploads', {
DeviceId: apiClient.deviceId(),
Name: name,
Album: 'Camera Roll',
Id: getUploadId(file),
api_key: apiClient.accessToken()
});
Logger.log('Uploading file to ' + url);
new MediaBrowser.FileUpload().upload(file, name, url).done(function () {
Logger.log('File upload succeeded');
deferred.resolve();
}).fail(function () {
Logger.log('File upload failed');
deferred.reject();
});
});
return deferred.promise();
} }
} }

View File

@ -4,14 +4,56 @@
var self = this; var self = this;
self.sync = function (apiClient) { self.sync = function (apiClient, server) {
var deferred = DeferredBuilder.Deferred(); var deferred = DeferredBuilder.Deferred();
deferred.resolve(); var users = server.Users || [];
syncNext(users, 0, deferred, apiClient, server);
return deferred.promise(); return deferred.promise();
}; };
function syncNext(users, index, deferred, apiClient, server) {
var length = users.length;
if (index >= length) {
deferred.resolve();
return;
}
syncUser(users[index], apiClient).done(function () {
syncNext(users, index + 1, deferred, apiClient, server);
}).fail(function () {
syncNext(users, index + 1, deferred, apiClient, server);
});
}
function syncUser(user, apiClient) {
var deferred = DeferredBuilder.Deferred();
apiClient.getOfflineUser(user.Id).done(function (result) {
require(['localassetmanager'], function () {
LocalAssetManager.saveOfflineUser(result).done(function () {
deferred.resolve();
}).fail(function () {
deferred.resolve();
});
});
}).fail(function () {
deferred.reject();
});
return deferred.promise();
}
} }
if (!globalScope.MediaBrowser) { if (!globalScope.MediaBrowser) {

View File

@ -12,7 +12,7 @@
Logger.log('Skipping sync to server ' + server.Id + ' because there is no saved authentication information.'); Logger.log('Skipping sync to server ' + server.Id + ' because there is no saved authentication information.');
deferred.resolve(); deferred.resolve();
return; return deferred.promise();
} }
var connectionOptions = { var connectionOptions = {
@ -66,7 +66,7 @@
var apiClient = connectionManager.getApiClient(server.Id); var apiClient = connectionManager.getApiClient(server.Id);
new MediaBrowser.OfflineUserSync().sync(apiClient).done(function () { new MediaBrowser.OfflineUserSync().sync(apiClient, server).done(function () {
Logger.log("OfflineUserSync succeeded to server: " + server.Id); Logger.log("OfflineUserSync succeeded to server: " + server.Id);

View File

@ -10,8 +10,16 @@
return null; return null;
} }
function getCameraPhotos() {
var deferred = DeferredBuilder.Deferred();
deferred.resolveWith(null, [[]]);
return deferred.promise();
}
window.LocalAssetManager = { window.LocalAssetManager = {
getLocalMediaSource: getLocalMediaSource getLocalMediaSource: getLocalMediaSource,
saveOfflineUser: saveOfflineUser,
getCameraPhotos: getCameraPhotos
}; };
})(); })();

44
dashboard-ui/cordova/fileupload.js vendored Normal file
View File

@ -0,0 +1,44 @@
(function (globalScope) {
function fileUpload() {
var self = this;
self.upload = function (file, name, url) {
var deferred = DeferredBuilder.Deferred();
var onSuccess = function (r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
deferred.resolve();
}
var onFail = function (error) {
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
deferred.reject();
}
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = name;
options.mimeType = 'image/jpg';
var params = {};
options.params = params;
new FileTransfer().upload(file, url, onSuccess, onFail, options);
return deferred.promise();
};
}
if (!globalScope.MediaBrowser) {
globalScope.MediaBrowser = {};
}
globalScope.MediaBrowser.FileUpload = fileUpload;
})(this);

View File

@ -4,38 +4,41 @@
var self = this; var self = this;
// Need to use this to fire events because the iOS vlc callbacks always go to the first instance
window.AudioRenderer.Current = self;
self.enableProgressReporting = options.type == 'audio'; self.enableProgressReporting = options.type == 'audio';
function onEnded() { function onEnded() {
Events.trigger(self, 'ended'); Events.trigger(window.AudioRenderer.Current, 'ended');
} }
function onTimeUpdate() { function onTimeUpdate() {
Events.trigger(self, 'timeupdate'); Events.trigger(window.AudioRenderer.Current, 'timeupdate');
} }
function onVolumeChange() { function onVolumeChange() {
Events.trigger(self, 'volumechange'); Events.trigger(window.AudioRenderer.Current, 'volumechange');
} }
function onPlaying() { function onPlaying() {
Events.trigger(self, 'playing'); Events.trigger(window.AudioRenderer.Current, 'playing');
} }
function onPlay() { function onPlay() {
Events.trigger(self, 'play'); Events.trigger(window.AudioRenderer.Current, 'play');
} }
function onPause() { function onPause() {
Events.trigger(self, 'pause'); Events.trigger(window.AudioRenderer.Current, 'pause');
} }
function onClick() { function onClick() {
Events.trigger(self, 'click'); Events.trigger(window.AudioRenderer.Current, 'click');
} }
function onDblClick() { function onDblClick() {
Events.trigger(self, 'dblclick'); Events.trigger(window.AudioRenderer.Current, 'dblclick');
} }
function onError() { function onError() {
@ -43,10 +46,10 @@
var errorCode = this.error ? this.error.code : ''; var errorCode = this.error ? this.error.code : '';
Logger.log('Media element error code: ' + errorCode); Logger.log('Media element error code: ' + errorCode);
Events.trigger(self, 'error'); Events.trigger(window.AudioRenderer.Current, 'error');
} }
var playerState = {}; self.playerState = {};
self.currentTime = function (val) { self.currentTime = function (val) {
@ -60,16 +63,12 @@
return; return;
} }
return playerState.currentTime; return self.playerState.currentTime;
}; };
self.duration = function (val) { self.duration = function (val) {
if (playerState) { return self.playerState.duration;
return playerState.duration;
}
return null;
}; };
self.stop = function () { self.stop = function () {
@ -103,14 +102,12 @@
}; };
self.volume = function (val) { self.volume = function (val) {
if (playerState) {
if (val != null) { if (val != null) {
// TODO // TODO
return; return;
} }
return playerState.volume; return self.playerState.volume;
}
}; };
self.setCurrentSrc = function (val, item, mediaSource, tracks) { self.setCurrentSrc = function (val, item, mediaSource, tracks) {
@ -161,31 +158,22 @@
} }
playerState.currentSrc = val; AudioRenderer.Current.playerState.currentSrc = val;
reportEvent('playing', {}); reportEvent('playing', {});
}; };
self.currentSrc = function () { self.currentSrc = function () {
return playerState.currentSrc; return self.playerState.currentSrc;
}; };
self.paused = function () { self.paused = function () {
if (playerState) { return self.playerState.paused;
return playerState.paused;
}
return false;
}; };
self.cleanup = function (destroyRenderer) { self.cleanup = function (destroyRenderer) {
playerState = {}; self.playerState = {};
};
self.enableCustomVideoControls = function () {
return false;
}; };
function reportEvent(eventName, result) { function reportEvent(eventName, result) {
@ -195,13 +183,11 @@
Logger.log('eventName: ' + eventName + '. position: ' + position); Logger.log('eventName: ' + eventName + '. position: ' + position);
var isPaused = result.state == 3 || eventName == 'paused'; var state = AudioRenderer.Current.playerState;
var state = playerState;
state.duration = duration; state.duration = duration;
state.currentTime = position; state.currentTime = position;
state.paused = isPaused; state.paused = result.state == 3 || eventName == 'paused';
state.volume = 0; state.volume = 0;
if (eventName == 'playbackstop') { if (eventName == 'playbackstop') {
@ -237,17 +223,20 @@
} }
} }
function errorHandler() {
onError();
}
self.init = function () { self.init = function () {
var deferred = DeferredBuilder.Deferred(); var deferred = DeferredBuilder.Deferred();
window.audioplayer.configure(function () { window.audioplayer.configure(successHandler, errorHandler);
Logger.log('audioplayer.configure success');
setTimeout(function () {
deferred.resolve(); deferred.resolve();
}, function () { }, 500);
Logger.log('audioplayer.configure error');
deferred.resolve();
});
return deferred.promise(); return deferred.promise();
}; };
} }

View File

@ -4,8 +4,42 @@
return null; return null;
} }
function saveOfflineUser(user) {
var deferred = DeferredBuilder.Deferred();
deferred.resolve();
return deferred.promise();
}
function getCameraPhotos() {
var deferred = DeferredBuilder.Deferred();
if (window.CameraRoll) {
var photos = [];
CameraRoll.getPhotos(function (result) {
photos.push(result);
});
setTimeout(function () {
// clone the array in case the callback is still getting called
Logger.log('Found ' + photos.length + ' in camera roll');
deferred.resolveWith(null, [photos]);
}, 2000);
} else {
deferred.resolveWith(null, [[]]);
}
return deferred.promise();
}
window.LocalAssetManager = { window.LocalAssetManager = {
getLocalMediaSource: getLocalMediaSource getLocalMediaSource: getLocalMediaSource,
saveOfflineUser: saveOfflineUser,
getCameraPhotos: getCameraPhotos
}; };
})(); })();

View File

@ -56,14 +56,6 @@
return appStorage.getItem('externalplayers') == 'true'; return appStorage.getItem('externalplayers') == 'true';
}, },
enableItemPreviews: function (val) {
if (val != null) {
update('enableItemPreviews', val.toString());
}
return appStorage.getItem('enableItemPreviews') == 'true';
},
enableFullScreen: function (val) { enableFullScreen: function (val) {
if (val != null) { if (val != null) {

View File

@ -824,59 +824,6 @@
return elem; return elem;
} }
function onCardClick(e) {
var targetElem = parentWithClass(e.target, 'mediaItem');
if (!targetElem) {
return;
}
if (isClickable(targetElem)) {
return;
}
if (targetElem.classList.contains('itemSelectionPanel') || this.querySelector('.itemSelectionPanel')) {
return;
}
var info = LibraryBrowser.getListItemInfo(this);
var itemId = info.id;
var context = info.context;
var card = this;
if (card.classList.contains('itemWithAction')) {
return;
}
if (!card.classList.contains('card')) {
card = $(card).parents('.card')[0];
}
if (card.classList.contains('groupedCard')) {
return;
}
if (card.getAttribute('data-detailsmenu') != 'true') {
return;
}
var target = $(targetElem);
if (target.parents('a').length || target.parents('button').length) {
return;
}
if (AppSettings.enableItemPreviews()) {
showItemsOverlay({
ids: [itemId],
context: context
});
return false;
}
}
$.fn.createCardMenus = function (options) { $.fn.createCardMenus = function (options) {
var preventHover = false; var preventHover = false;
@ -981,9 +928,6 @@
this.on("touchstart", '.card:not(.bannerCard) .cardContent', preventTouchHover); this.on("touchstart", '.card:not(.bannerCard) .cardContent', preventTouchHover);
} }
this.off('click', onCardClick);
this.on('click', onCardClick);
return this; return this;
}; };
@ -1192,7 +1136,14 @@
function playAllFromHere(index, itemsContainer, method) { function playAllFromHere(index, itemsContainer, method) {
var ids = $('.mediaItem', itemsContainer).get().map(function (i) { var ids = $('.mediaItem', itemsContainer).get().map(function (i) {
return i.getAttribute('data-itemid') || i.parentNode.getAttribute('data-itemid') || i.parentNode.parentNode.getAttribute('data-itemid');
var node = i;
var id = node.getAttribute('data-itemid');
while (!id) {
node = node.parentNode;
id = node.getAttribute('data-itemid');
}
return id;
}); });
ids = ids.slice(index); ids = ids.slice(index);

View File

@ -1,18 +1,47 @@
(function () { (function () {
var syncPromise;
window.LocalSync = { window.LocalSync = {
isSupported: function () { isSupported: function () {
return false; return AppInfo.isNativeApp;
}, },
startSync: function () { startSync: function () {
if (!syncPromise) {
require(['multiserversync'], function () {
syncPromise = new MediaBrowser.MultiServerSync(ConnectionManager).sync().done(function () {
syncPromise = null;
}).fail(function () {
syncPromise = null;
});
});
}
}, },
getSyncStatus: function () { getSyncStatus: function () {
if (syncPromise != null) {
return 'Syncing';
}
return 'Idle'; return 'Idle';
} }
}; };
Dashboard.ready(function () {
if (LocalSync.isSupported) {
setInterval(function () {
LocalSync.startSync();
}, 3600000);
}
});
})(); })();

View File

@ -839,16 +839,24 @@
self.supportsDirectPlay = function (mediaSource) { self.supportsDirectPlay = function (mediaSource) {
if (mediaSource.SupportsDirectPlay && mediaSource.Protocol == 'Http' && !mediaSource.RequiredHttpHeaders.length) { if (mediaSource.SupportsDirectPlay) {
// TODO: Need to verify the host is going to be reachable if (mediaSource.Protocol == 'Http' && !mediaSource.RequiredHttpHeaders.length) {
// If this is the only way it can be played, then allow it
if (!mediaSource.SupportsDirectStream && !mediaSource.SupportsTranscoding) {
return true; return true;
} }
if (mediaSource.SupportsDirectPlay && mediaSource.Protocol == 'File') { // 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;
}
if (mediaSource.Protocol == 'File') {
return FileSystemBridge.fileExists(mediaSource.Path); return FileSystemBridge.fileExists(mediaSource.Path);
} }
}
return false; return false;
}; };

View File

@ -1095,7 +1095,7 @@
var requiresNativeControls = false; var requiresNativeControls = false;
if (self.currentMediaRenderer && !self.currentMediaRenderer.enableCustomVideoControls) { if (self.currentMediaRenderer && self.currentMediaRenderer.enableCustomVideoControls) {
requiresNativeControls = self.currentMediaRenderer.enableCustomVideoControls(); requiresNativeControls = self.currentMediaRenderer.enableCustomVideoControls();
} }

View File

@ -10,7 +10,7 @@
ApiClient.ajax({ ApiClient.ajax({
type: "DELETE", type: "DELETE",
url: ApiClient.getUrl('Auth/Keys/' + key) url: ApiClient.getUrl('Auth/Keys' + key)
}).done(function () { }).done(function () {
@ -103,7 +103,7 @@
ApiClient.ajax({ ApiClient.ajax({
type: "POST", type: "POST",
url: ApiClient.getUrl('Auth/Keys/', { url: ApiClient.getUrl('Auth/Keys', {
App: $('#txtAppName', form).val() App: $('#txtAppName', form).val()

View File

@ -1516,7 +1516,7 @@ var Dashboard = {
SupportedLiveMediaTypes: ['Audio', 'Video'] SupportedLiveMediaTypes: ['Audio', 'Video']
}; };
if (Dashboard.isRunningInCordova() && $.browser.android) { if (Dashboard.isRunningInCordova()) {
caps.SupportsOfflineAccess = true; caps.SupportsOfflineAccess = true;
caps.SupportsSync = true; caps.SupportsSync = true;
caps.SupportsContentUploading = true; caps.SupportsContentUploading = true;
@ -2148,6 +2148,12 @@ var AppInfo = {};
define("offlineusersync", ["apiclient/sync/offlineusersync"]); define("offlineusersync", ["apiclient/sync/offlineusersync"]);
define("mediasync", ["apiclient/sync/mediasync"]); define("mediasync", ["apiclient/sync/mediasync"]);
if (Dashboard.isRunningInCordova()) {
define("fileupload", ["cordova/fileupload"]);
} else {
define("fileupload", ["apiclient/fileupload"]);
}
var deps = []; var deps = [];
if (!deviceId) { if (!deviceId) {
@ -2270,6 +2276,10 @@ var AppInfo = {};
Dashboard.initPromiseDone = true; Dashboard.initPromiseDone = true;
$.mobile.initializePage(); $.mobile.initializePage();
deferred.resolve(); deferred.resolve();
if (AppInfo.isNativeApp && !$.browser.android) {
require(['localsync']);
}
} }
function initCordovaWithDeviceId(deferred, deviceId) { function initCordovaWithDeviceId(deferred, deviceId) {