Improved login form
Added country selector Added phone number confirmation
This commit is contained in:
parent
ad05ee8987
commit
5eac2f5055
@ -449,6 +449,11 @@ input[type="number"]::-webkit-inner-spin-button {
|
||||
.modal-body {
|
||||
padding: 14px 14px;
|
||||
}
|
||||
.modal_simple_header {
|
||||
font-size: 14px;
|
||||
margin: 0 0 12px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.modal_simple_form {
|
||||
max-width: 230px;
|
||||
@ -691,6 +696,35 @@ a.tg_radio_on:hover i.icon-radio {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.login_country_selector {
|
||||
cursor: pointer;
|
||||
background: #f7f7f7;
|
||||
height: 34px;
|
||||
padding: 10px 12px 10px 13px;
|
||||
line-height: 14px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.login_country_selector .icon-caret {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.login_phone_country,
|
||||
.login_phone_number {
|
||||
float: left;
|
||||
display: inline-block;
|
||||
width: auto;
|
||||
font-size: 12px;
|
||||
}
|
||||
.login_phone_country {
|
||||
width: 53px;
|
||||
margin-right: 9px;
|
||||
padding: 6px 3px;
|
||||
text-align: center;
|
||||
}
|
||||
.login_phone_number {
|
||||
width: 198px;
|
||||
}
|
||||
|
||||
|
||||
/* IM page start */
|
||||
|
||||
@ -2306,6 +2340,12 @@ img.chat_modal_participant_photo {
|
||||
margin-top: 40px;
|
||||
}
|
||||
|
||||
.confirm_phone_number {
|
||||
font-weight: bold;
|
||||
padding: 15px 10px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.photo_modal_error {
|
||||
@ -3024,6 +3064,61 @@ ce671b orange
|
||||
}
|
||||
|
||||
|
||||
.countries_modal_window .modal-dialog {
|
||||
max-width: 392px;
|
||||
}
|
||||
|
||||
.countries_modal_search {
|
||||
padding: 0 20px 12px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.countries_modal_wrap .modal-body {
|
||||
padding: 14px 0;
|
||||
}
|
||||
|
||||
.countries_modal_col .nano > .pane {
|
||||
background : rgba(3,36,64,0.08);
|
||||
width : 3px;
|
||||
right: 6px;
|
||||
top: 0;
|
||||
-webkit-transition : .2s;
|
||||
-moz-transition : .2s;
|
||||
-o-transition : .2s;
|
||||
transition : .2s;
|
||||
-moz-border-radius : 0;
|
||||
-webkit-border-radius : 0;
|
||||
border-radius : 0;
|
||||
}
|
||||
.countries_modal_col .nano > .pane > .slider {
|
||||
background : rgba(3,46,79,0.22);
|
||||
margin: 0;
|
||||
-moz-border-radius : 0;
|
||||
-webkit-border-radius : 0;
|
||||
border-radius : 0;
|
||||
}
|
||||
|
||||
|
||||
.countries_scrollable_wrap a.countries_modal_country {
|
||||
clear: both;
|
||||
overflow: hidden;
|
||||
color: #000;
|
||||
padding: 8px 26px;
|
||||
font-size: 12px;
|
||||
border-radius: 0;
|
||||
}
|
||||
.countries_scrollable_wrap a.countries_modal_country:hover {
|
||||
border-radius: 2px;
|
||||
background: #f2f6fa;
|
||||
}
|
||||
|
||||
.countries_modal_country_code {
|
||||
color: #999;
|
||||
}
|
||||
.countries_scrollable_wrap a.countries_modal_country:hover .countries_modal_country_code {
|
||||
color: #698192;
|
||||
}
|
||||
|
||||
|
||||
/* Loading dots animation */
|
||||
.loading_dots
|
||||
|
@ -21,7 +21,7 @@ angular.module('myApp.controllers', [])
|
||||
});
|
||||
})
|
||||
|
||||
.controller('AppLoginController', function ($scope, $location, $timeout, MtpApiManager, ErrorService) {
|
||||
.controller('AppLoginController', function ($scope, $location, $timeout, $modal, MtpApiManager, ErrorService) {
|
||||
MtpApiManager.getUserID().then(function (id) {
|
||||
if (id) {
|
||||
$location.url('/im');
|
||||
@ -30,10 +30,51 @@ angular.module('myApp.controllers', [])
|
||||
});
|
||||
var options = {dcID: 1, createNetworker: true};
|
||||
|
||||
$scope.credentials = {};
|
||||
$scope.credentials = {phone_country: '+1', phone_country_name: 'USA', phone_number: '', phone_full: ''};
|
||||
$scope.progress = {};
|
||||
$scope.callPending = {};
|
||||
|
||||
$scope.selectCountry = function () {
|
||||
var modal = $modal.open({
|
||||
templateUrl: 'partials/country_select_modal.html',
|
||||
controller: 'CountrySelectModalController',
|
||||
windowClass: 'countries_modal_window'
|
||||
});
|
||||
|
||||
modal.result.then(function (code) {
|
||||
$scope.credentials.phone_country = code;
|
||||
$scope.$broadcast('country_selected');
|
||||
});
|
||||
};
|
||||
|
||||
$scope.$watch('credentials.phone_country', updateCountry);
|
||||
$scope.$watch('credentials.phone_number', updateCountry);
|
||||
|
||||
function updateCountry () {
|
||||
var phoneNumber = (
|
||||
($scope.credentials.phone_country || '') +
|
||||
($scope.credentials.phone_number || '')
|
||||
).replace(/\D+/g, ''),
|
||||
i, j, code,
|
||||
maxLength = 0,
|
||||
maxName = false;
|
||||
|
||||
if (phoneNumber.length) {
|
||||
for (i = 0; i < Config.CountryCodes.length; i++) {
|
||||
for (j = 1; 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][0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$scope.credentials.phone_full = phoneNumber;
|
||||
$scope.credentials.phone_country_name = maxName || 'Unknown';
|
||||
};
|
||||
|
||||
var callTimeout;
|
||||
|
||||
function saveAuth (result) {
|
||||
@ -51,7 +92,7 @@ angular.module('myApp.controllers', [])
|
||||
if (!(--$scope.callPending.remaining)) {
|
||||
$scope.callPending.success = false;
|
||||
MtpApiManager.invokeApi('auth.sendCall', {
|
||||
phone_number: $scope.credentials.phone_number,
|
||||
phone_number: $scope.credentials.phone_full,
|
||||
phone_code_hash: $scope.credentials.phone_code_hash
|
||||
}, options).then(function () {
|
||||
$scope.callPending.success = true;
|
||||
@ -63,38 +104,53 @@ angular.module('myApp.controllers', [])
|
||||
|
||||
$scope.sendCode = function () {
|
||||
$timeout.cancel(callTimeout);
|
||||
$scope.progress.enabled = true;
|
||||
MtpApiManager.invokeApi('auth.checkPhone', {
|
||||
|
||||
ErrorService.confirm({
|
||||
type: 'LOGIN_PHONE_CORRECT',
|
||||
country_code: $scope.credentials.phone_country,
|
||||
phone_number: $scope.credentials.phone_number
|
||||
}, options).then(function (result) {
|
||||
$scope.progress.enabled = false;
|
||||
if (!result.phone_registered) {
|
||||
ErrorService.show({
|
||||
error: {code: 400, type: 'ACCOUNT_REQUIRED'},
|
||||
phone: $scope.credentials.phone_number
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
}).then(function () {
|
||||
$scope.progress.enabled = true;
|
||||
MtpApiManager.invokeApi('auth.sendCode', {
|
||||
phone_number: $scope.credentials.phone_number,
|
||||
sms_type: 0,
|
||||
api_id: 2496,
|
||||
api_hash: '8da85b0d5bfe62527e5b244c209159c3'
|
||||
}, options).then(function (sentCode) {
|
||||
MtpApiManager.invokeApi('auth.checkPhone', {
|
||||
phone_number: $scope.credentials.phone_full
|
||||
}, options).then(function (result) {
|
||||
$scope.progress.enabled = false;
|
||||
if (!result.phone_registered) {
|
||||
ErrorService.show({
|
||||
error: {code: 400, type: 'ACCOUNT_REQUIRED'},
|
||||
phone: $scope.credentials.phone_full
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
$scope.credentials.phone_code_hash = sentCode.phone_code_hash;
|
||||
$scope.credentials.phone_occupied = sentCode.phone_registered;
|
||||
$scope.error = {};
|
||||
$scope.progress.enabled = true;
|
||||
MtpApiManager.invokeApi('auth.sendCode', {
|
||||
phone_number: $scope.credentials.phone_full,
|
||||
sms_type: 0,
|
||||
api_id: 2496,
|
||||
api_hash: '8da85b0d5bfe62527e5b244c209159c3'
|
||||
}, options).then(function (sentCode) {
|
||||
$scope.progress.enabled = false;
|
||||
|
||||
$scope.callPending.remaining = sentCode.send_call_timeout;
|
||||
callCheck();
|
||||
$scope.credentials.phone_code_hash = sentCode.phone_code_hash;
|
||||
$scope.credentials.phone_occupied = sentCode.phone_registered;
|
||||
$scope.error = {};
|
||||
|
||||
$scope.callPending.remaining = sentCode.send_call_timeout;
|
||||
callCheck();
|
||||
|
||||
}, 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;
|
||||
}
|
||||
});
|
||||
}, function (error) {
|
||||
$scope.progress.enabled = false;
|
||||
console.log('sendCode error', error);
|
||||
switch (error.type) {
|
||||
case 'PHONE_NUMBER_INVALID':
|
||||
$scope.error = {field: 'phone'};
|
||||
@ -102,20 +158,14 @@ angular.module('myApp.controllers', [])
|
||||
break;
|
||||
}
|
||||
});
|
||||
}, function (error) {
|
||||
$scope.progress.enabled = false;
|
||||
switch (error.type) {
|
||||
case 'PHONE_NUMBER_INVALID':
|
||||
$scope.error = {field: 'phone'};
|
||||
error.handled = true;
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
|
||||
$scope.logIn = function (forceSignUp) {
|
||||
var method = 'auth.signIn', params = {
|
||||
phone_number: $scope.credentials.phone_number,
|
||||
phone_number: $scope.credentials.phone_full,
|
||||
phone_code_hash: $scope.credentials.phone_code_hash,
|
||||
phone_code: $scope.credentials.phone_code
|
||||
};
|
||||
@ -1629,3 +1679,37 @@ angular.module('myApp.controllers', [])
|
||||
};
|
||||
|
||||
})
|
||||
|
||||
.controller('CountrySelectModalController', function ($scope, $modalInstance, $rootScope, SearchIndexManager) {
|
||||
|
||||
$scope.search = {};
|
||||
|
||||
var searchIndex = SearchIndexManager.createIndex();
|
||||
|
||||
for (var i = 0; i < Config.CountryCodes.length; i++) {
|
||||
SearchIndexManager.indexObject(i, Config.CountryCodes[i].join(' '), searchIndex);
|
||||
}
|
||||
|
||||
$scope.$watch('search.query', function (newValue) {
|
||||
var filtered = false,
|
||||
results = {};
|
||||
|
||||
if (angular.isString(newValue) && newValue.length) {
|
||||
filtered = true;
|
||||
results = SearchIndexManager.search(newValue, searchIndex);
|
||||
}
|
||||
|
||||
console.log(dT(), newValue, results);
|
||||
|
||||
$scope.countries = [];
|
||||
var j;
|
||||
for (var i = 0; i < Config.CountryCodes.length; i++) {
|
||||
if (!filtered || results[i]) {
|
||||
for (j = 1; j < Config.CountryCodes[i].length; j++) {
|
||||
$scope.countries.push({name: Config.CountryCodes[i][0], code: Config.CountryCodes[i][j]});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
})
|
||||
|
@ -149,6 +149,37 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
|
||||
})
|
||||
|
||||
.directive('myCountriesList', function($window, $timeout) {
|
||||
|
||||
return {
|
||||
link: link
|
||||
};
|
||||
|
||||
function link ($scope, element, attrs) {
|
||||
var searchWrap = $('.countries_modal_search')[0],
|
||||
panelWrap = $('.countries_modal_panel')[0],
|
||||
countriesWrap = $('.countries_wrap', element)[0];
|
||||
|
||||
onContentLoaded(function () {
|
||||
$(countriesWrap).nanoScroller({preventPageScrolling: true, tabIndex: -1, iOSNativeScrolling: true});
|
||||
updateSizes();
|
||||
});
|
||||
|
||||
function updateSizes () {
|
||||
$(element).css({
|
||||
height: $($window).height() - (panelWrap && panelWrap.offsetHeight || 0) - (searchWrap && searchWrap.offsetHeight || 0) - 200
|
||||
});
|
||||
$(countriesWrap).nanoScroller();
|
||||
}
|
||||
|
||||
$($window).on('resize', updateSizes);
|
||||
$scope.$on('contacts_change', function () {
|
||||
onContentLoaded(updateSizes)
|
||||
});
|
||||
};
|
||||
|
||||
})
|
||||
|
||||
.directive('myHistory', function ($window, $timeout, $transition) {
|
||||
|
||||
return {
|
||||
@ -972,6 +1003,18 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
};
|
||||
})
|
||||
|
||||
.directive('myFocusOn', function(){
|
||||
return {
|
||||
link: function($scope, element, attrs) {
|
||||
$scope.$on(attrs.myFocusOn, function () {
|
||||
onContentLoaded(function () {
|
||||
element[0].focus();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
})
|
||||
|
||||
.directive('myFileUpload', function(){
|
||||
|
||||
return {
|
||||
|
File diff suppressed because one or more lines are too long
@ -564,7 +564,7 @@ angular.module('myApp.services', [])
|
||||
var badCharsRe = /[`~!@#$%^&*()\-_=+\[\]\\|{}'";:\/?.>,<\s]+/g,
|
||||
trimRe = /^\s+|\s$/g,
|
||||
accentsReplace = {
|
||||
a: /[áâäà]/g,
|
||||
a: /[åáâäà]/g,
|
||||
e: /[éêëè]/g,
|
||||
i: /[íîïì]/g,
|
||||
o: /[óôöò]/g,
|
||||
@ -3252,7 +3252,7 @@ angular.module('myApp.services', [])
|
||||
if (typeof params === 'string') {
|
||||
params = {message: params};
|
||||
}
|
||||
confirm(params).then(function (result) {
|
||||
confirm(params.message).then(function (result) {
|
||||
callback(result || true)
|
||||
}, function () {
|
||||
callback(false)
|
||||
|
@ -16,6 +16,10 @@
|
||||
</span>
|
||||
<span ng-switch-when="FILE_CLIPBOARD_PASTE">Are you sure to send file(s) from clipboard?</span>
|
||||
<span ng-switch-when="MESSAGE_DELETE">Are you sure to delete the message?</span>
|
||||
<div ng-switch-when="LOGIN_PHONE_CORRECT">
|
||||
Is this phone number correct?
|
||||
<div class="confirm_phone_number"> <span ng-bind="country_code"></span> <span ng-bind="phone_number"></span> </div>
|
||||
</div>
|
||||
<span ng-switch-default ng-bind="message || 'Are you sure?'"></span>
|
||||
</div>
|
||||
|
||||
@ -31,6 +35,7 @@
|
||||
<span ng-switch-when="FILES_CLIPBOARD_PASTE">Send</span>
|
||||
<span ng-switch-when="FILE_CLIPBOARD_PASTE">Send</span>
|
||||
<span ng-switch-when="MESSAGE_DELETE">Delete</span>
|
||||
<span ng-switch-when="LOGIN_PHONE_CORRECT">Yes</span>
|
||||
<span ng-switch-default>OK</span>
|
||||
</button>
|
||||
</div>
|
||||
|
40
app/partials/country_select_modal.html
Normal file
40
app/partials/country_select_modal.html
Normal file
@ -0,0 +1,40 @@
|
||||
<div class="countries_modal_wrap" my-modal-position>
|
||||
|
||||
<div class="modal-body">
|
||||
|
||||
<h4 class="modal_simple_header">Country</h4>
|
||||
|
||||
<div class="countries_modal_search">
|
||||
<input class="form-control countries_modal_search_field" my-focused type="search" placeholder="Search" ng-model="search.query"/>
|
||||
<a class="countries_modal_search_clear" ng-click="search.query = ''" ng-show="search.query.length"></a>
|
||||
</div>
|
||||
|
||||
<div class="countries_modal_col" my-countries-list>
|
||||
|
||||
<div class="countries_wrap nano">
|
||||
<div class="countries_scrollable_wrap content">
|
||||
|
||||
<ul class="countries_modal_members_list nav nav-pills nav-stacked">
|
||||
|
||||
<li class="countries_modal_country_wrap clearfix" ng-repeat="country in countries track by $index">
|
||||
<a class="countries_modal_country" ng-click="$close(country.code)">
|
||||
<span class="countries_modal_country_code pull-right" ng-bind="country.code"></span>
|
||||
<span class="countries_modal_country_name" ng-bind="country.name"></span>
|
||||
</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="modal-footer">
|
||||
<a class="btn btn-link" ng-click="$dismiss()">Cancel</a>
|
||||
<button type="button" class="btn btn-primary" ng-click="$dismiss()">Done</button>
|
||||
</div>
|
||||
|
||||
</div>
|
@ -5,14 +5,21 @@
|
||||
<div class="error" ng-if="error.message">{{ error.message }}</div>
|
||||
<form name="mySendCodeForm" ng-if="!credentials.phone_code_hash" ng-submit="sendCode()">
|
||||
<h3 class="login_form_head">Sign in</h3>
|
||||
<p class="login_form_lead">Please enter your full phone number with country code.</p>
|
||||
<p class="login_form_lead">Please choose your country and enter your full phone number.</p>
|
||||
|
||||
<div class="form-group" ng-class="{'has-error': error.field == 'phone'}">
|
||||
<label class="control-label" for="phone_number" ng-if="error.field == 'phone'">Incorrect phone number</label>
|
||||
<input type="tel" class="form-control" my-focused name="phone_number" ng-model="credentials.phone_number" placeholder="Enter your phone" required>
|
||||
<div class="login_country_selector" ng-click="selectCountry()">
|
||||
<span ng-bind="credentials.phone_country_name"></span>
|
||||
<i class="icon icon-caret pull-right"></i>
|
||||
</div>
|
||||
<button class="btn btn-success btn-block" ng-class="{disabled: progress.enabled}" ng-disabled="progress.enabled" type="submit">
|
||||
{{progress.enabled ? 'Generating keys...' : 'Next'}}
|
||||
|
||||
<div class="form-group clearfix" ng-class="{'has-error': error.field == 'phone'}">
|
||||
<label class="control-label" for="phone_number" ng-if="error.field == 'phone'">Incorrect phone number</label>
|
||||
<input type="tel" class="form-control pull-left login_phone_country" my-focused name="phone_country" ng-model="credentials.phone_country">
|
||||
<input type="tel" class="form-control pull-left login_phone_number" my-focus-on="country_selected" name="phone_number" ng-model="credentials.phone_number" placeholder="Enter your phone" required>
|
||||
</div>
|
||||
<button class="btn btn-primary btn-block" ng-class="{disabled: progress.enabled}" ng-disabled="progress.enabled" type="submit" ng-switch="progress.enabled">
|
||||
<span ng-switch-when="true">Generating keys<span my-loading-dots></span></span>
|
||||
<span ng-switch-default>Next</span>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@ -31,8 +38,9 @@
|
||||
<input type="number" my-focused maxlength="5" class="form-control" name="phone_code" ng-model="credentials.phone_code" placeholder="Enter your code" required>
|
||||
</div>
|
||||
|
||||
<button class="btn btn-success btn-block" type="submit" ng-class="{disabled: progress.enabled}" ng-disabled="progress.enabled">
|
||||
{{progress.enabled ? 'Checking code...' : 'Sign in'}}
|
||||
<button class="btn btn-primary btn-block" type="submit" ng-class="{disabled: progress.enabled}" ng-disabled="progress.enabled" ng-switch="progress.enabled">
|
||||
<span ng-switch-when="true">Checking code<span my-loading-dots></span></span>
|
||||
<span ng-switch-default>Next</span>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user