mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit '26f946730a27623134d8ed8dd8fdd5c51dc55e92' into beta
This commit is contained in:
commit
2c294c7e48
@ -24,6 +24,10 @@
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>IntentsSupported</key>
|
||||
<array>
|
||||
<string>INSendMessageIntent</string>
|
||||
</array>
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<string>SUBQUERY (
|
||||
extensionItems,
|
||||
|
@ -4988,6 +4988,9 @@ Any member of this group will be able to see messages in the channel.";
|
||||
|
||||
"Wallet.Receive.ShareInvoiceUrlInfo" = "Share this link with other Gram wallet owners to receive %@ Grams from them.";
|
||||
|
||||
"Settings.Wallet" = "Gram Wallet";
|
||||
"SettingsSearch.Synonyms.Wallet" = "TON Telegram Open Network Crypto";
|
||||
|
||||
"Conversation.ClearCache" = "Clear Cache";
|
||||
"ClearCache.Description" = "Media files will be deleted from your phone, but available for re-downloading when necessary.";
|
||||
"ClearCache.FreeSpaceDescription" = "If you want to save space on your device, you don't need to delete anything.\n\nYou can use cache settings to remove unnecessary media — and re-download files if you need them again.";
|
||||
@ -5038,6 +5041,7 @@ Any member of this group will be able to see messages in the channel.";
|
||||
"AutoNightTheme.System" = "System";
|
||||
|
||||
"ChatSettings.OpenLinksIn" = "Open Links in";
|
||||
"SettingsSearch.Synonyms.ChatSettings.OpenLinksIn" = "Browser";
|
||||
|
||||
"WebBrowser.Title" = "Web Browser";
|
||||
"WebBrowser.DefaultBrowser" = "DEFAULT WEB BROWSER";
|
||||
|
@ -287,7 +287,7 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
|
||||
return cacheSettings
|
||||
})
|
||||
|
||||
var presentControllerImpl: ((ViewController, Any?) -> Void)?
|
||||
var presentControllerImpl: ((ViewController, PresentationContextType, Any?) -> Void)?
|
||||
|
||||
let statsPromise = Promise<CacheUsageStatsResult?>()
|
||||
let resetStats: () -> Void = {
|
||||
@ -341,7 +341,7 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
|
||||
ActionSheetItemGroup(items: timeoutItems),
|
||||
ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })])
|
||||
])
|
||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
presentControllerImpl?(controller, .window(.root), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}, openClearAll: {
|
||||
let _ = (statsPromise.get()
|
||||
|> take(1)
|
||||
@ -508,7 +508,7 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
|
||||
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: {
|
||||
cancelImpl?()
|
||||
}))
|
||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
presentControllerImpl?(controller, .window(.root), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
return ActionDisposable { [weak controller] in
|
||||
Queue.mainQueue().async() {
|
||||
controller?.dismiss()
|
||||
@ -533,7 +533,7 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
statsPromise.set(.single(.result(resultStats)))
|
||||
let deviceName = UIDevice.current.userInterfaceIdiom == .pad ? "iPad" : "iPhone"
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .succeed(text: presentationData.strings.ClearCache_Success("\(dataSizeString(totalSize, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator))", deviceName).0), elevatedLayout: false, action: { _ in }), nil)
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .succeed(text: presentationData.strings.ClearCache_Success("\(dataSizeString(totalSize, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator))", deviceName).0), elevatedLayout: false, action: { _ in }), .current, nil)
|
||||
}))
|
||||
}
|
||||
|
||||
@ -544,7 +544,7 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
|
||||
ActionSheetItemGroup(items: items),
|
||||
ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })])
|
||||
])
|
||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
presentControllerImpl?(controller, .window(.root), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}
|
||||
}
|
||||
})
|
||||
@ -576,12 +576,14 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
|
||||
|
||||
var sizeIndex: [PeerCacheUsageCategory: (Bool, Int64)] = [:]
|
||||
|
||||
var itemIndex = 0
|
||||
var itemIndex = 1
|
||||
|
||||
var finalSize: Int64 = 0
|
||||
let updateTotalSize: () -> Void = { [weak controller] in
|
||||
controller?.updateItem(groupIndex: 0, itemIndex: itemIndex, { item in
|
||||
let title: String
|
||||
let filteredSize = sizeIndex.values.reduce(0, { $0 + ($1.0 ? $1.1 : 0) })
|
||||
finalSize = filteredSize
|
||||
|
||||
if filteredSize == 0 {
|
||||
title = presentationData.strings.Cache_ClearNone
|
||||
@ -633,6 +635,7 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
|
||||
}
|
||||
}
|
||||
}
|
||||
finalSize = totalSize
|
||||
|
||||
if !items.isEmpty {
|
||||
items.append(ActionSheetButtonItem(title: presentationData.strings.Cache_Clear("\(dataSizeString(totalSize, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator))").0, action: {
|
||||
@ -687,7 +690,7 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
|
||||
let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: {
|
||||
cancelImpl?()
|
||||
}))
|
||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
presentControllerImpl?(controller, .window(.root), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
return ActionDisposable { [weak controller] in
|
||||
Queue.mainQueue().async() {
|
||||
controller?.dismiss()
|
||||
@ -712,7 +715,7 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
statsPromise.set(.single(.result(resultStats)))
|
||||
let deviceName = UIDevice.current.userInterfaceIdiom == .pad ? "iPad" : "iPhone"
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .succeed(text: presentationData.strings.ClearCache_Success("\(dataSizeString(totalSize, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator))", deviceName).0), elevatedLayout: false, action: { _ in }), nil)
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .succeed(text: presentationData.strings.ClearCache_Success("\(dataSizeString(finalSize, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator))", deviceName).0), elevatedLayout: false, action: { _ in }), .current, nil)
|
||||
}))
|
||||
}
|
||||
|
||||
@ -723,7 +726,7 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
|
||||
ActionSheetItemGroup(items: items),
|
||||
ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })])
|
||||
])
|
||||
presentControllerImpl?(controller, ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
presentControllerImpl?(controller, .window(.root), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -747,8 +750,8 @@ public func storageUsageController(context: AccountContext, isModal: Bool = fals
|
||||
}
|
||||
|
||||
let controller = ItemListController(context: context, state: signal)
|
||||
presentControllerImpl = { [weak controller] c, a in
|
||||
controller?.present(c, in: .window(.root), with: a)
|
||||
presentControllerImpl = { [weak controller] c, contextType, a in
|
||||
controller?.present(c, in: contextType, with: a)
|
||||
}
|
||||
dismissImpl = { [weak controller] in
|
||||
controller?.dismiss()
|
||||
|
@ -77,6 +77,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
private let backgroundNode: ASImageNode
|
||||
private let topStripeNode: ASDisplayNode
|
||||
private let bottomStripeNode: ASDisplayNode
|
||||
private let maskNode: ASImageNode
|
||||
|
||||
private let containerNode: ASDisplayNode
|
||||
|
||||
@ -101,6 +102,8 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
self.bottomStripeNode = ASDisplayNode()
|
||||
self.bottomStripeNode.isLayerBacked = true
|
||||
|
||||
self.maskNode = ASImageNode()
|
||||
|
||||
self.containerNode = ASDisplayNode()
|
||||
self.containerNode.subnodeTransform = CATransform3DMakeRotation(CGFloat.pi, 0.0, 0.0, 1.0)
|
||||
|
||||
@ -232,11 +235,18 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
if strongSelf.bottomStripeNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.bottomStripeNode, at: 2)
|
||||
}
|
||||
if strongSelf.maskNode.supernode == nil {
|
||||
strongSelf.insertSubnode(strongSelf.maskNode, at: 3)
|
||||
}
|
||||
let hasCorners = itemListHasRoundedBlockLayout(params)
|
||||
var hasTopCorners = false
|
||||
var hasBottomCorners = false
|
||||
switch neighbors.top {
|
||||
case .sameSection(false):
|
||||
strongSelf.topStripeNode.isHidden = true
|
||||
default:
|
||||
strongSelf.topStripeNode.isHidden = false
|
||||
hasTopCorners = true
|
||||
strongSelf.topStripeNode.isHidden = hasCorners
|
||||
}
|
||||
let bottomStripeInset: CGFloat
|
||||
let bottomStripeOffset: CGFloat
|
||||
@ -247,12 +257,17 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
default:
|
||||
bottomStripeInset = 0.0
|
||||
bottomStripeOffset = 0.0
|
||||
hasBottomCorners = true
|
||||
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
|
||||
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: layoutSize.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height + bottomStripeOffset), size: CGSize(width: layoutSize.width - bottomStripeInset, height: separatorHeight))
|
||||
|
||||
|
||||
strongSelf.textNode.attributedText = NSAttributedString(string: item.tooltipText, font: Font.regular(14.0), textColor: .white, paragraphAlignment: .center)
|
||||
|
||||
var textSize = strongSelf.textNode.updateLayout(CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude))
|
||||
@ -280,7 +295,7 @@ class ForwardPrivacyChatPreviewItemNode: ListViewItemNode {
|
||||
arrowOnBottom = false
|
||||
}
|
||||
|
||||
let horizontalOrigin: CGFloat = floor(min(max(8.0, sourceRect.midX - contentSize.width / 2.0), layout.size.width - contentSize.width - 8.0))
|
||||
let horizontalOrigin: CGFloat = floor(min(max(params.leftInset + 8.0, sourceRect.midX - contentSize.width / 2.0), layout.size.width - contentSize.width - 8.0))
|
||||
|
||||
strongSelf.tooltipContainerNode.frame = CGRect(origin: CGPoint(x: horizontalOrigin, y: verticalOrigin), size: contentSize)
|
||||
strongSelf.tooltipContainerNode.relativeArrowPosition = (sourceRect.midX - horizontalOrigin, arrowOnBottom)
|
||||
|
@ -626,6 +626,9 @@ private func dataSearchableItems(context: AccountContext) -> [SettingsSearchable
|
||||
}),
|
||||
SettingsSearchableItem(id: .data(13), title: strings.ChatSettings_DownloadInBackground, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_DownloadInBackground), icon: icon, breadcrumbs: [strings.Settings_ChatSettings], present: { context, _, present in
|
||||
presentDataSettings(context, present, .downloadInBackground)
|
||||
}),
|
||||
SettingsSearchableItem(id: .data(14), title: strings.ChatSettings_OpenLinksIn, alternate: synonyms(strings.SettingsSearch_Synonyms_ChatSettings_OpenLinksIn), icon: icon, breadcrumbs: [strings.Settings_ChatSettings], present: { context, _, present in
|
||||
present(.push, webBrowserSettingsController(context: context))
|
||||
})
|
||||
]
|
||||
}
|
||||
@ -860,7 +863,7 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
|
||||
allItems.append(passport)
|
||||
|
||||
if hasWallet {
|
||||
let wallet = SettingsSearchableItem(id: .wallet(0), title: "Gram Wallet", alternate: synonyms(""), icon: .wallet, breadcrumbs: [], present: { context, _, present in
|
||||
let wallet = SettingsSearchableItem(id: .wallet(0), title: strings.Settings_Wallet, alternate: synonyms(strings.SettingsSearch_Synonyms_Wallet), icon: .wallet, breadcrumbs: [], present: { context, _, present in
|
||||
context.sharedContext.openWallet(context: context, walletContext: .generic, present: { c in
|
||||
present(.push, c)
|
||||
})
|
||||
|
@ -283,7 +283,7 @@ public final class ShareController: ViewController {
|
||||
private let peers = Promise<([(RenderedPeer, PeerPresence?)], Peer)>()
|
||||
private let peersDisposable = MetaDisposable()
|
||||
private let readyDisposable = MetaDisposable()
|
||||
private let acountActiveDisposable = MetaDisposable()
|
||||
private let accountActiveDisposable = MetaDisposable()
|
||||
|
||||
private var defaultAction: ShareControllerAction?
|
||||
|
||||
@ -413,7 +413,7 @@ public final class ShareController: ViewController {
|
||||
deinit {
|
||||
self.peersDisposable.dispose()
|
||||
self.readyDisposable.dispose()
|
||||
self.acountActiveDisposable.dispose()
|
||||
self.accountActiveDisposable.dispose()
|
||||
}
|
||||
|
||||
override public func loadDisplayNode() {
|
||||
@ -789,7 +789,7 @@ public final class ShareController: ViewController {
|
||||
|
||||
private func switchToAccount(account: Account, animateIn: Bool) {
|
||||
self.currentAccount = account
|
||||
self.acountActiveDisposable.set(self.sharedContext.setAccountUserInterfaceInUse(account.id))
|
||||
self.accountActiveDisposable.set(self.sharedContext.setAccountUserInterfaceInUse(account.id))
|
||||
|
||||
self.peers.set(combineLatest(
|
||||
self.currentAccount.postbox.loadedPeerWithId(self.currentAccount.peerId)
|
||||
@ -840,4 +840,8 @@ public final class ShareController: ViewController {
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
public func sendImmediately(peerId: PeerId) {
|
||||
self.controllerNode.send(peerId: peerId)
|
||||
}
|
||||
}
|
||||
|
@ -504,63 +504,74 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
defaultAction.action()
|
||||
}
|
||||
} else {
|
||||
if !self.inputFieldNode.text.isEmpty {
|
||||
for peer in self.controllerInteraction!.selectedPeers {
|
||||
if let channel = peer.peer as? TelegramChannel, channel.isRestrictedBySlowmode {
|
||||
self.presentError(channel.title, self.presentationData.strings.Share_MultipleMessagesDisabled)
|
||||
return
|
||||
}
|
||||
self.send()
|
||||
}
|
||||
}
|
||||
|
||||
func send(peerId: PeerId? = nil) {
|
||||
if !self.inputFieldNode.text.isEmpty {
|
||||
for peer in self.controllerInteraction!.selectedPeers {
|
||||
if let channel = peer.peer as? TelegramChannel, channel.isRestrictedBySlowmode {
|
||||
self.presentError(channel.title, self.presentationData.strings.Share_MultipleMessagesDisabled)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
self.inputFieldNode.deactivateInput()
|
||||
let transition = ContainedViewLayoutTransition.animated(duration: 0.12, curve: .easeInOut)
|
||||
transition.updateAlpha(node: self.actionButtonNode, alpha: 0.0)
|
||||
transition.updateAlpha(node: self.inputFieldNode, alpha: 0.0)
|
||||
transition.updateAlpha(node: self.actionSeparatorNode, alpha: 0.0)
|
||||
transition.updateAlpha(node: self.actionsBackgroundNode, alpha: 0.0)
|
||||
|
||||
if let signal = self.share?(self.inputFieldNode.text, self.controllerInteraction!.selectedPeers.map { $0.peerId }) {
|
||||
self.transitionToContentNode(ShareLoadingContainerNode(theme: self.presentationData.theme, forceNativeAppearance: true), fastOut: true)
|
||||
let timestamp = CACurrentMediaTime()
|
||||
var wasDone = false
|
||||
let doneImpl: (Bool) -> Void = { [weak self] shouldDelay in
|
||||
let minDelay: Double = shouldDelay ? 0.9 : 0.6
|
||||
let delay = max(minDelay, (timestamp + minDelay) - CACurrentMediaTime())
|
||||
Queue.mainQueue().after(delay, {
|
||||
self?.animateOut(shared: true, completion: {
|
||||
self?.dismiss?(true)
|
||||
})
|
||||
}
|
||||
|
||||
self.inputFieldNode.deactivateInput()
|
||||
let transition = ContainedViewLayoutTransition.animated(duration: 0.12, curve: .easeInOut)
|
||||
transition.updateAlpha(node: self.actionButtonNode, alpha: 0.0)
|
||||
transition.updateAlpha(node: self.inputFieldNode, alpha: 0.0)
|
||||
transition.updateAlpha(node: self.actionSeparatorNode, alpha: 0.0)
|
||||
transition.updateAlpha(node: self.actionsBackgroundNode, alpha: 0.0)
|
||||
|
||||
let peerIds: [PeerId]
|
||||
if let peerId = peerId {
|
||||
peerIds = [peerId]
|
||||
} else {
|
||||
peerIds = self.controllerInteraction!.selectedPeers.map { $0.peerId }
|
||||
}
|
||||
|
||||
if let signal = self.share?(self.inputFieldNode.text, peerIds) {
|
||||
self.transitionToContentNode(ShareLoadingContainerNode(theme: self.presentationData.theme, forceNativeAppearance: true), fastOut: true)
|
||||
let timestamp = CACurrentMediaTime()
|
||||
var wasDone = false
|
||||
let doneImpl: (Bool) -> Void = { [weak self] shouldDelay in
|
||||
let minDelay: Double = shouldDelay ? 0.9 : 0.6
|
||||
let delay = max(minDelay, (timestamp + minDelay) - CACurrentMediaTime())
|
||||
Queue.mainQueue().after(delay, {
|
||||
self?.animateOut(shared: true, completion: {
|
||||
self?.dismiss?(true)
|
||||
})
|
||||
}
|
||||
self.shareDisposable.set((signal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
guard let strongSelf = self, let contentNode = strongSelf.contentNode as? ShareLoadingContainerNode else {
|
||||
return
|
||||
}
|
||||
switch status {
|
||||
case .preparing:
|
||||
contentNode.state = .preparing
|
||||
case let .progress(value):
|
||||
contentNode.state = .progress(value)
|
||||
case .done:
|
||||
contentNode.state = .done
|
||||
if !wasDone {
|
||||
if strongSelf.hapticFeedback == nil {
|
||||
strongSelf.hapticFeedback = HapticFeedback()
|
||||
}
|
||||
strongSelf.hapticFeedback?.success()
|
||||
|
||||
wasDone = true
|
||||
doneImpl(true)
|
||||
}
|
||||
}
|
||||
}, completed: {
|
||||
if !wasDone {
|
||||
doneImpl(false)
|
||||
}
|
||||
}))
|
||||
})
|
||||
}
|
||||
self.shareDisposable.set((signal
|
||||
|> deliverOnMainQueue).start(next: { [weak self] status in
|
||||
guard let strongSelf = self, let contentNode = strongSelf.contentNode as? ShareLoadingContainerNode else {
|
||||
return
|
||||
}
|
||||
switch status {
|
||||
case .preparing:
|
||||
contentNode.state = .preparing
|
||||
case let .progress(value):
|
||||
contentNode.state = .progress(value)
|
||||
case .done:
|
||||
contentNode.state = .done
|
||||
if !wasDone {
|
||||
if strongSelf.hapticFeedback == nil {
|
||||
strongSelf.hapticFeedback = HapticFeedback()
|
||||
}
|
||||
strongSelf.hapticFeedback?.success()
|
||||
|
||||
wasDone = true
|
||||
doneImpl(true)
|
||||
}
|
||||
}
|
||||
}, completed: {
|
||||
if !wasDone {
|
||||
doneImpl(false)
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -203,6 +203,7 @@ framework(
|
||||
"$SDKROOT/System/Library/Frameworks/UIKit.framework",
|
||||
"$SDKROOT/System/Library/Frameworks/CoreAudio.framework",
|
||||
"$SDKROOT/System/Library/Frameworks/WebKit.framework",
|
||||
"$SDKROOT/System/Library/Frameworks/Intents.framework",
|
||||
],
|
||||
weak_frameworks = [
|
||||
"Vision",
|
||||
|
@ -3008,7 +3008,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
if let banAuthor = actions.banAuthor {
|
||||
strongSelf.presentBanMessageOptions(accountPeerId: strongSelf.context.account.peerId, author: banAuthor, messageIds: messageIds, options: actions.options)
|
||||
} else {
|
||||
strongSelf.presentDeleteMessageOptions(messageIds: messageIds, options: actions.options, contextController: nil, completion: { _ in })
|
||||
if actions.options.intersection([.deleteLocally, .deleteGlobally]).isEmpty {
|
||||
strongSelf.presentClearCacheSuggestion()
|
||||
} else {
|
||||
strongSelf.presentDeleteMessageOptions(messageIds: messageIds, options: actions.options, contextController: nil, completion: { _ in })
|
||||
}
|
||||
}
|
||||
}
|
||||
}))
|
||||
@ -3051,14 +3055,19 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let _ = deleteMessagesInteractively(postbox: strongSelf.context.account.postbox, messageIds: Array(messageIds), type: .forEveryone, deleteAllInGroup: true).start()
|
||||
completion(.dismissWithoutContent)
|
||||
} else {
|
||||
var isScheduled = false
|
||||
for id in messageIds {
|
||||
if Namespaces.Message.allScheduled.contains(id.namespace) {
|
||||
isScheduled = true
|
||||
break
|
||||
if actions.options.intersection([.deleteLocally, .deleteGlobally]).isEmpty {
|
||||
strongSelf.presentClearCacheSuggestion()
|
||||
completion(.default)
|
||||
} else {
|
||||
var isScheduled = false
|
||||
for id in messageIds {
|
||||
if Namespaces.Message.allScheduled.contains(id.namespace) {
|
||||
isScheduled = true
|
||||
break
|
||||
}
|
||||
}
|
||||
strongSelf.presentDeleteMessageOptions(messageIds: messageIds, options: isScheduled ? [.deleteLocally] : actions.options, contextController: contextController, completion: completion)
|
||||
}
|
||||
strongSelf.presentDeleteMessageOptions(messageIds: messageIds, options: isScheduled ? [.deleteLocally] : actions.options, contextController: contextController, completion: completion)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -5019,7 +5028,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
} else {
|
||||
self?.chatDisplayNode.historyNode.historyAppearsCleared = false
|
||||
}
|
||||
}), in: .window(.root))
|
||||
}), in: .current)
|
||||
}
|
||||
|
||||
let actionSheet = ActionSheetController(presentationTheme: self.presentationData.theme)
|
||||
@ -5133,12 +5142,14 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
var sizeIndex: [PeerCacheUsageCategory: (Bool, Int64)] = [:]
|
||||
|
||||
var itemIndex = 0
|
||||
var itemIndex = 1
|
||||
|
||||
var finalSize: Int64 = 0
|
||||
let updateTotalSize: () -> Void = { [weak controller] in
|
||||
controller?.updateItem(groupIndex: 0, itemIndex: itemIndex, { item in
|
||||
let title: String
|
||||
let filteredSize = sizeIndex.values.reduce(0, { $0 + ($1.0 ? $1.1 : 0) })
|
||||
finalSize = filteredSize
|
||||
|
||||
if filteredSize == 0 {
|
||||
title = presentationData.strings.Cache_ClearNone
|
||||
@ -5172,6 +5183,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let validCategories: [PeerCacheUsageCategory] = [.image, .video, .audio, .file]
|
||||
|
||||
var totalSize: Int64 = 0
|
||||
finalSize = totalSize
|
||||
|
||||
func stringForCategory(strings: PresentationStrings, category: PeerCacheUsageCategory) -> String {
|
||||
switch category {
|
||||
@ -5224,20 +5236,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
media[peerId] = categories
|
||||
}
|
||||
// if let additionalPeerId = additionalPeerId {
|
||||
// if var categories = media[additionalPeerId] {
|
||||
// for category in clearCategories {
|
||||
// if let contents = categories[category] {
|
||||
// for (mediaId, _) in contents {
|
||||
// clearMediaIds.insert(mediaId)
|
||||
// }
|
||||
// }
|
||||
// categories.removeValue(forKey: category)
|
||||
// }
|
||||
//
|
||||
// media[additionalPeerId] = categories
|
||||
// }
|
||||
// }
|
||||
|
||||
var clearResourceIds = Set<WrappedMediaResourceId>()
|
||||
for id in clearMediaIds {
|
||||
@ -5282,7 +5280,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
if let strongSelf = self, let layout = strongSelf.validLayout {
|
||||
let deviceName = UIDevice.current.userInterfaceIdiom == .pad ? "iPad" : "iPhone"
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .succeed(text: presentationData.strings.ClearCache_Success("\(dataSizeString(totalSize, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator))", deviceName).0), elevatedLayout: true, action: { _ in }), in: .window(.root))
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .succeed(text: presentationData.strings.ClearCache_Success("\(dataSizeString(finalSize, decimalSeparator: presentationData.dateTimeFormat.decimalSeparator))", deviceName).0), elevatedLayout: true, action: { _ in }), in: .current)
|
||||
}
|
||||
}))
|
||||
|
||||
@ -8055,7 +8053,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let _ = (self.context.account.postbox.loadedPeerWithId(peerId)
|
||||
|> mapToSignal { peer -> Signal<(Peer, UIImage?), NoError> in
|
||||
let avatarImage = peerAvatarImage(account: self.context.account, peer: peer, authorOfMessage: nil, representation: peer.smallProfileImage, round: false) ?? .single(nil)
|
||||
|
||||
return avatarImage
|
||||
|> map { avatarImage in
|
||||
return (peer, avatarImage)
|
||||
|
@ -2123,7 +2123,6 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
messages.append(.message(text: text.string, attributes: attributes, mediaReference: webpage.flatMap(AnyMediaReference.standalone), replyToMessageId: self.chatPresentationInterfaceState.interfaceState.replyMessageId, localGroupingKey: nil))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var forwardingToSameChat = false
|
||||
if case let .peer(id) = self.chatPresentationInterfaceState.chatLocation, id.namespace == Namespaces.Peer.CloudUser, id != self.context.account.peerId, let forwardMessageIds = self.chatPresentationInterfaceState.interfaceState.forwardMessageIds {
|
||||
@ -2134,7 +2133,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
}
|
||||
if !messages.isEmpty && forwardingToSameChat {
|
||||
//self.controllerInteraction.displaySwipeToReplyHint()
|
||||
self.controllerInteraction.displaySwipeToReplyHint()
|
||||
}
|
||||
|
||||
if !messages.isEmpty || self.chatPresentationInterfaceState.interfaceState.forwardMessageIds != nil {
|
||||
|
@ -684,7 +684,11 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
||||
})))
|
||||
}
|
||||
|
||||
if !data.messageActions.options.intersection([.deleteLocally, .deleteGlobally]).isEmpty && !isAction {
|
||||
var clearCacheAsDelete = false
|
||||
if let peer = message.peers[message.id.peerId] as? TelegramChannel {
|
||||
clearCacheAsDelete = true
|
||||
}
|
||||
if (!data.messageActions.options.intersection([.deleteLocally, .deleteGlobally]).isEmpty || clearCacheAsDelete) && !isAction {
|
||||
let title = message.flags.isSending ? chatPresentationInterfaceState.strings.Conversation_ContextMenuCancelSending : chatPresentationInterfaceState.strings.Conversation_ContextMenuDelete
|
||||
actions.append(.action(ContextMenuActionItem(text: title, textColor: .destructive, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: message.flags.isSending ? "Chat/Context Menu/Clear" : "Chat/Context Menu/Delete"), color: theme.actionSheet.destructiveActionTextColor)
|
||||
|
@ -143,26 +143,24 @@ final class ChatMessageSelectionInputPanelNode: ChatInputPanelNode {
|
||||
self.forwardButton.isEnabled = actions.options.contains(.forward)
|
||||
self.shareButton.isEnabled = false
|
||||
|
||||
self.deleteButton.isEnabled = !actions.options.intersection([.deleteLocally, .deleteGlobally]).isEmpty
|
||||
self.deleteButton.isEnabled = true
|
||||
self.shareButton.isEnabled = !actions.options.intersection([.forward]).isEmpty
|
||||
self.reportButton.isEnabled = !actions.options.intersection([.report]).isEmpty
|
||||
|
||||
self.deleteButton.isHidden = !self.deleteButton.isEnabled
|
||||
self.deleteButton.isHidden = false
|
||||
self.reportButton.isHidden = !self.reportButton.isEnabled
|
||||
} else {
|
||||
self.deleteButton.isEnabled = false
|
||||
self.deleteButton.isHidden = true
|
||||
self.deleteButton.isHidden = false
|
||||
self.reportButton.isEnabled = false
|
||||
self.reportButton.isHidden = true
|
||||
self.forwardButton.isEnabled = false
|
||||
self.shareButton.isEnabled = false
|
||||
}
|
||||
|
||||
if self.deleteButton.isHidden && self.reportButton.isHidden {
|
||||
if self.reportButton.isHidden {
|
||||
if let peer = interfaceState.renderedPeer?.peer as? TelegramChannel, case .broadcast = peer.info {
|
||||
self.reportButton.isHidden = false
|
||||
} else {
|
||||
self.deleteButton.isHidden = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,7 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel
|
||||
self.contentContainerNode.addSubnode(self.cancelButton)
|
||||
self.contentContainerNode.addSubnode(self.doneButton)
|
||||
if case .scheduledMessages(true) = self.mode {
|
||||
self.contentContainerNode.addSubnode(self.onlineButton)
|
||||
//self.contentContainerNode.addSubnode(self.onlineButton)
|
||||
}
|
||||
|
||||
self.cancelButton.addTarget(self, action: #selector(self.cancelButtonPressed), forControlEvents: .touchUpInside)
|
||||
@ -316,7 +316,7 @@ class ChatScheduleTimeControllerNode: ViewControllerTracingNode, UIScrollViewDel
|
||||
|
||||
var buttonOffset: CGFloat = 0.0
|
||||
if case .scheduledMessages(true) = self.mode {
|
||||
buttonOffset += 60.0
|
||||
//buttonOffset += 60.0
|
||||
}
|
||||
|
||||
let bottomInset: CGFloat = 10.0 + cleanInsets.bottom
|
||||
|
Binary file not shown.
@ -14,6 +14,7 @@ import ShareItems
|
||||
import SettingsUI
|
||||
import OpenSSLEncryptionProvider
|
||||
import AppLock
|
||||
import Intents
|
||||
|
||||
private let inForeground = ValuePromise<Bool>(false, ignoreRepeated: true)
|
||||
|
||||
@ -326,6 +327,15 @@ public class ShareRootControllerImpl {
|
||||
strongSelf.mainWindow?.present(shareController, on: .root)
|
||||
}
|
||||
|
||||
if #available(iOS 13.0, *), let sendMessageIntent = self?.getExtensionContext()?.intent as? INSendMessageIntent {
|
||||
if let contact = sendMessageIntent.recipients?.first, let handle = contact.customIdentifier, handle.hasPrefix("tg") {
|
||||
let string = handle.suffix(from: handle.index(handle.startIndex, offsetBy: 2))
|
||||
if let userId = Int32(string) {
|
||||
shareController.sendImmediately(peerId: PeerId(namespace: Namespaces.Peer.CloudUser, id: userId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.account.resetStateManagement()
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user