Browse Source

Support edit messages

Closes #1155
master
Igor Zhukov 8 years ago
parent
commit
5e855779b9
  1. 178
      app/js/controllers.js
  2. 61
      app/js/directives.js
  3. 5
      app/js/locales/en-us.json
  4. 8
      app/js/message_composer.js
  5. 132
      app/js/messages_manager.js
  6. 15
      app/js/services.js
  7. 9
      app/less/app.less
  8. 8
      app/less/desktop.less
  9. 4
      app/less/mobile.less
  10. 8
      app/partials/desktop/im.html
  11. 5
      app/partials/desktop/message.html
  12. 5
      app/partials/desktop/reply_message.html
  13. 4
      app/partials/mobile/im.html
  14. 5
      app/partials/mobile/message.html
  15. 1
      app/partials/mobile/message_actions_modal.html

178
app/js/controllers.js

@ -502,6 +502,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -502,6 +502,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
channelActions: false,
canReply: false,
canDelete: false,
canEdit: false,
actions: function () {
return $scope.historyState.selectActions ? 'selected' : ($scope.historyState.botActions ? 'bot' : ($scope.historyState.channelActions ? 'channel' : false))
},
@ -1130,6 +1131,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -1130,6 +1131,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.selectedDelete = selectedDelete
$scope.selectedForward = selectedForward
$scope.selectedReply = selectedReply
$scope.selectedEdit = selectedEdit
$scope.selectedCancel = selectedCancel
$scope.selectedFlush = selectedFlush
$scope.selectInlineBot = selectInlineBot
@ -1610,8 +1612,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -1610,8 +1612,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
if (target.className &&
target.className.indexOf('im_message_date') != -1) {
if (AppPeersManager.isChannel(peerID) &&
!AppPeersManager.isMegagroup(peerID)) {
if (AppPeersManager.isBroadcast(peerID)) {
quickForward(messageID)
} else {
selectedReply(messageID)
@ -1630,6 +1631,8 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -1630,6 +1631,8 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
if (Config.Mobile) {
$scope.historyState.canEdit = AppMessagesManager.canEditMessage(messageID)
$modal.open({
templateUrl: templateUrl('message_actions_modal'),
windowClass: 'message_actions_modal_window',
@ -1640,6 +1643,10 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -1640,6 +1643,10 @@ angular.module('myApp.controllers', ['myApp.i18n'])
selectedReply(messageID)
break
case 'edit':
selectedEdit(messageID)
break
case 'delete':
selectedDelete(messageID)
break
@ -1704,6 +1711,11 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -1704,6 +1711,11 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$broadcast('ui_panel_update')
}
}
if ($scope.selectedCount == 1) {
angular.forEach($scope.selectedMsgs, function (t, messageID) {
$scope.historyState.canEdit = AppMessagesManager.canEditMessage(messageID)
})
}
$scope.$broadcast('messages_select')
}
@ -1813,6 +1825,18 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -1813,6 +1825,18 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
}
function selectedEdit (selectedMessageID) {
if (!selectedMessageID && $scope.selectedCount == 1) {
angular.forEach($scope.selectedMsgs, function (t, messageID) {
selectedMessageID = messageID
})
}
if (selectedMessageID) {
selectedCancel()
$scope.$broadcast('edit_selected', selectedMessageID)
}
}
function toggleEdit () {
if ($scope.historyState.selectActions) {
selectedCancel()
@ -2202,13 +2226,18 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2202,13 +2226,18 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$on('reply_selected', function (e, messageID) {
replySelect(messageID, true)
})
$scope.$on('edit_selected', function (e, messageID) {
setEditDraft(messageID, true)
})
$scope.$on('ui_typing', onTyping)
$scope.draftMessage = {
text: '',
send: sendMessage,
send: submitMessage,
replyClear: replyClear,
fwdsClear: fwdsClear
fwdsClear: fwdsClear,
type: 'new'
}
$scope.mentions = {}
$scope.commands = {}
@ -2232,6 +2261,8 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2232,6 +2261,8 @@ angular.module('myApp.controllers', ['myApp.i18n'])
$scope.$on('inline_bots_popular', updateMentions)
$scope.$on('last_message_edit', setEditLastMessage)
$scope.replyKeyboardToggle = replyKeyboardToggle
$scope.toggleSlash = toggleSlash
@ -2257,38 +2288,58 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2257,38 +2288,58 @@ angular.module('myApp.controllers', ['myApp.i18n'])
var replyToMarkup = false
var forceDraft = false
var editMessageID = false
function sendMessage (e) {
function submitMessage (e) {
$scope.$broadcast('ui_message_before_send')
$timeout(function () {
var text = $scope.draftMessage.text
if (editMessageID) {
editMessage()
} else {
sendMessage()
}
})
if (angular.isString(text) && text.length > 0) {
text = RichTextProcessor.parseEmojis(text)
return cancelEvent(e)
}
var options = {
replyToMsgID: $scope.draftMessage.replyToMsgID,
clearDraft: true
}
do {
AppMessagesManager.sendText($scope.curDialog.peerID, text.substr(0, 4096), options)
text = text.substr(4096)
options = angular.copy(options)
delete options.clearDraft
} while (text.length)
}
fwdsSend()
function sendMessage() {
var text = $scope.draftMessage.text
if (forceDraft == $scope.curDialog.peer) {
forceDraft = false
if (angular.isString(text) && text.length > 0) {
text = RichTextProcessor.parseEmojis(text)
var options = {
replyToMsgID: $scope.draftMessage.replyToMsgID,
clearDraft: true
}
do {
AppMessagesManager.sendText($scope.curDialog.peerID, text.substr(0, 4096), options)
text = text.substr(4096)
options = angular.copy(options)
delete options.clearDraft
} while (text.length)
}
fwdsSend()
if (forceDraft == $scope.curDialog.peer) {
forceDraft = false
}
resetDraft()
$scope.$broadcast('ui_message_send')
}
function editMessage() {
var text = $scope.draftMessage.text
AppMessagesManager.editMessage(editMessageID, text).then(function () {
editMessageID = false
resetDraft()
$scope.$broadcast('ui_message_send')
})
return cancelEvent(e)
}
function updateMentions () {
@ -2402,6 +2453,8 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2402,6 +2453,8 @@ angular.module('myApp.controllers', ['myApp.i18n'])
return
}
editMessageID = false
updateMentions()
updateCommands()
replyClear()
@ -2413,7 +2466,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2413,7 +2466,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
// console.log(dT(), 'reset draft', $scope.curDialog.peer, forceDraft)
if (forceDraft) {
if (forceDraft == $scope.curDialog.peer) {
$scope.draftMessage.isBroadcast = AppPeersManager.isChannel($scope.curDialog.peerID) && !AppPeersManager.isMegagroup($scope.curDialog.peerID)
$scope.draftMessage.isBroadcast = AppPeersManager.isBroadcast($scope.curDialog.peerID)
$scope.$broadcast('ui_peer_draft')
return
} else {
@ -2427,9 +2480,25 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2427,9 +2480,25 @@ angular.module('myApp.controllers', ['myApp.i18n'])
function getDraft () {
if ($scope.curDialog.peerID) {
DraftsManager.getDraft($scope.curDialog.peerID).then(function (draftData) {
var draftDataPromise
if (editMessageID) {
draftDataPromise = AppMessagesManager.getMessageEditData(editMessageID).then(function (draftData) {
draftData.replyToMsgID = editMessageID
return draftData
}, function (error) {
console.warn(error)
editMessageID = false
getDraft()
return $q.reject()
})
} else {
draftDataPromise = DraftsManager.getDraft($scope.curDialog.peerID)
}
draftDataPromise.then(function (draftData) {
console.warn('draft', editMessageID, draftData)
$scope.draftMessage.type = editMessageID ? 'edit' : 'new'
$scope.draftMessage.text = draftData ? draftData.text : ''
$scope.draftMessage.isBroadcast = AppPeersManager.isChannel($scope.curDialog.peerID) && !AppPeersManager.isMegagroup($scope.curDialog.peerID)
$scope.draftMessage.isBroadcast = AppPeersManager.isBroadcast($scope.curDialog.peerID)
if (draftData.replyToMsgID) {
var replyToMsgID = draftData.replyToMsgID
replySelect(replyToMsgID)
@ -2493,11 +2562,15 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2493,11 +2562,15 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
function replySelect (messageID, byUser) {
if (editMessageID && byUser) {
replyClear()
return
}
$scope.draftMessage.replyToMsgID = messageID
$scope.$broadcast('ui_peer_reply')
replyToMarkup = false
if (byUser) {
if (byUser && !editMessageID) {
DraftsManager.changeDraft($scope.curDialog.peerID, {
text: $scope.draftMessage.text,
replyToMsgID: messageID
@ -2505,7 +2578,33 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2505,7 +2578,33 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
}
function setEditDraft(messageID) {
editMessageID = messageID
getDraft()
}
function setEditLastMessage() {
if (editMessageID ||
!$scope.curDialog.peerID) {
return false
}
AppMessagesManager.getHistory($scope.curDialog.peerID).then(function (historyResult) {
for (var i = 0, messageID; i < historyResult.history.length; i++) {
messageID = historyResult.history[i]
if (AppMessagesManager.canEditMessage(messageID)) {
setEditDraft(messageID)
break
}
}
})
}
function replyClear (byUser) {
if (editMessageID) {
editMessageID = false
getDraft()
return
}
var mid = $scope.draftMessage.replyToMsgID
if (mid &&
$scope.historyState.replyKeyboard &&
@ -2608,16 +2707,18 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2608,16 +2707,18 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
}
if ($scope.curDialog.peerID) {
var replyToMsgID = $scope.draftMessage.replyToMsgID
if (replyToMsgID &&
$scope.historyState.replyKeyboard &&
$scope.historyState.replyKeyboard.mid == replyToMsgID) {
replyToMsgID = 0;
if (!editMessageID) {
var replyToMsgID = $scope.draftMessage.replyToMsgID
if (replyToMsgID &&
$scope.historyState.replyKeyboard &&
$scope.historyState.replyKeyboard.mid == replyToMsgID) {
replyToMsgID = 0;
}
DraftsManager.changeDraft($scope.curDialog.peerID, {
text: newVal,
replyToMsgID: replyToMsgID
})
}
DraftsManager.changeDraft($scope.curDialog.peerID, {
text: newVal,
replyToMsgID: replyToMsgID
})
checkInlinePattern(newVal)
}
}
@ -2685,8 +2786,7 @@ angular.module('myApp.controllers', ['myApp.i18n']) @@ -2685,8 +2786,7 @@ angular.module('myApp.controllers', ['myApp.i18n'])
}
function onTyping () {
if (AppPeersManager.isChannel($scope.curDialog.peerID) &&
!AppPeersManager.isMegagroup($scope.curDialog.peerID)) {
if (AppPeersManager.isBroadcast($scope.curDialog.peerID)) {
return false
}
MtpApiManager.invokeApi('messages.setTyping', {

61
app/js/directives.js

@ -527,16 +527,19 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -527,16 +527,19 @@ angular.module('myApp.directives', ['myApp.filters'])
function link ($scope, element, attrs) {
if (attrs.watch) {
$scope.$parent.$watch(attrs.myReplyMessage, function (mid) {
checkMessage($scope, element, mid)
var isEdit = $scope.$parent.$eval(attrs.edit)
checkMessage($scope, element, mid, isEdit)
})
} else {
var mid = $scope.$parent.$eval(attrs.myReplyMessage)
checkMessage($scope, element, mid)
var isEdit = $scope.$parent.$eval(attrs.edit)
checkMessage($scope, element, mid, isEdit)
}
}
function checkMessage ($scope, element, mid) {
function checkMessage ($scope, element, mid, isEdit) {
var message = $scope.replyMessage = AppMessagesManager.wrapSingleMessage(mid)
$scope.isEdit = isEdit || false
if (message.loading) {
var stopWaiting = $scope.$on('messages_downloaded', function (e, mids) {
if (mids.indexOf(mid) != -1) {
@ -667,6 +670,49 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -667,6 +670,49 @@ angular.module('myApp.directives', ['myApp.filters'])
}
})
.directive('myMessageEdited', function (_, $timeout, AppMessagesManager) {
var editedLabel = _('message_edited')
return {
scope: {},
link: link
}
function link($scope, element, attrs) {
var messageID = $scope.$parent.$eval(attrs.myMessageEdited)
console.log(attrs.myMessageEdited, messageID)
if (checkEdited($scope, element, messageID)) {
$scope.$on('message_edit', function (e, data) {
var messageID = $scope.$parent.$eval(attrs.myMessageEdited)
if (data.mid == messageID) {
checkEdited($scope, element, messageID)
}
})
}
}
function checkEdited($scope, element, messageID) {
var message = AppMessagesManager.getMessage(messageID)
console.warn('check edited', messageID, message.canBeEdited, message.edit_date)
if (!message.canBeEdited) {
$timeout(function () {
$scope.$destroy()
element.remove()
})
return false
}
if (message.edit_date) {
element.html(editedLabel).show()
$timeout(function () {
$scope.$destroy()
})
return false
}
return true
}
})
.directive('myDialogs', function ($modalStack, $transition, $window, $timeout) {
return {
link: link
@ -1528,6 +1574,7 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1528,6 +1574,7 @@ angular.module('myApp.directives', ['myApp.filters'])
mentions: $scope.mentions,
commands: $scope.commands,
onMessageSubmit: onMessageSubmit,
onDirectionKey: onDirectionKey,
onInlineResultSend: onInlineResultSend,
onFilePaste: onFilePaste,
onCommandSend: function (command) {
@ -1601,6 +1648,14 @@ angular.module('myApp.directives', ['myApp.filters']) @@ -1601,6 +1648,14 @@ angular.module('myApp.directives', ['myApp.filters'])
})
}
function onDirectionKey(e) {
if (e.keyCode == 38) {
$scope.$emit('last_message_edit')
return cancelEvent(e)
}
return true
}
function updateValue () {
if (richTextarea) {
composer.onChange()

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

@ -361,6 +361,7 @@ @@ -361,6 +361,7 @@
"message_service_scored_X": "{'one': 'scored {}', 'other': 'scored {}'}",
"message_action_reply": "Reply",
"message_action_edit": "Edit",
"message_action_delete": "Delete",
"message_action_forward": "Forward",
"message_action_select": "Select",
@ -485,6 +486,7 @@ @@ -485,6 +486,7 @@
"im_delete": "Delete {count}",
"im_forward": "Forward {count}",
"im_reply": "Reply",
"im_edit": "Edit",
"im_start": "Start",
"im_channel_join": "+ Join",
"im_channel_mute": "Mute",
@ -501,6 +503,8 @@ @@ -501,6 +503,8 @@
"im_attach_file_title": "Send file",
"im_emoji_btn_title": "Insert emoticon",
"im_submit_message": "Send",
"im_submit_edit_message": "Save",
"im_edit_message_title": "Edit message",
"login_sign_in": "Sign in",
"login_enter_number_description": "Please choose your country and enter your full phone number.",
@ -556,6 +560,7 @@ @@ -556,6 +560,7 @@
"message_forwarded_message": "Forwarded message",
"message_via_bot": "via {bot}",
"message_edited": "edited",
"message_forwarded_message_mobile": "Forwarded from {from}",
"message_forwarded_via_message_mobile": "Forwarded from {from} via {bot}",

8
app/js/message_composer.js

@ -708,6 +708,7 @@ function MessageComposer (textarea, options) { @@ -708,6 +708,7 @@ function MessageComposer (textarea, options) {
this.onTyping = options.onTyping
this.onMessageSubmit = options.onMessageSubmit
this.onDirectionKey = options.onDirectionKey
this.getSendOnEnter = options.getSendOnEnter
this.onFilePaste = options.onFilePaste
this.onCommandSend = options.onCommandSend
@ -941,6 +942,13 @@ MessageComposer.prototype.onKeyEvent = function (e) { @@ -941,6 +942,13 @@ MessageComposer.prototype.onKeyEvent = function (e) {
return cancelEvent(e)
}
}
// Control keys when content is empty
if ([33, 34, 35, 36, 38, 39].indexOf(e.keyCode) != -1 &&
this.richTextareaEl &&
!this.richTextareaEl[0].textContent.length) {
return this.onDirectionKey(e)
}
}
}

132
app/js/messages_manager.js

@ -877,6 +877,64 @@ angular.module('myApp.services') @@ -877,6 +877,64 @@ angular.module('myApp.services')
return messagesStorage[messageID] || {deleted: true}
}
function canMessageBeEdited(message) {
var goodMedias = ['messageMediaPhoto', 'messageMediaDocument', 'messageMediaWebPage', 'messageMediaPending']
if (message._ != 'message' ||
message.deleted ||
message.fwd_from ||
message.via_bot_id ||
message.media && goodMedias.indexOf(message.media._) == -1 ||
message.fromID && AppUsersManager.isBot(message.fromID)) {
return false
}
return true
}
function canEditMessage(messageID) {
if (messageID <= 0 ||
!messagesStorage[messageID]) {
return false
}
var message = messagesStorage[messageID]
if (!message ||
!message.canBeEdited ||
!message.pFlags.out ||
message.date < tsNow(true) - 2 * 86400) {
return false
}
return true
}
function getMessageEditData(messageID) {
if (!canEditMessage(messageID)) {
return $q.reject()
}
var message = getMessage(messageID)
if (message.media &&
message.media._ != 'messageMediaEmpty' &&
message.media._ != 'messageMediaWebPage') {
return $q.when({
caption: true,
text: typeof message.media.caption === 'string' ? message.media.caption : ''
})
}
var text = typeof message.message === 'string' ? message.message : ''
var entities = RichTextProcessor.parseEntities(text)
var serverEntities = message.entities || []
entities = RichTextProcessor.mergeEntities(entities, serverEntities)
text = RichTextProcessor.wrapDraftText(text, {entities: entities})
return $q.when({
caption: false,
text: text
})
}
function deleteMessages (messageIDs) {
var splitted = AppMessagesIDsManager.splitMessageIDsByChannels(messageIDs)
var promises = []
@ -1126,7 +1184,7 @@ angular.module('myApp.services') @@ -1126,7 +1184,7 @@ angular.module('myApp.services')
var peerID = getMessagePeer(apiMessage)
var isChannel = apiMessage.to_id._ == 'peerChannel'
var channelID = isChannel ? -peerID : 0
var isBroadcast = isChannel && !AppChatsManager.isMegagroup(channelID)
var isBroadcast = isChannel && AppChatsManager.isBroadcast(channelID)
var mid = AppMessagesIDsManager.getFullMessageID(apiMessage.id, channelID)
apiMessage.mid = mid
@ -1266,6 +1324,8 @@ angular.module('myApp.services') @@ -1266,6 +1324,8 @@ angular.module('myApp.services')
apiMessage.totalEntities = RichTextProcessor.mergeEntities(myEntities, apiEntities, !apiMessage.pending)
}
apiMessage.canBeEdited = canMessageBeEdited(apiMessage)
if (!options.isEdited) {
messagesStorage[mid] = apiMessage
}
@ -1285,18 +1345,7 @@ angular.module('myApp.services') @@ -1285,18 +1345,7 @@ angular.module('myApp.services')
return
}
var sendEntites = entities
if (entities.length) {
sendEntites = angular.copy(entities)
angular.forEach(sendEntites, function (entity) {
if (entity._ == 'messageEntityMentionName') {
entity._ = 'inputMessageEntityMentionName'
entity.user_id = AppUsersManager.getUserInput(entity.user_id)
}
})
}
var sendEntites = getInputEntities(entities)
var messageID = tempID--
var randomID = [nextRandomInt(0xFFFFFFFF), nextRandomInt(0xFFFFFFFF)]
var randomIDS = bigint(randomID[0]).shiftLeft(32).add(bigint(randomID[1])).toString()
@ -2038,6 +2087,51 @@ angular.module('myApp.services') @@ -2038,6 +2087,51 @@ angular.module('myApp.services')
return false
}
function getInputEntities(entities) {
var sendEntites = angular.copy(entities)
angular.forEach(sendEntites, function (entity) {
if (entity._ == 'messageEntityMentionName') {
entity._ = 'inputMessageEntityMentionName'
entity.user_id = AppUsersManager.getUserInput(entity.user_id)
}
})
return sendEntites
}
function editMessage(messageID, text) {
if (!angular.isString(text) ||
!canEditMessage(messageID)) {
return $q.reject()
}
var entities = []
text = RichTextProcessor.parseMarkdown(text, entities)
var message = getMessage(messageID)
var peerID = getMessagePeer(message)
var flags = 8 | (1 << 11)
return MtpApiManager.invokeApi('messages.editMessage', {
flags: flags,
peer: AppPeersManager.getInputPeerByID(peerID),
id: AppMessagesIDsManager.getMessageLocalID(messageID),
message: text,
entities: getInputEntities(entities)
}).then(function (updates) {
ApiUpdatesManager.processUpdateMessage(updates)
}, function (error) {
if (error &&
error.type == 'MESSAGE_NOT_MODIFIED') {
error.handled = true
return
}
if (error &&
error.type == 'MESSAGE_EMPTY') {
error.handled = true
}
return $q.reject(error)
})
}
function getMessagePeer (message) {
var toID = message.to_id && AppPeersManager.getPeerID(message.to_id) || 0
@ -2250,9 +2344,11 @@ angular.module('myApp.services') @@ -2250,9 +2344,11 @@ angular.module('myApp.services')
var fromUser = message.from_id && AppUsersManager.getUser(message.from_id)
var fromBot = fromUser && fromUser.pFlags.bot && fromUser.username || false
var toPeerID = AppPeersManager.getPeerID(message.to_id)
var withBot = (fromBot ||
toPeerID < 0 && !(AppChatsManager.isChannel(-toPeerID) && !AppChatsManager.isMegagroup(-toPeerID)) ||
toPeerID > 0 && AppUsersManager.isBot(toPeerID))
var withBot = (
fromBot ||
AppPeersManager.isBot(toPeerID) ||
AppPeersManager.isAnyGroup(toPeerID)
)
var options = {
noCommands: !withBot,
@ -3258,10 +3354,14 @@ angular.module('myApp.services') @@ -3258,10 +3354,14 @@ angular.module('myApp.services')
forwardMessages: forwardMessages,
startBot: startBot,
shareGame: shareGame,
editMessage: editMessage,
convertMigratedPeer: convertMigratedPeer,
getMessagePeer: getMessagePeer,
getMessageThumb: getMessageThumb,
getMessageShareLink: getMessageShareLink,
canMessageBeEdited: canMessageBeEdited,
canEditMessage: canEditMessage,
getMessageEditData: getMessageEditData,
clearDialogCache: clearDialogCache,
wrapForDialog: wrapForDialog,
wrapForHistory: wrapForHistory,

15
app/js/services.js

@ -709,6 +709,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -709,6 +709,10 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
return false
}
function isBroadcast (id) {
return isChannel(id) && !isMegagroup(id)
}
function getChatInput (id) {
return id || 0
}
@ -827,6 +831,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -827,6 +831,7 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
getChat: getChat,
isChannel: isChannel,
isMegagroup: isMegagroup,
isBroadcast: isBroadcast,
hasRights: hasRights,
saveChannelAccess: saveChannelAccess,
saveIsMegagroup: saveIsMegagroup,
@ -987,6 +992,14 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -987,6 +992,14 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
return (peerID < 0) && AppChatsManager.isMegagroup(-peerID)
}
function isAnyGroup (peerID) {
return (peerID < 0) && !AppChatsManager.isBroadcast(-peerID)
}
function isBroadcast (id) {
return isChannel(id) && !isMegagroup(id)
}
function isBot (peerID) {
return (peerID > 0) && AppUsersManager.isBot(peerID)
}
@ -1002,7 +1015,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils']) @@ -1002,7 +1015,9 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
getPeerPhoto: getPeerPhoto,
resolveUsername: resolveUsername,
isChannel: isChannel,
isAnyGroup: isAnyGroup,
isMegagroup: isMegagroup,
isBroadcast: isBroadcast,
isBot: isBot
}
})

9
app/less/app.less

@ -2103,7 +2103,11 @@ img.im_message_document_thumb { @@ -2103,7 +2103,11 @@ img.im_message_document_thumb {
padding: 0 0 20px 10px;
}
.im_message_date {
.im_message_edited {
display: none;
}
.im_message_date_text {
cursor: pointer;
&:hover {
text-decoration: underline;
@ -3908,7 +3912,8 @@ ul.chat_modal_migrate_list { @@ -3908,7 +3912,8 @@ ul.chat_modal_migrate_list {
.audio_player_size,
.im_message_fwd_date,
.im_message_views_cnt,
.im_message_sign_link {
.im_message_sign_link,
.im_message_edited {
color: #899daf;
}

8
app/less/desktop.less

@ -881,6 +881,14 @@ a.footer_link.active:active { @@ -881,6 +881,14 @@ a.footer_link.active:active {
}
}
.im_submit_edit_label,
.im_submit_edit .im_submit_send_label {
display: none;
}
.im_submit_edit .im_submit_edit_label {
display: inline;
}
.composer_emoji_panel {
display: block;
height: 30px;

4
app/less/mobile.less

@ -856,6 +856,10 @@ img.im_message_video_thumb, @@ -856,6 +856,10 @@ img.im_message_video_thumb,
font-size: 10px;
padding: 0;
}
.im_message_edited {
position: absolute;
top: -11px;
}
.im_message_out {
.im_message_fwd_date {

8
app/partials/desktop/im.html

@ -168,6 +168,7 @@ @@ -168,6 +168,7 @@
<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-primary im_edit_delete_btn" ng-click="selectedDelete()" ng-class="{disabled: !selectedCount}" ng-disabled="!selectedCount" my-i18n-format="im_delete" ng-show="historyState.canDelete"></a>
<a class="btn btn-primary im_edit_reply_btn" ng-click="selectedReply()" ng-show="selectedCount == 1 &amp;&amp; historyState.canReply" my-i18n="im_reply"></a>
<a class="btn btn-primary im_edit_reply_btn" ng-click="selectedEdit()" ng-show="selectedCount == 1 &amp;&amp; historyState.canEdit" my-i18n="im_edit"></a>
<my-i18n-param name="count"><strong class="im_selected_count" ng-show="selectedCount > 0" ng-bind="selectedCount"></strong></my-i18n-param>
</div>
</div>
@ -189,7 +190,7 @@ @@ -189,7 +190,7 @@
<div class="im_send_reply_wrap" ng-if="draftMessage.replyToMsgID > 0">
<a class="im_send_reply_cancel" ng-mousedown="draftMessage.replyClear(true)"><i class="icon icon-reply-bar"></i><i class="icon icon-reply-bar"></i></a>
<a class="im_message_reply_wrap" my-reply-message="draftMessage.replyToMsgID" watch="true"></a>
<a class="im_message_reply_wrap" my-reply-message="draftMessage.replyToMsgID" watch="true" edit="{{draftMessage.type == 'edit'}}"></a>
</div>
<div class="im_send_reply_wrap im_send_fwds_wrap" ng-if="draftMessage.fwdMessages.length > 0">
@ -210,7 +211,10 @@ @@ -210,7 +211,10 @@
</div>
<div class="im_send_buttons_wrap clearfix">
<button type="submit" class="btn btn-md im_submit nocopy" my-i18n="im_submit_message"></button>
<button type="submit" class="btn btn-md im_submit nocopy" ng-class="draftMessage.type == 'edit' ? 'im_submit_edit' : 'im_submit_send'">
<span class="im_submit_send_label" my-i18n="im_submit_message"></span>
<span class="im_submit_edit_label" my-i18n="im_submit_edit_message"></span>
</button>
<div class="im_attach pull-left">
<input type="file" class="im_attach_input" size="28" multiple="multiple" title="{{'im_attach_file_title' | i18n}}" />

5
app/partials/desktop/message.html

@ -38,7 +38,10 @@ @@ -38,7 +38,10 @@
<i class="icon-message-views"></i><span class="im_message_views_cnt" my-message-views="historyMessage.mid"></span>
</div>
</div>
<span class="im_message_date clickable nocopy" data-content="{{::historyMessage.date | time}}"></span>
<span class="im_message_date clickable">
<span class="im_message_edited" my-message-edited="historyMessage.mid"></span>
<span class="im_message_date_text nocopy" data-content="{{::historyMessage.date | time}}"></span>
</span>
</div>
<div class="im_message_body" ng-class="::{im_message_body_media: historyMessage._ == 'message' &amp;&amp; historyMessage.media ? true : false}">

5
app/partials/desktop/reply_message.html

@ -11,9 +11,10 @@ @@ -11,9 +11,10 @@
watch="true"
/>
</div>
<div class="im_message_reply_author" ng-switch-default>
<div class="im_message_reply_author" ng-switch-default ng-switch="isEdit">
<span class="copyonly">&gt;&nbsp;</span>
<span my-peer-link="replyMessage.fromID" peer-watch="true"></span>
<span ng-switch-when="true" my-i18n="im_edit_message_title"></span>
<span ng-switch-default my-peer-link="replyMessage.fromID" peer-watch="true"></span>
</div>
<div class="im_message_reply_body" ng-switch-default>
<span class="copyonly">&gt;&nbsp;</span>

4
app/partials/mobile/im.html

@ -136,11 +136,11 @@ @@ -136,11 +136,11 @@
<div class="im_send_form_wrap1">
<div class="im_send_form_wrap clearfix" ng-controller="AppImSendController">
<form my-send-form draft-message="draftMessage" mentions="mentions" commands="commands" class="im_send_form" ng-class="{im_send_form_empty: !draftMessage.text.length, composer_progress_enabled: draftMessage.inlineProgress}">
<form my-send-form draft-message="draftMessage" mentions="mentions" commands="commands" class="im_send_form" ng-class="{im_send_form_empty: !draftMessage.text.length && draftMessage.type != 'edit', composer_progress_enabled: draftMessage.inlineProgress}">
<div class="im_send_reply_wrap" ng-if="draftMessage.replyToMsgID > 0">
<a class="im_send_reply_cancel" ng-mousedown="draftMessage.replyClear()"><i class="icon icon-reply-bar"></i><i class="icon icon-reply-bar"></i></a>
<a class="im_message_reply_wrap" my-reply-message="draftMessage.replyToMsgID" watch="true"></a>
<a class="im_message_reply_wrap" my-reply-message="draftMessage.replyToMsgID" watch="true" edit="{{draftMessage.type == 'edit'}}"></a>
</div>
<div class="im_send_reply_wrap im_send_fwds_wrap" ng-if="draftMessage.fwdMessages.length > 0">

5
app/partials/mobile/message.html

@ -37,7 +37,10 @@ @@ -37,7 +37,10 @@
<i class="icon-message-status" tooltip="{{'message_action_retry' | i18n}}"></i>
</a>
<i ng-if="::historyMessage.pFlags.unread &amp;&amp; historyMessage.pFlags.out || historyMessage.pending || false" class="icon-message-status" ng-show="!historyMessage.error"></i>
<span class="im_message_date" ng-bind="::historyMessage.date | time"></span>
<span class="im_message_date">
<span class="im_message_edited" my-message-edited="historyMessage.mid"></span>
<span class="im_message_date_text" ng-bind="::historyMessage.date | time"></span>
</span>
</div>
<div my-message-body="historyMessage">

1
app/partials/mobile/message_actions_modal.html

@ -2,6 +2,7 @@ @@ -2,6 +2,7 @@
<div class="message_actions_wrap">
<button ng-if="historyState.canReply" class="btn btn-md btn-md-primary btn-block" my-i18n="message_action_reply" ng-click="$close('reply')"></button>
<button ng-if="historyState.canEdit" class="btn btn-md btn-md-primary btn-block" my-i18n="message_action_edit" ng-click="$close('edit')"></button>
<button class="btn btn-md btn-md-primary btn-block" my-i18n="message_action_forward" ng-click="$close('forward')"></button>
<button ng-if="historyState.canDelete" class="btn btn-md btn-md-primary btn-block" my-i18n="message_action_delete" ng-click="$close('delete')"></button>
<button class="btn btn-md btn-md-primary btn-block" my-i18n="message_action_select" ng-click="$close('select')"></button>

Loading…
Cancel
Save