Browse Source

Photos download, packaged app improvements

master
Igor Zhukov 11 years ago
parent
commit
2d50db467f
  1. 10
      app/css/app.css
  2. 67
      app/index.html
  3. 22
      app/js/controllers.js
  4. 2
      app/js/directives.js
  5. 63
      app/js/init.js
  6. 221
      app/js/lib/mtproto.js
  7. 80
      app/js/services.js
  8. 3
      app/manifest.json
  9. 6
      app/partials/head.html
  10. 1
      app/partials/photo_modal.html
  11. 6
      app/partials/welcome.html

10
app/css/app.css

@ -3,12 +3,14 @@
html { html {
display: none; display: none;
background: #dee4e9 url(../img/bg_tile.png) 0 0 repeat; background: #dee4e9 url(../img/bg_tile.png) 0 0 repeat;
overflow: visible;
/*background-size: 300px 468px;*/ /*background-size: 300px 468px;*/
} }
body { body {
color: #000; color: #000;
background: none; background: none;
font: 12px/18px "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, Verdana, sans-serif; font: 12px/18px "Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, Verdana, sans-serif;
overflow: visible;
/*-webkit-font-smoothing: antialiased;*/ /*-webkit-font-smoothing: antialiased;*/
} }
.font-light { .font-light {
@ -71,6 +73,10 @@ input[type="number"]::-webkit-inner-spin-button {
margin: 0; margin: 0;
} }
input[type="number"] {
-moz-appearance:textfield;
}
.btn-success { .btn-success {
color: #ffffff; color: #ffffff;
@ -312,9 +318,7 @@ input[type="number"]::-webkit-inner-spin-button {
.modal-backdrop { .modal-backdrop {
background: #111111; background: #111111;
} opacity: 0.25 !important;
.modal-backdrop.in {
opacity: 0.25;
} }
.modal.fade .modal-dialog { .modal.fade .modal-dialog {

67
app/index.html

@ -20,72 +20,6 @@
<meta property="og:site_name" content="Webogram"> <meta property="og:site_name" content="Webogram">
<meta property="og:description" content="Welcome to an experimental web-client of Telegram messenger. See https://github.com/zhukov/webogram for more info."> <meta property="og:description" content="Welcome to an experimental web-client of Telegram messenger. See https://github.com/zhukov/webogram for more info.">
<script type="text/javascript">
(function () {
// Prevent click-jacking
try {
if (self == top) {
document.documentElement.style.display = 'block';
} else {
top.location = self.location;
}
} catch (e) {console.error('CJ protection', e)};
window.safeConfirm = function (params, callback) {
if (typeof params === 'string') {
params = {message: params};
}
var result = false
try {
result = confirm(params.message);
} catch (e) {
result = true;
}
setTimeout(function () {callback(result)}, 10);
};
if (!window.applicationCache || !window.addEventListener) {
return;
}
var appCache = window.applicationCache,
declined = false,
updateTimeout = false,
scheduleUpdate = function (delay) {
clearTimeout(updateTimeout);
updateTimeout = setTimeout(function () {
try {
appCache.update();
} catch (ex) {
console.log('appCache.update: ' + ex);
}
}, delay || 300000);
},
attach = function () {
appCache.addEventListener('updateready', function(e) {
if (appCache.status == appCache.UPDATEREADY) {
if (!declined) {
safeConfirm({type: 'WEBOGRAM_UPDATED_RELOAD', message: 'A new version of Webogram is available. Load it?'}, function (result) {
if (result) {
window.location.reload();
} else {
declined = true;
}
});
scheduleUpdate();
}
}
}, false);
appCache.addEventListener('noupdate', function () {scheduleUpdate()}, false);
appCache.addEventListener('error', function () {scheduleUpdate()}, false);
};
scheduleUpdate(3000);
window.addEventListener('load', attach);
})();
</script>
</head> </head>
<body> <body>
@ -93,6 +27,7 @@
<!-- build:js js/app.js --> <!-- build:js js/app.js -->
<script type="text/javascript" src="vendor/console-polyfill/console-polyfill.js"></script> <script type="text/javascript" src="vendor/console-polyfill/console-polyfill.js"></script>
<script type="text/javascript" src="js/init.js"></script>
<script type="text/javascript" src="vendor/jquery/jquery.min.js"></script> <script type="text/javascript" src="vendor/jquery/jquery.min.js"></script>
<script type="text/javascript" src="vendor/jquery.nanoscroller/nanoscroller.js"></script> <script type="text/javascript" src="vendor/jquery.nanoscroller/nanoscroller.js"></script>
<script type="text/javascript" src="vendor/jquery.emojiarea/jquery.emojiarea.js"></script> <script type="text/javascript" src="vendor/jquery.emojiarea/jquery.emojiarea.js"></script>

22
app/js/controllers.js

@ -427,16 +427,18 @@ angular.module('myApp.controllers', [])
} }
AppMessagesManager.getDialogs($scope.search.query, maxID).then(function (dialogsResult) { AppMessagesManager.getDialogs($scope.search.query, maxID).then(function (dialogsResult) {
offset += dialogsResult.dialogs.length; if (dialogsResult.dialogs.length) {
maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message; offset += dialogsResult.dialogs.length;
hasMore = dialogsResult.count === null || offset < dialogsResult.count; maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message;
hasMore = dialogsResult.count === null || offset < dialogsResult.count;
angular.forEach(dialogsResult.dialogs, function (dialog) { angular.forEach(dialogsResult.dialogs, function (dialog) {
peersInDialogs[dialog.peerID] = true; peersInDialogs[dialog.peerID] = true;
$scope.dialogs.push(AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count)); $scope.dialogs.push(AppMessagesManager.wrapForDialog(dialog.top_message, dialog.unread_count));
}); });
$scope.$broadcast('ui_dialogs_append'); $scope.$broadcast('ui_dialogs_append');
}
}); });
}; };
@ -1081,6 +1083,10 @@ angular.module('myApp.controllers', [])
}); });
}; };
$scope.download = function () {
AppPhotosManager.downloadPhoto($scope.photoID);
};
$scope.$on('history_delete', function (e, historyUpdate) { $scope.$on('history_delete', function (e, historyUpdate) {
console.log(dT(), 'delete', historyUpdate); console.log(dT(), 'delete', historyUpdate);

2
app/js/directives.js

@ -833,7 +833,7 @@ angular.module('myApp.directives', ['myApp.filters'])
} }
} }
var downloadPromise = MtpApiFileManager.downloadFile($scope.video.dc_id, inputLocation, $scope.video.size, null, {mime: 'video/mp4'}); var downloadPromise = MtpApiFileManager.downloadFile($scope.video.dc_id, inputLocation, $scope.video.size, {mime: 'video/mp4'});
downloadPromise.then(function (url) { downloadPromise.then(function (url) {
$scope.progress.enabled = false; $scope.progress.enabled = false;

63
app/js/init.js

@ -0,0 +1,63 @@
(function () {
// Prevent click-jacking
try {
if (window.chrome && chrome.app && chrome.app.window || self == top) {
document.documentElement.style.display = 'block';
} else {
top.location = self.location;
}
} catch (e) {console.error('CJ protection', e)};
window.safeConfirm = function (params, callback) {
if (typeof params === 'string') {
params = {message: params};
}
var result = false
try {
result = confirm(params.message);
} catch (e) {
result = true;
}
setTimeout(function () {callback(result)}, 10);
};
if (!window.applicationCache || !window.addEventListener) {
return;
}
var appCache = window.applicationCache,
declined = false,
updateTimeout = false,
scheduleUpdate = function (delay) {
clearTimeout(updateTimeout);
updateTimeout = setTimeout(function () {
try {
appCache.update();
} catch (ex) {
console.log('appCache.update: ' + ex);
}
}, delay || 300000);
},
attach = function () {
appCache.addEventListener('updateready', function(e) {
if (appCache.status == appCache.UPDATEREADY) {
if (!declined) {
safeConfirm({type: 'WEBOGRAM_UPDATED_RELOAD', message: 'A new version of Webogram is available. Load it?'}, function (result) {
if (result) {
window.location.reload();
} else {
declined = true;
}
});
scheduleUpdate();
}
}
}, false);
appCache.addEventListener('noupdate', function () {scheduleUpdate()}, false);
appCache.addEventListener('error', function () {scheduleUpdate()}, false);
};
scheduleUpdate(3000);
window.addEventListener('load', attach);
})();

221
app/js/lib/mtproto.js

@ -1005,12 +1005,12 @@ factory('MtpDcConfigurator', function () {
var dcOptions = window._testMode var dcOptions = window._testMode
? [ ? [
{id: 1, host: '173.240.5.253', port: 80}, {id: 1, host: '173.240.5.253', port: 80},
{id: 2, host: '109.239.131.195', port: 80}, {id: 2, host: '149.154.167.40', port: 80},
{id: 3, host: '174.140.142.5', port: 80} {id: 3, host: '174.140.142.5', port: 80}
] ]
: [ : [
{id: 1, host: '173.240.5.1', port: 80}, {id: 1, host: '173.240.5.1', port: 80},
{id: 2, host: '109.239.131.193', port: 80}, {id: 2, host: '149.154.167.5', port: 80},
{id: 3, host: '174.140.142.6', port: 80}, {id: 3, host: '174.140.142.6', port: 80},
{id: 4, host: '31.210.235.12', port: 80}, {id: 4, host: '31.210.235.12', port: 80},
{id: 5, host: '116.51.22.2', port: 80}, {id: 5, host: '116.51.22.2', port: 80},
@ -2832,7 +2832,7 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
deferred.reject(); deferred.reject();
}; };
if (false) { // is file bytes if (bytes instanceof Blob) { // is file bytes
fileWriter.write(bytes); fileWriter.write(bytes);
} else { } else {
fileWriter.write(new Blob([bytesToArrayBuffer(bytes)])); fileWriter.write(new Blob([bytesToArrayBuffer(bytes)]));
@ -2841,6 +2841,23 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
return deferred.promise; return deferred.promise;
} }
function fileCopyTo (fromFileEntry, toFileEntry) {
var deferred = $q.defer();
toFileEntry.createWriter(function (fileWriter) {
fileWriteBytes(fileWriter, fromFileEntry).then(function () {
deferred.resolve(fileWriter);
}, function (e) {
fileWriter.truncate(0);
deferred.reject(e);
});
}, function (e) {
deferred.reject(e);
});
return deferred.promise;
}
function getFileName(location) { function getFileName(location) {
switch (location._) { switch (location._) {
case 'inputVideoFileLocation': case 'inputVideoFileLocation':
@ -2982,14 +2999,15 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
return cachedDownloadPromises[fileName] = deferred.promise; return cachedDownloadPromises[fileName] = deferred.promise;
} }
function downloadFile (dcID, location, size, fileEntry, options) { function downloadFile (dcID, location, size, options) {
options = options || {}; options = options || {};
console.log(dT(), 'Dload file', dcID, location, size); console.log(dT(), 'Dload file', dcID, location, size);
var fileName = getFileName(location), var fileName = getFileName(location),
toFileEntry = options.toFileEntry || null,
cachedPromise = cachedSavePromises[fileName] || cachedDownloadPromises[fileName]; cachedPromise = cachedSavePromises[fileName] || cachedDownloadPromises[fileName];
if (cachedPromise) { if (!toFileEntry && cachedPromise) {
return cachedPromise; return cachedPromise;
} }
@ -3049,7 +3067,11 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
if (isFinal) { if (isFinal) {
// console.timeEnd(fileName + ' ' + (size / 1024)); // console.timeEnd(fileName + ' ' + (size / 1024));
resolved = true; resolved = true;
deferred.resolve(cachedDownloads[fileName] = fileEntry.toURL(options.mime || 'image/jpeg')); if (toFileEntry) {
deferred.resolve();
} else {
deferred.resolve(cachedDownloads[fileName] = fileEntry.toURL(options.mime || 'image/jpeg'));
}
} else { } else {
// console.log('notify', {done: offset + limit, total: size}); // console.log('notify', {done: offset + limit, total: size});
deferred.notify({done: offset + limit, total: size}); deferred.notify({done: offset + limit, total: size});
@ -3070,90 +3092,104 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
}; };
if (fileEntry) { requestFS().then(function () {
saveToFileEntry(fileEntry); cachedFs.root.getFile(fileName, {create: false}, function(fileEntry) {
} else { fileEntry.file(function(file) {
requestFS().then(function () { // console.log(dT(), 'Check size', file.size, size);
cachedFs.root.getFile(fileName, {create: false}, function(fileEntry) { if (file.size >= size/* && false*/) {
fileEntry.file(function(file) { resolved = true;
// console.log(dT(), 'Check size', file.size, size); if (toFileEntry) {
if (file.size >= size/* && false*/) { fileCopyTo(file, toFileEntry).then(function () {
resolved = true; deferred.resolve();
})
} else {
deferred.resolve(cachedDownloads[fileName] = fileEntry.toURL()); deferred.resolve(cachedDownloads[fileName] = fileEntry.toURL());
}
} else {
// setTimeout(function () {
console.log('File bad size', file, size);
if (toFileEntry) {
saveToFileEntry(toFileEntry);
} else { } else {
// setTimeout(function () {
console.log('File bad size', file, size);
cachedFs.root.getFile(fileName, {create: true}, saveToFileEntry, errorHandler) cachedFs.root.getFile(fileName, {create: true}, saveToFileEntry, errorHandler)
// }, 10000);
} }
}, errorHandler); // }, 10000);
}, function () { }
cachedFs.root.getFile(fileName, {create: true}, saveToFileEntry, errorHandler) }, errorHandler);
});
}, function () { }, function () {
if (toFileEntry) {
saveToFileEntry(toFileEntry);
} else {
cachedFs.root.getFile(fileName, {create: true}, saveToFileEntry, errorHandler)
}
});
}, function () {
var blobParts = []; if (toFileEntry) {
var limit = size > 30400 ? 524288 : 4096; return saveToFileEntry(toFileEntry);
var writeBlobPromise = $q.when(), }
writeBlobDeferred;
for (var offset = 0; offset < size; offset += limit) { var blobParts = [];
writeBlobDeferred = $q.defer(); var limit = size > 30400 ? 524288 : 4096;
(function (isFinal, offset, writeBlobDeferred, writeBlobPromise) { var writeBlobPromise = $q.when(),
return downloadRequest(dcID, function () { writeBlobDeferred;
for (var offset = 0; offset < size; offset += limit) {
writeBlobDeferred = $q.defer();
(function (isFinal, offset, writeBlobDeferred, writeBlobPromise) {
return downloadRequest(dcID, function () {
if (canceled) {
return $q.when();
}
return MtpApiManager.invokeApi('upload.getFile', {
location: location,
offset: offset,
limit: limit
}, {
dcID: dcID,
fileDownload: true,
createNetworker: true
});
}, 6).then(function (result) {
writeBlobPromise.then(function () {
if (canceled) { if (canceled) {
return $q.when(); return $q.when();
} }
return MtpApiManager.invokeApi('upload.getFile', { try {
location: location, blobParts.push(bytesToArrayBuffer(result.bytes));
offset: offset, writeBlobDeferred.resolve();
limit: limit
}, { if (isFinal) {
dcID: dcID, try {
fileDownload: true, var blob = new Blob(blobParts, {type: options.mime || 'image/jpeg'});
createNetworker: true } catch (e) {
}); window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
}, 6).then(function (result) { var bb = new BlobBuilder;
writeBlobPromise.then(function () { angular.forEach(blobParts, function(blobPart) {
if (canceled) { bb.append(blobPart);
return $q.when(); });
} var blob = bb.getBlob(options.mime || 'image/jpeg');
try { }
blobParts.push(bytesToArrayBuffer(result.bytes));
writeBlobDeferred.resolve();
if (isFinal) {
try {
var blob = new Blob(blobParts, {type: options.mime || 'image/jpeg'});
} catch (e) {
window.BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
var bb = new BlobBuilder;
angular.forEach(blobParts, function(blobPart) {
bb.append(blobPart);
});
var blob = bb.getBlob(options.mime || 'image/jpeg');
}
window.URL = window.URL || window.webkitURL; window.URL = window.URL || window.webkitURL;
resolved = true; resolved = true;
deferred.resolve(cachedDownloads[fileName] = URL.createObjectURL(blob)); deferred.resolve(cachedDownloads[fileName] = URL.createObjectURL(blob));
} else { } else {
deferred.notify({done: offset + limit, total: size}); deferred.notify({done: offset + limit, total: size});
}; };
} catch (e) { } catch (e) {
errorHandler(e); errorHandler(e);
} }
}, errorHandler); }, errorHandler);
}); });
})(offset + limit >= size, offset, writeBlobDeferred, writeBlobPromise); })(offset + limit >= size, offset, writeBlobDeferred, writeBlobPromise);
writeBlobPromise = writeBlobDeferred.promise; writeBlobPromise = writeBlobDeferred.promise;
} }
}); });
}
deferred.promise.cancel = function () { deferred.promise.cancel = function () {
if (!canceled && !resolved) { if (!canceled && !resolved) {
@ -3163,37 +3199,12 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
} }
} }
return cachedDownloadPromises[fileName] = deferred.promise; if (!toFileEntry) {
} cachedDownloadPromises[fileName] = deferred.promise;
}
function writeFile (file) {
console.log(dT(), 'Write file', file);
var fileName = getTempFileName(file);
var deferred = $q.defer(),
cacheFileWriter,
errorHandler = function (error) {
console.log('fail');
deferred.reject(error);
if (cacheFileWriter) cacheFileWriter.truncate(0);
errorHandler = angular.noop;
};
requestFS().then(function () { return deferred.promise;
cachedFs.root.getFile(fileName, {create: false}, function(fileEntry) { }
deferred.resolve(fileEntry);
}, function () {
cachedFs.root.getFile(fileName, {create: true}, function(fileEntry) {
fileEntry.createWriter(function (fileWriter) {
cacheFileWriter = fileWriter;
fileWriteBytes(fileWriter, file).then(function () {
deferred.resolve(fileEntry);
}, errorHandler);
}, errorHandler);
});
});
});
};
function uploadFile (file) { function uploadFile (file) {
var fileSize = file.size, var fileSize = file.size,

80
app/js/services.js

@ -1975,7 +1975,7 @@ angular.module('myApp.services', [])
} }
}) })
.service('AppPhotosManager', function ($modal, $window, $rootScope, MtpApiFileManager, AppUsersManager) { .service('AppPhotosManager', function ($modal, $window, $timeout, $rootScope, MtpApiFileManager, AppUsersManager) {
var photos = {}; var photos = {};
function savePhoto (apiPhoto) { function savePhoto (apiPhoto) {
@ -2123,6 +2123,65 @@ angular.module('myApp.services', [])
}); });
} }
function downloadPhoto (photoID) {
var photo = photos[photoID],
ext = 'jpg',
mimeType = 'image/jpeg',
fileName = 'photo' + photoID + '.' + ext,
fullWidth = $(window).width() - 36,
fullHeight = $($window).height() - 150,
fullPhotoSize = choosePhotoSize(photo, fullWidth, fullHeight),
inputFileLocation = {
_: 'inputFileLocation',
volume_id: fullPhotoSize.location.volume_id,
local_id: fullPhotoSize.location.local_id,
secret: fullPhotoSize.location.secret
};
if (window.chrome && chrome.fileSystem && chrome.fileSystem.chooseEntry) {
chrome.fileSystem.chooseEntry({
type: 'saveFile',
suggestedName: fileName,
accepts: [{
mimeTypes: [mimeType],
extensions: [ext]
}]
}, function (writableFileEntry) {
var downloadPromise = MtpApiFileManager.downloadFile(fullPhotoSize.location.dc_id, inputFileLocation, fullPhotoSize.size, {
mime: mimeType,
toFileEntry: writableFileEntry
});
downloadPromise.then(function (url) {
console.log('file save done');
}, function (e) {
console.log('photo download failed', e);
});
});
} else {
var downloadPromise = MtpApiFileManager.downloadFile(fullPhotoSize.location.dc_id, inputFileLocation, fullPhotoSize.size, {mime: mimeType});
downloadPromise.then(function (url) {
var a = $('<a>Download</a>')
.css({position: 'absolute', top: 1, left: 1})
.attr('href', url)
.attr('target', '_blank')
.attr('download', fileName)
.appendTo('body');
a[0].dataset.downloadurl = [mimeType, fileName, url].join(':');
a[0].click();
$timeout(function () {
a.remove();
}, 100);
}, function (e) {
console.log('photo download failed', e);
});
}
};
$rootScope.openPhoto = openPhoto; $rootScope.openPhoto = openPhoto;
@ -2131,7 +2190,8 @@ angular.module('myApp.services', [])
preloadPhoto: preloadPhoto, preloadPhoto: preloadPhoto,
wrapForHistory: wrapForHistory, wrapForHistory: wrapForHistory,
wrapForFull: wrapForFull, wrapForFull: wrapForFull,
openPhoto: openPhoto openPhoto: openPhoto,
downloadPhoto: downloadPhoto
} }
}) })
@ -2263,7 +2323,10 @@ angular.module('myApp.services', [])
extensions: [ext] extensions: [ext]
}] }]
}, function (writableFileEntry) { }, function (writableFileEntry) {
var downloadPromise = MtpApiFileManager.downloadFile(video.dc_id, inputFileLocation, video.size, writableFileEntry, {mime: mimeType}); var downloadPromise = MtpApiFileManager.downloadFile(video.dc_id, inputFileLocation, video.size, {
mime: mimeType,
toFileEntry: writableFileEntry
});
downloadPromise.then(function (url) { downloadPromise.then(function (url) {
delete historyVideo.progress; delete historyVideo.progress;
console.log('file save done'); console.log('file save done');
@ -2275,7 +2338,7 @@ angular.module('myApp.services', [])
historyVideo.progress.cancel = downloadPromise.cancel; historyVideo.progress.cancel = downloadPromise.cancel;
}); });
} else { } else {
var downloadPromise = MtpApiFileManager.downloadFile(video.dc_id, inputFileLocation, video.size, null, {mime: mimeType}); var downloadPromise = MtpApiFileManager.downloadFile(video.dc_id, inputFileLocation, video.size, {mime: mimeType});
downloadPromise.then(function (url) { downloadPromise.then(function (url) {
delete historyVideo.progress; delete historyVideo.progress;
@ -2404,7 +2467,10 @@ angular.module('myApp.services', [])
extensions: [ext] extensions: [ext]
}] }]
}, function (writableFileEntry) { }, function (writableFileEntry) {
var downloadPromise = MtpApiFileManager.downloadFile(doc.dc_id, inputFileLocation, doc.size, writableFileEntry, {mime: doc.mime_type}); var downloadPromise = MtpApiFileManager.downloadFile(doc.dc_id, inputFileLocation, doc.size, {
mime: doc.mime_type,
toFileEntry: writableFileEntry
});
downloadPromise.then(function (url) { downloadPromise.then(function (url) {
delete historyDoc.progress; delete historyDoc.progress;
@ -2417,7 +2483,7 @@ angular.module('myApp.services', [])
historyDoc.progress.cancel = downloadPromise.cancel; historyDoc.progress.cancel = downloadPromise.cancel;
}); });
} else { } else {
var downloadPromise = MtpApiFileManager.downloadFile(doc.dc_id, inputFileLocation, doc.size, null, {mime: doc.mime_type}); var downloadPromise = MtpApiFileManager.downloadFile(doc.dc_id, inputFileLocation, doc.size, {mime: doc.mime_type});
downloadPromise.then(function (url) { downloadPromise.then(function (url) {
delete historyDoc.progress; delete historyDoc.progress;
@ -2496,7 +2562,7 @@ angular.module('myApp.services', [])
$rootScope.$broadcast('history_update'); $rootScope.$broadcast('history_update');
} }
var downloadPromise = MtpApiFileManager.downloadFile(audio.dc_id, inputFileLocation, audio.size, null, {mime: 'audio/ogg'}); var downloadPromise = MtpApiFileManager.downloadFile(audio.dc_id, inputFileLocation, audio.size, {mime: 'audio/ogg'});
downloadPromise.then(function (url) { downloadPromise.then(function (url) {
delete historyAudio.progress; delete historyAudio.progress;

3
app/manifest.json

@ -12,7 +12,8 @@
"notifications", "notifications",
"webview", "webview",
{"fileSystem": ["write"]}, {"fileSystem": ["write"]},
"storage" "storage",
"unlimitedStorage"
], ],
"icons": { "icons": {
"16": "img/icons/icon16.png", "16": "img/icons/icon16.png",

6
app/partials/head.html

@ -13,15 +13,15 @@
</div> </div>
<div class="navbar-collapse collapse"> <div class="navbar-collapse collapse" ng-switch="offline">
<ul ng-if="offline" class="nav navbar-nav navbar-offline"> <ul ng-switch-when="true" class="nav navbar-nav navbar-offline">
<li ng-show="!offlineConnecting"><span class="navbar-offline-text">Waiting for network<span my-loading-dots></span></span></li> <li ng-show="!offlineConnecting"><span class="navbar-offline-text">Waiting for network<span my-loading-dots></span></span></li>
<li ng-show="!offlineConnecting"><a href="" ng-click="retryOnline()">Retry</a></li> <li ng-show="!offlineConnecting"><a href="" ng-click="retryOnline()">Retry</a></li>
<li ng-show="offlineConnecting"><span class="navbar-offline-text">Connecting<span my-loading-dots></span></span></li> <li ng-show="offlineConnecting"><span class="navbar-offline-text">Connecting<span my-loading-dots></span></span></li>
</ul> </ul>
<ul ng-if="!offline" class="nav navbar-nav navbar-right"> <ul ng-switch-default class="nav navbar-nav navbar-right">
<li ng-if="isLoggedIn"><a href="" ng-click="openContacts()">Contacts</a></li> <li ng-if="isLoggedIn"><a href="" ng-click="openContacts()">Contacts</a></li>
<li ng-if="isLoggedIn"><a href="" ng-click="openSettings()">Settings</a></li> <li ng-if="isLoggedIn"><a href="" ng-click="openSettings()">Settings</a></li>
<li ng-if="isLoggedIn"><a href="" ng-click="logOut()">Log Out</a></li> <li ng-if="isLoggedIn"><a href="" ng-click="logOut()">Log Out</a></li>

1
app/partials/photo_modal.html

@ -5,6 +5,7 @@
<div class="photo_modal_image_wrap" my-load-full-photo full-photo="photo.full" thumb-location="photo.thumb.location" ng-click="nav.next()"> </div> <div class="photo_modal_image_wrap" my-load-full-photo full-photo="photo.full" thumb-location="photo.thumb.location" ng-click="nav.next()"> </div>
<div class="media_modal_actions pull-right" ng-if="messageID"> <div class="media_modal_actions pull-right" ng-if="messageID">
<a href="" class="media_modal_action_link" ng-click="download()">Download</a>
<a href="" class="media_modal_action_link" ng-click="forward()">Forward</a> <a href="" class="media_modal_action_link" ng-click="forward()">Forward</a>
<a href="" class="media_modal_action_link" ng-click="delete()">Delete</a> <a href="" class="media_modal_action_link" ng-click="delete()">Delete</a>
</div> </div>

6
app/partials/welcome.html

@ -22,7 +22,7 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row"> <div class="row">
<div class="col-md-4"> <div class="col-md-4 col-sm-4">
<div class="welcome_footer_card_wrap row"> <div class="welcome_footer_card_wrap row">
<div class="welcome_footer_card welcome_footer_card_messaging"></div> <div class="welcome_footer_card welcome_footer_card_messaging"></div>
<h4>Fast messaging</h4> <h4>Fast messaging</h4>
@ -30,7 +30,7 @@
</div> </div>
</div> </div>
<div class="col-md-4"> <div class="col-md-4 col-sm-4">
<div class="welcome_footer_card_wrap"> <div class="welcome_footer_card_wrap">
<div class="welcome_footer_card welcome_footer_card_filesharing"></div> <div class="welcome_footer_card welcome_footer_card_filesharing"></div>
<h4>Easy file sharing</h4> <h4>Easy file sharing</h4>
@ -38,7 +38,7 @@
</div> </div>
</div> </div>
<div class="col-md-4"> <div class="col-md-4 col-sm-4">
<div class="welcome_footer_card_wrap"> <div class="welcome_footer_card_wrap">
<div class="welcome_footer_card welcome_footer_card_powerful"></div> <div class="welcome_footer_card welcome_footer_card_powerful"></div>
<h4>Powerful tools</h4> <h4>Powerful tools</h4>

Loading…
Cancel
Save