Merge branch 'master' of github.com:peter-iakovlev/TelegramUI

This commit is contained in:
Ilya Laktyushin 2018-09-23 14:46:54 +01:00
commit cb30aa60a8
14 changed files with 2419 additions and 2308 deletions

View File

@ -323,11 +323,13 @@ public func channelMembersController(account: Account, peerId: PeerId) -> ViewCo
let arguments = ChannelMembersControllerArguments(account: account, addMember: {
let presentationData = account.telegramApplicationContext.currentPresentationData.with {$0}
actionsDisposable.add((peersPromise.get() |> take(1) |> deliverOnMainQueue).start(next: { members in
let disabledIds = members?.compactMap({$0.peer.id}) ?? []
let contactsController = ContactMultiselectionController(account: account, mode: .peerSelection, options: [], filters: [.excludeSelf, .disable(disabledIds)])
let addMembers: ([ContactListPeerId]) -> Signal<Void, NoError> = { members -> Signal<Void, NoError> in
let addMembers: ([ContactListPeerId]) -> Signal<Void, AddChannelMemberError> = { members -> Signal<Void, AddChannelMemberError> in
let peerIds = members.compactMap { contact -> PeerId? in
switch contact {
case let .peer(peerId):
@ -343,7 +345,9 @@ public func channelMembersController(account: Account, peerId: PeerId) -> ViewCo
|> deliverOnMainQueue |> mapToSignal { [weak contactsController] contacts in
contactsController?.displayProgress = true
return addMembers(contacts) |> mapToSignal { _ in
return addMembers(contacts) |> `catch` { error -> Signal<Void, NoError> in
return .single(Void())
} |> mapToSignal { _ in
return channelMembers(postbox: account.postbox, network: account.network, peerId: peerId)
} |> deliverOnMainQueue |> afterNext { _ in
contactsController?.dismiss()

View File

@ -4456,7 +4456,12 @@ public final class ChatController: TelegramController, UIViewControllerPreviewin
}
if concealed, let parsedUrlValue = parsedUrlValue, (parsedUrlValue.scheme == "http" || parsedUrlValue.scheme == "https"), !isConcealedUrlWhitelisted(parsedUrlValue) {
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: self.presentationData.theme), title: nil, text: self.presentationData.strings.Generic_OpenHiddenLinkAlert(url).0, actions: [TextAlertAction(type: .genericAction, title: self.presentationData.strings.Common_No, action: {}), TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_Yes, action: {
var displayUrl = url
let maxLength = 180
if displayUrl.count > maxLength {
displayUrl = String(displayUrl[..<displayUrl.index(displayUrl.startIndex, offsetBy: maxLength - 2)]) + "..."
}
self.present(standardTextAlertController(theme: AlertControllerTheme(presentationTheme: self.presentationData.theme), title: nil, text: self.presentationData.strings.Generic_OpenHiddenLinkAlert(displayUrl).0, actions: [TextAlertAction(type: .genericAction, title: self.presentationData.strings.Common_No, action: {}), TextAlertAction(type: .defaultAction, title: self.presentationData.strings.Common_Yes, action: {
openImpl()
})]), in: .window(.root))
} else {

View File

@ -94,6 +94,10 @@ private let internalExtensions = Set<String>([
"cs"
])
private let internalNotSupportedExtensions = Set<String>([
"djvu"
])
private let internalMimeTypes = Set<String>([
"application/pdf",
"application/postscript",
@ -101,7 +105,9 @@ private let internalMimeTypes = Set<String>([
])
private let internalMimePrefixes: [String] = [
"image/",
"image/jpeg",
"image/jpg",
"image/png",
"text/",
"application/vnd.ms-"
]
@ -118,6 +124,9 @@ func internalDocumentItemSupportsMimeType(_ type: String, fileName: String?) ->
if internalExtensions.contains(ext.lowercased()) {
return true
}
if internalNotSupportedExtensions.contains(ext.lowercased()) {
return false
}
}
if internalMimeTypes.contains(type) {

View File

@ -1462,7 +1462,7 @@ public func groupInfoController(account: Account, peerId: PeerId) -> ViewControl
}
}
let addMembers: ([ContactListPeerId]) -> Signal<Void, NoError> = { members -> Signal<Void, NoError> in
let addMembers: ([ContactListPeerId]) -> Signal<Void, AddChannelMemberError> = { members -> Signal<Void, AddChannelMemberError> in
let memberIds = members.compactMap { contact -> PeerId? in
switch contact {
case let .peer(peerId):
@ -1474,29 +1474,31 @@ public func groupInfoController(account: Account, peerId: PeerId) -> ViewControl
return account.postbox.multiplePeersView(memberIds)
|> take(1)
|> deliverOnMainQueue
|> mapToSignal { view -> Signal<Void, NoError> in
updateState { state in
var state = state
for (memberId, peer) in view.peers {
var found = false
for participant in state.temporaryParticipants {
if participant.peer.id == memberId {
found = true
break
|> mapError { _ in return .generic}
|> mapToSignal { view -> Signal<Void, AddChannelMemberError> in
return account.telegramApplicationContext.peerChannelMemberCategoriesContextsManager.addMembers(account: account, peerId: peerId, memberIds: memberIds) |> map { _ in
updateState { state in
var state = state
for (memberId, peer) in view.peers {
var found = false
for participant in state.temporaryParticipants {
if participant.peer.id == memberId {
found = true
break
}
}
if !found {
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
var temporaryParticipants = state.temporaryParticipants
temporaryParticipants.append(TemporaryParticipant(peer: peer, presence: view.presences[memberId], timestamp: timestamp))
state = state.withUpdatedTemporaryParticipants(temporaryParticipants)
}
}
if !found {
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
var temporaryParticipants = state.temporaryParticipants
temporaryParticipants.append(TemporaryParticipant(peer: peer, presence: view.presences[memberId], timestamp: timestamp))
state = state.withUpdatedTemporaryParticipants(temporaryParticipants)
}
return state
}
return state
}
return account.telegramApplicationContext.peerChannelMemberCategoriesContextsManager.addMembers(account: account, peerId: peerId, memberIds: memberIds)
}
}
@ -1531,7 +1533,21 @@ public func groupInfoController(account: Account, peerId: PeerId) -> ViewControl
contactsController?.displayProgress = true
addMemberDisposable.set((addMembers(peers)
|> deliverOnMainQueue).start(completed: {
|> deliverOnMainQueue).start(error: { error in
if peers.count == 1, error == .restricted {
switch peers[0] {
case let .peer(peerId):
_ = (account.postbox.loadedPeerWithId(peerId) |> deliverOnMainQueue).start(next: { peer in
let alert = standardTextAlertController(theme: AlertControllerTheme(presentationTheme: presentationData.theme), title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(peer.compactDisplayTitle, peer.compactDisplayTitle).0, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: {})])
presentControllerImpl?(alert, nil)
})
default:
break
}
}
contactsController?.dismiss()
},completed: {
contactsController?.dismiss()
}))
}))

View File

@ -12,16 +12,18 @@ public struct InAppNotificationSettings: PreferencesEntry, Equatable {
public var vibrate: Bool
public var displayPreviews: Bool
public var totalUnreadCountDisplayStyle: TotalUnreadCountDisplayStyle
public var displayNameOnLockscreen: Bool
public static var defaultSettings: InAppNotificationSettings {
return InAppNotificationSettings(playSounds: true, vibrate: false, displayPreviews: true, totalUnreadCountDisplayStyle: .filtered)
return InAppNotificationSettings(playSounds: true, vibrate: false, displayPreviews: true, totalUnreadCountDisplayStyle: .filtered, displayNameOnLockscreen: true)
}
init(playSounds: Bool, vibrate: Bool, displayPreviews: Bool, totalUnreadCountDisplayStyle: TotalUnreadCountDisplayStyle) {
init(playSounds: Bool, vibrate: Bool, displayPreviews: Bool, totalUnreadCountDisplayStyle: TotalUnreadCountDisplayStyle, displayNameOnLockscreen: Bool) {
self.playSounds = playSounds
self.vibrate = vibrate
self.displayPreviews = displayPreviews
self.totalUnreadCountDisplayStyle = totalUnreadCountDisplayStyle
self.displayNameOnLockscreen = displayNameOnLockscreen
}
public init(decoder: PostboxDecoder) {
@ -29,6 +31,7 @@ public struct InAppNotificationSettings: PreferencesEntry, Equatable {
self.vibrate = decoder.decodeInt32ForKey("v", orElse: 0) != 0
self.displayPreviews = decoder.decodeInt32ForKey("p", orElse: 0) != 0
self.totalUnreadCountDisplayStyle = TotalUnreadCountDisplayStyle(rawValue: decoder.decodeInt32ForKey("tds", orElse: 0)) ?? .filtered
self.displayNameOnLockscreen = decoder.decodeInt32ForKey("displayNameOnLockscreen", orElse: 1) != 0
}
public func encode(_ encoder: PostboxEncoder) {
@ -36,22 +39,7 @@ public struct InAppNotificationSettings: PreferencesEntry, Equatable {
encoder.encodeInt32(self.vibrate ? 1 : 0, forKey: "v")
encoder.encodeInt32(self.displayPreviews ? 1 : 0, forKey: "p")
encoder.encodeInt32(self.totalUnreadCountDisplayStyle.rawValue, forKey: "tds")
}
func withUpdatedPlaySounds(_ playSounds: Bool) -> InAppNotificationSettings {
return InAppNotificationSettings(playSounds: playSounds, vibrate: self.vibrate, displayPreviews: self.displayPreviews, totalUnreadCountDisplayStyle: self.totalUnreadCountDisplayStyle)
}
func withUpdatedVibrate(_ vibrate: Bool) -> InAppNotificationSettings {
return InAppNotificationSettings(playSounds: self.playSounds, vibrate: vibrate, displayPreviews: self.displayPreviews, totalUnreadCountDisplayStyle: self.totalUnreadCountDisplayStyle)
}
func withUpdatedDisplayPreviews(_ displayPreviews: Bool) -> InAppNotificationSettings {
return InAppNotificationSettings(playSounds: self.playSounds, vibrate: self.vibrate, displayPreviews: displayPreviews, totalUnreadCountDisplayStyle: self.totalUnreadCountDisplayStyle)
}
func withUpdatedTotalUnreadCountDisplayStyle(_ totalUnreadCountDisplayStyle: TotalUnreadCountDisplayStyle) -> InAppNotificationSettings {
return InAppNotificationSettings(playSounds: self.playSounds, vibrate: self.vibrate, displayPreviews: self.displayPreviews, totalUnreadCountDisplayStyle: totalUnreadCountDisplayStyle)
encoder.encodeInt32(self.displayNameOnLockscreen ? 1 : 0, forKey: "displayNameOnLockscreen")
}
public func isEqual(to: PreferencesEntry) -> Bool {
@ -61,22 +49,6 @@ public struct InAppNotificationSettings: PreferencesEntry, Equatable {
return false
}
}
public static func ==(lhs: InAppNotificationSettings, rhs: InAppNotificationSettings) -> Bool {
if lhs.playSounds != rhs.playSounds {
return false
}
if lhs.vibrate != rhs.vibrate {
return false
}
if lhs.displayPreviews != rhs.displayPreviews {
return false
}
if lhs.totalUnreadCountDisplayStyle != rhs.totalUnreadCountDisplayStyle {
return false
}
return true
}
}
func updateInAppNotificationSettingsInteractively(postbox: Postbox, _ f: @escaping (InAppNotificationSettings) -> InAppNotificationSettings) -> Signal<Void, NoError> {

View File

@ -551,6 +551,8 @@ public final class ManagedAudioSession {
print("ManagedAudioSession setting active false")
do {
try AVAudioSession.sharedInstance().setActive(false, with: [.notifyOthersOnDeactivation])
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
try AVAudioSession.sharedInstance().setPreferredInput(nil)
} catch let error {
print("ManagedAudioSession applyNone error \(error)")
}

View File

@ -21,11 +21,12 @@ private final class NotificationsAndSoundsArguments {
let updateInAppVibration: (Bool) -> Void
let updateInAppPreviews: (Bool) -> Void
let updateDisplayNameOnLockscreen: (Bool) -> Void
let updateTotalUnreadCountStyle: (Bool) -> Void
let resetNotifications: () -> Void
init(account: Account, presentController: @escaping (ViewController, ViewControllerPresentationArguments) -> Void, soundSelectionDisposable: MetaDisposable, updateMessageAlerts: @escaping (Bool) -> Void, updateMessagePreviews: @escaping (Bool) -> Void, updateMessageSound: @escaping (PeerMessageSound) -> Void, updateGroupAlerts: @escaping (Bool) -> Void, updateGroupPreviews: @escaping (Bool) -> Void, updateGroupSound: @escaping (PeerMessageSound) -> Void, updateInAppSounds: @escaping (Bool) -> Void, updateInAppVibration: @escaping (Bool) -> Void, updateInAppPreviews: @escaping (Bool) -> Void, updateTotalUnreadCountStyle: @escaping (Bool) -> Void, resetNotifications: @escaping () -> Void) {
init(account: Account, presentController: @escaping (ViewController, ViewControllerPresentationArguments) -> Void, soundSelectionDisposable: MetaDisposable, updateMessageAlerts: @escaping (Bool) -> Void, updateMessagePreviews: @escaping (Bool) -> Void, updateMessageSound: @escaping (PeerMessageSound) -> Void, updateGroupAlerts: @escaping (Bool) -> Void, updateGroupPreviews: @escaping (Bool) -> Void, updateGroupSound: @escaping (PeerMessageSound) -> Void, updateInAppSounds: @escaping (Bool) -> Void, updateInAppVibration: @escaping (Bool) -> Void, updateInAppPreviews: @escaping (Bool) -> Void, updateDisplayNameOnLockscreen: @escaping (Bool) -> Void, updateTotalUnreadCountStyle: @escaping (Bool) -> Void, resetNotifications: @escaping () -> Void) {
self.account = account
self.presentController = presentController
self.soundSelectionDisposable = soundSelectionDisposable
@ -38,6 +39,7 @@ private final class NotificationsAndSoundsArguments {
self.updateInAppSounds = updateInAppSounds
self.updateInAppVibration = updateInAppVibration
self.updateInAppPreviews = updateInAppPreviews
self.updateDisplayNameOnLockscreen = updateDisplayNameOnLockscreen
self.updateTotalUnreadCountStyle = updateTotalUnreadCountStyle
self.resetNotifications = resetNotifications
}
@ -47,6 +49,7 @@ private enum NotificationsAndSoundsSection: Int32 {
case messages
case groups
case inApp
case displayNamesOnLockscreen
case unreadCountStyle
case reset
}
@ -69,6 +72,8 @@ private enum NotificationsAndSoundsEntry: ItemListNodeEntry {
case inAppVibrate(PresentationTheme, String, Bool)
case inAppPreviews(PresentationTheme, String, Bool)
case displayNamesOnLockscreen(PresentationTheme, String, Bool)
case displayNamesOnLockscreenInfo(PresentationTheme, String)
case unreadCountStyle(PresentationTheme, String, Bool)
case reset(PresentationTheme, String)
@ -82,6 +87,8 @@ private enum NotificationsAndSoundsEntry: ItemListNodeEntry {
return NotificationsAndSoundsSection.groups.rawValue
case .inAppHeader, .inAppSounds, .inAppVibrate, .inAppPreviews:
return NotificationsAndSoundsSection.inApp.rawValue
case .displayNamesOnLockscreen, .displayNamesOnLockscreenInfo:
return NotificationsAndSoundsSection.displayNamesOnLockscreen.rawValue
case .unreadCountStyle:
return NotificationsAndSoundsSection.unreadCountStyle.rawValue
case .reset, .resetNotice:
@ -119,12 +126,16 @@ private enum NotificationsAndSoundsEntry: ItemListNodeEntry {
return 12
case .inAppPreviews:
return 13
case .unreadCountStyle:
case .displayNamesOnLockscreen:
return 14
case .reset:
case .displayNamesOnLockscreenInfo:
return 15
case .resetNotice:
case .unreadCountStyle:
return 16
case .reset:
return 17
case .resetNotice:
return 18
}
}
@ -214,6 +225,18 @@ private enum NotificationsAndSoundsEntry: ItemListNodeEntry {
} else {
return false
}
case let .displayNamesOnLockscreen(lhsTheme, lhsText, lhsValue):
if case let .displayNamesOnLockscreen(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
} else {
return false
}
case let .displayNamesOnLockscreenInfo(lhsTheme, lhsText):
if case let .displayNamesOnLockscreenInfo(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
return true
} else {
return false
}
case let .unreadCountStyle(lhsTheme, lhsText, lhsValue):
if case let .unreadCountStyle(rhsTheme, rhsText, rhsValue) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsValue == rhsValue {
return true
@ -293,6 +316,12 @@ private enum NotificationsAndSoundsEntry: ItemListNodeEntry {
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateInAppPreviews(updatedValue)
})
case let .displayNamesOnLockscreen(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateDisplayNameOnLockscreen(updatedValue)
})
case let .displayNamesOnLockscreenInfo(theme, text):
return ItemListTextItem(theme: theme, text: .plain(text), sectionId: self.section)
case let .unreadCountStyle(theme, text, value):
return ItemListSwitchItem(theme: theme, title: text, value: value, sectionId: self.section, style: .blocks, updated: { updatedValue in
arguments.updateTotalUnreadCountStyle(updatedValue)
@ -335,7 +364,11 @@ private func notificationsAndSoundsEntries(globalSettings: GlobalNotificationSet
entries.append(.inAppVibrate(presentationData.theme, presentationData.strings.Notifications_InAppNotificationsVibrate, inAppSettings.vibrate))
entries.append(.inAppPreviews(presentationData.theme, presentationData.strings.Notifications_InAppNotificationsPreview, inAppSettings.displayPreviews))
entries.append(.unreadCountStyle(presentationData.theme, "Include muted chats", inAppSettings.totalUnreadCountDisplayStyle == .raw))
entries.append(.displayNamesOnLockscreen(presentationData.theme, presentationData.strings.Notifications_DisplayNamesOnLockScreen, inAppSettings.displayNameOnLockscreen))
entries.append(.displayNamesOnLockscreenInfo(presentationData.theme, presentationData.strings.Notifications_DisplayNamesOnLockScreenInfo))
if !GlobalExperimentalSettings.isAppStoreBuild {
entries.append(.unreadCountStyle(presentationData.theme, "Include muted chats", inAppSettings.totalUnreadCountDisplayStyle == .raw))
}
entries.append(.reset(presentationData.theme, presentationData.strings.Notifications_ResetAllNotifications))
entries.append(.resetNotice(presentationData.theme, presentationData.strings.Notifications_ResetAllNotificationsHelp))
@ -386,19 +419,33 @@ public func notificationsAndSoundsController(account: Account) -> ViewController
}).start()
}, updateInAppSounds: { value in
let _ = updateInAppNotificationSettingsInteractively(postbox: account.postbox, { settings in
return settings.withUpdatedPlaySounds(value)
var settings = settings
settings.playSounds = value
return settings
}).start()
}, updateInAppVibration: { value in
let _ = updateInAppNotificationSettingsInteractively(postbox: account.postbox, { settings in
return settings.withUpdatedVibrate(value)
var settings = settings
settings.vibrate = value
return settings
}).start()
}, updateInAppPreviews: { value in
let _ = updateInAppNotificationSettingsInteractively(postbox: account.postbox, { settings in
return settings.withUpdatedDisplayPreviews(value)
var settings = settings
settings.displayPreviews = value
return settings
}).start()
}, updateDisplayNameOnLockscreen: { value in
let _ = updateInAppNotificationSettingsInteractively(postbox: account.postbox, { settings in
var settings = settings
settings.displayNameOnLockscreen = value
return settings
}).start()
}, updateTotalUnreadCountStyle: { value in
let _ = updateInAppNotificationSettingsInteractively(postbox: account.postbox, { settings in
return settings.withUpdatedTotalUnreadCountDisplayStyle(value ? .raw : .filtered)
var settings = settings
settings.totalUnreadCountDisplayStyle = value ? .raw : .filtered
return settings
}).start()
}, resetNotifications: {
let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 }

View File

@ -175,7 +175,7 @@ final class PeerChannelMemberCategoriesContextsManager {
}
}
func addMembers(account: Account, peerId: PeerId, memberIds: [PeerId]) -> Signal<Void, NoError> {
func addMembers(account: Account, peerId: PeerId, memberIds: [PeerId]) -> Signal<Void, AddChannelMemberError> {
return addChannelMembers(account: account, peerId: peerId, memberIds: memberIds) |> deliverOnMainQueue
|> beforeNext { [weak self] result in
if let strongSelf = self {
@ -188,7 +188,7 @@ final class PeerChannelMemberCategoriesContextsManager {
}
}
}
|> mapToSignal { _ -> Signal<Void, NoError> in
|> mapToSignal { _ -> Signal<Void, AddChannelMemberError> in
return .single(Void())
}
}

View File

@ -51,6 +51,14 @@ private final class PresentationCallToneRenderer {
}
let toneDataOffset = Atomic<Int>(value: 0)
let toneDataMaxOffset: Int?
if let loopCount = tone.loopCount {
toneDataMaxOffset = (data?.count ?? 0) * loopCount
} else {
toneDataMaxOffset = nil
}
self.toneRenderer.beginRequestingFrames(queue: DispatchQueue.global(), takeFrame: {
guard let toneData = data else {
return .finished
@ -65,6 +73,10 @@ private final class PresentationCallToneRenderer {
}
if let takeOffset = takeOffset {
if let toneDataMaxOffset = toneDataMaxOffset, takeOffset >= toneDataMaxOffset {
return .finished
}
var blockBuffer: CMBlockBuffer?
let bytes = malloc(frameSize)!
@ -77,6 +89,12 @@ private final class PresentationCallToneRenderer {
takenCount += dataCount
}
}
if let toneDataMaxOffset = toneDataMaxOffset, takeOffset + frameSize > toneDataMaxOffset {
let validCount = max(0, toneDataMaxOffset - takeOffset)
memset(bytes.advanced(by: validCount), 0, frameSize - validCount)
}
let status = CMBlockBufferCreateWithMemoryBlock(nil, bytes, frameSize, nil, nil, 0, frameSize, 0, &blockBuffer)
if status != noErr {
return .finished
@ -276,9 +294,11 @@ public final class PresentationCall {
if let audioSessionControl = strongSelf.audioSessionControl {
let audioSessionActive: Signal<Bool, NoError>
if let callKitIntegration = strongSelf.callKitIntegration {
audioSessionActive = callKitIntegration.audioSessionActive |> filter { $0 } |> timeout(2.0, queue: Queue.mainQueue(), alternate: Signal { subscriber in
audioSessionActive = callKitIntegration.audioSessionActive
|> filter { $0 }
|> timeout(2.0, queue: Queue.mainQueue(), alternate: Signal { subscriber in
if let strongSelf = self, let audioSessionControl = strongSelf.audioSessionControl {
audioSessionControl.activate({ _ in })
//audioSessionControl.activate({ _ in })
}
subscriber.putNext(true)
subscriber.putCompletion()
@ -432,12 +452,12 @@ public final class PresentationCall {
if case .terminated = sessionState.state, !wasTerminated {
if !self.didSetCanBeRemoved {
self.didSetCanBeRemoved = true
self.canBeRemovedPromise.set(.single(true) |> delay(2.0, queue: Queue.mainQueue()))
self.canBeRemovedPromise.set(.single(true) |> delay(2.4, queue: Queue.mainQueue()))
}
self.hungUpPromise.set(true)
if sessionState.isOutgoing {
if !self.droppedCall && self.dropCallKitCallTimer == nil {
let dropCallKitCallTimer = SwiftSignalKit.Timer(timeout: 2.0, repeat: false, completion: { [weak self] in
let dropCallKitCallTimer = SwiftSignalKit.Timer(timeout: 2.4, repeat: false, completion: { [weak self] in
if let strongSelf = self {
strongSelf.dropCallKitCallTimer = nil
if !strongSelf.droppedCall {

View File

@ -71,6 +71,15 @@ enum PresentationCallTone {
case busy
case failed
case ended
var loopCount: Int? {
switch self {
case .busy, .failed, .ended:
return 3
default:
return nil
}
}
}
func presentationCallToneData(_ tone: PresentationCallTone) -> Data? {

File diff suppressed because it is too large Load Diff

View File

@ -59,7 +59,8 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
if !filled {
if let contentNode = strongSelf.contentNode as? SecureIdAuthFormContentNode {
if let rect = contentNode.frameForField(field) {
strongSelf.scrollNode.view.scrollRectToVisible(rect, animated: true)
let subRect = contentNode.view.convert(rect, to: strongSelf.scrollNode.view)
strongSelf.scrollNode.view.scrollRectToVisible(subRect, animated: true)
}
contentNode.highlightField(field)
}
@ -266,6 +267,9 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
case let .passwordChallenge(hint, challengeState, _):
if let current = self.contentNode as? SecureIdAuthPasswordOptionContentNode {
current.updateIsChecking(challengeState == .checking)
if case .invalid = challengeState {
current.updateIsInvalid()
}
contentNode = current
} else {
let current = SecureIdAuthPasswordOptionContentNode(theme: presentationData.theme, strings: presentationData.strings, hint: hint, checkPassword: { [weak self] password in
@ -276,6 +280,9 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
self?.interaction.openPasswordHelp()
})
current.updateIsChecking(challengeState == .checking)
if case .invalid = challengeState {
current.updateIsInvalid()
}
contentNode = current
}
case .verified:

View File

@ -13,6 +13,7 @@ final class SecureIdAuthPasswordOptionContentNode: ASDisplayNode, SecureIdAuthCo
private let titleNode: ImmediateTextNode
private let inputBackground: ASImageNode
private let inputField: TextFieldNode
private var clearOnce: Bool = false
private let inputButtonNode: HighlightableButtonNode
private let inputActivityNode: ActivityIndicator
@ -180,7 +181,18 @@ final class SecureIdAuthPasswordOptionContentNode: ASDisplayNode, SecureIdAuthCo
}
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
return !self.isChecking
if self.isChecking {
return false
}
if self.clearOnce {
self.clearOnce = false
if range.length > string.count {
textField.text = ""
return false
}
}
return true
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
@ -196,4 +208,8 @@ final class SecureIdAuthPasswordOptionContentNode: ASDisplayNode, SecureIdAuthCo
self.inputActivityNode.isHidden = !isChecking
self.inputButtonNode.isHidden = isChecking
}
func updateIsInvalid() {
self.clearOnce = true
}
}

View File

@ -606,7 +606,7 @@ enum SecureIdPlaintextFormEntry: FormControllerEntry {
return FormControllerTextInputItem(title: strings.TwoStepAuth_Email, text: address, placeholder: strings.Passport_Email_EmailPlaceholder, type: .email, textUpdated: { value in
params.updateTextField(.email, value)
}, returnPressed: {
params.save()
})
case .emailInputInfo:
return FormControllerTextItem(text: strings.Passport_Email_Help)