mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
8188bc2858
commit
4c500ce3b2
@ -8934,3 +8934,5 @@ Sorry for the inconvenience.";
|
|||||||
"MediaPicker.VoiceOver.Camera" = "Camera";
|
"MediaPicker.VoiceOver.Camera" = "Camera";
|
||||||
|
|
||||||
"ChatList.ReadAll" = "Read All";
|
"ChatList.ReadAll" = "Read All";
|
||||||
|
|
||||||
|
"ChatList.ClearSavedMessagesConfirmation" = "Are you sure you want to delete all your saved messages?";
|
||||||
|
@ -2177,6 +2177,18 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
reorderedFilterIdsValue = reorderedFilterIds
|
reorderedFilterIdsValue = reorderedFilterIds
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let completion = { [weak self] in
|
||||||
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
strongSelf.chatListDisplayNode.isReorderingFilters = false
|
||||||
|
strongSelf.isReorderingTabsValue.set(false)
|
||||||
|
(strongSelf.parent as? TabBarController)?.updateIsTabBarEnabled(true, transition: .animated(duration: 0.2, curve: .easeInOut))
|
||||||
|
strongSelf.searchContentNode?.setIsEnabled(true, animated: true)
|
||||||
|
if let layout = strongSelf.validLayout {
|
||||||
|
strongSelf.updateLayout(layout: layout, transition: .animated(duration: 0.2, curve: .easeInOut))
|
||||||
|
}
|
||||||
|
}
|
||||||
if let reorderedFilterIds = reorderedFilterIdsValue {
|
if let reorderedFilterIds = reorderedFilterIdsValue {
|
||||||
let _ = (self.context.engine.peers.updateChatListFiltersInteractively { stateFilters in
|
let _ = (self.context.engine.peers.updateChatListFiltersInteractively { stateFilters in
|
||||||
var updatedFilters: [ChatListFilter] = []
|
var updatedFilters: [ChatListFilter] = []
|
||||||
@ -2199,18 +2211,11 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
strongSelf.reloadFilters(firstUpdate: {
|
strongSelf.reloadFilters(firstUpdate: {
|
||||||
guard let strongSelf = self else {
|
completion()
|
||||||
return
|
|
||||||
}
|
|
||||||
strongSelf.chatListDisplayNode.isReorderingFilters = false
|
|
||||||
strongSelf.isReorderingTabsValue.set(false)
|
|
||||||
(strongSelf.parent as? TabBarController)?.updateIsTabBarEnabled(true, transition: .animated(duration: 0.2, curve: .easeInOut))
|
|
||||||
strongSelf.searchContentNode?.setIsEnabled(true, animated: true)
|
|
||||||
if let layout = strongSelf.validLayout {
|
|
||||||
strongSelf.updateLayout(layout: layout, transition: .animated(duration: 0.2, curve: .easeInOut))
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
completion()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ func chatListSelectionOptions(context: AccountContext, peerIds: Set<PeerId>, fil
|
|||||||
return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.TotalReadCounters())
|
return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.TotalReadCounters())
|
||||||
|> map { readCounters -> ChatListSelectionOptions in
|
|> map { readCounters -> ChatListSelectionOptions in
|
||||||
var hasUnread = false
|
var hasUnread = false
|
||||||
if readCounters.count(for: .filtered, in: .chats, with: .all) != 0 {
|
if readCounters.count(for: .raw, in: .chats, with: .all) != 0 {
|
||||||
hasUnread = true
|
hasUnread = true
|
||||||
}
|
}
|
||||||
return ChatListSelectionOptions(read: .all(enabled: hasUnread), delete: false)
|
return ChatListSelectionOptions(read: .all(enabled: hasUnread), delete: false)
|
||||||
|
@ -129,7 +129,7 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode {
|
|||||||
}
|
}
|
||||||
case let .clearHistory(canClearCache):
|
case let .clearHistory(canClearCache):
|
||||||
if peer.id == context.account.peerId {
|
if peer.id == context.account.peerId {
|
||||||
text = PresentationStrings.FormattedString(string: strings.ChatList_DeleteSavedMessagesConfirmation, ranges: [])
|
text = PresentationStrings.FormattedString(string: strings.ChatList_ClearSavedMessagesConfirmation, ranges: [])
|
||||||
} else if case .user = peer {
|
} else if case .user = peer {
|
||||||
text = strings.ChatList_ClearChatConfirmation(peer.displayTitle(strings: strings, displayOrder: nameOrder))
|
text = strings.ChatList_ClearChatConfirmation(peer.displayTitle(strings: strings, displayOrder: nameOrder))
|
||||||
} else {
|
} else {
|
||||||
|
@ -1514,7 +1514,7 @@ open class TextNode: ASDisplayNode {
|
|||||||
if glyphCount == 2, let font = attributes["NSFont"] as? UIFont, font.fontName.contains("ColorEmoji"), let string = layout.attributedString {
|
if glyphCount == 2, let font = attributes["NSFont"] as? UIFont, font.fontName.contains("ColorEmoji"), let string = layout.attributedString {
|
||||||
let range = CTRunGetStringRange(run)
|
let range = CTRunGetStringRange(run)
|
||||||
|
|
||||||
if range.location < string.length && (range.location + range.length) < string.length {
|
if range.location < string.length && (range.location + range.length) <= string.length {
|
||||||
let substring = string.attributedSubstring(from: NSMakeRange(range.location, range.length)).string
|
let substring = string.attributedSubstring(from: NSMakeRange(range.location, range.length)).string
|
||||||
|
|
||||||
let heart = Unicode.Scalar(0x2764)!
|
let heart = Unicode.Scalar(0x2764)!
|
||||||
|
@ -1,435 +0,0 @@
|
|||||||
import Foundation
|
|
||||||
import UIKit
|
|
||||||
import Display
|
|
||||||
import SwiftSignalKit
|
|
||||||
import Postbox
|
|
||||||
import TelegramCore
|
|
||||||
import TelegramPresentationData
|
|
||||||
import ItemListUI
|
|
||||||
import PresentationDataUtils
|
|
||||||
import AccountContext
|
|
||||||
|
|
||||||
private enum NetworkUsageControllerSection {
|
|
||||||
case cellular
|
|
||||||
case wifi
|
|
||||||
}
|
|
||||||
|
|
||||||
private final class NetworkUsageStatsControllerArguments {
|
|
||||||
let resetStatistics: (NetworkUsageControllerSection) -> Void
|
|
||||||
|
|
||||||
init(resetStatistics: @escaping (NetworkUsageControllerSection) -> Void) {
|
|
||||||
self.resetStatistics = resetStatistics
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum NetworkUsageStatsSection: Int32 {
|
|
||||||
case messages
|
|
||||||
case image
|
|
||||||
case video
|
|
||||||
case audio
|
|
||||||
case file
|
|
||||||
case call
|
|
||||||
case total
|
|
||||||
case reset
|
|
||||||
}
|
|
||||||
|
|
||||||
private enum NetworkUsageStatsEntry: ItemListNodeEntry {
|
|
||||||
case messagesHeader(PresentationTheme, String)
|
|
||||||
case messagesSent(PresentationTheme, String, String)
|
|
||||||
case messagesReceived(PresentationTheme, String, String)
|
|
||||||
|
|
||||||
case imageHeader(PresentationTheme, String)
|
|
||||||
case imageSent(PresentationTheme, String, String)
|
|
||||||
case imageReceived(PresentationTheme, String, String)
|
|
||||||
|
|
||||||
case videoHeader(PresentationTheme, String)
|
|
||||||
case videoSent(PresentationTheme, String, String)
|
|
||||||
case videoReceived(PresentationTheme, String, String)
|
|
||||||
|
|
||||||
case audioHeader(PresentationTheme, String)
|
|
||||||
case audioSent(PresentationTheme, String, String)
|
|
||||||
case audioReceived(PresentationTheme, String, String)
|
|
||||||
|
|
||||||
case fileHeader(PresentationTheme, String)
|
|
||||||
case fileSent(PresentationTheme, String, String)
|
|
||||||
case fileReceived(PresentationTheme, String, String)
|
|
||||||
|
|
||||||
case callHeader(PresentationTheme, String)
|
|
||||||
case callSent(PresentationTheme, String, String)
|
|
||||||
case callReceived(PresentationTheme, String, String)
|
|
||||||
|
|
||||||
case reset(PresentationTheme, NetworkUsageControllerSection, String)
|
|
||||||
case resetTimestamp(PresentationTheme, String)
|
|
||||||
|
|
||||||
var section: ItemListSectionId {
|
|
||||||
switch self {
|
|
||||||
case .messagesHeader, .messagesSent, .messagesReceived:
|
|
||||||
return NetworkUsageStatsSection.messages.rawValue
|
|
||||||
case .imageHeader, .imageSent, .imageReceived:
|
|
||||||
return NetworkUsageStatsSection.image.rawValue
|
|
||||||
case .videoHeader, .videoSent, .videoReceived:
|
|
||||||
return NetworkUsageStatsSection.video.rawValue
|
|
||||||
case .audioHeader, .audioSent, .audioReceived:
|
|
||||||
return NetworkUsageStatsSection.audio.rawValue
|
|
||||||
case .fileHeader, .fileSent, .fileReceived:
|
|
||||||
return NetworkUsageStatsSection.file.rawValue
|
|
||||||
case .callHeader, .callSent, .callReceived:
|
|
||||||
return NetworkUsageStatsSection.call.rawValue
|
|
||||||
case .reset, .resetTimestamp:
|
|
||||||
return NetworkUsageStatsSection.reset.rawValue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var stableId: Int32 {
|
|
||||||
switch self {
|
|
||||||
case .messagesHeader:
|
|
||||||
return 0
|
|
||||||
case .messagesSent:
|
|
||||||
return 1
|
|
||||||
case .messagesReceived:
|
|
||||||
return 2
|
|
||||||
case .imageHeader:
|
|
||||||
return 3
|
|
||||||
case .imageSent:
|
|
||||||
return 4
|
|
||||||
case .imageReceived:
|
|
||||||
return 5
|
|
||||||
case .videoHeader:
|
|
||||||
return 6
|
|
||||||
case .videoSent:
|
|
||||||
return 7
|
|
||||||
case .videoReceived:
|
|
||||||
return 8
|
|
||||||
case .audioHeader:
|
|
||||||
return 9
|
|
||||||
case .audioSent:
|
|
||||||
return 10
|
|
||||||
case .audioReceived:
|
|
||||||
return 11
|
|
||||||
case .fileHeader:
|
|
||||||
return 12
|
|
||||||
case .fileSent:
|
|
||||||
return 13
|
|
||||||
case .fileReceived:
|
|
||||||
return 14
|
|
||||||
case .callHeader:
|
|
||||||
return 15
|
|
||||||
case .callSent:
|
|
||||||
return 16
|
|
||||||
case .callReceived:
|
|
||||||
return 17
|
|
||||||
case .reset:
|
|
||||||
return 18
|
|
||||||
case .resetTimestamp:
|
|
||||||
return 19
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static func ==(lhs: NetworkUsageStatsEntry, rhs: NetworkUsageStatsEntry) -> Bool {
|
|
||||||
switch lhs {
|
|
||||||
case let .messagesHeader(lhsTheme, lhsText):
|
|
||||||
if case let .messagesHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .messagesSent(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .messagesSent(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .messagesReceived(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .messagesReceived(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .imageHeader(lhsTheme, lhsText):
|
|
||||||
if case let .imageHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .imageSent(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .imageSent(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .imageReceived(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .imageReceived(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .videoHeader(lhsTheme, lhsText):
|
|
||||||
if case let .videoHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .videoSent(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .videoSent(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .videoReceived(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .videoReceived(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .audioHeader(lhsTheme, lhsText):
|
|
||||||
if case let .audioHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .audioSent(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .audioSent(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .audioReceived(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .audioReceived(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .fileHeader(lhsTheme, lhsText):
|
|
||||||
if case let .fileHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .fileSent(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .fileSent(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .fileReceived(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .fileReceived(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .callHeader(lhsTheme, lhsText):
|
|
||||||
if case let .callHeader(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .callSent(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .callSent(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .callReceived(lhsTheme, lhsText, lhsValue):
|
|
||||||
if case let .callReceived(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .reset(lhsTheme, lhsSection, lhsText):
|
|
||||||
if case let .reset(rhsTheme, rhsSection, rhsText) = rhs, lhsTheme === rhsTheme, lhsSection == rhsSection, lhsText == rhsText {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
case let .resetTimestamp(lhsTheme, lhsText):
|
|
||||||
if case let .resetTimestamp(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static func <(lhs: NetworkUsageStatsEntry, rhs: NetworkUsageStatsEntry) -> Bool {
|
|
||||||
return lhs.stableId < rhs.stableId
|
|
||||||
}
|
|
||||||
|
|
||||||
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
|
|
||||||
let arguments = arguments as! NetworkUsageStatsControllerArguments
|
|
||||||
switch self {
|
|
||||||
case let .messagesHeader(_, text):
|
|
||||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
|
||||||
case let .messagesSent(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .messagesReceived(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .imageHeader(_, text):
|
|
||||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
|
||||||
case let .imageSent(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .imageReceived(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .videoHeader(_, text):
|
|
||||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
|
||||||
case let .videoSent(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .videoReceived(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .audioHeader(_, text):
|
|
||||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
|
||||||
case let .audioSent(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .audioReceived(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .fileHeader(_, text):
|
|
||||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
|
||||||
case let .fileSent(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .fileReceived(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .callHeader(_, text):
|
|
||||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, sectionId: self.section)
|
|
||||||
case let .callSent(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .callReceived(_, text, value):
|
|
||||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .none , action: nil)
|
|
||||||
case let .reset(_, section, text):
|
|
||||||
return ItemListActionItem(presentationData: presentationData, title: text, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
|
||||||
arguments.resetStatistics(section)
|
|
||||||
})
|
|
||||||
case let .resetTimestamp(_, text):
|
|
||||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func networkUsageStatsControllerEntries(presentationData: PresentationData, section: NetworkUsageControllerSection, stats: NetworkUsageStats) -> [NetworkUsageStatsEntry] {
|
|
||||||
var entries: [NetworkUsageStatsEntry] = []
|
|
||||||
|
|
||||||
let formatting = DataSizeStringFormatting(presentationData: presentationData)
|
|
||||||
switch section {
|
|
||||||
case .cellular:
|
|
||||||
entries.append(.messagesHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_GeneralDataSection))
|
|
||||||
entries.append(.messagesSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.generic.cellular.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.messagesReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.generic.cellular.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.imageHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_MediaImageDataSection))
|
|
||||||
entries.append(.imageSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.image.cellular.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.imageReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.image.cellular.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.videoHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_MediaVideoDataSection))
|
|
||||||
entries.append(.videoSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.video.cellular.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.videoReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.video.cellular.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.audioHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_MediaAudioDataSection))
|
|
||||||
entries.append(.audioSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.audio.cellular.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.audioReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.audio.cellular.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.fileHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_MediaDocumentDataSection))
|
|
||||||
entries.append(.fileSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.file.cellular.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.fileReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.file.cellular.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.callHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_CallDataSection))
|
|
||||||
entries.append(.callSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.call.cellular.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.callReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.call.cellular.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.reset(presentationData.theme, section, presentationData.strings.NetworkUsageSettings_ResetStats))
|
|
||||||
|
|
||||||
if stats.resetCellularTimestamp != 0 {
|
|
||||||
let formatter = DateFormatter()
|
|
||||||
formatter.dateFormat = "E, d MMM yyyy HH:mm"
|
|
||||||
let dateStringPlain = formatter.string(from: Date(timeIntervalSince1970: Double(stats.resetCellularTimestamp)))
|
|
||||||
|
|
||||||
entries.append(.resetTimestamp(presentationData.theme, presentationData.strings.NetworkUsageSettings_CellularUsageSince(dateStringPlain).string))
|
|
||||||
}
|
|
||||||
case .wifi:
|
|
||||||
entries.append(.messagesHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_GeneralDataSection))
|
|
||||||
entries.append(.messagesSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.generic.wifi.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.messagesReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.generic.wifi.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.imageHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_MediaImageDataSection))
|
|
||||||
entries.append(.imageSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.image.wifi.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.imageReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.image.wifi.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.videoHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_MediaVideoDataSection))
|
|
||||||
entries.append(.videoSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.video.wifi.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.videoReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.video.wifi.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.audioHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_MediaAudioDataSection))
|
|
||||||
entries.append(.audioSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.audio.wifi.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.audioReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.audio.wifi.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.fileHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_MediaDocumentDataSection))
|
|
||||||
entries.append(.fileSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.file.wifi.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.fileReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.file.wifi.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.callHeader(presentationData.theme, presentationData.strings.NetworkUsageSettings_CallDataSection))
|
|
||||||
entries.append(.callSent(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesSent, dataSizeString(stats.call.wifi.outgoing, formatting: formatting)))
|
|
||||||
entries.append(.callReceived(presentationData.theme, presentationData.strings.NetworkUsageSettings_BytesReceived, dataSizeString(stats.call.wifi.incoming, formatting: formatting)))
|
|
||||||
|
|
||||||
entries.append(.reset(presentationData.theme, section, presentationData.strings.NetworkUsageSettings_ResetStats))
|
|
||||||
if stats.resetWifiTimestamp != 0 {
|
|
||||||
let formatter = DateFormatter()
|
|
||||||
formatter.dateFormat = "E, d MMM yyyy HH:mm"
|
|
||||||
let dateStringPlain = formatter.string(from: Date(timeIntervalSince1970: Double(stats.resetWifiTimestamp)))
|
|
||||||
|
|
||||||
entries.append(.resetTimestamp(presentationData.theme, presentationData.strings.NetworkUsageSettings_WifiUsageSince(dateStringPlain).string))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return entries
|
|
||||||
}
|
|
||||||
|
|
||||||
func networkUsageStatsController(context: AccountContext) -> ViewController {
|
|
||||||
let section = ValuePromise<NetworkUsageControllerSection>(.cellular)
|
|
||||||
let stats = Promise<NetworkUsageStats>()
|
|
||||||
stats.set(accountNetworkUsageStats(account: context.account, reset: []))
|
|
||||||
|
|
||||||
var presentControllerImpl: ((ViewController) -> Void)?
|
|
||||||
|
|
||||||
let arguments = NetworkUsageStatsControllerArguments(resetStatistics: { [weak stats] section in
|
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
|
||||||
let controller = ActionSheetController(presentationData: presentationData)
|
|
||||||
let dismissAction: () -> Void = { [weak controller] in
|
|
||||||
controller?.dismissAnimated()
|
|
||||||
}
|
|
||||||
controller.setItemGroups([
|
|
||||||
ActionSheetItemGroup(items: [
|
|
||||||
ActionSheetButtonItem(title: presentationData.strings.NetworkUsageSettings_ResetStats, color: .destructive, action: {
|
|
||||||
dismissAction()
|
|
||||||
|
|
||||||
let reset: ResetNetworkUsageStats
|
|
||||||
switch section {
|
|
||||||
case .wifi:
|
|
||||||
reset = .wifi
|
|
||||||
case .cellular:
|
|
||||||
reset = .cellular
|
|
||||||
}
|
|
||||||
stats?.set(accountNetworkUsageStats(account: context.account, reset: reset))
|
|
||||||
}),
|
|
||||||
]),
|
|
||||||
ActionSheetItemGroup(items: [ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, action: { dismissAction() })])
|
|
||||||
])
|
|
||||||
presentControllerImpl?(controller)
|
|
||||||
})
|
|
||||||
|
|
||||||
let signal = combineLatest(context.sharedContext.presentationData, section.get(), stats.get()) |> deliverOnMainQueue
|
|
||||||
|> map { presentationData, section, stats -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
|
||||||
|
|
||||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .sectionControl([presentationData.strings.NetworkUsageSettings_Cellular, presentationData.strings.NetworkUsageSettings_Wifi], 0), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
|
||||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: networkUsageStatsControllerEntries(presentationData: presentationData, section: section, stats: stats), style: .blocks, emptyStateItem: nil, animateChanges: false)
|
|
||||||
|
|
||||||
return (controllerState, (listState, arguments))
|
|
||||||
}
|
|
||||||
|
|
||||||
let controller = ItemListController(context: context, state: signal)
|
|
||||||
controller.titleControlValueChanged = { [weak section] index in
|
|
||||||
section?.set(index == 0 ? .cellular : .wifi)
|
|
||||||
}
|
|
||||||
|
|
||||||
presentControllerImpl = { [weak controller] c in
|
|
||||||
controller?.present(c, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
|
||||||
}
|
|
||||||
|
|
||||||
return controller
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -16,6 +16,7 @@ import UrlHandling
|
|||||||
import AccountUtils
|
import AccountUtils
|
||||||
import PremiumUI
|
import PremiumUI
|
||||||
import PasswordSetupUI
|
import PasswordSetupUI
|
||||||
|
import StorageUsageScreen
|
||||||
|
|
||||||
private struct DeleteAccountOptionsArguments {
|
private struct DeleteAccountOptionsArguments {
|
||||||
let changePhoneNumber: () -> Void
|
let changePhoneNumber: () -> Void
|
||||||
@ -276,7 +277,9 @@ public func deleteAccountOptionsController(context: AccountContext, navigationCo
|
|||||||
}, clearCache: {
|
}, clearCache: {
|
||||||
addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_clear_cache_tap")
|
addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_clear_cache_tap")
|
||||||
|
|
||||||
pushControllerImpl?(storageUsageController(context: context))
|
pushControllerImpl?(StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in
|
||||||
|
return storageUsageExceptionsScreen(context: context, category: category)
|
||||||
|
}))
|
||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
}, clearSyncedContacts: {
|
}, clearSyncedContacts: {
|
||||||
addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_clear_contacts_tap")
|
addAppLogEvent(postbox: context.account.postbox, type: "deactivate.options_clear_contacts_tap")
|
||||||
|
@ -15,6 +15,7 @@ import PresentationDataUtils
|
|||||||
import UrlHandling
|
import UrlHandling
|
||||||
import AccountUtils
|
import AccountUtils
|
||||||
import PremiumUI
|
import PremiumUI
|
||||||
|
import StorageUsageScreen
|
||||||
|
|
||||||
private struct LogoutOptionsItemArguments {
|
private struct LogoutOptionsItemArguments {
|
||||||
let addAccount: () -> Void
|
let addAccount: () -> Void
|
||||||
@ -181,7 +182,9 @@ public func logoutOptionsController(context: AccountContext, navigationControlle
|
|||||||
})
|
})
|
||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
}, clearCache: {
|
}, clearCache: {
|
||||||
pushControllerImpl?(storageUsageController(context: context))
|
pushControllerImpl?(StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in
|
||||||
|
return storageUsageExceptionsScreen(context: context, category: category)
|
||||||
|
}))
|
||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
}, changePhoneNumber: {
|
}, changePhoneNumber: {
|
||||||
let introController = PrivacyIntroController(context: context, mode: .changePhoneNumber(phoneNumber), proceedAction: {
|
let introController = PrivacyIntroController(context: context, mode: .changePhoneNumber(phoneNumber), proceedAction: {
|
||||||
|
@ -20,6 +20,7 @@ import InstantPageCache
|
|||||||
import NotificationPeerExceptionController
|
import NotificationPeerExceptionController
|
||||||
import QrCodeUI
|
import QrCodeUI
|
||||||
import PremiumUI
|
import PremiumUI
|
||||||
|
import StorageUsageScreen
|
||||||
|
|
||||||
enum SettingsSearchableItemIcon {
|
enum SettingsSearchableItemIcon {
|
||||||
case profile
|
case profile
|
||||||
@ -681,16 +682,54 @@ private func dataSearchableItems(context: AccountContext) -> [SettingsSearchable
|
|||||||
presentDataSettings(context, present, nil)
|
presentDataSettings(context, present, nil)
|
||||||
}),
|
}),
|
||||||
SettingsSearchableItem(id: .data(1), title: strings.ChatSettings_Cache, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_Storage_Title), icon: icon, breadcrumbs: [strings.Settings_ChatSettings], present: { context, _, present in
|
SettingsSearchableItem(id: .data(1), title: strings.ChatSettings_Cache, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_Storage_Title), icon: icon, breadcrumbs: [strings.Settings_ChatSettings], present: { context, _, present in
|
||||||
present(.push, storageUsageController(context: context))
|
let controller = StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in
|
||||||
|
return storageUsageExceptionsScreen(context: context, category: category)
|
||||||
|
})
|
||||||
|
present(.push, controller)
|
||||||
}),
|
}),
|
||||||
SettingsSearchableItem(id: .data(2), title: strings.Cache_KeepMedia, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_Storage_KeepMedia), icon: icon, breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_Cache], present: { context, _, present in
|
SettingsSearchableItem(id: .data(2), title: strings.Cache_KeepMedia, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_Storage_KeepMedia), icon: icon, breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_Cache], present: { context, _, present in
|
||||||
present(.push, storageUsageController(context: context))
|
let controller = StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in
|
||||||
|
return storageUsageExceptionsScreen(context: context, category: category)
|
||||||
|
})
|
||||||
|
present(.push, controller)
|
||||||
}),
|
}),
|
||||||
SettingsSearchableItem(id: .data(3), title: strings.Cache_ClearCache, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_Storage_ClearCache), icon: icon, breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_Cache], present: { context, _, present in
|
SettingsSearchableItem(id: .data(3), title: strings.Cache_ClearCache, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_Storage_ClearCache), icon: icon, breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_Cache], present: { context, _, present in
|
||||||
present(.push, storageUsageController(context: context))
|
let controller = StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in
|
||||||
|
return storageUsageExceptionsScreen(context: context, category: category)
|
||||||
|
})
|
||||||
|
present(.push, controller)
|
||||||
}),
|
}),
|
||||||
SettingsSearchableItem(id: .data(4), title: strings.NetworkUsageSettings_Title, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_NetworkUsage), icon: icon, breadcrumbs: [strings.Settings_ChatSettings], present: { context, _, present in
|
SettingsSearchableItem(id: .data(4), title: strings.NetworkUsageSettings_Title, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_NetworkUsage), icon: icon, breadcrumbs: [strings.Settings_ChatSettings], present: { context, _, present in
|
||||||
present(.push, networkUsageStatsController(context: context))
|
let mediaAutoDownloadSettings = context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings])
|
||||||
|
|> map { sharedData -> MediaAutoDownloadSettings in
|
||||||
|
var automaticMediaDownloadSettings: MediaAutoDownloadSettings
|
||||||
|
if let value = sharedData.entries[ApplicationSpecificSharedDataKeys.automaticMediaDownloadSettings]?.get(MediaAutoDownloadSettings.self) {
|
||||||
|
automaticMediaDownloadSettings = value
|
||||||
|
} else {
|
||||||
|
automaticMediaDownloadSettings = .defaultSettings
|
||||||
|
}
|
||||||
|
return automaticMediaDownloadSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = (combineLatest(
|
||||||
|
accountNetworkUsageStats(account: context.account, reset: []),
|
||||||
|
mediaAutoDownloadSettings
|
||||||
|
)
|
||||||
|
|> take(1)
|
||||||
|
|> deliverOnMainQueue).start(next: { stats, mediaAutoDownloadSettings in
|
||||||
|
var stats = stats
|
||||||
|
|
||||||
|
if stats.resetWifiTimestamp == 0 {
|
||||||
|
var value = stat()
|
||||||
|
if stat(context.account.basePath, &value) == 0 {
|
||||||
|
stats.resetWifiTimestamp = Int32(value.st_ctimespec.tv_sec)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
present(.push, DataUsageScreen(context: context, stats: stats, mediaAutoDownloadSettings: mediaAutoDownloadSettings, makeAutodownloadSettingsController: { isCellular in
|
||||||
|
return autodownloadMediaConnectionTypeController(context: context, connectionType: isCellular ? .cellular : .wifi)
|
||||||
|
}))
|
||||||
|
})
|
||||||
}),
|
}),
|
||||||
SettingsSearchableItem(id: .data(5), title: strings.ChatSettings_AutoDownloadUsingCellular, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_AutoDownloadUsingCellular), icon: icon, breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle], present: { context, _, present in
|
SettingsSearchableItem(id: .data(5), title: strings.ChatSettings_AutoDownloadUsingCellular, alternate: synonyms(strings.SettingsSearch_Synonyms_Data_AutoDownloadUsingCellular), icon: icon, breadcrumbs: [strings.Settings_ChatSettings, strings.ChatSettings_AutoDownloadTitle], present: { context, _, present in
|
||||||
present(.push, autodownloadMediaConnectionTypeController(context: context, connectionType: .cellular))
|
present(.push, autodownloadMediaConnectionTypeController(context: context, connectionType: .cellular))
|
||||||
|
@ -89,6 +89,7 @@ import ChatListHeaderComponent
|
|||||||
import ChatControllerInteraction
|
import ChatControllerInteraction
|
||||||
import FeaturedStickersScreen
|
import FeaturedStickersScreen
|
||||||
import ChatEntityKeyboardInputNode
|
import ChatEntityKeyboardInputNode
|
||||||
|
import StorageUsageScreen
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
import os.signpost
|
import os.signpost
|
||||||
@ -11704,6 +11705,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
self?.beginClearHistory(type: type)
|
self?.beginClearHistory(type: type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let context = self.context
|
||||||
let _ = (self.context.engine.data.get(
|
let _ = (self.context.engine.data.get(
|
||||||
TelegramEngine.EngineData.Item.Peer.ParticipantCount(id: peerId),
|
TelegramEngine.EngineData.Item.Peer.ParticipantCount(id: peerId),
|
||||||
TelegramEngine.EngineData.Item.Peer.CanDeleteHistory(id: peerId)
|
TelegramEngine.EngineData.Item.Peer.CanDeleteHistory(id: peerId)
|
||||||
@ -11890,9 +11892,19 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
default:
|
default:
|
||||||
text = strongSelf.presentationData.strings.ChatList_DeleteForCurrentUser
|
text = strongSelf.presentationData.strings.ChatList_DeleteForCurrentUser
|
||||||
}
|
}
|
||||||
items.append(ActionSheetButtonItem(title: text, color: .destructive, action: { [weak actionSheet] in
|
items.append(ActionSheetButtonItem(title: text, color: .destructive, action: { [weak self, weak actionSheet] in
|
||||||
actionSheet?.dismissAnimated()
|
actionSheet?.dismissAnimated()
|
||||||
beginClear(.forLocalPeer)
|
if mainPeer.id == context.account.peerId, let strongSelf = self {
|
||||||
|
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: strongSelf.presentationData.strings.ChatList_DeleteSavedMessagesConfirmationTitle, text: strongSelf.presentationData.strings.ChatList_DeleteSavedMessagesConfirmationText, actions: [
|
||||||
|
TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {
|
||||||
|
}),
|
||||||
|
TextAlertAction(type: .destructiveAction, title: strongSelf.presentationData.strings.ChatList_DeleteSavedMessagesConfirmationAction, action: {
|
||||||
|
beginClear(.forLocalPeer)
|
||||||
|
})
|
||||||
|
], parseMarkdown: true), in: .window(.root))
|
||||||
|
} else {
|
||||||
|
beginClear(.forLocalPeer)
|
||||||
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -12160,7 +12172,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }) })
|
strongSelf.updateChatPresentationInterfaceState(animated: true, interactive: true, { $0.updatedInterfaceState({ $0.withoutSelectionState() }) })
|
||||||
|
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
let controller = storageUsageController(context: strongSelf.context, isModal: true)
|
let context = strongSelf.context
|
||||||
|
let controller = StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in
|
||||||
|
return storageUsageExceptionsScreen(context: context, category: category)
|
||||||
|
})
|
||||||
strongSelf.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
strongSelf.present(controller, in: .window(.root), with: ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
@ -16974,7 +16989,10 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
actionSheet?.dismissAnimated()
|
actionSheet?.dismissAnimated()
|
||||||
if let strongSelf = self, !presented {
|
if let strongSelf = self, !presented {
|
||||||
presented = true
|
presented = true
|
||||||
strongSelf.push(storageUsageController(context: strongSelf.context, isModal: true))
|
let context = strongSelf.context
|
||||||
|
strongSelf.push(StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in
|
||||||
|
return storageUsageExceptionsScreen(context: context, category: category)
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
@ -2461,8 +2461,10 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
if textView.inputView !== updatedInputView {
|
if textView.inputView !== updatedInputView {
|
||||||
textView.inputView = updatedInputView
|
textView.inputView = updatedInputView
|
||||||
if textView.isFirstResponder {
|
if textView.isFirstResponder {
|
||||||
if self.chatPresentationInterfaceStateRequiresInputFocus(chatPresentationInterfaceState) {
|
if self.chatPresentationInterfaceStateRequiresInputFocus(chatPresentationInterfaceState), let validLayout = self.validLayout {
|
||||||
if let validLayout = self.validLayout, let inputHeight = validLayout.0.inputHeight, inputHeight > 100.0 {
|
if case .compact = validLayout.0.metrics.widthClass {
|
||||||
|
waitForKeyboardLayout = true
|
||||||
|
} else if let inputHeight = validLayout.0.inputHeight, inputHeight > 100.0 {
|
||||||
waitForKeyboardLayout = true
|
waitForKeyboardLayout = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import AccountContext
|
|||||||
import AlertUI
|
import AlertUI
|
||||||
import PresentationDataUtils
|
import PresentationDataUtils
|
||||||
import SettingsUI
|
import SettingsUI
|
||||||
|
import StorageUsageScreen
|
||||||
|
|
||||||
private func totalDiskSpace() -> Int64 {
|
private func totalDiskSpace() -> Int64 {
|
||||||
do {
|
do {
|
||||||
@ -31,7 +32,9 @@ func checkAvailableDiskSpace(context: AccountContext, threshold: Int64 = 100 * 1
|
|||||||
|
|
||||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||||
let controller = textAlertController(context: context, title: nil, text: presentationData.strings.Cache_LowDiskSpaceText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.AccessDenied_Settings, action: {
|
let controller = textAlertController(context: context, title: nil, text: presentationData.strings.Cache_LowDiskSpaceText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.AccessDenied_Settings, action: {
|
||||||
push(storageUsageController(context: context, isModal: true))
|
push(StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in
|
||||||
|
return storageUsageExceptionsScreen(context: context, category: category)
|
||||||
|
}))
|
||||||
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
|
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
|
||||||
push(controller)
|
push(controller)
|
||||||
|
|
||||||
|
@ -199,7 +199,7 @@ class ContactMultiselectionControllerImpl: ViewController, ContactMultiselection
|
|||||||
let rightNavigationButton = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.rightNavigationButtonPressed))
|
let rightNavigationButton = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.rightNavigationButtonPressed))
|
||||||
self.rightNavigationButton = rightNavigationButton
|
self.rightNavigationButton = rightNavigationButton
|
||||||
self.navigationItem.rightBarButtonItem = self.rightNavigationButton
|
self.navigationItem.rightBarButtonItem = self.rightNavigationButton
|
||||||
rightNavigationButton.isEnabled = count != 0 || self.params.alwaysEnabled
|
rightNavigationButton.isEnabled = true //count != 0 || self.params.alwaysEnabled
|
||||||
case .channelCreation:
|
case .channelCreation:
|
||||||
self.titleView.title = CounterContollerTitle(title: self.presentationData.strings.GroupInfo_AddParticipantTitle, counter: "")
|
self.titleView.title = CounterContollerTitle(title: self.presentationData.strings.GroupInfo_AddParticipantTitle, counter: "")
|
||||||
let rightNavigationButton = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.rightNavigationButtonPressed))
|
let rightNavigationButton = UIBarButtonItem(title: self.presentationData.strings.Common_Next, style: .done, target: self, action: #selector(self.rightNavigationButtonPressed))
|
||||||
|
@ -907,7 +907,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
|||||||
let _ = (settings
|
let _ = (settings
|
||||||
|> deliverOnMainQueue).start(next: { settings in
|
|> deliverOnMainQueue).start(next: { settings in
|
||||||
if settings.defaultWebBrowser == nil {
|
if settings.defaultWebBrowser == nil {
|
||||||
if isCompact {
|
if !"".isEmpty && isCompact {
|
||||||
let controller = BrowserScreen(context: context, subject: .webPage(url: parsedUrl.absoluteString))
|
let controller = BrowserScreen(context: context, subject: .webPage(url: parsedUrl.absoluteString))
|
||||||
navigationController?.pushViewController(controller)
|
navigationController?.pushViewController(controller)
|
||||||
} else {
|
} else {
|
||||||
|
@ -4564,7 +4564,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
canSetupAutoremoveTimeout = true
|
canSetupAutoremoveTimeout = true
|
||||||
}
|
}
|
||||||
} else if let user = chatPeer as? TelegramUser {
|
} else if let user = chatPeer as? TelegramUser {
|
||||||
if user.id != strongSelf.context.account.peerId && user.botInfo == nil {
|
if user.id != strongSelf.context.account.peerId {
|
||||||
canSetupAutoremoveTimeout = true
|
canSetupAutoremoveTimeout = true
|
||||||
}
|
}
|
||||||
} else if let channel = chatPeer as? TelegramChannel {
|
} else if let channel = chatPeer as? TelegramChannel {
|
||||||
|
@ -1239,8 +1239,9 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
guard let navigationController = self.mainWindow?.viewController as? NavigationController else {
|
guard let navigationController = self.mainWindow?.viewController as? NavigationController else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
let controller = StorageUsageScreen(context: context, makeStorageUsageExceptionsScreen: { category in
|
||||||
let controller = storageUsageController(context: context, isModal: true)
|
return storageUsageExceptionsScreen(context: context, category: category)
|
||||||
|
})
|
||||||
navigationController.pushViewController(controller)
|
navigationController.pushViewController(controller)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user