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 */
|
||||
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 */; };
|
||||
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 */; };
|
||||
@ -1022,6 +1023,7 @@
|
||||
/* End PBXBuildFile 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>"; };
|
||||
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>"; };
|
||||
@ -2164,6 +2166,15 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
092F368B2154AAD6001A9F49 /* Fonts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
092F368C2154AAE9001A9F49 /* SFCompactRounded-Semibold.otf */,
|
||||
);
|
||||
name = Fonts;
|
||||
path = TelegramUI/Resources/Fonts;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
09310D13213BC5DE0020033A /* Animations */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -2520,6 +2531,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
09310D13213BC5DE0020033A /* Animations */,
|
||||
092F368B2154AAD6001A9F49 /* Fonts */,
|
||||
D0C12A1B1F33964900B3F66D /* ChatWallpaperBuiltin0.jpg */,
|
||||
D0E9BA681F056F4C00F079A4 /* Stripe */,
|
||||
D0E9B9E91F00853C00F079A4 /* PhoneCountries.txt */,
|
||||
@ -4637,6 +4649,7 @@
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
092F368D2154AAEA001A9F49 /* SFCompactRounded-Semibold.otf in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
||||
@ -168,7 +168,7 @@ class CallListCallItem: ListViewItem {
|
||||
|
||||
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 {
|
||||
private let backgroundNode: ASDisplayNode
|
||||
|
||||
@ -2,8 +2,8 @@ import Foundation
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
|
||||
private let normalFont = UIFont(name: "ArialRoundedMTBold", size: 16.0)!
|
||||
private let smallFont = UIFont(name: "ArialRoundedMTBold", size: 12.0)!
|
||||
private let normalFont = UIFont(name: ".SFCompactRounded-Semibold", size: 16.0)!
|
||||
private let smallFont = UIFont(name: ".SFCompactRounded-Semibold", size: 12.0)!
|
||||
|
||||
final class ChatAvatarNavigationNode: ASDisplayNode {
|
||||
let avatarNode: AvatarNode
|
||||
|
||||
@ -205,7 +205,7 @@ private func leftRevealOptions(strings: PresentationStrings, theme: Presentation
|
||||
|
||||
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 {
|
||||
var item: ChatListItem?
|
||||
|
||||
@ -146,7 +146,8 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
|
||||
if let user = primaryPeer as? TelegramUser {
|
||||
if let _ = user.botInfo {
|
||||
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)
|
||||
} else {
|
||||
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 boundingImageSize = CGSize(width: 28.0, height: 28.0)
|
||||
private let highlightSize = CGSize(width: 35.0, height: 35.0)
|
||||
|
||||
@ -3,7 +3,7 @@ import Postbox
|
||||
import Display
|
||||
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 {
|
||||
private let account: Account
|
||||
|
||||
@ -5,7 +5,7 @@ import SwiftSignalKit
|
||||
import Postbox
|
||||
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 textFont = Font.regular(14.0)
|
||||
|
||||
@ -3,7 +3,7 @@ import Display
|
||||
import TelegramCore
|
||||
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 func addPulseAnimations(layer: CALayer) {
|
||||
|
||||
@ -2,7 +2,7 @@ import Foundation
|
||||
import AsyncDisplayKit
|
||||
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 {
|
||||
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 {
|
||||
private var item: ChatMessageNotificationItem?
|
||||
|
||||
@ -62,7 +62,7 @@ final class ChatReportPeerTitlePanelNode: ChatTitleAccessoryPanelNode {
|
||||
|
||||
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))
|
||||
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 descriptionFont = Font.regular(14.0)
|
||||
|
||||
|
||||
@ -151,10 +151,9 @@ private enum ContactListNodeEntry: Comparable, Identifiable {
|
||||
case let .peer(peer, isGlobal):
|
||||
if isGlobal, let _ = peer.addressName {
|
||||
status = .addressName("")
|
||||
} else if let presence = presence {
|
||||
status = .presence(presence, timeFormat)
|
||||
} else {
|
||||
status = .none
|
||||
let presence = presence ?? TelegramUserPresence(status: .none)
|
||||
status = .presence(presence, timeFormat)
|
||||
}
|
||||
itemPeer = .peer(peer: peer, chatPeer: peer)
|
||||
case let .deviceContact(id, contact):
|
||||
|
||||
@ -270,7 +270,7 @@ class ContactsPeerItem: ListViewItem {
|
||||
|
||||
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 {
|
||||
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 statusFont = Font.regular(15.0)
|
||||
|
||||
@ -410,7 +410,7 @@ class ItemListAvatarAndNameInfoItemNode: ListViewItemNode, ItemListItemNode, Ite
|
||||
} else if let _ = peer.botInfo {
|
||||
statusText = item.strings.Bot_GenericBotStatus
|
||||
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 timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
|
||||
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 labelFont = Font.regular(13.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 {
|
||||
private let backgroundNode: ASDisplayNode
|
||||
|
||||
@ -4,7 +4,7 @@ import Display
|
||||
import Postbox
|
||||
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 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 {
|
||||
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 secondaryFont = Font.regular(14.0)
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ import AsyncDisplayKit
|
||||
import Postbox
|
||||
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 {
|
||||
private var nodes: [(Peer, AvatarNode)] = []
|
||||
|
||||
@ -198,8 +198,8 @@ private enum ProxySettingsControllerEntry: ItemListNodeEntry {
|
||||
})
|
||||
case let .serversHeader(theme, text):
|
||||
return ItemListSectionHeaderItem(theme: theme, text: text, sectionId: self.section)
|
||||
case let .addServer(theme, text, editing):
|
||||
return ProxySettingsActionItem(theme: theme, title: text, sectionId: self.section, editing: false, action: {
|
||||
case let .addServer(theme, text, _):
|
||||
return ProxySettingsActionItem(theme: theme, title: text, icon: .add, sectionId: self.section, editing: false, action: {
|
||||
arguments.addNewServer()
|
||||
})
|
||||
case let .server(_, theme, strings, settings, active, status, editing, enabled):
|
||||
|
||||
@ -3,16 +3,23 @@ import Display
|
||||
import AsyncDisplayKit
|
||||
import SwiftSignalKit
|
||||
|
||||
enum ProxySettingsActionIcon {
|
||||
case none
|
||||
case add
|
||||
}
|
||||
|
||||
class ProxySettingsActionItem: ListViewItem, ItemListItem {
|
||||
let theme: PresentationTheme
|
||||
let title: String
|
||||
let icon: ProxySettingsActionIcon
|
||||
let editing: Bool
|
||||
let sectionId: ItemListSectionId
|
||||
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.title = title
|
||||
self.icon = icon
|
||||
self.editing = editing
|
||||
self.sectionId = sectionId
|
||||
self.action = action
|
||||
@ -117,7 +124,7 @@ class ProxySettingsActionItemNode: ListViewItemNode {
|
||||
if currentItem?.theme !== 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)
|
||||
|
||||
@ -131,7 +138,7 @@ class ProxySettingsActionItemNode: ListViewItemNode {
|
||||
let layout = ListViewItemNodeLayout(contentSize: contentSize, insets: insets)
|
||||
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
|
||||
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 {
|
||||
case let .identity(personalDetails, document, selfie, translations):
|
||||
if let document = document {
|
||||
@ -446,27 +455,38 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
|
||||
}
|
||||
}
|
||||
case let .oneOf(types):
|
||||
var chosenByError = false
|
||||
outer: for type in types {
|
||||
if let value = findValue(formData.values, key: type.valueKey)?.1 {
|
||||
let hasErrors = hasErrors(value, type.valueKey)
|
||||
|
||||
let data = extractSecureIdValueAdditionalData(value.value)
|
||||
var dataFilled = true
|
||||
if selfie && !data.selfie {
|
||||
dataFilled = false
|
||||
}
|
||||
if translations && !data.translation {
|
||||
dataFilled = false
|
||||
}
|
||||
|
||||
if hasValueType == nil || ((hasErrors || dataFilled) && !chosenByError) {
|
||||
chosenByError = hasErrors
|
||||
switch value.value {
|
||||
case .passport:
|
||||
hasValueType = .passport
|
||||
break outer
|
||||
case .idCard:
|
||||
hasValueType = .idCard
|
||||
break outer
|
||||
case .driversLicense:
|
||||
hasValueType = .driversLicense
|
||||
break outer
|
||||
case .internalPassport:
|
||||
hasValueType = .internalPassport
|
||||
break outer
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let hasValueType = hasValueType {
|
||||
self.interaction.present(SecureIdDocumentFormController(account: self.account, context: context, requestedData: .identity(details: personalDetails, document: hasValueType, selfie: selfie, translations: translations), primaryLanguageByCountry: encryptedFormData.primaryLanguageByCountry, values: formData.values, updatedValues: { values in
|
||||
var keys: [SecureIdValueKey] = []
|
||||
@ -506,8 +526,19 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
|
||||
}
|
||||
}
|
||||
case let .oneOf(types):
|
||||
var chosenByError = false
|
||||
outer: for type in types {
|
||||
if let value = findValue(formData.values, key: type.valueKey)?.1 {
|
||||
let hasErrors = hasErrors(value, type.valueKey)
|
||||
|
||||
let data = extractSecureIdValueAdditionalData(value.value)
|
||||
var dataFilled = true
|
||||
if translation && !data.translation {
|
||||
dataFilled = false
|
||||
}
|
||||
|
||||
if hasValueType == nil || ((hasErrors || dataFilled) && !chosenByError) {
|
||||
chosenByError = hasErrors
|
||||
switch value.value {
|
||||
case .utilityBill:
|
||||
hasValueType = .utilityBill
|
||||
@ -530,6 +561,7 @@ final class SecureIdAuthControllerNode: ViewControllerTracingNode {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let hasValueType = hasValueType {
|
||||
self.interaction.present(SecureIdDocumentFormController(account: self.account, context: context, requestedData: .address(details: addressDetails, document: hasValueType, translations: translation), primaryLanguageByCountry: encryptedFormData.primaryLanguageByCountry, values: formData.values, updatedValues: { values in
|
||||
var keys: [SecureIdValueKey] = []
|
||||
|
||||
@ -204,6 +204,9 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
||||
if personalDetails != nil {
|
||||
if let value = findValue(values, key: .personalDetails)?.1 {
|
||||
result.append(value)
|
||||
if !value.errors.isEmpty {
|
||||
filled = false
|
||||
}
|
||||
} else {
|
||||
filled = false
|
||||
}
|
||||
@ -213,13 +216,16 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
||||
case let .just(type):
|
||||
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||
result.append(value)
|
||||
let data = extractValueAdditionalData(value.value)
|
||||
let data = extractSecureIdValueAdditionalData(value.value)
|
||||
if selfie && !data.selfie {
|
||||
filled = false
|
||||
}
|
||||
if translation && !data.translation {
|
||||
filled = false
|
||||
}
|
||||
if !value.errors.isEmpty {
|
||||
filled = false
|
||||
}
|
||||
} else {
|
||||
filled = false
|
||||
}
|
||||
@ -231,7 +237,7 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
||||
if bestMatchingValue == nil {
|
||||
bestMatchingValue = value
|
||||
}
|
||||
let data = extractValueAdditionalData(value.value)
|
||||
let data = extractSecureIdValueAdditionalData(value.value)
|
||||
var dataFilled = true
|
||||
if selfie && !data.selfie {
|
||||
dataFilled = false
|
||||
@ -251,6 +257,9 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
||||
}
|
||||
if let bestMatchingValue = bestMatchingValue {
|
||||
result.append(bestMatchingValue)
|
||||
if !bestMatchingValue.errors.isEmpty {
|
||||
filled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -261,6 +270,9 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
||||
if addressDetails {
|
||||
if let value = findValue(values, key: .address)?.1 {
|
||||
result.append(value)
|
||||
if !value.errors.isEmpty {
|
||||
filled = false
|
||||
}
|
||||
} else {
|
||||
filled = false
|
||||
}
|
||||
@ -270,10 +282,13 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
||||
case let .just(type):
|
||||
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||
result.append(value)
|
||||
let data = extractValueAdditionalData(value.value)
|
||||
let data = extractSecureIdValueAdditionalData(value.value)
|
||||
if translation && !data.translation {
|
||||
filled = false
|
||||
}
|
||||
if !value.errors.isEmpty {
|
||||
filled = false
|
||||
}
|
||||
} else {
|
||||
filled = false
|
||||
}
|
||||
@ -285,7 +300,7 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
||||
if bestMatchingValue == nil {
|
||||
bestMatchingValue = value
|
||||
}
|
||||
let data = extractValueAdditionalData(value.value)
|
||||
let data = extractSecureIdValueAdditionalData(value.value)
|
||||
var dataFilled = true
|
||||
if translation && !data.translation {
|
||||
dataFilled = false
|
||||
@ -302,6 +317,9 @@ private func findValuesForField(field: SecureIdParsedRequestedFormField, values:
|
||||
}
|
||||
if let bestMatchingValue = 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)
|
||||
}
|
||||
|
||||
private struct ValueAdditionalData {
|
||||
var nativeNames: Bool = false
|
||||
var selfie: Bool = false
|
||||
var translation: Bool = false
|
||||
private func fieldErrorText(field: SecureIdParsedRequestedFormField, values: [SecureIdValueWithContext]) -> String? {
|
||||
switch field {
|
||||
case let .identity(personalDetails, document, _, _):
|
||||
if let _ = personalDetails, let value = findValue(values, key: .personalDetails)?.1 {
|
||||
if let error = value.errors[.value(.personalDetails)] {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func extractValueAdditionalData(_ value: SecureIdValue) -> ValueAdditionalData {
|
||||
var data = ValueAdditionalData()
|
||||
switch value {
|
||||
case let .personalDetails(value):
|
||||
data.nativeNames = value.nativeName != nil
|
||||
case let .passport(value):
|
||||
data.selfie = value.selfieDocument != nil
|
||||
data.translation = !value.translations.isEmpty
|
||||
case let .internalPassport(value):
|
||||
data.selfie = value.selfieDocument != nil
|
||||
data.translation = !value.translations.isEmpty
|
||||
case let .idCard(value):
|
||||
data.selfie = value.selfieDocument != nil
|
||||
data.translation = !value.translations.isEmpty
|
||||
case let .driversLicense(value):
|
||||
data.selfie = value.selfieDocument != nil
|
||||
data.translation = !value.translations.isEmpty
|
||||
case let .utilityBill(value):
|
||||
data.translation = !value.translations.isEmpty
|
||||
case let .rentalAgreement(value):
|
||||
data.translation = !value.translations.isEmpty
|
||||
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
|
||||
default:
|
||||
break
|
||||
return nil
|
||||
}
|
||||
return data
|
||||
return nil
|
||||
}
|
||||
|
||||
final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
||||
@ -805,23 +852,20 @@ final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
||||
|
||||
func updateValues(_ values: [SecureIdValueWithContext]) {
|
||||
var (title, text) = fieldTitleAndText(field: self.field, strings: self.strings, values: values)
|
||||
let 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 textColor = self.theme.list.itemSecondaryTextColor
|
||||
|
||||
var filled = true
|
||||
|
||||
if let errorText = fieldErrorText(field: self.field, values: values) {
|
||||
filled = false
|
||||
textColor = self.theme.list.itemDestructiveColor
|
||||
text = errorText
|
||||
} 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 = extractValueAdditionalData(value.value)
|
||||
let data = extractSecureIdValueAdditionalData(value.value)
|
||||
if personalDetails.nativeNames && !data.nativeNames {
|
||||
filled = false
|
||||
text = strings.Passport_FieldIdentityDetailsHelp
|
||||
@ -835,7 +879,7 @@ final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
||||
switch document {
|
||||
case let .just(type):
|
||||
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||
let data = extractValueAdditionalData(value.value)
|
||||
let data = extractSecureIdValueAdditionalData(value.value)
|
||||
if selfie && !data.selfie {
|
||||
filled = false
|
||||
text = strings.Passport_FieldIdentitySelfieHelp
|
||||
@ -849,15 +893,19 @@ final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
||||
}
|
||||
case let .oneOf(types):
|
||||
var anyDocument = false
|
||||
var missingSelfie = false
|
||||
var missingTranslation = false
|
||||
for type in types {
|
||||
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 {
|
||||
dataFilled = false
|
||||
missingSelfie = true
|
||||
}
|
||||
if translation && !data.translation {
|
||||
dataFilled = false
|
||||
missingTranslation = true
|
||||
}
|
||||
if dataFilled {
|
||||
anyDocument = true
|
||||
@ -866,6 +914,11 @@ final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
||||
}
|
||||
if !anyDocument {
|
||||
filled = false
|
||||
if missingSelfie {
|
||||
text = strings.Passport_FieldIdentitySelfieHelp
|
||||
} else if missingTranslation {
|
||||
text = strings.Passport_FieldIdentityTranslationHelp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -880,7 +933,7 @@ final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
||||
switch document {
|
||||
case let .just(type):
|
||||
if let value = findValue(values, key: type.valueKey)?.1 {
|
||||
let data = extractValueAdditionalData(value.value)
|
||||
let data = extractSecureIdValueAdditionalData(value.value)
|
||||
if translation && !data.translation {
|
||||
filled = false
|
||||
text = strings.Passport_FieldAddressTranslationHelp
|
||||
@ -890,12 +943,14 @@ final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
||||
}
|
||||
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 = extractValueAdditionalData(value.value)
|
||||
let data = extractSecureIdValueAdditionalData(value.value)
|
||||
var dataFilled = true
|
||||
if translation && !data.translation {
|
||||
dataFilled = false
|
||||
missingTranslation = true
|
||||
}
|
||||
if dataFilled {
|
||||
anyDocument = true
|
||||
@ -904,6 +959,9 @@ final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
||||
}
|
||||
if !anyDocument {
|
||||
filled = false
|
||||
if missingTranslation {
|
||||
text = strings.Passport_FieldIdentityTranslationHelp
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -916,6 +974,7 @@ final class SecureIdAuthFormFieldNode: ASDisplayNode {
|
||||
filled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.titleNode.attributedText = NSAttributedString(string: title, font: titleFont, textColor: self.theme.list.itemPrimaryTextColor)
|
||||
self.textNode.attributedText = NSAttributedString(string: text, font: textFont, textColor: textColor)
|
||||
|
||||
@ -5,7 +5,7 @@ import Postbox
|
||||
import TelegramCore
|
||||
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 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.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) {
|
||||
|
||||
@ -942,6 +942,24 @@ struct SecureIdDocumentFormState: FormControllerInnerState {
|
||||
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
|
||||
|
||||
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 {
|
||||
switch document {
|
||||
case let .local(local):
|
||||
@ -968,49 +986,77 @@ struct SecureIdDocumentFormState: FormControllerInnerState {
|
||||
case .uploaded:
|
||||
return true
|
||||
}
|
||||
case .remote:
|
||||
case let .remote(reference):
|
||||
if let badHashes = badHashes {
|
||||
return !badHashes.contains(reference.fileHash)
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if self.frontSideRequired {
|
||||
guard isDocumentReady(self.frontSideDocument) else {
|
||||
guard isDocumentReady(self.frontSideDocument, badHashes: badHashes) else {
|
||||
return .saveNotAvailable
|
||||
}
|
||||
}
|
||||
|
||||
if self.backSideRequired {
|
||||
guard isDocumentReady(self.backSideDocument) else {
|
||||
guard isDocumentReady(self.backSideDocument, badHashes: badHashes) else {
|
||||
return .saveNotAvailable
|
||||
}
|
||||
}
|
||||
|
||||
if self.selfieRequired {
|
||||
guard isDocumentReady(self.selfieDocument) else {
|
||||
guard isDocumentReady(self.selfieDocument, badHashes: badHashes) else {
|
||||
return .saveNotAvailable
|
||||
}
|
||||
}
|
||||
|
||||
var fileHashes: Set<Data> = []
|
||||
for document in self.documents {
|
||||
guard isDocumentReady(document) else {
|
||||
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 {
|
||||
return .saveNotAvailable
|
||||
}
|
||||
if let badFileHashes = badFileHashes, badFileHashes == fileHashes {
|
||||
return .saveNotAvailable
|
||||
}
|
||||
|
||||
var translationHashes: Set<Data> = []
|
||||
for document in self.translations {
|
||||
guard isDocumentReady(document) else {
|
||||
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 {
|
||||
return .saveNotAvailable
|
||||
}
|
||||
if let badTranslationHashes = badTranslationHashes, badTranslationHashes == translationHashes {
|
||||
return .saveNotAvailable
|
||||
}
|
||||
|
||||
return .saveAvailable
|
||||
}
|
||||
@ -2145,8 +2191,9 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
|
||||
}
|
||||
}
|
||||
if let valueKey = valueKey, let errorKey = errorKey {
|
||||
let valueErrorKey: SecureIdValueContentErrorKey = .value(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)
|
||||
@ -2198,8 +2245,9 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
|
||||
errorKey = .field(.address(.countryCode))
|
||||
}
|
||||
if let valueKey = valueKey, let errorKey = errorKey {
|
||||
let valueErrorKey: SecureIdValueContentErrorKey = .value(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)
|
||||
@ -2222,8 +2270,9 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
|
||||
break
|
||||
}
|
||||
if let valueKey = valueKey, let errorKey = errorKey {
|
||||
let valueErrorKey: SecureIdValueContentErrorKey = .value(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)
|
||||
@ -2289,9 +2338,11 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
|
||||
case .address:
|
||||
break
|
||||
}
|
||||
|
||||
if let valueKey = valueKey, let errorKey = errorKey {
|
||||
let valueErrorKey: SecureIdValueContentErrorKey = .value(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)
|
||||
@ -2312,8 +2363,9 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode<SecureIdDocum
|
||||
valueKey = .personalDetails
|
||||
errorKey = .field(.personalDetails(.gender))
|
||||
if let valueKey = valueKey, let errorKey = errorKey {
|
||||
let valueErrorKey: SecureIdValueContentErrorKey = .value(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)
|
||||
|
||||
@ -7,7 +7,7 @@ import SwiftSignalKit
|
||||
|
||||
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)
|
||||
|
||||
final class SelectablePeerNodeTheme {
|
||||
|
||||
@ -1146,13 +1146,11 @@ public func userInfoController(account: Account, peerId: PeerId) -> ViewControll
|
||||
})
|
||||
}
|
||||
shareMyContactImpl = { [weak controller] in
|
||||
let _ = (peerView.get()
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { view in
|
||||
guard let peer = peerViewMainPeer(view) as? TelegramUser, let phone = peer.phone else {
|
||||
let _ = (getUserPeer(postbox: account.postbox, peerId: account.peerId)
|
||||
|> deliverOnMainQueue).start(next: { peer in
|
||||
guard let peer = peer as? TelegramUser, let phone = peer.phone else {
|
||||
return
|
||||
}
|
||||
|
||||
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)])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user