mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Stories
This commit is contained in:
parent
8c60c011ec
commit
ad109328cf
@ -1083,26 +1083,19 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
|
|
||||||
self.chatListDisplayNode.mainContainerNode.currentItemNode.clearHighlightAnimated(true)
|
self.chatListDisplayNode.mainContainerNode.currentItemNode.clearHighlightAnimated(true)
|
||||||
|
|
||||||
|
if let navigationController = self.navigationController as? NavigationController {
|
||||||
|
let chatListController = ChatListControllerImpl(context: self.context, location: .chatList(groupId: groupId), controlsHistoryPreload: false, enableDebugActions: false)
|
||||||
|
chatListController.navigationPresentation = .master
|
||||||
|
navigationController.pushViewController(chatListController)
|
||||||
|
}
|
||||||
|
|
||||||
if !didDisplayTip {
|
if !didDisplayTip {
|
||||||
|
#if DEBUG
|
||||||
|
#else
|
||||||
let _ = ApplicationSpecificNotice.setDisplayChatListArchiveTooltip(accountManager: self.context.sharedContext.accountManager).start()
|
let _ = ApplicationSpecificNotice.setDisplayChatListArchiveTooltip(accountManager: self.context.sharedContext.accountManager).start()
|
||||||
|
#endif
|
||||||
|
|
||||||
self.push(ArchiveInfoScreen(context: self.context, settings: settings, buttonAction: { [weak self] in
|
self.push(ArchiveInfoScreen(context: self.context, settings: settings))
|
||||||
guard let self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if let navigationController = self.navigationController as? NavigationController {
|
|
||||||
let chatListController = ChatListControllerImpl(context: self.context, location: .chatList(groupId: groupId), controlsHistoryPreload: false, enableDebugActions: false)
|
|
||||||
chatListController.navigationPresentation = .master
|
|
||||||
navigationController.pushViewController(chatListController)
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
} else {
|
|
||||||
if let navigationController = self.navigationController as? NavigationController {
|
|
||||||
let chatListController = ChatListControllerImpl(context: self.context, location: .chatList(groupId: groupId), controlsHistoryPreload: false, enableDebugActions: false)
|
|
||||||
chatListController.navigationPresentation = .master
|
|
||||||
navigationController.pushViewController(chatListController)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -2693,6 +2686,10 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if peer.isService {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var items: [ContextMenuItem] = []
|
var items: [ContextMenuItem] = []
|
||||||
|
|
||||||
//TODO:localize
|
//TODO:localize
|
||||||
@ -2769,7 +2766,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
})))
|
})))
|
||||||
|
|
||||||
let isMuted = resolvedAreStoriesMuted(globalSettings: globalSettings._asGlobalNotificationSettings(), peer: peer._asPeer(), peerSettings: notificationSettings._asNotificationSettings(), topSearchPeers: topSearchPeers)
|
let isMuted = resolvedAreStoriesMuted(globalSettings: globalSettings._asGlobalNotificationSettings(), peer: peer._asPeer(), peerSettings: notificationSettings._asNotificationSettings(), topSearchPeers: topSearchPeers)
|
||||||
items.append(.action(ContextMenuActionItem(text: isMuted ? "Notify" : "Don't Notify", icon: { theme in
|
items.append(.action(ContextMenuActionItem(text: isMuted ? "Notify About Stories" : "Do Not Notify About Stories", icon: { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor)
|
return generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor)
|
||||||
}, action: { [weak self] _, f in
|
}, action: { [weak self] _, f in
|
||||||
f(.default)
|
f(.default)
|
||||||
@ -2814,11 +2811,11 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
|
|
||||||
let hideText: String
|
let hideText: String
|
||||||
if self.location == .chatList(groupId: .archive) {
|
if self.location == .chatList(groupId: .archive) {
|
||||||
hideText = "Unarchive"
|
hideText = "Unhide Stories"
|
||||||
} else {
|
} else {
|
||||||
hideText = "Archive"
|
hideText = "Hide Stories"
|
||||||
}
|
}
|
||||||
let iconName = self.location == .chatList(groupId: .archive) ? "Chat/Context Menu/MoveToChats" : "Chat/Context Menu/MoveToContacts"
|
let iconName = self.location == .chatList(groupId: .archive) ? "Chat/Context Menu/Unarchive" : "Chat/Context Menu/Archive"
|
||||||
items.append(.action(ContextMenuActionItem(text: hideText, icon: { theme in
|
items.append(.action(ContextMenuActionItem(text: hideText, icon: { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: iconName), color: theme.contextMenu.primaryColor)
|
return generateTintedImage(image: UIImage(bundleImageName: iconName), color: theme.contextMenu.primaryColor)
|
||||||
}, action: { [weak self] _, f in
|
}, action: { [weak self] _, f in
|
||||||
|
@ -194,6 +194,7 @@ public func archiveSettingsController(context: AccountContext) -> ViewController
|
|||||||
}
|
}
|
||||||
|
|
||||||
let controller = ItemListController(context: context, state: signal)
|
let controller = ItemListController(context: context, state: signal)
|
||||||
|
controller.navigationPresentation = .modal
|
||||||
|
|
||||||
presentUndoImpl = { [weak controller] content in
|
presentUndoImpl = { [weak controller] content in
|
||||||
guard let controller else {
|
guard let controller else {
|
||||||
|
@ -8973,6 +8973,25 @@ public extension Api.functions.users {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public extension Api.functions.users {
|
||||||
|
static func getStoriesMaxIDs(id: [Api.InputUser]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Int32]>) {
|
||||||
|
let buffer = Buffer()
|
||||||
|
buffer.appendInt32(-904087125)
|
||||||
|
buffer.appendInt32(481674261)
|
||||||
|
buffer.appendInt32(Int32(id.count))
|
||||||
|
for item in id {
|
||||||
|
item.serialize(buffer, true)
|
||||||
|
}
|
||||||
|
return (FunctionDescription(name: "users.getStoriesMaxIDs", parameters: [("id", String(describing: id))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> [Int32]? in
|
||||||
|
let reader = BufferReader(buffer)
|
||||||
|
var result: [Int32]?
|
||||||
|
if let _ = reader.readInt32() {
|
||||||
|
result = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
public extension Api.functions.users {
|
public extension Api.functions.users {
|
||||||
static func getUsers(id: [Api.InputUser]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.User]>) {
|
static func getUsers(id: [Api.InputUser]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<[Api.User]>) {
|
||||||
let buffer = Buffer()
|
let buffer = Buffer()
|
||||||
|
@ -1289,7 +1289,7 @@ public final class AccountViewTracker {
|
|||||||
let messageTimestamp = self.refreshStoriesForPeerIdsAndTimestamps[peerId]
|
let messageTimestamp = self.refreshStoriesForPeerIdsAndTimestamps[peerId]
|
||||||
var refresh = false
|
var refresh = false
|
||||||
if let messageTimestamp = messageTimestamp {
|
if let messageTimestamp = messageTimestamp {
|
||||||
refresh = messageTimestamp < timestamp - 60
|
refresh = messageTimestamp < timestamp - 60 * 60
|
||||||
} else {
|
} else {
|
||||||
refresh = true
|
refresh = true
|
||||||
}
|
}
|
||||||
@ -1304,8 +1304,14 @@ public final class AccountViewTracker {
|
|||||||
self.nextUpdatedUnsupportedMediaDisposableId += 1
|
self.nextUpdatedUnsupportedMediaDisposableId += 1
|
||||||
|
|
||||||
if let account = self.account {
|
if let account = self.account {
|
||||||
let signal = account.postbox.transaction { transaction -> [Api.InputUser] in
|
let signal = account.postbox.transaction { transaction -> [(PeerId, Api.InputUser)] in
|
||||||
return addedPeerIds.compactMap { transaction.getPeer($0).flatMap(apiInputUser) }
|
return addedPeerIds.compactMap { id -> (PeerId, Api.InputUser)? in
|
||||||
|
if let user = transaction.getPeer(id).flatMap(apiInputUser) {
|
||||||
|
return (id, user)
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|> mapToSignal { inputUsers -> Signal<Never, NoError> in
|
|> mapToSignal { inputUsers -> Signal<Never, NoError> in
|
||||||
guard !inputUsers.isEmpty else {
|
guard !inputUsers.isEmpty else {
|
||||||
@ -1314,21 +1320,30 @@ public final class AccountViewTracker {
|
|||||||
|
|
||||||
var requests: [Signal<Never, NoError>] = []
|
var requests: [Signal<Never, NoError>] = []
|
||||||
|
|
||||||
let batchCount = 50
|
let batchCount = 100
|
||||||
var startIndex = 0
|
var startIndex = 0
|
||||||
while startIndex < inputUsers.count {
|
while startIndex < inputUsers.count {
|
||||||
var slice: [Api.InputUser] = []
|
var slice: [(PeerId, Api.InputUser)] = []
|
||||||
for i in startIndex ..< min(startIndex + batchCount, inputUsers.count) {
|
for i in startIndex ..< min(startIndex + batchCount, inputUsers.count) {
|
||||||
slice.append(inputUsers[i])
|
slice.append(inputUsers[i])
|
||||||
}
|
}
|
||||||
startIndex += batchCount
|
startIndex += batchCount
|
||||||
requests.append(account.network.request(Api.functions.users.getUsers(id: slice))
|
requests.append(account.network.request(Api.functions.users.getStoriesMaxIDs(id: slice.map(\.1)))
|
||||||
|> `catch` { _ -> Signal<[Api.User], NoError> in
|
|> `catch` { _ -> Signal<[Int32], NoError> in
|
||||||
return .single([])
|
return .single([])
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<Never, NoError> in
|
|> mapToSignal { result -> Signal<Never, NoError> in
|
||||||
return account.postbox.transaction { transaction in
|
return account.postbox.transaction { transaction in
|
||||||
updatePeers(transaction: transaction, accountPeerId: account.peerId, peers: AccumulatedPeers(users: result))
|
for i in 0 ..< result.count {
|
||||||
|
if i < slice.count {
|
||||||
|
let value = result[i]
|
||||||
|
if value <= 0 {
|
||||||
|
transaction.clearStoryItemsInexactMaxId(peerId: slice[i].0)
|
||||||
|
} else {
|
||||||
|
transaction.setStoryItemsInexactMaxId(peerId: slice[i].0, id: value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|> ignoreValues
|
|> ignoreValues
|
||||||
})
|
})
|
||||||
|
@ -3850,7 +3850,114 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: component.theme)
|
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: component.theme)
|
||||||
var items: [ContextMenuItem] = []
|
var items: [ContextMenuItem] = []
|
||||||
|
|
||||||
if component.slice.item.storyItem.isPublic && (component.slice.peer.addressName != nil || !component.slice.peer._asPeer().usernames.isEmpty) {
|
let isMuted = resolvedAreStoriesMuted(globalSettings: globalSettings._asGlobalNotificationSettings(), peer: component.slice.peer._asPeer(), peerSettings: settings._asNotificationSettings(), topSearchPeers: topSearchPeers)
|
||||||
|
|
||||||
|
if !component.slice.peer.isService {
|
||||||
|
items.append(.action(ContextMenuActionItem(text: isMuted ? "Notify About Stories" : "Do Not Notify About Stories", icon: { theme in
|
||||||
|
return generateTintedImage(image: UIImage(bundleImageName: component.slice.additionalPeerData.isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor)
|
||||||
|
}, action: { [weak self] _, a in
|
||||||
|
a(.default)
|
||||||
|
|
||||||
|
guard let self, let component = self.component else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = component.context.engine.peers.togglePeerStoriesMuted(peerId: component.slice.peer.id).start()
|
||||||
|
|
||||||
|
let iconColor = UIColor.white
|
||||||
|
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: component.theme)
|
||||||
|
if isMuted {
|
||||||
|
self.component?.presentController(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 **\(component.slice.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))** posts a story.", customUndoText: nil, timeout: nil),
|
||||||
|
elevatedLayout: false,
|
||||||
|
animateInAsReplacement: false,
|
||||||
|
action: { _ in return false }
|
||||||
|
), nil)
|
||||||
|
} else {
|
||||||
|
self.component?.presentController(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 **\(component.slice.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))** posts a story.", customUndoText: nil, timeout: nil),
|
||||||
|
elevatedLayout: false,
|
||||||
|
animateInAsReplacement: false,
|
||||||
|
action: { _ in return false }
|
||||||
|
), nil)
|
||||||
|
}
|
||||||
|
})))
|
||||||
|
|
||||||
|
var isHidden = false
|
||||||
|
if case let .user(user) = component.slice.peer, let storiesHidden = user.storiesHidden {
|
||||||
|
isHidden = storiesHidden
|
||||||
|
}
|
||||||
|
|
||||||
|
items.append(.action(ContextMenuActionItem(text: isHidden ? "Unhide Stories" : "Hide Stories", icon: { theme in
|
||||||
|
return generateTintedImage(image: UIImage(bundleImageName: isHidden ? "Chat/Context Menu/Unarchive" : "Chat/Context Menu/Archive"), color: theme.contextMenu.primaryColor)
|
||||||
|
}, action: { [weak self] _, a in
|
||||||
|
a(.default)
|
||||||
|
|
||||||
|
guard let self, let component = self.component else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = component.context.engine.peers.updatePeerStoriesHidden(id: component.slice.peer.id, isHidden: !isHidden)
|
||||||
|
|
||||||
|
let text = isHidden ? "Stories from **\(component.slice.peer.compactDisplayTitle)** will now be shown in Archived Chats." : "Stories from **\(component.slice.peer.compactDisplayTitle)** will now be shown in Chats."
|
||||||
|
let tooltipScreen = TooltipScreen(
|
||||||
|
context: component.context,
|
||||||
|
account: component.context.account,
|
||||||
|
sharedContext: component.context.sharedContext,
|
||||||
|
text: .markdown(text: text),
|
||||||
|
style: .customBlur(UIColor(rgb: 0x1c1c1c), 0.0),
|
||||||
|
icon: .peer(peer: component.slice.peer, isStory: true),
|
||||||
|
action: TooltipScreen.Action(
|
||||||
|
title: "Undo",
|
||||||
|
action: {
|
||||||
|
component.context.engine.peers.updatePeerStoriesHidden(id: component.slice.peer.id, isHidden: isHidden)
|
||||||
|
}
|
||||||
|
),
|
||||||
|
location: .bottom,
|
||||||
|
shouldDismissOnTouch: { _, _ in return .dismiss(consume: false) }
|
||||||
|
)
|
||||||
|
tooltipScreen.willBecomeDismissed = { [weak self] _ in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.sendMessageContext.tooltipScreen = nil
|
||||||
|
self.updateIsProgressPaused()
|
||||||
|
}
|
||||||
|
self.sendMessageContext.tooltipScreen = tooltipScreen
|
||||||
|
self.updateIsProgressPaused()
|
||||||
|
component.controller()?.present(tooltipScreen, in: .current)
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !component.slice.item.storyItem.isForwardingDisabled {
|
||||||
|
let saveText: String = "Save to Gallery"
|
||||||
|
items.append(.action(ContextMenuActionItem(text: saveText, icon: { theme in
|
||||||
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Save"), color: theme.contextMenu.primaryColor)
|
||||||
|
}, action: { [weak self] _, a in
|
||||||
|
a(.default)
|
||||||
|
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.requestSave()
|
||||||
|
})))
|
||||||
|
}
|
||||||
|
|
||||||
|
if !component.slice.peer.isService && component.slice.item.storyItem.isPublic && (component.slice.peer.addressName != nil || !component.slice.peer._asPeer().usernames.isEmpty) {
|
||||||
items.append(.action(ContextMenuActionItem(text: "Copy Link", icon: { theme in
|
items.append(.action(ContextMenuActionItem(text: "Copy Link", icon: { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.contextMenu.primaryColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.contextMenu.primaryColor)
|
||||||
}, action: { [weak self] _, a in
|
}, action: { [weak self] _, a in
|
||||||
@ -3878,7 +3985,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})))
|
})))
|
||||||
items.append(.action(ContextMenuActionItem(text: "Share", icon: { theme in
|
/*items.append(.action(ContextMenuActionItem(text: "Share", icon: { theme in
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.contextMenu.primaryColor)
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Forward"), color: theme.contextMenu.primaryColor)
|
||||||
}, action: { [weak self] _, a in
|
}, action: { [weak self] _, a in
|
||||||
a(.default)
|
a(.default)
|
||||||
@ -3887,152 +3994,44 @@ public final class StoryItemSetContainerComponent: Component {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.sendMessageContext.performShareAction(view: self)
|
self.sendMessageContext.performShareAction(view: self)
|
||||||
})))
|
})))*/
|
||||||
}
|
|
||||||
|
|
||||||
let isMuted = resolvedAreStoriesMuted(globalSettings: globalSettings._asGlobalNotificationSettings(), peer: component.slice.peer._asPeer(), peerSettings: settings._asNotificationSettings(), topSearchPeers: topSearchPeers)
|
|
||||||
|
|
||||||
items.append(.action(ContextMenuActionItem(text: isMuted ? "Notify" : "Don't Notify", icon: { theme in
|
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: component.slice.additionalPeerData.isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor)
|
|
||||||
}, action: { [weak self] _, a in
|
|
||||||
a(.default)
|
|
||||||
|
|
||||||
guard let self, let component = self.component else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = component.context.engine.peers.togglePeerStoriesMuted(peerId: component.slice.peer.id).start()
|
|
||||||
|
|
||||||
let iconColor = UIColor.white
|
|
||||||
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: component.theme)
|
|
||||||
if isMuted {
|
|
||||||
self.component?.presentController(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 **\(component.slice.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))** posts a story.", customUndoText: nil, timeout: nil),
|
|
||||||
elevatedLayout: false,
|
|
||||||
animateInAsReplacement: false,
|
|
||||||
action: { _ in return false }
|
|
||||||
), nil)
|
|
||||||
} else {
|
|
||||||
self.component?.presentController(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 **\(component.slice.peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder))** posts a story.", customUndoText: nil, timeout: nil),
|
|
||||||
elevatedLayout: false,
|
|
||||||
animateInAsReplacement: false,
|
|
||||||
action: { _ in return false }
|
|
||||||
), nil)
|
|
||||||
}
|
|
||||||
})))
|
|
||||||
|
|
||||||
var isHidden = false
|
|
||||||
if case let .user(user) = component.slice.peer, let storiesHidden = user.storiesHidden {
|
|
||||||
isHidden = storiesHidden
|
|
||||||
}
|
}
|
||||||
|
|
||||||
items.append(.action(ContextMenuActionItem(text: isHidden ? "Unarchive" : "Archive", icon: { theme in
|
if !component.slice.peer.isService {
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: isHidden ? "Chat/Context Menu/MoveToChats" : "Chat/Context Menu/MoveToContacts"), color: theme.contextMenu.primaryColor)
|
items.append(.action(ContextMenuActionItem(text: "Report", icon: { theme in
|
||||||
}, action: { [weak self] _, a in
|
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Report"), color: theme.contextMenu.primaryColor)
|
||||||
a(.default)
|
}, action: { [weak self] c, a in
|
||||||
|
guard let self, let component = self.component, let controller = component.controller() else {
|
||||||
guard let self, let component = self.component else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let _ = component.context.engine.peers.updatePeerStoriesHidden(id: component.slice.peer.id, isHidden: !isHidden)
|
|
||||||
|
|
||||||
let text = isHidden ? "Stories from **\(component.slice.peer.compactDisplayTitle)** will now be shown in Chats, not Contacts." : "Stories from **\(component.slice.peer.compactDisplayTitle)** will now be shown in Contacts, not Chats."
|
|
||||||
let tooltipScreen = TooltipScreen(
|
|
||||||
context: component.context,
|
|
||||||
account: component.context.account,
|
|
||||||
sharedContext: component.context.sharedContext,
|
|
||||||
text: .markdown(text: text),
|
|
||||||
style: .customBlur(UIColor(rgb: 0x1c1c1c), 0.0),
|
|
||||||
icon: .peer(peer: component.slice.peer, isStory: true),
|
|
||||||
action: TooltipScreen.Action(
|
|
||||||
title: "Undo",
|
|
||||||
action: {
|
|
||||||
component.context.engine.peers.updatePeerStoriesHidden(id: component.slice.peer.id, isHidden: isHidden)
|
|
||||||
}
|
|
||||||
),
|
|
||||||
location: .bottom,
|
|
||||||
shouldDismissOnTouch: { _, _ in return .dismiss(consume: false) }
|
|
||||||
)
|
|
||||||
tooltipScreen.willBecomeDismissed = { [weak self] _ in
|
|
||||||
guard let self else {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.sendMessageContext.tooltipScreen = nil
|
|
||||||
self.updateIsProgressPaused()
|
let options: [PeerReportOption] = [.spam, .violence, .pornography, .childAbuse, .copyright, .illegalDrugs, .personalDetails, .other]
|
||||||
}
|
presentPeerReportOptions(
|
||||||
self.sendMessageContext.tooltipScreen = tooltipScreen
|
context: component.context,
|
||||||
self.updateIsProgressPaused()
|
parent: controller,
|
||||||
component.controller()?.present(tooltipScreen, in: .current)
|
contextController: c,
|
||||||
})))
|
backAction: { _ in },
|
||||||
|
subject: .story(component.slice.peer.id, component.slice.item.storyItem.id),
|
||||||
#if DEBUG
|
options: options,
|
||||||
let saveText: String
|
passthrough: true,
|
||||||
if case .file = component.slice.item.storyItem.media {
|
forceTheme: defaultDarkPresentationTheme,
|
||||||
saveText = "Save Video"
|
isDetailedReportingVisible: { [weak self] isReporting in
|
||||||
} else {
|
guard let self else {
|
||||||
saveText = "Save Image"
|
return
|
||||||
|
}
|
||||||
|
self.isReporting = isReporting
|
||||||
|
self.updateIsProgressPaused()
|
||||||
|
},
|
||||||
|
completion: { [weak self] reason, _ in
|
||||||
|
guard let self, let component = self.component, let controller = component.controller(), let reason else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let _ = component.context.engine.peers.reportPeerStory(peerId: component.slice.peer.id, storyId: component.slice.item.storyItem.id, reason: reason, message: "").start()
|
||||||
|
controller.present(UndoOverlayController(presentationData: presentationData, content: .emoji(name: "PoliceCar", text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})))
|
||||||
}
|
}
|
||||||
items.append(.action(ContextMenuActionItem(text: saveText, icon: { theme in
|
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Save"), color: theme.contextMenu.primaryColor)
|
|
||||||
}, action: { [weak self] _, a in
|
|
||||||
a(.default)
|
|
||||||
|
|
||||||
guard let self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
self.requestSave()
|
|
||||||
})))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
items.append(.action(ContextMenuActionItem(text: "Report", icon: { theme in
|
|
||||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Report"), color: theme.contextMenu.primaryColor)
|
|
||||||
}, action: { [weak self] c, a in
|
|
||||||
guard let self, let component = self.component, let controller = component.controller() else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let options: [PeerReportOption] = [.spam, .violence, .pornography, .childAbuse, .copyright, .illegalDrugs, .personalDetails, .other]
|
|
||||||
presentPeerReportOptions(
|
|
||||||
context: component.context,
|
|
||||||
parent: controller,
|
|
||||||
contextController: c,
|
|
||||||
backAction: { _ in },
|
|
||||||
subject: .story(component.slice.peer.id, component.slice.item.storyItem.id),
|
|
||||||
options: options,
|
|
||||||
passthrough: true,
|
|
||||||
forceTheme: defaultDarkPresentationTheme,
|
|
||||||
isDetailedReportingVisible: { [weak self] isReporting in
|
|
||||||
guard let self else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
self.isReporting = isReporting
|
|
||||||
self.updateIsProgressPaused()
|
|
||||||
},
|
|
||||||
completion: { [weak self] reason, _ in
|
|
||||||
guard let self, let component = self.component, let controller = component.controller(), let reason else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
let _ = component.context.engine.peers.reportPeerStory(peerId: component.slice.peer.id, storyId: component.slice.item.storyItem.id, reason: reason, message: "").start()
|
|
||||||
controller.present(UndoOverlayController(presentationData: presentationData, content: .emoji(name: "PoliceCar", text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), in: .current)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})))
|
|
||||||
|
|
||||||
var hasLinkedStickers = false
|
var hasLinkedStickers = false
|
||||||
let media = component.slice.item.storyItem.media._asMedia()
|
let media = component.slice.item.storyItem.media._asMedia()
|
||||||
|
@ -910,7 +910,7 @@ final class StoryItemSetContainerSendMessage {
|
|||||||
component.presentController(actionSheet, nil)
|
component.presentController(actionSheet, nil)
|
||||||
} else {
|
} else {
|
||||||
var preferredAction: ShareControllerPreferredAction?
|
var preferredAction: ShareControllerPreferredAction?
|
||||||
if focusedItem.storyItem.isPublic {
|
if focusedItem.storyItem.isPublic && !component.slice.peer.isService {
|
||||||
preferredAction = .custom(action: ShareControllerAction(title: "Copy Link", action: {
|
preferredAction = .custom(action: ShareControllerAction(title: "Copy Link", action: {
|
||||||
let _ = ((component.context.engine.messages.exportStoryLink(peerId: peerId, id: focusedItem.storyItem.id))
|
let _ = ((component.context.engine.messages.exportStoryLink(peerId: peerId, id: focusedItem.storyItem.id))
|
||||||
|> deliverOnMainQueue).start(next: { link in
|
|> deliverOnMainQueue).start(next: { link in
|
||||||
|
Loading…
x
Reference in New Issue
Block a user