no message

This commit is contained in:
Peter
2016-09-05 23:21:13 +03:00
parent e641db56e9
commit 18b1a3f62c
49 changed files with 1476 additions and 198 deletions

View File

@@ -397,6 +397,13 @@ public class ChatController: ViewController {
return self._chatHistoryLocation.get()
}
private var presentationInterfaceState = ChatPresentationInterfaceState(interfaceState: ChatInterfaceState(), peer: nil)
private let chatInterfaceStatePromise = Promise<ChatInterfaceState>()
private var leftNavigationButton: ChatNavigationButton?
private var rightNavigationButton: ChatNavigationButton?
private var chatInfoNavigationButton: ChatNavigationButton?
private let galleryHiddenMesageAndMediaDisposable = MetaDisposable()
private var controllerInteraction: ChatControllerInteraction?
@@ -438,7 +445,7 @@ public class ChatController: ViewController {
if let galleryMedia = galleryMedia {
if let file = galleryMedia as? TelegramMediaFile, file.mimeType == "audio/mpeg" {
debugPlayMedia(account: strongSelf.account, file: file)
//debugPlayMedia(account: strongSelf.account, file: file)
} else {
let gallery = GalleryController(account: strongSelf.account, messageId: id)
@@ -474,30 +481,92 @@ public class ChatController: ViewController {
}
}
}
}, testNavigateToMessage: { [weak self] fromId, id in
}, openPeer: { [weak self] id, navigation in
if let strongSelf = self {
(strongSelf.navigationController as? NavigationController)?.pushViewController(ChatController(account: strongSelf.account, peerId: id, messageId: nil))
}
}, openMessageContextMenu: { [weak self] id, node, frame in
if let strongSelf = self, let historyView = strongSelf.historyView {
var fromIndex: MessageIndex?
for case let .MessageEntry(message) in historyView.filteredEntries where message.id == fromId {
fromIndex = MessageIndex(message)
break
}
if let fromIndex = fromIndex {
var found = false
for case let .MessageEntry(message) in historyView.filteredEntries where message.id == id {
found = true
strongSelf._chatHistoryLocation.set(.single(ChatHistoryLocation.Scroll(index: MessageIndex(message), anchorIndex: MessageIndex(message), sourceIndex: fromIndex, scrollPosition: .Center(.Bottom), animated: true)))
let contextMenuController = ContextMenuController(actions: [
ContextMenuAction(content: .text("Reply"), action: { [weak strongSelf] in
if let strongSelf = strongSelf, let historyView = strongSelf.historyView {
for case let .MessageEntry(message) in historyView.filteredEntries where message.id == id {
strongSelf.updateChatInterfaceState(strongSelf.chatInterfaceState.withUpdatedReplyMessageId(message.id), animated: true)
strongSelf.chatDisplayNode.ensureInputViewFocused()
break
}
}
}),
ContextMenuAction(content: .text("Copy"), action: { [weak strongSelf] in
if let strongSelf = strongSelf, let historyView = strongSelf.historyView {
for case let .MessageEntry(message) in historyView.filteredEntries where message.id == id {
if !message.text.isEmpty {
UIPasteboard.general.string = message.text
}
break
}
}
}),
ContextMenuAction(content: .text("More..."), action: { [weak strongSelf] in
if let strongSelf = strongSelf, let historyView = strongSelf.historyView {
for case let .MessageEntry(message) in historyView.filteredEntries where message.id == id {
if strongSelf.chatInterfaceState.selectionState != nil {
strongSelf.updateChatInterfaceState(strongSelf.chatInterfaceState.withoutSelectionState(), animated: true)
} else {
strongSelf.updateChatInterfaceState(strongSelf.chatInterfaceState.withUpdatedSelectedMessage(message.id), animated: true)
}
break
}
}
})
])
strongSelf.present(contextMenuController, in: .window, with: ContextMenuControllerPresentationArguments(sourceNodeAndRect: { [weak strongSelf, weak node] in
if let node = node {
return (node, frame)
} else {
return nil
}
}))
}
}, navigateToMessage: { [weak self] fromId, id in
if let strongSelf = self, let historyView = strongSelf.historyView {
if id.peerId == strongSelf.peerId {
var fromIndex: MessageIndex?
for case let .MessageEntry(message) in historyView.filteredEntries where message.id == fromId {
fromIndex = MessageIndex(message)
break
}
if !found {
strongSelf.messageIndexDisposable.set((strongSelf.account.postbox.messageIndexAtId(id) |> deliverOnMainQueue).start(next: { [weak strongSelf] index in
if let strongSelf = strongSelf, let index = index {
strongSelf._chatHistoryLocation.set(.single(ChatHistoryLocation.Scroll(index:index, anchorIndex: index, sourceIndex: fromIndex, scrollPosition: .Center(.Bottom), animated: true)))
}
}))
if let fromIndex = fromIndex {
var found = false
for case let .MessageEntry(message) in historyView.filteredEntries where message.id == id {
found = true
strongSelf._chatHistoryLocation.set(.single(ChatHistoryLocation.Scroll(index: MessageIndex(message), anchorIndex: MessageIndex(message), sourceIndex: fromIndex, scrollPosition: .Center(.Bottom), animated: true)))
}
if !found {
strongSelf.messageIndexDisposable.set((strongSelf.account.postbox.messageIndexAtId(id) |> deliverOnMainQueue).start(next: { [weak strongSelf] index in
if let strongSelf = strongSelf, let index = index {
strongSelf._chatHistoryLocation.set(.single(ChatHistoryLocation.Scroll(index:index, anchorIndex: index, sourceIndex: fromIndex, scrollPosition: .Center(.Bottom), animated: true)))
}
}))
}
}
} else {
(strongSelf.navigationController as? NavigationController)?.pushViewController(ChatController(account: strongSelf.account, peerId: id.peerId, messageId: id))
}
}
}, clickThroughMessage: { [weak self] in
self?.view.endEditing(true)
}, toggleMessageSelection: { [weak self] messageId in
if let strongSelf = self, let historyView = strongSelf.historyView {
for case let .MessageEntry(message) in historyView.filteredEntries where message.id == messageId {
strongSelf.updateChatInterfaceState(strongSelf.chatInterfaceState.withToggledSelectedMessage(messageId), animated: false)
break
}
}
})
@@ -506,10 +575,14 @@ public class ChatController: ViewController {
let messageViewQueue = self.messageViewQueue
self.chatInfoNavigationButton = ChatNavigationButton(action: .openChatInfo, buttonItem: UIBarButtonItem(customDisplayNode: ChatAvatarNavigationNode()))
self.updateChatInterfaceState(self.chatInterfaceState, animated: false)
peerDisposable.set((account.postbox.peerWithId(peerId)
|> deliverOnMainQueue).start(next: { [weak self] peer in
if let strongSelf = self {
strongSelf.title = peer.displayTitle
(strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.avatarNode.setPeer(account: strongSelf.account, peer: peer)
}
}))
@@ -672,30 +745,40 @@ public class ChatController: ViewController {
self.chatDisplayNode.listView.visibleContentOffsetChanged = { [weak self] offset in
if let strongSelf = self {
if let offset = offset, offset < 40.0 {
if strongSelf.chatDisplayNode.navigateToLatestButton.alpha == 1.0 {
UIView.animate(withDuration: 0.2, delay: 0.0, options: [.beginFromCurrentState], animations: {
strongSelf.chatDisplayNode.navigateToLatestButton.alpha = 0.0
}, completion: nil)
}
} else {
if strongSelf.chatDisplayNode.navigateToLatestButton.alpha == 0.0 {
UIView.animate(withDuration: 0.2, delay: 0.0, options: [.beginFromCurrentState], animations: {
strongSelf.chatDisplayNode.navigateToLatestButton.alpha = 1.0
}, completion: nil)
}
let offsetAlpha: CGFloat
switch offset {
case let .known(offset):
if offset < 40.0 {
offsetAlpha = 0.0
} else {
offsetAlpha = 1.0
}
case .unknown:
offsetAlpha = 1.0
case .none:
offsetAlpha = 0.0
}
if !strongSelf.chatDisplayNode.navigateToLatestButton.alpha.isEqual(to: offsetAlpha) {
UIView.animate(withDuration: 0.2, delay: 0.0, options: [.beginFromCurrentState], animations: {
strongSelf.chatDisplayNode.navigateToLatestButton.alpha = offsetAlpha
}, completion: nil)
}
}
}
self.chatDisplayNode.requestLayout = { [weak self] animated in
self?.requestLayout(transition: animated ? .animated(duration: 0.1, curve: .easeInOut) : .immediate)
self.chatDisplayNode.requestLayout = { [weak self] transition in
self?.requestLayout(transition: transition)
}
self.chatDisplayNode.setupSendActionOnViewUpdate = { [weak self] f in
self?.layoutActionOnViewTransition = f
}
self.chatDisplayNode.requestUpdateChatInterfaceState = { [weak self] state, animated in
self?.updateChatInterfaceState(state, animated: animated)
}
self.chatDisplayNode.displayAttachmentMenu = { [weak self] in
if let strongSelf = self {
let controller = ChatMediaActionSheetController()
@@ -721,6 +804,22 @@ public class ChatController: ViewController {
}
}
self.chatDisplayNode.interfaceInteraction = ChatPanelInterfaceInteraction(deleteSelectedMessages: { [weak self] in
if let strongSelf = self {
if let messageIds = strongSelf.chatInterfaceState.selectionState?.selectedIds, !messageIds.isEmpty {
strongSelf.account.postbox.modify({ modifier in
modifier.deleteMessages(Array(messageIds))
}).start()
}
strongSelf.updateChatInterfaceState(strongSelf.chatInterfaceState.withoutSelectionState(), animated: true)
}
}, forwardSelectedMessages: { [weak self] in
if let strongSelf = self {
let controller = ShareRecipientsActionSheetController()
strongSelf.present(controller, in: .window)
}
})
self.displayNodeDidLoad()
self.dequeueHistoryViewTransition()
@@ -799,7 +898,7 @@ public class ChatController: ViewController {
self.layoutActionOnViewTransition = nil
layoutActionOnViewTransition()
self.chatDisplayNode.containerLayoutUpdated(self.containerLayout, navigationBarHeight: self.navigationBar.frame.maxY, transition: .animated(duration: 0.5 * 1.3, curve: .spring), listViewTransaction: { updateSizeAndInsets in
self.chatDisplayNode.containerLayoutUpdated(self.containerLayout, navigationBarHeight: self.navigationBar.frame.maxY, transition: .animated(duration: 0.4, curve: .spring), listViewTransaction: { updateSizeAndInsets in
var options = transition.options
let _ = options.insert(.Synchronous)
let _ = options.insert(.LowLatency)
@@ -819,7 +918,7 @@ public class ChatController: ViewController {
insertItems.append(ListViewInsertItem(index: item.index, previousIndex: item.previousIndex, item: item.item, directionHint: item.directionHint == .Down ? .Up : nil))
}
let scrollToItem = ListViewScrollToItem(index: 0, position: .Top, animated: true, curve: .Spring(speed: 1.3), directionHint: .Up)
let scrollToItem = ListViewScrollToItem(index: 0, position: .Top, animated: true, curve: .Spring(duration: 0.4), directionHint: .Up)
var stationaryItemRange: (Int, Int)?
if let maxInsertedItem = maxInsertedItem {
@@ -843,4 +942,75 @@ public class ChatController: ViewController {
self.chatDisplayNode.listView.deleteAndInsertItems(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: nil, updateSizeAndInsets: updateSizeAndInsets, stationaryItemRange: nil, completion: { _ in })
})
}
func updateChatInterfaceState(animated: Bool = true, _ f: (ChatInterfaceState) -> Void) {
if self.isNodeLoaded {
self.chatDisplayNode.updateChatInterfaceState(chatInterfaceState, animated: animated)
}
self.chatInterfaceState = chatInterfaceState
self.chatInterfaceStatePromise.set(.single(chatInterfaceState))
if let button = leftNavigationButtonForChatInterfaceState(chatInterfaceState, currentButton: self.leftNavigationButton, target: self, selector: #selector(self.leftNavigationButtonAction)) {
self.navigationItem.setLeftBarButton(button.buttonItem, animated: true)
self.leftNavigationButton = button
} else if let _ = self.leftNavigationButton {
self.navigationItem.setLeftBarButton(nil, animated: true)
self.leftNavigationButton = nil
}
if let button = rightNavigationButtonForChatInterfaceState(chatInterfaceState, currentButton: self.rightNavigationButton, target: self, selector: #selector(self.rightNavigationButtonAction), chatInfoNavigationButton: self.chatInfoNavigationButton) {
self.navigationItem.setRightBarButton(button.buttonItem, animated: true)
self.rightNavigationButton = button
} else if let _ = self.rightNavigationButton {
self.navigationItem.setRightBarButton(nil, animated: true)
self.rightNavigationButton = nil
}
if let controllerInteraction = self.controllerInteraction {
if chatInterfaceState.selectionState != controllerInteraction.selectionState {
let animated = controllerInteraction.selectionState == nil || chatInterfaceState.selectionState == nil
controllerInteraction.selectionState = chatInterfaceState.selectionState
self.chatDisplayNode.listView.forEachItemNode { itemNode in
if let itemNode = itemNode as? ChatMessageItemView {
itemNode.updateSelectionState(animated: animated)
}
}
}
}
}
@objc func leftNavigationButtonAction() {
if let button = self.leftNavigationButton {
self.navigationButtonAction(button.action)
}
}
@objc func rightNavigationButtonAction() {
if let button = self.rightNavigationButton {
self.navigationButtonAction(button.action)
}
}
private func navigationButtonAction(_ action: ChatNavigationButtonAction) {
switch action {
case .cancelMessageSelection:
self.updateChatInterfaceState(self.chatInterfaceState.withoutSelectionState(), animated: true)
case .clearHistory:
let actionSheet = ActionSheetController()
actionSheet.setItemGroups([ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: "Delete All Messages", color: .destructive, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
]), ActionSheetItemGroup(items: [
ActionSheetButtonItem(title: "Cancel", color: .accent, action: { [weak actionSheet] in
actionSheet?.dismissAnimated()
})
])])
self.present(actionSheet, in: .window)
case .openChatInfo:
break
}
}
}