|
|
/*! |
|
|
* Webogram v0.5.6 - messaging web application for MTProto |
|
|
* https://github.com/zhukov/webogram |
|
|
* Copyright (C) 2014 Igor Zhukov <igor.beatle@gmail.com> |
|
|
* https://github.com/zhukov/webogram/blob/master/LICENSE |
|
|
*/ |
|
|
|
|
|
'use strict' |
|
|
/* global Config, location, templateUrl, onContentLoaded, tsNow, cancelEvent, safeReplaceObject, dT, SearchIndexManager, setZeroTimeout, versionCompare, calcImageInBox, getSelectedText, SVGElement, hasOnclick */ |
|
|
|
|
|
/* Controllers */ |
|
|
|
|
|
angular.module('myApp.controllers', ['myApp.i18n']) |
|
|
|
|
|
.controller('AppWelcomeController', function ($scope, $location, MtpApiManager, ChangelogNotifyService, LayoutSwitchService) { |
|
|
MtpApiManager.getUserID().then(function (id) { |
|
|
if (id) { |
|
|
$location.url('/im') |
|
|
return |
|
|
} |
|
|
if (location.protocol == 'http:' && |
|
|
!Config.Modes.http && |
|
|
Config.App.domains.indexOf(location.hostname) != -1) { |
|
|
location.href = location.href.replace(/^http:/, 'https:') |
|
|
return |
|
|
} |
|
|
$location.url('/login') |
|
|
}) |
|
|
|
|
|
ChangelogNotifyService.checkUpdate() |
|
|
LayoutSwitchService.start() |
|
|
}) |
|
|
|
|
|
.controller('AppLoginController', function ($scope, $rootScope, $location, $timeout, $modal, $modalStack, MtpApiManager, ErrorService, NotificationsManager, PasswordManager, ChangelogNotifyService, IdleManager, LayoutSwitchService, TelegramMeWebService, _) { |
|
|
$modalStack.dismissAll() |
|
|
IdleManager.start() |
|
|
|
|
|
MtpApiManager.getUserID().then(function (id) { |
|
|
if (id) { |
|
|
$location.url('/im') |
|
|
return |
|
|
} |
|
|
if (location.protocol == 'http:' && |
|
|
!Config.Modes.http && |
|
|
Config.App.domains.indexOf(location.hostname) != -1) { |
|
|
location.href = location.href.replace(/^http:/, 'https:') |
|
|
return |
|
|
} |
|
|
TelegramMeWebService.setAuthorized(false) |
|
|
}) |
|
|
|
|
|
var options = {dcID: 2, createNetworker: true} |
|
|
var countryChanged = false |
|
|
var selectedCountry = false |
|
|
|
|
|
$scope.credentials = {phone_country: '', phone_country_name: '', phone_number: '', phone_full: ''} |
|
|
$scope.progress = {} |
|
|
$scope.nextPending = {} |
|
|
$scope.about = {} |
|
|
|
|
|
$scope.chooseCountry = function () { |
|
|
var modal = $modal.open({ |
|
|
templateUrl: templateUrl('country_select_modal'), |
|
|
controller: 'CountrySelectModalController', |
|
|
windowClass: 'countries_modal_window mobile_modal', |
|
|
backdrop: 'single' |
|
|
}) |
|
|
|
|
|
modal.result.then(selectCountry) |
|
|
} |
|
|
|
|
|
function initPhoneCountry () { |
|
|
var langCode = (navigator.language || '').toLowerCase() |
|
|
var countryIso2 = Config.LangCountries[langCode] |
|
|
var shouldPregenerate = !Config.Navigator.mobile |
|
|
|
|
|
if (['en', 'en-us', 'en-uk'].indexOf(langCode) == -1) { |
|
|
if (countryIso2 !== undefined) { |
|
|
selectPhoneCountryByIso2(countryIso2) |
|
|
} else if (langCode.indexOf('-') > 0) { |
|
|
selectPhoneCountryByIso2(langCode.split('-')[1].toUpperCase()) |
|
|
} else { |
|
|
selectPhoneCountryByIso2('US') |
|
|
} |
|
|
} else { |
|
|
selectPhoneCountryByIso2('US') |
|
|
} |
|
|
|
|
|
if (!shouldPregenerate) { |
|
|
return |
|
|
} |
|
|
var wasCountry = $scope.credentials.phone_country |
|
|
MtpApiManager.invokeApi('help.getNearestDc', {}, {dcID: 2, createNetworker: true}).then(function (nearestDcResult) { |
|
|
if (wasCountry == $scope.credentials.phone_country) { |
|
|
selectPhoneCountryByIso2(nearestDcResult.country) |
|
|
} |
|
|
if (nearestDcResult.nearest_dc != nearestDcResult.this_dc) { |
|
|
MtpApiManager.getNetworker(nearestDcResult.nearest_dc, {createNetworker: true}) |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
function selectPhoneCountryByIso2 (countryIso2) { |
|
|
if (countryIso2) { |
|
|
var i, country |
|
|
for (i = 0; i < Config.CountryCodes.length; i++) { |
|
|
country = Config.CountryCodes[i] |
|
|
if (country[0] == countryIso2) { |
|
|
return selectCountry({name: _(country[1] + '_raw'), code: country[2]}) |
|
|
} |
|
|
} |
|
|
} |
|
|
return selectCountry({name: _('country_select_modal_country_us_raw'), code: '+1'}) |
|
|
} |
|
|
|
|
|
function selectCountry (country) { |
|
|
selectedCountry = country |
|
|
if ($scope.credentials.phone_country != country.code) { |
|
|
$scope.credentials.phone_country = country.code |
|
|
} else { |
|
|
updateCountry() |
|
|
} |
|
|
$scope.$broadcast('country_selected') |
|
|
$scope.$broadcast('value_updated') |
|
|
} |
|
|
|
|
|
function updateCountry () { |
|
|
var phoneNumber = ( |
|
|
($scope.credentials.phone_country || '') + |
|
|
($scope.credentials.phone_number || '') |
|
|
).replace(/\D+/g, '') |
|
|
var i, j, code |
|
|
var maxLength = 0 |
|
|
var maxName = false |
|
|
|
|
|
if (phoneNumber.length) { |
|
|
if (selectedCountry && !phoneNumber.indexOf(selectedCountry.code.replace(/\D+/g, ''))) { |
|
|
maxName = selectedCountry.name |
|
|
} else { |
|
|
for (i = 0; i < Config.CountryCodes.length; i++) { |
|
|
for (j = 2; j < Config.CountryCodes[i].length; j++) { |
|
|
code = Config.CountryCodes[i][j].replace(/\D+/g, '') |
|
|
if (code.length > maxLength && !phoneNumber.indexOf(code)) { |
|
|
maxLength = code.length |
|
|
maxName = _(Config.CountryCodes[i][1] + '_raw') |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.credentials.phone_full = phoneNumber |
|
|
$scope.credentials.phone_country_name = maxName || _('login_controller_unknown_country_raw') |
|
|
} |
|
|
|
|
|
$scope.$watch('credentials.phone_country', updateCountry) |
|
|
$scope.$watch('credentials.phone_number', updateCountry) |
|
|
initPhoneCountry() |
|
|
|
|
|
var nextTimeout |
|
|
var updatePasswordTimeout = false |
|
|
|
|
|
function saveAuth (result) { |
|
|
MtpApiManager.setUserAuth(options.dcID, { |
|
|
id: result.user.id |
|
|
}) |
|
|
$timeout.cancel(nextTimeout) |
|
|
|
|
|
$location.url('/im') |
|
|
} |
|
|
|
|
|
$scope.sendCode = function () { |
|
|
$timeout.cancel(nextTimeout) |
|
|
|
|
|
var fullPhone = ($scope.credentials.phone_country || '') + ($scope.credentials.phone_number || '') |
|
|
var badPhone = !fullPhone.match(/^[\d\-+\s]+$/) |
|
|
if (!badPhone) { |
|
|
fullPhone = fullPhone.replace(/\D/g, '') |
|
|
if (fullPhone.length < 7) { |
|
|
badPhone = true |
|
|
} |
|
|
} |
|
|
if (badPhone) { |
|
|
$scope.progress.enabled = false |
|
|
$scope.error = {field: 'phone'} |
|
|
return |
|
|
} |
|
|
|
|
|
ErrorService.confirm({ |
|
|
type: 'LOGIN_PHONE_CORRECT', |
|
|
country_code: $scope.credentials.phone_country, |
|
|
phone_number: $scope.credentials.phone_number |
|
|
}).then(function () { |
|
|
$scope.progress.enabled = true |
|
|
|
|
|
onContentLoaded(function () { |
|
|
$scope.$broadcast('ui_height') |
|
|
}) |
|
|
|
|
|
var authKeyStarted = tsNow() |
|
|
MtpApiManager.invokeApi('auth.sendCode', { |
|
|
flags: 0, |
|
|
phone_number: $scope.credentials.phone_full, |
|
|
api_id: Config.App.id, |
|
|
api_hash: Config.App.hash, |
|
|
lang_code: navigator.language || 'en' |
|
|
}, options).then(function (sentCode) { |
|
|
$scope.progress.enabled = false |
|
|
|
|
|
$scope.error = {} |
|
|
$scope.about = {} |
|
|
$scope.credentials.phone_code_hash = sentCode.phone_code_hash |
|
|
applySentCode(sentCode) |
|
|
}, function (error) { |
|
|
$scope.progress.enabled = false |
|
|
console.log('sendCode error', error) |
|
|
switch (error.type) { |
|
|
case 'PHONE_NUMBER_INVALID': |
|
|
$scope.error = {field: 'phone'} |
|
|
error.handled = true |
|
|
break |
|
|
} |
|
|
})['finally'](function () { |
|
|
if ($rootScope.idle.isIDLE || tsNow() - authKeyStarted > 60000) { |
|
|
NotificationsManager.notify({ |
|
|
title: 'Telegram', |
|
|
message: 'Your authorization key was successfully generated! Open the app to log in.', |
|
|
tag: 'auth_key' |
|
|
}) |
|
|
} |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
function applySentCode (sentCode) { |
|
|
$scope.credentials.type = sentCode.type |
|
|
$scope.nextPending.type = sentCode.next_type || false |
|
|
$scope.nextPending.remaining = sentCode.timeout || false |
|
|
delete $scope.nextPending.progress |
|
|
|
|
|
nextTimeoutCheck() |
|
|
|
|
|
onContentLoaded(function () { |
|
|
$scope.$broadcast('ui_height') |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.sendNext = function () { |
|
|
if (!$scope.nextPending.type || |
|
|
$scope.nextPending.remaining > 0) { |
|
|
return |
|
|
} |
|
|
$scope.nextPending.progress = true |
|
|
MtpApiManager.invokeApi('auth.resendCode', { |
|
|
phone_number: $scope.credentials.phone_full, |
|
|
phone_code_hash: $scope.credentials.phone_code_hash |
|
|
}, options).then(applySentCode) |
|
|
} |
|
|
|
|
|
function nextTimeoutCheck () { |
|
|
$timeout.cancel(nextTimeout) |
|
|
if (!$scope.nextPending.type || |
|
|
$scope.nextPending.remaining === false) { |
|
|
return |
|
|
} |
|
|
if ((--$scope.nextPending.remaining) > 0) { |
|
|
nextTimeout = $timeout(nextTimeoutCheck, 1000) |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.editPhone = function () { |
|
|
$timeout.cancel(nextTimeout) |
|
|
|
|
|
if ($scope.credentials.phone_full && |
|
|
$scope.credentials.phone_code_hash) { |
|
|
MtpApiManager.invokeApi('auth.cancelCode', { |
|
|
phone_number: $scope.credentials.phone_full, |
|
|
phone_code_hash: $scope.credentials.phone_code_hash |
|
|
}, options) |
|
|
} |
|
|
|
|
|
delete $scope.credentials.phone_code_hash |
|
|
delete $scope.credentials.phone_unoccupied |
|
|
delete $scope.credentials.phone_code_valid |
|
|
delete $scope.nextPending.remaining |
|
|
} |
|
|
|
|
|
$scope.$watch('credentials.phone_code', function (newVal) { |
|
|
if (newVal && |
|
|
newVal.match(/^\d+$/) && |
|
|
$scope.credentials.type && |
|
|
$scope.credentials.type.length && |
|
|
newVal.length == $scope.credentials.type.length) { |
|
|
$scope.logIn() |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.logIn = function (forceSignUp) { |
|
|
if ($scope.progress.enabled && |
|
|
$scope.progress.forceSignUp == forceSignUp) { |
|
|
return |
|
|
} |
|
|
var method = 'auth.signIn' |
|
|
var params = { |
|
|
phone_number: $scope.credentials.phone_full, |
|
|
phone_code_hash: $scope.credentials.phone_code_hash, |
|
|
phone_code: $scope.credentials.phone_code |
|
|
} |
|
|
if (forceSignUp) { |
|
|
method = 'auth.signUp' |
|
|
angular.extend(params, { |
|
|
first_name: $scope.credentials.first_name || '', |
|
|
last_name: $scope.credentials.last_name || '' |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.progress.forceSignUp = forceSignUp |
|
|
$scope.progress.enabled = true |
|
|
MtpApiManager.invokeApi(method, params, options).then(saveAuth, function (error) { |
|
|
$scope.progress.enabled = false |
|
|
if (error.code == 400 && error.type == 'PHONE_NUMBER_UNOCCUPIED') { |
|
|
error.handled = true |
|
|
$scope.credentials.phone_code_valid = true |
|
|
$scope.credentials.phone_unoccupied = true |
|
|
$scope.about = {} |
|
|
return |
|
|
} else if (error.code == 400 && error.type == 'PHONE_NUMBER_OCCUPIED') { |
|
|
error.handled = true |
|
|
return $scope.logIn(false) |
|
|
} else if (error.code == 401 && error.type == 'SESSION_PASSWORD_NEEDED') { |
|
|
$scope.progress.enabled = true |
|
|
updatePasswordState().then(function () { |
|
|
$scope.progress.enabled = false |
|
|
$scope.credentials.phone_code_valid = true |
|
|
$scope.credentials.password_needed = true |
|
|
$scope.about = {} |
|
|
}) |
|
|
error.handled = true |
|
|
return |
|
|
} |
|
|
|
|
|
switch (error.type) { |
|
|
case 'FIRSTNAME_INVALID': |
|
|
$scope.error = {field: 'first_name'} |
|
|
error.handled = true |
|
|
break |
|
|
case 'LASTNAME_INVALID': |
|
|
$scope.error = {field: 'last_name'} |
|
|
error.handled = true |
|
|
break |
|
|
case 'PHONE_CODE_INVALID': |
|
|
$scope.error = {field: 'phone_code'} |
|
|
delete $scope.credentials.phone_code_valid |
|
|
error.handled = true |
|
|
break |
|
|
case 'PHONE_CODE_EXPIRED': |
|
|
$scope.editPhone() |
|
|
error.handled = true |
|
|
break |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.checkPassword = function () { |
|
|
$scope.progress.enabled = true |
|
|
return PasswordManager.check($scope.password, $scope.credentials.password, options).then(saveAuth, function (error) { |
|
|
$scope.progress.enabled = false |
|
|
switch (error.type) { |
|
|
case 'PASSWORD_HASH_INVALID': |
|
|
$scope.error = {field: 'password'} |
|
|
error.handled = true |
|
|
break |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.forgotPassword = function (event) { |
|
|
PasswordManager.requestRecovery($scope.password, options).then(function (emailRecovery) { |
|
|
var scope = $rootScope.$new() |
|
|
scope.recovery = emailRecovery |
|
|
scope.options = options |
|
|
var modal = $modal.open({ |
|
|
scope: scope, |
|
|
templateUrl: templateUrl('password_recovery_modal'), |
|
|
controller: 'PasswordRecoveryModalController', |
|
|
windowClass: 'md_simple_modal_window mobile_modal' |
|
|
}) |
|
|
|
|
|
modal.result.then(function (result) { |
|
|
if (result && result.user) { |
|
|
saveAuth(result) |
|
|
} else { |
|
|
$scope.canReset = true |
|
|
} |
|
|
}) |
|
|
}, function (error) { |
|
|
switch (error.type) { |
|
|
case 'PASSWORD_EMPTY': |
|
|
$scope.logIn() |
|
|
error.handled = true |
|
|
break |
|
|
case 'PASSWORD_RECOVERY_NA': |
|
|
$timeout(function () { |
|
|
$scope.canReset = true |
|
|
}, 1000) |
|
|
error.handled = true |
|
|
break |
|
|
} |
|
|
}) |
|
|
|
|
|
return cancelEvent(event) |
|
|
} |
|
|
|
|
|
$scope.resetAccount = function () { |
|
|
ErrorService.confirm({ |
|
|
type: 'RESET_ACCOUNT' |
|
|
}).then(function () { |
|
|
$scope.progress.enabled = true |
|
|
MtpApiManager.invokeApi('account.deleteAccount', { |
|
|
reason: 'Forgot password' |
|
|
}, options).then(function () { |
|
|
delete $scope.progress.enabled |
|
|
delete $scope.credentials.password_needed |
|
|
$scope.credentials.phone_unoccupied = true |
|
|
}, function (error) { |
|
|
if (error.type && |
|
|
error.type.substr(0, 17) == '2FA_CONFIRM_WAIT_') { |
|
|
error.waitTime = error.type.substr(17) |
|
|
error.type = '2FA_CONFIRM_WAIT_TIME' |
|
|
} |
|
|
|
|
|
delete $scope.progress.enabled |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
function updatePasswordState () { |
|
|
// $timeout.cancel(updatePasswordTimeout) |
|
|
// updatePasswordTimeout = false |
|
|
return PasswordManager.getState(options).then(function (result) { |
|
|
return $scope.password = result |
|
|
// if (result._ == 'account.noPassword' && result.email_unconfirmed_pattern) { |
|
|
// updatePasswordTimeout = $timeout(updatePasswordState, 5000) |
|
|
// } |
|
|
}) |
|
|
} |
|
|
|
|
|
ChangelogNotifyService.checkUpdate() |
|
|
LayoutSwitchService.start() |
|
|
}) |
|
|
|
|
|
.controller('AppIMController', function ($q, qSync, $scope, $location, $routeParams, $modal, $rootScope, $modalStack, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppPeersManager, ContactsSelectService, ChangelogNotifyService, ErrorService, AppRuntimeManager, HttpsMigrateService, LayoutSwitchService, LocationParamsService, AppStickersManager) { |
|
|
$scope.$on('$routeUpdate', updateCurDialog) |
|
|
|
|
|
var pendingParams = false |
|
|
var pendingAttachment = false |
|
|
$scope.$on('history_focus', function (e, peerData) { |
|
|
if (peerData.peerString == $scope.curDialog.peer && |
|
|
(peerData.messageID ? peerData.messageID == $scope.curDialog.messageID : !$scope.curDialog.messageID) && |
|
|
!peerData.startParam && |
|
|
!peerData.attachment) { |
|
|
if (peerData.messageID) { |
|
|
$scope.$broadcast('ui_history_change_scroll', true) |
|
|
} else { |
|
|
$scope.$broadcast('ui_history_focus') |
|
|
} |
|
|
} else { |
|
|
var peerID = AppPeersManager.getPeerID(peerData.peerString) |
|
|
var username = AppPeersManager.getPeer(peerID).username |
|
|
var peer = username ? '@' + username : peerData.peerString |
|
|
if (peerData.messageID || peerData.startParam) { |
|
|
pendingParams = { |
|
|
messageID: peerData.messageID, |
|
|
startParam: peerData.startParam |
|
|
} |
|
|
} else { |
|
|
pendingParams = false |
|
|
} |
|
|
if (peerData.attachment) { |
|
|
pendingAttachment = peerData.attachment |
|
|
} |
|
|
if ($routeParams.p != peer) { |
|
|
$location.url('/im?p=' + peer) |
|
|
} else { |
|
|
updateCurDialog() |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('esc_no_more', function () { |
|
|
$rootScope.$apply(function () { |
|
|
$location.url('/im') |
|
|
}) |
|
|
}) |
|
|
|
|
|
$scope.isLoggedIn = true |
|
|
$scope.isEmpty = {} |
|
|
$scope.search = {} |
|
|
$scope.historyFilter = {mediaType: false} |
|
|
$scope.historyPeer = {} |
|
|
$scope.historyState = { |
|
|
selectActions: false, |
|
|
botActions: false, |
|
|
channelActions: false, |
|
|
canReply: false, |
|
|
canDelete: false, |
|
|
canEdit: false, |
|
|
actions: function () { |
|
|
return $scope.historyState.selectActions ? 'selected' : ($scope.historyState.botActions ? 'bot' : ($scope.historyState.channelActions ? 'channel' : false)) |
|
|
}, |
|
|
typing: [], |
|
|
missedCount: 0, |
|
|
skipped: false |
|
|
} |
|
|
|
|
|
$scope.openSettings = function () { |
|
|
$modal.open({ |
|
|
templateUrl: templateUrl('settings_modal'), |
|
|
controller: 'SettingsModalController', |
|
|
windowClass: 'settings_modal_window mobile_modal', |
|
|
backdrop: 'single' |
|
|
}) |
|
|
} |
|
|
|
|
|
// setTimeout($scope.openSettings, 1000) |
|
|
|
|
|
$scope.openFaq = function () { |
|
|
var url = 'https://telegram.org/faq' |
|
|
switch (Config.I18n.locale) { |
|
|
case 'es-es': |
|
|
url += '/es' |
|
|
break |
|
|
case 'it-it': |
|
|
url += '/it' |
|
|
break |
|
|
case 'de-de': |
|
|
url += '/de' |
|
|
break |
|
|
case 'ko-ko': |
|
|
url += '/ko' |
|
|
break |
|
|
case 'pt-br': |
|
|
url += '/br' |
|
|
break |
|
|
} |
|
|
var popup = window.open(url, '_blank') |
|
|
try { |
|
|
popup.opener = null; |
|
|
} catch (e) {} |
|
|
} |
|
|
|
|
|
$scope.openContacts = function () { |
|
|
ContactsSelectService.selectContact().then(function (userID) { |
|
|
$scope.dialogSelect(AppUsersManager.getUserString(userID)) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.openGroup = function () { |
|
|
ContactsSelectService.selectContacts({action: 'new_group'}).then(function (userIDs) { |
|
|
if (userIDs.length == 1) { |
|
|
$scope.dialogSelect(AppUsersManager.getUserString(userIDs[0])) |
|
|
} else if (userIDs.length > 1) { |
|
|
var scope = $rootScope.$new() |
|
|
scope.userIDs = userIDs |
|
|
|
|
|
$modal.open({ |
|
|
templateUrl: templateUrl('chat_create_modal'), |
|
|
controller: 'ChatCreateModalController', |
|
|
scope: scope, |
|
|
windowClass: 'md_simple_modal_window mobile_modal', |
|
|
backdrop: 'single' |
|
|
}) |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.importContact = function () { |
|
|
AppUsersManager.openImportContact().then(function (foundContact) { |
|
|
if (foundContact) { |
|
|
$rootScope.$broadcast('history_focus', { |
|
|
peerString: AppUsersManager.getUserString(foundContact) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.searchClear = function () { |
|
|
$scope.search.query = '' |
|
|
$scope.$broadcast('search_clear') |
|
|
} |
|
|
|
|
|
$scope.dialogSelect = function (peerString, messageID) { |
|
|
var params = {peerString: peerString} |
|
|
if (messageID) { |
|
|
params.messageID = messageID |
|
|
} else if ($scope.search.query) { |
|
|
$scope.searchClear() |
|
|
} |
|
|
var peerID = AppPeersManager.getPeerID(peerString) |
|
|
var converted = AppMessagesManager.convertMigratedPeer(peerID) |
|
|
if (converted) { |
|
|
params.peerString = AppPeersManager.getPeerString(converted) |
|
|
} |
|
|
$rootScope.$broadcast('history_focus', params) |
|
|
} |
|
|
|
|
|
$scope.logOut = function () { |
|
|
ErrorService.confirm({type: 'LOGOUT'}).then(function () { |
|
|
MtpApiManager.logOut().then(function () { |
|
|
location.hash = '/login' |
|
|
AppRuntimeManager.reload() |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.openChangelog = function () { |
|
|
ChangelogNotifyService.showChangelog(false) |
|
|
} |
|
|
|
|
|
$scope.showPeerInfo = function () { |
|
|
if ($scope.curDialog.peerID > 0) { |
|
|
AppUsersManager.openUser($scope.curDialog.peerID) |
|
|
} else if ($scope.curDialog.peerID < 0) { |
|
|
AppChatsManager.openChat(-$scope.curDialog.peerID) |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.toggleEdit = function () { |
|
|
$scope.$broadcast('history_edit_toggle') |
|
|
} |
|
|
$scope.selectedFlush = function () { |
|
|
$scope.$broadcast('history_edit_flush') |
|
|
} |
|
|
$scope.toggleMedia = function (mediaType) { |
|
|
$scope.$broadcast('history_media_toggle', mediaType) |
|
|
} |
|
|
$scope.returnToRecent = function () { |
|
|
$scope.$broadcast('history_return_recent') |
|
|
} |
|
|
$scope.toggleSearch = function () { |
|
|
$scope.$broadcast('dialogs_search_toggle') |
|
|
} |
|
|
|
|
|
updateCurDialog() |
|
|
|
|
|
function updateCurDialog () { |
|
|
$modalStack.dismissAll() |
|
|
var addParams = pendingParams || {} |
|
|
pendingParams = false |
|
|
addParams.messageID = parseInt(addParams.messageID) || false |
|
|
addParams.startParam = addParams.startParam |
|
|
|
|
|
var peerStringPromise |
|
|
if ($routeParams.p && $routeParams.p.charAt(0) == '@') { |
|
|
if ($scope.curDialog === undefined) { |
|
|
$scope.curDialog = { |
|
|
peer: '', |
|
|
peerID: 0 |
|
|
} |
|
|
} |
|
|
peerStringPromise = AppPeersManager.resolveUsername($routeParams.p.substr(1)).then(function (peerID) { |
|
|
return qSync.when(AppPeersManager.getPeerString(peerID)) |
|
|
}) |
|
|
} else { |
|
|
peerStringPromise = qSync.when($routeParams.p) |
|
|
} |
|
|
peerStringPromise.then(function (peerString) { |
|
|
$scope.curDialog = angular.extend({ |
|
|
peer: peerString, |
|
|
peerID: AppPeersManager.getPeerID(peerString || '') |
|
|
}, addParams) |
|
|
if (pendingAttachment) { |
|
|
$scope.$broadcast('peer_draft_attachment', pendingAttachment) |
|
|
pendingAttachment = false |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
ChangelogNotifyService.checkUpdate() |
|
|
HttpsMigrateService.start() |
|
|
LayoutSwitchService.start() |
|
|
LocationParamsService.start() |
|
|
AppStickersManager.start() |
|
|
}) |
|
|
|
|
|
.controller('AppImDialogsController', function ($scope, $location, $q, $timeout, $routeParams, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppProfileManager, AppPeersManager, PhonebookContactsService, ErrorService, AppRuntimeManager) { |
|
|
$scope.dialogs = [] |
|
|
$scope.contacts = [] |
|
|
$scope.foundPeers = [] |
|
|
$scope.foundMessages = [] |
|
|
|
|
|
if ($scope.search === undefined) { |
|
|
$scope.search = {} |
|
|
} |
|
|
if ($scope.isEmpty === undefined) { |
|
|
$scope.isEmpty = {} |
|
|
} |
|
|
$scope.phonebookAvailable = PhonebookContactsService.isAvailable() |
|
|
|
|
|
var searchMessages = false |
|
|
var offsetIndex = 0 |
|
|
var maxID = 0 |
|
|
var hasMore = false |
|
|
var jump = 0 |
|
|
var contactsJump = 0 |
|
|
var peersInDialogs = {} |
|
|
var typingTimeouts = {} |
|
|
var contactsShown |
|
|
|
|
|
$scope.$on('dialogs_need_more', function () { |
|
|
// console.log('on need more') |
|
|
showMoreDialogs() |
|
|
}) |
|
|
|
|
|
$scope.$on('dialog_unread', function (e, dialog) { |
|
|
angular.forEach($scope.dialogs, function (curDialog) { |
|
|
if (curDialog.peerID == dialog.peerID) { |
|
|
curDialog.unreadCount = dialog.count |
|
|
} |
|
|
}) |
|
|
}) |
|
|
|
|
|
$scope.$on('history_search', function (e, peerID) { |
|
|
$scope.setSearchPeer(peerID) |
|
|
}) |
|
|
|
|
|
$scope.$on('esc_no_more', function () { |
|
|
$scope.setSearchPeer(false) |
|
|
}) |
|
|
|
|
|
$scope.$on('dialogs_multiupdate', function (e, dialogsUpdated) { |
|
|
if (searchMessages) { |
|
|
return false |
|
|
} |
|
|
if ($scope.search.query !== undefined && |
|
|
$scope.search.query.length) { |
|
|
return false |
|
|
} |
|
|
|
|
|
var i |
|
|
var dialog |
|
|
var newPeer = false |
|
|
var len = $scope.dialogs.length |
|
|
for (i = 0; i < len; i++) { |
|
|
dialog = $scope.dialogs[i] |
|
|
if (dialogsUpdated[dialog.peerID]) { |
|
|
$scope.dialogs.splice(i, 1) |
|
|
i-- |
|
|
len-- |
|
|
AppMessagesManager.clearDialogCache(dialog.mid) |
|
|
} |
|
|
} |
|
|
|
|
|
angular.forEach(dialogsUpdated, function (dialog, peerID) { |
|
|
if ($scope.noUsers && peerID > 0) { |
|
|
return |
|
|
} |
|
|
if (!peersInDialogs[peerID]) { |
|
|
peersInDialogs[peerID] = true |
|
|
newPeer = true |
|
|
} |
|
|
$scope.dialogs.unshift( |
|
|
AppMessagesManager.wrapForDialog(dialog.top_message, dialog) |
|
|
) |
|
|
}) |
|
|
|
|
|
sortDialogs() |
|
|
|
|
|
if (newPeer) { |
|
|
delete $scope.isEmpty.dialogs |
|
|
if (contactsShown) { |
|
|
showMoreConversations() |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
function deleteDialog (peerID) { |
|
|
for (var i = 0; i < $scope.dialogs.length; i++) { |
|
|
if ($scope.dialogs[i].peerID == peerID) { |
|
|
$scope.dialogs.splice(i, 1) |
|
|
break |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
function sortDialogs () { |
|
|
$scope.dialogs.sort(function (d1, d2) { |
|
|
return d2.index - d1.index |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.$on('dialog_top', function (e, dialog) { |
|
|
var curDialog, i, wrappedDialog |
|
|
var len = $scope.dialogs.length |
|
|
for (i = 0; i < len; i++) { |
|
|
curDialog = $scope.dialogs[i] |
|
|
if (curDialog.peerID == dialog.peerID) { |
|
|
wrappedDialog = AppMessagesManager.wrapForDialog(dialog.top_message, dialog) |
|
|
$scope.dialogs.splice(i, 1, wrappedDialog) |
|
|
break |
|
|
} |
|
|
} |
|
|
sortDialogs() |
|
|
if (wrappedDialog == $scope.dialogs[len - 1]) { |
|
|
$scope.dialogs.splice(len - 1, 1) |
|
|
} |
|
|
}) |
|
|
$scope.$on('dialog_flush', function (e, update) { |
|
|
var curDialog, i |
|
|
for (i = 0; i < $scope.dialogs.length; i++) { |
|
|
curDialog = $scope.dialogs[i] |
|
|
if (curDialog.peerID == update.peerID) { |
|
|
curDialog.deleted = true |
|
|
break |
|
|
} |
|
|
} |
|
|
}) |
|
|
$scope.$on('dialog_drop', function (e, dialog) { |
|
|
deleteDialog(dialog.peerID) |
|
|
}) |
|
|
|
|
|
$scope.$on('dialog_draft', function (e, draftUpdate) { |
|
|
var curDialog, i |
|
|
for (i = 0; i < $scope.dialogs.length; i++) { |
|
|
curDialog = $scope.dialogs[i] |
|
|
if (curDialog.peerID == draftUpdate.peerID) { |
|
|
curDialog.draft = draftUpdate.draft |
|
|
if (draftUpdate.index) { |
|
|
curDialog.index = draftUpdate.index |
|
|
} |
|
|
sortDialogs() |
|
|
break |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('history_delete', function (e, historyUpdate) { |
|
|
for (var i = 0; i < $scope.dialogs.length; i++) { |
|
|
if ($scope.dialogs[i].peerID == historyUpdate.peerID) { |
|
|
if (historyUpdate.msgs[$scope.dialogs[i].mid]) { |
|
|
$scope.dialogs[i].deleted = true |
|
|
} |
|
|
break |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('apiUpdate', function (e, update) { |
|
|
switch (update._) { |
|
|
case 'updateUserTyping': |
|
|
case 'updateChatUserTyping': |
|
|
if (!AppUsersManager.hasUser(update.user_id)) { |
|
|
if (update.chat_id && |
|
|
AppChatsManager.hasChat(update.chat_id) && |
|
|
!AppChatsManager.isChannel(update.chat_id)) { |
|
|
AppProfileManager.getChatFull(update.chat_id) |
|
|
} |
|
|
return |
|
|
} |
|
|
var peerID = update._ == 'updateUserTyping' ? update.user_id : -update.chat_id |
|
|
AppUsersManager.forceUserOnline(update.user_id) |
|
|
for (var i = 0; i < $scope.dialogs.length; i++) { |
|
|
if ($scope.dialogs[i].peerID == peerID) { |
|
|
$scope.dialogs[i].typing = update.user_id |
|
|
$timeout.cancel(typingTimeouts[peerID]) |
|
|
|
|
|
typingTimeouts[peerID] = $timeout(function () { |
|
|
for (var i = 0; i < $scope.dialogs.length; i++) { |
|
|
if ($scope.dialogs[i].peerID == peerID) { |
|
|
if ($scope.dialogs[i].typing == update.user_id) { |
|
|
delete $scope.dialogs[i].typing |
|
|
} |
|
|
} |
|
|
} |
|
|
}, 6000) |
|
|
break |
|
|
} |
|
|
} |
|
|
break |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$watchCollection('search', function () { |
|
|
$scope.dialogs = [] |
|
|
$scope.foundMessages = [] |
|
|
searchMessages = !!$scope.searchPeer |
|
|
contactsJump++ |
|
|
loadDialogs() |
|
|
}) |
|
|
|
|
|
if (Config.Mobile) { |
|
|
$scope.$watch('curDialog.peer', function () { |
|
|
$scope.$broadcast('ui_dialogs_update') |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.importPhonebook = function () { |
|
|
PhonebookContactsService.openPhonebookImport() |
|
|
} |
|
|
|
|
|
$scope.setSearchPeer = function (peerID) { |
|
|
$scope.searchPeer = peerID || false |
|
|
$scope.searchClear() |
|
|
if (peerID) { |
|
|
$scope.dialogs = [] |
|
|
$scope.foundPeers = [] |
|
|
searchMessages = true |
|
|
$scope.toggleSearch() |
|
|
} else { |
|
|
searchMessages = false |
|
|
} |
|
|
loadDialogs(true) |
|
|
} |
|
|
|
|
|
$scope.$on('contacts_update', function () { |
|
|
if (contactsShown) { |
|
|
showMoreConversations() |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('ui_dialogs_search_clear', $scope.searchClear) |
|
|
|
|
|
if (!$scope.noMessages) { |
|
|
$scope.$on('dialogs_search', function (e, data) { |
|
|
$scope.search.query = data.query || '' |
|
|
$scope.toggleSearch() |
|
|
}) |
|
|
} |
|
|
|
|
|
var searchTimeoutPromise |
|
|
function getDialogs (force) { |
|
|
var curJump = ++jump |
|
|
|
|
|
$timeout.cancel(searchTimeoutPromise) |
|
|
|
|
|
if (searchMessages) { |
|
|
searchTimeoutPromise = (force || maxID) ? $q.when() : $timeout(angular.noop, 500) |
|
|
return searchTimeoutPromise.then(function () { |
|
|
var searchPeerID = $scope.searchPeer || false |
|
|
return AppMessagesManager.getSearch(searchPeerID, $scope.search.query, {_: 'inputMessagesFilterEmpty'}, maxID).then(function (result) { |
|
|
if (curJump != jump) { |
|
|
return $q.reject() |
|
|
} |
|
|
var dialogs = [] |
|
|
angular.forEach(result.history, function (messageID) { |
|
|
var message = AppMessagesManager.getMessage(messageID) |
|
|
var peerID = AppMessagesManager.getMessagePeer(message) |
|
|
|
|
|
dialogs.push({ |
|
|
peerID: peerID, |
|
|
top_message: messageID, |
|
|
unread_count: -1 |
|
|
}) |
|
|
}) |
|
|
|
|
|
return { |
|
|
dialogs: dialogs |
|
|
} |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
var query = $scope.search.query || '' |
|
|
if ($scope.noUsers) { |
|
|
query = '%pg ' + query |
|
|
} |
|
|
return AppMessagesManager.getConversations(query, offsetIndex).then(function (result) { |
|
|
if (curJump != jump) { |
|
|
return $q.reject() |
|
|
} |
|
|
return result |
|
|
}) |
|
|
} |
|
|
|
|
|
function loadDialogs (force) { |
|
|
offsetIndex = 0 |
|
|
maxID = 0 |
|
|
hasMore = false |
|
|
if (!searchMessages) { |
|
|
peersInDialogs = {} |
|
|
contactsShown = false |
|
|
} |
|
|
|
|
|
getDialogs(force).then(function (dialogsResult) { |
|
|
if (!searchMessages) { |
|
|
$scope.dialogs = [] |
|
|
$scope.contacts = [] |
|
|
$scope.foundPeers = [] |
|
|
} |
|
|
$scope.foundMessages = [] |
|
|
|
|
|
var dialogsList = searchMessages ? $scope.foundMessages : $scope.dialogs |
|
|
|
|
|
if (dialogsResult.dialogs.length) { |
|
|
angular.forEach(dialogsResult.dialogs, function (dialog) { |
|
|
if ($scope.canSend && |
|
|
AppPeersManager.isChannel(dialog.peerID) && |
|
|
!AppChatsManager.hasRights(-dialog.peerID, 'send')) { |
|
|
return |
|
|
} |
|
|
var wrapDialog = searchMessages ? undefined : dialog |
|
|
var wrappedDialog = AppMessagesManager.wrapForDialog(dialog.top_message, wrapDialog) |
|
|
|
|
|
if (searchMessages && |
|
|
$scope.searchPeer) { |
|
|
var message = AppMessagesManager.getMessage(dialog.top_message) |
|
|
if (message.fromID > 0) { |
|
|
wrappedDialog.peerID = message.fromID |
|
|
} |
|
|
} |
|
|
|
|
|
if (searchMessages) { |
|
|
wrappedDialog.unreadCount = -1 |
|
|
} else { |
|
|
peersInDialogs[dialog.peerID] = true |
|
|
} |
|
|
dialogsList.push(wrappedDialog) |
|
|
}) |
|
|
|
|
|
if (searchMessages) { |
|
|
maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message |
|
|
} else { |
|
|
offsetIndex = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].index |
|
|
delete $scope.isEmpty.dialogs |
|
|
} |
|
|
hasMore = true |
|
|
} else { |
|
|
hasMore = false |
|
|
} |
|
|
|
|
|
$scope.$broadcast('ui_dialogs_change') |
|
|
|
|
|
if (!$scope.search.query) { |
|
|
AppMessagesManager.getConversations('', offsetIndex, 100) |
|
|
if (!dialogsResult.dialogs.length) { |
|
|
$scope.isEmpty.dialogs = true |
|
|
showMoreDialogs() |
|
|
} |
|
|
} else { |
|
|
showMoreDialogs() |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
function showMoreDialogs () { |
|
|
if (contactsShown && (!hasMore || (!offsetIndex && !maxID))) { |
|
|
return |
|
|
} |
|
|
|
|
|
if (!hasMore && |
|
|
!searchMessages && |
|
|
!$scope.noUsers && |
|
|
($scope.search.query || !$scope.dialogs.length)) { |
|
|
showMoreConversations() |
|
|
return |
|
|
} |
|
|
|
|
|
getDialogs().then(function (dialogsResult) { |
|
|
if (dialogsResult.dialogs.length) { |
|
|
var dialogsList = searchMessages ? $scope.foundMessages : $scope.dialogs |
|
|
|
|
|
angular.forEach(dialogsResult.dialogs, function (dialog) { |
|
|
if ($scope.canSend && |
|
|
AppPeersManager.isChannel(dialog.peerID) && |
|
|
!AppChatsManager.hasRights(-dialog.peerID, 'send')) { |
|
|
return |
|
|
} |
|
|
var wrapDialog = searchMessages ? undefined : dialog |
|
|
var wrappedDialog = AppMessagesManager.wrapForDialog(dialog.top_message, wrapDialog) |
|
|
|
|
|
if (searchMessages) { |
|
|
wrappedDialog.unreadCount = -1 |
|
|
} else { |
|
|
if (peersInDialogs[dialog.peerID]) { |
|
|
return |
|
|
} else { |
|
|
peersInDialogs[dialog.peerID] = true |
|
|
} |
|
|
} |
|
|
|
|
|
if (searchMessages && |
|
|
$scope.searchPeer) { |
|
|
var message = AppMessagesManager.getMessage(dialog.top_message) |
|
|
if (message.fromID > 0) { |
|
|
wrappedDialog.peerID = message.fromID |
|
|
} |
|
|
} |
|
|
|
|
|
dialogsList.push(wrappedDialog) |
|
|
}) |
|
|
|
|
|
if (searchMessages) { |
|
|
maxID = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].top_message |
|
|
} else { |
|
|
offsetIndex = dialogsResult.dialogs[dialogsResult.dialogs.length - 1].index |
|
|
} |
|
|
|
|
|
$scope.$broadcast('ui_dialogs_append') |
|
|
|
|
|
hasMore = true |
|
|
} else { |
|
|
hasMore = false |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
function showMoreConversations () { |
|
|
contactsShown = true |
|
|
|
|
|
var curJump = ++contactsJump |
|
|
AppUsersManager.getContacts($scope.search.query).then(function (contactsList) { |
|
|
if (curJump != contactsJump) return |
|
|
$scope.contacts = [] |
|
|
angular.forEach(contactsList, function (userID) { |
|
|
if (peersInDialogs[userID] === undefined) { |
|
|
$scope.contacts.push({ |
|
|
userID: userID, |
|
|
user: AppUsersManager.getUser(userID), |
|
|
peerString: AppUsersManager.getUserString(userID) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
if (contactsList.length) { |
|
|
delete $scope.isEmpty.contacts |
|
|
} else if (!$scope.search.query) { |
|
|
$scope.isEmpty.contacts = true |
|
|
} |
|
|
$scope.$broadcast('ui_dialogs_append') |
|
|
}) |
|
|
|
|
|
if ($scope.search.query && $scope.search.query.length >= 5) { |
|
|
$timeout(function () { |
|
|
if (curJump != contactsJump) return |
|
|
MtpApiManager.invokeApi('contacts.search', {q: $scope.search.query, limit: 10}).then(function (result) { |
|
|
AppUsersManager.saveApiUsers(result.users) |
|
|
AppChatsManager.saveApiChats(result.chats) |
|
|
if (curJump != contactsJump) return |
|
|
$scope.foundPeers = [] |
|
|
angular.forEach(result.results, function (contactFound) { |
|
|
var peerID = AppPeersManager.getPeerID(contactFound) |
|
|
if (peersInDialogs[peerID] === undefined) { |
|
|
if ($scope.canSend && |
|
|
AppPeersManager.isChannel(peerID) && |
|
|
!AppChatsManager.hasRights(-peerID, 'send')) { |
|
|
return |
|
|
} |
|
|
$scope.foundPeers.push({ |
|
|
id: peerID, |
|
|
username: AppPeersManager.getPeer(peerID).username, |
|
|
peerString: AppUsersManager.getUserString(peerID) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
}, function (error) { |
|
|
if (error.code == 400) { |
|
|
error.handled = true |
|
|
} |
|
|
}) |
|
|
}, 500) |
|
|
} |
|
|
|
|
|
if ($scope.search.query && !$scope.noMessages) { |
|
|
searchMessages = true |
|
|
loadDialogs() |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('AppImHistoryController', function ($scope, $location, $timeout, $modal, $rootScope, toaster, _, MtpApiManager, AppUsersManager, AppChatsManager, AppMessagesManager, AppPeersManager, ApiUpdatesManager, PeersSelectService, IdleManager, StatusManager, NotificationsManager, ErrorService, GeoLocationManager) { |
|
|
$scope.$watchCollection('curDialog', applyDialogSelect) |
|
|
|
|
|
ApiUpdatesManager.attach() |
|
|
IdleManager.start() |
|
|
StatusManager.start() |
|
|
|
|
|
$scope.peerHistories = [] |
|
|
$scope.selectedMsgs = {} |
|
|
$scope.selectedCount = 0 |
|
|
$scope.historyState.selectActions = false |
|
|
$scope.historyState.botActions = false |
|
|
$scope.historyState.channelActions = false |
|
|
$scope.historyState.canDelete = false |
|
|
$scope.historyState.canReply = false |
|
|
$scope.historyState.missedCount = 0 |
|
|
$scope.historyState.skipped = false |
|
|
$scope.state = {} |
|
|
|
|
|
$scope.toggleMessage = toggleMessage |
|
|
$scope.selectedDelete = selectedDelete |
|
|
$scope.selectedForward = selectedForward |
|
|
$scope.selectedReply = selectedReply |
|
|
$scope.selectedEdit = selectedEdit |
|
|
$scope.selectedCancel = selectedCancel |
|
|
$scope.selectedFlush = selectedFlush |
|
|
$scope.selectInlineBot = selectInlineBot |
|
|
|
|
|
$scope.startBot = startBot |
|
|
$scope.cancelBot = cancelBot |
|
|
$scope.joinChannel = joinChannel |
|
|
$scope.togglePeerMuted = togglePeerMuted |
|
|
|
|
|
$scope.toggleEdit = toggleEdit |
|
|
$scope.toggleMedia = toggleMedia |
|
|
$scope.returnToRecent = returnToRecent |
|
|
|
|
|
$scope.$on('history_edit_toggle', toggleEdit) |
|
|
$scope.$on('history_edit_flush', selectedFlush) |
|
|
$scope.$on('history_media_toggle', function (e, mediaType) { |
|
|
toggleMedia(mediaType) |
|
|
}) |
|
|
|
|
|
$scope.$on('history_return_recent', returnToRecent) |
|
|
|
|
|
var peerID |
|
|
var peerHistory = false |
|
|
var unreadAfterIdle = false |
|
|
var hasMore = false |
|
|
var hasLess = false |
|
|
var maxID = 0 |
|
|
var minID = 0 |
|
|
var lastSelectID = false |
|
|
var inputMediaFilters = { |
|
|
photos: 'inputMessagesFilterPhotos', |
|
|
video: 'inputMessagesFilterVideo', |
|
|
documents: 'inputMessagesFilterDocument', |
|
|
audio: 'inputMessagesFilterVoice' |
|
|
} |
|
|
var jump = 0 |
|
|
var moreJump = 0 |
|
|
var moreActive = false |
|
|
var morePending = false |
|
|
var lessJump = 0 |
|
|
var lessActive = false |
|
|
var lessPending = false |
|
|
|
|
|
function applyDialogSelect (newDialog, oldDialog) { |
|
|
peerID = $rootScope.selectedPeerID = newDialog.peerID |
|
|
$scope.historyFilter.mediaType = false |
|
|
|
|
|
AppPeersManager.getInputPeer(newDialog.peer || $scope.curDialog.peer || '') |
|
|
|
|
|
updateBotActions() |
|
|
selectedCancel(true) |
|
|
|
|
|
if (oldDialog.peer && |
|
|
oldDialog.peer == newDialog.peer && |
|
|
newDialog.messageID) { |
|
|
messageFocusHistory() |
|
|
} else if (peerID) { |
|
|
updateHistoryPeer(true) |
|
|
loadHistory() |
|
|
} else { |
|
|
showEmptyHistory() |
|
|
} |
|
|
} |
|
|
|
|
|
function historiesQueuePush (peerID) { |
|
|
var pos = -1 |
|
|
var maxLen = 10 |
|
|
var i, history, diff |
|
|
|
|
|
for (i = 0; i < $scope.peerHistories.length; i++) { |
|
|
if ($scope.peerHistories[i].peerID == peerID) { |
|
|
pos = i |
|
|
break |
|
|
} |
|
|
} |
|
|
if (pos > -1) { |
|
|
history = $scope.peerHistories[pos] |
|
|
return history |
|
|
} |
|
|
history = {peerID: peerID, messages: [], ids: []} |
|
|
$scope.peerHistories.unshift(history) |
|
|
diff = $scope.peerHistories.length - maxLen |
|
|
if (diff > 0) { |
|
|
$scope.peerHistories.splice(maxLen - 1, diff) |
|
|
} |
|
|
|
|
|
return history |
|
|
} |
|
|
|
|
|
function historiesQueueFind (peerID) { |
|
|
var i |
|
|
for (i = 0; i < $scope.peerHistories.length; i++) { |
|
|
if ($scope.peerHistories[i].peerID == peerID) { |
|
|
return $scope.peerHistories[i] |
|
|
} |
|
|
} |
|
|
return false |
|
|
} |
|
|
|
|
|
function historiesQueuePop (peerID) { |
|
|
var i |
|
|
for (i = 0; i < $scope.peerHistories.length; i++) { |
|
|
if ($scope.peerHistories[i].peerID == peerID) { |
|
|
$scope.peerHistories.splice(i, 1) |
|
|
return true |
|
|
} |
|
|
} |
|
|
return false |
|
|
} |
|
|
|
|
|
function updateHistoryPeer (preload) { |
|
|
var peerData = AppPeersManager.getPeer(peerID) |
|
|
// console.log('update', preload, peerData) |
|
|
if (!peerData || peerData.deleted) { |
|
|
safeReplaceObject($scope.state, {loaded: false}) |
|
|
return false |
|
|
} |
|
|
|
|
|
peerHistory = historiesQueuePush(peerID) |
|
|
|
|
|
safeReplaceObject($scope.historyPeer, { |
|
|
id: peerID, |
|
|
data: peerData |
|
|
}) |
|
|
|
|
|
MtpApiManager.getUserID().then(function (myID) { |
|
|
$scope.ownID = myID |
|
|
}) |
|
|
|
|
|
if (preload) { |
|
|
$scope.historyState.typing.splice(0, $scope.historyState.typing.length) |
|
|
$scope.$broadcast('ui_peer_change') |
|
|
$scope.$broadcast('ui_history_change') |
|
|
safeReplaceObject($scope.state, {loaded: true, empty: !peerHistory.messages.length, mayBeHasMore: true}) |
|
|
|
|
|
updateBotActions() |
|
|
updateChannelActions() |
|
|
} |
|
|
} |
|
|
|
|
|
function updateBotActions () { |
|
|
var wasBotActions = $scope.historyState.botActions |
|
|
if (!peerID || |
|
|
peerID < 0 || |
|
|
!AppUsersManager.isBot(peerID) || |
|
|
$scope.historyFilter.mediaType || |
|
|
$scope.curDialog.messageID) { |
|
|
$scope.historyState.botActions = false |
|
|
} else if ( |
|
|
$scope.state.empty || ( |
|
|
peerHistory && |
|
|
peerHistory.messages.length == 1 && |
|
|
peerHistory.messages[0].action && |
|
|
peerHistory.messages[0].action._ == 'messageActionBotIntro' |
|
|
) |
|
|
) { |
|
|
$scope.historyState.botActions = 'start' |
|
|
} else if ($scope.curDialog.startParam) { |
|
|
$scope.historyState.botActions = 'param' |
|
|
} else { |
|
|
$scope.historyState.botActions = false |
|
|
} |
|
|
if (wasBotActions != $scope.historyState.botActions) { |
|
|
$scope.$broadcast('ui_panel_update') |
|
|
} |
|
|
} |
|
|
|
|
|
function updateChannelActions () { |
|
|
var wasChannelActions = $scope.historyState.channelActions |
|
|
var channel |
|
|
if (peerID && |
|
|
AppPeersManager.isChannel(peerID) && |
|
|
(channel = AppChatsManager.getChat(-peerID))) { |
|
|
var canSend = AppChatsManager.hasRights(-peerID, 'send') |
|
|
if (!canSend) { |
|
|
if (channel.pFlags.left) { |
|
|
$scope.historyState.channelActions = 'join' |
|
|
} else { |
|
|
if (!$scope.historyState.channelActions) { |
|
|
$scope.historyState.channelActions = 'mute' |
|
|
} |
|
|
NotificationsManager.getPeerMuted(peerID).then(function (muted) { |
|
|
$scope.historyState.channelActions = muted ? 'unmute' : 'mute' |
|
|
}) |
|
|
} |
|
|
} else { |
|
|
$scope.historyState.channelActions = false |
|
|
} |
|
|
$scope.historyState.canReply = canSend |
|
|
$scope.historyState.canDelete = canSend || channel.pFlags.moderator |
|
|
} else { |
|
|
$scope.historyState.channelActions = false |
|
|
$scope.historyState.canReply = true |
|
|
$scope.historyState.canDelete = true |
|
|
} |
|
|
if (wasChannelActions != $scope.historyState.channelActions) { |
|
|
$scope.$broadcast('ui_panel_update') |
|
|
} |
|
|
} |
|
|
|
|
|
function messageFocusHistory () { |
|
|
var history = historiesQueueFind(peerID) |
|
|
|
|
|
if (history && |
|
|
history.ids.indexOf($scope.curDialog.messageID) != -1) { |
|
|
$scope.historyUnread = {} |
|
|
var focusedMsgID = $scope.curDialog.messageID || 0 |
|
|
$scope.$broadcast('messages_focus', focusedMsgID) |
|
|
$scope.$broadcast('ui_history_change_scroll', true) |
|
|
} else { |
|
|
loadHistory() |
|
|
} |
|
|
} |
|
|
|
|
|
function showLessHistory () { |
|
|
if (!hasLess) { |
|
|
return |
|
|
} |
|
|
if (moreActive) { |
|
|
lessPending = true |
|
|
return |
|
|
} |
|
|
lessPending = false |
|
|
$scope.state.lessActive = lessActive = true |
|
|
|
|
|
var curJump = jump |
|
|
var curLessJump = ++lessJump |
|
|
var limit = 0 |
|
|
var backLimit = 20 |
|
|
AppMessagesManager.getHistory($scope.curDialog.peerID, minID, limit, backLimit).then(function (historyResult) { |
|
|
$scope.state.lessActive = lessActive = false |
|
|
if (curJump != jump || curLessJump != lessJump) return |
|
|
|
|
|
var i, id |
|
|
for (i = historyResult.history.length - 1; i >= 0; i--) { |
|
|
id = historyResult.history[i] |
|
|
if (id > minID) { |
|
|
peerHistory.messages.push(AppMessagesManager.wrapForHistory(id)) |
|
|
peerHistory.ids.push(id) |
|
|
} |
|
|
} |
|
|
|
|
|
if (historyResult.history.length) { |
|
|
minID = historyResult.history.length >= backLimit |
|
|
? historyResult.history[0] |
|
|
: 0 |
|
|
if (AppMessagesManager.regroupWrappedHistory(peerHistory.messages, -backLimit)) { |
|
|
$scope.$broadcast('messages_regroup') |
|
|
} |
|
|
delete $scope.state.empty |
|
|
$scope.$broadcast('ui_history_append') |
|
|
} else { |
|
|
minID = 0 |
|
|
} |
|
|
$scope.historyState.skipped = hasLess = minID > 0 |
|
|
|
|
|
if (morePending) { |
|
|
showMoreHistory() |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
function showMoreHistory () { |
|
|
if (!hasMore) { |
|
|
return |
|
|
} |
|
|
if (lessActive) { |
|
|
morePending = true |
|
|
return |
|
|
} |
|
|
morePending = false |
|
|
$scope.state.moreActive = moreActive = true |
|
|
|
|
|
var curJump = jump |
|
|
var curMoreJump = ++moreJump |
|
|
var inputMediaFilter = $scope.historyFilter.mediaType && {_: inputMediaFilters[$scope.historyFilter.mediaType]} |
|
|
var limit = Config.Mobile ? 20 : 0 |
|
|
var getMessagesPromise = inputMediaFilter |
|
|
? AppMessagesManager.getSearch($scope.curDialog.peerID, '', inputMediaFilter, maxID, limit) |
|
|
: AppMessagesManager.getHistory($scope.curDialog.peerID, maxID, limit) |
|
|
|
|
|
getMessagesPromise.then(function (historyResult) { |
|
|
$scope.state.moreActive = moreActive = false |
|
|
if (curJump != jump || curMoreJump != moreJump) return |
|
|
|
|
|
angular.forEach(historyResult.history, function (id) { |
|
|
peerHistory.messages.unshift(AppMessagesManager.wrapForHistory(id)) |
|
|
peerHistory.ids.unshift(id) |
|
|
}) |
|
|
|
|
|
hasMore = historyResult.count === null || |
|
|
(historyResult.history.length && peerHistory.messages.length < historyResult.count) |
|
|
|
|
|
if (historyResult.history.length) { |
|
|
delete $scope.state.empty |
|
|
maxID = historyResult.history[historyResult.history.length - 1] |
|
|
$scope.$broadcast('ui_history_prepend') |
|
|
if (AppMessagesManager.regroupWrappedHistory(peerHistory.messages, historyResult.history.length + 1)) { |
|
|
$scope.$broadcast('messages_regroup') |
|
|
} |
|
|
} |
|
|
|
|
|
if (lessPending) { |
|
|
showLessHistory() |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
function loadHistory (forceRecent) { |
|
|
$scope.historyState.missedCount = 0 |
|
|
|
|
|
hasMore = false |
|
|
$scope.historyState.skipped = hasLess = false |
|
|
maxID = 0 |
|
|
minID = 0 |
|
|
peerHistory = historiesQueuePush(peerID) |
|
|
|
|
|
var limit = 0 |
|
|
var backLimit = 0 |
|
|
|
|
|
if ($scope.curDialog.messageID) { |
|
|
maxID = parseInt($scope.curDialog.messageID) |
|
|
limit = 20 |
|
|
backLimit = 20 |
|
|
} else if (forceRecent) { |
|
|
limit = 10 |
|
|
} |
|
|
|
|
|
$scope.state.moreActive = moreActive = false |
|
|
morePending = false |
|
|
$scope.state.lessActive = lessActive = false |
|
|
lessPending = false |
|
|
|
|
|
var prerenderedLen = peerHistory.messages.length |
|
|
if (prerenderedLen && (maxID || backLimit)) { |
|
|
prerenderedLen = 0 |
|
|
peerHistory.messages = [] |
|
|
peerHistory.ids = [] |
|
|
$scope.state.empty = true |
|
|
} |
|
|
|
|
|
var curJump = ++jump |
|
|
var inputMediaFilter = $scope.historyFilter.mediaType && {_: inputMediaFilters[$scope.historyFilter.mediaType]} |
|
|
var getMessagesPromise = inputMediaFilter |
|
|
? AppMessagesManager.getSearch($scope.curDialog.peerID, '', inputMediaFilter, maxID) |
|
|
: AppMessagesManager.getHistory($scope.curDialog.peerID, maxID, limit, backLimit, prerenderedLen) |
|
|
|
|
|
$scope.state.mayBeHasMore = true |
|
|
// console.log(dT(), 'start load history', $scope.curDialog) |
|
|
getMessagesPromise.then(function (historyResult) { |
|
|
if (curJump != jump) return |
|
|
// console.log(dT(), 'history loaded', angular.copy(historyResult)) |
|
|
|
|
|
var fetchedLength = historyResult.history.length |
|
|
|
|
|
minID = (historyResult.unreadSkip || (maxID && historyResult.history.indexOf(maxID) >= backLimit - 1)) |
|
|
? historyResult.history[0] |
|
|
: 0 |
|
|
maxID = historyResult.history[historyResult.history.length - 1] |
|
|
|
|
|
$scope.historyState.skipped = hasLess = minID > 0 |
|
|
hasMore = historyResult.count === null || |
|
|
(fetchedLength && fetchedLength < historyResult.count) |
|
|
|
|
|
updateHistoryPeer() |
|
|
safeReplaceObject($scope.state, {loaded: true, empty: !fetchedLength}) |
|
|
|
|
|
peerHistory.messages = [] |
|
|
peerHistory.ids = [] |
|
|
angular.forEach(historyResult.history, function (id) { |
|
|
var message = AppMessagesManager.wrapForHistory(id) |
|
|
if ($scope.historyState.skipped) { |
|
|
delete message.pFlags.unread |
|
|
} |
|
|
if (historyResult.unreadOffset) { |
|
|
message.unreadAfter = true |
|
|
} |
|
|
peerHistory.messages.push(message) |
|
|
peerHistory.ids.push(id) |
|
|
}) |
|
|
peerHistory.messages.reverse() |
|
|
peerHistory.ids.reverse() |
|
|
|
|
|
if (AppMessagesManager.regroupWrappedHistory(peerHistory.messages)) { |
|
|
$scope.$broadcast('messages_regroup') |
|
|
} |
|
|
|
|
|
if (historyResult.unreadOffset) { |
|
|
$scope.historyUnreadAfter = historyResult.history[historyResult.unreadOffset - 1] |
|
|
} else if ($scope.historyUnreadAfter) { |
|
|
delete $scope.historyUnreadAfter |
|
|
} |
|
|
$scope.$broadcast('messages_unread_after') |
|
|
var focusedMsgID = $scope.curDialog.messageID || 0 |
|
|
onContentLoaded(function () { |
|
|
$scope.$broadcast('messages_focus', focusedMsgID) |
|
|
}) |
|
|
$scope.$broadcast('ui_history_change') |
|
|
|
|
|
if (!$rootScope.idle.isIDLE) { |
|
|
AppMessagesManager.readHistory($scope.curDialog.peerID) |
|
|
} |
|
|
|
|
|
updateBotActions() |
|
|
updateChannelActions() |
|
|
}, function () { |
|
|
safeReplaceObject($scope.state, {error: true, loaded: true}) |
|
|
}) |
|
|
} |
|
|
|
|
|
function showEmptyHistory () { |
|
|
jump++ |
|
|
safeReplaceObject($scope.historyPeer, {}) |
|
|
safeReplaceObject($scope.state, {notSelected: true}) |
|
|
peerHistory = false |
|
|
hasMore = false |
|
|
|
|
|
$scope.$broadcast('ui_history_change') |
|
|
} |
|
|
|
|
|
function startBot () { |
|
|
AppMessagesManager.startBot(peerID, 0, $scope.curDialog.startParam) |
|
|
$scope.curDialog.startParam = false |
|
|
} |
|
|
|
|
|
function cancelBot () { |
|
|
delete $scope.curDialog.startParam |
|
|
} |
|
|
|
|
|
function joinChannel () { |
|
|
MtpApiManager.invokeApi('channels.joinChannel', { |
|
|
channel: AppChatsManager.getChannelInput(-peerID) |
|
|
}).then(function (result) { |
|
|
ApiUpdatesManager.processUpdateMessage(result) |
|
|
}) |
|
|
} |
|
|
|
|
|
function togglePeerMuted (muted) { |
|
|
NotificationsManager.getPeerSettings(peerID).then(function (settings) { |
|
|
settings.mute_until = !muted ? 0 : 2000000000 |
|
|
NotificationsManager.updatePeerSettings(peerID, settings) |
|
|
}) |
|
|
} |
|
|
|
|
|
function toggleMessage (messageID, $event) { |
|
|
if ($scope.historyState.botActions || |
|
|
$rootScope.idle.afterFocus) { |
|
|
return false |
|
|
} |
|
|
var message = AppMessagesManager.getMessage(messageID) |
|
|
if (message._ == 'messageService') { |
|
|
return false |
|
|
} |
|
|
|
|
|
if (!$scope.historyState.selectActions) { |
|
|
if (getSelectedText()) { |
|
|
return false |
|
|
} |
|
|
|
|
|
var target = $event.target |
|
|
while (target) { |
|
|
if (target instanceof SVGElement) { |
|
|
target = target.parentNode |
|
|
continue |
|
|
} |
|
|
if (target.className && target.className.indexOf('im_message_outer_wrap') != -1) { |
|
|
if (Config.Mobile) { |
|
|
return false |
|
|
} |
|
|
break |
|
|
} |
|
|
if (target.className && |
|
|
target.className.indexOf('im_message_date') != -1) { |
|
|
if (AppPeersManager.isBroadcast(peerID)) { |
|
|
quickForward(messageID) |
|
|
} else { |
|
|
selectedReply(messageID) |
|
|
} |
|
|
return false |
|
|
} |
|
|
if (Config.Mobile && |
|
|
target.className && |
|
|
target.className.indexOf('im_message_body') != -1) { |
|
|
break |
|
|
} |
|
|
if (target.tagName == 'A' || hasOnclick(target)) { |
|
|
return false |
|
|
} |
|
|
target = target.parentNode |
|
|
} |
|
|
|
|
|
if (Config.Mobile) { |
|
|
$scope.historyState.canEdit = AppMessagesManager.canEditMessage(messageID) |
|
|
|
|
|
$modal.open({ |
|
|
templateUrl: templateUrl('message_actions_modal'), |
|
|
windowClass: 'message_actions_modal_window', |
|
|
scope: $scope.$new() |
|
|
}).result.then(function (action) { |
|
|
switch (action) { |
|
|
case 'reply': |
|
|
selectedReply(messageID) |
|
|
break |
|
|
|
|
|
case 'edit': |
|
|
selectedEdit(messageID) |
|
|
break |
|
|
|
|
|
case 'delete': |
|
|
selectedDelete(messageID) |
|
|
break |
|
|
|
|
|
case 'forward': |
|
|
selectedForward(messageID) |
|
|
break |
|
|
|
|
|
case 'select': |
|
|
$scope.historyState.selectActions = 'selected' |
|
|
$scope.$broadcast('ui_panel_update') |
|
|
toggleMessage(messageID) |
|
|
break |
|
|
} |
|
|
}) |
|
|
return false |
|
|
} |
|
|
} |
|
|
|
|
|
var shiftClick = $event && $event.shiftKey |
|
|
if (shiftClick) { |
|
|
$scope.$broadcast('ui_selection_clear') |
|
|
} |
|
|
|
|
|
if ($scope.selectedMsgs[messageID]) { |
|
|
lastSelectID = false |
|
|
delete $scope.selectedMsgs[messageID] |
|
|
$scope.selectedCount-- |
|
|
if (!$scope.selectedCount) { |
|
|
$scope.historyState.selectActions = false |
|
|
$scope.$broadcast('ui_panel_update') |
|
|
} |
|
|
} else { |
|
|
if (!shiftClick) { |
|
|
lastSelectID = messageID |
|
|
} else if (lastSelectID != messageID) { |
|
|
var dir = lastSelectID > messageID |
|
|
var i, startPos, curMessageID |
|
|
|
|
|
for (i = 0; i < peerHistory.messages.length; i++) { |
|
|
if (peerHistory.messages[i].mid == lastSelectID) { |
|
|
startPos = i |
|
|
break |
|
|
} |
|
|
} |
|
|
|
|
|
i = startPos |
|
|
while (peerHistory.messages[i] && |
|
|
(curMessageID = peerHistory.messages[i].mid) != messageID) { |
|
|
if (!$scope.selectedMsgs[curMessageID]) { |
|
|
$scope.selectedMsgs[curMessageID] = true |
|
|
$scope.selectedCount++ |
|
|
} |
|
|
i += dir ? -1 : +1 |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.selectedMsgs[messageID] = true |
|
|
$scope.selectedCount++ |
|
|
if (!$scope.historyState.selectActions) { |
|
|
$scope.historyState.selectActions = 'selected' |
|
|
$scope.$broadcast('ui_panel_update') |
|
|
} |
|
|
} |
|
|
if ($scope.selectedCount == 1) { |
|
|
angular.forEach($scope.selectedMsgs, function (t, messageID) { |
|
|
$scope.historyState.canEdit = AppMessagesManager.canEditMessage(messageID) |
|
|
}) |
|
|
} |
|
|
$scope.$broadcast('messages_select') |
|
|
} |
|
|
|
|
|
function selectInlineBot (botID, $event) { |
|
|
if ($scope.historyState.canReply) { |
|
|
$scope.$broadcast('inline_bot_select', botID) |
|
|
} |
|
|
return cancelEvent($event) |
|
|
} |
|
|
|
|
|
function selectedCancel (noBroadcast) { |
|
|
$scope.selectedMsgs = {} |
|
|
$scope.selectedCount = 0 |
|
|
$scope.historyState.selectActions = false |
|
|
lastSelectID = false |
|
|
if (!noBroadcast) { |
|
|
$scope.$broadcast('ui_panel_update') |
|
|
} |
|
|
$scope.$broadcast('messages_select') |
|
|
} |
|
|
|
|
|
function selectedFlush () { |
|
|
ErrorService.confirm({type: 'HISTORY_FLUSH'}).then(function () { |
|
|
AppMessagesManager.flushHistory($scope.curDialog.peerID, true).then(function () { |
|
|
selectedCancel() |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
function selectedDelete (selectedMessageID) { |
|
|
var selectedMessageIDs = [] |
|
|
if (selectedMessageID) { |
|
|
selectedMessageIDs.push(selectedMessageID) |
|
|
} else if ($scope.selectedCount > 0) { |
|
|
angular.forEach($scope.selectedMsgs, function (t, messageID) { |
|
|
selectedMessageIDs.push(messageID) |
|
|
}) |
|
|
} |
|
|
if (selectedMessageIDs.length) { |
|
|
var peerID = $scope.curDialog.peerID |
|
|
var isUser = peerID > 0 |
|
|
var isChannel = AppPeersManager.isChannel(peerID) |
|
|
var isBroadcast = AppPeersManager.isBroadcast(peerID) |
|
|
var isMegagroup = AppPeersManager.isMegagroup(peerID) |
|
|
var isUsualGroup = !isChannel && !isUser |
|
|
|
|
|
var revocable = !isChannel |
|
|
for (var i = 0; revocable && i < selectedMessageIDs.length; i++) { |
|
|
var messageID = selectedMessageIDs[i] |
|
|
if (!AppMessagesManager.canRevokeMessage(messageID)) { |
|
|
revocable = false |
|
|
} |
|
|
} |
|
|
|
|
|
ErrorService.confirm({ |
|
|
type: 'MESSAGES_DELETE', |
|
|
count: selectedMessageIDs.length, |
|
|
revocable: revocable, |
|
|
isUser: isUser, |
|
|
peerID: peerID, |
|
|
isChannel: isBroadcast, |
|
|
isSupergroup: isMegagroup, |
|
|
isUsualGroup: isUsualGroup |
|
|
}, {}, { revoke: false }).then(function (data) { |
|
|
AppMessagesManager.deleteMessages(selectedMessageIDs, data.revoke).then(function () { |
|
|
selectedCancel() |
|
|
}) |
|
|
}) |
|
|
} |
|
|
} |
|
|
|
|
|
function quickForward (msgID) { |
|
|
PeersSelectService.selectPeers({ |
|
|
canSend: true, |
|
|
confirm_type: 'FORWARD_PEER', |
|
|
shareLinkPromise: AppMessagesManager.getMessageShareLink(msgID) |
|
|
}).then(function (peerStrings) { |
|
|
angular.forEach(peerStrings, function (peerString) { |
|
|
var peerID = AppPeersManager.getPeerID(peerString) |
|
|
AppMessagesManager.forwardMessages(peerID, [msgID]) |
|
|
}) |
|
|
var toastData = toaster.pop({ |
|
|
type: 'info', |
|
|
body: _('confirm_modal_forward_to_peer_success'), |
|
|
bodyOutputType: 'trustedHtml', |
|
|
clickHandler: function () { |
|
|
$rootScope.$broadcast('history_focus', { |
|
|
peerString: peerStrings[0] |
|
|
}) |
|
|
toaster.clear(toastData) |
|
|
}, |
|
|
showCloseButton: false |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
function selectedForward (selectedMessageID) { |
|
|
var selectedMessageIDs = [] |
|
|
if (selectedMessageID) { |
|
|
selectedMessageIDs.push(selectedMessageID) |
|
|
} else if ($scope.selectedCount > 0) { |
|
|
angular.forEach($scope.selectedMsgs, function (t, messageID) { |
|
|
selectedMessageIDs.push(messageID) |
|
|
}) |
|
|
} |
|
|
if (selectedMessageIDs.length) { |
|
|
PeersSelectService.selectPeer({canSend: true}).then(function (peerString) { |
|
|
selectedCancel() |
|
|
$rootScope.$broadcast('history_focus', { |
|
|
peerString: peerString, |
|
|
attachment: { |
|
|
_: 'fwd_messages', |
|
|
id: selectedMessageIDs |
|
|
} |
|
|
}) |
|
|
}) |
|
|
} |
|
|
} |
|
|
|
|
|
function selectedReply (selectedMessageID) { |
|
|
if (!selectedMessageID && $scope.selectedCount == 1) { |
|
|
angular.forEach($scope.selectedMsgs, function (t, messageID) { |
|
|
selectedMessageID = messageID |
|
|
}) |
|
|
} |
|
|
if (selectedMessageID) { |
|
|
selectedCancel() |
|
|
$scope.$broadcast('reply_selected', selectedMessageID) |
|
|
} |
|
|
} |
|
|
|
|
|
function selectedEdit (selectedMessageID) { |
|
|
if (!selectedMessageID && $scope.selectedCount == 1) { |
|
|
angular.forEach($scope.selectedMsgs, function (t, messageID) { |
|
|
selectedMessageID = messageID |
|
|
}) |
|
|
} |
|
|
if (selectedMessageID) { |
|
|
selectedCancel() |
|
|
$scope.$broadcast('edit_selected', selectedMessageID) |
|
|
} |
|
|
} |
|
|
|
|
|
function toggleEdit () { |
|
|
if ($scope.historyState.selectActions) { |
|
|
selectedCancel() |
|
|
} else { |
|
|
$scope.historyState.selectActions = 'selected' |
|
|
$scope.$broadcast('ui_panel_update') |
|
|
} |
|
|
} |
|
|
|
|
|
function toggleMedia (mediaType) { |
|
|
if (mediaType == 'search') { |
|
|
$rootScope.$broadcast('history_search', $scope.curDialog.peerID) |
|
|
return |
|
|
} |
|
|
$scope.historyFilter.mediaType = mediaType || false |
|
|
$scope.curDialog.messageID = false |
|
|
peerHistory.messages = [] |
|
|
peerHistory.ids = [] |
|
|
$scope.state.empty = true |
|
|
loadHistory() |
|
|
} |
|
|
|
|
|
function returnToRecent () { |
|
|
if ($scope.historyFilter.mediaType) { |
|
|
toggleMedia() |
|
|
} else { |
|
|
if ($scope.curDialog.messageID) { |
|
|
$rootScope.$broadcast('history_focus', {peerString: $scope.curDialog.peer}) |
|
|
} else { |
|
|
loadHistory(true) |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.$on('history_update', angular.noop) |
|
|
|
|
|
var loadAfterSync = false |
|
|
$scope.$on('stateSynchronized', function () { |
|
|
if (!loadAfterSync) { |
|
|
return |
|
|
} |
|
|
if (loadAfterSync == $scope.curDialog.peerID) { |
|
|
loadHistory() |
|
|
} |
|
|
loadAfterSync = false |
|
|
}) |
|
|
|
|
|
$scope.$on('reply_button_press', function (e, button) { |
|
|
var replyKeyboard = $scope.historyState.replyKeyboard |
|
|
if (!replyKeyboard) { |
|
|
return |
|
|
} |
|
|
var sendOptions = { |
|
|
replyToMsgID: peerID < 0 && replyKeyboard.mid |
|
|
} |
|
|
switch (button._) { |
|
|
case 'keyboardButtonRequestPhone': |
|
|
ErrorService.confirm({type: 'BOT_ACCESS_PHONE'}).then(function () { |
|
|
var user = AppUsersManager.getSelf() |
|
|
AppMessagesManager.sendOther(peerID, { |
|
|
_: 'inputMediaContact', |
|
|
phone_number: user.phone, |
|
|
first_name: user.first_name, |
|
|
last_name: user.last_name |
|
|
}, sendOptions) |
|
|
}) |
|
|
break |
|
|
|
|
|
case 'keyboardButtonRequestGeoLocation': |
|
|
ErrorService.confirm({type: 'BOT_ACCESS_GEO'}).then(function () { |
|
|
return GeoLocationManager.getPosition().then(function (coords) { |
|
|
AppMessagesManager.sendOther(peerID, { |
|
|
_: 'inputMediaGeoPoint', |
|
|
geo_point: { |
|
|
_: 'inputGeoPoint', |
|
|
'lat': coords['lat'], |
|
|
'long': coords['long'] |
|
|
} |
|
|
}, sendOptions) |
|
|
}, function (error) { |
|
|
ErrorService.alert( |
|
|
_('error_modal_bad_request_title_raw'), |
|
|
_('error_modal_gelocation_na_raw') |
|
|
) |
|
|
}) |
|
|
}) |
|
|
break |
|
|
|
|
|
default: |
|
|
AppMessagesManager.sendText(peerID, button.text, sendOptions) |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('history_reload', function (e, updPeerID) { |
|
|
if (updPeerID == $scope.curDialog.peerID) { |
|
|
loadHistory() |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('history_forbidden', function (e, updPeerID) { |
|
|
if (updPeerID == $scope.curDialog.peerID) { |
|
|
$location.url('/im') |
|
|
} |
|
|
historiesQueuePop(updPeerID) |
|
|
}) |
|
|
|
|
|
$scope.$on('dialog_migrate', function (e, data) { |
|
|
if (data.migrateFrom == $scope.curDialog.peerID) { |
|
|
var peerString = AppPeersManager.getPeerString(data.migrateTo) |
|
|
$rootScope.$broadcast('history_focus', {peerString: peerString}) |
|
|
} |
|
|
historiesQueuePop(data.migrateFrom) |
|
|
}) |
|
|
|
|
|
$scope.$on('notify_settings', function (e, data) { |
|
|
if (data.peerID == $scope.curDialog.peerID) { |
|
|
updateChannelActions() |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('channel_settings', function (e, data) { |
|
|
if (data.channelID == -$scope.curDialog.peerID) { |
|
|
updateChannelActions() |
|
|
} |
|
|
}) |
|
|
|
|
|
var typingTimeouts = {} |
|
|
$scope.$on('history_append', function (e, addedMessage) { |
|
|
var history = historiesQueueFind(addedMessage.peerID) |
|
|
if (!history) { |
|
|
return |
|
|
} |
|
|
var curPeer = addedMessage.peerID == $scope.curDialog.peerID |
|
|
if (curPeer) { |
|
|
if ($scope.historyFilter.mediaType || |
|
|
$scope.historyState.skipped) { |
|
|
if (addedMessage.my) { |
|
|
returnToRecent() |
|
|
} else { |
|
|
$scope.historyState.missedCount++ |
|
|
} |
|
|
return |
|
|
} |
|
|
if ($scope.curDialog.messageID && addedMessage.my) { |
|
|
returnToRecent() |
|
|
} |
|
|
delete $scope.state.empty |
|
|
} |
|
|
// console.log('append', addedMessage) |
|
|
// console.trace() |
|
|
var historyMessage = AppMessagesManager.wrapForHistory(addedMessage.messageID) |
|
|
history.messages.push(historyMessage) |
|
|
history.ids.push(addedMessage.messageID) |
|
|
if (AppMessagesManager.regroupWrappedHistory(history.messages, -3)) { |
|
|
$scope.$broadcast('messages_regroup') |
|
|
} |
|
|
|
|
|
if (curPeer) { |
|
|
$scope.historyState.typing.splice(0, $scope.historyState.typing.length) |
|
|
$scope.$broadcast('ui_history_append_new', { |
|
|
my: addedMessage.my, |
|
|
idleScroll: unreadAfterIdle && !historyMessage.pFlags.out && $rootScope.idle.isIDLE |
|
|
}) |
|
|
if (addedMessage.my && $scope.historyUnreadAfter) { |
|
|
delete $scope.historyUnreadAfter |
|
|
$scope.$broadcast('messages_unread_after') |
|
|
} |
|
|
|
|
|
// console.log('append check', $rootScope.idle.isIDLE, addedMessage.peerID, $scope.curDialog.peerID, historyMessage, history.messages[history.messages.length - 2]) |
|
|
if ($rootScope.idle.isIDLE) { |
|
|
if (historyMessage.pFlags.unread && |
|
|
!historyMessage.pFlags.out && |
|
|
!(history.messages[history.messages.length - 2] || {}).pFlags.unread) { |
|
|
$scope.historyUnreadAfter = historyMessage.mid |
|
|
unreadAfterIdle = true |
|
|
$scope.$broadcast('messages_unread_after') |
|
|
} |
|
|
} else { |
|
|
$timeout(function () { |
|
|
AppMessagesManager.readHistory($scope.curDialog.peerID) |
|
|
}) |
|
|
} |
|
|
|
|
|
updateBotActions() |
|
|
updateChannelActions() |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('history_multiappend', function (e, historyMultiAdded) { |
|
|
// console.log(dT(), 'multiappend', angular.copy(historyMultiAdded)) |
|
|
var regroupped = false |
|
|
var unreadAfterChanged = false |
|
|
var isIDLE = $rootScope.idle.isIDLE |
|
|
angular.forEach(historyMultiAdded, function (msgs, peerID) { |
|
|
var history = historiesQueueFind(peerID) |
|
|
// var history = historiesQueuePush(peerID) |
|
|
if (!history) { |
|
|
return |
|
|
} |
|
|
var curPeer = peerID == $scope.curDialog.peerID |
|
|
var exlen = history.messages.length |
|
|
var len = msgs.length |
|
|
|
|
|
if (curPeer) { |
|
|
if ($scope.historyFilter.mediaType || |
|
|
$scope.historyState.skipped) { |
|
|
$scope.historyState.missedCount += len |
|
|
return |
|
|
} |
|
|
delete $scope.state.empty |
|
|
} |
|
|
|
|
|
if ((!curPeer || isIDLE) && |
|
|
exlen > (len > 10 ? 10 : 100)) { |
|
|
console.warn(dT(), 'Drop too many messages', len, exlen, isIDLE, curPeer, peerID) |
|
|
if (curPeer) { |
|
|
minID = history.messages[exlen - 1].mid |
|
|
$scope.historyState.skipped = hasLess = minID > 0 |
|
|
if (hasLess) { |
|
|
loadAfterSync = peerID |
|
|
$scope.$broadcast('ui_history_append') |
|
|
} |
|
|
} else { |
|
|
historiesQueuePop(peerID) |
|
|
} |
|
|
return |
|
|
} |
|
|
|
|
|
var messageID, i |
|
|
var hasOut = false |
|
|
var unreadAfterNew = false |
|
|
var historyMessage = history.messages[history.messages.length - 1] |
|
|
var lastIsRead = !historyMessage || !historyMessage.pFlags.unread |
|
|
for (i = 0; i < len; i++) { |
|
|
messageID = msgs[i] |
|
|
if (messageID < maxID || |
|
|
history.ids.indexOf(messageID) !== -1) { |
|
|
continue |
|
|
} |
|
|
historyMessage = AppMessagesManager.wrapForHistory(messageID) |
|
|
history.messages.push(historyMessage) |
|
|
history.ids.push(messageID) |
|
|
if (!unreadAfterNew && isIDLE) { |
|
|
if (historyMessage.pFlags.unread && |
|
|
!historyMessage.pFlags.out && |
|
|
lastIsRead) { |
|
|
unreadAfterNew = messageID |
|
|
} else { |
|
|
lastIsRead = !historyMessage.pFlags.unread |
|
|
} |
|
|
} |
|
|
if (!hasOut && historyMessage.pFlags.out) { |
|
|
hasOut = true |
|
|
} |
|
|
} |
|
|
// console.log('after append', angular.copy(history.messages), angular.copy(history.ids)) |
|
|
|
|
|
if (AppMessagesManager.regroupWrappedHistory(history.messages, -len - 2)) { |
|
|
regroupped = true |
|
|
} |
|
|
|
|
|
if (curPeer) { |
|
|
if ($scope.historyState.typing.length) { |
|
|
$scope.historyState.typing.splice(0, $scope.historyState.typing.length) |
|
|
} |
|
|
$scope.$broadcast('ui_history_append_new', { |
|
|
idleScroll: unreadAfterIdle && !hasOut && isIDLE |
|
|
}) |
|
|
|
|
|
if (isIDLE) { |
|
|
if (unreadAfterNew) { |
|
|
$scope.historyUnreadAfter = unreadAfterNew |
|
|
unreadAfterIdle = true |
|
|
unreadAfterChanged = true |
|
|
} |
|
|
} else { |
|
|
$timeout(function () { |
|
|
AppMessagesManager.readHistory($scope.curDialog.peerID) |
|
|
}) |
|
|
} |
|
|
|
|
|
updateBotActions() |
|
|
updateChannelActions() |
|
|
} |
|
|
}) |
|
|
|
|
|
if (regroupped) { |
|
|
$scope.$broadcast('messages_regroup') |
|
|
} |
|
|
if (unreadAfterChanged) { |
|
|
$scope.$broadcast('messages_unread_after') |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('history_delete', function (e, historyUpdate) { |
|
|
var history = historiesQueueFind(historyUpdate.peerID) |
|
|
if (!history) { |
|
|
return |
|
|
} |
|
|
var newMessages = [] |
|
|
var i |
|
|
|
|
|
for (i = 0; i < history.messages.length; i++) { |
|
|
if (!historyUpdate.msgs[history.messages[i].mid]) { |
|
|
newMessages.push(history.messages[i]) |
|
|
} |
|
|
} |
|
|
history.messages = newMessages |
|
|
AppMessagesManager.regroupWrappedHistory(history.messages) |
|
|
$scope.$broadcast('messages_regroup') |
|
|
if (historyUpdate.peerID == $scope.curDialog.peerID) { |
|
|
$scope.state.empty = !newMessages.length |
|
|
updateBotActions() |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('dialog_flush', function (e, dialog) { |
|
|
var history = historiesQueueFind(dialog.peerID) |
|
|
if (history) { |
|
|
history.messages = [] |
|
|
history.ids = [] |
|
|
if (dialog.peerID == $scope.curDialog.peerID) { |
|
|
$scope.state.empty = true |
|
|
updateBotActions() |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('history_focus', function (e, peerData) { |
|
|
if ($scope.historyFilter.mediaType) { |
|
|
toggleMedia() |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('apiUpdate', function (e, update) { |
|
|
switch (update._) { |
|
|
case 'updateUserTyping': |
|
|
case 'updateChatUserTyping': |
|
|
AppUsersManager.forceUserOnline(update.user_id) |
|
|
if (AppUsersManager.hasUser(update.user_id) && |
|
|
$scope.curDialog.peerID == (update._ == 'updateUserTyping' |
|
|
? update.user_id |
|
|
: -update.chat_id |
|
|
)) { |
|
|
if ($scope.historyState.typing.indexOf(update.user_id) == -1) { |
|
|
$scope.historyState.typing.push(update.user_id) |
|
|
} |
|
|
$timeout.cancel(typingTimeouts[update.user_id]) |
|
|
|
|
|
typingTimeouts[update.user_id] = $timeout(function () { |
|
|
var pos = $scope.historyState.typing.indexOf(update.user_id) |
|
|
if (pos !== -1) { |
|
|
$scope.historyState.typing.splice(pos, 1) |
|
|
} |
|
|
}, 6000) |
|
|
} |
|
|
break |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('history_need_less', showLessHistory) |
|
|
$scope.$on('history_need_more', showMoreHistory) |
|
|
|
|
|
$rootScope.$watch('idle.isIDLE', function (newVal) { |
|
|
if (!newVal && |
|
|
$scope.curDialog && |
|
|
$scope.curDialog.peerID && |
|
|
!$scope.historyFilter.mediaType && |
|
|
!$scope.historyState.skipped) { |
|
|
AppMessagesManager.readHistory($scope.curDialog.peerID) |
|
|
} |
|
|
if (!newVal) { |
|
|
unreadAfterIdle = false |
|
|
if (loadAfterSync && |
|
|
loadAfterSync == $scope.curDialog.peerID) { |
|
|
loadHistory() |
|
|
loadAfterSync = false |
|
|
} |
|
|
} |
|
|
}) |
|
|
}) |
|
|
|
|
|
.controller('AppImPanelController', function ($scope) { |
|
|
$scope.$on('user_update', angular.noop) |
|
|
}) |
|
|
|
|
|
.controller('AppImSendController', function ($rootScope, $q, $scope, $timeout, MtpApiManager, Storage, AppProfileManager, AppChatsManager, AppUsersManager, AppPeersManager, AppDocsManager, AppStickersManager, AppMessagesManager, AppInlineBotsManager, MtpApiFileManager, DraftsManager, RichTextProcessor) { |
|
|
$scope.$watch('curDialog.peer', resetDraft) |
|
|
$scope.$on('user_update', angular.noop) |
|
|
$scope.$on('peer_draft_attachment', applyDraftAttachment) |
|
|
$scope.$on('reply_selected', function (e, messageID) { |
|
|
replySelect(messageID, true) |
|
|
}) |
|
|
$scope.$on('edit_selected', function (e, messageID) { |
|
|
setEditDraft(messageID, true) |
|
|
}) |
|
|
|
|
|
$scope.$on('ui_typing', onTyping) |
|
|
|
|
|
$scope.draftMessage = { |
|
|
text: '', |
|
|
send: submitMessage, |
|
|
replyClear: replyClear, |
|
|
fwdsClear: fwdsClear, |
|
|
type: 'new' |
|
|
} |
|
|
$scope.mentions = {} |
|
|
$scope.commands = {} |
|
|
$scope.$watch('draftMessage.text', onMessageChange) |
|
|
$scope.$watch('draftMessage.files', onFilesSelected) |
|
|
$scope.$watch('draftMessage.sticker', onStickerSelected) |
|
|
$scope.$watch('draftMessage.command', onCommandSelected) |
|
|
$scope.$watch('draftMessage.inlineResultID', onInlineResultSelected) |
|
|
|
|
|
$scope.$on('history_reply_markup', function (e, peerData) { |
|
|
if (peerData.peerID == $scope.curDialog.peerID) { |
|
|
updateReplyKeyboard() |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('inline_bot_select', function (e, botID) { |
|
|
var bot = AppUsersManager.getUser(botID) |
|
|
$scope.draftMessage.text = '@' + bot.username + ' ' |
|
|
$scope.$broadcast('ui_peer_draft', {focus: true}) |
|
|
}) |
|
|
|
|
|
$scope.$on('inline_bots_popular', updateMentions) |
|
|
|
|
|
$scope.$on('last_message_edit', setEditLastMessage) |
|
|
|
|
|
$scope.replyKeyboardToggle = replyKeyboardToggle |
|
|
$scope.toggleSlash = toggleSlash |
|
|
|
|
|
$rootScope.$watch('idle.isIDLE', function (newVal) { |
|
|
if ($rootScope.idle.initial) { |
|
|
return |
|
|
} |
|
|
if (newVal && $scope.curDialog.peerID) { |
|
|
$scope.$broadcast('ui_message_before_send') |
|
|
$timeout(function () { |
|
|
DraftsManager.syncDraft($scope.curDialog.peerID) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('draft_updated', function (e, draftUpdate) { |
|
|
if (draftUpdate.peerID == $scope.curDialog.peerID && |
|
|
!draftUpdate.local && |
|
|
(!$scope.draftMessage.text || $rootScope.idle.isIDLE)) { |
|
|
getDraft() |
|
|
} |
|
|
}) |
|
|
|
|
|
var replyToMarkup = false |
|
|
var forceDraft = false |
|
|
var editMessageID = false |
|
|
|
|
|
function submitMessage (e) { |
|
|
$scope.$broadcast('ui_message_before_send') |
|
|
|
|
|
$timeout(function () { |
|
|
if (editMessageID) { |
|
|
editMessage() |
|
|
} else { |
|
|
sendMessage() |
|
|
} |
|
|
}) |
|
|
|
|
|
return cancelEvent(e) |
|
|
} |
|
|
|
|
|
function sendMessage () { |
|
|
var text = $scope.draftMessage.text |
|
|
|
|
|
if (angular.isString(text) && text.length > 0) { |
|
|
text = RichTextProcessor.parseEmojis(text) |
|
|
|
|
|
var options = { |
|
|
replyToMsgID: $scope.draftMessage.replyToMsgID, |
|
|
clearDraft: true |
|
|
} |
|
|
do { |
|
|
AppMessagesManager.sendText($scope.curDialog.peerID, text.substr(0, 4096), options) |
|
|
text = text.substr(4096) |
|
|
options = angular.copy(options) |
|
|
delete options.clearDraft |
|
|
} while (text.length) |
|
|
} |
|
|
fwdsSend() |
|
|
|
|
|
if (forceDraft == $scope.curDialog.peer) { |
|
|
forceDraft = false |
|
|
} |
|
|
|
|
|
resetDraft() |
|
|
$scope.$broadcast('ui_message_send') |
|
|
} |
|
|
|
|
|
function editMessage () { |
|
|
var text = $scope.draftMessage.text |
|
|
text = RichTextProcessor.parseEmojis(text) |
|
|
|
|
|
AppMessagesManager.editMessage(editMessageID, text).then(function () { |
|
|
editMessageID = false |
|
|
|
|
|
resetDraft() |
|
|
$scope.$broadcast('ui_message_send') |
|
|
$timeout(function () { |
|
|
$scope.$broadcast('ui_peer_reply') |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
function updateMentions () { |
|
|
var peerID = $scope.curDialog.peerID |
|
|
|
|
|
if (!peerID) { |
|
|
safeReplaceObject($scope.mentions, {}) |
|
|
$scope.$broadcast('mentions_update') |
|
|
return |
|
|
} |
|
|
|
|
|
var mentionUsers = [] |
|
|
var mentionIndex = SearchIndexManager.createIndex() |
|
|
|
|
|
var inlineBotsPromise = AppInlineBotsManager.getPopularBots().then(function (inlineBots) { |
|
|
var ids = [] |
|
|
angular.forEach(inlineBots, function (bot) { |
|
|
ids.push(bot.id) |
|
|
}) |
|
|
return ids |
|
|
}) |
|
|
var chatParticipantsPromise |
|
|
if (peerID < 0) { |
|
|
chatParticipantsPromise = AppProfileManager.getChatFull(-peerID).then(function (chatFull) { |
|
|
var participantsVector = (chatFull.participants || {}).participants || [] |
|
|
var ids = [] |
|
|
angular.forEach(participantsVector, function (participant) { |
|
|
ids.push(participant.user_id) |
|
|
}) |
|
|
return ids |
|
|
}) |
|
|
} else { |
|
|
chatParticipantsPromise = $q.when([]) |
|
|
} |
|
|
|
|
|
$q.all({pop: inlineBotsPromise, chat: chatParticipantsPromise}).then(function (result) { |
|
|
var done = {} |
|
|
var ids = result.pop.concat(result.chat) |
|
|
angular.forEach(ids, function (userID) { |
|
|
if (done[userID]) { |
|
|
return |
|
|
} |
|
|
done[userID] = true |
|
|
mentionUsers.push(AppUsersManager.getUser(userID)) |
|
|
SearchIndexManager.indexObject(userID, AppUsersManager.getUserSearchText(userID), mentionIndex) |
|
|
}) |
|
|
|
|
|
safeReplaceObject($scope.mentions, { |
|
|
users: mentionUsers, |
|
|
index: mentionIndex |
|
|
}) |
|
|
$scope.$broadcast('mentions_update') |
|
|
}) |
|
|
} |
|
|
|
|
|
function updateCommands () { |
|
|
var peerID = $scope.curDialog.peerID |
|
|
if (!peerID) { |
|
|
safeReplaceObject($scope.commands, {}) |
|
|
$scope.$broadcast('mentions_update') |
|
|
return |
|
|
} |
|
|
|
|
|
AppProfileManager.getPeerBots(peerID).then(function (peerBots) { |
|
|
if (!peerBots.length) { |
|
|
safeReplaceObject($scope.commands, {}) |
|
|
$scope.$broadcast('mentions_update') |
|
|
return |
|
|
} |
|
|
|
|
|
var needMentions = peerID < 0 |
|
|
var commandsList = [] |
|
|
var commandsIndex = SearchIndexManager.createIndex() |
|
|
|
|
|
angular.forEach(peerBots, function (peerBot) { |
|
|
var mention = '' |
|
|
if (needMentions) { |
|
|
var bot = AppUsersManager.getUser(peerBot.id) |
|
|
if (bot && bot.username) { |
|
|
mention += '@' + bot.username |
|
|
} |
|
|
} |
|
|
var botSearchText = AppUsersManager.getUserSearchText(peerBot.id) |
|
|
angular.forEach(peerBot.commands, function (description, command) { |
|
|
var value = '/' + command + mention |
|
|
commandsList.push({ |
|
|
botID: peerBot.id, |
|
|
value: value, |
|
|
rDescription: RichTextProcessor.wrapRichText(description, {noLinks: true, noLineBreaks: true}) |
|
|
}) |
|
|
SearchIndexManager.indexObject(value, botSearchText + ' ' + command + ' ' + description, commandsIndex) |
|
|
}) |
|
|
}) |
|
|
|
|
|
safeReplaceObject($scope.commands, { |
|
|
list: commandsList, |
|
|
index: commandsIndex |
|
|
}) |
|
|
$scope.$broadcast('mentions_update') |
|
|
}) |
|
|
} |
|
|
|
|
|
function resetDraft (newPeer, prevPeer) { |
|
|
var prevPeerID = prevPeer ? AppPeersManager.getPeerID(prevPeer) : 0 |
|
|
if (newPeer != prevPeer && prevPeerID) { |
|
|
$scope.$broadcast('ui_message_before_send') |
|
|
$timeout(function () { |
|
|
DraftsManager.syncDraft(prevPeerID) |
|
|
resetDraft() |
|
|
}) |
|
|
return |
|
|
} |
|
|
|
|
|
editMessageID = false |
|
|
|
|
|
updateMentions() |
|
|
updateCommands() |
|
|
replyClear() |
|
|
updateReplyKeyboard() |
|
|
|
|
|
delete $scope.draftMessage.inlineProgress |
|
|
$scope.$broadcast('inline_results', false) |
|
|
|
|
|
// console.log(dT(), 'reset draft', $scope.curDialog.peer, forceDraft) |
|
|
if (forceDraft) { |
|
|
if (forceDraft == $scope.curDialog.peer) { |
|
|
$scope.draftMessage.isBroadcast = AppPeersManager.isBroadcast($scope.curDialog.peerID) |
|
|
$scope.$broadcast('ui_peer_draft') |
|
|
return |
|
|
} else { |
|
|
forceDraft = false |
|
|
} |
|
|
} |
|
|
|
|
|
fwdsClear() |
|
|
getDraft() |
|
|
} |
|
|
|
|
|
function getDraft () { |
|
|
if ($scope.curDialog.peerID) { |
|
|
var draftDataPromise |
|
|
if (editMessageID) { |
|
|
draftDataPromise = AppMessagesManager.getMessageEditData(editMessageID).then(function (draftData) { |
|
|
draftData.replyToMsgID = editMessageID |
|
|
return draftData |
|
|
}, function (error) { |
|
|
console.warn(error) |
|
|
editMessageID = false |
|
|
getDraft() |
|
|
return $q.reject() |
|
|
}) |
|
|
} else { |
|
|
draftDataPromise = DraftsManager.getDraft($scope.curDialog.peerID) |
|
|
} |
|
|
draftDataPromise.then(function (draftData) { |
|
|
$scope.draftMessage.type = editMessageID ? 'edit' : 'new' |
|
|
$scope.draftMessage.text = draftData ? draftData.text : '' |
|
|
$scope.draftMessage.isBroadcast = AppPeersManager.isBroadcast($scope.curDialog.peerID) |
|
|
if (draftData.replyToMsgID) { |
|
|
var replyToMsgID = draftData.replyToMsgID |
|
|
replySelect(replyToMsgID) |
|
|
} else { |
|
|
replyClear() |
|
|
} |
|
|
$scope.$broadcast('ui_peer_draft') |
|
|
}) |
|
|
} else { |
|
|
// console.log('Reset peer') |
|
|
$scope.draftMessage.text = '' |
|
|
$scope.$broadcast('ui_peer_draft') |
|
|
} |
|
|
} |
|
|
|
|
|
function applyDraftAttachment (e, attachment) { |
|
|
console.log(dT(), 'apply draft attach', attachment) |
|
|
if (!attachment || !attachment._) { |
|
|
return |
|
|
} |
|
|
|
|
|
if (attachment._ == 'share_url') { |
|
|
var url = attachment.url |
|
|
var text = attachment.text || ' ' |
|
|
forceDraft = $scope.curDialog.peer |
|
|
|
|
|
$timeout(function () { |
|
|
$scope.draftMessage.text = url + '\n' + text |
|
|
$scope.$broadcast('ui_peer_draft', { |
|
|
customSelection: [ |
|
|
url + '\n', |
|
|
text, |
|
|
'' |
|
|
] |
|
|
}) |
|
|
}, 1000) |
|
|
} else if (attachment._ == 'fwd_messages') { |
|
|
forceDraft = $scope.curDialog.peer |
|
|
$timeout(function () { |
|
|
$scope.draftMessage.fwdMessages = attachment.id |
|
|
$scope.$broadcast('ui_peer_reply') |
|
|
}, 100) |
|
|
} else if (attachment._ == 'inline_query') { |
|
|
var mention = attachment.mention |
|
|
var query = attachment.query |
|
|
forceDraft = $scope.curDialog.peer |
|
|
|
|
|
$timeout(function () { |
|
|
$scope.draftMessage.text = mention + ' ' + query |
|
|
$scope.$broadcast('ui_peer_draft', { |
|
|
customSelection: [ |
|
|
mention + ' ' + query, |
|
|
'', |
|
|
'' |
|
|
] |
|
|
}) |
|
|
}, 1000) |
|
|
} |
|
|
} |
|
|
|
|
|
function replySelect (messageID, byUser) { |
|
|
if (editMessageID && byUser) { |
|
|
replyClear() |
|
|
return |
|
|
} |
|
|
$scope.draftMessage.replyToMsgID = messageID |
|
|
$scope.$broadcast('ui_peer_reply') |
|
|
replyToMarkup = false |
|
|
|
|
|
if (byUser && !editMessageID) { |
|
|
DraftsManager.changeDraft($scope.curDialog.peerID, { |
|
|
text: $scope.draftMessage.text, |
|
|
replyToMsgID: messageID |
|
|
}) |
|
|
} |
|
|
} |
|
|
|
|
|
function setEditDraft (messageID) { |
|
|
editMessageID = messageID |
|
|
getDraft() |
|
|
} |
|
|
|
|
|
function setEditLastMessage () { |
|
|
if (editMessageID || |
|
|
!$scope.curDialog.peerID) { |
|
|
return false |
|
|
} |
|
|
AppMessagesManager.getHistory($scope.curDialog.peerID).then(function (historyResult) { |
|
|
for (var i = 0, messageID; i < historyResult.history.length; i++) { |
|
|
messageID = historyResult.history[i] |
|
|
if (AppMessagesManager.canEditMessage(messageID)) { |
|
|
setEditDraft(messageID) |
|
|
break |
|
|
} |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
function replyClear (byUser) { |
|
|
if (editMessageID) { |
|
|
editMessageID = false |
|
|
getDraft() |
|
|
return |
|
|
} |
|
|
var mid = $scope.draftMessage.replyToMsgID |
|
|
if (mid && |
|
|
$scope.historyState.replyKeyboard && |
|
|
$scope.historyState.replyKeyboard.mid == mid && |
|
|
!$scope.historyState.replyKeyboard.pFlags.hidden) { |
|
|
$scope.historyState.replyKeyboard.pFlags.hidden = true |
|
|
$scope.$broadcast('ui_keyboard_update') |
|
|
} |
|
|
delete $scope.draftMessage.replyToMsgID |
|
|
$scope.$broadcast('ui_peer_reply') |
|
|
|
|
|
if (byUser) { |
|
|
DraftsManager.changeDraft($scope.curDialog.peerID, { |
|
|
text: $scope.draftMessage.text |
|
|
}) |
|
|
} |
|
|
} |
|
|
|
|
|
function fwdsClear () { |
|
|
if ($scope.draftMessage.fwdMessages && |
|
|
$scope.draftMessage.fwdMessages.length) { |
|
|
delete $scope.draftMessage.fwdMessages |
|
|
$scope.$broadcast('ui_peer_reply') |
|
|
|
|
|
if (forceDraft == $scope.curDialog.peer) { |
|
|
forceDraft = false |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
function fwdsSend () { |
|
|
if ($scope.draftMessage.fwdMessages && |
|
|
$scope.draftMessage.fwdMessages.length) { |
|
|
var ids = $scope.draftMessage.fwdMessages.slice() |
|
|
fwdsClear() |
|
|
setZeroTimeout(function () { |
|
|
AppMessagesManager.forwardMessages($scope.curDialog.peerID, ids) |
|
|
}) |
|
|
} |
|
|
} |
|
|
|
|
|
function toggleSlash ($event) { |
|
|
if ($scope.draftMessage.text && |
|
|
$scope.draftMessage.text.charAt(0) == '/') { |
|
|
$scope.draftMessage.text = '' |
|
|
} else { |
|
|
$scope.draftMessage.text = '/' |
|
|
} |
|
|
$scope.$broadcast('ui_peer_draft', {focus: true}) |
|
|
return cancelEvent($event) |
|
|
} |
|
|
|
|
|
function updateReplyKeyboard () { |
|
|
var peerID = $scope.curDialog.peerID |
|
|
var replyKeyboard = AppMessagesManager.getReplyKeyboard(peerID) |
|
|
if (replyKeyboard) { |
|
|
replyKeyboard = AppMessagesManager.wrapReplyMarkup(replyKeyboard) |
|
|
} |
|
|
// console.log('update reply markup', peerID, replyKeyboard) |
|
|
$scope.historyState.replyKeyboard = replyKeyboard |
|
|
|
|
|
var addReplyMessage = |
|
|
replyKeyboard && |
|
|
!replyKeyboard.pFlags.hidden && |
|
|
(replyKeyboard._ == 'replyKeyboardForceReply' || |
|
|
(replyKeyboard._ == 'replyKeyboardMarkup' && peerID < 0)) |
|
|
|
|
|
if (addReplyMessage) { |
|
|
replySelect(replyKeyboard.mid) |
|
|
replyToMarkup = true |
|
|
} else if (replyToMarkup) { |
|
|
replyClear() |
|
|
} |
|
|
var enabled = replyKeyboard && |
|
|
!replyKeyboard.pFlags.hidden && |
|
|
replyKeyboard._ == 'replyKeyboardMarkup' |
|
|
$scope.$broadcast('ui_keyboard_update', {enabled: enabled}) |
|
|
$scope.$emit('ui_panel_update', {blur: enabled}) |
|
|
} |
|
|
|
|
|
function replyKeyboardToggle ($event) { |
|
|
var replyKeyboard = $scope.historyState.replyKeyboard |
|
|
if (replyKeyboard) { |
|
|
replyKeyboard.pFlags.hidden = !replyKeyboard.pFlags.hidden |
|
|
updateReplyKeyboard() |
|
|
} |
|
|
return cancelEvent($event) |
|
|
} |
|
|
|
|
|
function onMessageChange (newVal, prevVal, a) { |
|
|
// console.log('ctrl text changed', newVal, prevVal); |
|
|
if (newVal === '' && prevVal === '') { |
|
|
return |
|
|
} |
|
|
|
|
|
if (newVal && newVal.length) { |
|
|
if (!$scope.historyFilter.mediaType && !$scope.historyState.skipped) { |
|
|
AppMessagesManager.readHistory($scope.curDialog.peerID) |
|
|
} |
|
|
} |
|
|
if ($scope.curDialog.peerID) { |
|
|
if (!editMessageID) { |
|
|
var replyToMsgID = $scope.draftMessage.replyToMsgID |
|
|
if (replyToMsgID && |
|
|
$scope.historyState.replyKeyboard && |
|
|
$scope.historyState.replyKeyboard.mid == replyToMsgID) { |
|
|
replyToMsgID = 0 |
|
|
} |
|
|
DraftsManager.changeDraft($scope.curDialog.peerID, { |
|
|
text: newVal, |
|
|
replyToMsgID: replyToMsgID |
|
|
}) |
|
|
} |
|
|
checkInlinePattern(newVal) |
|
|
} |
|
|
} |
|
|
|
|
|
var inlineUsernameRegex = /^@([a-zA-Z\d_]{1,32})( | )([\s\S]*)$/ |
|
|
var inlineStickersEmojiRegex = /^\s*:(\S+):\s*$/ |
|
|
var getInlineResultsTO = false |
|
|
var lastInlineBot = false |
|
|
var jump = 0 |
|
|
|
|
|
function checkInlinePattern (message) { |
|
|
if (getInlineResultsTO) { |
|
|
$timeout.cancel(getInlineResultsTO) |
|
|
} |
|
|
var curJump = ++jump |
|
|
if (!message || !message.length) { |
|
|
delete $scope.draftMessage.inlineProgress |
|
|
$scope.$broadcast('inline_results', false) |
|
|
return |
|
|
} |
|
|
var matches = message.match(inlineUsernameRegex) |
|
|
if (!matches) { |
|
|
matches = message.match(inlineStickersEmojiRegex) |
|
|
if (matches) { |
|
|
var emojiCode = EmojiHelper.shortcuts[matches[1]] |
|
|
if (emojiCode) { |
|
|
$scope.draftMessage.inlineProgress = true |
|
|
AppStickersManager.searchStickers(emojiCode).then(function (docs) { |
|
|
var inlineResults = [] |
|
|
angular.forEach(docs, function (doc) { |
|
|
inlineResults.push({ |
|
|
_: 'botInlineMediaResult', |
|
|
qID: '_sticker_' + doc.id, |
|
|
pFlags: {sticker: true}, |
|
|
id: doc.id, |
|
|
type: 'sticker', |
|
|
document: doc, |
|
|
send_message: {_: 'botInlineMessageMediaAuto'} |
|
|
}) |
|
|
}) |
|
|
var botResults = { |
|
|
pFlags: {gallery: true}, |
|
|
query_id: 0, |
|
|
results: inlineResults |
|
|
} |
|
|
botResults.text = message |
|
|
$scope.$broadcast('inline_results', botResults) |
|
|
delete $scope.draftMessage.inlineProgress |
|
|
}) |
|
|
} else { |
|
|
delete $scope.draftMessage.inlineProgress |
|
|
$scope.$broadcast('inline_results', false) |
|
|
return |
|
|
} |
|
|
} |
|
|
delete $scope.draftMessage.inlineProgress |
|
|
$scope.$broadcast('inline_results', false) |
|
|
return |
|
|
} |
|
|
var username = matches[1] |
|
|
var inlineBotPromise |
|
|
$scope.draftMessage.inlineProgress = true |
|
|
if (lastInlineBot && lastInlineBot.username == username) { |
|
|
inlineBotPromise = $q.when(lastInlineBot) |
|
|
} else { |
|
|
inlineBotPromise = AppInlineBotsManager.resolveInlineMention(username) |
|
|
} |
|
|
inlineBotPromise.then(function (inlineBot) { |
|
|
if (curJump != jump) { |
|
|
return |
|
|
} |
|
|
lastInlineBot = inlineBot |
|
|
$scope.$broadcast('inline_placeholder', { |
|
|
prefix: '@' + username + matches[2], |
|
|
placeholder: inlineBot.placeholder |
|
|
}) |
|
|
if (getInlineResultsTO) { |
|
|
$timeout.cancel(getInlineResultsTO) |
|
|
} |
|
|
getInlineResultsTO = $timeout(function () { |
|
|
var query = RichTextProcessor.parseEmojis(matches[3]) |
|
|
AppInlineBotsManager.getInlineResults($scope.curDialog.peerID, inlineBot.id, query, inlineBot.geo, '').then(function (botResults) { |
|
|
getInlineResultsTO = false |
|
|
if (curJump != jump) { |
|
|
return |
|
|
} |
|
|
botResults.text = message |
|
|
$scope.$broadcast('inline_results', botResults) |
|
|
delete $scope.draftMessage.inlineProgress |
|
|
}, function () { |
|
|
$scope.$broadcast('inline_results', false) |
|
|
delete $scope.draftMessage.inlineProgress |
|
|
}) |
|
|
}, 500) |
|
|
}, function (error) { |
|
|
$scope.$broadcast('inline_results', false) |
|
|
delete $scope.draftMessage.inlineProgress |
|
|
}) |
|
|
} |
|
|
|
|
|
function onTyping () { |
|
|
if (AppPeersManager.isBroadcast($scope.curDialog.peerID)) { |
|
|
return false |
|
|
} |
|
|
MtpApiManager.invokeApi('messages.setTyping', { |
|
|
peer: AppPeersManager.getInputPeerByID($scope.curDialog.peerID), |
|
|
action: {_: 'sendMessageTypingAction'} |
|
|
})['catch'](function (error) { |
|
|
error.handled = true |
|
|
}) |
|
|
} |
|
|
|
|
|
function onFilesSelected (newVal) { |
|
|
if (!angular.isArray(newVal) || !newVal.length) { |
|
|
return |
|
|
} |
|
|
var options = { |
|
|
replyToMsgID: $scope.draftMessage.replyToMsgID, |
|
|
isMedia: $scope.draftMessage.isMedia |
|
|
} |
|
|
|
|
|
delete $scope.draftMessage.replyToMsgID |
|
|
|
|
|
if (newVal[0].lastModified) { |
|
|
newVal.sort(function (file1, file2) { |
|
|
return file1.lastModified - file2.lastModified |
|
|
}) |
|
|
} |
|
|
|
|
|
for (var i = 0; i < newVal.length; i++) { |
|
|
AppMessagesManager.sendFile($scope.curDialog.peerID, newVal[i], options) |
|
|
$scope.$broadcast('ui_message_send') |
|
|
} |
|
|
fwdsSend() |
|
|
} |
|
|
|
|
|
function onStickerSelected (newVal) { |
|
|
if (!newVal) { |
|
|
return |
|
|
} |
|
|
|
|
|
var doc = AppDocsManager.getDoc(newVal) |
|
|
if (doc.id && doc.access_hash) { |
|
|
var inputMedia = { |
|
|
_: 'inputMediaDocument', |
|
|
id: { |
|
|
_: 'inputDocument', |
|
|
id: doc.id, |
|
|
access_hash: doc.access_hash |
|
|
} |
|
|
} |
|
|
var options = { |
|
|
replyToMsgID: $scope.draftMessage.replyToMsgID |
|
|
} |
|
|
AppMessagesManager.sendOther($scope.curDialog.peerID, inputMedia, options) |
|
|
$scope.$broadcast('ui_message_send') |
|
|
|
|
|
fwdsSend() |
|
|
replyClear(true) |
|
|
} |
|
|
delete $scope.draftMessage.sticker |
|
|
} |
|
|
|
|
|
function onCommandSelected (command) { |
|
|
if (!command) { |
|
|
return |
|
|
} |
|
|
AppMessagesManager.sendText($scope.curDialog.peerID, command, { |
|
|
clearDraft: true |
|
|
}) |
|
|
|
|
|
if (forceDraft == $scope.curDialog.peer) { |
|
|
forceDraft = false |
|
|
} |
|
|
|
|
|
fwdsSend() |
|
|
resetDraft() |
|
|
delete $scope.draftMessage.sticker |
|
|
delete $scope.draftMessage.text |
|
|
delete $scope.draftMessage.command |
|
|
delete $scope.draftMessage.inlineResultID |
|
|
$scope.$broadcast('ui_message_send') |
|
|
$scope.$broadcast('ui_peer_draft') |
|
|
} |
|
|
|
|
|
function onInlineResultSelected (qID) { |
|
|
if (!qID) { |
|
|
return |
|
|
} |
|
|
|
|
|
if (qID.substr(0, 11) == '_switch_pm_') { |
|
|
var botID = lastInlineBot.id |
|
|
var startParam = qID.substr(11) |
|
|
return AppInlineBotsManager.switchToPM($scope.curDialog.peerID, botID, startParam) |
|
|
} |
|
|
|
|
|
var options = { |
|
|
replyToMsgID: $scope.draftMessage.replyToMsgID, |
|
|
clearDraft: true |
|
|
} |
|
|
|
|
|
if (qID.substr(0, 9) == '_sticker_') { |
|
|
var docID = qID.substr(9) |
|
|
var doc = AppDocsManager.getDoc(docID) |
|
|
if (doc.id && doc.access_hash) { |
|
|
var inputMedia = { |
|
|
_: 'inputMediaDocument', |
|
|
id: { |
|
|
_: 'inputDocument', |
|
|
id: doc.id, |
|
|
access_hash: doc.access_hash |
|
|
} |
|
|
} |
|
|
AppMessagesManager.sendOther($scope.curDialog.peerID, inputMedia, options) |
|
|
} |
|
|
} |
|
|
else { |
|
|
AppInlineBotsManager.sendInlineResult($scope.curDialog.peerID, qID, options) |
|
|
} |
|
|
|
|
|
|
|
|
if (forceDraft == $scope.curDialog.peer) { |
|
|
forceDraft = false |
|
|
} |
|
|
|
|
|
fwdsSend() |
|
|
resetDraft() |
|
|
delete $scope.draftMessage.sticker |
|
|
delete $scope.draftMessage.text |
|
|
delete $scope.draftMessage.command |
|
|
delete $scope.draftMessage.inlineResultID |
|
|
$scope.$broadcast('ui_message_send') |
|
|
$scope.$broadcast('ui_peer_draft') |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('AppLangSelectController', function ($scope, _, Storage, ErrorService, AppRuntimeManager) { |
|
|
$scope.supportedLocales = Config.I18n.supported |
|
|
$scope.langNames = Config.I18n.languages |
|
|
$scope.curLocale = Config.I18n.locale |
|
|
$scope.form = {locale: Config.I18n.locale} |
|
|
|
|
|
$scope.localeSelect = function localeSelect (newLocale) { |
|
|
newLocale = newLocale || $scope.form.locale |
|
|
if ($scope.curLocale !== newLocale) { |
|
|
ErrorService.confirm({type: 'APPLY_LANG_WITH_RELOAD'}).then(function () { |
|
|
Storage.set({i18n_locale: newLocale}).then(function () { |
|
|
AppRuntimeManager.reload() |
|
|
}) |
|
|
}, function () { |
|
|
$scope.form.locale = $scope.curLocale |
|
|
}) |
|
|
} |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('AppFooterController', function ($scope, LayoutSwitchService) { |
|
|
$scope.switchLayout = function (mobile) { |
|
|
LayoutSwitchService.switchLayout(mobile) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('PhotoModalController', function ($q, $scope, $rootScope, $modalInstance, AppPhotosManager, AppMessagesManager, AppPeersManager, AppWebPagesManager, PeersSelectService, ErrorService) { |
|
|
$scope.photo = AppPhotosManager.wrapForFull($scope.photoID) |
|
|
$scope.nav = {} |
|
|
|
|
|
$scope.download = function () { |
|
|
AppPhotosManager.downloadPhoto($scope.photoID) |
|
|
} |
|
|
|
|
|
if (!$scope.messageID) { |
|
|
return |
|
|
} |
|
|
|
|
|
$scope.forward = function () { |
|
|
var messageID = $scope.messageID |
|
|
|
|
|
PeersSelectService.selectPeer({canSend: true}).then(function (peerString) { |
|
|
$rootScope.$broadcast('history_focus', { |
|
|
peerString: peerString, |
|
|
attachment: { |
|
|
_: 'fwd_messages', |
|
|
id: [messageID] |
|
|
} |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.goToMessage = function () { |
|
|
var messageID = $scope.messageID |
|
|
var peerID = AppMessagesManager.getMessagePeer(AppMessagesManager.getMessage(messageID)) |
|
|
var peerString = AppPeersManager.getPeerString(peerID) |
|
|
$modalInstance.dismiss() |
|
|
$rootScope.$broadcast('history_focus', {peerString: peerString, messageID: messageID}) |
|
|
} |
|
|
|
|
|
$scope['delete'] = function () { |
|
|
var messageID = $scope.messageID |
|
|
ErrorService.confirm({type: 'MESSAGE_DELETE'}).then(function () { |
|
|
AppMessagesManager.deleteMessages([messageID]) |
|
|
}) |
|
|
} |
|
|
|
|
|
var peerID = AppMessagesManager.getMessagePeer(AppMessagesManager.getMessage($scope.messageID)) |
|
|
var inputPeer = AppPeersManager.getInputPeerByID(peerID) |
|
|
var inputQuery = '' |
|
|
var inputFilter = {_: 'inputMessagesFilterPhotos'} |
|
|
var list = [$scope.messageID] |
|
|
var preloaded = {} |
|
|
var maxID = $scope.messageID |
|
|
var hasMore = true |
|
|
|
|
|
preloaded[$scope.messageID] = true |
|
|
|
|
|
updatePrevNext() |
|
|
|
|
|
function preloadPhotos (sign) { |
|
|
// var preloadOffsets = sign < 0 ? [-1,-2,1,-3,2] : [1,2,-1,3,-2] |
|
|
var preloadOffsets = sign < 0 ? [-1, -2] : [1, 2] |
|
|
var index = list.indexOf($scope.messageID) |
|
|
angular.forEach(preloadOffsets, function (offset) { |
|
|
var messageID = list[index + offset] |
|
|
if (messageID !== undefined && preloaded[messageID] === undefined) { |
|
|
preloaded[messageID] = true |
|
|
var message = AppMessagesManager.getMessage(messageID) |
|
|
var photoID = message.media.photo.id |
|
|
AppPhotosManager.preloadPhoto(photoID) |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
function updatePrevNext (count) { |
|
|
var index = list.indexOf($scope.messageID) |
|
|
if (hasMore) { |
|
|
if (count) { |
|
|
$scope.count = Math.max(count, list.length) |
|
|
} |
|
|
} else { |
|
|
$scope.count = list.length |
|
|
} |
|
|
$scope.pos = $scope.count - index |
|
|
$scope.nav.hasNext = index > 0 |
|
|
$scope.nav.hasPrev = hasMore || index < list.length - 1 |
|
|
$scope.canForward = $scope.canDelete = $scope.messageID > 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.$on('history_delete', function (e, 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 |
|
|
} |
|
|
}) |
|
|
|
|
|
if ($scope.webpageID) { |
|
|
$scope.webpage = AppWebPagesManager.wrapForHistory($scope.webpageID) |
|
|
return |
|
|
} |
|
|
|
|
|
AppMessagesManager.getSearch(peerID, inputQuery, inputFilter, 0, 1000).then(function (searchCachedResult) { |
|
|
if (searchCachedResult.history.indexOf($scope.messageID) >= 0) { |
|
|
list = searchCachedResult.history |
|
|
maxID = list[list.length - 1] |
|
|
|
|
|
updatePrevNext() |
|
|
preloadPhotos(+1) |
|
|
} |
|
|
loadMore() |
|
|
}, loadMore) |
|
|
|
|
|
var jump = 0 |
|
|
function movePosition (sign) { |
|
|
var curIndex = list.indexOf($scope.messageID) |
|
|
var index = curIndex >= 0 ? curIndex + sign : 0 |
|
|
var curJump = ++jump |
|
|
|
|
|
var promise = index >= list.length ? loadMore() : $q.when() |
|
|
promise.then(function () { |
|
|
if (curJump != jump) { |
|
|
return |
|
|
} |
|
|
|
|
|
var messageID = list[index] |
|
|
var message = AppMessagesManager.getMessage(messageID) |
|
|
var photoID = message && message.media && |
|
|
((message.media.photo && message.media.photo.id) || |
|
|
(message.media.webpage && message.media.webpage.photo && message.media.webpage.photo.id)) |
|
|
if (!photoID) { |
|
|
console.error('Invalid photo message', index, list, messageID, message) |
|
|
return |
|
|
} |
|
|
|
|
|
$scope.messageID = messageID |
|
|
$scope.photoID = photoID |
|
|
$scope.photo = AppPhotosManager.wrapForFull($scope.photoID) |
|
|
|
|
|
preloaded[$scope.messageID] = true |
|
|
|
|
|
updatePrevNext() |
|
|
|
|
|
if (sign > 0 && hasMore && list.indexOf(messageID) + 1 >= list.length) { |
|
|
loadMore() |
|
|
} else { |
|
|
preloadPhotos(sign) |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
var loadingPromise = false |
|
|
function loadMore () { |
|
|
if (loadingPromise) return loadingPromise |
|
|
|
|
|
return loadingPromise = AppMessagesManager.getSearch(peerID, inputQuery, inputFilter, maxID).then(function (searchResult) { |
|
|
if (searchResult.history.length) { |
|
|
maxID = searchResult.history[searchResult.history.length - 1] |
|
|
list = list.concat(searchResult.history) |
|
|
hasMore = list.length < searchResult.count |
|
|
} else { |
|
|
hasMore = false |
|
|
} |
|
|
|
|
|
updatePrevNext(searchResult.count) |
|
|
loadingPromise = false |
|
|
|
|
|
if (searchResult.history.length) { |
|
|
return $q.reject() |
|
|
} |
|
|
|
|
|
preloadPhotos(+1) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('UserpicModalController', function ($q, $scope, $rootScope, $modalInstance, MtpApiManager, AppPhotosManager, AppUsersManager, AppPeersManager, AppMessagesManager, ApiUpdatesManager, PeersSelectService, ErrorService) { |
|
|
$scope.photo = AppPhotosManager.wrapForFull($scope.photoID) |
|
|
$scope.photo.thumb = { |
|
|
location: AppPhotosManager.choosePhotoSize($scope.photo, 0, 0).location |
|
|
} |
|
|
|
|
|
$scope.nav = {} |
|
|
$scope.canForward = true |
|
|
|
|
|
var list = [$scope.photoID] |
|
|
var maxID = $scope.photoID |
|
|
var preloaded = {} |
|
|
var myID = 0 |
|
|
var hasMore = true |
|
|
|
|
|
updatePrevNext() |
|
|
|
|
|
AppPhotosManager.getUserPhotos($scope.userID, 0, 1000).then(function (userpicCachedResult) { |
|
|
if (userpicCachedResult.photos.indexOf($scope.photoID) >= 0) { |
|
|
list = userpicCachedResult.photos |
|
|
maxID = list[list.length - 1] |
|
|
} |
|
|
hasMore = list.length < userpicCachedResult.count |
|
|
updatePrevNext() |
|
|
}) |
|
|
|
|
|
MtpApiManager.getUserID().then(function (id) { |
|
|
myID = id |
|
|
$scope.canDelete = $scope.photo.user_id == myID |
|
|
}) |
|
|
|
|
|
var jump = 0 |
|
|
function movePosition (sign, deleteCurrent) { |
|
|
var curIndex = list.indexOf($scope.photoID) |
|
|
var index = curIndex >= 0 ? curIndex + sign : 0 |
|
|
var curJump = ++jump |
|
|
|
|
|
var promise = index >= list.length ? loadMore() : $q.when() |
|
|
promise.then(function () { |
|
|
if (curJump != jump) { |
|
|
return |
|
|
} |
|
|
|
|
|
$scope.photoID = list[index] |
|
|
$scope.photo = AppPhotosManager.wrapForFull($scope.photoID) |
|
|
$scope.photo.thumb = { |
|
|
location: AppPhotosManager.choosePhotoSize($scope.photo, 0, 0).location |
|
|
} |
|
|
|
|
|
var newCount |
|
|
if (deleteCurrent) { |
|
|
list.splice(curIndex, 1) |
|
|
newCount = $scope.count - 1 |
|
|
} |
|
|
|
|
|
updatePrevNext(newCount) |
|
|
|
|
|
preloaded[$scope.photoID] = true |
|
|
|
|
|
updatePrevNext() |
|
|
|
|
|
if (sign > 0 && hasMore && list.indexOf($scope.photoID) + 1 >= list.length) { |
|
|
loadMore() |
|
|
} else { |
|
|
preloadPhotos(sign) |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
function preloadPhotos (sign) { |
|
|
var preloadOffsets = sign < 0 ? [-1, -2] : [1, 2] |
|
|
var index = list.indexOf($scope.photoID) |
|
|
angular.forEach(preloadOffsets, function (offset) { |
|
|
var photoID = list[index + offset] |
|
|
if (photoID !== undefined && preloaded[photoID] === undefined) { |
|
|
preloaded[photoID] = true |
|
|
AppPhotosManager.preloadPhoto(photoID) |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
var loadingPromise = false |
|
|
function loadMore () { |
|
|
if (loadingPromise) return loadingPromise |
|
|
|
|
|
return loadingPromise = AppPhotosManager.getUserPhotos($scope.userID, maxID).then(function (userpicResult) { |
|
|
if (userpicResult.photos.length) { |
|
|
maxID = userpicResult.photos[userpicResult.photos.length - 1] |
|
|
list = list.concat(userpicResult.photos) |
|
|
|
|
|
hasMore = list.length < userpicResult.count |
|
|
} else { |
|
|
hasMore = false |
|
|
} |
|
|
|
|
|
updatePrevNext(userpicResult.count) |
|
|
loadingPromise = false |
|
|
|
|
|
if (userpicResult.photos.length) { |
|
|
return $q.reject() |
|
|
} |
|
|
|
|
|
preloadPhotos(+1) |
|
|
}) |
|
|
} |
|
|
|
|
|
function updatePrevNext (count) { |
|
|
var index = list.indexOf($scope.photoID) |
|
|
if (hasMore) { |
|
|
if (count) { |
|
|
$scope.count = Math.max(count, list.length) |
|
|
} |
|
|
} else { |
|
|
$scope.count = list.length |
|
|
} |
|
|
$scope.pos = $scope.count - index |
|
|
$scope.nav.hasNext = index > 0 |
|
|
$scope.nav.hasPrev = hasMore || index < list.length - 1 |
|
|
$scope.canDelete = $scope.photo.user_id == myID |
|
|
} |
|
|
|
|
|
$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 () { |
|
|
PeersSelectService.selectPeer({confirm_type: 'FORWARD_PEER', canSend: true}).then(function (peerString) { |
|
|
var peerID = AppPeersManager.getPeerID(peerString) |
|
|
AppMessagesManager.sendOther(peerID, { |
|
|
_: 'inputMediaPhoto', |
|
|
id: { |
|
|
_: 'inputPhoto', |
|
|
id: $scope.photoID, |
|
|
access_hash: $scope.photo.access_hash |
|
|
} |
|
|
}) |
|
|
$rootScope.$broadcast('history_focus', {peerString: peerString}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope['delete'] = function () { |
|
|
var photoID = $scope.photoID |
|
|
var myUser = AppUsersManager.getUser(myID) |
|
|
var onDeleted = function () { |
|
|
if (!$scope.nav.hasNext && !$scope.nav.hasPrev) { |
|
|
return $modalInstance.dismiss() |
|
|
} |
|
|
movePosition($scope.nav.hasNext ? -1 : +1, true) |
|
|
} |
|
|
|
|
|
ErrorService.confirm({type: 'PHOTO_DELETE'}).then(function () { |
|
|
if (myUser && myUser.photo && myUser.photo.photo_id == photoID) { |
|
|
MtpApiManager.invokeApi('photos.updateProfilePhoto', { |
|
|
id: {_: 'inputPhotoEmpty'} |
|
|
}).then(function (updateResult) { |
|
|
ApiUpdatesManager.processUpdateMessage({ |
|
|
_: 'updateShort', |
|
|
update: { |
|
|
_: 'updateUserPhoto', |
|
|
user_id: myID, |
|
|
date: tsNow(true), |
|
|
photo: updateResult, |
|
|
previous: true |
|
|
} |
|
|
}) |
|
|
onDeleted() |
|
|
}) |
|
|
} else { |
|
|
MtpApiManager.invokeApi('photos.deletePhotos', { |
|
|
id: [{_: 'inputPhoto', id: photoID, access_hash: 0}] |
|
|
}).then(onDeleted) |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.download = function () { |
|
|
AppPhotosManager.downloadPhoto($scope.photoID) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('ChatpicModalController', function ($q, $scope, $rootScope, $modalInstance, MtpApiManager, AppPhotosManager, AppChatsManager, AppPeersManager, AppMessagesManager, ApiUpdatesManager, PeersSelectService, ErrorService) { |
|
|
$scope.photo = AppPhotosManager.wrapForFull($scope.photoID) |
|
|
$scope.photo.thumb = { |
|
|
location: AppPhotosManager.choosePhotoSize($scope.photo, 0, 0).location |
|
|
} |
|
|
|
|
|
var chat = AppChatsManager.getChat($scope.chatID) |
|
|
var isChannel = AppChatsManager.isChannel($scope.chatID) |
|
|
|
|
|
$scope.canForward = true |
|
|
$scope.canDelete = isChannel ? chat.pFlags.creator : true |
|
|
|
|
|
$scope.forward = function () { |
|
|
PeersSelectService.selectPeer({confirm_type: 'FORWARD_PEER', canSend: true}).then(function (peerString) { |
|
|
var peerID = AppPeersManager.getPeerID(peerString) |
|
|
AppMessagesManager.sendOther(peerID, { |
|
|
_: 'inputMediaPhoto', |
|
|
id: { |
|
|
_: 'inputPhoto', |
|
|
id: $scope.photoID, |
|
|
access_hash: $scope.photo.access_hash |
|
|
} |
|
|
}) |
|
|
$rootScope.$broadcast('history_focus', {peerString: peerString}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope['delete'] = function () { |
|
|
ErrorService.confirm({type: 'PHOTO_DELETE'}).then(function () { |
|
|
$scope.photo.updating = true |
|
|
var apiPromise |
|
|
if (AppChatsManager.isChannel($scope.chatID)) { |
|
|
apiPromise = MtpApiManager.invokeApi('channels.editPhoto', { |
|
|
channel: AppChatsManager.getChannelInput($scope.chatID), |
|
|
photo: {_: 'inputChatPhotoEmpty'} |
|
|
}) |
|
|
} else { |
|
|
apiPromise = MtpApiManager.invokeApi('messages.editChatPhoto', { |
|
|
chat_id: AppChatsManager.getChatInput($scope.chatID), |
|
|
photo: {_: 'inputChatPhotoEmpty'} |
|
|
}) |
|
|
} |
|
|
apiPromise.then(function (updates) { |
|
|
ApiUpdatesManager.processUpdateMessage(updates) |
|
|
$modalInstance.dismiss() |
|
|
$rootScope.$broadcast('history_focus', {peerString: AppChatsManager.getChatString($scope.chatID)}) |
|
|
})['finally'](function () { |
|
|
$scope.photo.updating = false |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.download = function () { |
|
|
AppPhotosManager.downloadPhoto($scope.photoID) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('VideoModalController', function ($scope, $rootScope, $modalInstance, PeersSelectService, AppMessagesManager, AppDocsManager, AppPeersManager, ErrorService) { |
|
|
$scope.video = AppDocsManager.wrapVideoForFull($scope.docID) |
|
|
|
|
|
$scope.progress = {enabled: false} |
|
|
$scope.player = {} |
|
|
|
|
|
$scope.forward = function () { |
|
|
var messageID = $scope.messageID |
|
|
PeersSelectService.selectPeer({canSend: true}).then(function (peerString) { |
|
|
$rootScope.$broadcast('history_focus', { |
|
|
peerString: peerString, |
|
|
attachment: { |
|
|
_: 'fwd_messages', |
|
|
id: [messageID] |
|
|
} |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope['delete'] = function () { |
|
|
var messageID = $scope.messageID |
|
|
ErrorService.confirm({type: 'MESSAGE_DELETE'}).then(function () { |
|
|
AppMessagesManager.deleteMessages([messageID]) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.download = function () { |
|
|
AppDocsManager.saveDocFile($scope.docID) |
|
|
} |
|
|
|
|
|
$scope.$on('history_delete', function (e, historyUpdate) { |
|
|
if (historyUpdate && historyUpdate.msgs && historyUpdate.msgs[$scope.messageID]) { |
|
|
$modalInstance.dismiss() |
|
|
} |
|
|
}) |
|
|
}) |
|
|
|
|
|
.controller('DocumentModalController', function ($scope, $rootScope, $modalInstance, PeersSelectService, AppMessagesManager, AppDocsManager, AppPeersManager, ErrorService) { |
|
|
$scope.document = AppDocsManager.wrapForHistory($scope.docID) |
|
|
|
|
|
$scope.forward = function () { |
|
|
var messageID = $scope.messageID |
|
|
PeersSelectService.selectPeer({canSend: true}).then(function (peerString) { |
|
|
$rootScope.$broadcast('history_focus', { |
|
|
peerString: peerString, |
|
|
attachment: { |
|
|
_: 'fwd_messages', |
|
|
id: [messageID] |
|
|
} |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope['delete'] = function () { |
|
|
var messageID = $scope.messageID |
|
|
ErrorService.confirm({type: 'MESSAGE_DELETE'}).then(function () { |
|
|
AppMessagesManager.deleteMessages([messageID]) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.download = function () { |
|
|
AppDocsManager.saveDocFile($scope.docID) |
|
|
} |
|
|
|
|
|
$scope.$on('history_delete', function (e, historyUpdate) { |
|
|
if (historyUpdate && historyUpdate.msgs && historyUpdate.msgs[$scope.messageID]) { |
|
|
$modalInstance.dismiss() |
|
|
} |
|
|
}) |
|
|
}) |
|
|
|
|
|
.controller('EmbedModalController', function ($q, $scope, $rootScope, $modalInstance, AppPhotosManager, AppMessagesManager, AppPeersManager, AppWebPagesManager, PeersSelectService, ErrorService) { |
|
|
$scope.webpage = AppWebPagesManager.wrapForFull($scope.webpageID) |
|
|
|
|
|
$scope.nav = {} |
|
|
|
|
|
$scope.forward = function () { |
|
|
var messageID = $scope.messageID |
|
|
PeersSelectService.selectPeer({canSend: true}).then(function (peerString) { |
|
|
$rootScope.$broadcast('history_focus', { |
|
|
peerString: peerString, |
|
|
attachment: { |
|
|
_: 'fwd_messages', |
|
|
id: [messageID] |
|
|
} |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope['delete'] = function () { |
|
|
var messageID = $scope.messageID |
|
|
ErrorService.confirm({type: 'MESSAGE_DELETE'}).then(function () { |
|
|
AppMessagesManager.deleteMessages([messageID]) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('GameModalController', function ($q, $scope, $rootScope, $modalInstance, AppPhotosManager, AppMessagesManager, AppPeersManager, AppGamesManager, PeersSelectService, ErrorService) { |
|
|
$scope.game = AppGamesManager.wrapForFull($scope.gameID, $scope.messageID, $scope.embedUrl) |
|
|
var messageID = $scope.messageID |
|
|
|
|
|
var message = AppMessagesManager.getMessage(messageID) |
|
|
$scope.botID = message.viaBotID || message.fromID |
|
|
|
|
|
$scope.nav = {} |
|
|
|
|
|
$scope.forward = function (withMyScore) { |
|
|
PeersSelectService.selectPeer({canSend: true, confirm_type: 'INVITE_TO_GAME'}).then(function (peerString) { |
|
|
var peerID = AppPeersManager.getPeerID(peerString) |
|
|
AppMessagesManager.forwardMessages(peerID, [messageID], { |
|
|
withMyScore: withMyScore |
|
|
}).then(function () { |
|
|
$rootScope.$broadcast('history_focus', { |
|
|
peerString: peerString |
|
|
}) |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.$on('game_frame_event', function (e, eventData) { |
|
|
if (eventData.eventType == 'share_score') { |
|
|
$scope.forward(true) |
|
|
} |
|
|
}) |
|
|
}) |
|
|
|
|
|
.controller('UserModalController', function ($scope, $location, $rootScope, $modalInstance, AppProfileManager, $modal, AppUsersManager, MtpApiManager, NotificationsManager, AppPhotosManager, AppMessagesManager, AppPeersManager, PeersSelectService, ErrorService) { |
|
|
var peerString = AppUsersManager.getUserString($scope.userID) |
|
|
|
|
|
$scope.user = AppUsersManager.getUser($scope.userID) |
|
|
$scope.blocked = false |
|
|
|
|
|
$scope.settings = {notifications: true} |
|
|
|
|
|
AppProfileManager.getProfile($scope.userID, $scope.override).then(function (userFull) { |
|
|
$scope.blocked = userFull.pFlags.blocked |
|
|
$scope.bot_info = userFull.bot_info |
|
|
$scope.rAbout = userFull.rAbout |
|
|
|
|
|
NotificationsManager.getPeerMuted($scope.userID).then(function (muted) { |
|
|
$scope.settings.notifications = !muted |
|
|
|
|
|
$scope.$watch('settings.notifications', function (newValue, oldValue) { |
|
|
if (newValue === oldValue) { |
|
|
return false |
|
|
} |
|
|
NotificationsManager.getPeerSettings($scope.userID).then(function (settings) { |
|
|
settings.mute_until = newValue ? 0 : 2000000000 |
|
|
NotificationsManager.updatePeerSettings($scope.userID, settings) |
|
|
}) |
|
|
}) |
|
|
}) |
|
|
}) |
|
|
|
|
|
$scope.goToHistory = function () { |
|
|
$rootScope.$broadcast('history_focus', {peerString: peerString}) |
|
|
} |
|
|
|
|
|
$scope.flushHistory = function (justClear) { |
|
|
ErrorService.confirm({type: justClear ? 'HISTORY_FLUSH' : 'HISTORY_FLUSH_AND_DELETE'}).then(function () { |
|
|
AppMessagesManager.flushHistory($scope.userID, justClear).then(function () { |
|
|
if (justClear) { |
|
|
$scope.goToHistory() |
|
|
} else { |
|
|
$modalInstance.close() |
|
|
$location.url('/im') |
|
|
} |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.importContact = function (edit) { |
|
|
var scope = $rootScope.$new() |
|
|
scope.importContact = { |
|
|
phone: $scope.user.phone, |
|
|
first_name: $scope.user.first_name, |
|
|
last_name: $scope.user.last_name |
|
|
} |
|
|
|
|
|
$modal.open({ |
|
|
templateUrl: templateUrl(edit ? 'edit_contact_modal' : 'import_contact_modal'), |
|
|
controller: 'ImportContactModalController', |
|
|
windowClass: 'md_simple_modal_window mobile_modal', |
|
|
scope: scope |
|
|
}).result.then(function (foundUserID) { |
|
|
if ($scope.userID == foundUserID) { |
|
|
$scope.user = AppUsersManager.getUser($scope.userID) |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.deleteContact = function () { |
|
|
AppUsersManager.deleteContacts([$scope.userID]).then(function () { |
|
|
$scope.user = AppUsersManager.getUser($scope.userID) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.inviteToGroup = function () { |
|
|
PeersSelectService.selectPeer({ |
|
|
confirm_type: 'INVITE_TO_GROUP', |
|
|
noUsers: true |
|
|
}).then(function (peerString) { |
|
|
var peerID = AppPeersManager.getPeerID(peerString) |
|
|
var chatID = peerID < 0 ? -peerID : 0 |
|
|
AppMessagesManager.startBot($scope.user.id, chatID).then(function () { |
|
|
$rootScope.$broadcast('history_focus', {peerString: peerString}) |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.sendCommand = function (command) { |
|
|
AppMessagesManager.sendText($scope.userID, '/' + command) |
|
|
$rootScope.$broadcast('history_focus', { |
|
|
peerString: peerString |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.toggleBlock = function (block) { |
|
|
MtpApiManager.invokeApi(block ? 'contacts.block' : 'contacts.unblock', { |
|
|
id: AppUsersManager.getUserInput($scope.userID) |
|
|
}).then(function () { |
|
|
$scope.blocked = block |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.shareContact = function () { |
|
|
PeersSelectService.selectPeer({confirm_type: 'SHARE_CONTACT_PEER', canSend: true}).then(function (peerString) { |
|
|
var peerID = AppPeersManager.getPeerID(peerString) |
|
|
AppMessagesManager.sendOther(peerID, { |
|
|
_: 'inputMediaContact', |
|
|
phone_number: $scope.user.phone, |
|
|
first_name: $scope.user.first_name, |
|
|
last_name: $scope.user.last_name, |
|
|
user_id: $scope.user.id |
|
|
}) |
|
|
$rootScope.$broadcast('history_focus', {peerString: peerString}) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('ChatModalController', function ($scope, $modalInstance, $location, $timeout, $rootScope, $modal, AppUsersManager, AppChatsManager, AppProfileManager, AppPhotosManager, MtpApiManager, MtpApiFileManager, NotificationsManager, AppMessagesManager, AppPeersManager, ApiUpdatesManager, ContactsSelectService, ErrorService) { |
|
|
$scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, {}) |
|
|
$scope.settings = {notifications: true} |
|
|
|
|
|
$scope.maxParticipants = 200 |
|
|
|
|
|
AppProfileManager.getChatFull($scope.chatID).then(function (chatFull) { |
|
|
$scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, chatFull) |
|
|
$scope.$broadcast('ui_height') |
|
|
|
|
|
$scope.needMigrate = $scope.chatFull && |
|
|
$scope.chatFull.participants && |
|
|
$scope.chatFull.participants.participants && |
|
|
$scope.chatFull.participants.participants.length >= 200 |
|
|
|
|
|
if (Config.Modes.test || Config.Modes.debug) { |
|
|
$scope.needMigrate = true |
|
|
} |
|
|
|
|
|
NotificationsManager.savePeerSettings(-$scope.chatID, chatFull.notify_settings) |
|
|
|
|
|
NotificationsManager.getPeerMuted(-$scope.chatID).then(function (muted) { |
|
|
$scope.settings.notifications = !muted |
|
|
|
|
|
$scope.$watch('settings.notifications', function (newValue, oldValue) { |
|
|
if (newValue === oldValue) { |
|
|
return false |
|
|
} |
|
|
NotificationsManager.getPeerSettings(-$scope.chatID).then(function (settings) { |
|
|
if (newValue) { |
|
|
settings.mute_until = 0 |
|
|
} else { |
|
|
settings.mute_until = 2000000000 |
|
|
} |
|
|
NotificationsManager.updatePeerSettings(-$scope.chatID, settings) |
|
|
}) |
|
|
}) |
|
|
}) |
|
|
}) |
|
|
|
|
|
function onChatUpdated (updates) { |
|
|
ApiUpdatesManager.processUpdateMessage(updates) |
|
|
$rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString}) |
|
|
} |
|
|
|
|
|
$scope.leaveGroup = function () { |
|
|
ErrorService.confirm({type: 'HISTORY_LEAVE_AND_FLUSH'}).then(function () { |
|
|
MtpApiManager.invokeApi('messages.deleteChatUser', { |
|
|
chat_id: AppChatsManager.getChatInput($scope.chatID), |
|
|
user_id: {_: 'inputUserSelf'} |
|
|
}).then(function (updates) { |
|
|
ApiUpdatesManager.processUpdateMessage(updates) |
|
|
AppMessagesManager.flushHistory(-$scope.chatID).then(function () { |
|
|
$modalInstance.close() |
|
|
$location.url('/im') |
|
|
}) |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.inviteToGroup = function () { |
|
|
var disabled = [] |
|
|
angular.forEach($scope.chatFull.participants.participants, function (participant) { |
|
|
disabled.push(participant.user_id) |
|
|
}) |
|
|
|
|
|
ContactsSelectService.selectContacts({disabled: disabled}).then(function (userIDs) { |
|
|
angular.forEach(userIDs, function (userID) { |
|
|
MtpApiManager.invokeApi('messages.addChatUser', { |
|
|
chat_id: AppChatsManager.getChatInput($scope.chatID), |
|
|
user_id: AppUsersManager.getUserInput(userID), |
|
|
fwd_limit: 100 |
|
|
}).then(function (updates) { |
|
|
ApiUpdatesManager.processUpdateMessage(updates) |
|
|
}) |
|
|
}) |
|
|
|
|
|
$rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.migrateToSuperGroup = function () { |
|
|
ErrorService.confirm({type: 'SUPERGROUP_MIGRATE'}).then(function () { |
|
|
MtpApiManager.invokeApi('messages.migrateChat', { |
|
|
chat_id: AppChatsManager.getChatInput($scope.chatID) |
|
|
}).then(onChatUpdated) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.kickFromGroup = function (userID) { |
|
|
MtpApiManager.invokeApi('messages.deleteChatUser', { |
|
|
chat_id: AppChatsManager.getChatInput($scope.chatID), |
|
|
user_id: AppUsersManager.getUserInput(userID) |
|
|
}).then(onChatUpdated) |
|
|
} |
|
|
|
|
|
$scope.flushHistory = function (justClear) { |
|
|
ErrorService.confirm({type: justClear ? 'HISTORY_FLUSH' : 'HISTORY_FLUSH_AND_DELETE'}).then(function () { |
|
|
AppMessagesManager.flushHistory(-$scope.chatID, justClear).then(function () { |
|
|
if (justClear) { |
|
|
$rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString}) |
|
|
} else { |
|
|
$modalInstance.close() |
|
|
$location.url('/im') |
|
|
} |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.inviteViaLink = function () { |
|
|
var scope = $rootScope.$new() |
|
|
scope.chatID = $scope.chatID |
|
|
|
|
|
$modal.open({ |
|
|
templateUrl: templateUrl('chat_invite_link_modal'), |
|
|
controller: 'ChatInviteLinkModalController', |
|
|
scope: scope, |
|
|
windowClass: 'md_simple_modal_window' |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.photo = {} |
|
|
|
|
|
$scope.$watch('photo.file', onPhotoSelected) |
|
|
|
|
|
function onPhotoSelected (photo) { |
|
|
if (!photo || !photo.type || photo.type.indexOf('image') !== 0) { |
|
|
return |
|
|
} |
|
|
$scope.photo.updating = true |
|
|
MtpApiFileManager.uploadFile(photo).then(function (inputFile) { |
|
|
return MtpApiManager.invokeApi('messages.editChatPhoto', { |
|
|
chat_id: AppChatsManager.getChatInput($scope.chatID), |
|
|
photo: { |
|
|
_: 'inputChatUploadedPhoto', |
|
|
file: inputFile |
|
|
} |
|
|
}).then(onChatUpdated) |
|
|
})['finally'](function () { |
|
|
$scope.photo.updating = false |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.deletePhoto = function () { |
|
|
$scope.photo.updating = true |
|
|
MtpApiManager.invokeApi('messages.editChatPhoto', { |
|
|
chat_id: AppChatsManager.getChatInput($scope.chatID), |
|
|
photo: {_: 'inputChatPhotoEmpty'} |
|
|
}).then(onChatUpdated)['finally'](function () { |
|
|
$scope.photo.updating = false |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.editTitle = function () { |
|
|
var scope = $rootScope.$new() |
|
|
scope.chatID = $scope.chatID |
|
|
|
|
|
$modal.open({ |
|
|
templateUrl: templateUrl('chat_edit_modal'), |
|
|
controller: 'ChatEditModalController', |
|
|
scope: scope, |
|
|
windowClass: 'md_simple_modal_window mobile_modal' |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.hasRights = function (action) { |
|
|
return AppChatsManager.hasRights($scope.chatID, action) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('ChannelModalController', function ($scope, $timeout, $rootScope, $modal, AppUsersManager, AppChatsManager, AppProfileManager, AppPhotosManager, MtpApiManager, MtpApiFileManager, NotificationsManager, AppMessagesManager, AppPeersManager, ApiUpdatesManager, ContactsSelectService, ErrorService) { |
|
|
$scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, {}) |
|
|
$scope.settings = {notifications: true} |
|
|
$scope.isMegagroup = AppChatsManager.isMegagroup($scope.chatID) |
|
|
|
|
|
AppProfileManager.getChannelFull($scope.chatID, true).then(function (chatFull) { |
|
|
$scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, chatFull) |
|
|
$scope.$broadcast('ui_height') |
|
|
|
|
|
NotificationsManager.savePeerSettings(-$scope.chatID, chatFull.notify_settings) |
|
|
|
|
|
NotificationsManager.getPeerMuted(-$scope.chatID).then(function (muted) { |
|
|
$scope.settings.notifications = !muted |
|
|
|
|
|
$scope.$watch('settings.notifications', function (newValue, oldValue) { |
|
|
if (newValue === oldValue) { |
|
|
return false |
|
|
} |
|
|
NotificationsManager.getPeerSettings(-$scope.chatID).then(function (settings) { |
|
|
if (newValue) { |
|
|
settings.mute_until = 0 |
|
|
} else { |
|
|
settings.mute_until = 2000000000 |
|
|
} |
|
|
NotificationsManager.updatePeerSettings(-$scope.chatID, settings) |
|
|
}) |
|
|
}) |
|
|
}) |
|
|
|
|
|
if ($scope.chatFull.chat && |
|
|
$scope.chatFull.chat.pFlags.creator && |
|
|
$scope.chatFull.exported_invite && |
|
|
$scope.chatFull.exported_invite._ == 'chatInviteEmpty') { |
|
|
AppProfileManager.getChatInviteLink($scope.chatID, true).then(function (link) { |
|
|
$scope.chatFull.exported_invite = {_: 'chatInviteExported', link: link} |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
function onChatUpdated (updates) { |
|
|
ApiUpdatesManager.processUpdateMessage(updates) |
|
|
$rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString}) |
|
|
} |
|
|
|
|
|
$scope.leaveChannel = function () { |
|
|
return ErrorService.confirm({type: $scope.isMegagroup ? 'MEGAGROUP_LEAVE' : 'CHANNEL_LEAVE'}).then(function () { |
|
|
MtpApiManager.invokeApi('channels.leaveChannel', { |
|
|
channel: AppChatsManager.getChannelInput($scope.chatID) |
|
|
}).then(onChatUpdated) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.deleteChannel = function () { |
|
|
return ErrorService.confirm({type: $scope.isMegagroup ? 'MEGAGROUP_DELETE' : 'CHANNEL_DELETE'}).then(function () { |
|
|
MtpApiManager.invokeApi('channels.deleteChannel', { |
|
|
channel: AppChatsManager.getChannelInput($scope.chatID) |
|
|
}).then(onChatUpdated) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.joinChannel = function () { |
|
|
MtpApiManager.invokeApi('channels.joinChannel', { |
|
|
channel: AppChatsManager.getChannelInput($scope.chatID) |
|
|
}).then(onChatUpdated) |
|
|
} |
|
|
|
|
|
$scope.inviteToChannel = function () { |
|
|
var disabled = [] |
|
|
angular.forEach(($scope.chatFull.participants || {}).participants || [], function (participant) { |
|
|
disabled.push(participant.user_id) |
|
|
}) |
|
|
|
|
|
ContactsSelectService.selectContacts({disabled: disabled}).then(function (userIDs) { |
|
|
var inputUsers = [] |
|
|
angular.forEach(userIDs, function (userID) { |
|
|
inputUsers.push(AppUsersManager.getUserInput(userID)) |
|
|
}) |
|
|
MtpApiManager.invokeApi('channels.inviteToChannel', { |
|
|
channel: AppChatsManager.getChannelInput($scope.chatID), |
|
|
users: inputUsers |
|
|
}).then(onChatUpdated) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.kickFromChannel = function (userID) { |
|
|
MtpApiManager.invokeApi('channels.kickFromChannel', { |
|
|
channel: AppChatsManager.getChannelInput($scope.chatID), |
|
|
user_id: AppUsersManager.getUserInput(userID), |
|
|
kicked: true |
|
|
}).then(onChatUpdated) |
|
|
} |
|
|
|
|
|
$scope.shareLink = function ($event) { |
|
|
var scope = $rootScope.$new() |
|
|
scope.chatID = $scope.chatID |
|
|
|
|
|
$modal.open({ |
|
|
templateUrl: templateUrl('chat_invite_link_modal'), |
|
|
controller: 'ChatInviteLinkModalController', |
|
|
scope: scope, |
|
|
windowClass: 'md_simple_modal_window' |
|
|
}) |
|
|
|
|
|
return cancelEvent($event) |
|
|
} |
|
|
|
|
|
$scope.photo = {} |
|
|
|
|
|
$scope.$watch('photo.file', onPhotoSelected) |
|
|
|
|
|
function onPhotoSelected (photo) { |
|
|
if (!photo || !photo.type || photo.type.indexOf('image') !== 0) { |
|
|
return |
|
|
} |
|
|
$scope.photo.updating = true |
|
|
MtpApiFileManager.uploadFile(photo).then(function (inputFile) { |
|
|
return MtpApiManager.invokeApi('channels.editPhoto', { |
|
|
channel: AppChatsManager.getChannelInput($scope.chatID), |
|
|
photo: { |
|
|
_: 'inputChatUploadedPhoto', |
|
|
file: inputFile |
|
|
} |
|
|
}).then(onChatUpdated) |
|
|
})['finally'](function () { |
|
|
$scope.photo.updating = false |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.deletePhoto = function () { |
|
|
$scope.photo.updating = true |
|
|
MtpApiManager.invokeApi('channels.editPhoto', { |
|
|
channel: AppChatsManager.getChannelInput($scope.chatID), |
|
|
photo: {_: 'inputChatPhotoEmpty'} |
|
|
}).then(onChatUpdated)['finally'](function () { |
|
|
$scope.photo.updating = false |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.editChannel = function () { |
|
|
var scope = $rootScope.$new() |
|
|
scope.chatID = $scope.chatID |
|
|
|
|
|
$modal.open({ |
|
|
templateUrl: templateUrl($scope.isMegagroup ? 'megagroup_edit_modal' : 'channel_edit_modal'), |
|
|
controller: 'ChannelEditModalController', |
|
|
scope: scope, |
|
|
windowClass: 'md_simple_modal_window mobile_modal' |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.goToHistory = function () { |
|
|
$rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString}) |
|
|
} |
|
|
|
|
|
$scope.hasRights = function (action) { |
|
|
return AppChatsManager.hasRights($scope.chatID, action) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('SettingsModalController', function ($rootScope, $scope, $timeout, $modal, AppUsersManager, AppChatsManager, AppPhotosManager, MtpApiManager, Storage, NotificationsManager, MtpApiFileManager, PasswordManager, ApiUpdatesManager, ChangelogNotifyService, LayoutSwitchService, WebPushApiManager, AppRuntimeManager, ErrorService, _) { |
|
|
$scope.profile = {} |
|
|
$scope.photo = {} |
|
|
$scope.version = Config.App.version |
|
|
|
|
|
MtpApiManager.getUserID().then(function (id) { |
|
|
$scope.profile = AppUsersManager.getUser(id) |
|
|
}) |
|
|
|
|
|
MtpApiManager.invokeApi('users.getFullUser', { |
|
|
id: {_: 'inputUserSelf'} |
|
|
}).then(function (userFullResult) { |
|
|
AppUsersManager.saveApiUser(userFullResult.user) |
|
|
if (userFullResult.profile_photo) { |
|
|
AppPhotosManager.savePhoto(userFullResult.profile_photo, { |
|
|
user_id: userFullResult.user.id |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.notify = {volume: 0.5} |
|
|
$scope.send = {} |
|
|
|
|
|
$scope.$watch('photo.file', onPhotoSelected) |
|
|
|
|
|
$scope.password = {_: 'account.noPassword'} |
|
|
updatePasswordState() |
|
|
var updatePasswordTimeout = false |
|
|
var stopped = false |
|
|
|
|
|
$scope.changePassword = function (options) { |
|
|
options = options || {} |
|
|
if (options.action == 'cancel_email') { |
|
|
return ErrorService.confirm({type: 'PASSWORD_ABORT_SETUP'}).then(function () { |
|
|
PasswordManager.updateSettings($scope.password, {email: ''}).then(updatePasswordState) |
|
|
}) |
|
|
} |
|
|
var scope = $rootScope.$new() |
|
|
scope.password = $scope.password |
|
|
angular.extend(scope, options) |
|
|
var modal = $modal.open({ |
|
|
scope: scope, |
|
|
templateUrl: templateUrl('password_update_modal'), |
|
|
controller: 'PasswordUpdateModalController', |
|
|
windowClass: 'md_simple_modal_window mobile_modal' |
|
|
}) |
|
|
|
|
|
modal.result['finally'](updatePasswordState) |
|
|
} |
|
|
|
|
|
$scope.showSessions = function () { |
|
|
$modal.open({ |
|
|
templateUrl: templateUrl('sessions_list_modal'), |
|
|
controller: 'SessionsListModalController', |
|
|
windowClass: 'md_simple_modal_window mobile_modal' |
|
|
}) |
|
|
} |
|
|
|
|
|
function updatePasswordState () { |
|
|
$timeout.cancel(updatePasswordTimeout) |
|
|
updatePasswordTimeout = false |
|
|
PasswordManager.getState().then(function (result) { |
|
|
$scope.password = result |
|
|
if (result._ == 'account.noPassword' && result.email_unconfirmed_pattern && !stopped) { |
|
|
updatePasswordTimeout = $timeout(updatePasswordState, 5000) |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.$on('$destroy', function () { |
|
|
$timeout.cancel(updatePasswordTimeout) |
|
|
stopped = true |
|
|
}) |
|
|
|
|
|
function onPhotoSelected (photo) { |
|
|
if (!photo || !photo.type || photo.type.indexOf('image') !== 0) { |
|
|
return |
|
|
} |
|
|
$scope.photo.updating = true |
|
|
MtpApiFileManager.uploadFile(photo).then(function (inputFile) { |
|
|
MtpApiManager.invokeApi('photos.uploadProfilePhoto', { |
|
|
file: inputFile, |
|
|
caption: '', |
|
|
geo_point: {_: 'inputGeoPointEmpty'} |
|
|
}).then(function (updateResult) { |
|
|
AppUsersManager.saveApiUsers(updateResult.users) |
|
|
MtpApiManager.getUserID().then(function (id) { |
|
|
AppPhotosManager.savePhoto(updateResult.photo, { |
|
|
user_id: id |
|
|
}) |
|
|
ApiUpdatesManager.processUpdateMessage({ |
|
|
_: 'updateShort', |
|
|
update: { |
|
|
_: 'updateUserPhoto', |
|
|
user_id: id, |
|
|
date: tsNow(true), |
|
|
photo: AppUsersManager.getUser(id).photo, |
|
|
previous: true |
|
|
} |
|
|
}) |
|
|
$scope.photo = {} |
|
|
}) |
|
|
}) |
|
|
})['finally'](function () { |
|
|
delete $scope.photo.updating |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.deletePhoto = function () { |
|
|
$scope.photo.updating = true |
|
|
MtpApiManager.invokeApi('photos.updateProfilePhoto', { |
|
|
id: {_: 'inputPhotoEmpty'} |
|
|
}).then(function (updateResult) { |
|
|
MtpApiManager.getUserID().then(function (id) { |
|
|
ApiUpdatesManager.processUpdateMessage({ |
|
|
_: 'updateShort', |
|
|
update: { |
|
|
_: 'updateUserPhoto', |
|
|
user_id: id, |
|
|
date: tsNow(true), |
|
|
photo: updateResult, |
|
|
previous: true |
|
|
} |
|
|
}) |
|
|
$scope.photo = {} |
|
|
}) |
|
|
})['finally'](function () { |
|
|
delete $scope.photo.updating |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.editProfile = function () { |
|
|
$modal.open({ |
|
|
templateUrl: templateUrl('profile_edit_modal'), |
|
|
controller: 'ProfileEditModalController', |
|
|
windowClass: 'md_simple_modal_window mobile_modal' |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.changeUsername = function () { |
|
|
$modal.open({ |
|
|
templateUrl: templateUrl('username_edit_modal'), |
|
|
controller: 'UsernameEditModalController', |
|
|
windowClass: 'md_simple_modal_window mobile_modal' |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.terminateSessions = function () { |
|
|
ErrorService.confirm({type: 'TERMINATE_SESSIONS'}).then(function () { |
|
|
MtpApiManager.invokeApi('auth.resetAuthorizations', {}) |
|
|
}) |
|
|
} |
|
|
|
|
|
Storage.get('notify_nodesktop', 'send_ctrlenter', 'notify_volume', 'notify_novibrate', 'notify_nopreview', 'notify_nopush').then(function (settings) { |
|
|
$scope.notify.desktop = !settings[0] |
|
|
$scope.send.enter = settings[1] ? '' : '1' |
|
|
|
|
|
$scope.notify.pushAvailable = WebPushApiManager.isAvailable |
|
|
$scope.notify.push = !settings[5] |
|
|
|
|
|
if (settings[2] !== false) { |
|
|
$scope.notify.volume = settings[2] > 0 && settings[2] <= 1.0 ? settings[2] : 0 |
|
|
} else { |
|
|
$scope.notify.volume = 0.5 |
|
|
} |
|
|
|
|
|
$scope.notify.canVibrate = NotificationsManager.getVibrateSupport() |
|
|
$scope.notify.vibrate = !settings[3] |
|
|
|
|
|
$scope.notify.preview = !settings[4] |
|
|
|
|
|
$scope.notify.volumeOf4 = function () { |
|
|
return 1 + Math.ceil(($scope.notify.volume - 0.1) / 0.33) |
|
|
} |
|
|
|
|
|
$scope.toggleSound = function () { |
|
|
if ($scope.notify.volume) { |
|
|
$scope.notify.volume = 0 |
|
|
} else { |
|
|
$scope.notify.volume = 0.5 |
|
|
} |
|
|
} |
|
|
|
|
|
var testSoundPromise |
|
|
$scope.$watch('notify.volume', function (newValue, oldValue) { |
|
|
if (newValue !== oldValue) { |
|
|
Storage.set({notify_volume: newValue}) |
|
|
$rootScope.$broadcast('settings_changed') |
|
|
NotificationsManager.clear() |
|
|
|
|
|
if (testSoundPromise) { |
|
|
$timeout.cancel(testSoundPromise) |
|
|
} |
|
|
testSoundPromise = $timeout(function () { |
|
|
NotificationsManager.testSound(newValue) |
|
|
}, 500) |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.toggleDesktop = function () { |
|
|
$scope.notify.desktop = !$scope.notify.desktop |
|
|
|
|
|
if ($scope.notify.desktop) { |
|
|
Storage.remove('notify_nodesktop') |
|
|
} else { |
|
|
Storage.set({notify_nodesktop: true}) |
|
|
} |
|
|
$rootScope.$broadcast('settings_changed') |
|
|
} |
|
|
|
|
|
$scope.togglePush = function () { |
|
|
$scope.notify.push = !$scope.notify.push |
|
|
|
|
|
if ($scope.notify.push) { |
|
|
Storage.remove('notify_nopush') |
|
|
} else { |
|
|
Storage.set({notify_nopush: true}) |
|
|
} |
|
|
$rootScope.$broadcast('settings_changed') |
|
|
} |
|
|
|
|
|
$scope.togglePreview = function () { |
|
|
$scope.notify.preview = !$scope.notify.preview |
|
|
|
|
|
if ($scope.notify.preview) { |
|
|
Storage.remove('notify_nopreview') |
|
|
} else { |
|
|
Storage.set({notify_nopreview: true}) |
|
|
} |
|
|
$rootScope.$broadcast('settings_changed') |
|
|
} |
|
|
|
|
|
$scope.toggleVibrate = function () { |
|
|
$scope.notify.vibrate = !$scope.notify.vibrate |
|
|
|
|
|
if ($scope.notify.vibrate) { |
|
|
Storage.remove('notify_novibrate') |
|
|
} else { |
|
|
Storage.set({notify_novibrate: true}) |
|
|
} |
|
|
$rootScope.$broadcast('settings_changed') |
|
|
} |
|
|
|
|
|
$scope.toggleCtrlEnter = function (newValue) { |
|
|
$scope.send.enter = newValue |
|
|
|
|
|
if ($scope.send.enter) { |
|
|
Storage.remove('send_ctrlenter') |
|
|
} else { |
|
|
Storage.set({send_ctrlenter: true}) |
|
|
} |
|
|
$rootScope.$broadcast('settings_changed') |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.openChangelog = function () { |
|
|
ChangelogNotifyService.showChangelog(false) |
|
|
} |
|
|
|
|
|
$scope.logOut = function () { |
|
|
ErrorService.confirm({type: 'LOGOUT'}).then(function () { |
|
|
MtpApiManager.logOut().then(function () { |
|
|
location.hash = '/login' |
|
|
AppRuntimeManager.reload() |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.switchBackToDesktop = Config.Mobile && !Config.Navigator.mobile |
|
|
$scope.switchToDesktop = function () { |
|
|
LayoutSwitchService.switchLayout(false) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('ChangelogModalController', function ($scope, $modal) { |
|
|
$scope.currentVersion = Config.App.version |
|
|
if (!$scope.lastVersion) { |
|
|
var versionParts = $scope.currentVersion.split('.') |
|
|
$scope.lastVersion = versionParts[0] + '.' + versionParts[1] + '.' + Math.max(0, versionParts[2] - 1) |
|
|
} |
|
|
|
|
|
$scope.changelogHidden = false |
|
|
$scope.changelogShown = false |
|
|
|
|
|
$scope.canShowVersion = function (curVersion) { |
|
|
if ($scope.changelogShown) { |
|
|
return true |
|
|
} |
|
|
|
|
|
var show = versionCompare(curVersion, $scope.lastVersion) >= 0 |
|
|
if (!show) { |
|
|
$scope.changelogHidden = true |
|
|
} |
|
|
|
|
|
return show |
|
|
} |
|
|
|
|
|
$scope.showAllVersions = function () { |
|
|
$scope.changelogShown = true |
|
|
$scope.changelogHidden = false |
|
|
$scope.$emit('ui_height') |
|
|
$scope.$broadcast('ui_height') |
|
|
} |
|
|
|
|
|
$scope.changeUsername = function () { |
|
|
$modal.open({ |
|
|
templateUrl: templateUrl('username_edit_modal'), |
|
|
controller: 'UsernameEditModalController', |
|
|
windowClass: 'md_simple_modal_window mobile_modal' |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('ProfileEditModalController', function ($scope, $modalInstance, AppUsersManager, MtpApiManager) { |
|
|
$scope.profile = {} |
|
|
$scope.error = {} |
|
|
|
|
|
MtpApiManager.getUserID().then(function (id) { |
|
|
var user = AppUsersManager.getUser(id) |
|
|
$scope.profile = { |
|
|
first_name: user.first_name, |
|
|
last_name: user.last_name |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.updateProfile = function () { |
|
|
$scope.profile.updating = true |
|
|
var flags = (1 << 0) | (1 << 1) |
|
|
MtpApiManager.invokeApi('account.updateProfile', { |
|
|
flags: flags, |
|
|
first_name: $scope.profile.first_name || '', |
|
|
last_name: $scope.profile.last_name || '' |
|
|
}).then(function (user) { |
|
|
$scope.error = {} |
|
|
AppUsersManager.saveApiUser(user) |
|
|
$modalInstance.close() |
|
|
}, function (error) { |
|
|
switch (error.type) { |
|
|
case 'FIRSTNAME_INVALID': |
|
|
$scope.error = {field: 'first_name'} |
|
|
error.handled = true |
|
|
break |
|
|
|
|
|
case 'LASTNAME_INVALID': |
|
|
$scope.error = {field: 'last_name'} |
|
|
error.handled = true |
|
|
break |
|
|
|
|
|
case 'NAME_NOT_MODIFIED': |
|
|
error.handled = true |
|
|
$modalInstance.close() |
|
|
break |
|
|
} |
|
|
})['finally'](function () { |
|
|
delete $scope.profile.updating |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('UsernameEditModalController', function ($scope, $modalInstance, AppUsersManager, MtpApiManager) { |
|
|
$scope.profile = {} |
|
|
$scope.error = {} |
|
|
|
|
|
MtpApiManager.getUserID().then(function (id) { |
|
|
var user = AppUsersManager.getUser(id) |
|
|
$scope.profile = { |
|
|
username: user.username |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.updateUsername = function () { |
|
|
$scope.profile.updating = true |
|
|
|
|
|
MtpApiManager.invokeApi('account.updateUsername', { |
|
|
username: $scope.profile.username || '' |
|
|
}).then(function (user) { |
|
|
$scope.checked = {} |
|
|
AppUsersManager.saveApiUser(user) |
|
|
$modalInstance.close() |
|
|
}, function (error) { |
|
|
switch (error.type) { |
|
|
case 'USERNAME_NOT_MODIFIED': |
|
|
error.handled = true |
|
|
$modalInstance.close() |
|
|
break |
|
|
} |
|
|
})['finally'](function () { |
|
|
delete $scope.profile.updating |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.$watch('profile.username', function (newVal) { |
|
|
if (!newVal || !newVal.length) { |
|
|
$scope.checked = {} |
|
|
return |
|
|
} |
|
|
MtpApiManager.invokeApi('account.checkUsername', { |
|
|
username: newVal |
|
|
}).then(function (valid) { |
|
|
if ($scope.profile.username !== newVal) { |
|
|
return |
|
|
} |
|
|
if (valid) { |
|
|
$scope.checked = {success: true} |
|
|
} else { |
|
|
$scope.checked = {error: true} |
|
|
} |
|
|
}, function (error) { |
|
|
if ($scope.profile.username !== newVal) { |
|
|
return |
|
|
} |
|
|
switch (error.type) { |
|
|
case 'USERNAME_INVALID': |
|
|
$scope.checked = {error: true} |
|
|
error.handled = true |
|
|
break |
|
|
} |
|
|
}) |
|
|
}) |
|
|
}) |
|
|
|
|
|
.controller('SessionsListModalController', function ($scope, $q, $timeout, _, MtpApiManager, ErrorService, $modalInstance) { |
|
|
$scope.slice = {limit: 20, limitDelta: 20} |
|
|
|
|
|
var updateSessionsTimeout = false |
|
|
var stopped = false |
|
|
|
|
|
function updateSessions () { |
|
|
$timeout.cancel(updateSessionsTimeout) |
|
|
MtpApiManager.invokeApi('account.getAuthorizations').then(function (result) { |
|
|
$scope.sessionsLoaded = true |
|
|
$scope.authorizations = result.authorizations |
|
|
|
|
|
var authorization |
|
|
for (var i = 0, len = $scope.authorizations.length; i < len; i++) { |
|
|
authorization = $scope.authorizations[i] |
|
|
authorization.current = (authorization.flags & 1) == 1 |
|
|
} |
|
|
$scope.authorizations.sort(function (sA, sB) { |
|
|
if (sA.current) { |
|
|
return -1 |
|
|
} |
|
|
if (sB.current) { |
|
|
return 1 |
|
|
} |
|
|
return sB.date_active - sA.date_active |
|
|
}) |
|
|
if (!stopped) { |
|
|
updateSessionsTimeout = $timeout(updateSessions, 5000) |
|
|
} |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.terminateSession = function (hash) { |
|
|
ErrorService.confirm({type: 'TERMINATE_SESSION'}).then(function () { |
|
|
MtpApiManager.invokeApi('account.resetAuthorization', {hash: hash}).then(updateSessions) |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.terminateAllSessions = function () { |
|
|
ErrorService.confirm({type: 'TERMINATE_SESSIONS'}).then(function () { |
|
|
MtpApiManager.invokeApi('auth.resetAuthorizations', {}) |
|
|
}) |
|
|
} |
|
|
|
|
|
updateSessions() |
|
|
|
|
|
$scope.$on('apiUpdate', function (e, update) { |
|
|
if (update._ == 'updateNewAuthorization') { |
|
|
updateSessions() |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.$on('$destroy', function () { |
|
|
$timeout.cancel(updateSessionsTimeout) |
|
|
stopped = true |
|
|
}) |
|
|
}) |
|
|
|
|
|
.controller('PasswordUpdateModalController', function ($scope, $q, _, PasswordManager, MtpApiManager, ErrorService, $modalInstance) { |
|
|
$scope.passwordSettings = {} |
|
|
|
|
|
$scope.updatePassword = function () { |
|
|
delete $scope.passwordSettings.error_field |
|
|
|
|
|
var confirmPromise |
|
|
if ($scope.action == 'disable') { |
|
|
confirmPromise = $q.when() |
|
|
} else { |
|
|
if (!$scope.passwordSettings.new_password) { |
|
|
$scope.passwordSettings.error_field = 'new_password' |
|
|
$scope.$broadcast('new_password_focus') |
|
|
return false |
|
|
} |
|
|
if ($scope.passwordSettings.new_password != $scope.passwordSettings.confirm_password) { |
|
|
$scope.passwordSettings.error_field = 'confirm_password' |
|
|
$scope.$broadcast('confirm_password_focus') |
|
|
return false |
|
|
} |
|
|
confirmPromise = $scope.passwordSettings.email |
|
|
? $q.when() |
|
|
: ErrorService.confirm({type: 'RECOVERY_EMAIL_EMPTY'}) |
|
|
} |
|
|
|
|
|
$scope.passwordSettings.loading = true |
|
|
|
|
|
confirmPromise.then(function () { |
|
|
PasswordManager.updateSettings($scope.password, { |
|
|
cur_password: $scope.passwordSettings.cur_password || '', |
|
|
new_password: $scope.passwordSettings.new_password, |
|
|
email: $scope.passwordSettings.email, |
|
|
hint: $scope.passwordSettings.hint |
|
|
}).then(function (result) { |
|
|
delete $scope.passwordSettings.loading |
|
|
$modalInstance.close(true) |
|
|
if ($scope.action == 'disable') { |
|
|
ErrorService.alert( |
|
|
_('error_modal_password_disabled_title_raw'), |
|
|
_('error_modal_password_disabled_descripion_raw') |
|
|
) |
|
|
} else { |
|
|
ErrorService.alert( |
|
|
_('error_modal_password_success_title_raw'), |
|
|
_('error_modal_password_success_descripion_raw') |
|
|
) |
|
|
} |
|
|
}, function (error) { |
|
|
switch (error.type) { |
|
|
case 'PASSWORD_HASH_INVALID': |
|
|
case 'NEW_PASSWORD_BAD': |
|
|
$scope.passwordSettings.error_field = 'cur_password' |
|
|
error.handled = true |
|
|
$scope.$broadcast('cur_password_focus') |
|
|
break |
|
|
case 'NEW_PASSWORD_BAD': |
|
|
$scope.passwordSettings.error_field = 'new_password' |
|
|
error.handled = true |
|
|
break |
|
|
case 'EMAIL_INVALID': |
|
|
$scope.passwordSettings.error_field = 'email' |
|
|
error.handled = true |
|
|
break |
|
|
case 'EMAIL_UNCONFIRMED': |
|
|
ErrorService.alert( |
|
|
_('error_modal_email_unconfirmed_title_raw'), |
|
|
_('error_modal_email_unconfirmed_descripion_raw') |
|
|
) |
|
|
$modalInstance.close(true) |
|
|
error.handled = true |
|
|
break |
|
|
} |
|
|
delete $scope.passwordSettings.loading |
|
|
}) |
|
|
}) |
|
|
} |
|
|
|
|
|
switch ($scope.action) { |
|
|
case 'disable': |
|
|
$scope.passwordSettings.new_password = '' |
|
|
break |
|
|
case 'create': |
|
|
onContentLoaded(function () { |
|
|
$scope.$broadcast('new_password_focus') |
|
|
}) |
|
|
break |
|
|
} |
|
|
|
|
|
$scope.$watch('passwordSettings.new_password', function (newValue) { |
|
|
var len = (newValue && newValue.length) || 0 |
|
|
if (!len) { |
|
|
$scope.passwordSettings.hint = '' |
|
|
} else if (len <= 3) { |
|
|
$scope.passwordSettings.hint = '***' |
|
|
} else { |
|
|
$scope.passwordSettings.hint = newValue.charAt(0) + (new Array(len - 1)).join('*') + newValue.charAt(len - 1) |
|
|
} |
|
|
$scope.$broadcast('value_updated') |
|
|
}) |
|
|
}) |
|
|
|
|
|
.controller('PasswordRecoveryModalController', function ($scope, $q, _, PasswordManager, MtpApiManager, ErrorService, $modalInstance) { |
|
|
$scope.checkCode = function () { |
|
|
$scope.recovery.updating = true |
|
|
|
|
|
PasswordManager.recover($scope.recovery.code, $scope.options).then(function (result) { |
|
|
ErrorService.alert( |
|
|
_('error_modal_password_disabled_title_raw'), |
|
|
_('error_modal_password_disabled_descripion_raw') |
|
|
) |
|
|
$modalInstance.close(result) |
|
|
}, function (error) { |
|
|
delete $scope.recovery.updating |
|
|
switch (error.type) { |
|
|
case 'CODE_EMPTY': |
|
|
case 'CODE_INVALID': |
|
|
$scope.recovery.error_field = 'code' |
|
|
error.handled = true |
|
|
break |
|
|
|
|
|
case 'PASSWORD_EMPTY': |
|
|
case 'PASSWORD_RECOVERY_NA': |
|
|
case 'PASSWORD_RECOVERY_EXPIRED': |
|
|
$modalInstance.dismiss() |
|
|
error.handled = true |
|
|
break |
|
|
} |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('ContactsModalController', function ($scope, $rootScope, $timeout, $modal, $modalInstance, MtpApiManager, AppUsersManager, ErrorService) { |
|
|
$scope.contacts = [] |
|
|
$scope.foundPeers = [] |
|
|
$scope.search = {} |
|
|
$scope.slice = {limit: 20, limitDelta: 20} |
|
|
|
|
|
var jump = 0 |
|
|
var i |
|
|
|
|
|
resetSelected() |
|
|
$scope.disabledContacts = {} |
|
|
|
|
|
if ($scope.disabled) { |
|
|
for (i = 0; i < $scope.disabled.length; i++) { |
|
|
$scope.disabledContacts[$scope.disabled[i]] = true |
|
|
} |
|
|
} |
|
|
|
|
|
if ($scope.selected) { |
|
|
for (i = 0; i < $scope.selected.length; i++) { |
|
|
if (!$scope.selectedContacts[$scope.selected[i]]) { |
|
|
$scope.selectedContacts[$scope.selected[i]] = true |
|
|
$scope.selectedCount++ |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
function resetSelected () { |
|
|
$scope.selectedContacts = {} |
|
|
$scope.selectedCount = 0 |
|
|
} |
|
|
|
|
|
function updateContacts (query) { |
|
|
var curJump = ++jump |
|
|
var doneIDs = [] |
|
|
AppUsersManager.getContacts(query).then(function (contactsList) { |
|
|
if (curJump != jump) return |
|
|
$scope.contacts = [] |
|
|
$scope.slice.limit = 20 |
|
|
|
|
|
angular.forEach(contactsList, function (userID) { |
|
|
var contact = { |
|
|
userID: userID, |
|
|
user: AppUsersManager.getUser(userID) |
|
|
} |
|
|
doneIDs.push(userID) |
|
|
$scope.contacts.push(contact) |
|
|
}) |
|
|
$scope.contactsEmpty = query ? false : !$scope.contacts.length |
|
|
$scope.$broadcast('contacts_change') |
|
|
}) |
|
|
|
|
|
if (query && query.length >= 5) { |
|
|
$timeout(function () { |
|
|
if (curJump != jump) return |
|
|
MtpApiManager.invokeApi('contacts.search', {q: query, limit: 10}).then(function (result) { |
|
|
AppUsersManager.saveApiUsers(result.users) |
|
|
if (curJump != jump) return |
|
|
angular.forEach(result.results, function (contactFound) { |
|
|
var userID = contactFound.user_id |
|
|
if (doneIDs.indexOf(userID) != -1) return |
|
|
$scope.contacts.push({ |
|
|
userID: userID, |
|
|
user: AppUsersManager.getUser(userID), |
|
|
peerString: AppUsersManager.getUserString(userID), |
|
|
found: true |
|
|
}) |
|
|
}) |
|
|
}, function (error) { |
|
|
if (error.code == 400) { |
|
|
error.handled = true |
|
|
} |
|
|
}) |
|
|
}, 500) |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.$watch('search.query', updateContacts) |
|
|
$scope.$on('contacts_update', function () { |
|
|
updateContacts(($scope.search && $scope.search.query) || '') |
|
|
}) |
|
|
|
|
|
$scope.toggleEdit = function (enabled) { |
|
|
$scope.action = enabled ? 'edit' : '' |
|
|
$scope.multiSelect = enabled |
|
|
resetSelected() |
|
|
} |
|
|
|
|
|
$scope.contactSelect = function (userID) { |
|
|
if ($scope.disabledContacts[userID]) { |
|
|
return false |
|
|
} |
|
|
if (!$scope.multiSelect) { |
|
|
return $modalInstance.close(userID) |
|
|
} |
|
|
if ($scope.selectedContacts[userID]) { |
|
|
delete $scope.selectedContacts[userID] |
|
|
$scope.selectedCount-- |
|
|
} else { |
|
|
$scope.selectedContacts[userID] = true |
|
|
$scope.selectedCount++ |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.submitSelected = function () { |
|
|
if ($scope.selectedCount > 0) { |
|
|
var selectedUserIDs = [] |
|
|
angular.forEach($scope.selectedContacts, function (t, userID) { |
|
|
selectedUserIDs.push(userID) |
|
|
}) |
|
|
return $modalInstance.close(selectedUserIDs) |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.deleteSelected = function () { |
|
|
if ($scope.selectedCount > 0) { |
|
|
var selectedUserIDs = [] |
|
|
angular.forEach($scope.selectedContacts, function (t, userID) { |
|
|
selectedUserIDs.push(userID) |
|
|
}) |
|
|
AppUsersManager.deleteContacts(selectedUserIDs).then(function () { |
|
|
$scope.toggleEdit(false) |
|
|
}) |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.importContact = function () { |
|
|
AppUsersManager.openImportContact().then(function (foundContact) { |
|
|
if (foundContact) { |
|
|
$rootScope.$broadcast('history_focus', { |
|
|
peerString: AppUsersManager.getUserString(foundContact) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('PeerSelectController', function ($scope, $modalInstance, $q, AppPeersManager, ErrorService) { |
|
|
$scope.selectedPeers = {} |
|
|
$scope.selectedPeerIDs = [] |
|
|
$scope.selectedCount = 0 |
|
|
|
|
|
if ($scope.shareLinkPromise) { |
|
|
$scope.shareLink = {loading: true} |
|
|
$scope.shareLinkPromise.then(function (url) { |
|
|
$scope.shareLink = {url: url} |
|
|
}, function () { |
|
|
delete $scope.shareLink |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.dialogSelect = function (peerString) { |
|
|
var peerID |
|
|
if (!$scope.multiSelect) { |
|
|
var promise |
|
|
if ($scope.confirm_type) { |
|
|
peerID = AppPeersManager.getPeerID(peerString) |
|
|
var peerData = AppPeersManager.getPeer(peerID) |
|
|
promise = ErrorService.confirm({ |
|
|
type: $scope.confirm_type, |
|
|
peer_id: peerID, |
|
|
peer_data: peerData |
|
|
}) |
|
|
} else { |
|
|
promise = $q.when() |
|
|
} |
|
|
promise.then(function () { |
|
|
$modalInstance.close(peerString) |
|
|
}) |
|
|
return |
|
|
} |
|
|
|
|
|
peerID = AppPeersManager.getPeerID(peerString) |
|
|
if ($scope.selectedPeers[peerID]) { |
|
|
delete $scope.selectedPeers[peerID] |
|
|
$scope.selectedCount-- |
|
|
var pos = $scope.selectedPeerIDs.indexOf(peerID) |
|
|
if (pos >= 0) { |
|
|
$scope.selectedPeerIDs.splice(pos, 1) |
|
|
} |
|
|
} else { |
|
|
$scope.selectedPeers[peerID] = AppPeersManager.getPeer(peerID) |
|
|
$scope.selectedCount++ |
|
|
$scope.selectedPeerIDs.unshift(peerID) |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.submitSelected = function () { |
|
|
if ($scope.selectedCount > 0) { |
|
|
var selectedPeerStrings = [] |
|
|
angular.forEach($scope.selectedPeers, function (t, peerID) { |
|
|
selectedPeerStrings.push(AppPeersManager.getPeerString(peerID)) |
|
|
}) |
|
|
return $modalInstance.close(selectedPeerStrings) |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.toggleSearch = function () { |
|
|
$scope.$broadcast('dialogs_search_toggle') |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('ChatCreateModalController', function ($scope, $modalInstance, $rootScope, MtpApiManager, AppUsersManager, AppChatsManager, ApiUpdatesManager) { |
|
|
$scope.group = {name: ''} |
|
|
|
|
|
$scope.createGroup = function () { |
|
|
if (!$scope.group.name) { |
|
|
return |
|
|
} |
|
|
$scope.group.creating = true |
|
|
var inputUsers = [] |
|
|
angular.forEach($scope.userIDs, function (userID) { |
|
|
inputUsers.push(AppUsersManager.getUserInput(userID)) |
|
|
}) |
|
|
return MtpApiManager.invokeApi('messages.createChat', { |
|
|
title: $scope.group.name, |
|
|
users: inputUsers |
|
|
}).then(function (updates) { |
|
|
ApiUpdatesManager.processUpdateMessage(updates) |
|
|
|
|
|
if (updates.updates && updates.updates.length) { |
|
|
for (var i = 0, len = updates.updates.length, update; i < len; i++) { |
|
|
update = updates.updates[i] |
|
|
if (update._ == 'updateNewMessage') { |
|
|
$rootScope.$broadcast('history_focus', {peerString: AppChatsManager.getChatString(update.message.to_id.chat_id) |
|
|
}) |
|
|
break |
|
|
} |
|
|
} |
|
|
$modalInstance.close() |
|
|
} |
|
|
})['finally'](function () { |
|
|
delete $scope.group.creating |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('ChatEditModalController', function ($scope, $modalInstance, $rootScope, MtpApiManager, AppUsersManager, AppChatsManager, ApiUpdatesManager) { |
|
|
var chat = AppChatsManager.getChat($scope.chatID) |
|
|
$scope.group = {name: chat.title} |
|
|
|
|
|
$scope.updateGroup = function () { |
|
|
if (!$scope.group.name) { |
|
|
return |
|
|
} |
|
|
if ($scope.group.name == chat.title) { |
|
|
return $modalInstance.close() |
|
|
} |
|
|
|
|
|
$scope.group.updating = true |
|
|
|
|
|
var apiPromise |
|
|
if (AppChatsManager.isChannel($scope.chatID)) { |
|
|
apiPromise = MtpApiManager.invokeApi('channels.editTitle', { |
|
|
channel: AppChatsManager.getChannelInput($scope.chatID), |
|
|
title: $scope.group.name |
|
|
}) |
|
|
} else { |
|
|
apiPromise = MtpApiManager.invokeApi('messages.editChatTitle', { |
|
|
chat_id: AppChatsManager.getChatInput($scope.chatID), |
|
|
title: $scope.group.name |
|
|
}) |
|
|
} |
|
|
|
|
|
return apiPromise.then(function (updates) { |
|
|
ApiUpdatesManager.processUpdateMessage(updates) |
|
|
var peerString = AppChatsManager.getChatString($scope.chatID) |
|
|
$rootScope.$broadcast('history_focus', {peerString: peerString}) |
|
|
})['finally'](function () { |
|
|
delete $scope.group.updating |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('ChannelEditModalController', function ($q, $scope, $modalInstance, $rootScope, MtpApiManager, AppUsersManager, AppChatsManager, AppProfileManager, ApiUpdatesManager) { |
|
|
var channel = AppChatsManager.getChat($scope.chatID) |
|
|
var initial = {title: channel.title} |
|
|
$scope.channel = {title: channel.title} |
|
|
|
|
|
AppProfileManager.getChannelFull($scope.chatID).then(function (channelFull) { |
|
|
initial.about = channelFull.about |
|
|
$scope.channel.about = channelFull.about |
|
|
}) |
|
|
|
|
|
$scope.updateChannel = function () { |
|
|
if (!$scope.channel.title.length) { |
|
|
return |
|
|
} |
|
|
var promises = [] |
|
|
if ($scope.channel.title != initial.title) { |
|
|
promises.push(editTitle()) |
|
|
} |
|
|
if ($scope.channel.about != initial.about) { |
|
|
promises.push(editAbout()) |
|
|
} |
|
|
|
|
|
$scope.channel.updating = true |
|
|
return $q.all(promises).then(function () { |
|
|
var peerString = AppChatsManager.getChatString($scope.chatID) |
|
|
$rootScope.$broadcast('history_focus', {peerString: peerString}) |
|
|
})['finally'](function () { |
|
|
delete $scope.channel.updating |
|
|
}) |
|
|
} |
|
|
|
|
|
function editTitle () { |
|
|
return MtpApiManager.invokeApi('channels.editTitle', { |
|
|
channel: AppChatsManager.getChannelInput($scope.chatID), |
|
|
title: $scope.channel.title |
|
|
}).then(function (updates) { |
|
|
ApiUpdatesManager.processUpdateMessage(updates) |
|
|
}) |
|
|
} |
|
|
|
|
|
function editAbout () { |
|
|
return MtpApiManager.invokeApi('channels.editAbout', { |
|
|
channel: AppChatsManager.getChannelInput($scope.chatID), |
|
|
about: $scope.channel.about |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('ChatInviteLinkModalController', function (_, $scope, $timeout, $modalInstance, AppChatsManager, AppProfileManager, ErrorService) { |
|
|
$scope.exportedInvite = {link: _('group_invite_link_loading_raw')} |
|
|
|
|
|
var isChannel = AppChatsManager.isChannel($scope.chatID) |
|
|
var isMegagroup = AppChatsManager.isMegagroup($scope.chatID) |
|
|
|
|
|
function selectLink () { |
|
|
$timeout(function () { |
|
|
$scope.$broadcast('ui_invite_select') |
|
|
}, 100) |
|
|
} |
|
|
|
|
|
function updateLink (force) { |
|
|
var chat = AppChatsManager.getChat($scope.chatID) |
|
|
if (chat.username) { |
|
|
$scope.exportedInvite = {link: 'https://t.me/' + chat.username, short: true} |
|
|
selectLink() |
|
|
return |
|
|
} |
|
|
if (force) { |
|
|
$scope.exportedInvite.revoking = true |
|
|
} |
|
|
AppProfileManager.getChatInviteLink($scope.chatID, force).then(function (link) { |
|
|
$scope.exportedInvite = {link: link, canRevoke: true} |
|
|
selectLink() |
|
|
})['finally'](function () { |
|
|
delete $scope.exportedInvite.revoking |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.revokeLink = function () { |
|
|
ErrorService.confirm({ |
|
|
type: isChannel && !isMegagroup ? 'REVOKE_CHANNEL_INVITE_LINK' : 'REVOKE_GROUP_INVITE_LINK' |
|
|
}).then(function () { |
|
|
updateLink(true) |
|
|
}) |
|
|
} |
|
|
|
|
|
updateLink() |
|
|
}) |
|
|
|
|
|
.controller('ImportContactModalController', function ($scope, $modalInstance, $rootScope, AppUsersManager, ErrorService, PhonebookContactsService) { |
|
|
if ($scope.importContact === undefined) { |
|
|
$scope.importContact = {} |
|
|
} |
|
|
|
|
|
$scope.phonebookAvailable = PhonebookContactsService.isAvailable() |
|
|
|
|
|
$scope.doImport = function () { |
|
|
if ($scope.importContact && $scope.importContact.phone) { |
|
|
$scope.progress = {enabled: true} |
|
|
AppUsersManager.importContact( |
|
|
$scope.importContact.phone, |
|
|
$scope.importContact.first_name || '', |
|
|
$scope.importContact.last_name || '' |
|
|
).then(function (foundUserID) { |
|
|
if (!foundUserID) { |
|
|
ErrorService.show({ |
|
|
error: {code: 404, type: 'USER_NOT_USING_TELEGRAM'} |
|
|
}) |
|
|
} |
|
|
$modalInstance.close(foundUserID) |
|
|
})['finally'](function () { |
|
|
delete $scope.progress.enabled |
|
|
}) |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.importPhonebook = function () { |
|
|
PhonebookContactsService.openPhonebookImport().result.then(function (foundContacts) { |
|
|
if (foundContacts) { |
|
|
$modalInstance.close(foundContacts[0]) |
|
|
} else { |
|
|
$modalInstance.dismiss() |
|
|
} |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('CountrySelectModalController', function ($scope, $modalInstance, $rootScope, _) { |
|
|
$scope.search = {} |
|
|
$scope.slice = {limit: 20, limitDelta: 20} |
|
|
|
|
|
var searchIndex = SearchIndexManager.createIndex() |
|
|
|
|
|
for (var i = 0; i < Config.CountryCodes.length; i++) { |
|
|
var searchString = Config.CountryCodes[i][0] |
|
|
searchString += ' ' + _(Config.CountryCodes[i][1] + '_raw') |
|
|
searchString += ' ' + Config.CountryCodes[i].slice(2).join(' ') |
|
|
SearchIndexManager.indexObject(i, searchString, searchIndex) |
|
|
} |
|
|
|
|
|
$scope.$watch('search.query', function (newValue) { |
|
|
var filtered = false |
|
|
var results = {} |
|
|
|
|
|
if (angular.isString(newValue) && newValue.length) { |
|
|
filtered = true |
|
|
results = SearchIndexManager.search(newValue, searchIndex) |
|
|
} |
|
|
|
|
|
$scope.countries = [] |
|
|
$scope.slice.limit = 20 |
|
|
|
|
|
var j |
|
|
for (var i = 0; i < Config.CountryCodes.length; i++) { |
|
|
if (!filtered || results[i]) { |
|
|
for (j = 2; j < Config.CountryCodes[i].length; j++) { |
|
|
$scope.countries.push({name: _(Config.CountryCodes[i][1] + '_raw'), code: Config.CountryCodes[i][j]}) |
|
|
} |
|
|
} |
|
|
} |
|
|
if (String.prototype.localeCompare) { |
|
|
$scope.countries.sort(function (a, b) { |
|
|
return a.name.localeCompare(b.name) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
}) |
|
|
|
|
|
.controller('PhonebookModalController', function ($scope, $modalInstance, $rootScope, AppUsersManager, PhonebookContactsService, ErrorService) { |
|
|
$scope.search = {} |
|
|
$scope.phonebook = [] |
|
|
$scope.selectedContacts = {} |
|
|
$scope.selectedCount = 0 |
|
|
$scope.slice = {limit: 20, limitDelta: 20} |
|
|
$scope.progress = {enabled: false} |
|
|
$scope.multiSelect = true |
|
|
|
|
|
var searchIndex = SearchIndexManager.createIndex() |
|
|
var phonebookReady = false |
|
|
|
|
|
PhonebookContactsService.getPhonebookContacts().then(function (phonebook) { |
|
|
for (var i = 0; i < phonebook.length; i++) { |
|
|
SearchIndexManager.indexObject(i, phonebook[i].first_name + ' ' + phonebook[i].last_name + ' ' + phonebook[i].phones.join(' '), searchIndex) |
|
|
} |
|
|
$scope.phonebook = phonebook |
|
|
$scope.toggleSelection(true) |
|
|
phonebookReady = true |
|
|
updateList() |
|
|
}, function (error) { |
|
|
ErrorService.show({ |
|
|
error: {code: 403, type: 'PHONEBOOK_GET_CONTACTS_FAILED', originalError: error} |
|
|
}) |
|
|
}) |
|
|
|
|
|
function updateList () { |
|
|
var filtered = false |
|
|
var results = {} |
|
|
|
|
|
if (angular.isString($scope.search.query) && $scope.search.query.length) { |
|
|
filtered = true |
|
|
results = SearchIndexManager.search($scope.search.query, searchIndex) |
|
|
|
|
|
$scope.contacts = [] |
|
|
delete $scope.contactsEmpty |
|
|
for (var i = 0; i < $scope.phonebook.length; i++) { |
|
|
if (!filtered || results[i]) { |
|
|
$scope.contacts.push($scope.phonebook[i]) |
|
|
} |
|
|
} |
|
|
} else { |
|
|
$scope.contacts = $scope.phonebook |
|
|
$scope.contactsEmpty = !$scope.contacts.length |
|
|
} |
|
|
|
|
|
$scope.slice.limit = 20 |
|
|
} |
|
|
|
|
|
$scope.$watch('search.query', function (newValue) { |
|
|
if (phonebookReady) { |
|
|
updateList() |
|
|
} |
|
|
}) |
|
|
|
|
|
$scope.contactSelect = function (i) { |
|
|
if (!$scope.multiSelect) { |
|
|
return $modalInstance.close($scope.phonebook[i]) |
|
|
} |
|
|
if ($scope.selectedContacts[i]) { |
|
|
delete $scope.selectedContacts[i] |
|
|
$scope.selectedCount-- |
|
|
} else { |
|
|
$scope.selectedContacts[i] = true |
|
|
$scope.selectedCount++ |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.toggleSelection = function (fill) { |
|
|
if (!$scope.selectedCount || fill) { |
|
|
$scope.selectedCount = $scope.phonebook.length |
|
|
for (var i = 0; i < $scope.phonebook.length; i++) { |
|
|
$scope.selectedContacts[i] = true |
|
|
} |
|
|
} else { |
|
|
$scope.selectedCount = 0 |
|
|
$scope.selectedContacts = {} |
|
|
} |
|
|
} |
|
|
|
|
|
$scope.submitSelected = function () { |
|
|
if ($scope.selectedCount <= 0) { |
|
|
$modalInstance.dismiss() |
|
|
} |
|
|
|
|
|
var selectedContacts = [] |
|
|
angular.forEach($scope.selectedContacts, function (t, i) { |
|
|
selectedContacts.push($scope.phonebook[i]) |
|
|
}) |
|
|
|
|
|
ErrorService.confirm({ |
|
|
type: 'CONTACTS_IMPORT_PERFORM' |
|
|
}).then(function () { |
|
|
$scope.progress.enabled = true |
|
|
AppUsersManager.importContacts(selectedContacts).then(function (foundContacts) { |
|
|
if (!foundContacts.length) { |
|
|
ErrorService.show({ |
|
|
error: {code: 404, type: 'USERS_NOT_USING_TELEGRAM'} |
|
|
}) |
|
|
} |
|
|
$modalInstance.close(foundContacts) |
|
|
})['finally'](function () { |
|
|
$scope.progress.enabled = false |
|
|
}) |
|
|
}) |
|
|
} |
|
|
}) |
|
|
|
|
|
.controller('StickersetModalController', function ($scope, $rootScope, $modalInstance, MtpApiManager, RichTextProcessor, AppStickersManager, AppDocsManager, AppMessagesManager, LocationParamsService) { |
|
|
$scope.slice = {limit: 20, limitDelta: 20} |
|
|
|
|
|
var fullSet |
|
|
|
|
|
AppStickersManager.getStickerset($scope.inputStickerset).then(function (result) { |
|
|
$scope.$broadcast('ui_height') |
|
|
$scope.stickersetLoaded = true |
|
|
fullSet = result |
|
|
$scope.stickerset = result.set |
|
|
$scope.stickersetInstalled = result.set.pFlags.installed == true |
|
|
$scope.documents = result.documents |
|
|
|
|
|
$scope.stickerEmojis = {} |
|
|
$scope.stickerDimensions = {} |
|
|
angular.forEach($scope.documents, function (doc) { |
|
|
$scope.stickerEmojis[doc.id] = RichTextProcessor.wrapRichText(doc.stickerEmojiRaw, { |
|
|
noLinks: true, |
|
|
noLinebreaks: true, |
|
|
emojiIconSize: 26 |
|
|
}) |
|
|
var dim = calcImageInBox(doc.w, doc.h, 192, 192) |
|
|
$scope.stickerDimensions[doc.id] = {width: dim.w, height: dim.h} |
|
|
}) |
|
|
}) |
|
|
|
|
|
$scope.toggleInstalled = function (installed) { |
|
|
AppStickersManager.installStickerset(fullSet, !installed).then(function () { |
|
|
$scope.stickersetInstalled = installed |
|
|
}) |
|
|
} |
|
|
|
|
|
$scope.chooseSticker = function (docID) { |
|
|
var doc = AppDocsManager.getDoc(docID) |
|
|
if (!doc.id || !doc.access_hash || !$rootScope.selectedPeerID) { |
|
|
return |
|
|
} |
|
|
var inputMedia = { |
|
|
_: 'inputMediaDocument', |
|
|
id: { |
|
|
_: 'inputDocument', |
|
|
id: doc.id, |
|
|
access_hash: doc.access_hash |
|
|
} |
|
|
} |
|
|
AppMessagesManager.sendOther($rootScope.selectedPeerID, inputMedia) |
|
|
$modalInstance.close(doc.id) |
|
|
} |
|
|
|
|
|
$scope.share = function () { |
|
|
LocationParamsService.shareUrl('https://t.me/addstickers/' + $scope.stickerset.short_name, $scope.stickerset.title) |
|
|
} |
|
|
})
|
|
|
|