mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-16 11:20:18 +00:00
no message
This commit is contained in:
parent
f82e4c1c7c
commit
f7963c166c
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
091BEAB3214552D9003AEA30 /* Vision.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D02DADBE2138D76F00116225 /* Vision.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
091BEAB3214552D9003AEA30 /* Vision.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D02DADBE2138D76F00116225 /* Vision.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
||||||
|
092F368D2154AAEA001A9F49 /* SFCompactRounded-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 092F368C2154AAE9001A9F49 /* SFCompactRounded-Semibold.otf */; };
|
||||||
09310D2C213ED5FB0020033A /* anim_read.json in Resources */ = {isa = PBXBuildFile; fileRef = 09310D14213BC5DE0020033A /* anim_read.json */; };
|
09310D2C213ED5FB0020033A /* anim_read.json in Resources */ = {isa = PBXBuildFile; fileRef = 09310D14213BC5DE0020033A /* anim_read.json */; };
|
||||||
09310D2D213ED5FB0020033A /* anim_pin.json in Resources */ = {isa = PBXBuildFile; fileRef = 09310D15213BC5DE0020033A /* anim_pin.json */; };
|
09310D2D213ED5FB0020033A /* anim_pin.json in Resources */ = {isa = PBXBuildFile; fileRef = 09310D15213BC5DE0020033A /* anim_pin.json */; };
|
||||||
09310D2E213ED5FB0020033A /* anim_unmute.json in Resources */ = {isa = PBXBuildFile; fileRef = 09310D16213BC5DE0020033A /* anim_unmute.json */; };
|
09310D2E213ED5FB0020033A /* anim_unmute.json in Resources */ = {isa = PBXBuildFile; fileRef = 09310D16213BC5DE0020033A /* anim_unmute.json */; };
|
||||||
@ -1022,6 +1023,7 @@
|
|||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
|
092F368C2154AAE9001A9F49 /* SFCompactRounded-Semibold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SFCompactRounded-Semibold.otf"; sourceTree = "<group>"; };
|
||||||
09310D14213BC5DE0020033A /* anim_read.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = anim_read.json; sourceTree = "<group>"; };
|
09310D14213BC5DE0020033A /* anim_read.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = anim_read.json; sourceTree = "<group>"; };
|
||||||
09310D15213BC5DE0020033A /* anim_pin.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = anim_pin.json; sourceTree = "<group>"; };
|
09310D15213BC5DE0020033A /* anim_pin.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = anim_pin.json; sourceTree = "<group>"; };
|
||||||
09310D16213BC5DE0020033A /* anim_unmute.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = anim_unmute.json; sourceTree = "<group>"; };
|
09310D16213BC5DE0020033A /* anim_unmute.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = anim_unmute.json; sourceTree = "<group>"; };
|
||||||
@ -2164,6 +2166,15 @@
|
|||||||
/* End PBXFrameworksBuildPhase section */
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXGroup section */
|
/* Begin PBXGroup section */
|
||||||
|
092F368B2154AAD6001A9F49 /* Fonts */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
092F368C2154AAE9001A9F49 /* SFCompactRounded-Semibold.otf */,
|
||||||
|
);
|
||||||
|
name = Fonts;
|
||||||
|
path = TelegramUI/Resources/Fonts;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
09310D13213BC5DE0020033A /* Animations */ = {
|
09310D13213BC5DE0020033A /* Animations */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -2520,6 +2531,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
09310D13213BC5DE0020033A /* Animations */,
|
09310D13213BC5DE0020033A /* Animations */,
|
||||||
|
092F368B2154AAD6001A9F49 /* Fonts */,
|
||||||
D0C12A1B1F33964900B3F66D /* ChatWallpaperBuiltin0.jpg */,
|
D0C12A1B1F33964900B3F66D /* ChatWallpaperBuiltin0.jpg */,
|
||||||
D0E9BA681F056F4C00F079A4 /* Stripe */,
|
D0E9BA681F056F4C00F079A4 /* Stripe */,
|
||||||
D0E9B9E91F00853C00F079A4 /* PhoneCountries.txt */,
|
D0E9B9E91F00853C00F079A4 /* PhoneCountries.txt */,
|
||||||
@ -4637,6 +4649,7 @@
|
|||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
092F368D2154AAEA001A9F49 /* SFCompactRounded-Semibold.otf in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -168,7 +168,7 @@ class CallListCallItem: ListViewItem {
|
|||||||
|
|
||||||
private let separatorHeight = 1.0 / UIScreen.main.scale
|
private let separatorHeight = 1.0 / UIScreen.main.scale
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 15.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 16.0)!
|
||||||
|
|
||||||
class CallListCallItemNode: ItemListRevealOptionsItemNode {
|
class CallListCallItemNode: ItemListRevealOptionsItemNode {
|
||||||
private let backgroundNode: ASDisplayNode
|
private let backgroundNode: ASDisplayNode
|
||||||
|
|||||||
@ -2,8 +2,8 @@ import Foundation
|
|||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
import Display
|
import Display
|
||||||
|
|
||||||
private let normalFont = UIFont(name: "ArialRoundedMTBold", size: 16.0)!
|
private let normalFont = UIFont(name: ".SFCompactRounded-Semibold", size: 16.0)!
|
||||||
private let smallFont = UIFont(name: "ArialRoundedMTBold", size: 12.0)!
|
private let smallFont = UIFont(name: ".SFCompactRounded-Semibold", size: 12.0)!
|
||||||
|
|
||||||
final class ChatAvatarNavigationNode: ASDisplayNode {
|
final class ChatAvatarNavigationNode: ASDisplayNode {
|
||||||
let avatarNode: AvatarNode
|
let avatarNode: AvatarNode
|
||||||
|
|||||||
@ -205,7 +205,7 @@ private func leftRevealOptions(strings: PresentationStrings, theme: Presentation
|
|||||||
|
|
||||||
private let separatorHeight = 1.0 / UIScreen.main.scale
|
private let separatorHeight = 1.0 / UIScreen.main.scale
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 26.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 26.0)!
|
||||||
|
|
||||||
class ChatListItemNode: ItemListRevealOptionsItemNode {
|
class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||||
var item: ChatListItem?
|
var item: ChatListItem?
|
||||||
|
|||||||
@ -146,7 +146,8 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
|
|||||||
if let user = primaryPeer as? TelegramUser {
|
if let user = primaryPeer as? TelegramUser {
|
||||||
if let _ = user.botInfo {
|
if let _ = user.botInfo {
|
||||||
status = .custom(strings.Bot_GenericBotStatus)
|
status = .custom(strings.Bot_GenericBotStatus)
|
||||||
} else if user.id != account.peerId, let presence = peer.presence {
|
} else if user.id != account.peerId {
|
||||||
|
let presence = peer.presence ?? TelegramUserPresence(status: .none)
|
||||||
status = .presence(presence, timeFormat)
|
status = .presence(presence, timeFormat)
|
||||||
} else {
|
} else {
|
||||||
status = .none
|
status = .none
|
||||||
|
|||||||
@ -56,7 +56,7 @@ final class ChatMediaInputPeerSpecificItem: ListViewItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 10.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 10.0)!
|
||||||
private let boundingSize = CGSize(width: 41.0, height: 41.0)
|
private let boundingSize = CGSize(width: 41.0, height: 41.0)
|
||||||
private let boundingImageSize = CGSize(width: 28.0, height: 28.0)
|
private let boundingImageSize = CGSize(width: 28.0, height: 28.0)
|
||||||
private let highlightSize = CGSize(width: 35.0, height: 35.0)
|
private let highlightSize = CGSize(width: 35.0, height: 35.0)
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import Postbox
|
|||||||
import Display
|
import Display
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 15.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 16.0)!
|
||||||
|
|
||||||
final class ChatMessageAvatarAccessoryItem: ListViewAccessoryItem {
|
final class ChatMessageAvatarAccessoryItem: ListViewAccessoryItem {
|
||||||
private let account: Account
|
private let account: Account
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import SwiftSignalKit
|
|||||||
import Postbox
|
import Postbox
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 15.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 16.0)!
|
||||||
|
|
||||||
private let titleFont = Font.medium(14.0)
|
private let titleFont = Font.medium(14.0)
|
||||||
private let textFont = Font.regular(14.0)
|
private let textFont = Font.regular(14.0)
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import Display
|
|||||||
import TelegramCore
|
import TelegramCore
|
||||||
import Postbox
|
import Postbox
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 24.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 24.0)!
|
||||||
private let avatarBackgroundImage = UIImage(bundleImageName: "Chat/Message/LocationPin")?.precomposed()
|
private let avatarBackgroundImage = UIImage(bundleImageName: "Chat/Message/LocationPin")?.precomposed()
|
||||||
|
|
||||||
private func addPulseAnimations(layer: CALayer) {
|
private func addPulseAnimations(layer: CALayer) {
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import Foundation
|
|||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
import Display
|
import Display
|
||||||
|
|
||||||
private let textFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 13.0)!
|
private let textFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 13.0)!
|
||||||
|
|
||||||
private class ChatMessageLiveLocationTimerNodeParams: NSObject {
|
private class ChatMessageLiveLocationTimerNodeParams: NSObject {
|
||||||
let backgroundColor: UIColor
|
let backgroundColor: UIColor
|
||||||
|
|||||||
@ -45,7 +45,7 @@ public final class ChatMessageNotificationItem: NotificationItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 24.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 24.0)!
|
||||||
|
|
||||||
final class ChatMessageNotificationItemNode: NotificationItemNode {
|
final class ChatMessageNotificationItemNode: NotificationItemNode {
|
||||||
private var item: ChatMessageNotificationItem?
|
private var item: ChatMessageNotificationItem?
|
||||||
|
|||||||
@ -62,7 +62,7 @@ final class ChatReportPeerTitlePanelNode: ChatTitleAccessoryPanelNode {
|
|||||||
|
|
||||||
let panelHeight: CGFloat = 40.0
|
let panelHeight: CGFloat = 40.0
|
||||||
|
|
||||||
let contentRightInset: CGFloat = 18.0 + rightInset
|
let contentRightInset: CGFloat = 14.0 + rightInset
|
||||||
|
|
||||||
let closeButtonSize = self.closeButton.measure(CGSize(width: 100.0, height: 100.0))
|
let closeButtonSize = self.closeButton.measure(CGSize(width: 100.0, height: 100.0))
|
||||||
transition.updateFrame(node: self.closeButton, frame: CGRect(origin: CGPoint(x: width - contentRightInset - closeButtonSize.width, y: floorToScreenPixels((panelHeight - closeButtonSize.height) / 2.0)), size: closeButtonSize))
|
transition.updateFrame(node: self.closeButton, frame: CGRect(origin: CGPoint(x: width - contentRightInset - closeButtonSize.width, y: floorToScreenPixels((panelHeight - closeButtonSize.height) / 2.0)), size: closeButtonSize))
|
||||||
|
|||||||
@ -72,7 +72,7 @@ final class CommandChatInputPanelItem: ListViewItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 16.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 16.0)!
|
||||||
private let textFont = Font.medium(14.0)
|
private let textFont = Font.medium(14.0)
|
||||||
private let descriptionFont = Font.regular(14.0)
|
private let descriptionFont = Font.regular(14.0)
|
||||||
|
|
||||||
|
|||||||
@ -151,10 +151,9 @@ private enum ContactListNodeEntry: Comparable, Identifiable {
|
|||||||
case let .peer(peer, isGlobal):
|
case let .peer(peer, isGlobal):
|
||||||
if isGlobal, let _ = peer.addressName {
|
if isGlobal, let _ = peer.addressName {
|
||||||
status = .addressName("")
|
status = .addressName("")
|
||||||
} else if let presence = presence {
|
|
||||||
status = .presence(presence, timeFormat)
|
|
||||||
} else {
|
} else {
|
||||||
status = .none
|
let presence = presence ?? TelegramUserPresence(status: .none)
|
||||||
|
status = .presence(presence, timeFormat)
|
||||||
}
|
}
|
||||||
itemPeer = .peer(peer: peer, chatPeer: peer)
|
itemPeer = .peer(peer: peer, chatPeer: peer)
|
||||||
case let .deviceContact(id, contact):
|
case let .deviceContact(id, contact):
|
||||||
|
|||||||
@ -270,7 +270,7 @@ class ContactsPeerItem: ListViewItem {
|
|||||||
|
|
||||||
private let separatorHeight = 1.0 / UIScreen.main.scale
|
private let separatorHeight = 1.0 / UIScreen.main.scale
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 15.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 16.0)!
|
||||||
|
|
||||||
class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
class ContactsPeerItemNode: ItemListRevealOptionsItemNode {
|
||||||
private let backgroundNode: ASDisplayNode
|
private let backgroundNode: ASDisplayNode
|
||||||
|
|||||||
@ -240,7 +240,7 @@ class ItemListAvatarAndNameInfoItem: ListViewItem, ItemListItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 28.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 28.0)!
|
||||||
private let nameFont = Font.medium(19.0)
|
private let nameFont = Font.medium(19.0)
|
||||||
private let statusFont = Font.regular(15.0)
|
private let statusFont = Font.regular(15.0)
|
||||||
|
|
||||||
@ -410,7 +410,7 @@ class ItemListAvatarAndNameInfoItemNode: ListViewItemNode, ItemListItemNode, Ite
|
|||||||
} else if let _ = peer.botInfo {
|
} else if let _ = peer.botInfo {
|
||||||
statusText = item.strings.Bot_GenericBotStatus
|
statusText = item.strings.Bot_GenericBotStatus
|
||||||
statusColor = item.theme.list.itemSecondaryTextColor
|
statusColor = item.theme.list.itemSecondaryTextColor
|
||||||
} else if case .generic = item.mode {
|
} else if case .generic = item.mode, !(peer.id.namespace == Namespaces.Peer.CloudUser && peer.id.id == 777000) {
|
||||||
let presence = (item.presence as? TelegramUserPresence) ?? TelegramUserPresence(status: .none)
|
let presence = (item.presence as? TelegramUserPresence) ?? TelegramUserPresence(status: .none)
|
||||||
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
|
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
|
||||||
let (string, activity) = stringAndActivityForUserPresence(strings: item.strings, timeFormat: .regular, presence: presence, relativeTo: Int32(timestamp))
|
let (string, activity) = stringAndActivityForUserPresence(strings: item.strings, timeFormat: .regular, presence: presence, relativeTo: Int32(timestamp))
|
||||||
|
|||||||
@ -151,7 +151,7 @@ private let titleBoldFont = Font.medium(17.0)
|
|||||||
private let statusFont = Font.regular(14.0)
|
private let statusFont = Font.regular(14.0)
|
||||||
private let labelFont = Font.regular(13.0)
|
private let labelFont = Font.regular(13.0)
|
||||||
private let labelDisclosureFont = Font.regular(17.0)
|
private let labelDisclosureFont = Font.regular(17.0)
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 17.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 17.0)!
|
||||||
|
|
||||||
class ItemListPeerItemNode: ItemListRevealOptionsItemNode {
|
class ItemListPeerItemNode: ItemListRevealOptionsItemNode {
|
||||||
private let backgroundNode: ASDisplayNode
|
private let backgroundNode: ASDisplayNode
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import Display
|
|||||||
import Postbox
|
import Postbox
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 26.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 26.0)!
|
||||||
|
|
||||||
private final class MoreNode: ASDisplayNode {
|
private final class MoreNode: ASDisplayNode {
|
||||||
private let avatarNode = AvatarNode(font: Font.regular(24.0))
|
private let avatarNode = AvatarNode(font: Font.regular(24.0))
|
||||||
|
|||||||
@ -39,7 +39,7 @@ public class LocationBroadcastActionSheetItem: ActionSheetItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 15.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 15.0)!
|
||||||
|
|
||||||
public class LocationBroadcastActionSheetItemNode: ActionSheetItemNode {
|
public class LocationBroadcastActionSheetItemNode: ActionSheetItemNode {
|
||||||
private let theme: ActionSheetControllerTheme
|
private let theme: ActionSheetControllerTheme
|
||||||
|
|||||||
@ -74,7 +74,7 @@ final class MentionChatInputPanelItem: ListViewItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 16.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 16.0)!
|
||||||
private let primaryFont = Font.medium(14.0)
|
private let primaryFont = Font.medium(14.0)
|
||||||
private let secondaryFont = Font.regular(14.0)
|
private let secondaryFont = Font.regular(14.0)
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import AsyncDisplayKit
|
|||||||
import Postbox
|
import Postbox
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 13.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 13.0)!
|
||||||
|
|
||||||
final class MultipleAvatarsNode: ASDisplayNode {
|
final class MultipleAvatarsNode: ASDisplayNode {
|
||||||
private var nodes: [(Peer, AvatarNode)] = []
|
private var nodes: [(Peer, AvatarNode)] = []
|
||||||
|
|||||||
@ -198,8 +198,8 @@ private enum ProxySettingsControllerEntry: ItemListNodeEntry {
|
|||||||
})
|
})
|
||||||
case let .serversHeader(theme, text):
|
case let .serversHeader(theme, text):
|
||||||
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
||||||
case let .addServer(theme, text, editing):
|
case let .addServer(theme, text, _):
|
||||||
return ProxySettingsActionItem(theme: theme, title: text, sectionId: self.section, editing: false, action: {
|
return ProxySettingsActionItem(theme: theme, title: text, icon: .add, sectionId: self.section, editing: false, action: {
|
||||||
arguments.addNewServer()
|
arguments.addNewServer()
|
||||||
})
|
})
|
||||||
case let .server(_, theme, strings, settings, active, status, editing, enabled):
|
case let .server(_, theme, strings, settings, active, status, editing, enabled):
|
||||||
|
|||||||
@ -3,16 +3,23 @@ import Display
|
|||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
|
|
||||||
|
enum ProxySettingsActionIcon {
|
||||||
|
case none
|
||||||
|
case add
|
||||||
|
}
|
||||||
|
|
||||||
class ProxySettingsActionItem: ListViewItem, ItemListItem {
|
class ProxySettingsActionItem: ListViewItem, ItemListItem {
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let title: String
|
let title: String
|
||||||
|
let icon: ProxySettingsActionIcon
|
||||||
let editing: Bool
|
let editing: Bool
|
||||||
let sectionId: ItemListSectionId
|
let sectionId: ItemListSectionId
|
||||||
let action: () -> Void
|
let action: () -> Void
|
||||||
|
|
||||||
init(theme: PresentationTheme, title: String, sectionId: ItemListSectionId, editing: Bool, action: @escaping () -> Void) {
|
init(theme: PresentationTheme, title: String, icon: ProxySettingsActionIcon = .none, sectionId: ItemListSectionId, editing: Bool, action: @escaping () -> Void) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.title = title
|
self.title = title
|
||||||
|
self.icon = icon
|
||||||
self.editing = editing
|
self.editing = editing
|
||||||
self.sectionId = sectionId
|
self.sectionId = sectionId
|
||||||
self.action = action
|
self.action = action
|
||||||
@ -117,7 +124,7 @@ class ProxySettingsActionItemNode: ListViewItemNode {
|
|||||||
if currentItem?.theme !== item.theme {
|
if currentItem?.theme !== item.theme {
|
||||||
updatedTheme = item.theme
|
updatedTheme = item.theme
|
||||||
}
|
}
|
||||||
let leftInset: CGFloat = 50.0 + params.leftInset
|
let leftInset: CGFloat = (item.icon != .none ? 50.0 : 16.0) + params.leftInset
|
||||||
|
|
||||||
let editingOffset: CGFloat = (item.editing ? 38.0 : 0.0)
|
let editingOffset: CGFloat = (item.editing ? 38.0 : 0.0)
|
||||||
|
|
||||||
@ -131,7 +138,7 @@ class ProxySettingsActionItemNode: ListViewItemNode {
|
|||||||
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
||||||
let layoutSize = layout.size
|
let layoutSize = layout.size
|
||||||
|
|
||||||
let icon = PresentationResourcesItemList.plusIconImage(item.theme)
|
let icon = item.icon == .add ? PresentationResourcesItemList.plusIconImage(item.theme) : nil
|
||||||
|
|
||||||
return (layout, { [weak self] animated in
|
return (layout, { [weak self] animated in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
|
|||||||
BIN
TelegramUI/Resources/Fonts/SFCompactRounded-Semibold.otf
Normal file
BIN
TelegramUI/Resources/Fonts/SFCompactRounded-Semibold.otf
Normal file
Binary file not shown.
@ -425,6 +425,15 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let hasErrors: (SecureIdValueWithContext, SecureIdValueKey) -> Bool = { value, key in
|
||||||
|
for error in value.errors {
|
||||||
|
if case let .value(valueKey) = error.key, valueKey != key {
|
||||||
|
return value.errors.count > 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return !value.errors.isEmpty
|
||||||
|
}
|
||||||
|
|
||||||
switch field {
|
switch field {
|
||||||
case let .identity(personalDetails, document, selfie, translations):
|
case let .identity(personalDetails, document, selfie, translations):
|
||||||
if let document = document {
|
if let document = document {
|
||||||
@ -446,23 +455,34 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .oneOf(types):
|
case let .oneOf(types):
|
||||||
|
var chosenByError = false
|
||||||
outer: for type in types {
|
outer: for type in types {
|
||||||
if let value = findValue(formData.values, key: type.valueKey)?.1 {
|
if let value = findValue(formData.values, key: type.valueKey)?.1 {
|
||||||
switch value.value {
|
let hasErrors = hasErrors(value, type.valueKey)
|
||||||
case .passport:
|
|
||||||
hasValueType = .passport
|
let data = extractSecureIdValueAdditionalData(value.value)
|
||||||
break outer
|
var dataFilled = true
|
||||||
case .idCard:
|
if selfie && !data.selfie {
|
||||||
hasValueType = .idCard
|
dataFilled = false
|
||||||
break outer
|
}
|
||||||
case .driversLicense:
|
if translations && !data.translation {
|
||||||
hasValueType = .driversLicense
|
dataFilled = false
|
||||||
break outer
|
}
|
||||||
case .internalPassport:
|
|
||||||
hasValueType = .internalPassport
|
if hasValueType == nil || ((hasErrors || dataFilled) && !chosenByError) {
|
||||||
break outer
|
chosenByError = hasErrors
|
||||||
default:
|
switch value.value {
|
||||||
break
|
case .passport:
|
||||||
|
hasValueType = .passport
|
||||||
|
case .idCard:
|
||||||
|
hasValueType = .idCard
|
||||||
|
case .driversLicense:
|
||||||
|
hasValueType = .driversLicense
|
||||||
|
case .internalPassport:
|
||||||
|
hasValueType = .internalPassport
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -506,26 +526,38 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .oneOf(types):
|
case let .oneOf(types):
|
||||||
|
var chosenByError = false
|
||||||
outer: for type in types {
|
outer: for type in types {
|
||||||
if let value = findValue(formData.values, key: type.valueKey)?.1 {
|
if let value = findValue(formData.values, key: type.valueKey)?.1 {
|
||||||
switch value.value {
|
let hasErrors = hasErrors(value, type.valueKey)
|
||||||
case .utilityBill:
|
|
||||||
hasValueType = .utilityBill
|
let data = extractSecureIdValueAdditionalData(value.value)
|
||||||
break outer
|
var dataFilled = true
|
||||||
case .bankStatement:
|
if translation && !data.translation {
|
||||||
hasValueType = .bankStatement
|
dataFilled = false
|
||||||
break outer
|
}
|
||||||
case .rentalAgreement:
|
|
||||||
hasValueType = .rentalAgreement
|
if hasValueType == nil || ((hasErrors || dataFilled) && !chosenByError) {
|
||||||
break outer
|
chosenByError = hasErrors
|
||||||
case .passportRegistration:
|
switch value.value {
|
||||||
hasValueType = .passportRegistration
|
case .utilityBill:
|
||||||
break outer
|
hasValueType = .utilityBill
|
||||||
case .temporaryRegistration:
|
break outer
|
||||||
hasValueType = .temporaryRegistration
|
case .bankStatement:
|
||||||
break outer
|
hasValueType = .bankStatement
|
||||||
default:
|
break outer
|
||||||
break
|
case .rentalAgreement:
|
||||||
|
hasValueType = .rentalAgreement
|
||||||
|
break outer
|
||||||
|
case .passportRegistration:
|
||||||
|
hasValueType = .passportRegistration
|
||||||
|
break outer
|
||||||
|
case .temporaryRegistration:
|
||||||
|
hasValueType = .temporaryRegistration
|
||||||
|
break outer
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -204,6 +204,9 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
|||||||
if personalDetails != nil {
|
if personalDetails != nil {
|
||||||
if let value = findValue(values, key: .personalDetails)?.1 {
|
if let value = findValue(values, key: .personalDetails)?.1 {
|
||||||
result.append(value)
|
result.append(value)
|
||||||
|
if !value.errors.isEmpty {
|
||||||
|
filled = false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
filled = false
|
filled = false
|
||||||
}
|
}
|
||||||
@ -213,13 +216,16 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
|||||||
case let .just(type):
|
case let .just(type):
|
||||||
if let value = findValue(values, key: type.valueKey)?.1 {
|
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||||
result.append(value)
|
result.append(value)
|
||||||
let data = extractValueAdditionalData(value.value)
|
let data = extractSecureIdValueAdditionalData(value.value)
|
||||||
if selfie && !data.selfie {
|
if selfie && !data.selfie {
|
||||||
filled = false
|
filled = false
|
||||||
}
|
}
|
||||||
if translation && !data.translation {
|
if translation && !data.translation {
|
||||||
filled = false
|
filled = false
|
||||||
}
|
}
|
||||||
|
if !value.errors.isEmpty {
|
||||||
|
filled = false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
filled = false
|
filled = false
|
||||||
}
|
}
|
||||||
@ -231,7 +237,7 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
|||||||
if bestMatchingValue == nil {
|
if bestMatchingValue == nil {
|
||||||
bestMatchingValue = value
|
bestMatchingValue = value
|
||||||
}
|
}
|
||||||
let data = extractValueAdditionalData(value.value)
|
let data = extractSecureIdValueAdditionalData(value.value)
|
||||||
var dataFilled = true
|
var dataFilled = true
|
||||||
if selfie && !data.selfie {
|
if selfie && !data.selfie {
|
||||||
dataFilled = false
|
dataFilled = false
|
||||||
@ -251,6 +257,9 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
|||||||
}
|
}
|
||||||
if let bestMatchingValue = bestMatchingValue {
|
if let bestMatchingValue = bestMatchingValue {
|
||||||
result.append(bestMatchingValue)
|
result.append(bestMatchingValue)
|
||||||
|
if !bestMatchingValue.errors.isEmpty {
|
||||||
|
filled = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -261,6 +270,9 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
|||||||
if addressDetails {
|
if addressDetails {
|
||||||
if let value = findValue(values, key: .address)?.1 {
|
if let value = findValue(values, key: .address)?.1 {
|
||||||
result.append(value)
|
result.append(value)
|
||||||
|
if !value.errors.isEmpty {
|
||||||
|
filled = false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
filled = false
|
filled = false
|
||||||
}
|
}
|
||||||
@ -270,10 +282,13 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
|||||||
case let .just(type):
|
case let .just(type):
|
||||||
if let value = findValue(values, key: type.valueKey)?.1 {
|
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||||
result.append(value)
|
result.append(value)
|
||||||
let data = extractValueAdditionalData(value.value)
|
let data = extractSecureIdValueAdditionalData(value.value)
|
||||||
if translation && !data.translation {
|
if translation && !data.translation {
|
||||||
filled = false
|
filled = false
|
||||||
}
|
}
|
||||||
|
if !value.errors.isEmpty {
|
||||||
|
filled = false
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
filled = false
|
filled = false
|
||||||
}
|
}
|
||||||
@ -285,7 +300,7 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
|||||||
if bestMatchingValue == nil {
|
if bestMatchingValue == nil {
|
||||||
bestMatchingValue = value
|
bestMatchingValue = value
|
||||||
}
|
}
|
||||||
let data = extractValueAdditionalData(value.value)
|
let data = extractSecureIdValueAdditionalData(value.value)
|
||||||
var dataFilled = true
|
var dataFilled = true
|
||||||
if translation && !data.translation {
|
if translation && !data.translation {
|
||||||
dataFilled = false
|
dataFilled = false
|
||||||
@ -302,6 +317,9 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
|||||||
}
|
}
|
||||||
if let bestMatchingValue = bestMatchingValue {
|
if let bestMatchingValue = bestMatchingValue {
|
||||||
result.append(bestMatchingValue)
|
result.append(bestMatchingValue)
|
||||||
|
if !bestMatchingValue.errors.isEmpty {
|
||||||
|
filled = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -673,43 +691,72 @@ private func fieldTitleAndText(field: SecureIdParsedRequestedFormField, strings:
|
|||||||
return (title, text.isEmpty ? placeholder : text)
|
return (title, text.isEmpty ? placeholder : text)
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct ValueAdditionalData {
|
private func fieldErrorText(field: SecureIdParsedRequestedFormField, values: [SecureIdValueWithContext]) -> String? {
|
||||||
var nativeNames: Bool = false
|
switch field {
|
||||||
var selfie: Bool = false
|
case let .identity(personalDetails, document, _, _):
|
||||||
var translation: Bool = false
|
if let _ = personalDetails, let value = findValue(values, key: .personalDetails)?.1 {
|
||||||
}
|
if let error = value.errors[.value(.personalDetails)] {
|
||||||
|
return error
|
||||||
private func extractValueAdditionalData(_ value: SecureIdValue) -> ValueAdditionalData {
|
} else if let error = value.errors.first?.value {
|
||||||
var data = ValueAdditionalData()
|
return error
|
||||||
switch value {
|
}
|
||||||
case let .personalDetails(value):
|
}
|
||||||
data.nativeNames = value.nativeName != nil
|
if let document = document {
|
||||||
case let .passport(value):
|
switch document {
|
||||||
data.selfie = value.selfieDocument != nil
|
case let .just(type):
|
||||||
data.translation = !value.translations.isEmpty
|
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||||
case let .internalPassport(value):
|
if let error = value.errors[.value(type.valueKey)] {
|
||||||
data.selfie = value.selfieDocument != nil
|
return error
|
||||||
data.translation = !value.translations.isEmpty
|
} else if let error = value.errors.first?.value {
|
||||||
case let .idCard(value):
|
return error
|
||||||
data.selfie = value.selfieDocument != nil
|
}
|
||||||
data.translation = !value.translations.isEmpty
|
}
|
||||||
case let .driversLicense(value):
|
case let .oneOf(types):
|
||||||
data.selfie = value.selfieDocument != nil
|
for type in types {
|
||||||
data.translation = !value.translations.isEmpty
|
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||||
case let .utilityBill(value):
|
if let error = value.errors[.value(type.valueKey)] {
|
||||||
data.translation = !value.translations.isEmpty
|
return error
|
||||||
case let .rentalAgreement(value):
|
} else if let error = value.errors.first?.value {
|
||||||
data.translation = !value.translations.isEmpty
|
return error
|
||||||
case let .bankStatement(value):
|
}
|
||||||
data.translation = !value.translations.isEmpty
|
}
|
||||||
case let .temporaryRegistration(value):
|
}
|
||||||
data.translation = !value.translations.isEmpty
|
}
|
||||||
case let .passportRegistration(value):
|
}
|
||||||
data.translation = !value.translations.isEmpty
|
case let .address(addressDetails, document, _):
|
||||||
|
if addressDetails, let value = findValue(values, key: .address)?.1 {
|
||||||
|
if let error = value.errors[.value(.address)] {
|
||||||
|
return error
|
||||||
|
} else if let error = value.errors.first?.value {
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let document = document {
|
||||||
|
switch document {
|
||||||
|
case let .just(type):
|
||||||
|
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||||
|
if let error = value.errors[.value(type.valueKey)] {
|
||||||
|
return error
|
||||||
|
} else if let error = value.errors.first?.value {
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case let .oneOf(types):
|
||||||
|
for type in types {
|
||||||
|
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||||
|
if let error = value.errors[.value(type.valueKey)] {
|
||||||
|
return error
|
||||||
|
} else if let error = value.errors.first?.value {
|
||||||
|
return error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break
|
return nil
|
||||||
}
|
}
|
||||||
return data
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
||||||
@ -805,116 +852,128 @@ final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
|||||||
|
|
||||||
func updateValues(_ values: [SecureIdValueWithContext]) {
|
func updateValues(_ values: [SecureIdValueWithContext]) {
|
||||||
var (title, text) = fieldTitleAndText(field: self.field, strings: self.strings, values: values)
|
var (title, text) = fieldTitleAndText(field: self.field, strings: self.strings, values: values)
|
||||||
let textColor = self.theme.list.itemSecondaryTextColor
|
var textColor = self.theme.list.itemSecondaryTextColor
|
||||||
/*switch self.field {
|
|
||||||
case .identity:
|
|
||||||
if let error = errors[.personalDetails]?.first {
|
|
||||||
text = error
|
|
||||||
textColor = self.theme.list.itemDestructiveColor
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}*/
|
|
||||||
|
|
||||||
var filled = true
|
var filled = true
|
||||||
switch self.field {
|
|
||||||
case let .identity(personalDetails, document, selfie, translation):
|
if let errorText = fieldErrorText(field: self.field, values: values) {
|
||||||
if let personalDetails = personalDetails {
|
filled = false
|
||||||
if let value = findValue(values, key: .personalDetails)?.1 {
|
textColor = self.theme.list.itemDestructiveColor
|
||||||
let data = extractValueAdditionalData(value.value)
|
text = errorText
|
||||||
if personalDetails.nativeNames && !data.nativeNames {
|
} else {
|
||||||
|
switch self.field {
|
||||||
|
case let .identity(personalDetails, document, selfie, translation):
|
||||||
|
if let personalDetails = personalDetails {
|
||||||
|
if let value = findValue(values, key: .personalDetails)?.1 {
|
||||||
|
let data = extractSecureIdValueAdditionalData(value.value)
|
||||||
|
if personalDetails.nativeNames && !data.nativeNames {
|
||||||
|
filled = false
|
||||||
|
text = strings.Passport_FieldIdentityDetailsHelp
|
||||||
|
}
|
||||||
|
} else {
|
||||||
filled = false
|
filled = false
|
||||||
text = strings.Passport_FieldIdentityDetailsHelp
|
text = strings.Passport_FieldIdentityDetailsHelp
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
filled = false
|
|
||||||
text = strings.Passport_FieldIdentityDetailsHelp
|
|
||||||
}
|
}
|
||||||
}
|
if let document = document {
|
||||||
if let document = document {
|
switch document {
|
||||||
switch document {
|
case let .just(type):
|
||||||
case let .just(type):
|
|
||||||
if let value = findValue(values, key: type.valueKey)?.1 {
|
|
||||||
let data = extractValueAdditionalData(value.value)
|
|
||||||
if selfie && !data.selfie {
|
|
||||||
filled = false
|
|
||||||
text = strings.Passport_FieldIdentitySelfieHelp
|
|
||||||
}
|
|
||||||
if translation && !data.translation {
|
|
||||||
filled = false
|
|
||||||
text = strings.Passport_FieldIdentityTranslationHelp
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
filled = false
|
|
||||||
}
|
|
||||||
case let .oneOf(types):
|
|
||||||
var anyDocument = false
|
|
||||||
for type in types {
|
|
||||||
if let value = findValue(values, key: type.valueKey)?.1 {
|
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||||
let data = extractValueAdditionalData(value.value)
|
let data = extractSecureIdValueAdditionalData(value.value)
|
||||||
var dataFilled = true
|
|
||||||
if selfie && !data.selfie {
|
if selfie && !data.selfie {
|
||||||
dataFilled = false
|
filled = false
|
||||||
|
text = strings.Passport_FieldIdentitySelfieHelp
|
||||||
}
|
}
|
||||||
if translation && !data.translation {
|
if translation && !data.translation {
|
||||||
dataFilled = false
|
filled = false
|
||||||
|
text = strings.Passport_FieldIdentityTranslationHelp
|
||||||
}
|
}
|
||||||
if dataFilled {
|
} else {
|
||||||
anyDocument = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !anyDocument {
|
|
||||||
filled = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case let .address(addressDetails, document, translation):
|
|
||||||
if addressDetails {
|
|
||||||
if findValue(values, key: .address) == nil {
|
|
||||||
filled = false
|
|
||||||
text = strings.Passport_FieldAddressHelp
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let document = document {
|
|
||||||
switch document {
|
|
||||||
case let .just(type):
|
|
||||||
if let value = findValue(values, key: type.valueKey)?.1 {
|
|
||||||
let data = extractValueAdditionalData(value.value)
|
|
||||||
if translation && !data.translation {
|
|
||||||
filled = false
|
filled = false
|
||||||
text = strings.Passport_FieldAddressTranslationHelp
|
|
||||||
}
|
}
|
||||||
} else {
|
case let .oneOf(types):
|
||||||
filled = false
|
var anyDocument = false
|
||||||
}
|
var missingSelfie = false
|
||||||
case let .oneOf(types):
|
var missingTranslation = false
|
||||||
var anyDocument = false
|
for type in types {
|
||||||
for type in types {
|
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||||
if let value = findValue(values, key: type.valueKey)?.1 {
|
let data = extractSecureIdValueAdditionalData(value.value)
|
||||||
let data = extractValueAdditionalData(value.value)
|
var dataFilled = true
|
||||||
var dataFilled = true
|
if selfie && !data.selfie {
|
||||||
if translation && !data.translation {
|
dataFilled = false
|
||||||
dataFilled = false
|
missingSelfie = true
|
||||||
}
|
}
|
||||||
if dataFilled {
|
if translation && !data.translation {
|
||||||
anyDocument = true
|
dataFilled = false
|
||||||
|
missingTranslation = true
|
||||||
|
}
|
||||||
|
if dataFilled {
|
||||||
|
anyDocument = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if !anyDocument {
|
||||||
if !anyDocument {
|
filled = false
|
||||||
filled = false
|
if missingSelfie {
|
||||||
}
|
text = strings.Passport_FieldIdentitySelfieHelp
|
||||||
|
} else if missingTranslation {
|
||||||
|
text = strings.Passport_FieldIdentityTranslationHelp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
case let .address(addressDetails, document, translation):
|
||||||
case .phone:
|
if addressDetails {
|
||||||
if findValue(values, key: .phone) == nil {
|
if findValue(values, key: .address) == nil {
|
||||||
filled = false
|
filled = false
|
||||||
}
|
text = strings.Passport_FieldAddressHelp
|
||||||
case .email:
|
}
|
||||||
if findValue(values, key: .email) == nil {
|
}
|
||||||
filled = false
|
if let document = document {
|
||||||
}
|
switch document {
|
||||||
|
case let .just(type):
|
||||||
|
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||||
|
let data = extractSecureIdValueAdditionalData(value.value)
|
||||||
|
if translation && !data.translation {
|
||||||
|
filled = false
|
||||||
|
text = strings.Passport_FieldAddressTranslationHelp
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
filled = false
|
||||||
|
}
|
||||||
|
case let .oneOf(types):
|
||||||
|
var anyDocument = false
|
||||||
|
var missingTranslation = false
|
||||||
|
for type in types {
|
||||||
|
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||||
|
let data = extractSecureIdValueAdditionalData(value.value)
|
||||||
|
var dataFilled = true
|
||||||
|
if translation && !data.translation {
|
||||||
|
dataFilled = false
|
||||||
|
missingTranslation = true
|
||||||
|
}
|
||||||
|
if dataFilled {
|
||||||
|
anyDocument = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !anyDocument {
|
||||||
|
filled = false
|
||||||
|
if missingTranslation {
|
||||||
|
text = strings.Passport_FieldIdentityTranslationHelp
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case .phone:
|
||||||
|
if findValue(values, key: .phone) == nil {
|
||||||
|
filled = false
|
||||||
|
}
|
||||||
|
case .email:
|
||||||
|
if findValue(values, key: .email) == nil {
|
||||||
|
filled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.titleNode.attributedText = NSAttributedString(string: title, font: titleFont, textColor: self.theme.list.itemPrimaryTextColor)
|
self.titleNode.attributedText = NSAttributedString(string: title, font: titleFont, textColor: self.theme.list.itemPrimaryTextColor)
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import Postbox
|
|||||||
import TelegramCore
|
import TelegramCore
|
||||||
import SwiftSignalKit
|
import SwiftSignalKit
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 26.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 26.0)!
|
||||||
private let titleFont: UIFont = Font.semibold(14.0)
|
private let titleFont: UIFont = Font.semibold(14.0)
|
||||||
private let textFont: UIFont = Font.regular(14.0)
|
private let textFont: UIFont = Font.regular(14.0)
|
||||||
|
|
||||||
|
|||||||
@ -74,7 +74,7 @@ final class SecureIdDocumentFormController: FormController<SecureIdDocumentFormS
|
|||||||
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed))
|
self.navigationItem.leftBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed))
|
||||||
|
|
||||||
self.doneItem = UIBarButtonItem(title: self.presentationData.strings.Common_Done, style: .done, target: self, action: #selector(self.donePressed))
|
self.doneItem = UIBarButtonItem(title: self.presentationData.strings.Common_Done, style: .done, target: self, action: #selector(self.donePressed))
|
||||||
self.navigationItem.rightBarButtonItem = doneItem
|
self.navigationItem.rightBarButtonItem = self.doneItem
|
||||||
}
|
}
|
||||||
|
|
||||||
required init(coder aDecoder: NSCoder) {
|
required init(coder aDecoder: NSCoder) {
|
||||||
|
|||||||
@ -942,6 +942,24 @@ struct SecureIdDocumentFormState: FormControllerInnerState {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var badHashes: Set<Data> = []
|
||||||
|
var badFileHashes: Set<Data>?
|
||||||
|
var badTranslationHashes: Set<Data>?
|
||||||
|
for value in self.previousValues {
|
||||||
|
for error in value.value.errors {
|
||||||
|
switch error.key {
|
||||||
|
case .value, .field:
|
||||||
|
return .saveNotAvailable
|
||||||
|
case let .file(hash), let .selfie(hash), let .frontSide(hash), let .backSide(hash), let .translationFile(hash):
|
||||||
|
badHashes.insert(hash)
|
||||||
|
case let .files(hashes):
|
||||||
|
badFileHashes = hashes
|
||||||
|
case let .translationFiles(hashes):
|
||||||
|
badTranslationHashes = hashes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var documentsRequired = false
|
var documentsRequired = false
|
||||||
|
|
||||||
switch self.documentState {
|
switch self.documentState {
|
||||||
@ -958,7 +976,7 @@ struct SecureIdDocumentFormState: FormControllerInnerState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isDocumentReady(_ document: SecureIdVerificationDocument?) -> Bool {
|
func isDocumentReady(_ document: SecureIdVerificationDocument?, badHashes: Set<Data>? = nil) -> Bool {
|
||||||
if let document = document {
|
if let document = document {
|
||||||
switch document {
|
switch document {
|
||||||
case let .local(local):
|
case let .local(local):
|
||||||
@ -968,8 +986,12 @@ struct SecureIdDocumentFormState: FormControllerInnerState {
|
|||||||
case .uploaded:
|
case .uploaded:
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
case .remote:
|
case let .remote(reference):
|
||||||
return true
|
if let badHashes = badHashes {
|
||||||
|
return !badHashes.contains(reference.fileHash)
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -977,40 +999,64 @@ struct SecureIdDocumentFormState: FormControllerInnerState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.frontSideRequired {
|
if self.frontSideRequired {
|
||||||
guard isDocumentReady(self.frontSideDocument) else {
|
guard isDocumentReady(self.frontSideDocument, badHashes: badHashes) else {
|
||||||
return .saveNotAvailable
|
return .saveNotAvailable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.backSideRequired {
|
if self.backSideRequired {
|
||||||
guard isDocumentReady(self.backSideDocument) else {
|
guard isDocumentReady(self.backSideDocument, badHashes: badHashes) else {
|
||||||
return .saveNotAvailable
|
return .saveNotAvailable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.selfieRequired {
|
if self.selfieRequired {
|
||||||
guard isDocumentReady(self.selfieDocument) else {
|
guard isDocumentReady(self.selfieDocument, badHashes: badHashes) else {
|
||||||
return .saveNotAvailable
|
return .saveNotAvailable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var fileHashes: Set<Data> = []
|
||||||
for document in self.documents {
|
for document in self.documents {
|
||||||
guard isDocumentReady(document) else {
|
guard isDocumentReady(document) else {
|
||||||
return .saveNotAvailable
|
return .saveNotAvailable
|
||||||
}
|
}
|
||||||
|
switch document {
|
||||||
|
case let .remote(reference):
|
||||||
|
fileHashes.insert(reference.fileHash)
|
||||||
|
case let .local(document):
|
||||||
|
if case let .uploaded(file) = document.state {
|
||||||
|
fileHashes.insert(file.fileHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if documentsRequired && self.documents.isEmpty {
|
if documentsRequired && self.documents.isEmpty {
|
||||||
return .saveNotAvailable
|
return .saveNotAvailable
|
||||||
}
|
}
|
||||||
|
if let badFileHashes = badFileHashes, badFileHashes == fileHashes {
|
||||||
|
return .saveNotAvailable
|
||||||
|
}
|
||||||
|
|
||||||
|
var translationHashes: Set<Data> = []
|
||||||
for document in self.translations {
|
for document in self.translations {
|
||||||
guard isDocumentReady(document) else {
|
guard isDocumentReady(document) else {
|
||||||
return .saveNotAvailable
|
return .saveNotAvailable
|
||||||
}
|
}
|
||||||
|
switch document {
|
||||||
|
case let .remote(reference):
|
||||||
|
translationHashes.insert(reference.fileHash)
|
||||||
|
case let .local(document):
|
||||||
|
if case let .uploaded(file) = document.state {
|
||||||
|
translationHashes.insert(file.fileHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if self.translationsRequired && self.translations.isEmpty {
|
if self.translationsRequired && self.translations.isEmpty {
|
||||||
return .saveNotAvailable
|
return .saveNotAvailable
|
||||||
}
|
}
|
||||||
|
if let badTranslationHashes = badTranslationHashes, badTranslationHashes == translationHashes {
|
||||||
|
return .saveNotAvailable
|
||||||
|
}
|
||||||
|
|
||||||
return .saveAvailable
|
return .saveAvailable
|
||||||
}
|
}
|
||||||
@ -2145,8 +2191,9 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let valueKey = valueKey, let errorKey = errorKey {
|
if let valueKey = valueKey, let errorKey = errorKey {
|
||||||
|
let valueErrorKey: SecureIdValueContentErrorKey = .value(valueKey)
|
||||||
if let previousValue = innerState.previousValues[valueKey] {
|
if let previousValue = innerState.previousValues[valueKey] {
|
||||||
innerState.previousValues[valueKey] = previousValue.withRemovedErrors([errorKey])
|
innerState.previousValues[valueKey] = previousValue.withRemovedErrors([errorKey, valueErrorKey])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strongSelf.updateInnerState(transition: .immediate, with: innerState)
|
strongSelf.updateInnerState(transition: .immediate, with: innerState)
|
||||||
@ -2198,8 +2245,9 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
|
|||||||
errorKey = .field(.address(.countryCode))
|
errorKey = .field(.address(.countryCode))
|
||||||
}
|
}
|
||||||
if let valueKey = valueKey, let errorKey = errorKey {
|
if let valueKey = valueKey, let errorKey = errorKey {
|
||||||
|
let valueErrorKey: SecureIdValueContentErrorKey = .value(valueKey)
|
||||||
if let previousValue = innerState.previousValues[valueKey] {
|
if let previousValue = innerState.previousValues[valueKey] {
|
||||||
innerState.previousValues[valueKey] = previousValue.withRemovedErrors([errorKey])
|
innerState.previousValues[valueKey] = previousValue.withRemovedErrors([errorKey, valueErrorKey])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strongSelf.updateInnerState(transition: .immediate, with: innerState)
|
strongSelf.updateInnerState(transition: .immediate, with: innerState)
|
||||||
@ -2222,8 +2270,9 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
if let valueKey = valueKey, let errorKey = errorKey {
|
if let valueKey = valueKey, let errorKey = errorKey {
|
||||||
|
let valueErrorKey: SecureIdValueContentErrorKey = .value(valueKey)
|
||||||
if let previousValue = innerState.previousValues[valueKey] {
|
if let previousValue = innerState.previousValues[valueKey] {
|
||||||
innerState.previousValues[valueKey] = previousValue.withRemovedErrors([errorKey])
|
innerState.previousValues[valueKey] = previousValue.withRemovedErrors([errorKey, valueErrorKey])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strongSelf.updateInnerState(transition: .immediate, with: innerState)
|
strongSelf.updateInnerState(transition: .immediate, with: innerState)
|
||||||
@ -2289,9 +2338,11 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
|
|||||||
case .address:
|
case .address:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
if let valueKey = valueKey, let errorKey = errorKey {
|
if let valueKey = valueKey, let errorKey = errorKey {
|
||||||
|
let valueErrorKey: SecureIdValueContentErrorKey = .value(valueKey)
|
||||||
if let previousValue = innerState.previousValues[valueKey] {
|
if let previousValue = innerState.previousValues[valueKey] {
|
||||||
innerState.previousValues[valueKey] = previousValue.withRemovedErrors([errorKey])
|
innerState.previousValues[valueKey] = previousValue.withRemovedErrors([errorKey, valueErrorKey])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strongSelf.updateInnerState(transition: .immediate, with: innerState)
|
strongSelf.updateInnerState(transition: .immediate, with: innerState)
|
||||||
@ -2312,8 +2363,9 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
|
|||||||
valueKey = .personalDetails
|
valueKey = .personalDetails
|
||||||
errorKey = .field(.personalDetails(.gender))
|
errorKey = .field(.personalDetails(.gender))
|
||||||
if let valueKey = valueKey, let errorKey = errorKey {
|
if let valueKey = valueKey, let errorKey = errorKey {
|
||||||
|
let valueErrorKey: SecureIdValueContentErrorKey = .value(valueKey)
|
||||||
if let previousValue = innerState.previousValues[valueKey] {
|
if let previousValue = innerState.previousValues[valueKey] {
|
||||||
innerState.previousValues[valueKey] = previousValue.withRemovedErrors([errorKey])
|
innerState.previousValues[valueKey] = previousValue.withRemovedErrors([errorKey, valueErrorKey])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
strongSelf.updateInnerState(transition: .immediate, with: innerState)
|
strongSelf.updateInnerState(transition: .immediate, with: innerState)
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import SwiftSignalKit
|
|||||||
|
|
||||||
import LegacyComponents
|
import LegacyComponents
|
||||||
|
|
||||||
private let avatarFont: UIFont = UIFont(name: "ArialRoundedMTBold", size: 24.0)!
|
private let avatarFont: UIFont = UIFont(name: ".SFCompactRounded-Semibold", size: 24.0)!
|
||||||
private let textFont = Font.regular(11.0)
|
private let textFont = Font.regular(11.0)
|
||||||
|
|
||||||
final class SelectablePeerNodeTheme {
|
final class SelectablePeerNodeTheme {
|
||||||
|
|||||||
@ -1146,13 +1146,11 @@ public func userInfoController(account: Account, peerId: PeerId) -> ViewControll
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
shareMyContactImpl = { [weak controller] in
|
shareMyContactImpl = { [weak controller] in
|
||||||
let _ = (peerView.get()
|
let _ = (getUserPeer(postbox: account.postbox, peerId: account.peerId)
|
||||||
|> take(1)
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|> deliverOnMainQueue).start(next: { view in
|
guard let peer = peer as? TelegramUser, let phone = peer.phone else {
|
||||||
guard let peer = peerViewMainPeer(view) as? TelegramUser, let phone = peer.phone else {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let contact = TelegramMediaContact(firstName: peer.firstName ?? "", lastName: peer.lastName ?? "", phoneNumber: phone, peerId: peer.id, vCardData: nil)
|
let contact = TelegramMediaContact(firstName: peer.firstName ?? "", lastName: peer.lastName ?? "", phoneNumber: phone, peerId: peer.id, vCardData: nil)
|
||||||
|
|
||||||
let _ = (enqueueMessages(account: account, peerId: peerId, messages: [.message(text: "", attributes: [], mediaReference: .standalone(media: contact), replyToMessageId: nil, localGroupingKey: nil)])
|
let _ = (enqueueMessages(account: account, peerId: peerId, messages: [.message(text: "", attributes: [], mediaReference: .standalone(media: contact), replyToMessageId: nil, localGroupingKey: nil)])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user