mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
707d5137ca
commit
d761d9314c
@ -12880,3 +12880,6 @@ Sorry for the inconvenience.";
|
||||
"BoostGift.PrepaidGiveawayStarsCount_1" = "%@ Telegram Premium";
|
||||
"BoostGift.PrepaidGiveawayStarsCount_any" = "%@ Telegram Premium";
|
||||
"BoostGift.PrepaidGiveawayStarsMonths" = "%@-month subscriptions";
|
||||
|
||||
"WebBrowser.ShowInstantView" = "Show Instant View";
|
||||
"WebBrowser.HideInstantView" = "Hide Instant View";
|
||||
|
@ -1175,12 +1175,12 @@ public class BrowserScreen: ViewController, MinimizableController {
|
||||
|
||||
if case .webPage = contentState.contentType {
|
||||
let isAvailable = contentState.hasInstantView
|
||||
items.append(.action(ContextMenuActionItem(text: "Show Instant View", textColor: isAvailable ? .primary : .disabled, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Boost"), color: isAvailable ? theme.contextMenu.primaryColor : theme.contextMenu.primaryColor.withAlphaComponent(0.3)) }, action: isAvailable ? { (controller, action) in
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.WebBrowser_ShowInstantView, textColor: isAvailable ? .primary : .disabled, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Boost"), color: isAvailable ? theme.contextMenu.primaryColor : theme.contextMenu.primaryColor.withAlphaComponent(0.3)) }, action: isAvailable ? { (controller, action) in
|
||||
performAction.invoke(.toggleInstantView(true))
|
||||
action(.default)
|
||||
} : nil)))
|
||||
} else if case .instantPage = contentState.contentType, contentState.isInnerInstantViewEnabled {
|
||||
items.append(.action(ContextMenuActionItem(text: "Hide Instant View", textColor: .primary, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Boost"), color: theme.contextMenu.primaryColor) }, action: { (controller, action) in
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.WebBrowser_HideInstantView, textColor: .primary, icon: { theme in return generateTintedImage(image: UIImage(bundleImageName: "Instant View/InstantViewOff"), color: theme.contextMenu.primaryColor) }, action: { (controller, action) in
|
||||
performAction.invoke(.toggleInstantView(false))
|
||||
action(.default)
|
||||
})))
|
||||
|
@ -93,17 +93,13 @@ final class ContactsControllerNode: ASDisplayNode, ASGestureRecognizerDelegate {
|
||||
self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
self.stringsPromise.set(.single(self.presentationData.strings))
|
||||
|
||||
var addNearbyImpl: (() -> Void)?
|
||||
var inviteImpl: (() -> Void)?
|
||||
|
||||
let presentation = combineLatest(sortOrder, self.stringsPromise.get())
|
||||
|> map { sortOrder, strings -> ContactListPresentation in
|
||||
let options = [ContactListAdditionalOption(title: strings.Contacts_AddPeopleNearby, icon: .generic(UIImage(bundleImageName: "Contact List/PeopleNearbyIcon")!), action: {
|
||||
addNearbyImpl?()
|
||||
}), ContactListAdditionalOption(title: strings.Contacts_InviteFriends, icon: .generic(UIImage(bundleImageName: "Contact List/AddMemberIcon")!), action: {
|
||||
let options = [ContactListAdditionalOption(title: strings.Contacts_InviteFriends, icon: .generic(UIImage(bundleImageName: "Contact List/AddMemberIcon")!), action: {
|
||||
inviteImpl?()
|
||||
})]
|
||||
|
||||
switch sortOrder {
|
||||
case .presence:
|
||||
return .orderedByPresence(options: options)
|
||||
@ -145,13 +141,7 @@ final class ContactsControllerNode: ASDisplayNode, ASGestureRecognizerDelegate {
|
||||
}
|
||||
}
|
||||
}).strict()
|
||||
|
||||
addNearbyImpl = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.openPeopleNearby?()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inviteImpl = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.openInvite?()
|
||||
|
@ -471,7 +471,7 @@ private enum CreateGiveawayEntry: ItemListNodeEntry {
|
||||
default:
|
||||
color = .blue
|
||||
}
|
||||
case let .stars(amount):
|
||||
case let .stars(amount, _):
|
||||
if amount <= 1000 {
|
||||
color = .green
|
||||
} else if amount < 2500 {
|
||||
@ -777,7 +777,7 @@ private func createGiveawayControllerEntries(
|
||||
case let .premium(months):
|
||||
title = presentationData.strings.BoostGift_PrepaidGiveawayCount(prepaidGiveaway.quantity)
|
||||
text = presentationData.strings.BoostGift_PrepaidGiveawayMonths("\(months)").string
|
||||
case let .stars(stars):
|
||||
case let .stars(stars, _):
|
||||
//TODO:localize
|
||||
title = "\(stars) Telegram Stars"
|
||||
text = "among \(prepaidGiveaway.quantity) winners"
|
||||
@ -1013,7 +1013,7 @@ public func createGiveawayController(context: AccountContext, updatedPresentatio
|
||||
let initialStars: Int64
|
||||
let initialWinners: Int32
|
||||
if case let .prepaid(prepaidGiveaway) = subject {
|
||||
if case let .stars(stars) = prepaidGiveaway.prize {
|
||||
if case let .stars(stars, _) = prepaidGiveaway.prize {
|
||||
initialStars = stars
|
||||
} else {
|
||||
initialStars = 500
|
||||
|
@ -1050,7 +1050,7 @@ private enum StatsEntry: ItemListNodeEntry {
|
||||
default:
|
||||
color = .blue
|
||||
}
|
||||
case let .stars(amount):
|
||||
case let .stars(amount, _):
|
||||
if amount <= 1000 {
|
||||
color = .green
|
||||
} else if amount < 2500 {
|
||||
@ -1440,7 +1440,7 @@ private func boostsEntries(
|
||||
case let .premium(months):
|
||||
title = presentationData.strings.Stats_Boosts_PrepaidGiveawayCount(giveaway.quantity)
|
||||
text = presentationData.strings.Stats_Boosts_PrepaidGiveawayMonths("\(months)").string
|
||||
case let .stars(stars):
|
||||
case let .stars(stars, _):
|
||||
title = "\(stars) Telegram Stars"
|
||||
text = "among \(giveaway.quantity) winners"
|
||||
}
|
||||
|
@ -746,7 +746,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[1958953753] = { return Api.PremiumGiftOption.parse_premiumGiftOption($0) }
|
||||
dict[1596792306] = { return Api.PremiumSubscriptionOption.parse_premiumSubscriptionOption($0) }
|
||||
dict[-1303143084] = { return Api.PrepaidGiveaway.parse_prepaidGiveaway($0) }
|
||||
dict[-1973402371] = { return Api.PrepaidGiveaway.parse_prepaidStarsGiveaway($0) }
|
||||
dict[-1700956192] = { return Api.PrepaidGiveaway.parse_prepaidStarsGiveaway($0) }
|
||||
dict[-1534675103] = { return Api.PrivacyKey.parse_privacyKeyAbout($0) }
|
||||
dict[1124062251] = { return Api.PrivacyKey.parse_privacyKeyAddedByPhone($0) }
|
||||
dict[536913176] = { return Api.PrivacyKey.parse_privacyKeyBirthday($0) }
|
||||
|
@ -1013,7 +1013,7 @@ public extension Api {
|
||||
public extension Api {
|
||||
enum PrepaidGiveaway: TypeConstructorDescription {
|
||||
case prepaidGiveaway(id: Int64, months: Int32, quantity: Int32, date: Int32)
|
||||
case prepaidStarsGiveaway(id: Int64, stars: Int64, quantity: Int32, date: Int32)
|
||||
case prepaidStarsGiveaway(id: Int64, stars: Int64, quantity: Int32, boosts: Int32, date: Int32)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
@ -1026,13 +1026,14 @@ public extension Api {
|
||||
serializeInt32(quantity, buffer: buffer, boxed: false)
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .prepaidStarsGiveaway(let id, let stars, let quantity, let date):
|
||||
case .prepaidStarsGiveaway(let id, let stars, let quantity, let boosts, let date):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1973402371)
|
||||
buffer.appendInt32(-1700956192)
|
||||
}
|
||||
serializeInt64(id, buffer: buffer, boxed: false)
|
||||
serializeInt64(stars, buffer: buffer, boxed: false)
|
||||
serializeInt32(quantity, buffer: buffer, boxed: false)
|
||||
serializeInt32(boosts, buffer: buffer, boxed: false)
|
||||
serializeInt32(date, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
@ -1042,8 +1043,8 @@ public extension Api {
|
||||
switch self {
|
||||
case .prepaidGiveaway(let id, let months, let quantity, let date):
|
||||
return ("prepaidGiveaway", [("id", id as Any), ("months", months as Any), ("quantity", quantity as Any), ("date", date as Any)])
|
||||
case .prepaidStarsGiveaway(let id, let stars, let quantity, let date):
|
||||
return ("prepaidStarsGiveaway", [("id", id as Any), ("stars", stars as Any), ("quantity", quantity as Any), ("date", date as Any)])
|
||||
case .prepaidStarsGiveaway(let id, let stars, let quantity, let boosts, let date):
|
||||
return ("prepaidStarsGiveaway", [("id", id as Any), ("stars", stars as Any), ("quantity", quantity as Any), ("boosts", boosts as Any), ("date", date as Any)])
|
||||
}
|
||||
}
|
||||
|
||||
@ -1076,12 +1077,15 @@ public extension Api {
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
var _5: Int32?
|
||||
_5 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.PrepaidGiveaway.prepaidStarsGiveaway(id: _1!, stars: _2!, quantity: _3!, date: _4!)
|
||||
let _c5 = _5 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 && _c5 {
|
||||
return Api.PrepaidGiveaway.prepaidStarsGiveaway(id: _1!, stars: _2!, quantity: _3!, boosts: _4!, date: _5!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
@ -91,7 +91,7 @@ public enum PremiumGiveawayInfo: Equatable {
|
||||
public struct PrepaidGiveaway: Equatable {
|
||||
public enum Prize: Equatable {
|
||||
case premium(months: Int32)
|
||||
case stars(stars: Int64)
|
||||
case stars(stars: Int64, boosts: Int32)
|
||||
}
|
||||
|
||||
public let id: Int64
|
||||
@ -312,9 +312,9 @@ extension PrepaidGiveaway {
|
||||
self.prize = .premium(months: months)
|
||||
self.quantity = quantity
|
||||
self.date = date
|
||||
case let .prepaidStarsGiveaway(id, stars, quantity, date):
|
||||
case let .prepaidStarsGiveaway(id, stars, quantity, boosts, date):
|
||||
self.id = id
|
||||
self.prize = .stars(stars: stars)
|
||||
self.prize = .stars(stars: stars, boosts: boosts)
|
||||
self.quantity = quantity
|
||||
self.date = date
|
||||
}
|
||||
|
@ -551,7 +551,7 @@ public final class ChatMessageAvatarHeaderNodeImpl: ListViewItemHeaderNode, Chat
|
||||
}
|
||||
|
||||
public func setPeer(context: AccountContext, theme: PresentationTheme, synchronousLoad: Bool, peer: Peer, authorOfMessage: MessageReference?, emptyColor: UIColor) {
|
||||
self.containerNode.isGestureEnabled = peer.smallProfileImage != nil
|
||||
self.containerNode.isGestureEnabled = true
|
||||
|
||||
var overrideImage: AvatarNodeImageOverride?
|
||||
if peer.isDeleted {
|
||||
|
12
submodules/TelegramUI/Images.xcassets/Instant View/InstantViewOff.imageset/Contents.json
vendored
Normal file
12
submodules/TelegramUI/Images.xcassets/Instant View/InstantViewOff.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "boostoff_24.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
submodules/TelegramUI/Images.xcassets/Instant View/InstantViewOff.imageset/boostoff_24.pdf
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Instant View/InstantViewOff.imageset/boostoff_24.pdf
vendored
Normal file
Binary file not shown.
@ -306,11 +306,7 @@ public final class AccountContextImpl: AccountContext {
|
||||
|
||||
self.account.stateManager.starsContext = self.starsContext
|
||||
|
||||
if let locationManager = self.sharedContextImpl.locationManager, sharedContext.applicationBindings.isMainApp && !temp {
|
||||
self.peersNearbyManager = PeersNearbyManagerImpl(account: account, engine: self.engine, locationManager: locationManager, inForeground: sharedContext.applicationBindings.applicationInForeground)
|
||||
} else {
|
||||
self.peersNearbyManager = nil
|
||||
}
|
||||
self.peersNearbyManager = nil
|
||||
|
||||
self.cachedGroupCallContexts = AccountGroupCallContextCacheImpl()
|
||||
|
||||
|
@ -129,6 +129,7 @@ import PhoneNumberFormat
|
||||
import OwnershipTransferController
|
||||
import OldChannelsController
|
||||
import BrowserUI
|
||||
import NotificationPeerExceptionController
|
||||
|
||||
public enum ChatControllerPeekActions {
|
||||
case standard
|
||||
@ -3617,13 +3618,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
let _ = (dataSignal
|
||||
|> deliverOnMainQueue).startStandalone(next: { [weak self] peer, message in
|
||||
guard let strongSelf = self, let peer = peer, peer.smallProfileImage != nil else {
|
||||
guard let strongSelf = self, let peer = peer else {
|
||||
return
|
||||
}
|
||||
|
||||
let galleryController = AvatarGalleryController(context: context, peer: peer, remoteEntries: nil, replaceRootController: { controller, ready in
|
||||
}, synchronousLoad: true)
|
||||
galleryController.setHintWillBePresentedInPreviewingContext(true)
|
||||
|
||||
var isChannel = false
|
||||
if case let .channel(peer) = peer, case .broadcast = peer.info {
|
||||
@ -3681,7 +3678,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
strongSelf.canReadHistory.set(false)
|
||||
|
||||
let contextController = ContextController(presentationData: strongSelf.presentationData, source: .controller(ChatContextControllerContentSourceImpl(controller: galleryController, sourceNode: node, passthroughTouches: false)), items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
|
||||
let source: ContextContentSource
|
||||
if let _ = peer.smallProfileImage {
|
||||
let galleryController = AvatarGalleryController(context: context, peer: peer, remoteEntries: nil, replaceRootController: { controller, ready in
|
||||
}, synchronousLoad: true)
|
||||
galleryController.setHintWillBePresentedInPreviewingContext(true)
|
||||
source = .controller(ChatContextControllerContentSourceImpl(controller: galleryController, sourceNode: node, passthroughTouches: false))
|
||||
} else {
|
||||
source = .reference(ChatControllerContextReferenceContentSource(controller: strongSelf, sourceView: node.view, insets: .zero))
|
||||
}
|
||||
|
||||
let contextController = ContextController(presentationData: strongSelf.presentationData, source: source, items: .single(ContextController.Items(content: .list(items))), gesture: gesture)
|
||||
contextController.dismissed = { [weak self] in
|
||||
self?.canReadHistory.set(true)
|
||||
}
|
||||
@ -4655,58 +4662,347 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
case .peer, .replyThread:
|
||||
let avatarNode = ChatAvatarNavigationNode()
|
||||
avatarNode.contextAction = { [weak self] node, gesture in
|
||||
guard let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer, peer.smallProfileImage != nil else {
|
||||
guard let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer else {
|
||||
return
|
||||
}
|
||||
let galleryController = AvatarGalleryController(context: strongSelf.context, peer: EnginePeer(peer), remoteEntries: nil, replaceRootController: { controller, ready in
|
||||
}, synchronousLoad: true)
|
||||
galleryController.setHintWillBePresentedInPreviewingContext(true)
|
||||
|
||||
let items: Signal<[ContextMenuItem], NoError> = context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.CanViewStats(id: peer.id)
|
||||
)
|
||||
|> map { canViewStats -> [ContextMenuItem] in
|
||||
var items: [ContextMenuItem] = [
|
||||
.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_LinkDialogOpen, icon: { theme in
|
||||
let items: Signal<[ContextMenuItem], NoError>
|
||||
switch chatLocation {
|
||||
case .peer:
|
||||
items = context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.CanViewStats(id: peer.id)
|
||||
)
|
||||
|> map { canViewStats -> [ContextMenuItem] in
|
||||
var items: [ContextMenuItem] = []
|
||||
|
||||
let openText = strongSelf.presentationData.strings.Conversation_ContextMenuOpenProfile
|
||||
items.append(.action(ContextMenuActionItem(text: openText, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Info"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
self?.navigationButtonAction(.openChatInfo(expandAvatar: true, recommendedChannels: false))
|
||||
}))
|
||||
]
|
||||
if canViewStats {
|
||||
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.ChannelInfo_Stats, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Statistics"), color: theme.actionSheet.primaryTextColor)
|
||||
})))
|
||||
|
||||
if canViewStats {
|
||||
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.ChannelInfo_Stats, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Statistics"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
guard let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer else {
|
||||
return
|
||||
}
|
||||
strongSelf.view.endEditing(true)
|
||||
|
||||
let statsController: ViewController
|
||||
if let channel = peer as? TelegramChannel, case .group = channel.info {
|
||||
statsController = groupStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id)
|
||||
} else {
|
||||
statsController = channelStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id)
|
||||
}
|
||||
strongSelf.push(statsController)
|
||||
})))
|
||||
}
|
||||
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_Search, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Search"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
guard let strongSelf = self, let peer = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer else {
|
||||
return
|
||||
}
|
||||
strongSelf.view.endEditing(true)
|
||||
|
||||
let statsController: ViewController
|
||||
if let channel = peer as? TelegramChannel, case .group = channel.info {
|
||||
statsController = groupStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id)
|
||||
} else {
|
||||
statsController = channelStatsController(context: context, updatedPresentationData: strongSelf.updatedPresentationData, peerId: peer.id)
|
||||
}
|
||||
strongSelf.push(statsController)
|
||||
self?.interfaceInteraction?.beginMessageSearch(.everything, "")
|
||||
})))
|
||||
|
||||
return items
|
||||
}
|
||||
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_Search, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Search"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
self?.interfaceInteraction?.beginMessageSearch(.everything, "")
|
||||
})))
|
||||
return items
|
||||
case let .replyThread(message):
|
||||
let peerId = peer.id
|
||||
let threadId = message.threadId
|
||||
|
||||
items = context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peerId),
|
||||
TelegramEngine.EngineData.Item.Peer.ThreadData(id: peer.id, threadId: threadId),
|
||||
TelegramEngine.EngineData.Item.NotificationSettings.Global()
|
||||
)
|
||||
|> map { peerNotificationSettings, threadData, globalNotificationSettings -> [ContextMenuItem] in
|
||||
guard let channel = peer as? TelegramChannel else {
|
||||
return []
|
||||
}
|
||||
guard let threadData = threadData else {
|
||||
return []
|
||||
}
|
||||
|
||||
var items: [ContextMenuItem] = []
|
||||
|
||||
var isMuted = false
|
||||
switch threadData.notificationSettings.muteState {
|
||||
case .muted:
|
||||
isMuted = true
|
||||
case .unmuted:
|
||||
isMuted = false
|
||||
case .default:
|
||||
var peerIsMuted = false
|
||||
if case let .muted(until) = peerNotificationSettings.muteState, until >= Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) {
|
||||
peerIsMuted = true
|
||||
} else if case .default = peerNotificationSettings.muteState {
|
||||
if case .group = channel.info {
|
||||
peerIsMuted = !globalNotificationSettings.groupChats.enabled
|
||||
}
|
||||
}
|
||||
isMuted = peerIsMuted
|
||||
}
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: isMuted ? presentationData.strings.ChatList_Context_Unmute : presentationData.strings.ChatList_Context_Mute, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isMuted ? "Chat/Context Menu/Unmute" : "Chat/Context Menu/Muted"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, f in
|
||||
if isMuted {
|
||||
let _ = (context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: 0)
|
||||
|> deliverOnMainQueue).startStandalone(completed: {
|
||||
f(.default)
|
||||
})
|
||||
} else {
|
||||
var items: [ContextMenuItem] = []
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.PeerInfo_MuteFor, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Mute2d"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { c, _ in
|
||||
var subItems: [ContextMenuItem] = []
|
||||
|
||||
let presetValues: [Int32] = [
|
||||
1 * 60 * 60,
|
||||
8 * 60 * 60,
|
||||
1 * 24 * 60 * 60,
|
||||
7 * 24 * 60 * 60
|
||||
]
|
||||
|
||||
for value in presetValues {
|
||||
subItems.append(.action(ContextMenuActionItem(text: muteForIntervalString(strings: presentationData.strings, value: value), icon: { _ in
|
||||
return nil
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: value).startStandalone()
|
||||
|
||||
self?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_mute_for", scale: 0.066, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipMutedFor(mutedForTimeIntervalString(strings: presentationData.strings, value: value)).string, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
}
|
||||
|
||||
subItems.append(.action(ContextMenuActionItem(text: presentationData.strings.PeerInfo_MuteForCustom, icon: { _ in
|
||||
return nil
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
// if let chatListController = chatListController {
|
||||
// openCustomMute(context: context, peerId: peerId, threadId: threadId, baseController: chatListController)
|
||||
// }
|
||||
})))
|
||||
|
||||
c?.setItems(.single(ContextController.Items(content: .list(subItems))), minHeight: nil, animated: true)
|
||||
})))
|
||||
|
||||
items.append(.separator)
|
||||
|
||||
var isSoundEnabled = true
|
||||
switch threadData.notificationSettings.messageSound {
|
||||
case .none:
|
||||
isSoundEnabled = false
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if case .muted = threadData.notificationSettings.muteState {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.PeerInfo_ButtonUnmute, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/SoundOn"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: nil).startStandalone()
|
||||
|
||||
let iconColor: UIColor = .white
|
||||
self?.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: presentationData.strings.PeerInfo_TooltipUnmuted, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
} else if !isSoundEnabled {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.PeerInfo_EnableSound, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/SoundOn"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .default).startStandalone()
|
||||
|
||||
self?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_sound_on", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipSoundEnabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
} else {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.PeerInfo_DisableSound, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/SoundOff"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: .none).startStandalone()
|
||||
|
||||
self?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_sound_off", scale: 0.056, colors: [:], title: nil, text: presentationData.strings.PeerInfo_TooltipSoundDisabled, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
}
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.PeerInfo_NotificationsCustomize, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Customize"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
|
||||
let _ = (context.engine.data.get(
|
||||
TelegramEngine.EngineData.Item.NotificationSettings.Global()
|
||||
)
|
||||
|> deliverOnMainQueue).startStandalone(next: { globalSettings in
|
||||
let updatePeerSound: (PeerId, PeerMessageSound) -> Signal<Void, NoError> = { peerId, sound in
|
||||
return context.engine.peers.updatePeerNotificationSoundInteractive(peerId: peerId, threadId: threadId, sound: sound) |> deliverOnMainQueue
|
||||
}
|
||||
|
||||
let updatePeerNotificationInterval: (PeerId, Int32?) -> Signal<Void, NoError> = { peerId, muteInterval in
|
||||
return context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: muteInterval) |> deliverOnMainQueue
|
||||
}
|
||||
|
||||
let updatePeerDisplayPreviews: (PeerId, PeerNotificationDisplayPreviews) -> Signal<Void, NoError> = {
|
||||
peerId, displayPreviews in
|
||||
return context.engine.peers.updatePeerDisplayPreviewsSetting(peerId: peerId, threadId: threadId, displayPreviews: displayPreviews) |> deliverOnMainQueue
|
||||
}
|
||||
|
||||
let updatePeerStoriesMuted: (PeerId, PeerStoryNotificationSettings.Mute) -> Signal<Void, NoError> = {
|
||||
peerId, mute in
|
||||
return context.engine.peers.updatePeerStoriesMutedSetting(peerId: peerId, mute: mute) |> deliverOnMainQueue
|
||||
}
|
||||
|
||||
let updatePeerStoriesHideSender: (PeerId, PeerStoryNotificationSettings.HideSender) -> Signal<Void, NoError> = {
|
||||
peerId, hideSender in
|
||||
return context.engine.peers.updatePeerStoriesHideSenderSetting(peerId: peerId, hideSender: hideSender) |> deliverOnMainQueue
|
||||
}
|
||||
|
||||
let updatePeerStorySound: (PeerId, PeerMessageSound) -> Signal<Void, NoError> = { peerId, sound in
|
||||
return context.engine.peers.updatePeerStorySoundInteractive(peerId: peerId, sound: sound) |> deliverOnMainQueue
|
||||
}
|
||||
|
||||
let defaultSound: PeerMessageSound
|
||||
|
||||
if case .broadcast = channel.info {
|
||||
defaultSound = globalSettings.channels.sound._asMessageSound()
|
||||
} else {
|
||||
defaultSound = globalSettings.groupChats.sound._asMessageSound()
|
||||
}
|
||||
|
||||
let canRemove = false
|
||||
|
||||
let exceptionController = notificationPeerExceptionController(context: context, updatedPresentationData: nil, peer: .channel(channel), threadId: threadId, isStories: nil, canRemove: canRemove, defaultSound: defaultSound, defaultStoriesSound: defaultSound, edit: true, updatePeerSound: { peerId, sound in
|
||||
let _ = (updatePeerSound(peerId, sound)
|
||||
|> deliverOnMainQueue).startStandalone(next: { _ in
|
||||
})
|
||||
}, updatePeerNotificationInterval: { [weak self] peerId, muteInterval in
|
||||
let _ = (updatePeerNotificationInterval(peerId, muteInterval)
|
||||
|> deliverOnMainQueue).startStandalone(next: { _ in
|
||||
if let muteInterval = muteInterval, muteInterval == Int32.max {
|
||||
let iconColor: UIColor = .white
|
||||
self?.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: presentationData.strings.PeerInfo_TooltipMutedForever, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
}
|
||||
})
|
||||
}, updatePeerDisplayPreviews: { peerId, displayPreviews in
|
||||
let _ = (updatePeerDisplayPreviews(peerId, displayPreviews)
|
||||
|> deliverOnMainQueue).startStandalone(next: { _ in
|
||||
|
||||
})
|
||||
}, updatePeerStoriesMuted: { peerId, mute in
|
||||
let _ = (updatePeerStoriesMuted(peerId, mute)
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
}, updatePeerStoriesHideSender: { peerId, hideSender in
|
||||
let _ = (updatePeerStoriesHideSender(peerId, hideSender)
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
}, updatePeerStorySound: { peerId, sound in
|
||||
let _ = (updatePeerStorySound(peerId, sound)
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
}, removePeerFromExceptions: {
|
||||
}, modifiedPeer: {
|
||||
})
|
||||
exceptionController.navigationPresentation = .modal
|
||||
self?.push(exceptionController)
|
||||
})
|
||||
})))
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.PeerInfo_MuteForever, textColor: .destructive, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Muted"), color: theme.contextMenu.destructiveColor)
|
||||
}, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.updatePeerMuteSetting(peerId: peerId, threadId: threadId, muteInterval: Int32.max).startStandalone()
|
||||
|
||||
let iconColor: UIColor = .white
|
||||
self?.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: presentationData.strings.PeerInfo_TooltipMutedForever, customUndoText: nil, timeout: nil), elevatedLayout: false, animateInAsReplacement: true, action: { _ in return false }), in: .current)
|
||||
})))
|
||||
|
||||
c?.setItems(.single(ContextController.Items(content: .list(items))), minHeight: nil, animated: true)
|
||||
}
|
||||
})))
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: strongSelf.presentationData.strings.Conversation_Search, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Search"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
f(.dismissWithoutContent)
|
||||
self?.interfaceInteraction?.beginMessageSearch(.everything, "")
|
||||
})))
|
||||
|
||||
if threadId != 1 {
|
||||
var canOpenClose = false
|
||||
if channel.flags.contains(.isCreator) {
|
||||
canOpenClose = true
|
||||
} else if channel.hasPermission(.manageTopics) {
|
||||
canOpenClose = true
|
||||
} else if threadData.isOwnedByMe {
|
||||
canOpenClose = true
|
||||
}
|
||||
if canOpenClose {
|
||||
items.append(.action(ContextMenuActionItem(text: threadData.isClosed ? presentationData.strings.ChatList_Context_ReopenTopic : presentationData.strings.ChatList_Context_CloseTopic, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: threadData.isClosed ? "Chat/Context Menu/Play": "Chat/Context Menu/Pause"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.setForumChannelTopicClosed(id: peer.id, threadId: threadId, isClosed: !threadData.isClosed).startStandalone()
|
||||
})))
|
||||
}
|
||||
// if channel.hasPermission(.deleteAllMessages) {
|
||||
// items.append(.action(ContextMenuActionItem(text: strings.ChatList_Context_Delete, textColor: .destructive, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) }, action: { [weak chatListController] _, f in
|
||||
// f(.default)
|
||||
//
|
||||
// chatListController?.deletePeerThread(peerId: peerId, threadId: threadId)
|
||||
// })))
|
||||
// }
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
default:
|
||||
items = .single([])
|
||||
}
|
||||
|
||||
strongSelf.chatDisplayNode.messageTransitionNode.dismissMessageReactionContexts()
|
||||
|
||||
strongSelf.canReadHistory.set(false)
|
||||
|
||||
let contextController = ContextController(presentationData: strongSelf.presentationData, source: .controller(ChatContextControllerContentSourceImpl(controller: galleryController, sourceNode: node, passthroughTouches: false)), items: items |> map { ContextController.Items(content: .list($0)) }, gesture: gesture)
|
||||
let source: ContextContentSource
|
||||
if let peer = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer, peer.smallProfileImage != nil {
|
||||
let galleryController = AvatarGalleryController(context: strongSelf.context, peer: EnginePeer(peer), remoteEntries: nil, replaceRootController: { controller, ready in
|
||||
}, synchronousLoad: true)
|
||||
galleryController.setHintWillBePresentedInPreviewingContext(true)
|
||||
source = .controller(ChatContextControllerContentSourceImpl(controller: galleryController, sourceNode: node, passthroughTouches: false))
|
||||
} else {
|
||||
source = .reference(ChatControllerContextReferenceContentSource(controller: strongSelf, sourceView: node.view, insets: .zero))
|
||||
}
|
||||
|
||||
let contextController = ContextController(presentationData: strongSelf.presentationData, source: source, items: items |> map { ContextController.Items(content: .list($0)) }, gesture: gesture)
|
||||
contextController.dismissed = { [weak self] in
|
||||
self?.canReadHistory.set(true)
|
||||
}
|
||||
@ -5123,7 +5419,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
imageOverride = nil
|
||||
}
|
||||
(strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.setPeer(context: strongSelf.context, theme: strongSelf.presentationData.theme, peer: EnginePeer(peer), overrideImage: imageOverride)
|
||||
(strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.contextActionIsEnabled = strongSelf.chatLocation.threadId == nil && peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil
|
||||
(strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.contextActionIsEnabled = peer.restrictionText(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with { $0 }) == nil
|
||||
strongSelf.chatInfoNavigationButton?.buttonItem.accessibilityLabel = presentationInterfaceState.strings.Conversation_ContextMenuOpenProfile
|
||||
|
||||
strongSelf.storyStats = peerView.storyStats
|
||||
@ -5660,7 +5956,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
} else if case let .replyThread(messagePromise) = self.chatLocationInfoData, let peerId = peerId {
|
||||
self.reportIrrelvantGeoNoticePromise.set(.single(nil))
|
||||
|
||||
|
||||
let replyThreadType: ChatTitleContent.ReplyThreadType
|
||||
var replyThreadId: Int64?
|
||||
switch chatLocation {
|
||||
@ -6013,6 +6309,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if strongSelf.isNodeLoaded {
|
||||
strongSelf.chatDisplayNode.overlayTitle = strongSelf.overlayTitle
|
||||
}
|
||||
(strongSelf.chatInfoNavigationButton?.buttonItem.customDisplayNode as? ChatAvatarNavigationNode)?.contextActionIsEnabled = true
|
||||
|
||||
var peerDiscussionId: PeerId?
|
||||
var peerGeoLocation: PeerGeoLocation?
|
||||
|
Loading…
x
Reference in New Issue
Block a user