Browse Source

Merge branch 'layer-18-usernames'

master
Igor Zhukov 10 years ago
parent
commit
279104f2d1
  1. 13
      app/css/app.css
  2. 10
      app/css/desktop.css
  3. 2
      app/css/mobile.css
  4. BIN
      app/img/icons/IconsetW.png
  5. BIN
      app/img/icons/IconsetW_1x.png
  6. 118
      app/js/controllers.js
  7. 4
      app/js/lib/config.js
  8. 2
      app/js/lib/mtproto.js
  9. 36
      app/js/lib/schema.tl.txt
  10. 13
      app/js/locales/en-us.json
  11. 6
      app/js/services.js
  12. 13
      app/partials/desktop/changelog_modal.html
  13. 30
      app/partials/desktop/im.html
  14. 25
      app/partials/desktop/settings_modal.html
  15. 15
      app/partials/desktop/user_modal.html
  16. 27
      app/partials/desktop/username_edit_modal.html
  17. 33
      app/partials/mobile/im.html
  18. 13
      app/partials/mobile/settings_modal.html
  19. 44
      app/partials/mobile/username_edit_modal.html
  20. 33
      app/vendor/jquery.emojiarea/jquery.emojiarea.js

13
app/css/app.css

@ -461,6 +461,12 @@ input[type="number"] {
.modal_simple_form .form-group { .modal_simple_form .form-group {
margin-bottom: 13px; margin-bottom: 13px;
} }
.modal_simple_form_description {
color: #777;
line-height: 160%;
margin: 10px 0 0;
text-align: justify;
}
.modal_section_header { .modal_section_header {
font-size: 12px; font-size: 12px;
@ -473,7 +479,8 @@ input[type="number"] {
.modal_section_body { .modal_section_body {
padding: 14px 14px; padding: 14px 14px;
} }
.modal_section_body p { .modal_section_body p,
.modal_section_body dl {
margin: 5px 0; margin: 5px 0;
} }
.modal_section:last-child .modal_section_body { .modal_section:last-child .modal_section_body {
@ -2111,6 +2118,10 @@ img.img_fullsize {
.settings_modal_wrap .im_attach_input { .settings_modal_wrap .im_attach_input {
z-index: 999; z-index: 999;
} }
.settings_modal_username_link,
.settings_modal_username_link:hover {
color: inherit;
}
.settings_external_service { .settings_external_service {
line-height: 0; line-height: 0;
display: inline-block; display: inline-block;

10
app/css/desktop.css

@ -545,7 +545,15 @@ div.im_panel_own_photo {
} }
.user_modal_status { .user_modal_status {
color: #999; color: #999;
margin-bottom: 16px; margin-bottom: 15px;
}
.modal_section_body dt {
font-weight: normal;
display: inline-block;
width: 80px;
}
.modal_section_body dd {
display: inline-block;
} }
.user_modal_main_btn { .user_modal_main_btn {

2
app/css/mobile.css

@ -181,6 +181,7 @@ html {
} }
.navbar-quick-media-back h4 { .navbar-quick-media-back h4 {
margin: 9px 0 12px 0; margin: 9px 0 12px 0;
line-height: 120%;
} }
.navbar-quick-profile-back h4, .navbar-quick-profile-back h4,
.navbar-quick-group-back h4 { .navbar-quick-group-back h4 {
@ -884,6 +885,7 @@ a.mobile_modal_action .tg_checkbox_label {
} }
.mobile_modal_section { .mobile_modal_section {
display: block;
border-bottom: 1px solid #e0e0e0; border-bottom: 1px solid #e0e0e0;
padding: 15px 0; padding: 15px 0;
} }

BIN
app/img/icons/IconsetW.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

BIN
app/img/icons/IconsetW_1x.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

118
app/js/controllers.js

@ -439,6 +439,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.dialogs = []; $scope.dialogs = [];
$scope.contacts = []; $scope.contacts = [];
$scope.foundUsers = [];
$scope.contactsLoaded = false; $scope.contactsLoaded = false;
if ($scope.search === undefined) { if ($scope.search === undefined) {
$scope.search = {}; $scope.search = {};
@ -636,6 +637,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
getDialogs(force).then(function (dialogsResult) { getDialogs(force).then(function (dialogsResult) {
$scope.dialogs = []; $scope.dialogs = [];
$scope.contacts = []; $scope.contacts = [];
$scope.foundUsers = [];
if (dialogsResult.dialogs.length) { if (dialogsResult.dialogs.length) {
offset += dialogsResult.dialogs.length; offset += dialogsResult.dialogs.length;
@ -678,7 +680,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.contacts.push({ $scope.contacts.push({
userID: userID, userID: userID,
user: AppUsersManager.getUser(userID), user: AppUsersManager.getUser(userID),
userPhoto: AppUsersManager.getUserPhoto(userID, 'User'),
peerString: AppUsersManager.getUserString(userID) peerString: AppUsersManager.getUserString(userID)
}); });
} }
@ -689,8 +690,31 @@ angular.module('myApp.controllers', ['myApp.i18n'])
} else if (!$scope.search.query) { } else if (!$scope.search.query) {
$scope.isEmpty.contacts = true; $scope.isEmpty.contacts = true;
} }
});
$scope.$broadcast('ui_dialogs_append'); $scope.$broadcast('ui_dialogs_append');
});
if ($scope.search.query && $scope.search.query.length >= 5) {
MtpApiManager.invokeApi('contacts.search', {q: $scope.search.query, limit: 10}).then(function (result) {
console.log($scope.search.query, result);
AppUsersManager.saveApiUsers(result.users);
if (curJump != jump) return;
$scope.foundUsers = [];
angular.forEach(result.results, function(contactFound) {
var userID = contactFound.user_id;
if (peersInDialogs[userID] === undefined) {
$scope.foundUsers.push({
userID: userID,
user: AppUsersManager.getUser(userID),
peerString: AppUsersManager.getUserString(userID)
});
}
});
}, function (error) {
if (error.code == 400) {
error.handled = true;
}
});
}
} }
function showMoreDialogs () { function showMoreDialogs () {
@ -2119,6 +2143,14 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}); });
}; };
$scope.changeUsername = function () {
$modal.open({
templateUrl: templateUrl('username_edit_modal'),
controller: 'UsernameEditModalController',
windowClass: 'username_edit_modal_window mobile_modal'
});
};
$scope.terminateSessions = function () { $scope.terminateSessions = function () {
ErrorService.confirm({type: 'TERMINATE_SESSIONS'}).then(function () { ErrorService.confirm({type: 'TERMINATE_SESSIONS'}).then(function () {
MtpApiManager.invokeApi('auth.resetAuthorizations', {}); MtpApiManager.invokeApi('auth.resetAuthorizations', {});
@ -2206,7 +2238,17 @@ angular.module('myApp.controllers', ['myApp.i18n'])
} }
}) })
.controller('ProfileEditModalController', function ($rootScope, $scope, $timeout, $modal, $modalInstance, AppUsersManager, AppChatsManager, MtpApiManager, Storage, NotificationsManager, MtpApiFileManager, ApiUpdatesManager) { .controller('ChangelogModalController', function ($scope, $modal) {
$scope.changeUsername = function () {
$modal.open({
templateUrl: templateUrl('username_edit_modal'),
controller: 'UsernameEditModalController',
windowClass: 'username_edit_modal_window mobile_modal'
});
};
})
.controller('ProfileEditModalController', function ($scope, $modalInstance, AppUsersManager, MtpApiManager) {
$scope.profile = {}; $scope.profile = {};
$scope.error = {}; $scope.error = {};
@ -2248,6 +2290,76 @@ angular.module('myApp.controllers', ['myApp.i18n'])
} }
}) })
.controller('UsernameEditModalController', function ($scope, $modalInstance, AppUsersManager, MtpApiManager) {
$scope.profile = {};
$scope.error = {};
MtpApiManager.getUserID().then(function (id) {
$scope.profile = angular.copy(AppUsersManager.getUser(id));
});
$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_INVALID':
$scope.checked = {error: true};
error.handled = true;
break;
case 'USERNAME_OCCUPIED':
$scope.checked = {error: true};
error.handled = true;
break;
case 'USERNAME_NOT_MODIFIED':
error.handled = true;
$modalInstance.close();
break;
}
})['finally'](function () {
delete $scope.profile.updating;
});
}
$scope.$watch('profile.username', function (newVal) {
if (!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('ContactsModalController', function ($scope, $modal, $modalInstance, AppUsersManager, ErrorService) { .controller('ContactsModalController', function ($scope, $modal, $modalInstance, AppUsersManager, ErrorService) {
$scope.contacts = []; $scope.contacts = [];

4
app/js/lib/config.js

File diff suppressed because one or more lines are too long

2
app/js/lib/mtproto.js

@ -711,7 +711,7 @@ angular.module('izhukov.mtproto', ['izhukov.utils'])
var serializer = new TLSerialization(options); var serializer = new TLSerialization(options);
if (!this.connectionInited) { if (!this.connectionInited) {
serializer.storeInt(0x50858a19, 'invokeWithLayer17'); serializer.storeInt(0x1c900537, 'invokeWithLayer18');
serializer.storeInt(0x69796de9, 'initConnection'); serializer.storeInt(0x69796de9, 'initConnection');
serializer.storeInt(Config.App.id, 'api_id'); serializer.storeInt(Config.App.id, 'api_id');
serializer.storeString(navigator.userAgent || 'Unknown UserAgent', 'device_model'); serializer.storeString(navigator.userAgent || 'Unknown UserAgent', 'device_model');

36
app/js/lib/schema.tl.txt

@ -70,11 +70,11 @@ fileLocationUnavailable#7c596b46 volume_id:long local_id:int secret:long = FileL
fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation; fileLocation#53d69076 dc_id:int volume_id:long local_id:int secret:long = FileLocation;
userEmpty#200250ba id:int = User; userEmpty#200250ba id:int = User;
userSelf#720535ec id:int first_name:string last_name:string phone:string photo:UserProfilePhoto status:UserStatus inactive:Bool = User; userSelf#7007b451 id:int first_name:string last_name:string username:string phone:string photo:UserProfilePhoto status:UserStatus inactive:Bool = User;
userContact#f2fb8319 id:int first_name:string last_name:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User; userContact#cab35e18 id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userRequest#22e8ceb0 id:int first_name:string last_name:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User; userRequest#d9ccc4ef id:int first_name:string last_name:string username:string access_hash:long phone:string photo:UserProfilePhoto status:UserStatus = User;
userForeign#5214c89d id:int first_name:string last_name:string access_hash:long photo:UserProfilePhoto status:UserStatus = User; userForeign#75cf7a8 id:int first_name:string last_name:string username:string access_hash:long photo:UserProfilePhoto status:UserStatus = User;
userDeleted#b29ad7cc id:int first_name:string last_name:string = User; userDeleted#d6016d7a id:int first_name:string last_name:string username:string = User;
userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto; userProfilePhotoEmpty#4f11bae1 = UserProfilePhoto;
userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto; userProfilePhoto#d559d8c8 photo_id:long photo_small:FileLocation photo_big:FileLocation = UserProfilePhoto;
@ -166,8 +166,6 @@ importedContact#d0028438 user_id:int client_id:long = ImportedContact;
contactBlocked#561bc879 user_id:int date:int = ContactBlocked; contactBlocked#561bc879 user_id:int date:int = ContactBlocked;
contactFound#ea879f95 user_id:int = ContactFound;
contactSuggested#3de191a1 user_id:int mutual_contacts:int = ContactSuggested; contactSuggested#3de191a1 user_id:int mutual_contacts:int = ContactSuggested;
contactStatus#aa77b873 user_id:int expires:int = ContactStatus; contactStatus#aa77b873 user_id:int expires:int = ContactStatus;
@ -192,8 +190,6 @@ contacts.importedContacts#ad524315 imported:Vector<ImportedContact> retry_contac
contacts.blocked#1c138d15 blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked; contacts.blocked#1c138d15 blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.blockedSlice#900802a1 count:int blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked; contacts.blockedSlice#900802a1 count:int blocked:Vector<ContactBlocked> users:Vector<User> = contacts.Blocked;
contacts.found#566000e results:Vector<ContactFound> users:Vector<User> = contacts.Found;
contacts.suggested#5649dcc5 results:Vector<ContactSuggested> users:Vector<User> = contacts.Suggested; contacts.suggested#5649dcc5 results:Vector<ContactSuggested> users:Vector<User> = contacts.Suggested;
messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs; messages.dialogs#15ba6c40 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Dialogs;
@ -235,7 +231,7 @@ updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update;
updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update; updateChatUserTyping#9a65ea1f chat_id:int user_id:int action:SendMessageAction = Update;
updateChatParticipants#7761198 participants:ChatParticipants = Update; updateChatParticipants#7761198 participants:ChatParticipants = Update;
updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update; updateUserStatus#1bfbd823 user_id:int status:UserStatus = Update;
updateUserName#da22d9ad user_id:int first_name:string last_name:string = Update; updateUserName#a7332b73 user_id:int first_name:string last_name:string username:string = Update;
updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update; updateUserPhoto#95313b0c user_id:int date:int photo:UserProfilePhoto previous:Bool = Update;
updateContactRegistered#2575bbb9 user_id:int date:int = Update; updateContactRegistered#2575bbb9 user_id:int date:int = Update;
updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update; updateContactLink#51a48a9a user_id:int my_link:contacts.MyLink foreign_link:contacts.ForeignLink = Update;
@ -389,11 +385,17 @@ sendMessageUploadDocumentAction#8faee98e = SendMessageAction;
sendMessageGeoLocationAction#176f8ba1 = SendMessageAction; sendMessageGeoLocationAction#176f8ba1 = SendMessageAction;
sendMessageChooseContactAction#628cbc6f = SendMessageAction; sendMessageChooseContactAction#628cbc6f = SendMessageAction;
contactFound#ea879f95 user_id:int = ContactFound;
contacts.found#566000e results:Vector<ContactFound> users:Vector<User> = contacts.Found;
updateServiceNotification#382dd3e4 type:string message:string media:MessageMedia popup:Bool = Update;
---functions--- ---functions---
invokeAfterMsg#cb9f372d msg_id:long query:!X = X; invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
invokeAfterMsgs#3dc4b4f0 msg_ids:Vector<long> query:!X = X; invokeAfterMsgs#3dc4b4f0 {X:Type} msg_ids:Vector<long> query:!X = X;
auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone; auth.checkPhone#6fe51dfb phone_number:string = auth.CheckedPhone;
auth.sendCode#768d5f4d phone_number:string sms_type:int api_id:int api_hash:string lang_code:string = auth.SentCode; auth.sendCode#768d5f4d phone_number:string sms_type:int api_id:int api_hash:string lang_code:string = auth.SentCode;
@ -422,7 +424,6 @@ users.getFullUser#ca30a5b1 id:InputUser = UserFull;
contacts.getStatuses#c4a353ee = Vector<ContactStatus>; contacts.getStatuses#c4a353ee = Vector<ContactStatus>;
contacts.getContacts#22c6aa08 hash:string = contacts.Contacts; contacts.getContacts#22c6aa08 hash:string = contacts.Contacts;
contacts.importContacts#da30b32d contacts:Vector<InputContact> replace:Bool = contacts.ImportedContacts; contacts.importContacts#da30b32d contacts:Vector<InputContact> replace:Bool = contacts.ImportedContacts;
contacts.search#11f812d8 q:string limit:int = contacts.Found;
contacts.getSuggested#cd773428 limit:int = contacts.Suggested; contacts.getSuggested#cd773428 limit:int = contacts.Suggested;
contacts.deleteContact#8e953744 id:InputUser = contacts.Link; contacts.deleteContact#8e953744 id:InputUser = contacts.Link;
contacts.deleteContacts#59ab389e id:Vector<InputUser> = Bool; contacts.deleteContacts#59ab389e id:Vector<InputUser> = Bool;
@ -499,7 +500,7 @@ messages.receivedQueue#55a5bb66 max_qts:int = Vector<long>;
upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool; upload.saveBigFilePart#de7b673d file_id:long file_part:int file_total_parts:int bytes:bytes = Bool;
initConnection#69796de9 api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X; initConnection#69796de9 {X:Type} api_id:int device_model:string system_version:string app_version:string lang_code:string query:!X = X;
help.getSupport#9cdf08cd = help.Support; help.getSupport#9cdf08cd = help.Support;
@ -507,4 +508,9 @@ auth.sendSms#da9f3e8 phone_number:string phone_code_hash:string = Bool;
messages.readMessageContents#354b5bc2 id:Vector<int> = Vector<int>; messages.readMessageContents#354b5bc2 id:Vector<int> = Vector<int>;
invokeWithLayer17#50858a19 query:!X = X; account.checkUsername#2714d86c username:string = Bool;
account.updateUsername#3e0bdd7c username:string = User;
contacts.search#11f812d8 q:string limit:int = contacts.Found;
invokeWithLayer18#1c900537 {X:Type} query:!X = X;

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

@ -30,6 +30,8 @@
"settings_modal_set_photo": "Set profile photo", "settings_modal_set_photo": "Set profile photo",
"settings_modal_photo_updating": "Updating", "settings_modal_photo_updating": "Updating",
"settings_modal_edit_profile": "Edit profile", "settings_modal_edit_profile": "Edit profile",
"settings_modal_edit_username": "Change username",
"settings_modal_empty_username_set": "Set username",
"settings_modal_terminate_sessions": "Terminate all sessions", "settings_modal_terminate_sessions": "Terminate all sessions",
"settings_modal_settings": "Settings", "settings_modal_settings": "Settings",
"settings_modal_notification_alert": "Notification alerts", "settings_modal_notification_alert": "Notification alerts",
@ -41,7 +43,6 @@
"settings_modal_enter_send_description_md": "**Enter** - send message, **Shift + Enter** - new line", "settings_modal_enter_send_description_md": "**Enter** - send message, **Shift + Enter** - new line",
"settings_modal_ctrl_enter_send_description_md": "**Ctrl + Enter** - send message, **Enter** - new line", "settings_modal_ctrl_enter_send_description_md": "**Ctrl + Enter** - send message, **Enter** - new line",
"settings_modal_send_on_enter": "Send on Enter", "settings_modal_send_on_enter": "Send on Enter",
"settings_modal_phone": "Phone",
"settings_modal_about": "About", "settings_modal_about": "About",
"settings_modal_source_code_github": "Source code on GitHub", "settings_modal_source_code_github": "Source code on GitHub",
"settings_modal_follow_us_twitter": "Follow us on Twitter!", "settings_modal_follow_us_twitter": "Follow us on Twitter!",
@ -55,6 +56,13 @@
"profile_edit_submit": "Save", "profile_edit_submit": "Save",
"profile_edit_submit_active": "Saving...", "profile_edit_submit_active": "Saving...",
"username_edit_modal_title": "Change username",
"username_edit_placeholder": "Username",
"username_edit_description_md": "Choose a username so that other people can find you on **Telegram** and message you without knowing your phone number.\n\nYou can use a-z, 0-9 and underscores.",
"username_edit_submit": "Save",
"username_edit_submit_active": "Saving...",
"user_modal_menu_more": "More", "user_modal_menu_more": "More",
"user_modal_send_message": "Send message", "user_modal_send_message": "Send message",
"user_modal_edit_contact": "Edit contact", "user_modal_edit_contact": "Edit contact",
@ -62,7 +70,9 @@
"user_modal_add_contact": "Add to contacts", "user_modal_add_contact": "Add to contacts",
"user_modal_share_contact": "Share contact", "user_modal_share_contact": "Share contact",
"user_modal_delete_chat": "Delete chat", "user_modal_delete_chat": "Delete chat",
"user_modal_info": "Info",
"user_modal_phone": "Phone", "user_modal_phone": "Phone",
"user_modal_username": "Username",
"user_modal_settings": "Settings", "user_modal_settings": "Settings",
"user_modal_notifications": "Notifications", "user_modal_notifications": "Notifications",
"user_modal_contact_info": "Contact info", "user_modal_contact_info": "Contact info",
@ -218,6 +228,7 @@
"head_new_contact": "New Contact", "head_new_contact": "New Contact",
"head_contacts": "Contacts", "head_contacts": "Contacts",
"head_contacts_title": "Contacts", "head_contacts_title": "Contacts",
"im_found_title": "Global search",
"head_settings": "Settings", "head_settings": "Settings",
"head_log_out": "Log Out", "head_log_out": "Log Out",
"head_edit_messages": "Edit messages", "head_edit_messages": "Edit messages",

6
app/js/services.js

@ -52,7 +52,7 @@ angular.module('myApp.services', ['myApp.i18n'])
return false; return false;
} }
return (user.first_name || '') + ' ' + (user.last_name || '') + ' ' + (user.phone || ''); return (user.first_name || '') + ' ' + (user.last_name || '') + ' ' + (user.phone || '') + ' ' + (user.username || '');
} }
function getContacts (query) { function getContacts (query) {
@ -1268,6 +1268,9 @@ angular.module('myApp.services', ['myApp.i18n'])
} }
function sendText(peerID, text) { function sendText(peerID, text) {
if (!angular.isString(text) || !text.length) {
return;
}
var messageID = tempID--, var messageID = tempID--,
randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)], randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)],
randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString(), randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString(),
@ -3947,6 +3950,7 @@ angular.module('myApp.services', ['myApp.i18n'])
}; };
$modal.open({ $modal.open({
controller: 'ChangelogModalController',
templateUrl: templateUrl('changelog_modal'), templateUrl: templateUrl('changelog_modal'),
scope: $scope, scope: $scope,
windowClass: 'changelog_modal_window mobile_modal' windowClass: 'changelog_modal_window mobile_modal'

13
app/partials/desktop/changelog_modal.html

@ -19,7 +19,20 @@
<div class="modal_section changelog_version_wrap"> <div class="modal_section changelog_version_wrap">
<h3 class="modal_section_header changelog_version_title"> <h3 class="modal_section_header changelog_version_title">
Version 0.3.2
<span class="pull-right" my-i18n="changelog_modal_title_current_version"></span> <span class="pull-right" my-i18n="changelog_modal_title_current_version"></span>
</h3>
<div class="modal_section_body changelog_version_changes">
<ul class="list-unstyled changelog_version_changes_list">
<li>Supported usernames. <a href="" ng-click="changeUsername">Set up right now!</a></li>
<li>Conversations search field is now searching public users by username.</li>
<li>Added default recent emoticons.</li>
</ul>
</div>
</div>
<div class="modal_section changelog_version_wrap">
<h3 class="modal_section_header changelog_version_title">
Version 0.3.1 Version 0.3.1
</h3> </h3>
<div class="modal_section_body changelog_version_changes"> <div class="modal_section_body changelog_version_changes">

30
app/partials/desktop/im.html

@ -57,16 +57,10 @@
<ul class="nav nav-pills nav-stacked"> <ul class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" ng-repeat="contact in contacts | orderBy:'user.sortName' track by contact.userID" ng-class="{active: curDialog.peerID == contact.userID}"> <li class="im_dialog_wrap" ng-repeat="contact in contacts | orderBy:'user.sortName' track by contact.userID" ng-class="{active: curDialog.peerID == contact.userID}">
<a class="im_dialog" ng-mousedown="dialogSelect(contact.peerString)"> <a class="im_dialog" ng-mousedown="dialogSelect(contact.peerString)">
<div class="im_dialog_photo pull-left"> <div class="im_dialog_photo pull-left" my-user-photolink="contact.userID" img-class="im_dialog_photo"></div>
<img
class="im_dialog_photo"
my-load-thumb
thumb="contact.userPhoto"
/>
</div>
<div class="im_dialog_message_wrap"> <div class="im_dialog_message_wrap">
<div class="im_dialog_peer"> <div class="im_dialog_peer">
<span class="im_dialog_user" ng-bind-html="contact.user.rFullName"></span> <span class="im_dialog_user" my-user-link="contact.userID"></span>
</div> </div>
<div class="im_dialog_message"> <div class="im_dialog_message">
<span class="im_dialog_message_text" my-user-status="::contact.userID"></span> <span class="im_dialog_message_text" my-user-status="::contact.userID"></span>
@ -77,6 +71,26 @@
</ul> </ul>
</div> </div>
<div class="im_dialogs_contacts_wrap" ng-show="!search.messages &amp;&amp; foundUsers.length > 0">
<h5 my-i18n="im_found_title"></h5>
<ul class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" ng-repeat="foundUser in foundUsers | orderBy:'user.sortName' track by foundUser.userID" ng-class="{active: curDialog.peerID == foundUser.userID}">
<a class="im_dialog" ng-mousedown="dialogSelect(foundUser.peerString)">
<div class="im_dialog_photo pull-left" my-user-photolink="foundUser.userID" img-class="im_dialog_photo"></div>
<div class="im_dialog_message_wrap">
<div class="im_dialog_peer">
<span class="im_dialog_user" my-user-link="foundUser.userID"></span>
</div>
<div class="im_dialog_message" ng-switch="foundUser.user.username.length > 0">
<span ng-switch-when="true" class="im_dialog_message_text" ng-bind="::'@' + foundUser.user.username"></span>
<span ng-switch-default class="im_dialog_message_text" my-user-status="::foundUser.userID"></span>
</div>
</div>
</a>
</li>
</ul>
</div>
</div> </div>
</div> </div>
</div> </div>

25
app/partials/desktop/settings_modal.html

@ -41,6 +41,9 @@
<li> <li>
<a ng-click="editProfile()" my-i18n="settings_modal_edit_profile"></a> <a ng-click="editProfile()" my-i18n="settings_modal_edit_profile"></a>
</li> </li>
<li>
<a ng-click="changeUsername()" my-i18n="settings_modal_edit_username"></a>
</li>
<li> <li>
<a ng-click="terminateSessions()" my-i18n="settings_modal_terminate_sessions"></a> <a ng-click="terminateSessions()" my-i18n="settings_modal_terminate_sessions"></a>
</li> </li>
@ -52,10 +55,22 @@
</div> </div>
<div class="modal_section" ng-if="profile.phone"> <div class="modal_section">
<h3 class="modal_section_header" my-i18n="settings_modal_phone"></h3> <h3 class="modal_section_header" my-i18n="user_modal_info"></h3>
<div class="modal_section_body"> <div class="modal_section_body">
<p><span ng-bind="profile.phone | phoneNumber"></span></p>
<dl ng-if="profile.phone">
<dt><my-i18n msgid="user_modal_phone"></my-i18n>:</dt>
<dd ng-bind="profile.phone | phoneNumber"></dd>
</dl>
<dl>
<dt><my-i18n msgid="user_modal_username"></my-i18n>:</dt>
<dd ng-switch="profile.username.length > 0">
<a class="settings_modal_username_link" ng-switch-when="true" href="" ng-click="changeUsername()" ng-bind="'@' + profile.username"></a>
<a ng-switch-default href="" ng-click="changeUsername()" my-i18n="settings_modal_empty_username_set"></a>
</dd>
</dl>
</div> </div>
</div> </div>
@ -64,10 +79,6 @@
<div class="modal_section_body"> <div class="modal_section_body">
<div class="tg_form_group"> <div class="tg_form_group">
<!--label my-i18n="settings_modal_language"></label>
<select class="tg_select" ng-model="i18n.locale">
<option value="{{lang}}" ng-selected="lang == i18n.locale" ng-repeat="(lang, name) in i18n.supported" ng-bind="name"></option>
</select-->
<a class="tg_checkbox" ng-click="toggleDesktop()" ng-class="notify.desktop ? 'tg_checkbox_on' : ''"> <a class="tg_checkbox" ng-click="toggleDesktop()" ng-class="notify.desktop ? 'tg_checkbox_on' : ''">
<span class="icon icon-checkbox-outer"><i class="icon-checkbox-inner"></i></span> <span class="icon icon-checkbox-outer"><i class="icon-checkbox-inner"></i></span>

15
app/partials/desktop/user_modal.html

@ -50,10 +50,19 @@
</div> </div>
<div class="modal_section" ng-if="user.phone"> <div class="modal_section" ng-if="user.phone || user.username">
<h3 class="modal_section_header" my-i18n="user_modal_phone"></h3> <h3 class="modal_section_header" my-i18n="user_modal_info"></h3>
<div class="modal_section_body"> <div class="modal_section_body">
<p><span ng-bind="user.phone | phoneNumber"></span></p>
<dl ng-if="user.phone">
<dt><my-i18n msgid="user_modal_phone"></my-i18n>:</dt>
<dd ng-bind="user.phone | phoneNumber"></dd>
</dl>
<dl ng-if="user.username">
<dt><my-i18n msgid="user_modal_username"></my-i18n>:</dt>
<dd ng-bind="'@' + user.username"></dd>
</dl>
</div> </div>
</div> </div>

27
app/partials/desktop/username_edit_modal.html

@ -0,0 +1,27 @@
<div class="username_edit_modal_wrap" my-modal-position>
<a class="modal-close-button" ng-click="$dismiss()"><i></i></a>
<div class="modal-body">
<form class="modal_simple_form" ng-submit="updateUsername()">
<h4 my-i18n="username_edit_modal_title"></h4>
<div class="form-group import_modal_field_wrap" ng-class="{'has-error': checked.error, 'has-feedback': checked.feedback.length > 0, 'has-success': checked.success}">
<input class="form-control input-md" my-focused type="text" placeholder="{{'username_edit_placeholder' | i18n}}" ng-model="profile.username" name="username" ng-model-options="{debounce: 600}"/>
<span ng-if="checked.error" class="glyphicon form-control-feedback" ng-class="{'glyphicon-remove': checked.error}"></span>
</div>
<div class="modal_simple_form_description" my-i18n="username_edit_description_md"></div>
</form>
</div>
<div class="modal-footer">
<a class="btn btn-link" ng-click="$dismiss()" my-i18n="modal_cancel"></a>
<button class="btn btn-primary" ng-class="{disabled: profile.updating}" ng-click="updateUsername()" ng-bind="profile.updating ? 'username_edit_submit_active' : 'username_edit_submit' | i18n" ng-disabled="profile.updating"></button>
</div>
</div>

33
app/partials/mobile/im.html

@ -41,17 +41,11 @@
<h5 my-i18n="im_contacts_title"></h5> <h5 my-i18n="im_contacts_title"></h5>
<ul class="nav nav-pills nav-stacked"> <ul class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" ng-repeat="contact in contacts | orderBy:'user.sortName' track by contact.userID" ng-class="{active: curDialog.peerID == contact.userID}"> <li class="im_dialog_wrap" ng-repeat="contact in contacts | orderBy:'user.sortName' track by contact.userID" ng-class="{active: curDialog.peerID == contact.userID}">
<a class="im_dialog" ng-click="dialogSelect(contact.peerString)"> <a class="im_dialog" ng-mousedown="dialogSelect(contact.peerString)">
<div class="im_dialog_photo pull-left"> <div class="im_dialog_photo pull-left" my-user-photolink="contact.userID" img-class="im_dialog_photo"></div>
<img
class="im_dialog_photo"
my-load-thumb
thumb="contact.userPhoto"
/>
</div>
<div class="im_dialog_message_wrap"> <div class="im_dialog_message_wrap">
<div class="im_dialog_peer"> <div class="im_dialog_peer">
<span class="im_dialog_user" ng-bind-html="contact.user.rFullName"></span> <span class="im_dialog_user" my-user-link="contact.userID"></span>
</div> </div>
<div class="im_dialog_message"> <div class="im_dialog_message">
<span class="im_dialog_message_text" my-user-status="::contact.userID"></span> <span class="im_dialog_message_text" my-user-status="::contact.userID"></span>
@ -61,6 +55,27 @@
</li> </li>
</ul> </ul>
</div> </div>
<div class="im_dialogs_contacts_wrap" ng-show="!search.messages &amp;&amp; foundUsers.length > 0">
<h5 my-i18n="im_found_title"></h5>
<ul class="nav nav-pills nav-stacked">
<li class="im_dialog_wrap" ng-repeat="foundUser in foundUsers | orderBy:'user.sortName' track by foundUser.userID" ng-class="{active: curDialog.peerID == foundUser.userID}">
<a class="im_dialog" ng-mousedown="dialogSelect(foundUser.peerString)">
<div class="im_dialog_photo pull-left" my-user-photolink="foundUser.userID" img-class="im_dialog_photo"></div>
<div class="im_dialog_message_wrap">
<div class="im_dialog_peer">
<span class="im_dialog_user" my-user-link="foundUser.userID"></span>
</div>
<div class="im_dialog_message" ng-switch="foundUser.user.username.length > 0">
<span ng-switch-when="true" class="im_dialog_message_text" ng-bind="::'@' + foundUser.user.username"></span>
<span ng-switch-default class="im_dialog_message_text" my-user-status="::foundUser.userID"></span>
</div>
</div>
</a>
</li>
</ul>
</div>
</div> </div>
</div> </div>

13
app/partials/mobile/settings_modal.html

@ -17,6 +17,9 @@
<li> <li>
<a ng-click="editProfile()" my-i18n="settings_modal_edit_profile"></a> <a ng-click="editProfile()" my-i18n="settings_modal_edit_profile"></a>
</li> </li>
<li>
<a ng-click="changeUsername()" my-i18n="settings_modal_edit_username"></a>
</li>
<li> <li>
<a ng-click="terminateSessions()" my-i18n="settings_modal_terminate_sessions"></a> <a ng-click="terminateSessions()" my-i18n="settings_modal_terminate_sessions"></a>
</li> </li>
@ -112,10 +115,18 @@
</div> </div>
<div class="mobile_modal_section" ng-if="profile.phone"> <div class="mobile_modal_section" ng-if="profile.phone">
<h4 class="mobile_modal_section_header" my-i18n="settings_modal_phone"></h4> <h4 class="mobile_modal_section_header" my-i18n="user_modal_phone"></h4>
<div class="mobile_modal_section_value" ng-bind="profile.phone | phoneNumber"></div> <div class="mobile_modal_section_value" ng-bind="profile.phone | phoneNumber"></div>
</div> </div>
<div class="mobile_modal_section">
<h4 class="mobile_modal_section_header" my-i18n="user_modal_username"></h4>
<div class="mobile_modal_section_value" ng-click="changeUsername()" ng-switch="profile.username.length > 0">
<a class="settings_modal_username_link" ng-switch-when="true" href="" ng-click="changeUsername()" ng-bind="'@' + profile.username"></a>
<a ng-switch-default href="" ng-click="changeUsername()" my-i18n="settings_modal_empty_username_set"></a>
</div>
</div>
<div class="mobile_modal_section"> <div class="mobile_modal_section">
<h4 class="mobile_modal_section_header" my-i18n="settings_modal_about"></h4> <h4 class="mobile_modal_section_header" my-i18n="settings_modal_about"></h4>
<div class="mobile_modal_section_body settings_about_section_body clearfix"> <div class="mobile_modal_section_body settings_about_section_body clearfix">

44
app/partials/mobile/username_edit_modal.html

@ -0,0 +1,44 @@
<div class="username_edit_modal_wrap">
<div class="tg_page_head tg_modal_head">
<div class="navbar navbar-static-top navbar-inverse">
<div class="container">
<div class="navbar-header">
<ul class="nav navbar-nav navbar-quick-nav">
<li class="navbar-quick-right">
<a ng-class="{disabled: profile.updating}" ng-click="updateUsername()" ng-bind="profile.updating ? 'username_edit_submit_active' : 'username_edit_submit' | i18n" ng-disabled="profile.updating"></a>
</li>
<li>
<a ng-click="$dismiss()" class="navbar-quick-media-back">
<i class="icon icon-back"></i>
<div class="navbar-quick-back-title">
<h4 my-i18n="username_edit_modal_title"></h4>
</div>
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
<div class="modal-body">
<form class="modal_simple_form" ng-submit="updateUsername()" my-vertical-position="0.3">
<div class="form-group import_modal_field_wrap" ng-class="{'has-error': checked.error, 'has-feedback': checked.feedback.length > 0, 'has-success': checked.success}">
<input class="form-control input-md" my-focused type="text" placeholder="{{'username_edit_placeholder' | i18n}}" ng-model="profile.username" name="username" ng-model-options="{debounce: 600}"/>
<span ng-if="checked.error" class="glyphicon form-control-feedback" ng-class="{'glyphicon-remove': checked.error}"></span>
</div>
<div class="modal_simple_form_description" my-i18n="username_edit_description_md"></div>
</form>
</div>
</div>

33
app/vendor/jquery.emojiarea/jquery.emojiarea.js vendored

@ -44,6 +44,7 @@
buttonPosition: 'after' buttonPosition: 'after'
} }
}; };
var defaultRecentEmojis = ':joy:,:kissing_heart:,:heart:,:heart_eyes:,:blush:,:grin:,:+1:,:relaxed:,:pensive:,:smile:,:sob:,:kiss:,:unamused:,:flushed:,:stuck_out_tongue_winking_eye:,:see_no_evil:,:wink:,:smiley:,:cry:,:stuck_out_tongue_closed_eyes:,:scream:,:rage:,:smirk:,:disappointed:,:sweat_smile:,:kissing_closed_eyes:,:speak_no_evil:,:relieved:,:grinning:,:yum:,:laughing:,:ok_hand:,:neutral_face:,:confused:'.split(',');
/*! MODIFICATION END */ /*! MODIFICATION END */
$.fn.emojiarea = function(options) { $.fn.emojiarea = function(options) {
@ -173,7 +174,7 @@
*/ */
util.emojiInserted = function (emojiKey, menu) { util.emojiInserted = function (emojiKey, menu) {
ConfigStorage.get('emojis_recent', function (curEmojis) { ConfigStorage.get('emojis_recent', function (curEmojis) {
curEmojis = curEmojis || []; curEmojis = curEmojis || defaultRecentEmojis || [];
var pos = curEmojis.indexOf(emojiKey); var pos = curEmojis.indexOf(emojiKey);
if (!pos) { if (!pos) {
@ -188,10 +189,6 @@
} }
ConfigStorage.set({emojis_recent: curEmojis}); ConfigStorage.set({emojis_recent: curEmojis});
if (menu) {
menu.updateRecentTab(curEmojis);
}
}) })
}; };
/*! MODIFICATION END */ /*! MODIFICATION END */
@ -468,8 +465,6 @@
this.$menu = $('<div>'); this.$menu = $('<div>');
this.$menu.addClass('emoji-menu'); this.$menu.addClass('emoji-menu');
this.$menu.hide(); this.$menu.hide();
/* MODIFICATION: Following line was added by Igor Zhukov, in order to store emoji tab visibility */
this.hasRecent = true;
/*! MODIFICATION START /*! MODIFICATION START
Following code was modified by Igor Zhukov, in order to add scrollbars and tail to EmojiMenu Following code was modified by Igor Zhukov, in order to add scrollbars and tail to EmojiMenu
@ -559,10 +554,6 @@
/* MODIFICATION: Following line was modified by Andre Staltz, in order to select a default category. */ /* MODIFICATION: Following line was modified by Andre Staltz, in order to select a default category. */
this.selectCategory(0); this.selectCategory(0);
/* MODIFICATION: Following 3 lines was added by Igor Zhukov, in order to update emoji tab visibility */
ConfigStorage.get('emojis_recent', function (curEmojis) {
self.updateRecentTab(curEmojis);
});
}; };
/*! MODIFICATION START /*! MODIFICATION START
@ -628,6 +619,7 @@
updateItems(); updateItems();
} else { } else {
ConfigStorage.get('emojis_recent', function (curEmojis) { ConfigStorage.get('emojis_recent', function (curEmojis) {
curEmojis = curEmojis || defaultRecentEmojis || [];
var key, i; var key, i;
for (i = 0; i < curEmojis.length; i++) { for (i = 0; i < curEmojis.length; i++) {
key = curEmojis[i] key = curEmojis[i]
@ -640,25 +632,6 @@
} }
}; };
/*! MODIFICATION START
This function was added by Igor Zhukov to update recent emojis tab state.
*/
EmojiMenu.prototype.updateRecentTab = function(curEmojis) {
if (this.hasRecent != (curEmojis.length > 1)) {
var tabEl = this.$categoryTabs.find('.emoji-menu-tab').eq(0);
if (this.hasRecent) {
tabEl.hide();
if (!this.currentCategory) {
this.selectCategory(1);
}
} else {
tabEl.show();
}
this.hasRecent = !this.hasRecent;
}
};
/*! MODIFICATION END */
EmojiMenu.prototype.reposition = function() { EmojiMenu.prototype.reposition = function() {
var $button = this.emojiarea.$button; var $button = this.emojiarea.$button;
var offset = $button.offset(); var offset = $button.offset();

Loading…
Cancel
Save