Browse Source

IE10+ fixes

Textfield height
Unsupported media modal
Download blobs
master
Igor Zhukov 10 years ago
parent
commit
847b7df54e
  1. 6
      app/css/app.css
  2. 2
      app/js/controllers.js
  3. 103
      app/js/directives.js
  4. 16
      app/js/lib/mtproto_wrapper.js
  5. 22
      app/js/lib/ng_utils.js
  6. 2
      app/js/locales/en-us.json
  7. 41
      app/js/services.js
  8. 2
      app/partials/desktop/error_modal.html

6
app/css/app.css

@ -1963,12 +1963,14 @@ img.img_fullsize {
} }
.emoji-wysiwyg-editor { .emoji-wysiwyg-editor {
box-sizing: content-box;
font-size: 12px; font-size: 12px;
margin-bottom: 10px; margin-bottom: 10px;
padding: 6px; padding: 6px;
min-height: 50px; min-height: 34px;
height: auto; height: auto;
max-height: 300px; width: auto;
max-height: 284px;
overflow: auto; overflow: auto;
line-height: 17px; line-height: 17px;

2
app/js/controllers.js

@ -1791,7 +1791,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}; };
$scope.download = function () { $scope.download = function () {
$rootScope.downloadVideo($scope.videoID) AppVideoManager.saveVideoFile($scope.videoID);
}; };
$scope.$on('history_delete', function (e, historyUpdate) { $scope.$on('history_delete', function (e, historyUpdate) {

103
app/js/directives.js

@ -1270,7 +1270,7 @@ angular.module('myApp.directives', ['myApp.filters'])
} }
}) })
.directive('myLoadThumb', function(MtpApiFileManager) { .directive('myLoadThumb', function(MtpApiFileManager, FileManager) {
return { return {
link: link, link: link,
@ -1282,15 +1282,15 @@ angular.module('myApp.directives', ['myApp.filters'])
function link ($scope, element, attrs) { function link ($scope, element, attrs) {
var counter = 0; var counter = 0;
var cachedSrc = MtpApiFileManager.getCachedFile( var cachedBlob = MtpApiFileManager.getCachedFile(
$scope.thumb && $scope.thumb &&
$scope.thumb.location && $scope.thumb.location &&
!$scope.thumb.location.empty && !$scope.thumb.location.empty &&
$scope.thumb.location $scope.thumb.location
); );
if (cachedSrc) { if (cachedBlob) {
element.attr('src', cachedSrc); element.attr('src', FileManager.getUrl(cachedBlob, 'image/jpeg'));
} }
if ($scope.thumb && $scope.thumb.width && $scope.thumb.height) { if ($scope.thumb && $scope.thumb.width && $scope.thumb.height) {
element.attr('width', $scope.thumb.width); element.attr('width', $scope.thumb.width);
@ -1311,9 +1311,9 @@ angular.module('myApp.directives', ['myApp.filters'])
return; return;
} }
var cachedSrc = MtpApiFileManager.getCachedFile(newLocation); var cachedBlob = MtpApiFileManager.getCachedFile(newLocation);
if (cachedSrc) { if (cachedBlob) {
element.attr('src', cachedSrc); element.attr('src', FileManager.getUrl(cachedBlob, 'image/jpeg'));
cleanup(); cleanup();
return; return;
} }
@ -1322,9 +1322,9 @@ angular.module('myApp.directives', ['myApp.filters'])
element.attr('src', $scope.thumb.placeholder || 'img/blank.gif'); element.attr('src', $scope.thumb.placeholder || 'img/blank.gif');
} }
MtpApiFileManager.downloadSmallFile($scope.thumb.location).then(function (url) { MtpApiFileManager.downloadSmallFile($scope.thumb.location).then(function (blob) {
if (counterSaved == counter) { if (counterSaved == counter) {
element.attr('src', url); element.attr('src', FileManager.getUrl(blob, 'image/jpeg'));
cleanup(); cleanup();
} }
}, function (e) { }, function (e) {
@ -1348,7 +1348,7 @@ angular.module('myApp.directives', ['myApp.filters'])
}) })
.directive('myLoadFullPhoto', function(MtpApiFileManager, _) { .directive('myLoadFullPhoto', function(MtpApiFileManager, FileManager, _) {
return { return {
link: link, link: link,
@ -1402,10 +1402,10 @@ angular.module('myApp.directives', ['myApp.filters'])
$scope.progress = {enabled: true, percent: 0}; $scope.progress = {enabled: true, percent: 0};
apiPromise.then(function (url) { apiPromise.then(function (blob) {
if (curJump == jump) { if (curJump == jump) {
$scope.progress.enabled = false; $scope.progress.enabled = false;
imgElement.src = url; imgElement.src = FileManager.getUrl(blob, 'image/jpeg');
resize(); resize();
} }
}, function (e) { }, function (e) {
@ -1431,7 +1431,7 @@ angular.module('myApp.directives', ['myApp.filters'])
}) })
.directive('myLoadVideo', function($sce, AppVideoManager, _) { .directive('myLoadVideo', function($sce, AppVideoManager, ErrorService, _) {
return { return {
link: link, link: link,
@ -1448,6 +1448,35 @@ angular.module('myApp.directives', ['myApp.filters'])
downloadPromise.then(function () { downloadPromise.then(function () {
$scope.$emit('ui_height'); $scope.$emit('ui_height');
onContentLoaded(function () {
var videoEl = $('video', element)[0];
if (videoEl) {
var errorAlready = false;
var onVideoError = function (event) {
if (errorAlready) {
return;
}
if (!event.target ||
!event.target.error ||
event.target.error.code == event.target.error.MEDIA_ERR_DECODE ||
event.target.error.code == event.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED) {
errorAlready = true;
ErrorService.show({
error: {
type: 'MEDIA_TYPE_NOT_SUPPORTED',
originalError: event.target && event.target.error
}
});
}
};
videoEl.addEventListener('error', onVideoError, true);
$(videoEl).on('$destroy', function () {
errorAlready = true;
videoEl.removeEventListener('error', onVideoError);
});
}
});
}, function (e) { }, function (e) {
console.log('Download video failed', e, $scope.video); console.log('Download video failed', e, $scope.video);
@ -1516,7 +1545,7 @@ angular.module('myApp.directives', ['myApp.filters'])
} }
}) })
.directive('myLoadDocument', function(MtpApiFileManager, AppDocsManager) { .directive('myLoadDocument', function(MtpApiFileManager, AppDocsManager, FileManager) {
return { return {
link: link, link: link,
@ -1567,7 +1596,8 @@ angular.module('myApp.directives', ['myApp.filters'])
var checkSizesInt; var checkSizesInt;
var realImageWidth, realImageHeight; var realImageWidth, realImageHeight;
AppDocsManager.downloadDoc($scope.document.id).then(function (url) { AppDocsManager.downloadDoc($scope.document.id).then(function (blob) {
var url = FileManager.getUrl(blob, $scope.document.mime_type);
var image = new Image(); var image = new Image();
var limit = 100; // 2 sec var limit = 100; // 2 sec
var checkSizes = function (e) { var checkSizes = function (e) {
@ -2012,7 +2042,7 @@ angular.module('myApp.directives', ['myApp.filters'])
} }
}) })
.directive('myAudioPlayer', function ($timeout, $q, Storage, AppAudioManager, AppDocsManager) { .directive('myAudioPlayer', function ($timeout, $q, Storage, AppAudioManager, AppDocsManager, ErrorService) {
var currentPlayer = false; var currentPlayer = false;
var audioVolume = 0.5; var audioVolume = 0.5;
@ -2023,6 +2053,20 @@ angular.module('myApp.directives', ['myApp.filters'])
} }
}); });
var onAudioError = function (event) {
if (!event.target ||
!event.target.error ||
event.target.error.code == event.target.error.MEDIA_ERR_DECODE ||
event.target.error.code == event.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED) {
ErrorService.show({
error: {
type: 'MEDIA_TYPE_NOT_SUPPORTED',
originalError: event.target && event.target.error
}
});
}
};
return { return {
link: link, link: link,
scope: { scope: {
@ -2077,6 +2121,33 @@ angular.module('myApp.directives', ['myApp.filters'])
downloadPromise.then(function () { downloadPromise.then(function () {
onContentLoaded(function () { onContentLoaded(function () {
var audioEl = $('audio', element)[0];
if (audioEl) {
var errorAlready = false;
var onAudioError = function (event) {
if (errorAlready) {
return;
}
if (!event.target ||
!event.target.error ||
event.target.error.code == event.target.error.MEDIA_ERR_DECODE ||
event.target.error.code == event.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED) {
errorAlready = true;
ErrorService.show({
error: {
type: 'MEDIA_TYPE_NOT_SUPPORTED',
originalError: event.target && event.target.error
}
});
}
};
audioEl.addEventListener('error', onAudioError, true);
$(audioEl).on('$destroy', function () {
errorAlready = true;
audioEl.removeEventListener('error', onAudioError);
});
}
checkPlayer($scope.mediaPlayer.player); checkPlayer($scope.mediaPlayer.player);
$scope.mediaPlayer.player.setVolume(audioVolume); $scope.mediaPlayer.player.setVolume(audioVolume);
$scope.mediaPlayer.player.play(); $scope.mediaPlayer.player.play();

16
app/js/lib/mtproto_wrapper.js

@ -328,7 +328,7 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
if (!cachedSavePromises[fileName]) { if (!cachedSavePromises[fileName]) {
cachedSavePromises[fileName] = getFileStorage().saveFile(fileName, bytes).then(function (blob) { cachedSavePromises[fileName] = getFileStorage().saveFile(fileName, bytes).then(function (blob) {
return cachedDownloads[fileName] = FileManager.getUrl(blob, mimeType); return cachedDownloads[fileName] = blob;
}); });
} }
return cachedSavePromises[fileName]; return cachedSavePromises[fileName];
@ -350,7 +350,7 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
var fileStorage = getFileStorage(); var fileStorage = getFileStorage();
return cachedDownloadPromises[fileName] = fileStorage.getFile(fileName).then(function (blob) { return cachedDownloadPromises[fileName] = fileStorage.getFile(fileName).then(function (blob) {
return cachedDownloads[fileName] = FileManager.getUrl(blob, mimeType); return cachedDownloads[fileName] = blob;
}, function () { }, function () {
var downloadPromise = downloadRequest(location.dc_id, function () { var downloadPromise = downloadRequest(location.dc_id, function () {
// console.log('next small promise'); // console.log('next small promise');
@ -368,7 +368,7 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
return fileStorage.getFileWriter(fileName, mimeType).then(function (fileWriter) { return fileStorage.getFileWriter(fileName, mimeType).then(function (fileWriter) {
return downloadPromise.then(function (result) { return downloadPromise.then(function (result) {
return FileManager.write(fileWriter, result.bytes).then(function () { return FileManager.write(fileWriter, result.bytes).then(function () {
return cachedDownloads[fileName] = FileManager.getUrl(fileWriter.finalize(), mimeType); return cachedDownloads[fileName] = fileWriter.finalize();
}); });
}); });
}); });
@ -400,10 +400,8 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
if (cachedPromise) { if (cachedPromise) {
if (toFileEntry) { if (toFileEntry) {
return cachedPromise.then(function (url) { return cachedPromise.then(function (blob) {
return fileStorage.getFile(fileName).then(function (blob) { return FileManager.copy(blob, toFileEntry);
return FileManager.copy(blob, toFileEntry);
});
}) })
} }
return cachedPromise; return cachedPromise;
@ -430,7 +428,7 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
deferred.resolve(); deferred.resolve();
}, errorHandler); }, errorHandler);
} else { } else {
deferred.resolve(cachedDownloads[fileName] = FileManager.getUrl(blob, mimeType)); deferred.resolve(cachedDownloads[fileName] = blob);
} }
}, function () { }, function () {
var fileWriterPromise = toFileEntry ? FileManager.getFileWriter(toFileEntry) : fileStorage.getFileWriter(fileName, mimeType); var fileWriterPromise = toFileEntry ? FileManager.getFileWriter(toFileEntry) : fileStorage.getFileWriter(fileName, mimeType);
@ -476,7 +474,7 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
if (toFileEntry) { if (toFileEntry) {
deferred.resolve(); deferred.resolve();
} else { } else {
deferred.resolve(cachedDownloads[fileName] = FileManager.getUrl(fileWriter.finalize(), mimeType)); deferred.resolve(cachedDownloads[fileName] = fileWriter.finalize());
} }
} else { } else {
deferred.notify({done: offset + limit, total: size}); deferred.notify({done: offset + limit, total: size});

22
app/js/lib/ng_utils.js

@ -182,11 +182,13 @@ angular.module('izhukov.utils', [])
return 'data:' + mimeType + ';base64,' + bytesToBase64(fileData); return 'data:' + mimeType + ';base64,' + bytesToBase64(fileData);
} }
function downloadFile (url, mimeType, fileName) { function downloadFile (blob, mimeType, fileName) {
// if (Config.Mobile) { if (window.navigator && navigator.msSaveBlob !== undefined) {
// window.open(url, '_blank'); window.navigator.msSaveBlob(blob, fileName);
// return; }
// }
var url = getUrl(blob, mimeType);
var anchor = $('<a>Download</a>') var anchor = $('<a>Download</a>')
.css({position: 'absolute', top: 1, left: 1}) .css({position: 'absolute', top: 1, left: 1})
.attr('href', url) .attr('href', url)
@ -194,8 +196,14 @@ angular.module('izhukov.utils', [])
.attr('download', fileName) .attr('download', fileName)
.appendTo('body'); .appendTo('body');
anchor[0].dataset.downloadurl = [mimeType, fileName, url].join(':'); if (anchor[0].dataset) {
anchor[0].click(); anchor[0].dataset.downloadurl = [mimeType, fileName, url].join(':');
}
try {
anchor[0].click();
} catch (e) {
window.open(url, '_blank');
}
$timeout(function () { $timeout(function () {
anchor.remove(); anchor.remove();
}, 100); }, 100);

2
app/js/locales/en-us.json

@ -204,6 +204,7 @@
"error_modal_flood_title": "Too fast", "error_modal_flood_title": "Too fast",
"error_modal_internal_title": "Server error", "error_modal_internal_title": "Server error",
"error_modal_alert": "Alert", "error_modal_alert": "Alert",
"error_modal_media_not_supported_title": "Unsupported media",
"error_modal_network_description": "Please check your internet connection.", "error_modal_network_description": "Please check your internet connection.",
"error_modal_firstname_invali_description": "The first name you entered is invalid.", "error_modal_firstname_invali_description": "The first name you entered is invalid.",
@ -218,6 +219,7 @@
"error_modal_username_invalid_description": "Sorry, this username is not allowed.", "error_modal_username_invalid_description": "Sorry, this username is not allowed.",
"error_modal_phonebook_required_description": "Telegram needs access to phonebook to import contacts.", "error_modal_phonebook_required_description": "Telegram needs access to phonebook to import contacts.",
"error_modal_username_occupied_description": "Sorry, this username is already taken.", "error_modal_username_occupied_description": "Sorry, this username is already taken.",
"error_modal_media_not_supported_description": "Your browser cannot play this media file. Try downloading the file and opening it in a standalone player.",
"error_modal_bad_request_description": "One of the params is missing or invalid.", "error_modal_bad_request_description": "One of the params is missing or invalid.",
"error_modal_unauthorized_description": "This action requires authorization access. Please {login-link: log in}.", "error_modal_unauthorized_description": "This action requires authorization access. Please {login-link: log in}.",

41
app/js/services.js

@ -602,7 +602,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
} }
}) })
.service('AppMessagesManager', function ($q, $rootScope, $location, $filter, ApiUpdatesManager, AppUsersManager, AppChatsManager, AppPeersManager, AppPhotosManager, AppVideoManager, AppDocsManager, AppAudioManager, MtpApiManager, MtpApiFileManager, RichTextProcessor, NotificationsManager, SearchIndexManager, PeersSelectService,Storage, _) { .service('AppMessagesManager', function ($q, $rootScope, $location, $filter, ApiUpdatesManager, AppUsersManager, AppChatsManager, AppPeersManager, AppPhotosManager, AppVideoManager, AppDocsManager, AppAudioManager, MtpApiManager, MtpApiFileManager, RichTextProcessor, NotificationsManager, SearchIndexManager, PeersSelectService,Storage, FileManager, _) {
var messagesStorage = {}; var messagesStorage = {};
var messagesForHistory = {}; var messagesForHistory = {};
@ -1883,8 +1883,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
notification.tag = peerString; notification.tag = peerString;
if (notificationPhoto.location && !notificationPhoto.location.empty) { if (notificationPhoto.location && !notificationPhoto.location.empty) {
MtpApiFileManager.downloadSmallFile(notificationPhoto.location, notificationPhoto.size).then(function (url) { MtpApiFileManager.downloadSmallFile(notificationPhoto.location, notificationPhoto.size).then(function (blob) {
notification.image = url; notification.image = FileManager.getUrl(blob, 'image/jpeg');
if (message.unread) { if (message.unread) {
NotificationsManager.notify(notification); NotificationsManager.notify(notification);
@ -2337,7 +2337,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
fullPhotoSize.location.dc_id, inputFileLocation, fullPhotoSize.size, { fullPhotoSize.location.dc_id, inputFileLocation, fullPhotoSize.size, {
mime: mimeType, mime: mimeType,
toFileEntry: writableFileEntry toFileEntry: writableFileEntry
}).then(function (url) { }).then(function () {
// console.log('file save done'); // console.log('file save done');
}, function (e) { }, function (e) {
console.log('photo download failed', e); console.log('photo download failed', e);
@ -2346,8 +2346,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}, function () { }, function () {
MtpApiFileManager.downloadFile( MtpApiFileManager.downloadFile(
fullPhotoSize.location.dc_id, inputFileLocation, fullPhotoSize.size, {mime: mimeType} fullPhotoSize.location.dc_id, inputFileLocation, fullPhotoSize.size, {mime: mimeType}
).then(function (url) { ).then(function (blob) {
FileManager.download(url, mimeType, fileName); FileManager.download(blob, mimeType, fileName);
}, function (e) { }, function (e) {
console.log('photo download failed', e); console.log('photo download failed', e);
}); });
@ -2487,6 +2487,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
function downloadVideo (videoID, toFileEntry) { function downloadVideo (videoID, toFileEntry) {
var video = videos[videoID], var video = videos[videoID],
historyVideo = videosForHistory[videoID] || video || {}, historyVideo = videosForHistory[videoID] || video || {},
mimeType = video.mime_type || 'video/ogg',
inputFileLocation = { inputFileLocation = {
_: 'inputVideoFileLocation', _: 'inputVideoFileLocation',
id: videoID, id: videoID,
@ -2496,11 +2497,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
historyVideo.progress = {enabled: !historyVideo.downloaded, percent: 1, total: video.size}; historyVideo.progress = {enabled: !historyVideo.downloaded, percent: 1, total: video.size};
var downloadPromise = MtpApiFileManager.downloadFile(video.dc_id, inputFileLocation, video.size, { var downloadPromise = MtpApiFileManager.downloadFile(video.dc_id, inputFileLocation, video.size, {
mime: video.mime_type || 'video/ogg', mime: mimeType,
toFileEntry: toFileEntry toFileEntry: toFileEntry
}); });
downloadPromise.then(function (url) { downloadPromise.then(function (blob) {
var url = FileManager.getUrl(blob, mimeType);
delete historyVideo.progress; delete historyVideo.progress;
historyVideo.url = $sce.trustAsResourceUrl(url); historyVideo.url = $sce.trustAsResourceUrl(url);
historyVideo.downloaded = true; historyVideo.downloaded = true;
@ -2533,8 +2535,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
downloadVideo(videoID, writableFileEntry); downloadVideo(videoID, writableFileEntry);
} }
}, function () { }, function () {
downloadVideo(videoID).then(function (url) { downloadVideo(videoID).then(function (blob) {
FileManager.download(url, mimeType, fileName); FileManager.download(blob, mimeType, fileName);
}); });
}); });
} }
@ -2606,7 +2608,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
doc.thumb = thumb; doc.thumb = thumb;
doc.canDownload = !(window.chrome && chrome.fileSystem && chrome.fileSystem.chooseEntry); doc.canDownload = !(window.chrome && chrome.fileSystem && chrome.fileSystem.chooseEntry);
doc.withPreview = doc.canDownload && doc.mime_type.match(/^(image\/|application\/pdf)/) ? 1 : 0; doc.withPreview = doc.canDownload && doc.mime_type.match(/^(image\/)/) ? 1 : 0;
if (isGif && doc.thumb) { if (isGif && doc.thumb) {
doc.isSpecial = 'gif'; doc.isSpecial = 'gif';
@ -2654,7 +2656,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
toFileEntry: toFileEntry toFileEntry: toFileEntry
}); });
downloadPromise.then(function (url) { downloadPromise.then(function (blob) {
var url = FileManager.getUrl(blob, doc.mime_type);
delete historyDoc.progress; delete historyDoc.progress;
historyDoc.url = $sce.trustAsResourceUrl(url); historyDoc.url = $sce.trustAsResourceUrl(url);
historyDoc.downloaded = true; historyDoc.downloaded = true;
@ -2698,8 +2701,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
downloadDoc(docID, writableFileEntry); downloadDoc(docID, writableFileEntry);
} }
}, function () { }, function () {
downloadDoc(docID).then(function (url) { downloadDoc(docID).then(function (blob) {
FileManager.download(url, doc.mime_type, doc.file_name); FileManager.download(blob, doc.mime_type, doc.file_name);
}); });
}); });
} }
@ -2755,6 +2758,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
function downloadAudio (audioID, toFileEntry) { function downloadAudio (audioID, toFileEntry) {
var audio = audios[audioID], var audio = audios[audioID],
historyAudio = audiosForHistory[audioID] || audio || {}, historyAudio = audiosForHistory[audioID] || audio || {},
mimeType = audio.mime_type || 'audio/ogg',
inputFileLocation = { inputFileLocation = {
_: 'inputAudioFileLocation', _: 'inputAudioFileLocation',
id: audioID, id: audioID,
@ -2764,11 +2768,12 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
historyAudio.progress = {enabled: !historyAudio.downloaded, percent: 1, total: audio.size}; historyAudio.progress = {enabled: !historyAudio.downloaded, percent: 1, total: audio.size};
var downloadPromise = MtpApiFileManager.downloadFile(audio.dc_id, inputFileLocation, audio.size, { var downloadPromise = MtpApiFileManager.downloadFile(audio.dc_id, inputFileLocation, audio.size, {
mime: audio.mime_type || 'audio/ogg', mime: mimeType,
toFileEntry: toFileEntry toFileEntry: toFileEntry
}); });
downloadPromise.then(function (url) { downloadPromise.then(function (blob) {
var url = FileManager.getUrl(blob, mimeType);
delete historyAudio.progress; delete historyAudio.progress;
historyAudio.url = $sce.trustAsResourceUrl(url); historyAudio.url = $sce.trustAsResourceUrl(url);
historyAudio.downloaded = true; historyAudio.downloaded = true;
@ -2801,8 +2806,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
downloadAudio(audioID, writableFileEntry); downloadAudio(audioID, writableFileEntry);
} }
}, function () { }, function () {
downloadAudio(audioID).then(function (url) { downloadAudio(audioID).then(function (blob) {
FileManager.download(url, mimeType, fileName); FileManager.download(blob, mimeType, fileName);
}); });
}); });
} }

2
app/partials/desktop/error_modal.html

@ -5,6 +5,7 @@
<div class="modal-body"> <div class="modal-body">
<h4 ng-if="error" class="modal_simple_header" ng-switch="error.type"> <h4 ng-if="error" class="modal_simple_header" ng-switch="error.type">
<span ng-switch-when="MEDIA_TYPE_NOT_SUPPORTED" my-i18n="error_modal_media_not_supported_title"></span>
<span ng-switch-default ng-switch="error.code"> <span ng-switch-default ng-switch="error.code">
<span ng-switch-when="400" my-i18n="error_modal_bad_request_title"></span> <span ng-switch-when="400" my-i18n="error_modal_bad_request_title"></span>
<span ng-switch-when="401" my-i18n="error_modal_unauthorized_title"></span> <span ng-switch-when="401" my-i18n="error_modal_unauthorized_title"></span>
@ -35,6 +36,7 @@
<span ng-switch-when="PHONEBOOK_GET_CONTACTS_FAILED" my-i18n="error_modal_phonebook_required_description"></span> <span ng-switch-when="PHONEBOOK_GET_CONTACTS_FAILED" my-i18n="error_modal_phonebook_required_description"></span>
<span ng-switch-when="USERNAME_INVALID" my-i18n="error_modal_username_invalid_description"></span> <span ng-switch-when="USERNAME_INVALID" my-i18n="error_modal_username_invalid_description"></span>
<span ng-switch-when="USERNAME_OCCUPIED" my-i18n="error_modal_username_occupied_description"></span> <span ng-switch-when="USERNAME_OCCUPIED" my-i18n="error_modal_username_occupied_description"></span>
<span ng-switch-when="MEDIA_TYPE_NOT_SUPPORTED" my-i18n="error_modal_media_not_supported_description"></span>
<div ng-switch-default ng-switch="error.code"> <div ng-switch-default ng-switch="error.code">

Loading…
Cancel
Save