Implement #225 - shared photos navigation
Also fixed fetching Vector<…> results
This commit is contained in:
parent
7e2b65d526
commit
a6e5aa9e40
@ -339,13 +339,13 @@ input[type="number"]::-webkit-inner-spin-button {
|
||||
height: 100%;
|
||||
}
|
||||
.modal_close {
|
||||
background: url(../img/icons/CloseHover_2x.png) 0 0 no-repeat;
|
||||
background-size: 33px 33px;
|
||||
background: url(../img/icons/PhotoControls.png) 0 -53px no-repeat;
|
||||
background-size: 33px 86px;
|
||||
width: 33px;
|
||||
height: 33px;
|
||||
float: right;
|
||||
margin: 60px 30px 0 0;
|
||||
opacity: 0.5;
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
|
||||
-webkit-transition : .2s;
|
||||
@ -354,7 +354,40 @@ input[type="number"]::-webkit-inner-spin-button {
|
||||
transition : .2s;
|
||||
}
|
||||
.modal_close_wrap:hover .modal_close {
|
||||
opacity: 1;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
|
||||
.modal_prev_wrap {
|
||||
cursor: pointer;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
.modal_prev {
|
||||
background: url(../img/icons/PhotoControls.png) 0 0 no-repeat;
|
||||
background-size: 33px 86px;
|
||||
width: 33px;
|
||||
height: 33px;
|
||||
float: left;
|
||||
margin: 60px 0 0 30px;
|
||||
opacity: 0.6;
|
||||
pointer-events: none;
|
||||
|
||||
-webkit-transition : .2s;
|
||||
-moz-transition : .2s;
|
||||
-o-transition : .2s;
|
||||
transition : .2s;
|
||||
}
|
||||
.modal_prev_wrap:hover .modal_prev {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.is_1x .modal_close,
|
||||
.is_1x .modal_prev {
|
||||
background-image: url(../img/icons/PhotoControls_1x.png);
|
||||
}
|
||||
|
||||
.text-invisible {
|
||||
@ -1849,6 +1882,12 @@ img.img_fullsize {
|
||||
color: #777;
|
||||
margin: 20px 0 0;
|
||||
}
|
||||
.media_modal_actions {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.media_modal_action_link {
|
||||
margin-left: 15px;
|
||||
}
|
||||
.media_modal_author {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 789 B |
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 783 B |
Binary file not shown.
Before Width: | Height: | Size: 1.5 KiB |
BIN
app/img/icons/PhotoControls.png
Normal file
BIN
app/img/icons/PhotoControls.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
BIN
app/img/icons/PhotoControls_1x.png
Normal file
BIN
app/img/icons/PhotoControls_1x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
@ -866,8 +866,128 @@ angular.module('myApp.controllers', [])
|
||||
}
|
||||
})
|
||||
|
||||
.controller('PhotoModalController', function ($scope, AppPhotosManager) {
|
||||
.controller('PhotoModalController', function ($q, $scope, $rootScope, $modalInstance, AppPhotosManager, AppMessagesManager, AppPeersManager, PeersSelectService, ErrorService) {
|
||||
|
||||
$scope.photo = AppPhotosManager.wrapForFull($scope.photoID);
|
||||
$scope.nav = {};
|
||||
|
||||
var peerID = AppMessagesManager.getMessagePeer(AppMessagesManager.getMessage($scope.messageID)),
|
||||
inputPeer = AppPeersManager.getInputPeerByID(peerID),
|
||||
inputQuery = '',
|
||||
inputFilter = {_: 'inputMessagesFilterPhotos'},
|
||||
list = [$scope.messageID],
|
||||
maxID = $scope.messageID,
|
||||
hasMore = true;
|
||||
|
||||
updatePrevNext();
|
||||
|
||||
AppMessagesManager.getSearch(inputPeer, inputQuery, inputFilter, 0, 1000).then(function (searchCachedResult) {
|
||||
// console.log(dT(), 'search cache', searchCachedResult);
|
||||
if (searchCachedResult.history.indexOf($scope.messageID) >= 0) {
|
||||
list = searchCachedResult.history;
|
||||
maxID = list[list.length - 1];
|
||||
|
||||
updatePrevNext();
|
||||
}
|
||||
// console.log(dT(), list, maxID);
|
||||
});
|
||||
|
||||
|
||||
var jump = 0;
|
||||
function movePosition (sign) {
|
||||
var curIndex = list.indexOf($scope.messageID),
|
||||
index = curIndex >= 0 ? curIndex + sign : 0,
|
||||
curJump = ++jump;
|
||||
|
||||
var promise = index >= list.length ? loadMore() : $q.when();
|
||||
promise.then(function () {
|
||||
if (curJump != jump) {
|
||||
return;
|
||||
}
|
||||
|
||||
$scope.messageID = list[index];
|
||||
$scope.photoID = AppMessagesManager.getMessage($scope.messageID).media.photo.id;
|
||||
$scope.photo = AppPhotosManager.wrapForFull($scope.photoID);
|
||||
|
||||
updatePrevNext();
|
||||
});
|
||||
};
|
||||
|
||||
var loadingPromise = false;
|
||||
function loadMore () {
|
||||
if (loadingPromise) return loadingPromise;
|
||||
|
||||
return loadingPromise = AppMessagesManager.getSearch(inputPeer, inputQuery, inputFilter, maxID).then(function (searchResult) {
|
||||
maxID = searchResult.history[searchResult.history.length - 1];
|
||||
list = list.concat(searchResult.history);
|
||||
|
||||
hasMore = searchResult.history.length || list.length < searchResult.count;
|
||||
updatePrevNext();
|
||||
loadingPromise = false;
|
||||
});
|
||||
};
|
||||
|
||||
function updatePrevNext () {
|
||||
var index = list.indexOf($scope.messageID);
|
||||
$scope.nav.hasNext = hasMore || index < list.length - 1;
|
||||
$scope.nav.hasPrev = index > 0;
|
||||
};
|
||||
|
||||
$scope.nav.next = function () {
|
||||
if (!$scope.nav.hasNext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
movePosition(+1);
|
||||
};
|
||||
|
||||
$scope.nav.prev = function () {
|
||||
if (!$scope.nav.hasPrev) {
|
||||
return false;
|
||||
}
|
||||
movePosition(-1);
|
||||
};
|
||||
|
||||
$scope.forward = function () {
|
||||
var messageID = $scope.messageID;
|
||||
PeersSelectService.selectPeer().then(function (peerString) {
|
||||
var peerID = AppPeersManager.getPeerID(peerString);
|
||||
AppMessagesManager.forwardMessages(peerID, [messageID]).then(function () {
|
||||
$rootScope.$broadcast('history_focus', {peerString: peerString});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$scope.delete = function () {
|
||||
var messageID = $scope.messageID;
|
||||
ErrorService.confirm({type: 'MESSAGE_DELETE'}).then(function () {
|
||||
AppMessagesManager.deleteMessages([messageID]);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
$scope.$on('history_delete', function (e, historyUpdate) {
|
||||
console.log(dT(), 'delete', historyUpdate);
|
||||
if (historyUpdate.peerID == peerID) {
|
||||
if (historyUpdate.msgs[$scope.messageID]) {
|
||||
if ($scope.nav.hasNext) {
|
||||
$scope.nav.next();
|
||||
} else if ($scope.nav.hasPrev) {
|
||||
$scope.nav.prev();
|
||||
} else {
|
||||
return $modalInstance.dismiss();
|
||||
}
|
||||
}
|
||||
var newList = [];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
if (!historyUpdate.msgs[list[i]]) {
|
||||
newList.push(list[i]);
|
||||
}
|
||||
};
|
||||
list = newList;
|
||||
}
|
||||
});
|
||||
|
||||
})
|
||||
|
||||
.controller('VideoModalController', function ($scope, AppVideoManager) {
|
||||
|
@ -683,19 +683,18 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
link: link,
|
||||
transclude: true,
|
||||
template:
|
||||
'<div class="img_fullsize_with_progress_wrap" ng-style="{width: fullPhoto.width + \'px\', height: fullPhoto.height + \'px\'}">\
|
||||
'<div class="img_fullsize_with_progress_wrap"">\
|
||||
<div class="img_fullsize_progress_overlay" ng-show="progress.enabled">\
|
||||
<div class="img_fullsize_progress_wrap" ng-style="{width: fullPhoto.width + \'px\', height: fullPhoto.height + \'px\'}">\
|
||||
<div class="img_fullsize_progress progress tg_progress">\
|
||||
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{progress.percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{progress.percent}}%">\
|
||||
<span class="sr-only">{{progress.percent}}% Complete (success)</span>\
|
||||
<div class="img_fullsize_progress_wrap"">\
|
||||
<div class="img_fullsize_progress progress tg_progress" ng-show="progress.percent > 0">\
|
||||
<div class="progress-bar progress-bar-success" ng-style="{width: progress.percent + \'%\'}">\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
<div class="photo_full_wrap">\
|
||||
<a class="photo_modal_image">\
|
||||
<img class="photo_modal_image" width="{{fullPhoto.width}}" height="{{fullPhoto.height}}" />\
|
||||
<img class="photo_modal_image"/>\
|
||||
</a>\
|
||||
</div>\
|
||||
<div class="photo_modal_error_wrap" ng-if="error">\
|
||||
@ -711,53 +710,68 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
|
||||
function link ($scope, element, attrs) {
|
||||
|
||||
var imgElement = $('img', element);
|
||||
var imgElement = $('img', element)[0],
|
||||
resizeElements = $('.img_fullsize_with_progress_wrap', element)
|
||||
.add('.img_fullsize_progress_wrap', element)
|
||||
.add($(imgElement)),
|
||||
resize = function () {
|
||||
resizeElements.css({width: $scope.fullPhoto.width, height: $scope.fullPhoto.height});
|
||||
$scope.$emit('ui_height');
|
||||
};
|
||||
|
||||
imgElement
|
||||
.attr('src', MtpApiFileManager.getCachedFile($scope.thumbLocation) || 'img/blank.gif')
|
||||
.addClass('thumb_blurred')
|
||||
.addClass('thumb_blur_animation');
|
||||
var jump = 0;
|
||||
$scope.$watchCollection('fullPhoto.location', function () {
|
||||
var cachedSrc = MtpApiFileManager.getCachedFile($scope.thumbLocation),
|
||||
curJump = ++jump;
|
||||
|
||||
if (!$scope.fullPhoto.location) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
var apiPromise;
|
||||
if ($scope.fullPhoto.size) {
|
||||
var inputLocation = {
|
||||
_: 'inputFileLocation',
|
||||
volume_id: $scope.fullPhoto.location.volume_id,
|
||||
local_id: $scope.fullPhoto.location.local_id,
|
||||
secret: $scope.fullPhoto.location.secret
|
||||
};
|
||||
apiPromise = MtpApiFileManager.downloadFile($scope.fullPhoto.location.dc_id, inputLocation, $scope.fullPhoto.size);
|
||||
} else {
|
||||
apiPromise = MtpApiFileManager.downloadSmallFile($scope.fullPhoto.location);
|
||||
}
|
||||
|
||||
$scope.progress = {enabled: true, percent: 1};
|
||||
|
||||
apiPromise.then(function (url) {
|
||||
$scope.progress.enabled = false;
|
||||
imgElement
|
||||
.attr('src', url)
|
||||
.removeClass('thumb_blurred');
|
||||
|
||||
}, function (e) {
|
||||
console.log('Download image failed', e, $scope.fullPhoto.location);
|
||||
$scope.progress.enabled = false;
|
||||
|
||||
if (e && e.type == 'FS_BROWSER_UNSUPPORTED') {
|
||||
$scope.error = {html: 'Your browser doesn\'t support <a href="https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem" target="_blank">LocalFileSystem</a> feature which is needed to display this image.<br/>Please, install <a href="http://google.com/chrome" target="_blank">Google Chrome</a> or use <a href="https://telegram.org/" target="_blank">mobile app</a> instead.'};
|
||||
if (cachedSrc) {
|
||||
imgElement.src = cachedSrc;
|
||||
resize();
|
||||
} else {
|
||||
$scope.error = {text: 'Download failed', error: e};
|
||||
imgElement.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
|
||||
}
|
||||
}, function (progress) {
|
||||
$scope.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
|
||||
});
|
||||
}
|
||||
|
||||
if (!$scope.fullPhoto.location) {
|
||||
return;
|
||||
}
|
||||
|
||||
var apiPromise;
|
||||
if ($scope.fullPhoto.size) {
|
||||
var inputLocation = {
|
||||
_: 'inputFileLocation',
|
||||
volume_id: $scope.fullPhoto.location.volume_id,
|
||||
local_id: $scope.fullPhoto.location.local_id,
|
||||
secret: $scope.fullPhoto.location.secret
|
||||
};
|
||||
apiPromise = MtpApiFileManager.downloadFile($scope.fullPhoto.location.dc_id, inputLocation, $scope.fullPhoto.size);
|
||||
} else {
|
||||
apiPromise = MtpApiFileManager.downloadSmallFile($scope.fullPhoto.location);
|
||||
}
|
||||
|
||||
$scope.progress = {enabled: true, percent: 0};
|
||||
|
||||
apiPromise.then(function (url) {
|
||||
if (curJump == jump) {
|
||||
$scope.progress.enabled = false;
|
||||
imgElement.src = url;
|
||||
resize();
|
||||
}
|
||||
}, function (e) {
|
||||
console.log('Download image failed', e, $scope.fullPhoto.location);
|
||||
$scope.progress.enabled = false;
|
||||
|
||||
if (e && e.type == 'FS_BROWSER_UNSUPPORTED') {
|
||||
$scope.error = {html: 'Your browser doesn\'t support <a href="https://developer.mozilla.org/en-US/docs/Web/API/LocalFileSystem" target="_blank">LocalFileSystem</a> feature which is needed to display this image.<br/>Please, install <a href="http://google.com/chrome" target="_blank">Google Chrome</a> or use <a href="https://telegram.org/" target="_blank">mobile app</a> instead.'};
|
||||
} else {
|
||||
$scope.error = {text: 'Download failed', error: e};
|
||||
}
|
||||
}, function (progress) {
|
||||
$scope.progress.percent = Math.max(1, Math.floor(100 * progress.done / progress.total));
|
||||
});
|
||||
})
|
||||
|
||||
resize();
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@ -771,9 +785,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
<div class="img_fullsize_progress_overlay" ng-show="progress.enabled">\
|
||||
<div class="img_fullsize_progress_wrap" ng-style="{width: video.full.width + \'px\', height: video.full.height + \'px\'}">\
|
||||
<div class="img_fullsize_progress progress tg_progress">\
|
||||
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="{{progress.percent}}" aria-valuemin="0" aria-valuemax="100" style="width: {{progress.percent}}%">\
|
||||
<span class="sr-only">{{progress.percent}}% Complete (success)</span>\
|
||||
</div>\
|
||||
<div class="progress-bar progress-bar-success" style="width: {{progress.percent}}%"></div>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>\
|
||||
@ -975,6 +987,44 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
|
||||
})
|
||||
|
||||
.directive('myModalNav', function () {
|
||||
|
||||
return {
|
||||
link: link
|
||||
};
|
||||
|
||||
function link($scope, element, attrs) {
|
||||
|
||||
var onKeyDown = function (event) {
|
||||
var target = event.target;
|
||||
if (target && (target.tagName == 'INPUT' || target.tagName == 'TEXTAREA')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (event.keyCode) {
|
||||
case 39: // right
|
||||
case 32: // space
|
||||
case 34: // pg down
|
||||
case 40: // down
|
||||
$scope.$eval(attrs.next);
|
||||
break;
|
||||
|
||||
case 37: // left
|
||||
case 33: // pg up
|
||||
case 38: // up
|
||||
$scope.$eval(attrs.prev);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
$(document).on('keydown', onKeyDown);
|
||||
|
||||
$scope.$on('$destroy', function () {
|
||||
$(document).off('keydown', onKeyDown);
|
||||
});
|
||||
};
|
||||
})
|
||||
|
||||
|
||||
.directive('myModalPosition', function ($window, $timeout) {
|
||||
|
||||
@ -993,9 +1043,12 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
} else {
|
||||
$(element[0].parentNode).css('marginTop', '');
|
||||
}
|
||||
$timeout(function () {
|
||||
$(element[0].parentNode).addClass('modal-content-animated');
|
||||
}, 300);
|
||||
|
||||
if (attrs.animation != 'no') {
|
||||
$timeout(function () {
|
||||
$(element[0].parentNode).addClass('modal-content-animated');
|
||||
}, 300);
|
||||
}
|
||||
};
|
||||
|
||||
onContentLoaded(updateMargin);
|
||||
|
@ -638,6 +638,8 @@ TLSerialization.prototype.storeMethod = function (methodName, params) {
|
||||
angular.forEach(methodData.params, function (param) {
|
||||
self.storeObject(params[param.name], param.type, methodName + '[' + param.name + ']');
|
||||
});
|
||||
|
||||
return methodData.type;
|
||||
};
|
||||
|
||||
TLSerialization.prototype.storeObject = function (obj, type, field) {
|
||||
@ -707,6 +709,8 @@ TLSerialization.prototype.storeObject = function (obj, type, field) {
|
||||
angular.forEach(constructorData.params, function (param) {
|
||||
self.storeObject(obj[param.name], param.type, field + '[' + predicate + '][' + param.name + ']');
|
||||
});
|
||||
|
||||
return constructorData.type;
|
||||
};
|
||||
|
||||
|
||||
@ -715,6 +719,7 @@ function TLDeserialization (buffer, options) {
|
||||
options = options || {};
|
||||
|
||||
this.offset = 0; // in bytes
|
||||
this.override = options.override || {};
|
||||
|
||||
this.buffer = buffer;
|
||||
this.intView = new Uint32Array(this.buffer);
|
||||
@ -961,12 +966,16 @@ TLDeserialization.prototype.fetchObject = function (type, field) {
|
||||
|
||||
predicate = constructorData.predicate;
|
||||
|
||||
var result = {'_': predicate};
|
||||
var result = {'_': predicate},
|
||||
self = this;
|
||||
|
||||
var self = this;
|
||||
angular.forEach(constructorData.params, function (param) {
|
||||
result[param.name] = self.fetchObject(param.type, field + '[' + predicate + '][' + param.name + ']');
|
||||
});
|
||||
if (this.override[predicate]) {
|
||||
this.override[predicate].apply(this, [result, field + '[' + predicate + ']']);
|
||||
} else {
|
||||
angular.forEach(constructorData.params, function (param) {
|
||||
result[param.name] = self.fetchObject(param.type, field + '[' + predicate + '][' + param.name + ']');
|
||||
});
|
||||
}
|
||||
|
||||
if (fallback) {
|
||||
this.mtproto = true;
|
||||
@ -1773,7 +1782,7 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
|
||||
serializer.storeLong(options.afterMessageID, 'msg_id');
|
||||
}
|
||||
|
||||
serializer.storeMethod(method, params);
|
||||
options.resultType = serializer.storeMethod(method, params);
|
||||
|
||||
var messageID = MtpMessageIdGenerator.generateID(),
|
||||
seqNo = this.generateSeqNo(),
|
||||
@ -2215,7 +2224,36 @@ factory('MtpNetworkerFactory', function (MtpDcConfigurator, MtpMessageIdGenerato
|
||||
}
|
||||
|
||||
var buffer = bytesToArrayBuffer(messageBody);
|
||||
var deserializer = new TLDeserialization(buffer, {mtproto: true});
|
||||
var deserializerOptions = {
|
||||
mtproto: true,
|
||||
override: {
|
||||
message: function (result, field) {
|
||||
result.msg_id = this.fetchLong(field + '[msg_id]');
|
||||
result.seqno = this.fetchInt(field + '[seqno]');
|
||||
result.bytes = this.fetchInt(field + '[bytes]');
|
||||
|
||||
var offset = this.getOffset();
|
||||
|
||||
try {
|
||||
result.body = this.fetchObject('Object', field + '[body]');
|
||||
} catch (e) {
|
||||
result.body = {_: 'parse_error', error: e};
|
||||
}
|
||||
this.offset = offset + result.bytes;
|
||||
// console.log(dT(), 'override message', result);
|
||||
},
|
||||
rpc_result: function (result, field) {
|
||||
result.req_msg_id = this.fetchLong(field + '[req_msg_id]');
|
||||
|
||||
var sentMessage = self.sentMessages[result.req_msg_id],
|
||||
type = sentMessage && sentMessage.resultType || 'Object';
|
||||
|
||||
result.result = this.fetchObject(type, field + '[result]');
|
||||
// console.log(dT(), 'override rpc_result', type, result);
|
||||
}
|
||||
}
|
||||
};
|
||||
var deserializer = new TLDeserialization(buffer, deserializerOptions);
|
||||
|
||||
var response = deserializer.fetchObject('', 'INPUT');
|
||||
|
||||
|
@ -886,6 +886,54 @@ angular.module('myApp.services', [])
|
||||
}
|
||||
|
||||
function getSearch (inputPeer, query, inputFilter, maxID, limit) {
|
||||
var foundMsgs = [];
|
||||
|
||||
if (!maxID && !query) {
|
||||
var peerID = AppPeersManager.getPeerID(inputPeer),
|
||||
historyStorage = historiesStorage[peerID];
|
||||
|
||||
if (historyStorage !== undefined && historyStorage.history.length) {
|
||||
var neededContents = {},
|
||||
neededLimit = limit || 20,
|
||||
i, message;
|
||||
|
||||
switch (inputFilter._) {
|
||||
case 'inputMessagesFilterPhotos':
|
||||
neededContents['messageMediaPhoto'] = true;
|
||||
break;
|
||||
|
||||
case 'inputMessagesFilterVideo':
|
||||
neededContents['messageMediaVideo'] = true;
|
||||
break;
|
||||
|
||||
case 'inputMessagesFilterPhotoVideo':
|
||||
neededContents['messageMediaPhoto'] = true;
|
||||
neededContents['messageMediaVideo'] = true;
|
||||
break;
|
||||
|
||||
case 'inputMessagesFilterDocument':
|
||||
neededContents['messageMediaDocument'] = true;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < historyStorage.history.length; i++) {
|
||||
message = messagesStorage[historyStorage.history[i]];
|
||||
if (message.media && neededContents[message.media._]) {
|
||||
foundMsgs.push(message.id);
|
||||
if (foundMsgs.length >= neededLimit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (foundMsgs.length || limit == 1000) {
|
||||
return $q.when({
|
||||
count: null,
|
||||
history: foundMsgs
|
||||
});
|
||||
}
|
||||
|
||||
return MtpApiManager.invokeApi('messages.search', {
|
||||
peer: inputPeer,
|
||||
q: query || '',
|
||||
@ -903,7 +951,7 @@ angular.module('myApp.services', [])
|
||||
? searchResult.count
|
||||
: searchResult.messages.length;
|
||||
|
||||
var foundMsgs = [];
|
||||
foundMsgs = [];
|
||||
angular.forEach(searchResult.messages, function (message) {
|
||||
foundMsgs.push(message.id);
|
||||
});
|
||||
@ -915,6 +963,10 @@ angular.module('myApp.services', [])
|
||||
});
|
||||
}
|
||||
|
||||
function getMessage (messageID) {
|
||||
return messagesStorage[messageID] || {deleted: true};
|
||||
}
|
||||
|
||||
function deleteMessages (messageIDs) {
|
||||
return MtpApiManager.invokeApi('messages.deleteMessages', {
|
||||
id: messageIDs
|
||||
@ -1874,6 +1926,7 @@ angular.module('myApp.services', [])
|
||||
getDialogs: getDialogs,
|
||||
getHistory: getHistory,
|
||||
getSearch: getSearch,
|
||||
getMessage: getMessage,
|
||||
readHistory: readHistory,
|
||||
flushHistory: flushHistory,
|
||||
deleteMessages: deleteMessages,
|
||||
@ -2011,6 +2064,8 @@ angular.module('myApp.services', [])
|
||||
full.height = fullPhotoSize.h;
|
||||
}
|
||||
|
||||
full.modalWidth = Math.max(full.width, Math.min(400, fullWidth));
|
||||
|
||||
full.location = fullPhotoSize.location;
|
||||
full.size = fullPhotoSize.size;
|
||||
}
|
||||
|
@ -14,9 +14,8 @@
|
||||
when="{'one': 'Are you sure to send file from clipboard?', 'other': 'Are you sure to send {} files from clipboard?'}">
|
||||
</ng-pluralize>
|
||||
</span>
|
||||
<span ng-switch-when="FILE_CLIPBOARD_PASTE">
|
||||
Are you sure to send file(s) from clipboard?
|
||||
</span>
|
||||
<span ng-switch-when="FILE_CLIPBOARD_PASTE">Are you sure to send file(s) from clipboard?</span>
|
||||
<span ng-switch-when="MESSAGE_DELETE">Are you sure to delete the message?</span>
|
||||
<span ng-switch-default ng-bind="message || 'Are you sure?'"></span>
|
||||
</div>
|
||||
|
||||
@ -31,6 +30,7 @@
|
||||
<span ng-switch-when="HISTORY_FLUSH">Delete Chat</span>
|
||||
<span ng-switch-when="FILES_CLIPBOARD_PASTE">Send</span>
|
||||
<span ng-switch-when="FILE_CLIPBOARD_PASTE">Send</span>
|
||||
<span ng-switch-when="MESSAGE_DELETE">Delete</span>
|
||||
<span ng-switch-default>OK</span>
|
||||
</button>
|
||||
</div>
|
||||
|
@ -92,7 +92,7 @@
|
||||
|
||||
<div bo-if="historyMessage.media && historyMessage.media._ != 'messageMediaEmpty'" class="im_message_media" ng-switch="historyMessage.media._">
|
||||
|
||||
<a ng-switch-when="messageMediaPhoto" class="im_message_photo_thumb" href="" ng-click="openPhoto(historyMessage.media.photo.id)" bo-style="{width: historyMessage.media.photo.thumb.width + 'px'}" ng-mouseover="preloadPhoto(historyMessage.media.photo.id)">
|
||||
<a ng-switch-when="messageMediaPhoto" class="im_message_photo_thumb" href="" ng-click="openPhoto(historyMessage.media.photo.id, historyMessage.id)" bo-style="{width: historyMessage.media.photo.thumb.width + 'px'}" ng-mouseover="preloadPhoto(historyMessage.media.photo.id)">
|
||||
<img
|
||||
class="im_message_photo_thumb"
|
||||
my-load-thumb
|
||||
|
@ -1,10 +1,17 @@
|
||||
<div my-modal-width="{{photo.full.width}}" class="media_modal_wrap photo_modal_wrap" my-modal-position>
|
||||
<div my-modal-width="{{photo.full.modalWidth}}" class="media_modal_wrap photo_modal_wrap" my-modal-position animation="no" my-modal-nav next="nav.next()" prev="nav.prev()">
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<div class="photo_modal_image_wrap" my-load-full-photo full-photo="photo.full" thumb-location="photo.thumb.location" ng-click="$close()"> </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>
|
||||
|
||||
<p class="media_modal_info">From: <span class="media_modal_author" ng-bind-html="photo.fromUser.rFullName" ></span>, {{photo.date | dateOrTime}}</p>
|
||||
<div class="media_modal_actions pull-right">
|
||||
<a href="" class="media_modal_action_link" ng-click="forward()">Forward</a>
|
||||
<a href="" class="media_modal_action_link" ng-click="delete()">Delete</a>
|
||||
</div>
|
||||
|
||||
<p class="media_modal_info">
|
||||
<span class="media_modal_author" ng-bind-html="photo.fromUser.rFullName"></span>, {{photo.date | dateOrTime}}
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -4,7 +4,14 @@
|
||||
|
||||
<div class="video_modal_image_wrap" my-load-video video="video"></div>
|
||||
|
||||
<p class="media_modal_info">From: <span class="media_modal_author" ng-bind-html="video.fromUser.rFullName"></span>, {{video.date | dateOrTime}}</p>
|
||||
<div class="media_modal_actions pull-right">
|
||||
<a href="" class="media_modal_action_link" ng-click="forward()">Forward</a>
|
||||
<a href="" class="media_modal_action_link" ng-click="delete()">Delete</a>
|
||||
</div>
|
||||
|
||||
<p class="media_modal_info">
|
||||
<span class="media_modal_author" ng-bind-html="video.fromUser.rFullName" ></span>, {{video.date | dateOrTime}}
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -300,7 +300,8 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
|
||||
restrict: 'EA',
|
||||
scope: {
|
||||
index: '@',
|
||||
animate: '='
|
||||
animate: '=',
|
||||
nav: '='
|
||||
},
|
||||
replace: true,
|
||||
transclude: true,
|
||||
@ -447,6 +448,7 @@ angular.module('ui.bootstrap.modal', ['ui.bootstrap.transition'])
|
||||
angularDomEl.attr('window-class', modal.windowClass);
|
||||
angularDomEl.attr('index', openedWindows.length() - 1);
|
||||
angularDomEl.attr('animate', 'animate');
|
||||
angularDomEl.attr('nav', 'nav');
|
||||
angularDomEl.html(modal.content);
|
||||
|
||||
var modalDomEl = $compile(angularDomEl)(modal.scope);
|
||||
@ -1074,6 +1076,9 @@ angular.module("template/modal/backdrop.html", []).run(["$templateCache", functi
|
||||
angular.module("template/modal/window.html", []).run(["$templateCache", function($templateCache) {
|
||||
$templateCache.put("template/modal/window.html",
|
||||
"<div tabindex=\"-1\" class=\"modal fade {{ windowClass }}\" ng-class=\"{in: animate}\" ng-style=\"{'z-index': 1050 + index*10, display: 'block'}\" ng-click=\"close($event)\">\n" +
|
||||
" <div class=\"modal_prev_wrap hidden-xs hidden-sm\" ng-show=\"nav.hasPrev\" ng-click=\"nav.prev($event)\">\n" +
|
||||
" <div class=\"modal_prev\"></div>\n" +
|
||||
" </div>\n" +
|
||||
" <div class=\"modal_close_wrap hidden-xs hidden-sm\" ng-click=\"close($event)\">\n" +
|
||||
" <div class=\"modal_close\"></div>\n" +
|
||||
" </div>\n" +
|
||||
|
@ -5,7 +5,7 @@
|
||||
"follow_symlinks": true,
|
||||
"path": ".",
|
||||
"folder_exclude_patterns": ["*dist", "node_modules", "releases"],
|
||||
"file_exclude_patterns": ["*.zip"]
|
||||
"file_exclude_patterns": ["*.zip", "templates.js"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user