Telegram Web, preconfigured for usage in I2P.
http://web.telegram.i2p/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
274 lines
14 KiB
274 lines
14 KiB
<div my-head></div> |
|
|
|
<div class="im_page_wrap" ng-class="{im_page_peer_not_selected: !curDialog.peer}"> |
|
|
|
<div class="im_page_split clearfix"> |
|
|
|
<div class="im_dialogs_col_wrap" ng-controller="AppImDialogsController" my-dialogs has-tabs="{{search.query.length > 0}}"> |
|
<div class="im_dialogs_panel"> |
|
<div class="dropdown im_dialogs_panel_dropdown pull-right"> |
|
<a class="dropdown-toggle"> |
|
<span class="icon-bar"></span> |
|
<span class="icon-bar"></span> |
|
<span class="icon-bar"></span> |
|
</a> |
|
<ul class="dropdown-menu"> |
|
<li><a ng-click="openGroup()" my-i18n="im_new_group"></a></li> |
|
<li><a ng-click="importContact()" my-i18n="im_new_contact"></a></li> |
|
<li ng-if="!isEmpty.contacts"><a ng-click="openContacts()" my-i18n="im_contacts"></a></li> |
|
<li><a ng-click="openSettings()" my-i18n="im_settings"></a></li> |
|
</ul> |
|
</div> |
|
<div class="im_dialogs_search"> |
|
<input class="form-control im_dialogs_search_field no_outline" type="search" placeholder="{{'modal_search' | i18n}}" ng-model="search.query"/> |
|
<a class="im_dialogs_search_clear" ng-click="searchClear()" ng-show="search.query.length"></a> |
|
</div> |
|
|
|
<div class="im_dialogs_tabs_wrap"> |
|
<div class="im_dialogs_tabs clearfix"> |
|
<a href="" class="im_dialogs_tab" ng-class="{active: !search.messages}" ng-click="search.messages = false" my-i18n="im_conversations"></a> |
|
<a href="" class="im_dialogs_tab" ng-class="{active: search.messages}" ng-click="search.messages = true" my-i18n="im_messages"></a> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div my-dialogs-list class="im_dialogs_col"> |
|
<div class="im_dialogs_wrap nano"> |
|
<div class="im_dialogs_scrollable_wrap nano-content"> |
|
|
|
<div class="im_dialogs_empty_wrap" ng-if="isEmpty.contacts"> |
|
<h3 class="im_dialogs_empty_header" my-i18n="im_no_contacts"></h3> |
|
<p class="im_dialogs_empty_lead" my-i18n="im_get_started_long"></p> |
|
<button type="button" class="btn btn-primary btn-sm" ng-click="importContact()" my-i18n="im_add_contact"></button> |
|
<button ng-if="phonebookAvailable" type="button" class="btn btn-primary btn-sm im_dialogs_import_phonebook" ng-click="importPhonebook()" my-i18n="im_import_phonebook"></button> |
|
</div> |
|
|
|
<div ng-switch="search.messages"> |
|
<ul ng-switch-when="true" class="nav nav-pills nav-stacked"> |
|
<li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in dialogs track by dialogMessage.id" ng-class="{active: curDialog.peerID == dialogMessage.peerID && curDialog.messageID == dialogMessage.id}"></li> |
|
</ul> |
|
<ul ng-switch-default class="nav nav-pills nav-stacked"> |
|
<li class="im_dialog_wrap" my-dialog dialog-message="dialogMessage" ng-repeat="dialogMessage in dialogs track by dialogMessage.peerID" ng-class="{active: curDialog.peerID == dialogMessage.peerID}"></li> |
|
</ul> |
|
</div> |
|
|
|
<div class="im_dialogs_contacts_wrap" ng-show="!search.messages && contacts.length > 0"> |
|
<h5 my-i18n="im_contacts_title"></h5> |
|
<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}"> |
|
<a class="im_dialog" ng-mousedown="dialogSelect(contact.peerString)"> |
|
<div class="im_dialog_photo pull-left"> |
|
<img |
|
class="im_dialog_photo" |
|
my-load-thumb |
|
thumb="contact.userPhoto" |
|
/> |
|
</div> |
|
<div class="im_dialog_message_wrap"> |
|
<div class="im_dialog_peer"> |
|
<span class="im_dialog_user" ng-bind-html="contact.user.rFullName"></span> |
|
</div> |
|
<div class="im_dialog_message"> |
|
<span class="im_dialog_message_text" my-user-status="::contact.userID"></span> |
|
</div> |
|
</div> |
|
</a> |
|
</li> |
|
</ul> |
|
</div> |
|
|
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="im_history_col_wrap" ng-controller="AppImHistoryController"> |
|
|
|
<div ng-show="state.notSelected" ng-switch="isEmpty.contacts && isEmpty.dialogs"> |
|
<div ng-switch-when="true" class="im_history_no_dialogs_wrap"> |
|
<h3 class="im_dialogs_empty_header" my-i18n="im_get_started"></h3> |
|
<p class="im_dialogs_empty_lead" my-i18n="im_welcome_text"></p> |
|
<button type="button" class="btn btn-primary btn-sm" ng-click="openSettings()" my-i18n="im_open_settings"></button> |
|
</div> |
|
<div ng-switch-default class="im_history_not_selected" my-vertical-position="0.35" padding="true" my-i18n="im_select_a_chat"></div> |
|
</div> |
|
|
|
<div ng-show="!state.notSelected && !state.loaded" class="im_history_not_selected" my-vertical-position="0.35" padding="true"> |
|
<my-i18n msgid="im_loading_history"></my-i18n><span my-loading-dots></span> |
|
</div> |
|
|
|
<div ng-show="state.loaded"> |
|
<div my-history class="im_history_col"> |
|
|
|
<div class="im_history_panel_wrap"> |
|
|
|
<div class="im_history_panel clearfix" ng-controller="AppImPanelController"> |
|
<div class="im_history_panel_title"> |
|
|
|
<a class="im_history_panel_info_link pull-right" ng-click="showPeerInfo()" my-i18n="im_info"></a> |
|
<a class="im_history_panel_edit_link pull-right" ng-click="toggleEdit()" my-i18n="im_edit"></a> |
|
|
|
<div class="dropdown im_history_panel_media_dropdown pull-right"> |
|
<a class="dropdown-toggle"><my-i18n msgid="im_media"></my-i18n><i class="icon icon-caret"></i></a> |
|
<ul class="dropdown-menu"> |
|
<li><a ng-click="toggleMedia('photos')" my-i18n="im_media_photos"></a></li> |
|
<li><a ng-click="toggleMedia('video')" my-i18n="im_media_video"></a></li> |
|
<li><a ng-click="toggleMedia('documents')" my-i18n="im_media_documents"></a></li> |
|
<li><a ng-click="toggleMedia('audio')" my-i18n="im_media_audio"></a></li> |
|
</ul> |
|
</div> |
|
<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" my-i18n="im_show_recent_messages"></span> |
|
<span ng-switch-default my-i18n="im_show_all_messages"></span> |
|
<strong class="im_history_panel_return_count" ng-show="missedCount > 0" ng-bind="'+' + missedCount"></strong> |
|
</a> |
|
|
|
<div ng-switch="historyFilter.mediaType"> |
|
<h4 ng-switch-when="photos" my-i18n="im_media_photos"></h4> |
|
<h4 ng-switch-when="video" my-i18n="im_media_video"></h4> |
|
<h4 ng-switch-when="documents" my-i18n="im_media_documents"></h4> |
|
<h4 ng-switch-when="audio" my-i18n="im_media_audio"></h4> |
|
|
|
<h4 ng-switch-default ng-switch="historyPeer.id > 0" ng-click="showPeerInfo()"> |
|
<div ng-switch-when="true"> |
|
<span ng-bind-html="historyPeer.data.rFullName"></span> |
|
<small class="im_peer_online" my-user-status="historyPeer.id"></small> |
|
</div> |
|
<div ng-switch-default> |
|
<span ng-bind-html="historyPeer.data.rTitle"></span> |
|
<small class="im_chat_users"> |
|
<ng-pluralize count="historyPeer.data.participants_count" |
|
when="im_pluralize_participants"> |
|
</ng-pluralize> |
|
</small> |
|
</div> |
|
</h4> |
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="im_history_wrap nano"> |
|
|
|
<div class="im_history_scrollable_wrap nano-content"> |
|
|
|
<div class="im_history_scrollable"> |
|
<div class="im_history" ng-class="{im_history_selectable: historyState.selectActions}"> |
|
<div ng-if="state.empty" class="im_history_empty" ng-switch="state.mayBeHasMore" my-vertical-position="0.25" padding="true"> |
|
<span ng-switch-when="true"> |
|
<my-i18n msgid="im_loading_history"></my-i18n><span my-loading-dots></span> |
|
</span> |
|
<span ng-switch-default my-i18n="im_no_messages"></span> |
|
</div> |
|
|
|
<div class="im_history_messages" ng-class="{im_history_messages_group: historyPeer.id < 0}"> |
|
<div class="im_history_messages_peer" ng-show="peerHistory.peerID == historyPeer.id" ng-repeat="peerHistory in peerHistories"> |
|
<div class="im_history_message_wrap" my-message ng-repeat="historyMessage in peerHistory.messages"></div> |
|
</div> |
|
</div> |
|
|
|
</div> |
|
|
|
<div class="im_history_typing_wrap"> |
|
|
|
<div class="im_history_typing" ng-show="historyState.typing.length > 0 && !historyFilter.mediaType" ng-switch="historyState.typing.length" my-i18n> |
|
<span ng-switch-when="1" my-i18n-format="im_one_typing"></span> |
|
<span ng-switch-when="2" my-i18n-format="im_two_typing"></span> |
|
<span ng-switch-default my-i18n-format="im_many_typing"></span> |
|
<my-i18n-param name="name1"><a class="im_history_typing_author" my-user-link="historyState.typing[0]"></a></my-i18n-param> |
|
<my-i18n-param name="name2"><a class="im_history_typing_author" my-user-link="historyState.typing[1]"></a></my-i18n-param> |
|
<my-i18n-param name="count">{{historyState.typing.length - 2}}</my-i18n-param> |
|
<my-i18n-param name="dots"><span my-loading-dots></span></my-i18n-param> |
|
</div> |
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div class="im_bottom_panel_wrap"> |
|
|
|
<div class="im_edit_panel_wrap clearfix" ng-show="historyState.selectActions"> |
|
<div class="im_edit_panel_border"></div> |
|
<a class="im_edit_flush_link" ng-click="selectedFlush()" ng-switch="historyPeer.id > 0"> |
|
<span ng-switch-when="true" my-i18n="im_delete_chat"></span> |
|
<span ng-switch-default my-i18n="im_clear_history"></span> |
|
</a> |
|
<a class="im_edit_cancel_link" ng-click="selectedCancel()" my-i18n="modal_cancel"></a> |
|
<div class="im_edit_selected_actions" my-i18n> |
|
<a class="btn btn-primary im_edit_forward_btn" ng-click="selectedForward()" ng-class="{disabled: !selectedCount}" ng-disabled="!selectedCount" my-i18n-format="im_forward"></a> |
|
<a class="btn btn-danger im_edit_delete_btn" ng-click="selectedDelete()" ng-class="{disabled: !selectedCount}" ng-disabled="!selectedCount" my-i18n-format="im_delete"></a> |
|
<my-i18n-param name="count"><strong class="im_selected_count" ng-show="selectedCount > 0" ng-bind="selectedCount"></strong></my-i18n-param> |
|
</div> |
|
</div> |
|
|
|
<div class="im_send_panel_wrap" ng-hide="historyState.selectActions"> |
|
|
|
<div class="im_send_form_wrap1"> |
|
|
|
<div class="im_send_form_wrap clearfix" ng-controller="AppImSendController"> |
|
<div class="pull-right im_panel_peer_photo" ng-click="showPeerInfo()"> |
|
<img |
|
class="im_panel_peer_photo" |
|
my-load-thumb |
|
watch="true" |
|
thumb="historyPeer.photo" |
|
/> |
|
<i class="icon im_panel_peer_online" ng-show="historyPeer.id > 0 && historyPeer.data.status._ == 'userStatusOnline'"></i> |
|
</div> |
|
<div class="pull-left im_panel_own_photo"> |
|
<img |
|
class="im_panel_own_photo" |
|
my-load-thumb |
|
watch="true" |
|
thumb="ownPhoto" |
|
/> |
|
</div> |
|
<form my-send-form draft-message="draftMessage" class="im_send_form" ng-class="{im_send_form_empty: !draftMessage.text.length}" ng-submit="sendMessage($event)"> |
|
|
|
<div class="im_send_field_wrap"> |
|
<div class="im_send_dropbox_wrap" my-i18n="im_photos_drop_text"></div> |
|
<textarea ng-model="draftMessage.text" placeholder="{{'im_message_field_placeholder' | i18n}}" class="form-control im_message_field no_outline"></textarea> |
|
</div> |
|
|
|
<div class="im_media_attach pull-right"> |
|
<input type="file" class="im_media_attach_input" size="28" multiple="true" accept="image/*, video/*, audio/*" title="{{'im_media_attach_title' | i18n}}"/> |
|
<i class="icon icon-camera"></i> |
|
</div> |
|
|
|
<div class="im_attach pull-right"> |
|
<input type="file" class="im_attach_input" size="28" multiple="true" title="{{'im_attach_file_title' | i18n}}" /> |
|
<i class="icon icon-paperclip"></i> |
|
</div> |
|
|
|
<div class="im_emoji_btn pull-right" title="{{'im_emoji_btn_title' | i18n}}"> |
|
<i class="icon icon-emoji"></i> |
|
</div> |
|
|
|
<button type="submit" class="btn btn-success im_submit"> |
|
<span class="im_submit_text" my-i18n="im_submit_message"></span> |
|
</button> |
|
</form> |
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div my-lang-footer></div> |