Browse Source

Supported pinned messages

Closes #1088
master
Igor Zhukov 7 years ago
parent
commit
77630dcf5c
  1. 10
      app/js/controllers.js
  2. 64
      app/js/directives.js
  3. 8
      app/js/directives_mobile.js
  4. 3
      app/js/lib/utils.js
  5. 2
      app/js/messages_manager.js
  6. 129
      app/js/services.js
  7. 36
      app/less/app.less
  8. 4
      app/partials/desktop/channel_modal.html
  9. 3
      app/partials/desktop/im.html
  10. 4
      app/partials/desktop/peer_pinned_message_bar.html
  11. 4
      app/partials/mobile/channel_modal.html
  12. 8
      app/partials/mobile/im.html

10
app/js/controllers.js

@ -3793,8 +3793,6 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -3793,8 +3793,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.needMigrate = true
}
NotificationsManager.savePeerSettings(-$scope.chatID, chatFull.notify_settings)
NotificationsManager.getPeerMuted(-$scope.chatID).then(function (muted) {
$scope.settings.notifications = !muted
@ -3953,8 +3951,6 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -3953,8 +3951,6 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.chatFull = AppChatsManager.wrapForFull($scope.chatID, chatFull)
$scope.$broadcast('ui_height')
NotificationsManager.savePeerSettings(-$scope.chatID, chatFull.notify_settings)
NotificationsManager.getPeerMuted(-$scope.chatID).then(function (muted) {
$scope.settings.notifications = !muted
@ -3983,6 +3979,12 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -3983,6 +3979,12 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
})
AppProfileManager.getChannelParticipants($scope.chatID).then(function (participants) {
$scope.participants = AppChatsManager.wrapParticipants($scope.chatID, participants)
$scope.$broadcast('ui_height')
})
function onChatUpdated (updates) {
ApiUpdatesManager.processUpdateMessage(updates)
$rootScope.$broadcast('history_focus', {peerString: $scope.chatFull.peerString})

64
app/js/directives.js

@ -586,6 +586,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -586,6 +586,7 @@ angular.module('myApp.directives', ['myApp.filters'])
function checkMessage ($scope, element, mid, isEdit) {
var message = $scope.replyMessage = AppMessagesManager.wrapSingleMessage(mid)
$scope.thumb = false
$scope.isEdit = isEdit || false
if (message.loading) {
var stopWaiting = $scope.$on('messages_downloaded', function (e, mids) {
@ -668,6 +669,60 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -668,6 +669,60 @@ angular.module('myApp.directives', ['myApp.filters'])
}
})
.directive('myPeerPinnedMessageBar', function (AppMessagesManager, AppPeersManager, AppProfileManager) {
return {
templateUrl: templateUrl('peer_pinned_message_bar'),
scope: {},
link: link
}
function updatePeerID(peerID, $scope, force) {
if (force) {
$scope.pinnedMessageID = 0
$scope.$emit('ui_height')
}
if (!AppPeersManager.isChannel(peerID)) {
return
}
var channelID = -peerID
var jump = ++$scope.jump
AppProfileManager.getChannelPinnedMessage(channelID).then(function (pinnedMessageID) {
if (jump != $scope.jump) {
return
}
$scope.pinnedMessageID = pinnedMessageID || 0
$scope.$emit('ui_height')
})
}
function link ($scope, element, attrs) {
$scope.jump = 0
$scope.$parent.$watch(attrs.myPeerPinnedMessageBar, function (peerID) {
$scope.peerID = peerID
updatePeerID(peerID, $scope, true)
})
$scope.$on('peer_pinned_message', function (e, updPeerID) {
if (updPeerID == $scope.peerID) {
updatePeerID($scope.peerID, $scope)
}
})
$scope.$on('chat_full_update', function (e, updChatID) {
if (updChatID == -$scope.peerID) {
updatePeerID($scope.peerID, $scope)
}
})
$scope.hidePinned = function () {
AppProfileManager.hideChannelPinnedMessage(-$scope.peerID, $scope.pinnedMessageID)
$scope.pinnedMessageID = 0
$scope.$emit('ui_height')
}
}
})
.directive('myForwardedMessages', function (AppPhotosManager, AppMessagesManager, AppPeersManager, $rootScope) {
return {
templateUrl: templateUrl('forwarded_messages'),
@ -1213,6 +1268,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1213,6 +1268,7 @@ angular.module('myApp.directives', ['myApp.filters'])
var scrollableWrap = $('.im_history_scrollable_wrap', element)[0]
var scrollable = $('.im_history_scrollable', element)[0]
var emptyWrapEl = $('.im_history_empty_wrap', element)[0]
var pinnedPanelEl = $('.im_history_pinned_panel', element)[0]
var bottomPanelWrap = $('.im_bottom_panel_wrap', element)[0]
var sendFormWrap = $('.im_send_form_wrap', element)[0]
var headWrap = $('.tg_page_head')[0]
@ -1545,11 +1601,17 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1545,11 +1601,17 @@ angular.module('myApp.directives', ['myApp.filters'])
if (!footer || !footer.offsetHeight) {
footer = $('.footer_wrap')[0]
}
if (!pinnedPanelEl || !pinnedPanelEl.offsetHeight) {
pinnedPanelEl = $('.im_history_pinned_panel', element)[0]
}
var footerHeight = footer ? footer.offsetHeight : 0
if (footerHeight) {
footerHeight++ // Border bottom
}
var historyH = $($window).height() - bottomPanelWrap.offsetHeight - (headWrap ? headWrap.offsetHeight : 48) - footerHeight
var pinnedHeight = pinnedPanelEl && pinnedPanelEl.offsetHeight || 0
var historyH = $($window).height() - bottomPanelWrap.offsetHeight - (headWrap ? headWrap.offsetHeight : 48) - footerHeight - pinnedHeight
$(historyWrap).css({
height: historyH
})

8
app/js/directives_mobile.js

@ -105,6 +105,7 @@ angular.module('myApp.directives') @@ -105,6 +105,7 @@ angular.module('myApp.directives')
var bottomPanelWrap = $('.im_bottom_panel_wrap', element)[0]
var sendFormWrap = $('.im_send_form_wrap', element)[0]
var headWrap = $('.tg_page_head')[0]
var pinnedPanelEl = $('.im_history_pinned_panel', element)[0]
var sendForm = $('.im_send_form', element)[0]
var moreNotified = false
var lessNotified = false
@ -306,7 +307,12 @@ angular.module('myApp.directives') @@ -306,7 +307,12 @@ angular.module('myApp.directives')
if (!headWrap || !headWrap.offsetHeight) {
headWrap = $('.tg_page_head')[0]
}
var historyH = $($window).height() - bottomPanelWrap.offsetHeight - (headWrap ? headWrap.offsetHeight : 46)
if (!pinnedPanelEl || !pinnedPanelEl.offsetHeight) {
pinnedPanelEl = $('.im_history_pinned_panel', element)[0]
}
var pinnedHeight = pinnedPanelEl && pinnedPanelEl.offsetHeight || 0
var historyH = $($window).height() - bottomPanelWrap.offsetHeight - (headWrap ? headWrap.offsetHeight : 46) - pinnedHeight
$(historyWrap).css({
height: historyH
})

3
app/js/lib/utils.js

@ -393,7 +393,8 @@ function templateUrl (tplName) { @@ -393,7 +393,8 @@ function templateUrl (tplName) {
channel_edit_modal: 'desktop',
megagroup_edit_modal: 'desktop',
inline_results: 'desktop',
composer_dropdown: 'desktop'
composer_dropdown: 'desktop',
peer_pinned_message_bar: 'desktop'
}
var layout = forceLayout[tplName] || (Config.Mobile ? 'mobile' : 'desktop')
return 'partials/' + layout + '/' + tplName + '.html'

2
app/js/messages_manager.js

@ -2365,7 +2365,7 @@ angular.module('myApp.services') @@ -2365,7 +2365,7 @@ angular.module('myApp.services')
}
if (message.message && message.message.length) {
message.richMessage = RichTextProcessor.wrapRichText(message.message.substr(0, 64), {noLinks: true, noLinebreaks: true})
message.richMessage = RichTextProcessor.wrapRichText(message.message.substr(0, 128), {noLinks: true, noLinebreaks: true})
}
message.dateText = dateOrTimeFilter(message.date)

129
app/js/services.js

@ -773,45 +773,51 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -773,45 +773,51 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
var chatFull = angular.copy(fullChat)
var chat = getChat(id)
console.warn(chat, chatFull)
if (!chatFull.participants_count) {
chatFull.participants_count = chat.participants_count
}
if (chatFull.participants && chatFull.participants._ == 'chatParticipants') {
MtpApiManager.getUserID().then(function (myID) {
var isAdmin = chat.pFlags.creator || chat.pFlags.admins_enabled && chat.pFlags.admin
angular.forEach(chatFull.participants.participants, function (participant) {
participant.canLeave = myID == participant.user_id
participant.canKick = !participant.canLeave && (
chat.pFlags.creator ||
participant._ == 'chatParticipant' && (isAdmin || myID == participant.inviter_id)
)
if (chatFull.participants &&
chatFull.participants._ == 'chatParticipants') {
chatFull.participants.participants = wrapParticipants(id, chatFull.participants.participants)
}
// just for order by last seen
participant.user = AppUsersManager.getUser(participant.user_id)
})
})
if (chatFull.about) {
chatFull.rAbout = RichTextProcessor.wrapRichText(chatFull.about, {noLinebreaks: true})
}
if (chatFull.participants && chatFull.participants._ == 'channelParticipants') {
chatFull.peerString = getChatString(id)
chatFull.chat = chat
return chatFull
}
function wrapParticipants(id, participants) {
var chat = getChat(id)
if (isChannel(id)) {
var isAdmin = chat.pFlags.creator || chat.pFlags.editor || chat.pFlags.moderator
angular.forEach(chatFull.participants.participants, function (participant) {
angular.forEach(participants, function (participant) {
participant.canLeave = participant._ == 'channelParticipantSelf'
participant.canKick = isAdmin && participant._ == 'channelParticipant'
// just for order by last seen
participant.user = AppUsersManager.getUser(participant.user_id)
})
}
} else {
var myID = AppUsersManager.getSelf().id
var isAdmin = chat.pFlags.creator || chat.pFlags.admins_enabled && chat.pFlags.admin
angular.forEach(participants, function (participant) {
participant.canLeave = myID == participant.user_id
participant.canKick = !participant.canLeave && (
chat.pFlags.creator ||
participant._ == 'chatParticipant' && (isAdmin || myID == participant.inviter_id)
)
if (chatFull.about) {
chatFull.rAbout = RichTextProcessor.wrapRichText(chatFull.about, {noLinebreaks: true})
// just for order by last seen
participant.user = AppUsersManager.getUser(participant.user_id)
})
}
chatFull.peerString = getChatString(id)
chatFull.chat = chat
return chatFull
return participants
}
function openChat (chatID, accessHash) {
@ -862,6 +868,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -862,6 +868,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
resolveUsername: resolveUsername,
hasChat: hasChat,
wrapForFull: wrapForFull,
wrapParticipants: wrapParticipants,
openChat: openChat
}
})
@ -1042,7 +1049,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1042,7 +1049,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}
})
.service('AppProfileManager', function ($q, $rootScope, AppUsersManager, AppChatsManager, AppPeersManager, AppPhotosManager, NotificationsManager, MtpApiManager, ApiUpdatesManager, RichTextProcessor) {
.service('AppProfileManager', function ($q, $rootScope, AppUsersManager, AppChatsManager, AppMessagesIDsManager, AppPeersManager, AppPhotosManager, NotificationsManager, MtpApiManager, ApiUpdatesManager, RichTextProcessor, Storage) {
var botInfos = {}
var chatsFull = {}
var chatFullPromises = {}
@ -1191,6 +1198,14 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1191,6 +1198,14 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
var promiseKey = [id, filter._, offset, limit].join('_')
var promiseData = chatParticipantsPromises[promiseKey]
if (filter._ == 'channelParticipantsRecent') {
var chat = AppChatsManager.getChat(id)
if (chat.pFlags.kicked ||
chat.pFlags.broadcast && !chat.pFlags.creator && !chat.admin_rights) {
return $q.reject()
}
}
var fetchParticipants = function (cachedParticipants) {
var hash = 0
if (cachedParticipants) {
@ -1279,32 +1294,21 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1279,32 +1294,21 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
AppChatsManager.saveApiChats(result.chats)
AppUsersManager.saveApiUsers(result.users)
var fullChannel = result.full_chat
var chat = AppChatsManager.getChat(id)
if (fullChannel && fullChannel.chat_photo.id) {
AppPhotosManager.savePhoto(fullChannel.chat_photo)
}
NotificationsManager.savePeerSettings(-id, fullChannel.notify_settings)
var participantsPromise
if (fullChannel.flags & 8) {
participantsPromise = getChannelParticipants(id).then(function (participants) {
delete chatFullPromises[id]
fullChannel.participants = {
_: 'channelParticipants',
participants: participants
}
}, function (error) {
error.handled = true
})
} else {
participantsPromise = $q.when()
if (fullChannel.pinned_msg_id) {
fullChannel.pinned_msg_id = AppMessagesIDsManager.getFullMessageID(fullChannel.pinned_msg_id, id)
}
return participantsPromise.then(function () {
delete chatFullPromises[id]
chatsFull[id] = fullChannel
$rootScope.$broadcast('chat_full_update', id)
return fullChannel
})
delete chatFullPromises[id]
chatsFull[id] = fullChannel
$rootScope.$broadcast('chat_full_update', id)
return fullChannel
}, function (error) {
switch (error.type) {
case 'CHANNEL_PRIVATE':
@ -1325,6 +1329,28 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1325,6 +1329,28 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
})
}
function getChannelPinnedMessage(id) {
return getChannelFull(id).then(function (fullChannel) {
var pinnedMessageID = fullChannel && fullChannel.pinned_msg_id
if (!pinnedMessageID) {
return false
}
return Storage.get('pinned_hidden' + id).then(function (hiddenMessageID) {
if (AppMessagesIDsManager.getMessageLocalID(pinnedMessageID) == hiddenMessageID) {
return false
}
return pinnedMessageID
})
})
}
function hideChannelPinnedMessage(id, pinnedMessageID) {
var setKeys = {}
setKeys['pinned_hidden' + id] = AppMessagesIDsManager.getMessageLocalID(pinnedMessageID)
Storage.set(setKeys)
$rootScope.$broadcast('peer_pinned_message', -id)
}
$rootScope.$on('apiUpdate', function (e, update) {
// console.log('on apiUpdate', update)
switch (update._) {
@ -1372,6 +1398,15 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1372,6 +1398,15 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
}
break
case 'updateChannelPinnedMessage':
var channelID = update.channel_id
var fullChannel = chatsFull[channelID]
if (fullChannel !== undefined) {
fullChannel.pinned_msg_id = AppMessagesIDsManager.getFullMessageID(update.id, channelID)
$rootScope.$broadcast('peer_pinned_message', -channelID)
}
break
}
})
@ -1404,7 +1439,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1404,7 +1439,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
getChatInviteLink: getChatInviteLink,
getChatFull: getChatFull,
getChannelFull: getChannelFull,
getChannelParticipants: getChannelParticipants
getChannelParticipants: getChannelParticipants,
getChannelPinnedMessage: getChannelPinnedMessage,
hideChannelPinnedMessage: hideChannelPinnedMessage
}
})

36
app/less/app.less

@ -1499,6 +1499,42 @@ a.im_dialog_selected { @@ -1499,6 +1499,42 @@ a.im_dialog_selected {
}
}
.im_history_pinned_wrap {
padding: 7px 10px 7px 20px;
border-bottom: 1px solid #E9EBED;
}
.im_history_pinned_message {
cursor: pointer;
}
.im_history_pinned_message:hover {
text-decoration: none;
}
.im_history_pinned_hide {
float: right;
display: block;
width: 18px;
height: 18px;
margin-right: 6px;
margin-top: 11px;
-webkit-transform: translate3d(0, 0, 0);
padding-top: 7px;
.icon-reply-bar {
display: block;
background: #999;
width: 18px;
height: 2px;
transform-origin: 50% 50%;
}
&:hover {
.icon-reply-bar {
background: #44a1e8;
}
}
}
.im_history {
// padding: 20px 0 0 0;
padding: 0;

4
app/partials/desktop/channel_modal.html

@ -126,7 +126,7 @@ @@ -126,7 +126,7 @@
</div>
<div ng-if="chatFull.participants.participants.length > 0">
<div ng-if="participants.length > 0">
<div class="md_modal_section_splitter"></div>
@ -135,7 +135,7 @@ @@ -135,7 +135,7 @@
<div class="md_modal_section_peers_wrap">
<div class="md_modal_list_peer_wrap clearfix" ng-repeat="participant in chatFull.participants.participants">
<div class="md_modal_list_peer_wrap clearfix" ng-repeat="participant in participants">
<a ng-if="participant.canLeave" ng-click="leaveChannel()" class="md_modal_list_peer_action pull-right" my-i18n="group_modal_menu_leave"></a>
<a ng-if="participant.canKick" ng-click="kickFromChannel(participant.user_id)" class="md_modal_list_peer_action pull-right" my-i18n="group_modal_members_kick"></a>

3
app/partials/desktop/im.html

@ -92,8 +92,6 @@ @@ -92,8 +92,6 @@
<span ng-switch-when="true" class="im_dialog_message_text" my-user-status="::foundPeer.id"></span>
<span ng-switch-default class="im_dialog_message_text" my-chat-status="::-foundPeer.id"></span>
</span>
<!-- <div class="im_dialog_message">
</div> -->
</div>
</div>
</a>
@ -130,6 +128,7 @@ @@ -130,6 +128,7 @@
<div class="im_history_selected_wrap">
<div my-history class="im_history_col">
<div my-peer-pinned-message-bar="curDialog.peerID" class="im_history_pinned_panel"></div>
<div class="im_history_wrap nano">

4
app/partials/desktop/peer_pinned_message_bar.html

@ -0,0 +1,4 @@ @@ -0,0 +1,4 @@
<div class="im_history_pinned_wrap" ng-if="pinnedMessageID > 0">
<a class="im_history_pinned_hide" ng-mousedown="hidePinned()"><i class="icon icon-reply-bar"></i><i class="icon icon-reply-bar"></i></a>
<a class="im_history_pinned_message" my-reply-message="pinnedMessageID" watch="true"></a>
</div>

4
app/partials/mobile/channel_modal.html

@ -132,13 +132,13 @@ @@ -132,13 +132,13 @@
</a>
</div>
<div class="mobile_modal_section" ng-if="chatFull.participants.participants.length > 0">
<div class="mobile_modal_section" ng-if="participants.length > 0">
<h4 class="mobile_modal_section_header" my-i18n="group_modal_members"></h4>
<div class="mobile_modal_section_body">
<div class="chat_modal_members_list">
<div class="chat_modal_participant_wrap clearfix" ng-repeat="participant in chatFull.participants.participants | orderBy:'-user.sortStatus'">
<div class="chat_modal_participant_wrap clearfix" ng-repeat="participant in participants | orderBy:'-user.sortStatus'">
<a ng-if="participant.canLeave" ng-click="leaveChannel()" class="chat_modal_participant_kick pull-right" my-i18n="group_modal_menu_leave"></a>
<a ng-if="participant.canKick" ng-click="kickFromChannel(participant.user_id)" class="chat_modal_participant_kick pull-right" my-i18n="group_modal_members_kick"></a>

8
app/partials/mobile/im.html

@ -58,7 +58,11 @@ @@ -58,7 +58,11 @@
<span class="im_dialog_user" my-peer-link="foundPeer.id" verified="true"></span>
</div>
<div class="im_dialog_message">
<span class="im_dialog_message_text" ng-bind="::'@' + foundPeer.username"></span>
<span class="im_dialog_message_text" ng-switch="foundPeer.id > 0">
<span ng-bind="::'@' + foundPeer.username + ', '"></span>
<span ng-switch-when="true" class="im_dialog_message_text" my-user-status="::foundPeer.id"></span>
<span ng-switch-default class="im_dialog_message_text" my-chat-status="::-foundPeer.id"></span>
</span>
</div>
</div>
</a>
@ -85,6 +89,8 @@ @@ -85,6 +89,8 @@
<div class="im_history_selected_wrap">
<div my-history-mobile class="im_history_col">
<div my-peer-pinned-message-bar="curDialog.peerID" class="im_history_pinned_panel"></div>
<div class="im_history_wrap im_history_scrollable_wrap mobile_scrollable_wrap">
<div class="im_history_scrollable">

Loading…
Cancel
Save