Browse Source

Improved mobile layout

Some modifications from #35
master
Igor Zhukov 11 years ago
parent
commit
8cf5fca521
  1. 300
      app/css/app.css
  2. 326
      app/css/app_mobile.css
  3. 3
      app/index.html
  4. 103
      app/js/controllers.js
  5. 54
      app/js/directives.js
  6. 3
      app/js/lib/config.js
  7. 22
      app/js/services.js
  8. 3
      app/partials/chat_modal.html
  9. 6
      app/partials/contacts_modal.html
  10. 72
      app/partials/head.html
  11. 22
      app/partials/im.html
  12. 2
      app/partials/login.html
  13. 7
      app/partials/message.html
  14. 4
      app/partials/peer_select.html
  15. 3
      app/partials/photo_modal.html
  16. 2
      app/partials/video_modal.html
  17. 3
      app/partials/welcome.html
  18. 2
      app/webogram.appcache

300
app/css/app.css

@ -176,16 +176,15 @@ input[type="number"] {
.tg_page_head .navbar { .tg_page_head .navbar {
min-height: 44px; min-height: 44px;
} }
.tg_page_head .navbar-quick-nav,
.tg_page_head .navbar-toggle { .tg_page_head .navbar-toggle {
margin-top: 5px; display: none;
margin-bottom: 5px;
} }
.tg_page_head .container { .tg_page_head .container {
display: block; display: block;
width: auto; width: auto;
} }
.tg_page_head .navbar-inverse { .tg_page_head .navbar-inverse {
/*-webkit-app-region: drag;*/
background: #497495; background: #497495;
border: 0; border: 0;
@ -205,6 +204,10 @@ input[type="number"] {
line-height: 0; line-height: 0;
height: auto; height: auto;
} }
.navbar_offline .navbar-header,
.navbar_offline .navbar-offline > li {
float: left;
}
.navbar-offline { .navbar-offline {
max-width: 250px; max-width: 250px;
margin: 0 auto; margin: 0 auto;
@ -274,33 +277,6 @@ input[type="number"] {
background-color: rgba(255,255,255,0.1); background-color: rgba(255,255,255,0.1);
} }
.tg_page_head .navbar-quick-nav {
margin: 0;
}
.tg_page_head .navbar-quick-nav li {
float: left;
}
.tg_page_head .navbar-quick-nav a {
padding-top: 15px;
padding-bottom: 15px;
}
.icon-back {
display: inline-block;
width: 10px;
height: 18px;
vertical-align: text-top;
background: url(../img/icons/IconsetW.png) -15px -419px no-repeat;
background-size: 42px 710px;
opacity: 0.6;
}
.is_1x .icon-back {
background-image: url(../img/icons/IconsetW_1x.png);
}
.tg_page_head .navbar-quick-nav a:hover .icon-back {
opacity: 1;
}
.tg_progress { .tg_progress {
height: 12px; height: 12px;
@ -328,6 +304,9 @@ input[type="number"] {
padding: 5px 14px; padding: 5px 14px;
font-size: 13px; font-size: 13px;
} }
.dropdown-header {
padding: 3px 14px;
}
.modal-backdrop { .modal-backdrop {
background: #111111; background: #111111;
@ -418,6 +397,13 @@ input[type="number"] {
background-image: url(../img/icons/PhotoControls_1x.png); background-image: url(../img/icons/PhotoControls_1x.png);
} }
.modal {
padding: 10px;
}
.modal-dialog {
margin: 0 auto;
}
.text-invisible { .text-invisible {
visibility: hidden; visibility: hidden;
} }
@ -467,7 +453,7 @@ input[type="number"] {
margin: 17px; margin: 17px;
opacity: 0.8; opacity: 0.8;
} }
.is_1x .icon-back { .is_1x .modal-close-button i {
background-image: url(../img/icons/IconsetW_1x.png); background-image: url(../img/icons/IconsetW_1x.png);
} }
.modal-close-button:hover i { .modal-close-button:hover i {
@ -1296,11 +1282,11 @@ a.im_dialog_selected .im_dialog_date {
} }
.im_history_appending { .im_history_appending {
-webkit-transition: all 0.2s; -webkit-transition: all ease-in-out 0.2s;
-moz-transition: all 0.2s; -moz-transition: all ease-in-out 0.2s;
-ms-transition: all 0.2s; -ms-transition: all ease-in-out 0.2s;
-o-transition: all 0.2s; -o-transition: all ease-in-out 0.2s;
transition: all 0.2s; transition: all ease-in-out 0.2s;
} }
@ -1791,45 +1777,74 @@ img.im_message_document_thumb {
width: 10px; width: 10px;
height: 10px; height: 10px;
border-radius: 7px; border-radius: 7px;
overflow: hidden;
position: absolute; position: absolute;
margin-left: -26px; margin-left: -26px;
margin-top: 13px; margin-top: 13px;
opacity: 0; opacity: 0;
} }
.icon-message-status-unread { .im_message_unread .icon-message-status {
opacity: 1.0; opacity: 1.0;
} }
.icon-message-status-pending { .im_message_pending .icon-message-status {
opacity: 0.5; opacity: 0.5;
} }
.icon-message-status-error {
.im_message_error_btn {
display: none;
}
.im_message_error .im_message_error_btn {
display: inline;
}
.im_message_error_btn .icon-message-status {
background: #da564d; background: #da564d;
opacity: 0.85; opacity: 0.85;
} }
.icon-message-status-error:hover { .im_message_error_btn .icon-message-status:hover {
opacity: 1; opacity: 1;
} }
.icon-message-status-tick { .im_message_date {
color: #adadad;
font-size: 0.85em;
padding: 0 0 20px 10px;
}
@media (max-width: 900px) {
/* Status ticks */
.icon-message-status,
.im_message_error_btn,
.icon-message-status-tick {
display: none; display: none;
}
.im_message_out .icon-message-status-tick {
display: inline-block;
width: 16px; width: 16px;
height: 10px; height: 10px;
background: url(../img/icons/Checks2_2x.png) 0 0 no-repeat; background: url(../img/icons/Checks2_2x.png);
background-size: 16px 10px; background-size: 16px 10px;
top: 2px; top: 2px;
position: relative; position: relative;
} }
.icon-message-status-tick.message-status-unread-tick { .is_1x .im_message_out .icon-message-status-tick {
/*width: 13px;*/ background-image: url(../img/icons/Checks2_1x.png);
background: url(../img/icons/Checks1_2x.png) 0 0 no-repeat; }
.im_message_pending .icon-message-status-tick {
display: none;
}
.im_message_unread .icon-message-status-tick {
background: url(../img/icons/Checks1_2x.png);
background-size: 16px 10px; background-size: 16px 10px;
}
.is_1x .im_message_unread .icon-message-status-tick {
background-image: url(../img/icons/Checks1_1x.png);
}
.im_message_date {
padding: 0;
}
} }
.im_message_date {
color: #adadad;
font-size: 0.85em;
padding: 0 0 20px 10px;
}
div.im_message_author, div.im_message_author,
div.im_message_body { div.im_message_body {
display: block; display: block;
@ -1882,11 +1897,17 @@ span.emoji {
.im_history_not_selected, .im_history_not_selected,
.im_history_empty { .im_history_empty {
visibility: hidden;
text-align: center; text-align: center;
color: #999; color: #999;
font-size: 16px; font-size: 16px;
line-height: 18px; line-height: 18px;
padding: 1px 50px; padding: 1px 50px;
margin: 0;
}
.im_history_not_selected.vertical-aligned,
.im_history_empty.vertical-aligned {
visibility: visible;
} }
.im_history_to_bottom .im_history_not_selected, .im_history_to_bottom .im_history_not_selected,
.im_history_to_bottom .im_history_empty { .im_history_to_bottom .im_history_empty {
@ -2143,21 +2164,19 @@ img.img_fullsize {
} }
.user_modal_status { .user_modal_status {
color: #999; color: #999;
margin-bottom: 24px; margin-bottom: 16px;
} }
.user_modal_actions_wrap {
margin-top: 8px;
}
.user_modal_main_btn { .user_modal_main_btn {
border: 0; border: 0;
font-size: 12px; font-size: 12px;
padding-left: 16px; padding-left: 16px;
padding-right: 16px; padding-right: 16px;
margin: 8px 10px 0 0;
float: left; float: left;
} }
.user_modal_other_btn { .user_modal_other_btn {
margin-left: 10px; margin: 8px 0 0 0;
float: left; float: left;
} }
.user_modal_other_btn .dropdown-toggle { .user_modal_other_btn .dropdown-toggle {
@ -2189,12 +2208,13 @@ img.img_fullsize {
} }
.chat_modal_members_count { .chat_modal_members_count {
color: #999; color: #999;
margin-bottom: 24px; margin-bottom: 16px;
} }
.chat_modal_actions_wrap { .chat_modal_actions_wrap {
margin-top: 8px; position: relative;
} }
.chat_modal_main_btn { .chat_modal_main_btn {
border: 0; border: 0;
font-size: 12px; font-size: 12px;
@ -2203,6 +2223,8 @@ img.img_fullsize {
float: left; float: left;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
margin-right: 10px;
margin-top: 8px;
} }
.chat_modal_invite_btn { .chat_modal_invite_btn {
border: 0; border: 0;
@ -2212,6 +2234,7 @@ img.img_fullsize {
float: left; float: left;
position: relative; position: relative;
margin-right: 10px; margin-right: 10px;
margin-top: 8px;
} }
.chat_modal_delete_btn { .chat_modal_delete_btn {
border: 0; border: 0;
@ -2219,9 +2242,11 @@ img.img_fullsize {
padding-left: 16px; padding-left: 16px;
padding-right: 16px; padding-right: 16px;
float: left; float: left;
margin-right: 10px;
margin-top: 8px;
} }
.chat_modal_other_btn { .chat_modal_other_btn {
margin-left: 10px; margin-top: 8px;
float: left; float: left;
} }
.chat_modal_other_btn .dropdown-toggle { .chat_modal_other_btn .dropdown-toggle {
@ -3039,160 +3064,6 @@ a.contacts_modal_contact:hover .contacts_modal_contact_status {
} }
@media (min-width: 480px) {
.tg_page_head .navbar-quick-nav {
display: none;
}
}
@media (max-width: 480px) {
.tg_page_head .navbar > .container .navbar-brand {
padding-left: 9px;
}
.im_history_panel_edit_link {
margin-right: 0;
}
.im_dialogs_panel_dropdown .dropdown-menu {
right: 0;
left: auto;
}
}
@media (max-width: 480px) {
.login_form_wrap {
border-radius: 0;
max-width: auto;
box-shadow: none;
-webkit-box-shadow: none;
margin: 30px auto 20px;
}
}
@media (max-width: 640px) {
.im_page_footer {
display: none;
}
.im_panel_own_photo,
.im_panel_peer_photo {
display: none;
}
.im_history_panel_wrap {
margin: 0 15px;
}
.im_send_panel_wrap {
padding: 10px 15px;
}
.icon-select-tick {
margin: 10px 0 0 -24px
}
.im_content_message_wrap {
margin-left: 0;
}
.im_history_typing {
padding: 0 15px 0 60px;
}
.im_history_panel_info_link {
display: none;
}
.im_send_form {
left: 0;
right: 0;
max-width: none;
}
.im_edit_flush_link,
.im_edit_cancel_link,
.im_edit_delete_btn,
.im_edit_forward_btn {
padding-left: 5px;
padding-right: 5px;
margin: 6px 4px;
}
.im_edit_panel_border {
margin: 0 18px 22px 3px;
}
.im_edit_panel_wrap {
margin: 0 5px;
padding-bottom: 18px;
}
.emoji-wysiwyg-editor {
min-height: 34px;
max-height: 150px;
}
.im_dialog_peer {
white-space: normal;
height: 2.84em;
}
.im_dialog_message {
display: none;
}
}
@media (max-width: 900px) {
.icon-message-status {
z-index: 10;
margin-left: -5px;
border-radius: 0;
height: 34px;
border: 0;
width: 2px;
margin-top: 1px;
border: 0;
}
.im_message_grouped1 .icon-message-status,
.im_message_grouped2 .icon-message-status {
margin-top: -8px;
}
}
@media (max-width: 480px) {
.im_dialogs_col_wrap,
.im_page_peer_not_selected .im_history_col_wrap {
display: none;
}
.im_page_peer_not_selected .im_dialogs_col_wrap {
display: block;
border-right: 0;
}
.im_page_peer_not_selected .im_dialogs_col {
margin-right: 0;
}
.im_page_peer_not_selected .im_dialogs_col_wrap .pane {
width: 12px;
right: 0px;
}
.im_page_peer_not_selected .im_dialogs_col_wrap .pane > .slider {
border-radius: 3px;
margin: 0 3px;
}
.im_dialogs_scrollable_wrap {
padding: 0 12px 0 12px;
}
.im_dialogs_col_wrap,
.im_history_col_wrap {
float: none;
width: auto;
max-width: auto;
min-width: auto;
}
.im_page_peer_not_selected .im_dialog_peer {
white-space: nowrap;
height: auto;
}
.im_page_peer_not_selected .im_dialog_message {
display: block;
}
}
/* Dialogs modal */ /* Dialogs modal */
.peer_select_window .modal-dialog { .peer_select_window .modal-dialog {
max-width: 506px; max-width: 506px;
@ -3579,4 +3450,3 @@ ce671b orange
.changelog_version_changes_list li { .changelog_version_changes_list li {
line-height: 20px; line-height: 20px;
} }

326
app/css/app_mobile.css

@ -0,0 +1,326 @@
@media (max-width: 479px) {
html {
background: #FFF;
}
.tg_page_head .navbar > .container .navbar-brand {
padding-left: 9px;
}
.im_history_panel_edit_link {
margin-right: 0;
}
.navbar-header {
float: none;
}
.navbar-toggle-wrap {
float: right;
display: block;
margin: 5px;
}
.navbar-toggle-wrap .navbar-toggle {
float: none;
display: block;
margin: 0;
}
.navbar-toggle .dropdown-toggle {
display: block;
}
.navbar-toggle-wrap .dropdown-menu {
margin-top: 4px;
right: 0;
left: auto;
}
.tg_page_head .navbar-quick-nav {
display: block;
margin: 0;
}
.tg_page_head .navbar-quick-nav li {
float: left;
}
.tg_page_head .navbar-quick-nav a {
padding-top: 15px;
padding-bottom: 15px;
}
.icon-back {
display: inline-block;
width: 10px;
height: 18px;
vertical-align: text-top;
background: url(../img/icons/IconsetW.png) -15px -419px no-repeat;
background-size: 42px 710px;
opacity: 0.8;
}
.is_1x .icon-back {
background-image: url(../img/icons/IconsetW_1x.png);
}
.tg_page_head .navbar-quick-nav a:hover .icon-back {
opacity: 1;
}
.tg_page_head .navbar > .container .navbar-brand {
display: none;
}
.tg_page_head .navbar_peer_not_selected > .container .navbar-brand {
display: block;
}
.tg_page_head .navbar-inverse .navbar-quick-nav > li > a {
padding-left: 15px;
padding: 6px 10px 2px 25px;
color: #b9cfe3;
font-size: 13px;
height: 44px;
}
.tg_page_head .navbar-inverse .navbar-quick-nav > li > a:hover {
color: #b9cfe3;
background-color: rgba(255,255,255,0.1);
}
.navbar-quick-nav .icon-back {
position: absolute;
margin-left: -15px;
margin-top: 9px;
}
.navbar-quick-nav h4 {
font-size: 14px;
color: #FFF;
white-space: nowrap;
overflow: hidden;
margin: 0;
}
.navbar-quick-media-back h4 {
margin: 9px 0 12px 0;
}
.navbar-quick-profile-back small,
.navbar-quick-group-back small {
white-space: nowrap;
overflow: hidden;
margin-left: 0;
}
.navbar-menu {
display: none;
}
.navbar_offline .navbar-menu {
display: block;
}
.navbar_offline .navbar-offline {
float: left;
margin: 0;
}
.navbar_offline .tg_head_logo_text {
display: none;
}
.tg_page_head .navbar_offline > .container .navbar-brand {
margin-right: 0;
}
.navbar_offline .navbar-quick-nav li > a > h4,
.navbar_offline .navbar-quick-nav li > a > small {
display: none;
}
.login_form_wrap {
border-radius: 0;
max-width: auto;
box-shadow: none;
-webkit-box-shadow: none;
margin: 30px auto 20px;
}
.im_page_wrap {
background: none;
box-shadow: none;
border: 0;
overflow: hidden;
}
.im_page_footer {
display: none;
}
.im_panel_own_photo,
.im_panel_peer_photo {
display: none;
}
.im_history_panel_wrap {
margin: 0 15px;
}
.im_send_panel_wrap {
padding: 10px 10px;
}
.icon-select-tick {
margin: 10px 0 0 -24px
}
.im_message_wrap {
padding: 0 10px;
}
.im_content_message_wrap {
margin-left: 0;
}
.im_history_typing {
padding: 0 15px 0 56px;
}
.im_history_panel_info_link {
display: none;
}
.im_send_form {
left: 0;
right: 0;
max-width: none;
}
.im_edit_flush_link,
.im_edit_cancel_link,
.im_edit_delete_btn,
.im_edit_forward_btn {
padding-left: 5px;
padding-right: 5px;
margin: 6px 4px;
}
.im_edit_panel_border {
margin: 0 18px 22px 3px;
}
.im_edit_panel_wrap {
margin: 0 5px;
padding-bottom: 18px;
}
.emoji-wysiwyg-editor {
min-height: 34px;
max-height: 150px;
}
.im_dialog_peer {
white-space: normal;
height: 2.84em;
}
.im_dialog_message {
display: none;
}
.im_history_col .nano > .pane {
top: 3px;
right: 3px;
width: 6px;
}
.im_history_col .nano > .pane > .slider,
.contacts_modal_col .nano > .pane > .slider,
.im_dialogs_modal_col .nano > .pane > .slider {
background : rgba(3,46,79,0.22);
border-radius: 3px;
margin: 0;
}
.im_dialogs_col_wrap,
.im_page_peer_not_selected .im_history_col_wrap {
display: none;
}
.im_page_peer_not_selected .im_dialogs_col_wrap {
display: block;
border-right: 0;
}
.im_page_peer_not_selected .im_dialogs_col {
margin-right: 0;
}
.im_page_peer_not_selected .im_dialogs_col_wrap .pane {
width: 6px;
right: 3px;
}
.im_page_peer_not_selected .im_dialogs_col_wrap .pane > .slider {
background : rgba(3,46,79,0.22);
border-radius: 3px;
margin: 0;
}
.im_dialogs_panel {
padding-left: 9px;
padding-right: 9px;
}
.im_dialogs_panel_dropdown {
display: none;
}
.im_page_split .im_dialogs_search {
margin-right: 0;
}
.im_dialogs_modal_col .im_dialogs_scrollable_wrap,
.im_dialogs_scrollable_wrap {
padding: 0;
}
.peer_select_modal_wrap .modal-body {
padding-left: 0;
padding-right: 0;
}
.im_dialogs_col_wrap,
.im_history_col_wrap {
float: none;
width: auto;
max-width: auto;
min-width: auto;
}
.im_dialogs_modal_col_wrap .im_dialog_peer,
.im_page_peer_not_selected .im_dialog_peer {
white-space: nowrap;
height: auto;
}
.im_dialogs_modal_col_wrap .im_dialog_message,
.im_page_peer_not_selected .im_dialog_message {
display: block;
}
.im_history_panel_wrap {
display: none;
}
.modal.page_modal {
background: #FFF;
}
.page_modal .modal-content {
border-radius: 0;
box-shadow: none;
}
.page_modal .modal-dialog {
margin: 0;
}
.page_modal .modal-content .modal-body {
padding-left: 0;
padding-right: 0;
}
.user_modal_other_btn button {
padding-right: 0;
}
.user_modal_other_btn .dropdown-menu {
left: auto;
right: -9px;
}
.chat_modal_actions_wrap {
clear: both;
}
.chat_modal_other_btn button {
padding-right: 0;
}
.chat_modal_other_btn .dropdown-menu {
left: auto;
right: -9px;
}
.photo_modal_window .modal-content,
.video_modal_window .modal-content {
border-radius: 0;
}
.media_modal_wrap .modal-body {
padding: 0 0 0;
}
.media_modal_actions,
.media_modal_info{
margin: 10px;
}
}

3
app/index.html

@ -10,6 +10,7 @@
<link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.css"/> <link rel="stylesheet" href="vendor/bootstrap/css/bootstrap.css"/>
<link rel="stylesheet" href="vendor/jquery.nanoscroller/nanoscroller.css"/> <link rel="stylesheet" href="vendor/jquery.nanoscroller/nanoscroller.css"/>
<link rel="stylesheet" href="css/app.css"/> <link rel="stylesheet" href="css/app.css"/>
<link rel="stylesheet" href="css/app_mobile.css"/>
<!-- endbuild --> <!-- endbuild -->
<link rel="icon" href="favicon.ico" type="image/x-icon" /> <link rel="icon" href="favicon.ico" type="image/x-icon" />
@ -23,7 +24,7 @@
</head> </head>
<body> <body>
<div ng-view></div> <div class="page_wrap" ng-view></div>
<!-- build:js js/app.js --> <!-- build:js js/app.js -->
<script type="text/javascript" src="vendor/console-polyfill/console-polyfill.js"></script> <script type="text/javascript" src="vendor/console-polyfill/console-polyfill.js"></script>

103
app/js/controllers.js

@ -230,12 +230,14 @@ angular.module('myApp.controllers', [])
$scope.isLoggedIn = true; $scope.isLoggedIn = true;
$scope.isEmpty = {}; $scope.isEmpty = {};
$scope.historyFilter = {mediaType: false};
$scope.historyPeer = {};
$scope.openSettings = function () { $scope.openSettings = function () {
$modal.open({ $modal.open({
templateUrl: 'partials/settings_modal.html', templateUrl: 'partials/settings_modal.html',
controller: 'SettingsModalController', controller: 'SettingsModalController',
windowClass: 'settings_modal_window' windowClass: 'settings_modal_window page_modal'
}); });
} }
@ -243,7 +245,7 @@ angular.module('myApp.controllers', [])
ContactsSelectService.selectContact().then(function (userID) { ContactsSelectService.selectContact().then(function (userID) {
$scope.dialogSelect(AppUsersManager.getUserString(userID)); $scope.dialogSelect(AppUsersManager.getUserString(userID));
}); });
} };
$scope.openGroup = function () { $scope.openGroup = function () {
ContactsSelectService.selectContacts().then(function (userIDs) { ContactsSelectService.selectContacts().then(function (userIDs) {
@ -263,7 +265,15 @@ angular.module('myApp.controllers', [])
} }
}); });
};
$scope.importContact = function () {
AppUsersManager.openImportContact().then(function (foundContact) {
if (foundContact) {
$scope.$broadcast('contact_imported');
} }
});
};
$scope.dialogSelect = function (peerString, messageID) { $scope.dialogSelect = function (peerString, messageID) {
var params = {peerString: peerString}; var params = {peerString: peerString};
@ -280,7 +290,27 @@ angular.module('myApp.controllers', [])
location.reload(); location.reload();
}); });
}) })
};
$scope.showPeerInfo = function () {
if ($scope.curDialog.peerID > 0) {
$rootScope.openUser($scope.curDialog.peerID)
} else if ($scope.curDialog.peerID < 0) {
$rootScope.openChat(-$scope.curDialog.peerID)
} }
};
$scope.toggleEdit = function () {
$scope.$broadcast('history_edit_toggle');
};
$scope.returnToRecent = function () {
$scope.$broadcast('history_return_recent');
};
$scope.toggleMedia = function (mediaType) {
$scope.$broadcast('history_media_toggle', mediaType);
};
updateCurDialog(); updateCurDialog();
@ -353,6 +383,12 @@ angular.module('myApp.controllers', [])
} }
}); });
$scope.$on('contact_imported', function () {
if (contactsShown) {
loadDialogs();
}
})
var prevMessages = false; var prevMessages = false;
$scope.$watchCollection('search', function () { $scope.$watchCollection('search', function () {
if ($scope.search.messages && (!angular.isString($scope.search.query) || !$scope.search.query.length)) { if ($scope.search.messages && (!angular.isString($scope.search.query) || !$scope.search.query.length)) {
@ -367,14 +403,6 @@ angular.module('myApp.controllers', [])
} }
}); });
$scope.importContact = function () {
AppUsersManager.openImportContact().then(function (foundContact) {
if (contactsShown && foundContact) {
loadDialogs();
}
});
};
$scope.importPhonebook = function () { $scope.importPhonebook = function () {
PhonebookContactsService.openPhonebookImport().result.then(function (foundContacts) { PhonebookContactsService.openPhonebookImport().result.then(function (foundContacts) {
if (contactsShown && foundContacts.length) { if (contactsShown && foundContacts.length) {
@ -444,14 +472,6 @@ angular.module('myApp.controllers', [])
}); });
}; };
$scope.importContact = function () {
AppUsersManager.openImportContact().then(function (foundContact) {
if (contactsShown && foundContact) {
loadDialogs();
}
});
};
$scope.importPhonebook = function () { $scope.importPhonebook = function () {
PhonebookContactsService.openPhonebookImport().result.then(function (foundContacts) { PhonebookContactsService.openPhonebookImport().result.then(function (foundContacts) {
if (contactsShown && foundContacts.length) { if (contactsShown && foundContacts.length) {
@ -558,7 +578,6 @@ angular.module('myApp.controllers', [])
StatusManager.start(); StatusManager.start();
$scope.history = []; $scope.history = [];
$scope.mediaType = false;
$scope.skippedHistory = false; $scope.skippedHistory = false;
$scope.selectedMsgs = {}; $scope.selectedMsgs = {};
$scope.selectedCount = 0; $scope.selectedCount = 0;
@ -572,10 +591,16 @@ angular.module('myApp.controllers', [])
$scope.selectedForward = selectedForward; $scope.selectedForward = selectedForward;
$scope.selectedCancel = selectedCancel; $scope.selectedCancel = selectedCancel;
$scope.selectedFlush = selectedFlush; $scope.selectedFlush = selectedFlush;
$scope.toggleEdit = toggleEdit; $scope.toggleEdit = toggleEdit;
$scope.toggleMedia = toggleMedia; $scope.toggleMedia = toggleMedia;
$scope.returnToRecent = returnToRecent; $scope.returnToRecent = returnToRecent;
$scope.showPeerInfo = showPeerInfo;
$scope.$on('history_edit_toggle', toggleEdit);
$scope.$on('history_media_toggle', function (e, mediaType) {
toggleMedia(mediaType);
});
$scope.$on('history_return_recent', returnToRecent);
var peerID, var peerID,
hasMore = false, hasMore = false,
@ -603,7 +628,7 @@ angular.module('myApp.controllers', [])
$scope.curDialog.peerID = peerID; $scope.curDialog.peerID = peerID;
$scope.curDialog.inputPeer = AppPeersManager.getInputPeer(newPeer); $scope.curDialog.inputPeer = AppPeersManager.getInputPeer(newPeer);
$scope.mediaType = false; $scope.historyFilter.mediaType = false;
selectedCancel(true); selectedCancel(true);
@ -629,11 +654,11 @@ angular.module('myApp.controllers', [])
$scope.history = []; $scope.history = [];
$scope.historyPeer = { safeReplaceObject($scope.historyPeer, {
id: peerID, id: peerID,
data: peerData, data: peerData,
photo: AppPeersManager.getPeerPhoto(peerID, 'User', 'Group') photo: AppPeersManager.getPeerPhoto(peerID, 'User', 'Group')
}; });
MtpApiManager.getUserID().then(function (id) { MtpApiManager.getUserID().then(function (id) {
$scope.ownPhoto = AppUsersManager.getUserPhoto(id, 'User'); $scope.ownPhoto = AppUsersManager.getUserPhoto(id, 'User');
@ -734,7 +759,7 @@ angular.module('myApp.controllers', [])
var curJump = jump, var curJump = jump,
curMoreJump = moreJump, curMoreJump = moreJump,
inputMediaFilter = $scope.mediaType && {_: inputMediaFilters[$scope.mediaType]}, inputMediaFilter = $scope.historyFilter.mediaType && {_: inputMediaFilters[$scope.historyFilter.mediaType]},
getMessagesPromise = inputMediaFilter getMessagesPromise = inputMediaFilter
? AppMessagesManager.getSearch($scope.curDialog.inputPeer, '', inputMediaFilter, maxID) ? AppMessagesManager.getSearch($scope.curDialog.inputPeer, '', inputMediaFilter, maxID)
: AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID); : AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID);
@ -777,7 +802,7 @@ angular.module('myApp.controllers', [])
} }
var curJump = ++jump, var curJump = ++jump,
inputMediaFilter = $scope.mediaType && {_: inputMediaFilters[$scope.mediaType]}, inputMediaFilter = $scope.historyFilter.mediaType && {_: inputMediaFilters[$scope.historyFilter.mediaType]},
getMessagesPromise = inputMediaFilter getMessagesPromise = inputMediaFilter
? AppMessagesManager.getSearch($scope.curDialog.inputPeer, '', inputMediaFilter, maxID) ? AppMessagesManager.getSearch($scope.curDialog.inputPeer, '', inputMediaFilter, maxID)
: AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID, limit, backLimit); : AppMessagesManager.getHistory($scope.curDialog.inputPeer, maxID, limit, backLimit);
@ -814,7 +839,7 @@ angular.module('myApp.controllers', [])
if (historyResult.unreadOffset) { if (historyResult.unreadOffset) {
$scope.historyUnreadAfter = historyResult.history[historyResult.unreadOffset - 1]; $scope.historyUnreadAfter = historyResult.history[historyResult.unreadOffset - 1];
} else { } else {
$scope.historyUnreadAfter = {}; delete $scope.historyUnreadAfter;
} }
$scope.historyFocus = $scope.curDialog.messageID || 0; $scope.historyFocus = $scope.curDialog.messageID || 0;
@ -950,13 +975,13 @@ angular.module('myApp.controllers', [])
} }
function toggleMedia (mediaType) { function toggleMedia (mediaType) {
$scope.mediaType = mediaType || false; $scope.historyFilter.mediaType = mediaType || false;
$scope.history = []; $scope.history = [];
loadHistory(); loadHistory();
} }
function returnToRecent () { function returnToRecent () {
if ($scope.mediaType) { if ($scope.historyFilter.mediaType) {
toggleMedia(); toggleMedia();
} else { } else {
if ($scope.curDialog.messageID) { if ($scope.curDialog.messageID) {
@ -967,14 +992,6 @@ angular.module('myApp.controllers', [])
} }
} }
function showPeerInfo () {
if ($scope.curDialog.peerID > 0) {
$rootScope.openUser($scope.curDialog.peerID)
} else if ($scope.curDialog.peerID < 0) {
$rootScope.openChat(-$scope.curDialog.peerID)
}
}
var typingTimeouts = {}; var typingTimeouts = {};
@ -982,7 +999,7 @@ angular.module('myApp.controllers', [])
$scope.$on('history_append', function (e, addedMessage) { $scope.$on('history_append', function (e, addedMessage) {
if (addedMessage.peerID == $scope.curDialog.peerID) { if (addedMessage.peerID == $scope.curDialog.peerID) {
if ($scope.mediaType || $scope.skippedHistory) { if ($scope.historyFilter.mediaType || $scope.skippedHistory) {
if (addedMessage.my) { if (addedMessage.my) {
returnToRecent(); returnToRecent();
} else { } else {
@ -997,7 +1014,7 @@ angular.module('myApp.controllers', [])
$scope.typing = {}; $scope.typing = {};
$scope.$broadcast('ui_history_append_new', {my: addedMessage.my}); $scope.$broadcast('ui_history_append_new', {my: addedMessage.my});
if (addedMessage.my) { if (addedMessage.my) {
$scope.historyUnread = {}; delete $scope.historyUnreadAfter;
} }
// console.log('append check', $rootScope.idle.isIDLE, addedMessage.peerID, $scope.curDialog.peerID); // console.log('append check', $rootScope.idle.isIDLE, addedMessage.peerID, $scope.curDialog.peerID);
@ -1030,7 +1047,7 @@ angular.module('myApp.controllers', [])
}); });
$scope.$on('history_focus', function (e, peerData) { $scope.$on('history_focus', function (e, peerData) {
if ($scope.mediaType) { if ($scope.historyFilter.mediaType) {
toggleMedia(); toggleMedia();
} }
}); });
@ -1068,7 +1085,7 @@ angular.module('myApp.controllers', [])
$scope.$on('history_need_more', showMoreHistory); $scope.$on('history_need_more', showMoreHistory);
$rootScope.$watch('idle.isIDLE', function (newVal) { $rootScope.$watch('idle.isIDLE', function (newVal) {
if (!newVal && $scope.curDialog && $scope.curDialog.peerID && !$scope.mediaType && !$scope.skippedHistory) { if (!newVal && $scope.curDialog && $scope.curDialog.peerID && !$scope.historyFilter.mediaType && !$scope.skippedHistory) {
AppMessagesManager.readHistory($scope.curDialog.inputPeer); AppMessagesManager.readHistory($scope.curDialog.inputPeer);
} }
}); });
@ -1152,7 +1169,7 @@ angular.module('myApp.controllers', [])
// console.trace('ctrl text changed', newVal); // console.trace('ctrl text changed', newVal);
if (newVal && newVal.length) { if (newVal && newVal.length) {
if (!$scope.mediaType && !$scope.skippedHistory) { if (!$scope.historyFilter.mediaType && !$scope.skippedHistory) {
AppMessagesManager.readHistory($scope.curDialog.inputPeer); AppMessagesManager.readHistory($scope.curDialog.inputPeer);
} }
@ -1530,7 +1547,7 @@ angular.module('myApp.controllers', [])
$modal.open({ $modal.open({
templateUrl: edit ? 'partials/edit_contact_modal.html' : 'partials/import_contact_modal.html', templateUrl: edit ? 'partials/edit_contact_modal.html' : 'partials/import_contact_modal.html',
controller: 'ImportContactModalController', controller: 'ImportContactModalController',
windowClass: 'import_contact_modal_window', windowClass: 'import_contact_modal_window page_modal',
scope: scope scope: scope
}).result.then(function (foundUserID) { }).result.then(function (foundUserID) {
if ($scope.userID == foundUserID) { if ($scope.userID == foundUserID) {
@ -1820,7 +1837,7 @@ angular.module('myApp.controllers', [])
$modal.open({ $modal.open({
templateUrl: 'partials/profile_edit_modal.html', templateUrl: 'partials/profile_edit_modal.html',
controller: 'ProfileEditModalController', controller: 'ProfileEditModalController',
windowClass: 'profile_edit_modal_window' windowClass: 'profile_edit_modal_window page_modal'
}); });
}; };

54
app/js/directives.js

@ -11,6 +11,15 @@
angular.module('myApp.directives', ['myApp.filters']) angular.module('myApp.directives', ['myApp.filters'])
.directive('myHead', function() {
return {
restrict: 'AE',
scope: true,
templateUrl: 'partials/head.html'
};
})
.directive('myDialog', function() { .directive('myDialog', function() {
return { return {
restrict: 'AE', restrict: 'AE',
@ -236,7 +245,8 @@ angular.module('myApp.directives', ['myApp.filters'])
function updateSizes () { function updateSizes () {
if (attrs.modal) { if (attrs.modal) {
$(element).css({ $(element).css({
height: $($window).height() - 200 height: $($window).height() -
(Config.Navigator.mobile ? 100 : 200)
}); });
updateScroller(); updateScroller();
return; return;
@ -281,7 +291,10 @@ angular.module('myApp.directives', ['myApp.filters'])
function updateSizes () { function updateSizes () {
$(element).css({ $(element).css({
height: $($window).height() - (panelWrap && panelWrap.offsetHeight || 0) - (searchWrap && searchWrap.offsetHeight || 0) - 200 height: $($window).height() -
(panelWrap && panelWrap.offsetHeight || 0) -
(searchWrap && searchWrap.offsetHeight || 0) -
(Config.Navigator.mobile ? 60 : 200)
}); });
$(contactsWrap).nanoScroller(); $(contactsWrap).nanoScroller();
} }
@ -370,21 +383,24 @@ angular.module('myApp.directives', ['myApp.filters'])
} }
} }
var animated = transform && !$rootScope.idle.isIDLE ? true : false, var animated = transform ? true : false,
curAnimation = false; curAnimation = false;
$scope.$on('ui_history_append_new', function (e, options) { $scope.$on('ui_history_append_new', function (e, options) {
if (!atBottom && !options.my) { if (!atBottom && !options.my) {
return; return;
} }
if (!animated) { var curAnimated = animated && !$rootScope.idle.isIDLE,
wasH;
if (!curAnimated) {
$(scrollable).css({bottom: 0}); $(scrollable).css({bottom: 0});
$(scrollableWrap).addClass('im_history_to_bottom'); $(scrollableWrap).addClass('im_history_to_bottom');
} else {
wasH = scrollableWrap.scrollHeight;
} }
var wasH = scrollableWrap.scrollHeight;
onContentLoaded(function () { onContentLoaded(function () {
if (animated) { if (curAnimated) {
curAnimation = true; curAnimation = true;
$(historyMessagesEl).removeClass('im_history_appending'); $(historyMessagesEl).removeClass('im_history_appending');
scrollableWrap.scrollTop = scrollableWrap.scrollHeight; scrollableWrap.scrollTop = scrollableWrap.scrollHeight;
@ -740,7 +756,7 @@ angular.module('myApp.directives', ['myApp.filters'])
$(richTextarea).on('DOMNodeInserted', onPastedImageEvent); $(richTextarea).on('DOMNodeInserted', onPastedImageEvent);
} }
if (!Config.Navigator.mobile) { if (!Config.Navigator.touch) {
$scope.$on('ui_peer_change', focusField); $scope.$on('ui_peer_change', focusField);
$scope.$on('ui_history_focus', focusField); $scope.$on('ui_history_focus', focusField);
$scope.$on('ui_history_change', focusField); $scope.$on('ui_history_change', focusField);
@ -761,7 +777,7 @@ angular.module('myApp.directives', ['myApp.filters'])
} }
}); });
if (!Config.Navigator.mobile) { if (!Config.Navigator.touch) {
focusField(); focusField();
} }
@ -1221,7 +1237,7 @@ angular.module('myApp.directives', ['myApp.filters'])
.directive('myFocused', function(){ .directive('myFocused', function(){
return { return {
link: function($scope, element, attrs) { link: function($scope, element, attrs) {
if (Config.Navigator.mobile) { if (Config.Navigator.touch) {
return false; return false;
} }
setTimeout(function () { setTimeout(function () {
@ -1235,7 +1251,7 @@ angular.module('myApp.directives', ['myApp.filters'])
return { return {
link: function($scope, element, attrs) { link: function($scope, element, attrs) {
$scope.$on(attrs.myFocusOn, function () { $scope.$on(attrs.myFocusOn, function () {
if (Config.Navigator.mobile) { if (Config.Navigator.touch) {
return false; return false;
} }
onContentLoaded(function () { onContentLoaded(function () {
@ -1276,7 +1292,7 @@ angular.module('myApp.directives', ['myApp.filters'])
function link($scope, element, attrs) { function link($scope, element, attrs) {
attrs.$observe('myModalWidth', function (newW) { attrs.$observe('myModalWidth', function (newW) {
$(element[0].parentNode.parentNode).css({width: parseInt(newW) + 36}); $(element[0].parentNode.parentNode).css({width: parseInt(newW) + (Config.Navigator.mobile ? 0 : 36)});
}); });
}; };
@ -1379,6 +1395,10 @@ angular.module('myApp.directives', ['myApp.filters'])
function link($scope, element, attrs) { function link($scope, element, attrs) {
var updateMargin = function () { var updateMargin = function () {
if (Config.Navigator.mobile &&
$(element[0].parentNode.parentNode.parentNode).hasClass('page_modal')) {
return;
}
var height = element[0].parentNode.offsetHeight, var height = element[0].parentNode.offsetHeight,
contHeight = element[0].parentNode.parentNode.parentNode.offsetHeight; contHeight = element[0].parentNode.parentNode.parentNode.offsetHeight;
@ -1416,15 +1436,21 @@ angular.module('myApp.directives', ['myApp.filters'])
function link($scope, element, attrs) { function link($scope, element, attrs) {
var prevMargin = false; var usePadding = attrs.padding === 'true',
prevMargin = 0;
var updateMargin = function () { var updateMargin = function () {
var height = element[0].offsetHeight, var height = element[0].offsetHeight,
fullHeight = height - (height && usePadding ? 2 * prevMargin : 0),
contHeight = $($window).height(), contHeight = $($window).height(),
ratio = attrs.myVerticalPosition && parseFloat(attrs.myVerticalPosition) || 0.5, ratio = attrs.myVerticalPosition && parseFloat(attrs.myVerticalPosition) || 0.5,
margin = height < contHeight ? parseInt((contHeight - height) * ratio) : ''; margin = fullHeight < contHeight ? parseInt((contHeight - fullHeight) * ratio) : '',
styles = usePadding
? {paddingTop: margin, paddingBottom: margin}
: {marginTop: margin, marginBottom: margin};
element.css({marginTop: margin, marginBottom: margin}); element.css(styles);
element.addClass('vertical-aligned');
if (prevMargin !== margin) { if (prevMargin !== margin) {
$scope.$emit('ui_height'); $scope.$emit('ui_height');

3
app/js/lib/config.js

@ -35,7 +35,8 @@ Config.Navigator = {
osX: (navigator.platform || '').toLowerCase().indexOf('mac') != -1 || osX: (navigator.platform || '').toLowerCase().indexOf('mac') != -1 ||
(navigator.userAgent || '').toLowerCase().indexOf('mac') != -1, (navigator.userAgent || '').toLowerCase().indexOf('mac') != -1,
retina: window.devicePixelRatio > 1, retina: window.devicePixelRatio > 1,
mobile: $(window).height() < 600 touch: $(window).width() <= 768,
mobile: $(window).width() < 480
}; };
Config.Schema = Config.Schema || {}; Config.Schema = Config.Schema || {};

22
app/js/services.js

@ -284,7 +284,7 @@ angular.module('myApp.services', [])
templateUrl: 'partials/user_modal.html', templateUrl: 'partials/user_modal.html',
controller: 'UserModalController', controller: 'UserModalController',
scope: scope, scope: scope,
windowClass: 'user_modal_window' windowClass: 'user_modal_window page_modal'
}); });
}; };
$rootScope.openUser = openUser; $rootScope.openUser = openUser;
@ -377,7 +377,7 @@ angular.module('myApp.services', [])
return $modal.open({ return $modal.open({
templateUrl: 'partials/import_contact_modal.html', templateUrl: 'partials/import_contact_modal.html',
controller: 'ImportContactModalController', controller: 'ImportContactModalController',
windowClass: 'import_contact_modal_window' windowClass: 'import_contact_modal_window page_modal'
}).result.then(function (foundUserID) { }).result.then(function (foundUserID) {
if (!foundUserID) { if (!foundUserID) {
return $q.reject(); return $q.reject();
@ -457,7 +457,7 @@ angular.module('myApp.services', [])
return $modal.open({ return $modal.open({
templateUrl: 'partials/phonebook_modal.html', templateUrl: 'partials/phonebook_modal.html',
controller: 'PhonebookModalController', controller: 'PhonebookModalController',
windowClass: 'phonebook_modal_window' windowClass: 'phonebook_modal_window page_modal'
}); });
} }
@ -598,7 +598,7 @@ angular.module('myApp.services', [])
var modalInstance = $modal.open({ var modalInstance = $modal.open({
templateUrl: 'partials/chat_modal.html', templateUrl: 'partials/chat_modal.html',
controller: 'ChatModalController', controller: 'ChatModalController',
windowClass: 'chat_modal_window', windowClass: 'chat_modal_window page_modal',
scope: scope scope: scope
}); });
} }
@ -985,15 +985,16 @@ angular.module('myApp.services', [])
} }
} }
if (!offsetNotFound && historyStorage.count !== null && historyStorage.history.length == historyStorage.count || if (!offsetNotFound && (
historyStorage.count !== null && historyStorage.history.length == historyStorage.count ||
historyStorage.history.length >= offset + (limit || 1) historyStorage.history.length >= offset + (limit || 1)
) { )) {
if (backLimit) { if (backLimit) {
backLimit = Math.min(offset, backLimit); backLimit = Math.min(offset, backLimit);
offset = Math.max(0, offset - backLimit); offset = Math.max(0, offset - backLimit);
limit += backLimit; limit += backLimit;
} else { } else {
limit = limit || 20; limit = limit || (offset ? 20 : 5);
} }
return $q.when({ return $q.when({
@ -2291,7 +2292,7 @@ angular.module('myApp.services', [])
function wrapForFull (photoID) { function wrapForFull (photoID) {
var photo = wrapForHistory(photoID), var photo = wrapForHistory(photoID),
fullWidth = $(window).width() - 36, fullWidth = $(window).width() - (Config.Navigator.mobile ? 20 : 36),
fullHeight = $($window).height() - 150, fullHeight = $($window).height() - 150,
fullPhotoSize = choosePhotoSize(photo, fullWidth, fullHeight), fullPhotoSize = choosePhotoSize(photo, fullWidth, fullHeight),
full = { full = {
@ -2522,7 +2523,8 @@ angular.module('myApp.services', [])
var modalInstance = $modal.open({ var modalInstance = $modal.open({
templateUrl: 'partials/video_modal.html', templateUrl: 'partials/video_modal.html',
controller: 'VideoModalController', controller: 'VideoModalController',
scope: scope scope: scope,
windowClass: 'video_modal_window'
}); });
} }
@ -3723,7 +3725,7 @@ angular.module('myApp.services', [])
$modal.open({ $modal.open({
templateUrl: 'partials/changelog_modal.html', templateUrl: 'partials/changelog_modal.html',
scope: $scope, scope: $scope,
windowClass: 'changelog_modal_window' windowClass: 'changelog_modal_window page_modal'
}); });
} }

3
app/partials/chat_modal.html

@ -22,8 +22,6 @@
</ng-pluralize> </ng-pluralize>
</p> </p>
<div class="chat_modal_settings_wrap">
<div class="chat_modal_actions_wrap clearfix"> <div class="chat_modal_actions_wrap clearfix">
<button ng-if="!chatFull.chat.left &amp;&amp; chatFull.participants.participants.length" class="btn btn-primary chat_modal_invite_btn" ng-click="inviteToGroup()">Add member</button> <button ng-if="!chatFull.chat.left &amp;&amp; chatFull.participants.participants.length" class="btn btn-primary chat_modal_invite_btn" ng-click="inviteToGroup()">Add member</button>
@ -58,7 +56,6 @@
</div> </div>
</div> </div>
</div>
</div> </div>
</div> </div>

6
app/partials/contacts_modal.html

@ -1,7 +1,11 @@
<div class="contacts_modal_wrap" my-modal-position> <div class="contacts_modal_wrap" my-modal-position>
<a class="modal-close-button visible-xs" ng-click="$dismiss()"><i></i></a>
<div class="modal-body"> <div class="modal-body">
<h4 class="modal_simple_header visible-xs">Contacts</h4>
<div class="contacts_modal_search"> <div class="contacts_modal_search">
<input class="form-control contacts_modal_search_field" my-focused type="search" placeholder="Search" ng-model="search.query"/> <input class="form-control contacts_modal_search_field" my-focused type="search" placeholder="Search" ng-model="search.query"/>
<a class="contacts_modal_search_clear" ng-click="search.query = ''" ng-show="search.query.length"></a> <a class="contacts_modal_search_clear" ng-click="search.query = ''" ng-show="search.query.length"></a>
@ -44,7 +48,7 @@
</div> </div>
<div class="modal-footer" ng-switch="multiSelect"> <div class="modal-footer contacts_modal_panel" ng-switch="multiSelect">
<button ng-switch-when="true" class="btn btn-success btn-block" ng-class="{disabled: !selectedCount}" ng-disabled="!selectedCount" ng-click="submitSelected()" type="submit"> <button ng-switch-when="true" class="btn btn-success btn-block" ng-class="{disabled: !selectedCount}" ng-disabled="!selectedCount" ng-click="submitSelected()" type="submit">
Next » Next »
</button> </button>

72
app/partials/head.html

@ -1,19 +1,78 @@
<div class="tg_page_head"> <div class="tg_page_head">
<div class="navbar navbar-static-top navbar-inverse" role="navigation"> <div class="navbar navbar-static-top navbar-inverse" role="navigation" ng-class="{navbar_peer_not_selected: !curDialog.peer, navbar_offline: offline}">
<div class="container"> <div class="container">
<div class="navbar-toggle-wrap dropdown">
<a class="dropdown-toggle navbar-toggle">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<ul ng-if="!curDialog.peer &amp;&amp; isLoggedIn" class="dropdown-menu">
<li><a ng-click="openGroup()">New Group</a></li>
<li><a ng-click="importContact()">New Contact</a></li>
<li><a ng-click="openContacts()">Contacts</a></li>
<li><a ng-click="openSettings()">Settings</a></li>
<li><a ng-click="logOut()">Log Out</a></li>
</ul>
<ul ng-if="curDialog.peer &amp;&amp; isLoggedIn" class="dropdown-menu">
<li><a ng-click="showPeerInfo()" ng-switch="historyPeer.id > 0">
<span ng-switch-when="true">Profile</span>
<span ng-switch-default>Group info</span>
</a></li>
<li><a ng-click="toggleEdit()">Edit chat</a></li>
<li ng-if="!historyFilter.mediaType" class="divider"></li>
<li ng-if="!historyFilter.mediaType" class="dropdown-header">Media</li>
<li ng-if="!historyFilter.mediaType"><a ng-click="toggleMedia('photos')">Photos</a></li>
<li ng-if="!historyFilter.mediaType"><a ng-click="toggleMedia('video')">Videos</a></li>
<li ng-if="!historyFilter.mediaType"><a ng-click="toggleMedia('documents')">Documents</a></li>
<li ng-if="!historyFilter.mediaType"><a ng-click="toggleMedia('audio')">Voice messages</a></li>
</ul>
<ul ng-if="!isLoggedIn" class="dropdown-menu">
<li><a href="https://github.com/zhukov/webogram" target="_blank">About</a></li>
</ul>
</div>
<div class="navbar-header"> <div class="navbar-header">
<a class="navbar-brand" href="{{isLoggedIn ? '#/im' : '#/'}}"><span class="tg_head_logo"></span><span class="tg_head_logo_text"></span></a> <a class="navbar-brand" href="{{isLoggedIn ? '#/im' : '#/'}}"><span class="tg_head_logo"></span><span class="tg_head_logo_text"></span></a>
<ul class="nav navbar-nav navbar-quick-nav" ng-show="curDialog.peer">
<div ng-show="curDialog.peer" ng-switch="curDialog.peer &amp;&amp; historyFilter.mediaType.length">
<ul ng-switch-when="true" class="nav navbar-nav navbar-quick-nav">
<li> <li>
<a href="#/im"> <a ng-click="toggleMedia()" class="navbar-quick-media-back" ng-switch="historyFilter.mediaType">
<i class="icon icon-back"></i> Back <i class="icon icon-back"></i>
<h4 ng-switch-when="photos">Photos</h4>
<h4 ng-switch-when="video">Videos</h4>
<h4 ng-switch-when="documents">Documents</h4>
<h4 ng-switch-when="audio">Voice messages</h4>
</a>
</li>
</ul>
<ul ng-switch-default class="nav navbar-nav navbar-quick-nav" ng-switch="historyPeer.id > 0">
<li ng-switch-when="true">
<a href="#/im" class="navbar-quick-profile-back">
<i class="icon icon-back"></i>
<h4 ng-bind-html="historyPeer.data.rFullName"></h4>
<small ng-bind="historyPeer.data | userStatus"></small>
</a>
</li>
<li ng-switch-default>
<a href="#/im" class="navbar-quick-group-back">
<i class="icon icon-back"></i>
<h4 ng-bind-html="historyPeer.data.rTitle"></h4>
<small>
<ng-pluralize count="historyPeer.data.participants_count"
when="{'0': 'No members', 'one': '1 member', 'other': '{} members'}">
</ng-pluralize>
</small>
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
</div>
<div class="navbar-menu" ng-switch="offline">
<div class="navbar-collapse collapse" ng-switch="offline">
<ul ng-switch-when="true" class="nav navbar-nav navbar-offline"> <ul ng-switch-when="true" class="nav navbar-nav navbar-offline">
<li ng-show="!offlineConnecting"><span class="navbar-offline-text">Waiting for network<span my-loading-dots></span></span></li> <li ng-show="!offlineConnecting"><span class="navbar-offline-text">Waiting for network<span my-loading-dots></span></span></li>
@ -29,6 +88,7 @@
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
</div> </div>

22
app/partials/im.html

@ -1,4 +1,4 @@
<div ng-include="'partials/head.html'"></div> <div my-head></div>
<div class="im_page_wrap" ng-class="{im_page_peer_not_selected: !curDialog.peer}"> <div class="im_page_wrap" ng-class="{im_page_peer_not_selected: !curDialog.peer}">
@ -89,11 +89,11 @@
<p class="im_dialogs_empty_lead">Welcome to Telegram Web. You can always set your profile photo and change your name in Settings.</p> <p class="im_dialogs_empty_lead">Welcome to Telegram Web. You can always set your profile photo and change your name in Settings.</p>
<button type="button" class="btn btn-primary btn-sm" ng-click="openSettings()">Open Settings</button> <button type="button" class="btn btn-primary btn-sm" ng-click="openSettings()">Open Settings</button>
</div> </div>
<div ng-switch-default class="im_history_not_selected" my-vertical-position="0.35"> <div ng-switch-default class="im_history_not_selected" my-vertical-position="0.35" padding="true">
Please select a chat to start messaging Please select a chat to start messaging
</div> </div>
</div> </div>
<div ng-show="!state.notSelected &amp;&amp; !state.loaded" class="im_history_not_selected" my-vertical-position="0.35"> <div ng-show="!state.notSelected &amp;&amp; !state.loaded" class="im_history_not_selected" my-vertical-position="0.35" padding="true">
Loading history<span my-loading-dots></span> Loading history<span my-loading-dots></span>
</div> </div>
@ -117,13 +117,13 @@
<li><a ng-click="toggleMedia('audio')">Voice messages</a></li> <li><a ng-click="toggleMedia('audio')">Voice messages</a></li>
</ul> </ul>
</div> </div>
<a ng-show="mediaType !== false || skippedHistory" class="im_history_panel_return_link pull-right" ng-click="returnToRecent()" ng-switch="skippedHistory"> <a ng-show="historyFilter.mediaType.length || skippedHistory" class="im_history_panel_return_link pull-right" ng-click="returnToRecent()" ng-switch="skippedHistory">
<span ng-switch-when="true">Show recent messages</span> <span ng-switch-when="true">Show recent messages</span>
<span ng-switch-default>Show all messages</span> <span ng-switch-default>Show all messages</span>
<strong class="im_history_panel_return_count" ng-show="missedCount > 0" ng-bind="'+' + missedCount"></strong> <strong class="im_history_panel_return_count" ng-show="missedCount > 0" ng-bind="'+' + missedCount"></strong>
</a> </a>
<div ng-switch="mediaType"> <div ng-switch="historyFilter.mediaType">
<h4 ng-switch-when="photos">Photos</h4> <h4 ng-switch-when="photos">Photos</h4>
<h4 ng-switch-when="video">Videos</h4> <h4 ng-switch-when="video">Videos</h4>
<h4 ng-switch-when="documents">Documents</h4> <h4 ng-switch-when="documents">Documents</h4>
@ -157,13 +157,9 @@
<div class="im_history_scrollable"> <div class="im_history_scrollable">
<div class="im_history" ng-class="{im_history_selectable: selectActions}"> <div class="im_history" ng-class="{im_history_selectable: selectActions}">
<div ng-if="!history.length" class="im_history_empty" ng-switch="state.mayBeHasMore"> <div ng-if="!history.length" class="im_history_empty" ng-switch="state.mayBeHasMore" my-vertical-position="0.25" padding="true">
<div my-vertical-position="0.25" ng-switch-when="true"> <span ng-switch-when="true">Loading history<span my-loading-dots></span></span>
Loading history<span my-loading-dots></span> <span ng-switch-default>No messages here yet...</span>
</div>
<div my-vertical-position="0.25" ng-switch-default>
No messages here yet...
</div>
</div> </div>
<div class="im_history_messages"> <div class="im_history_messages">
@ -172,7 +168,7 @@
</div> </div>
<div class="im_history_typing_wrap"> <div class="im_history_typing_wrap">
<div class="im_history_typing" ng-show="typing.user &amp;&amp; !mediaType"> <div class="im_history_typing" ng-show="typing.user &amp;&amp; !historyFilter.mediaType">
<strong class="im_history_typing_author" ng-bind-html="typing.user.rFullName"></strong> is typing<span my-loading-dots></span> <strong class="im_history_typing_author" ng-bind-html="typing.user.rFullName"></strong> is typing<span my-loading-dots></span>
</div> </div>
</div> </div>

2
app/partials/login.html

@ -1,4 +1,4 @@
<div ng-include="'partials/head.html'"></div> <div my-head></div>
<div class="login_form_wrap" my-vertical-position="0.4"> <div class="login_form_wrap" my-vertical-position="0.4">

7
app/partials/message.html

@ -57,13 +57,13 @@
</div> </div>
<div bindonce bo-if="historyMessage._ != 'messageService'" class="im_content_message_wrap"> <div bindonce bo-if="historyMessage._ != 'messageService'" class="im_content_message_wrap" ng-class="{im_message_unread: historyMessage.unread, im_message_out: historyMessage.out, im_message_in: !historyMessage.out, im_message_error: historyMessage.error, im_message_pending: historyMessage.pending}">
<div class="im_content_message_select_area"> <div class="im_content_message_select_area">
<i class="icon icon-select-tick"></i> <i class="icon icon-select-tick"></i>
</div> </div>
<a bo-if="historyMessage.pending || historyMessage.error" ng-click="historyMessage.send()" ng-show="historyMessage.error"> <a class="im_message_error_btn" bo-if="historyMessage.pending || historyMessage.error" ng-click="historyMessage.send()">
<i class="icon-message-status icon-message-status-error" tooltip="Try again"></i> <i class="icon-message-status" tooltip="Try again"></i>
</a> </a>
<i bo-if="historyMessage.unread || historyMessage.pending" class="icon-message-status" ng-class="{'icon-message-status-unread': historyMessage.unread, 'icon-message-status-pending': historyMessage.pending}" ng-show="!historyMessage.error"></i> <i bo-if="historyMessage.unread || historyMessage.pending" class="icon-message-status" ng-class="{'icon-message-status-unread': historyMessage.unread, 'icon-message-status-pending': historyMessage.pending}" ng-show="!historyMessage.error"></i>
@ -76,6 +76,7 @@
/> />
</a> </a>
<div class="im_message_meta pull-right text-right"> <div class="im_message_meta pull-right text-right">
<i class="icon-message-status-tick"></i>
<span class="im_message_date" bo-bind="historyMessage.date | dateOrTime"></span> <span class="im_message_date" bo-bind="historyMessage.date | dateOrTime"></span>
</div> </div>

4
app/partials/peer_select.html

@ -1,7 +1,11 @@
<div class="peer_select_modal_wrap" my-modal-position> <div class="peer_select_modal_wrap" my-modal-position>
<a class="modal-close-button visible-xs" ng-click="$dismiss()"><i></i></a>
<div class="modal-body"> <div class="modal-body">
<h4 class="modal_simple_header visible-xs">Contacts</h4>
<div class="im_dialogs_modal_col_wrap" ng-controller="AppImDialogsController" my-dialogs> <div class="im_dialogs_modal_col_wrap" ng-controller="AppImDialogsController" my-dialogs>
<div class="im_dialogs_panel"> <div class="im_dialogs_panel">
<div class="im_dialogs_search"> <div class="im_dialogs_search">

3
app/partials/photo_modal.html

@ -4,6 +4,7 @@
<div class="photo_modal_image_wrap" my-load-full-photo full-photo="photo.full" thumb-location="photo.thumb.location" ng-click="nav.next()"> </div> <div class="photo_modal_image_wrap" my-load-full-photo full-photo="photo.full" thumb-location="photo.thumb.location" ng-click="nav.next()"> </div>
<div class="media_meta_wrap clearfix">
<div class="media_modal_actions pull-right"> <div class="media_modal_actions pull-right">
<a href="" class="media_modal_action_link" ng-click="download()">Download</a> <a href="" class="media_modal_action_link" ng-click="download()">Download</a>
<a href="" class="media_modal_action_link" ng-if="canForward" ng-click="forward()">Forward</a> <a href="" class="media_modal_action_link" ng-if="canForward" ng-click="forward()">Forward</a>
@ -13,6 +14,8 @@
<p class="media_modal_info"> <p class="media_modal_info">
<span class="media_modal_author" ng-bind-html="photo.fromUser.rFullName"></span>, {{photo.date | dateOrTime}} <span class="media_modal_author" ng-bind-html="photo.fromUser.rFullName"></span>, {{photo.date | dateOrTime}}
</p> </p>
</div>
</div> </div>

2
app/partials/video_modal.html

@ -4,6 +4,7 @@
<div class="video_modal_image_wrap" my-load-video video="video"></div> <div class="video_modal_image_wrap" my-load-video video="video"></div>
<div class="media_meta_wrap clearfix">
<div class="media_modal_actions pull-right" ng-if="messageID"> <div class="media_modal_actions pull-right" ng-if="messageID">
<a href="" class="media_modal_action_link" ng-click="forward()">Forward</a> <a href="" class="media_modal_action_link" ng-click="forward()">Forward</a>
<a href="" class="media_modal_action_link" ng-click="delete()">Delete</a> <a href="" class="media_modal_action_link" ng-click="delete()">Delete</a>
@ -12,6 +13,7 @@
<p class="media_modal_info"> <p class="media_modal_info">
<span class="media_modal_author" ng-bind-html="video.fromUser.rFullName" ></span>, {{video.date | dateOrTime}} <span class="media_modal_author" ng-bind-html="video.fromUser.rFullName" ></span>, {{video.date | dateOrTime}}
</p> </p>
</div>
</div> </div>

3
app/partials/welcome.html

@ -1,5 +1,4 @@
<div ng-include="'partials/head.html'"></div> <div my-head></div>
<div ng-if="showWelcome"> <div ng-if="showWelcome">

2
app/webogram.appcache

@ -1,6 +1,6 @@
CACHE MANIFEST CACHE MANIFEST
# 8 # 12
NETWORK: NETWORK:
* *

Loading…
Cancel
Save