File download improvements
Added some opengraph meta tags Fixed multiDC file download problems Added fallback blob mode for downloads (for Safari & Firefox)
This commit is contained in:
parent
b077e126e5
commit
e999975808
@ -9,6 +9,13 @@
|
|||||||
<link rel="stylesheet" href="vendor/jquery.nanoscroller/nanoscroller.css"/>
|
<link rel="stylesheet" href="vendor/jquery.nanoscroller/nanoscroller.css"/>
|
||||||
<link rel="stylesheet" href="css/app.css?4"/>
|
<link rel="stylesheet" href="css/app.css?4"/>
|
||||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||||
|
|
||||||
|
<meta property="og:title" content="Webogram">
|
||||||
|
<meta property="og:url" content="http://zhukov.github.io/webogram">
|
||||||
|
<meta property="og:image" content="http://zhukov.github.io/webogram/img/Logo_2x.png">
|
||||||
|
<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.">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
@ -30,14 +37,14 @@
|
|||||||
|
|
||||||
|
|
||||||
<script type="text/javascript" src="js/lib/config.js"></script>
|
<script type="text/javascript" src="js/lib/config.js"></script>
|
||||||
<script type="text/javascript" src="js/lib/mtproto.js?7"></script>
|
<script type="text/javascript" src="js/lib/mtproto.js?8"></script>
|
||||||
|
|
||||||
<script type="text/javascript" src="js/util.js"></script>
|
<script type="text/javascript" src="js/util.js"></script>
|
||||||
<script type="text/javascript" src="js/app.js?3"></script>
|
<script type="text/javascript" src="js/app.js?4"></script>
|
||||||
<script type="text/javascript" src="js/services.js?6"></script>
|
<script type="text/javascript" src="js/services.js?6"></script>
|
||||||
<script type="text/javascript" src="js/controllers.js?8"></script>
|
<script type="text/javascript" src="js/controllers.js?8"></script>
|
||||||
<script type="text/javascript" src="js/filters.js?3"></script>
|
<script type="text/javascript" src="js/filters.js?3"></script>
|
||||||
<script type="text/javascript" src="js/directives.js?5"></script>
|
<script type="text/javascript" src="js/directives.js?6"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -49,7 +49,7 @@ config(['$locationProvider', '$routeProvider', '$compileProvider', function($loc
|
|||||||
// $locationProvider.html5Mode(true);
|
// $locationProvider.html5Mode(true);
|
||||||
$routeProvider.when('/', {templateUrl: 'partials/welcome.html', controller: 'AppWelcomeController'});
|
$routeProvider.when('/', {templateUrl: 'partials/welcome.html', controller: 'AppWelcomeController'});
|
||||||
$routeProvider.when('/login', {templateUrl: 'partials/login.html?1', controller: 'AppLoginController'});
|
$routeProvider.when('/login', {templateUrl: 'partials/login.html?1', controller: 'AppLoginController'});
|
||||||
$routeProvider.when('/im', {templateUrl: 'partials/im.html?2', controller: 'AppIMController', reloadOnSearch: false});
|
$routeProvider.when('/im', {templateUrl: 'partials/im.html?3', controller: 'AppIMController', reloadOnSearch: false});
|
||||||
$routeProvider.otherwise({redirectTo: '/'});
|
$routeProvider.otherwise({redirectTo: '/'});
|
||||||
|
|
||||||
}]);
|
}]);
|
||||||
|
@ -16,7 +16,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
restrict: 'AE',
|
restrict: 'AE',
|
||||||
scope: true,
|
scope: true,
|
||||||
translude: false,
|
translude: false,
|
||||||
templateUrl: 'partials/dialog.html?2'
|
templateUrl: 'partials/dialog.html?3'
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
restrict: 'AE',
|
restrict: 'AE',
|
||||||
scope: true,
|
scope: true,
|
||||||
translude: false,
|
translude: false,
|
||||||
templateUrl: 'partials/message.html?3'
|
templateUrl: 'partials/message.html?4'
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -359,18 +359,31 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
};
|
};
|
||||||
|
|
||||||
function link (scope, element, attrs) {
|
function link (scope, element, attrs) {
|
||||||
element.src = 'img/blank.gif';
|
var counter = 0;
|
||||||
scope.$watch('thumb.location', function (newVal) {
|
scope.$watch('thumb.location', function (newVal) {
|
||||||
|
var counterSaved = ++counter;
|
||||||
if (!scope.thumb || !scope.thumb.location) {
|
if (!scope.thumb || !scope.thumb.location) {
|
||||||
element.attr('src', scope.thumb && scope.thumb.placeholder || '');
|
element.attr('src', scope.thumb && scope.thumb.placeholder || 'img/blank.gif');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cachedSrc = MtpApiFileManager.getCachedFile(location);
|
||||||
|
if (cachedSrc) {
|
||||||
|
element.attr('src', cachedSrc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.attr('src', scope.thumb.placeholder || 'img/blank.gif');
|
||||||
|
|
||||||
MtpApiFileManager.downloadSmallFile(scope.thumb.location, scope.thumb.size).then(function (url) {
|
MtpApiFileManager.downloadSmallFile(scope.thumb.location, scope.thumb.size).then(function (url) {
|
||||||
element.attr('src', url);
|
if (counterSaved == counter) {
|
||||||
|
element.attr('src', url);
|
||||||
|
}
|
||||||
}, function (e) {
|
}, function (e) {
|
||||||
dLog('Download image failed', e, scope.thumb.location);
|
dLog('Download image failed', e, scope.thumb.location);
|
||||||
element.attr('src', scope.thumb.placeholder || '');
|
if (counterSaved == counter) {
|
||||||
|
element.attr('src', scope.thumb.placeholder || 'img/blank.gif');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -411,24 +424,18 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
};
|
};
|
||||||
|
|
||||||
function link (scope, element, attrs) {
|
function link (scope, element, attrs) {
|
||||||
var imgElement = $('img', element),
|
|
||||||
fullLoaded = false;
|
|
||||||
|
|
||||||
|
var imgElement = $('img', element);
|
||||||
|
|
||||||
imgElement.attr('src', scope.fullPhoto.placeholder || 'img/blank.gif');
|
imgElement
|
||||||
|
.attr('src', MtpApiFileManager.getCachedFile(scope.thumbLocation) || 'img/blank.gif')
|
||||||
|
.addClass('thumb_blurred')
|
||||||
|
.addClass('thumb_blur_animation');
|
||||||
|
|
||||||
if (!scope.fullPhoto.location) {
|
if (!scope.fullPhoto.location) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MtpApiFileManager.getCachedFile(scope.thumbLocation).then(function (url) {
|
|
||||||
if (!fullLoaded) {
|
|
||||||
imgElement
|
|
||||||
.attr('src', url)
|
|
||||||
.addClass('thumb_blurred')
|
|
||||||
.addClass('thumb_blur_animation');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
var apiPromise;
|
var apiPromise;
|
||||||
if (scope.fullPhoto.size) {
|
if (scope.fullPhoto.size) {
|
||||||
@ -446,7 +453,6 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
scope.progress = {enabled: true, percent: 1};
|
scope.progress = {enabled: true, percent: 1};
|
||||||
|
|
||||||
apiPromise.then(function (url) {
|
apiPromise.then(function (url) {
|
||||||
fullLoaded = true;
|
|
||||||
scope.progress.enabled = false;
|
scope.progress.enabled = false;
|
||||||
imgElement
|
imgElement
|
||||||
.attr('src', url)
|
.attr('src', url)
|
||||||
@ -486,7 +492,13 @@ angular.module('myApp.directives', ['myApp.filters'])
|
|||||||
</div>\
|
</div>\
|
||||||
</div>\
|
</div>\
|
||||||
<div class="img_fullsize_wrap" ng-if="!player.src">\
|
<div class="img_fullsize_wrap" ng-if="!player.src">\
|
||||||
<img class="img_fullsize" my-load-thumb thumb="video.thumb" width="{{video.full.width}}" height="{{video.full.height}}" />\
|
<img\
|
||||||
|
class="img_fullsize"\
|
||||||
|
my-load-thumb\
|
||||||
|
thumb="video.thumb"\
|
||||||
|
width="{{video.full.width}}"\
|
||||||
|
height="{{video.full.height}}"\
|
||||||
|
/>\
|
||||||
</div>\
|
</div>\
|
||||||
<div class="video_full_player" ng-if="player.src">\
|
<div class="video_full_player" ng-if="player.src">\
|
||||||
<embed ng-src="{{player.src}}" width="{{video.full.width}}" height="{{video.full.height}}" autoplay="true" CONTROLLER="TRUE" loop="false" pluginspace="http://www.apple.com/quicktime/" ng-if="player.quicktime"/>\
|
<embed ng-src="{{player.src}}" width="{{video.full.width}}" height="{{video.full.height}}" autoplay="true" CONTROLLER="TRUE" loop="false" pluginspace="http://www.apple.com/quicktime/" ng-if="player.quicktime"/>\
|
||||||
|
@ -2297,14 +2297,16 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
var apiUploadPromise = $q.when();
|
var apiUploadPromise = $q.when();
|
||||||
var cachedSavePromises = {};
|
var cachedSavePromises = {};
|
||||||
var cachedDownloadPromises = {};
|
var cachedDownloadPromises = {};
|
||||||
|
var cachedDownloads = {};
|
||||||
|
|
||||||
var downloadPulls = {};
|
var downloadPulls = {};
|
||||||
var downloadActive = 0;
|
var downloadActives = {};
|
||||||
var downloadLimit = 5;
|
var downloadLimit = 5;
|
||||||
|
|
||||||
function downloadRequest(dcID, cb, activeDelta) {
|
function downloadRequest(dcID, cb, activeDelta) {
|
||||||
if (downloadPulls[dcID] === undefined) {
|
if (downloadPulls[dcID] === undefined) {
|
||||||
downloadPulls[dcID] = [];
|
downloadPulls[dcID] = [];
|
||||||
|
downloadActives[dcID] = 0
|
||||||
}
|
}
|
||||||
var downloadPull = downloadPulls[dcID];
|
var downloadPull = downloadPulls[dcID];
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
@ -2319,25 +2321,25 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
function downloadCheck(dcID) {
|
function downloadCheck(dcID) {
|
||||||
var downloadPull = downloadPulls[dcID];
|
var downloadPull = downloadPulls[dcID];
|
||||||
|
|
||||||
if (downloadActive >= downloadLimit || !downloadPull || !downloadPull.length) {
|
if (downloadActives[dcID] >= downloadLimit || !downloadPull || !downloadPull.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = downloadPull.shift(),
|
var data = downloadPull.shift(),
|
||||||
activeDelta = data.activeDelta || 1;
|
activeDelta = data.activeDelta || 1;
|
||||||
|
|
||||||
downloadActive += activeDelta;
|
downloadActives[dcID] += activeDelta;
|
||||||
|
|
||||||
var a = index++;
|
var a = index++;
|
||||||
data.cb()
|
data.cb()
|
||||||
.then(function (result) {
|
.then(function (result) {
|
||||||
downloadActive -= activeDelta;
|
downloadActives[dcID] -= activeDelta;
|
||||||
downloadCheck(dcID);
|
downloadCheck(dcID);
|
||||||
|
|
||||||
data.deferred.resolve(result);
|
data.deferred.resolve(result);
|
||||||
|
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
downloadActive -= activeDelta;
|
downloadActives[dcID] -= activeDelta;
|
||||||
downloadCheck(dcID);
|
downloadCheck(dcID);
|
||||||
|
|
||||||
data.deferred.reject(error);
|
data.deferred.reject(error);
|
||||||
@ -2351,7 +2353,7 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
|
|
||||||
$window.requestFileSystem = $window.requestFileSystem || $window.webkitRequestFileSystem;
|
$window.requestFileSystem = $window.requestFileSystem || $window.webkitRequestFileSystem;
|
||||||
|
|
||||||
if (!$window.requestFileSystem) {
|
if (!$window.requestFileSystem/* || true*/) {
|
||||||
return $q.reject({type: 'FS_BROWSER_UNSUPPORTED', description: 'requestFileSystem not present'});
|
return $q.reject({type: 'FS_BROWSER_UNSUPPORTED', description: 'requestFileSystem not present'});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2404,23 +2406,12 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function getCachedFile (location) {
|
function getCachedFile (location) {
|
||||||
|
if (!location) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
var fileName = getFileName(location);
|
var fileName = getFileName(location);
|
||||||
|
|
||||||
if (cachedSavePromises[fileName]) {
|
return cachedDownloads[fileName] || false;
|
||||||
return cachedSavePromises[fileName];
|
|
||||||
}
|
|
||||||
var deferred = $q.defer(),
|
|
||||||
errorHandler = function (error) {
|
|
||||||
deferred.reject();
|
|
||||||
};
|
|
||||||
|
|
||||||
requestFS().then(function () {
|
|
||||||
cachedFS.root.getFile(fileName, {create: false}, function(fileEntry) {
|
|
||||||
deferred.resolve(fileEntry.toURL());
|
|
||||||
}, errorHandler);
|
|
||||||
}, errorHandler);
|
|
||||||
|
|
||||||
return deferred.promise;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveSmallFile (location, bytes) {
|
function saveSmallFile (location, bytes) {
|
||||||
@ -2434,17 +2425,18 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
errorHandler = function (error) {
|
errorHandler = function (error) {
|
||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
if (cacheFileWriter) cacheFileWriter.truncate();
|
if (cacheFileWriter) cacheFileWriter.truncate();
|
||||||
|
errorHandler = angular.noop;
|
||||||
};
|
};
|
||||||
|
|
||||||
requestFS().then(function () {
|
requestFS().then(function () {
|
||||||
cachedFS.root.getFile(fileName, {create: false}, function(fileEntry) {
|
cachedFS.root.getFile(fileName, {create: false}, function(fileEntry) {
|
||||||
deferred.resolve(fileEntry.toURL());
|
deferred.resolve(cachedDownloads[fileName] = fileEntry.toURL());
|
||||||
}, function () {
|
}, function () {
|
||||||
cachedFS.root.getFile(fileName, {create: true}, function(fileEntry) {
|
cachedFS.root.getFile(fileName, {create: true}, function(fileEntry) {
|
||||||
fileEntry.createWriter(function (fileWriter) {
|
fileEntry.createWriter(function (fileWriter) {
|
||||||
cacheFileWriter = fileWriter;
|
cacheFileWriter = fileWriter;
|
||||||
fileWriteBytes(fileWriter, bytes).then(function () {
|
fileWriteBytes(fileWriter, bytes).then(function () {
|
||||||
deferred.resolve(fileEntry.toURL());
|
deferred.resolve(cachedDownloads[fileName] = fileEntry.toURL());
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
@ -2468,6 +2460,7 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
errorHandler = function (error) {
|
errorHandler = function (error) {
|
||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
if (cacheFileWriter) cacheFileWriter.truncate();
|
if (cacheFileWriter) cacheFileWriter.truncate();
|
||||||
|
errorHandler = angular.noop;
|
||||||
},
|
},
|
||||||
doDownload = function () {
|
doDownload = function () {
|
||||||
cachedFS.root.getFile(fileName, {create: true}, function(fileEntry) {
|
cachedFS.root.getFile(fileName, {create: true}, function(fileEntry) {
|
||||||
@ -2485,7 +2478,7 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
downloadPromise.then(function (result) {
|
downloadPromise.then(function (result) {
|
||||||
fileWriteBytes(fileWriter, result.bytes).then(function () {
|
fileWriteBytes(fileWriter, result.bytes).then(function () {
|
||||||
// dLog('Success', location, fileEntry.toURL());
|
// dLog('Success', location, fileEntry.toURL());
|
||||||
deferred.resolve(fileEntry.toURL());
|
deferred.resolve(cachedDownloads[fileName] = fileEntry.toURL());
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
@ -2496,7 +2489,7 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
cachedFS.root.getFile(fileName, {create: false}, function(fileEntry) {
|
cachedFS.root.getFile(fileName, {create: false}, function(fileEntry) {
|
||||||
fileEntry.file(function(file) {
|
fileEntry.file(function(file) {
|
||||||
if (file.size) {
|
if (file.size) {
|
||||||
deferred.resolve(fileEntry.toURL());
|
deferred.resolve(cachedDownloads[fileName] = fileEntry.toURL());
|
||||||
} else {
|
} else {
|
||||||
dLog('Small file empty', file);
|
dLog('Small file empty', file);
|
||||||
doDownload();
|
doDownload();
|
||||||
@ -2513,7 +2506,7 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
limit: 0
|
limit: 0
|
||||||
}, {dcID: location.dc_id});
|
}, {dcID: location.dc_id});
|
||||||
}).then(function (result) {
|
}).then(function (result) {
|
||||||
deferred.resolve('data:image/jpeg;base64,' + bytesToBase64(result.bytes))
|
deferred.resolve(cachedDownloads[fileName] = 'data:image/jpeg;base64,' + bytesToBase64(result.bytes))
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -2536,6 +2529,7 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
// dLog('fail');
|
// dLog('fail');
|
||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
if (cacheFileWriter) cacheFileWriter.truncate();
|
if (cacheFileWriter) cacheFileWriter.truncate();
|
||||||
|
errorHandler = angular.noop;
|
||||||
},
|
},
|
||||||
saveToFileEntry = function (fileEntry) {
|
saveToFileEntry = function (fileEntry) {
|
||||||
fileEntry.createWriter(function (fileWriter) {
|
fileEntry.createWriter(function (fileWriter) {
|
||||||
@ -2571,7 +2565,7 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
}, errorHandler).then(function () {
|
}, errorHandler).then(function () {
|
||||||
|
|
||||||
if (isFinal) {
|
if (isFinal) {
|
||||||
deferred.resolve(fileEntry.toURL('image/jpeg'));
|
deferred.resolve(cachedDownloads[fileName] = fileEntry.toURL('image/jpeg'));
|
||||||
} else {
|
} else {
|
||||||
// dLog('notify', {done: offset + limit, total: size});
|
// dLog('notify', {done: offset + limit, total: size});
|
||||||
deferred.notify({done: offset + limit, total: size});
|
deferred.notify({done: offset + limit, total: size});
|
||||||
@ -2590,9 +2584,6 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
}
|
}
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
|
|
||||||
},
|
|
||||||
doDownload = function () {
|
|
||||||
cachedFS.root.getFile(fileName, {create: true}, saveToFileEntry, errorHandler);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (fileEntry) {
|
if (fileEntry) {
|
||||||
@ -2603,14 +2594,68 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
fileEntry.file(function(file) {
|
fileEntry.file(function(file) {
|
||||||
dLog('check size', file.size, size);
|
dLog('check size', file.size, size);
|
||||||
if (file.size >= size) {
|
if (file.size >= size) {
|
||||||
deferred.resolve(fileEntry.toURL());
|
deferred.resolve(cachedDownloads[fileName] = fileEntry.toURL());
|
||||||
} else {
|
} else {
|
||||||
dLog('File bad size', file, size);
|
dLog('File bad size', file, size);
|
||||||
doDownload();
|
cachedFS.root.getFile(fileName, {create: true}, saveToFileEntry, errorHandler)
|
||||||
}
|
}
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
}, doDownload);
|
}, function () {
|
||||||
}, errorHandler);
|
cachedFS.root.getFile(fileName, {create: true}, saveToFileEntry, errorHandler)
|
||||||
|
});
|
||||||
|
}, function () {
|
||||||
|
|
||||||
|
var blobParts = [];
|
||||||
|
var limit = size > 30400 ? 524288 : 4096;
|
||||||
|
var writeBlobPromise = $q.when(),
|
||||||
|
writeBlobDeferred;
|
||||||
|
for (var offset = 0; offset < size; offset += limit) {
|
||||||
|
writeBlobDeferred = $q.defer();
|
||||||
|
(function (isFinal, offset, writeBlobDeferred, writeBlobPromise) {
|
||||||
|
return downloadRequest(dcID, function () {
|
||||||
|
return MtpApiManager.invokeApi('upload.getFile', {
|
||||||
|
location: location,
|
||||||
|
offset: offset,
|
||||||
|
limit: limit
|
||||||
|
}, {dcID: dcID});
|
||||||
|
}, 6).then(function (result) {
|
||||||
|
writeBlobPromise.then(function () {
|
||||||
|
try {
|
||||||
|
blobParts.push(bytesToArrayBuffer(result.bytes));
|
||||||
|
writeBlobDeferred.resolve();
|
||||||
|
|
||||||
|
if (isFinal) {
|
||||||
|
try {
|
||||||
|
var blob = new Blob(blobParts, {type: '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('image/jpeg');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
window.URL = window.URL || window.webkitURL;
|
||||||
|
deferred.resolve(cachedDownloads[fileName] = URL.createObjectURL(blob));
|
||||||
|
} else {
|
||||||
|
deferred.notify({done: offset + limit, total: size});
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
errorHandler(e);
|
||||||
|
}
|
||||||
|
}, errorHandler);
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
})(offset + limit >= size, offset, writeBlobDeferred, writeBlobPromise);
|
||||||
|
|
||||||
|
writeBlobPromise = writeBlobDeferred.promise;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return cachedDownloadPromises[fileName] = deferred.promise;
|
return cachedDownloadPromises[fileName] = deferred.promise;
|
||||||
@ -2626,6 +2671,7 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
dLog('fail');
|
dLog('fail');
|
||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
if (cacheFileWriter) cacheFileWriter.truncate();
|
if (cacheFileWriter) cacheFileWriter.truncate();
|
||||||
|
errorHandler = angular.noop;
|
||||||
};
|
};
|
||||||
|
|
||||||
requestFS().then(function () {
|
requestFS().then(function () {
|
||||||
@ -2660,6 +2706,7 @@ factory('MtpApiFileManager', function (MtpApiManager, $q, $window) {
|
|||||||
errorHandler = function (error) {
|
errorHandler = function (error) {
|
||||||
dLog('error', error);
|
dLog('error', error);
|
||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
|
errorHandler = angular.noop;
|
||||||
},
|
},
|
||||||
part = 0,
|
part = 0,
|
||||||
offset,
|
offset,
|
||||||
|
@ -213,7 +213,7 @@ angular.module('myApp.services', [])
|
|||||||
scope.userID = userID;
|
scope.userID = userID;
|
||||||
|
|
||||||
var modalInstance = $modal.open({
|
var modalInstance = $modal.open({
|
||||||
templateUrl: 'partials/user_modal.html',
|
templateUrl: 'partials/user_modal.html?1',
|
||||||
controller: 'UserModalController',
|
controller: 'UserModalController',
|
||||||
scope: scope,
|
scope: scope,
|
||||||
windowClass: 'user_modal_window',
|
windowClass: 'user_modal_window',
|
||||||
@ -335,7 +335,7 @@ angular.module('myApp.services', [])
|
|||||||
scope.chatID = chatID;
|
scope.chatID = chatID;
|
||||||
|
|
||||||
var modalInstance = $modal.open({
|
var modalInstance = $modal.open({
|
||||||
templateUrl: 'partials/chat_modal.html?2',
|
templateUrl: 'partials/chat_modal.html?3',
|
||||||
controller: 'ChatModalController',
|
controller: 'ChatModalController',
|
||||||
windowClass: 'chat_modal_window',
|
windowClass: 'chat_modal_window',
|
||||||
scope: scope
|
scope: scope
|
||||||
|
@ -8,7 +8,10 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="chat_modal_image_wrap pull-left">
|
<div class="chat_modal_image_wrap pull-left">
|
||||||
<img class="chat_modal_image" src="img/blank.gif" my-load-thumb thumb="chatFull.thumb"/>
|
<img
|
||||||
|
class="chat_modal_image"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="chatFull.thumb"/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="chat_modal_info_wrap clearfix">
|
<div class="chat_modal_info_wrap clearfix">
|
||||||
@ -27,7 +30,11 @@
|
|||||||
|
|
||||||
<div class="chat_modal_participant_wrap clearfix" ng-repeat="participant in chatFull.participants.participants">
|
<div class="chat_modal_participant_wrap clearfix" ng-repeat="participant in chatFull.participants.participants">
|
||||||
<a ng-click="openUser(participant.user_id)" class="chat_modal_participant_photo pull-left">
|
<a ng-click="openUser(participant.user_id)" class="chat_modal_participant_photo pull-left">
|
||||||
<img class="chat_modal_participant_photo" my-load-thumb thumb="participant.userPhoto"/>
|
<img
|
||||||
|
class="chat_modal_participant_photo"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="participant.userPhoto"
|
||||||
|
/>
|
||||||
<i class="icon modal_participant_online" ng-show="participant.user.status._ == 'userStatusOnline'"></i>
|
<i class="icon modal_participant_online" ng-show="participant.user.status._ == 'userStatusOnline'"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="chat_modal_participant_name">
|
<div class="chat_modal_participant_name">
|
||||||
|
@ -4,11 +4,19 @@
|
|||||||
<div class="im_dialog_date">
|
<div class="im_dialog_date">
|
||||||
{{dialogMessage.date | dateOrTime}}
|
{{dialogMessage.date | dateOrTime}}
|
||||||
</div>
|
</div>
|
||||||
<span class="im_dialog_badge badge" ng-show="dialogMessage.unreadCount > 0" ng-bind="dialogMessage.unreadCount"></span>
|
<span
|
||||||
|
class="im_dialog_badge badge"
|
||||||
|
ng-show="dialogMessage.unreadCount > 0"
|
||||||
|
ng-bind="dialogMessage.unreadCount"
|
||||||
|
></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="im_dialog_photo pull-left">
|
<div class="im_dialog_photo pull-left">
|
||||||
<img class="im_dialog_photo" src="img/blank.gif" my-load-thumb thumb="dialogMessage.peerPhoto" />
|
<img
|
||||||
|
class="im_dialog_photo"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="dialogMessage.peerPhoto"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="im_dialog_message_wrap">
|
<div class="im_dialog_message_wrap">
|
||||||
@ -22,7 +30,14 @@
|
|||||||
|
|
||||||
<div class="im_dialog_message">
|
<div class="im_dialog_message">
|
||||||
<span class="im_dialog_chat_from_wrap">
|
<span class="im_dialog_chat_from_wrap">
|
||||||
<span class="im_dialog_chat_from" ng-if="!dialogMessage.out && dialogMessage.chatID" ng-bind-html="dialogMessage.fromUser.rFirstName"></span><span class="im_dialog_chat_from" ng-if="dialogMessage.out">You</span>{{((dialogMessage.out || dialogMessage.peerID < 0) && (dialogMessage.message.length || dialogMessage.media && dialogMessage.media._ != 'messageMediaEmpty')) ? ':' : ''}}
|
<span
|
||||||
|
class="im_dialog_chat_from"
|
||||||
|
ng-if="!dialogMessage.out && dialogMessage.chatID"
|
||||||
|
ng-bind-html="dialogMessage.fromUser.rFirstName"
|
||||||
|
></span><span
|
||||||
|
class="im_dialog_chat_from"
|
||||||
|
ng-if="dialogMessage.out"
|
||||||
|
>You</span>{{((dialogMessage.out || dialogMessage.peerID < 0) && (dialogMessage.message.length || dialogMessage.media && dialogMessage.media._ != 'messageMediaEmpty')) ? ':' : ''}}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="im_dialog_message_media" ng-if="dialogMessage.media && dialogMessage.media._ != 'messageMediaEmpty'" ng-switch="dialogMessage.media._">
|
<span class="im_dialog_message_media" ng-if="dialogMessage.media && dialogMessage.media._ != 'messageMediaEmpty'" ng-switch="dialogMessage.media._">
|
||||||
|
@ -80,14 +80,26 @@
|
|||||||
|
|
||||||
<div class="im_send_form_wrap clearfix" ng-controller="AppImSendController">
|
<div class="im_send_form_wrap clearfix" ng-controller="AppImSendController">
|
||||||
<div class="pull-right im_panel_peer_photo" ng-click="openUser(historyPeer.id)" ng-if="historyPeer.id > 0">
|
<div class="pull-right im_panel_peer_photo" ng-click="openUser(historyPeer.id)" ng-if="historyPeer.id > 0">
|
||||||
<img class="im_panel_peer_photo" src="img/blank.gif" my-load-thumb thumb="historyPeer.photo" />
|
<img
|
||||||
|
class="im_panel_peer_photo"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="historyPeer.photo"
|
||||||
|
/>
|
||||||
<i class="icon im_panel_peer_online" ng-show="historyPeer.data.status._ == 'userStatusOnline'"></i>
|
<i class="icon im_panel_peer_online" ng-show="historyPeer.data.status._ == 'userStatusOnline'"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="pull-right im_panel_peer_photo" ng-click="openChat(-historyPeer.id)" ng-if="historyPeer.id < 0">
|
<div class="pull-right im_panel_peer_photo" ng-click="openChat(-historyPeer.id)" ng-if="historyPeer.id < 0">
|
||||||
<img class="im_panel_peer_photo" src="img/blank.gif" my-load-thumb thumb="historyPeer.photo" />
|
<img
|
||||||
|
class="im_panel_peer_photo"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="historyPeer.photo"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="pull-left im_panel_own_photo">
|
<div class="pull-left im_panel_own_photo">
|
||||||
<img class="im_panel_own_photo" src="img/blank.gif" my-load-thumb thumb="ownPhoto" />
|
<img
|
||||||
|
class="im_panel_own_photo"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="ownPhoto"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<form my-send-form draft-message="draftMessage" class="im_send_form" ng-submit="sendMessage($event)">
|
<form my-send-form draft-message="draftMessage" class="im_send_form" ng-submit="sendMessage($event)">
|
||||||
<div class="im_send_dropbox_wrap"> Drop photos here to send </div>
|
<div class="im_send_dropbox_wrap"> Drop photos here to send </div>
|
||||||
|
@ -43,7 +43,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a ng-if="historyMessage.action._ == 'messageActionChatEditPhoto'" class="im_service_message_photo_thumb" href="" ng-click="openPhoto(historyMessage.action.photo.id)">
|
<a ng-if="historyMessage.action._ == 'messageActionChatEditPhoto'" class="im_service_message_photo_thumb" href="" ng-click="openPhoto(historyMessage.action.photo.id)">
|
||||||
<img class="im_service_message_photo_thumb" src="img/blank.gif" my-load-thumb thumb="historyMessage.action.photo.thumb" width="{{historyMessage.action.photo.thumb.width}}" height="{{historyMessage.action.photo.thumb.height}}" />
|
<img
|
||||||
|
class="im_service_message_photo_thumb"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="historyMessage.action.photo.thumb"
|
||||||
|
width="{{historyMessage.action.photo.thumb.width}}"
|
||||||
|
height="{{historyMessage.action.photo.thumb.height}}"
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -52,7 +58,11 @@
|
|||||||
<i class="icon-message-status" ng-class="{'icon-message-status-unread': historyMessage.unread, 'icon-message-status-pending': historyMessage.pending}"></i>
|
<i class="icon-message-status" ng-class="{'icon-message-status-unread': historyMessage.unread, 'icon-message-status-pending': historyMessage.pending}"></i>
|
||||||
|
|
||||||
<a ng-click="openUser(historyMessage.from_id)" class="im_message_from_photo pull-left">
|
<a ng-click="openUser(historyMessage.from_id)" class="im_message_from_photo pull-left">
|
||||||
<img class="im_message_from_photo" src="img/blank.gif" my-load-thumb thumb="historyMessage.fromPhoto"/>
|
<img
|
||||||
|
class="im_message_from_photo"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="historyMessage.fromPhoto"
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
<div class="im_message_meta pull-right text-right">
|
<div class="im_message_meta pull-right text-right">
|
||||||
<i ng-if="historyMessage.out" class="icon icon-message-status-tick" ng-class="{'message-status-delivered-tick': true, 'message-status-unread-tick': historyMessage.unread}"></i>
|
<i ng-if="historyMessage.out" class="icon icon-message-status-tick" ng-class="{'message-status-delivered-tick': true, 'message-status-unread-tick': historyMessage.unread}"></i>
|
||||||
@ -71,11 +81,23 @@
|
|||||||
<div class="im_message_media" ng-if="historyMessage.media && historyMessage.media._ != 'messageMediaEmpty'" ng-switch="historyMessage.media._">
|
<div class="im_message_media" ng-if="historyMessage.media && historyMessage.media._ != 'messageMediaEmpty'" ng-switch="historyMessage.media._">
|
||||||
|
|
||||||
<a ng-switch-when="messageMediaPhoto" class="im_message_photo_thumb" href="" ng-click="openPhoto(historyMessage.media.photo.id)" >
|
<a ng-switch-when="messageMediaPhoto" class="im_message_photo_thumb" href="" ng-click="openPhoto(historyMessage.media.photo.id)" >
|
||||||
<img class="im_message_photo_thumb" src="img/blank.gif" my-load-thumb thumb="historyMessage.media.photo.thumb" width="{{historyMessage.media.photo.thumb.width}}" height="{{historyMessage.media.photo.thumb.height}}" />
|
<img
|
||||||
|
class="im_message_photo_thumb"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="historyMessage.media.photo.thumb"
|
||||||
|
width="{{historyMessage.media.photo.thumb.width}}"
|
||||||
|
height="{{historyMessage.media.photo.thumb.height}}"
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a ng-switch-when="messageMediaVideo" class="im_message_video_thumb" href="" ng-click="openVideo(historyMessage.media.video.id)">
|
<a ng-switch-when="messageMediaVideo" class="im_message_video_thumb" href="" ng-click="openVideo(historyMessage.media.video.id)">
|
||||||
<img class="im_message_video_thumb" src="img/blank.gif" my-load-thumb thumb="historyMessage.media.video.thumb" width="{{historyMessage.media.video.thumb.width}}" height="{{historyMessage.media.video.thumb.height}}" />
|
<img
|
||||||
|
class="im_message_video_thumb"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="historyMessage.media.video.thumb"
|
||||||
|
width="{{historyMessage.media.video.thumb.width}}"
|
||||||
|
height="{{historyMessage.media.video.thumb.height}}"
|
||||||
|
/>
|
||||||
<div class="im_message_video_duration_wrap" style="width: {{historyMessage.media.video.thumb.width}}px;">
|
<div class="im_message_video_duration_wrap" style="width: {{historyMessage.media.video.thumb.width}}px;">
|
||||||
<span class="im_message_video_duration pull-right">{{historyMessage.media.video.duration | duration}}</span>
|
<span class="im_message_video_duration pull-right">{{historyMessage.media.video.duration | duration}}</span>
|
||||||
<span class="glyphicon glyphicon-facetime-video"></span>
|
<span class="glyphicon glyphicon-facetime-video"></span>
|
||||||
@ -117,7 +139,11 @@
|
|||||||
|
|
||||||
<div ng-switch-when="messageMediaContact">
|
<div ng-switch-when="messageMediaContact">
|
||||||
<a ng-click="openUser(historyMessage.media.user.id)" class="im_message_contact_photo pull-left" ng-if="historyMessage.media.user">
|
<a ng-click="openUser(historyMessage.media.user.id)" class="im_message_contact_photo pull-left" ng-if="historyMessage.media.user">
|
||||||
<img class="im_message_contact_photo" src="img/blank.gif" my-load-thumb thumb="historyMessage.media.userPhoto"/>
|
<img
|
||||||
|
class="im_message_contact_photo"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="historyMessage.media.userPhoto"
|
||||||
|
/>
|
||||||
</a>
|
</a>
|
||||||
<div class="im_message_contact_name"><span class="glyphicon glyphicon-user"></span>
|
<div class="im_message_contact_name"><span class="glyphicon glyphicon-user"></span>
|
||||||
{{historyMessage.media.first_name}} {{historyMessage.media.last_name}}
|
{{historyMessage.media.first_name}} {{historyMessage.media.last_name}}
|
||||||
|
@ -9,7 +9,11 @@
|
|||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
<div class="user_modal_image_wrap pull-left">
|
<div class="user_modal_image_wrap pull-left">
|
||||||
<img class="user_modal_image" my-load-thumb thumb="user.thumb"/>
|
<img
|
||||||
|
class="user_modal_image"
|
||||||
|
my-load-thumb
|
||||||
|
thumb="user.thumb"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="user_modal_info_wrap clearfix">
|
<div class="user_modal_info_wrap clearfix">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user