Contact menu

This commit is contained in:
Ali
2023-06-26 14:58:57 +03:00
parent f168c482f8
commit 163abf782b
5 changed files with 105 additions and 72 deletions

View File

@@ -2671,7 +2671,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
}
})))
items.append(.action(ContextMenuActionItem(text: "Hide", icon: { theme in
items.append(.action(ContextMenuActionItem(text: "Move to Contacts", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MoveToContacts"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] _, f in
f(.dismissWithoutContent)
@@ -2680,8 +2680,6 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
return
}
self.context.engine.peers.updatePeerStoriesHidden(id: peer.id, isHidden: true)
})))
}

View File

@@ -42,6 +42,7 @@ swift_library(
"//submodules/TelegramUI/Components/ChatListTitleView",
"//submodules/TelegramUI/Components/ChatListHeaderComponent",
"//submodules/ComponentFlow",
"//submodules/UndoUI",
],
visibility = [
"//visibility:public",

View File

@@ -9,6 +9,7 @@ import AlertUI
import PresentationDataUtils
import OverlayStatusController
import LocalizedPeerData
import UndoUI
func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, contactsController: ContactsController?, isStories: Bool) -> Signal<[ContextMenuItem], NoError> {
let strings = context.sharedContext.currentPresentationData.with({ $0 }).strings
@@ -16,20 +17,83 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
return context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
TelegramEngine.EngineData.Item.Peer.AreVoiceCallsAvailable(id: peerId),
TelegramEngine.EngineData.Item.Peer.AreVideoCallsAvailable(id: peerId)
TelegramEngine.EngineData.Item.Peer.AreVideoCallsAvailable(id: peerId),
TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peerId)
)
|> map { [weak contactsController] peer, areVoiceCallsAvailable, areVideoCallsAvailable -> [ContextMenuItem] in
|> map { [weak contactsController] peer, areVoiceCallsAvailable, areVideoCallsAvailable, notificationSettings -> [ContextMenuItem] in
var items: [ContextMenuItem] = []
if isStories {
//TODO:localize
items.append(.action(ContextMenuActionItem(text: "Unhide", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Unarchive"), color: theme.contextMenu.primaryColor)
items.append(.action(ContextMenuActionItem(text: "View Profile", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/User"), color: theme.contextMenu.primaryColor)
}, action: { c, _ in
c.dismiss(completion: {
let _ = (context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
)
|> deliverOnMainQueue).start(next: { peer in
guard let peer = peer, let controller = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) else {
return
}
(contactsController?.navigationController as? NavigationController)?.pushViewController(controller)
})
})
})))
let isMuted = notificationSettings.storiesMuted == true
items.append(.action(ContextMenuActionItem(text: isMuted ? "Notify" : "Not Notify", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor)
}, action: { _, f in
f(.default)
let _ = context.engine.peers.togglePeerStoriesMuted(peerId: peerId).start()
if let peer {
let iconColor = UIColor.white
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
if isMuted {
contactsController?.present(UndoOverlayController(
presentationData: presentationData,
content: .universal(animation: "anim_profileunmute", scale: 0.075, colors: [
"Middle.Group 1.Fill 1": iconColor,
"Top.Group 1.Fill 1": iconColor,
"Bottom.Group 1.Fill 1": iconColor,
"EXAMPLE.Group 1.Fill 1": iconColor,
"Line.Group 1.Stroke 1": iconColor
], title: nil, text: "You will now get a notification whenever **\(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))** posts a story.", customUndoText: nil, timeout: nil),
elevatedLayout: false,
animateInAsReplacement: false,
action: { _ in return false }
), in: .current)
} else {
contactsController?.present(UndoOverlayController(
presentationData: presentationData,
content: .universal(animation: "anim_profilemute", scale: 0.075, colors: [
"Middle.Group 1.Fill 1": iconColor,
"Top.Group 1.Fill 1": iconColor,
"Bottom.Group 1.Fill 1": iconColor,
"EXAMPLE.Group 1.Fill 1": iconColor,
"Line.Group 1.Stroke 1": iconColor
], title: nil, text: "You will no longer receive a notification when **\(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))** posts a story.", customUndoText: nil, timeout: nil),
elevatedLayout: false,
animateInAsReplacement: false,
action: { _ in return false }
), in: .current)
}
}
})))
items.append(.action(ContextMenuActionItem(text: "Move to chats", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/MoveToChats"), color: theme.contextMenu.primaryColor)
}, action: { _, f in
f(.default)
context.engine.peers.updatePeerStoriesHidden(id: peerId, isHidden: false)
})))
return items
}
items.append(.action(ContextMenuActionItem(text: strings.ContactList_Context_SendMessage, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Message"), color: theme.contextMenu.primaryColor) }, action: { _, f in

View File

@@ -559,67 +559,6 @@ public class ContactsController: ViewController {
self.push(storyContainerScreen)
})
}
/*componentView.storyContextPeerAction = { [weak self] sourceNode, gesture, peer in
guard let self else {
return
}
var items: [ContextMenuItem] = []
//TODO:localize
if peer.id == self.context.account.peerId {
} else {
items.append(.action(ContextMenuActionItem(text: "View Profile", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/User"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] c, _ in
c.dismiss(completion: {
guard let self else {
return
}
let _ = (self.context.engine.data.get(
TelegramEngine.EngineData.Item.Peer.Peer(id: peer.id)
)
|> deliverOnMainQueue).start(next: { [weak self] peer in
guard let self else {
return
}
guard let peer = peer, let controller = self.context.sharedContext.makePeerInfoController(context: self.context, updatedPresentationData: nil, peer: peer._asPeer(), mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) else {
return
}
(self.navigationController as? NavigationController)?.pushViewController(controller)
})
})
})))
/*items.append(.action(ContextMenuActionItem(text: "Mute", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Unmute"), color: theme.contextMenu.primaryColor)
}, action: { _, f in
f(.default)
})))*/
if case let .user(user) = peer, let storiesHidden = user.storiesHidden, storiesHidden {
items.append(.action(ContextMenuActionItem(text: "Unarchive", icon: { theme in
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Unarchive"), color: theme.contextMenu.primaryColor)
}, action: { [weak self] _, f in
f(.default)
guard let self else {
return
}
self.context.engine.peers.updatePeerStoriesHidden(id: peer.id, isHidden: false)
})))
}
}
if items.isEmpty {
return
}
let controller = ContextController(account: self.context.account, presentationData: self.presentationData, source: .extracted(ChatListHeaderBarContextExtractedContentSource(controller: self, sourceNode: sourceNode, keepInPlace: false)), items: .single(ContextController.Items(content: .list(items))), recognizer: nil, gesture: gesture)
self.context.sharedContext.mainWindow?.presentInGlobalOverlay(controller)
}
}*/
}
@objc private func sortPressed() {

View File

@@ -527,11 +527,19 @@ final class ContactsControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
guard let contactsController = self.controller else {
return
}
let items = contactContextMenuItems(context: self.context, peerId: peer.id, contactsController: contactsController, isStories: isStories) |> map { ContextController.Items(content: .list($0)) }
if isStories, let node = node?.subnodes?.first(where: { $0 is ContextExtractedContentContainingNode }) as? ContextExtractedContentContainingNode {
let controller = ContextController(account: self.context.account, presentationData: self.presentationData, source: .extracted(ContactContextExtractedContentSource(sourceNode: node, shouldBeDismissed: .single(false))), items: items, recognizer: nil, gesture: gesture)
contactsController.presentInGlobalOverlay(controller)
} else {
let chatController = self.context.sharedContext.makeChatController(context: self.context, chatLocation: .peer(id: peer.id), subject: nil, botStart: nil, mode: .standard(previewing: true))
chatController.canReadHistory.set(false)
let contextController = ContextController(account: self.context.account, presentationData: self.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: contactContextMenuItems(context: self.context, peerId: peer.id, contactsController: contactsController, isStories: isStories) |> map { ContextController.Items(content: .list($0)) }, gesture: gesture)
let contextController = ContextController(account: self.context.account, presentationData: self.presentationData, source: .controller(ContextControllerContentSourceImpl(controller: chatController, sourceNode: node)), items: items, gesture: gesture)
contactsController.presentInGlobalOverlay(contextController)
}
}
func activateSearch(placeholderNode: SearchBarPlaceholderNode) {
guard let (containerLayout, navigationBarHeight) = self.containerLayout, self.searchDisplayController == nil else {
@@ -616,3 +624,26 @@ final class ContactsControllerNode: ASDisplayNode, UIGestureRecognizerDelegate {
}
}
}
private final class ContactContextExtractedContentSource: ContextExtractedContentSource {
let keepInPlace: Bool = false
let ignoreContentTouches: Bool = true
let blurBackground: Bool = true
let shouldBeDismissed: Signal<Bool, NoError>
private let sourceNode: ContextExtractedContentContainingNode
init(sourceNode: ContextExtractedContentContainingNode, shouldBeDismissed: Signal<Bool, NoError>? = nil) {
self.sourceNode = sourceNode
self.shouldBeDismissed = shouldBeDismissed ?? .single(false)
}
func takeView() -> ContextControllerTakeViewInfo? {
return ContextControllerTakeViewInfo(containingItem: .node(self.sourceNode), contentAreaInScreenSpace: UIScreen.main.bounds)
}
func putBack() -> ContextControllerPutBackViewInfo? {
return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: UIScreen.main.bounds)
}
}