mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Fixes
This commit is contained in:
parent
97fd1d10f0
commit
801b26f157
Binary file not shown.
@ -7,7 +7,7 @@ private let leftFadeImage = generateImage(CGSize(width: 64.0, height: 1.0), opaq
|
||||
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||
context.clear(bounds)
|
||||
|
||||
let gradientColors = [UIColor.black.withAlphaComponent(0.5).cgColor, UIColor.black.withAlphaComponent(0.0).cgColor] as CFArray
|
||||
let gradientColors = [UIColor.black.withAlphaComponent(0.35).cgColor, UIColor.black.withAlphaComponent(0.0).cgColor] as CFArray
|
||||
|
||||
var locations: [CGFloat] = [0.0, 1.0]
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
@ -20,7 +20,7 @@ private let rightFadeImage = generateImage(CGSize(width: 64.0, height: 1.0), opa
|
||||
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||
context.clear(bounds)
|
||||
|
||||
let gradientColors = [UIColor.black.withAlphaComponent(0.0).cgColor, UIColor.black.withAlphaComponent(0.5).cgColor] as CFArray
|
||||
let gradientColors = [UIColor.black.withAlphaComponent(0.0).cgColor, UIColor.black.withAlphaComponent(0.35).cgColor] as CFArray
|
||||
|
||||
var locations: [CGFloat] = [0.0, 1.0]
|
||||
let colorSpace = CGColorSpaceCreateDeviceRGB()
|
||||
@ -63,12 +63,12 @@ open class ZoomableContentGalleryItemNode: GalleryItemNode, UIScrollViewDelegate
|
||||
self.leftFadeNode = ASImageNode()
|
||||
self.leftFadeNode.contentMode = .scaleToFill
|
||||
self.leftFadeNode.image = leftFadeImage
|
||||
self.leftFadeNode.isHidden = true
|
||||
self.leftFadeNode.alpha = 0.0
|
||||
|
||||
self.rightFadeNode = ASImageNode()
|
||||
self.rightFadeNode.contentMode = .scaleToFill
|
||||
self.rightFadeNode.image = rightFadeImage
|
||||
self.rightFadeNode.isHidden = true
|
||||
self.rightFadeNode.alpha = 0.0
|
||||
|
||||
super.init()
|
||||
|
||||
@ -90,21 +90,21 @@ open class ZoomableContentGalleryItemNode: GalleryItemNode, UIScrollViewDelegate
|
||||
}
|
||||
tapRecognizer.highlight = { [weak self] location in
|
||||
if let strongSelf = self {
|
||||
let transition: ContainedViewLayoutTransition = .animated(duration: 0.07, curve: .easeInOut)
|
||||
if let location = location, location.x < 44.0 {
|
||||
strongSelf.leftFadeNode.isHidden = false
|
||||
transition.updateAlpha(node: strongSelf.leftFadeNode, alpha: 1.0)
|
||||
} else {
|
||||
strongSelf.leftFadeNode.isHidden = true
|
||||
transition.updateAlpha(node: strongSelf.leftFadeNode, alpha: 0.0)
|
||||
}
|
||||
if let location = location, location.x > strongSelf.frame.width - 44.0 {
|
||||
strongSelf.rightFadeNode.isHidden = false
|
||||
transition.updateAlpha(node: strongSelf.rightFadeNode, alpha: 1.0)
|
||||
} else {
|
||||
strongSelf.rightFadeNode.isHidden = true
|
||||
transition.updateAlpha(node: strongSelf.rightFadeNode, alpha: 0.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.scrollNode.view.addGestureRecognizer(tapRecognizer)
|
||||
|
||||
|
||||
self.addSubnode(self.scrollNode)
|
||||
self.addSubnode(self.leftFadeNode)
|
||||
@ -114,9 +114,10 @@ open class ZoomableContentGalleryItemNode: GalleryItemNode, UIScrollViewDelegate
|
||||
@objc open func contentTap(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) {
|
||||
if recognizer.state == .ended {
|
||||
if let (gesture, location) = recognizer.lastRecognizedGestureAndLocation {
|
||||
if location.x < 44.0 {
|
||||
let pointInNode = self.scrollNode.view.convert(location, to: self.view)
|
||||
if pointInNode.x < 44.0 {
|
||||
self.goToPreviousItem()
|
||||
} else if location.x > self.frame.width - 44.0 {
|
||||
} else if pointInNode.x > self.frame.width - 44.0 {
|
||||
self.goToNextItem()
|
||||
} else {
|
||||
switch gesture {
|
||||
@ -159,8 +160,9 @@ open class ZoomableContentGalleryItemNode: GalleryItemNode, UIScrollViewDelegate
|
||||
}
|
||||
self.containerLayout = layout
|
||||
|
||||
self.leftFadeNode.frame = CGRect(x: 0.0, y: 0.0, width: layout.size.width * 0.2, height: layout.size.height)
|
||||
self.rightFadeNode.frame = CGRect(x: layout.size.width - layout.size.width * 0.2, y: 0.0, width: layout.size.width * 0.2, height: layout.size.height)
|
||||
let fadeWidth = min(72.0, layout.size.width * 0.2)
|
||||
self.leftFadeNode.frame = CGRect(x: 0.0, y: 0.0, width: fadeWidth, height: layout.size.height)
|
||||
self.rightFadeNode.frame = CGRect(x: layout.size.width - fadeWidth, y: 0.0, width: fadeWidth, height: layout.size.height)
|
||||
|
||||
if shouldResetContents {
|
||||
var previousFrame: CGRect?
|
||||
|
@ -24,6 +24,8 @@ import ContextUI
|
||||
import TelegramNotices
|
||||
import TelegramStringFormatting
|
||||
|
||||
private let maxUsersDisplayedLimit: Int32 = 5
|
||||
|
||||
private struct PeerNearbyEntry {
|
||||
let peer: (Peer, CachedPeerData?)
|
||||
let expires: Int32
|
||||
@ -57,14 +59,16 @@ private final class PeersNearbyControllerArguments {
|
||||
let openChat: (Peer) -> Void
|
||||
let openCreateGroup: (Double, Double, String?) -> Void
|
||||
let contextAction: (Peer, ASDisplayNode, ContextGesture?) -> Void
|
||||
let expandUsers: () -> Void
|
||||
|
||||
init(context: AccountContext, toggleVisibility: @escaping (Bool) -> Void, openProfile: @escaping (Peer) -> Void, openChat: @escaping (Peer) -> Void, openCreateGroup: @escaping (Double, Double, String?) -> Void, contextAction: @escaping (Peer, ASDisplayNode, ContextGesture?) -> Void) {
|
||||
init(context: AccountContext, toggleVisibility: @escaping (Bool) -> Void, openProfile: @escaping (Peer) -> Void, openChat: @escaping (Peer) -> Void, openCreateGroup: @escaping (Double, Double, String?) -> Void, contextAction: @escaping (Peer, ASDisplayNode, ContextGesture?) -> Void, expandUsers: @escaping () -> Void) {
|
||||
self.context = context
|
||||
self.toggleVisibility = toggleVisibility
|
||||
self.openProfile = openProfile
|
||||
self.openChat = openChat
|
||||
self.openCreateGroup = openCreateGroup
|
||||
self.contextAction = contextAction
|
||||
self.expandUsers = expandUsers
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,6 +86,7 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
|
||||
case empty(PresentationTheme, String)
|
||||
case visibility(PresentationTheme, String, Bool)
|
||||
case user(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, PresentationPersonNameOrder, PeerNearbyEntry)
|
||||
case expand(PresentationTheme, String)
|
||||
|
||||
case groupsHeader(PresentationTheme, String, Bool)
|
||||
case createGroup(PresentationTheme, String, Double?, Double?, String?)
|
||||
@ -94,7 +99,7 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
|
||||
switch self {
|
||||
case .header:
|
||||
return PeersNearbySection.header.rawValue
|
||||
case .usersHeader, .empty, .visibility, .user:
|
||||
case .usersHeader, .empty, .visibility, .user, .expand:
|
||||
return PeersNearbySection.users.rawValue
|
||||
case .groupsHeader, .createGroup, .group:
|
||||
return PeersNearbySection.groups.rawValue
|
||||
@ -115,12 +120,14 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
|
||||
return 3
|
||||
case let .user(index, _, _, _, _, _):
|
||||
return 4 + index
|
||||
case .groupsHeader:
|
||||
case .expand:
|
||||
return 1000
|
||||
case .createGroup:
|
||||
case .groupsHeader:
|
||||
return 1001
|
||||
case .createGroup:
|
||||
return 1002
|
||||
case let .group(index, _, _, _, _, _):
|
||||
return 1002 + index
|
||||
return 1003 + index
|
||||
case .channelsHeader:
|
||||
return 2000
|
||||
case let .channel(index, _, _, _, _, _):
|
||||
@ -161,6 +168,12 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .expand(lhsTheme, lhsText):
|
||||
if case let .expand(rhsTheme, rhsText) = rhs, lhsTheme === rhsTheme, lhsText == rhsText {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .groupsHeader(lhsTheme, lhsText, lhsLoading):
|
||||
if case let .groupsHeader(rhsTheme, rhsText, rhsLoading) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsLoading == rhsLoading {
|
||||
return true
|
||||
@ -224,14 +237,19 @@ private enum PeersNearbyEntry: ItemListNodeEntry {
|
||||
})
|
||||
case let .user(_, theme, strings, dateTimeFormat, nameDisplayOrder, peer):
|
||||
var text = strings.Map_DistanceAway(stringForDistance(peer.distance)).0
|
||||
if peer.peer.0.id == arguments.context.account.peerId {
|
||||
let isSelfPeer = peer.peer.0.id == arguments.context.account.peerId
|
||||
if isSelfPeer {
|
||||
text = strings.PeopleNearby_VisibleUntil(humanReadableStringForTimestamp(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: peer.expires)).0
|
||||
}
|
||||
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer.peer.0, aliasHandling: .standard, nameColor: .primary, nameStyle: .distinctBold, presence: nil, text: .text(strings.Map_DistanceAway(stringForDistance(peer.distance)).0), label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), revealOptions: nil, switchValue: nil, enabled: true, selectable: true, sectionId: self.section, action: {
|
||||
arguments.openProfile(peer.peer.0)
|
||||
}, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, toggleUpdated: nil, contextAction: { node, gesture in
|
||||
arguments.contextAction(peer.peer.0, node, gesture)
|
||||
}, hasTopGroupInset: false, tag: nil)
|
||||
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: peer.peer.0, aliasHandling: .standard, nameColor: .primary, nameStyle: .distinctBold, presence: nil, text: .text(text), label: .none, editing: ItemListPeerItemEditing(editable: false, editing: false, revealed: false), revealOptions: nil, switchValue: nil, enabled: true, selectable: !isSelfPeer, sectionId: self.section, action: {
|
||||
if !isSelfPeer {
|
||||
arguments.openProfile(peer.peer.0)
|
||||
}
|
||||
}, setPeerIdWithRevealedOptions: { _, _ in }, removePeer: { _ in }, toggleUpdated: nil, contextAction: nil, hasTopGroupInset: false, tag: nil)
|
||||
case let .expand(theme, title):
|
||||
return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.downArrowImage(theme), title: title, sectionId: self.section, editing: false, action: {
|
||||
arguments.expandUsers()
|
||||
})
|
||||
case let .groupsHeader(theme, text, loading):
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, activityIndicator: loading ? .left : .none, sectionId: self.section)
|
||||
case let .createGroup(theme, title, latitude, longitude, address):
|
||||
@ -294,7 +312,7 @@ private struct PeersNearbyData: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
private func peersNearbyControllerEntries(data: PeersNearbyData?, presentationData: PresentationData, displayLoading: Bool) -> [PeersNearbyEntry] {
|
||||
private func peersNearbyControllerEntries(data: PeersNearbyData?, presentationData: PresentationData, displayLoading: Bool, expanded: Bool) -> [PeersNearbyEntry] {
|
||||
var entries: [PeersNearbyEntry] = []
|
||||
|
||||
entries.append(.header(presentationData.theme, presentationData.strings.PeopleNearby_DiscoverDescription))
|
||||
@ -305,10 +323,22 @@ private func peersNearbyControllerEntries(data: PeersNearbyData?, presentationDa
|
||||
|
||||
if let data = data, !data.users.isEmpty {
|
||||
var i: Int32 = 0
|
||||
for user in data.users {
|
||||
var users = data.users
|
||||
var effectiveExpanded = expanded
|
||||
if users.count > maxUsersDisplayedLimit && !expanded {
|
||||
users = Array(users.prefix(Int(maxUsersDisplayedLimit)))
|
||||
} else {
|
||||
effectiveExpanded = true
|
||||
}
|
||||
|
||||
for user in users {
|
||||
entries.append(.user(i, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, presentationData.nameDisplayOrder, user))
|
||||
i += 1
|
||||
}
|
||||
|
||||
if !effectiveExpanded {
|
||||
entries.append(.expand(presentationData.theme, presentationData.strings.PeopleNearby_ShowMorePeople(Int32(data.users.count) - maxUsersDisplayedLimit)))
|
||||
}
|
||||
}
|
||||
|
||||
entries.append(.groupsHeader(presentationData.theme, presentationData.strings.PeopleNearby_Groups.uppercased(), displayLoading && data == nil))
|
||||
@ -429,6 +459,9 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
|
||||
let dataPromise = Promise<PeersNearbyData?>(nil)
|
||||
let addressPromise = Promise<String?>(nil)
|
||||
|
||||
let visibilityPromise = ValuePromise<Bool>(true)
|
||||
let expandedPromise = ValuePromise<Bool>(false)
|
||||
|
||||
let coordinatePromise = Promise<CLLocationCoordinate2D?>(nil)
|
||||
coordinatePromise.set(.single(nil) |> then(currentLocationManagerCoordinate(manager: context.sharedContext.locationManager!, timeout: 5.0)))
|
||||
|
||||
@ -440,12 +473,16 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
|
||||
let _ = (coordinatePromise.get()
|
||||
|> deliverOnMainQueue).start(next: { coordinate in
|
||||
if let coordinate = coordinate {
|
||||
let _ = peersNearbyUpdateVisibility(network: context.account.network, stateManager: context.account.stateManager, update: .visible(latitude: coordinate.latitude, longitude: coordinate.longitude), background: false).start()
|
||||
let _ = peersNearbyUpdateVisibility(account: context.account, update: .visible(latitude: coordinate.latitude, longitude: coordinate.longitude), background: false).start()
|
||||
}
|
||||
})
|
||||
})]), nil)
|
||||
|
||||
visibilityPromise.set(true)
|
||||
} else {
|
||||
let _ = peersNearbyUpdateVisibility(network: context.account.network, stateManager: context.account.stateManager, update: .invisible, background: false).start()
|
||||
let _ = peersNearbyUpdateVisibility(account: context.account, update: .invisible, background: false).start()
|
||||
|
||||
visibilityPromise.set(false)
|
||||
}
|
||||
}, openProfile: { peer in
|
||||
navigateToProfileImpl?(peer)
|
||||
@ -498,6 +535,8 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
|
||||
presentControllerImpl?(c, nil)
|
||||
}), reactionItems: [], gesture: gesture)
|
||||
presentInGlobalOverlayImpl?(contextController)
|
||||
}, expandUsers: {
|
||||
expandedPromise.set(true)
|
||||
})
|
||||
|
||||
let dataSignal: Signal<PeersNearbyData?, NoError> = coordinatePromise.get()
|
||||
@ -569,9 +608,9 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
|
||||
|> delay(1.0, queue: Queue.mainQueue())
|
||||
)
|
||||
|
||||
let signal = combineLatest(context.sharedContext.presentationData, dataPromise.get(), displayLoading)
|
||||
let signal = combineLatest(context.sharedContext.presentationData, dataPromise.get(), displayLoading, visibilityPromise.get(), expandedPromise.get())
|
||||
|> deliverOnMainQueue
|
||||
|> map { presentationData, data, displayLoading -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
|> map { presentationData, data, displayLoading, visibility, expanded -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let previous = previousData.swap(data)
|
||||
|
||||
var crossfade = false
|
||||
@ -583,7 +622,7 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.PeopleNearby_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: peersNearbyControllerEntries(data: data, presentationData: presentationData, displayLoading: displayLoading), style: .blocks, emptyStateItem: nil, crossfadeState: crossfade, animateChanges: !crossfade)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: peersNearbyControllerEntries(data: data, presentationData: presentationData, displayLoading: displayLoading, expanded: expanded), style: .blocks, emptyStateItem: nil, crossfadeState: crossfade, animateChanges: !crossfade)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
@ -596,7 +635,7 @@ public func peersNearbyController(context: AccountContext) -> ViewController {
|
||||
controller?.clearItemNodesHighlight(animated: true)
|
||||
}
|
||||
navigateToProfileImpl = { [weak controller] peer in
|
||||
if let navigationController = controller?.navigationController as? NavigationController, let controller = context.sharedContext.makePeerInfoController(context: context, peer: peer, mode: .generic, avatarInitiallyExpanded: true) {
|
||||
if let navigationController = controller?.navigationController as? NavigationController, let controller = context.sharedContext.makePeerInfoController(context: context, peer: peer, mode: .generic, avatarInitiallyExpanded: false) {
|
||||
(navigationController as? NavigationController)?.pushViewController(controller)
|
||||
}
|
||||
}
|
||||
|
@ -197,6 +197,7 @@ private enum PreferencesKeyValues: Int32 {
|
||||
case walletCollection = 18
|
||||
case contentSettings = 19
|
||||
case chatListFilters = 20
|
||||
case peersNearby = 21
|
||||
}
|
||||
|
||||
public func applicationSpecificPreferencesKey(_ value: Int32) -> ValueBoxKey {
|
||||
@ -313,6 +314,12 @@ public struct PreferencesKeys {
|
||||
key.setInt32(0, value: PreferencesKeyValues.chatListFilters.rawValue)
|
||||
return key
|
||||
}()
|
||||
|
||||
public static let peersNearby: ValueBoxKey = {
|
||||
let key = ValueBoxKey(length: 4)
|
||||
key.setInt32(0, value: PreferencesKeyValues.peersNearby.rawValue)
|
||||
return key
|
||||
}()
|
||||
}
|
||||
|
||||
private enum SharedDataKeyValues: Int32 {
|
||||
|
@ -561,6 +561,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-1739392570] = { return Api.DocumentAttribute.parse_documentAttributeAudio($0) }
|
||||
dict[358154344] = { return Api.DocumentAttribute.parse_documentAttributeFilename($0) }
|
||||
dict[-1744710921] = { return Api.DocumentAttribute.parse_documentAttributeHasStickers($0) }
|
||||
dict[-177732982] = { return Api.BankCardOpenUrl.parse_bankCardOpenUrl($0) }
|
||||
dict[307276766] = { return Api.account.Authorizations.parse_authorizations($0) }
|
||||
dict[935395612] = { return Api.ChatPhoto.parse_chatPhotoEmpty($0) }
|
||||
dict[1197267925] = { return Api.ChatPhoto.parse_chatPhoto($0) }
|
||||
@ -818,7 +819,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
||||
dict[-1707344487] = { return Api.messages.HighScores.parse_highScores($0) }
|
||||
dict[-892779534] = { return Api.WebAuthorization.parse_webAuthorization($0) }
|
||||
dict[-805141448] = { return Api.ImportedContact.parse_importedContact($0) }
|
||||
dict[-419239361] = { return Api.payments.BankCardData.parse_bankCardData($0) }
|
||||
dict[1042605427] = { return Api.payments.BankCardData.parse_bankCardData($0) }
|
||||
return dict
|
||||
}()
|
||||
|
||||
@ -1238,6 +1239,8 @@ public struct Api {
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.DocumentAttribute:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.BankCardOpenUrl:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.account.Authorizations:
|
||||
_1.serialize(buffer, boxed)
|
||||
case let _1 as Api.ChatPhoto:
|
||||
|
@ -15952,6 +15952,44 @@ public extension Api {
|
||||
return Api.DocumentAttribute.documentAttributeHasStickers
|
||||
}
|
||||
|
||||
}
|
||||
public enum BankCardOpenUrl: TypeConstructorDescription {
|
||||
case bankCardOpenUrl(url: String, name: String)
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .bankCardOpenUrl(let url, let name):
|
||||
if boxed {
|
||||
buffer.appendInt32(-177732982)
|
||||
}
|
||||
serializeString(url, buffer: buffer, boxed: false)
|
||||
serializeString(name, buffer: buffer, boxed: false)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .bankCardOpenUrl(let url, let name):
|
||||
return ("bankCardOpenUrl", [("url", url), ("name", name)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_bankCardOpenUrl(_ reader: BufferReader) -> BankCardOpenUrl? {
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.BankCardOpenUrl.bankCardOpenUrl(url: _1!, name: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public enum ChatPhoto: TypeConstructorDescription {
|
||||
case chatPhotoEmpty
|
||||
|
@ -491,44 +491,42 @@ public struct payments {
|
||||
|
||||
}
|
||||
public enum BankCardData: TypeConstructorDescription {
|
||||
case bankCardData(flags: Int32, title: String, url: String?, urlName: String?)
|
||||
case bankCardData(title: String, openUrls: [Api.BankCardOpenUrl])
|
||||
|
||||
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
|
||||
switch self {
|
||||
case .bankCardData(let flags, let title, let url, let urlName):
|
||||
case .bankCardData(let title, let openUrls):
|
||||
if boxed {
|
||||
buffer.appendInt32(-419239361)
|
||||
buffer.appendInt32(1042605427)
|
||||
}
|
||||
serializeInt32(flags, buffer: buffer, boxed: false)
|
||||
serializeString(title, buffer: buffer, boxed: false)
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(url!, buffer: buffer, boxed: false)}
|
||||
if Int(flags) & Int(1 << 0) != 0 {serializeString(urlName!, buffer: buffer, boxed: false)}
|
||||
buffer.appendInt32(481674261)
|
||||
buffer.appendInt32(Int32(openUrls.count))
|
||||
for item in openUrls {
|
||||
item.serialize(buffer, true)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
public func descriptionFields() -> (String, [(String, Any)]) {
|
||||
switch self {
|
||||
case .bankCardData(let flags, let title, let url, let urlName):
|
||||
return ("bankCardData", [("flags", flags), ("title", title), ("url", url), ("urlName", urlName)])
|
||||
case .bankCardData(let title, let openUrls):
|
||||
return ("bankCardData", [("title", title), ("openUrls", openUrls)])
|
||||
}
|
||||
}
|
||||
|
||||
public static func parse_bankCardData(_ reader: BufferReader) -> BankCardData? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: String?
|
||||
_2 = parseString(reader)
|
||||
var _3: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_3 = parseString(reader) }
|
||||
var _4: String?
|
||||
if Int(_1!) & Int(1 << 0) != 0 {_4 = parseString(reader) }
|
||||
var _1: String?
|
||||
_1 = parseString(reader)
|
||||
var _2: [Api.BankCardOpenUrl]?
|
||||
if let _ = reader.readInt32() {
|
||||
_2 = Api.parseVector(reader, elementSignature: 0, elementType: Api.BankCardOpenUrl.self)
|
||||
}
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
|
||||
let _c4 = (Int(_1!) & Int(1 << 0) == 0) || _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.payments.BankCardData.bankCardData(flags: _1!, title: _2!, url: _3, urlName: _4)
|
||||
if _c1 && _c2 {
|
||||
return Api.payments.BankCardData.bankCardData(title: _1!, openUrls: _2!)
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
@ -3263,6 +3263,33 @@ public extension Api {
|
||||
})
|
||||
}
|
||||
}
|
||||
public static func inputMediaDice() -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.InputMedia>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(-1358977017)
|
||||
|
||||
return (FunctionDescription(name: "inputMediaDice", parameters: []), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.InputMedia? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.InputMedia?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.InputMedia
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
|
||||
public static func messageMediaDice(value: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.MessageMedia>) {
|
||||
let buffer = Buffer()
|
||||
buffer.appendInt32(1670374507)
|
||||
serializeInt32(value, buffer: buffer, boxed: false)
|
||||
return (FunctionDescription(name: "messageMediaDice", parameters: [("value", value)]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.MessageMedia? in
|
||||
let reader = BufferReader(buffer)
|
||||
var result: Api.MessageMedia?
|
||||
if let signature = reader.readInt32() {
|
||||
result = Api.parse(reader, signature: signature) as? Api.MessageMedia
|
||||
}
|
||||
return result
|
||||
})
|
||||
}
|
||||
public struct channels {
|
||||
public static func readHistory(channel: Api.InputChannel, maxId: Int32) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
|
||||
let buffer = Buffer()
|
||||
|
@ -2,33 +2,58 @@ import Foundation
|
||||
import Postbox
|
||||
import TelegramApi
|
||||
import SyncCore
|
||||
import MtProtoKit
|
||||
import SwiftSignalKit
|
||||
|
||||
public struct BankCardUrl {
|
||||
public let title: String
|
||||
public let url: String
|
||||
}
|
||||
|
||||
public struct BankCardInfo {
|
||||
public let title: String
|
||||
public let url: String?
|
||||
public let actionTitle: String?
|
||||
public let urls: [BankCardUrl]
|
||||
}
|
||||
|
||||
public func getBankCardInfo(account: Account, cardNumber: String) -> Signal<BankCardInfo?, NoError> {
|
||||
return account.network.request(Api.functions.payments.getBankCardData(number: cardNumber))
|
||||
|> map { result -> BankCardInfo? in
|
||||
return BankCardInfo(apiBankCardData: result)
|
||||
return currentWebDocumentsHostDatacenterId(postbox: account.postbox, isTestingEnvironment: false)
|
||||
|> mapToSignal { datacenterId in
|
||||
let signal: Signal<Api.payments.BankCardData, MTRpcError>
|
||||
if account.network.datacenterId != datacenterId {
|
||||
signal = account.network.download(datacenterId: Int(datacenterId), isMedia: false, tag: nil)
|
||||
|> castError(MTRpcError.self)
|
||||
|> mapToSignal { worker in
|
||||
return worker.request(Api.functions.payments.getBankCardData(number: cardNumber))
|
||||
}
|
||||
} else {
|
||||
signal = account.network.request(Api.functions.payments.getBankCardData(number: cardNumber))
|
||||
}
|
||||
return signal
|
||||
|> map { result -> BankCardInfo? in
|
||||
return BankCardInfo(apiBankCardData: result)
|
||||
}
|
||||
|> `catch` { _ -> Signal<BankCardInfo?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
|> `catch` { _ -> Signal<BankCardInfo?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
extension BankCardUrl {
|
||||
init(apiBankCardOpenUrl: Api.BankCardOpenUrl) {
|
||||
switch apiBankCardOpenUrl {
|
||||
case let .bankCardOpenUrl(url, name):
|
||||
self.title = name
|
||||
self.url = url
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension BankCardInfo {
|
||||
init(apiBankCardData: Api.payments.BankCardData) {
|
||||
switch apiBankCardData {
|
||||
case let .bankCardData(flags, title, url, urlName):
|
||||
case let .bankCardData(title, urls):
|
||||
self.title = title
|
||||
self.url = url
|
||||
self.actionTitle = urlName
|
||||
self.urls = urls.map { BankCardUrl(apiBankCardOpenUrl: $0) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,7 +25,7 @@ public enum PeerNearbyVisibilityUpdate {
|
||||
case invisible
|
||||
}
|
||||
|
||||
public func peersNearbyUpdateVisibility(network: Network, stateManager: AccountStateManager, update: PeerNearbyVisibilityUpdate, background: Bool) -> Signal<Void, NoError> {
|
||||
public func peersNearbyUpdateVisibility(account: Account, update: PeerNearbyVisibilityUpdate, background: Bool) -> Signal<Void, NoError> {
|
||||
var flags: Int32 = 0
|
||||
var geoPoint: Api.InputGeoPoint
|
||||
var selfExpires: Int32?
|
||||
@ -43,18 +43,30 @@ public func peersNearbyUpdateVisibility(network: Network, stateManager: AccountS
|
||||
selfExpires = 0
|
||||
}
|
||||
|
||||
let _ = (account.postbox.transaction { transaction in
|
||||
transaction.updatePreferencesEntry(key: PreferencesKeys.peersNearby, { entry in
|
||||
var settings = entry as? PeersNearbyState ?? PeersNearbyState.default
|
||||
if let expires = selfExpires {
|
||||
settings.visibilityExpires = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) + expires
|
||||
} else if case .invisible = update {
|
||||
settings.visibilityExpires = nil
|
||||
}
|
||||
return settings
|
||||
})
|
||||
}).start()
|
||||
|
||||
if background {
|
||||
flags |= (1 << 1)
|
||||
}
|
||||
|
||||
return network.request(Api.functions.contacts.getLocated(flags: flags, geoPoint: geoPoint, selfExpires: selfExpires))
|
||||
return account.network.request(Api.functions.contacts.getLocated(flags: flags, geoPoint: geoPoint, selfExpires: selfExpires))
|
||||
|> map(Optional.init)
|
||||
|> `catch` { _ -> Signal<Api.Updates?, NoError> in
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { updates -> Signal<Void, NoError> in
|
||||
if let updates = updates {
|
||||
stateManager.addUpdates(updates)
|
||||
account.stateManager.addUpdates(updates)
|
||||
}
|
||||
return .complete()
|
||||
}
|
||||
@ -258,3 +270,33 @@ public func updateChannelGeoLocation(postbox: Postbox, network: Network, channel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public struct PeersNearbyState: PreferencesEntry, Equatable {
|
||||
public var visibilityExpires: Int32?
|
||||
|
||||
public static var `default` = PeersNearbyState(visibilityExpires: nil)
|
||||
|
||||
public init(visibilityExpires: Int32?) {
|
||||
self.visibilityExpires = visibilityExpires
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
self.visibilityExpires = decoder.decodeOptionalInt32ForKey("expires")
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
if let expires = self.visibilityExpires {
|
||||
encoder.encodeInt32(expires, forKey: "expires")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "expires")
|
||||
}
|
||||
}
|
||||
|
||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
||||
if let to = to as? PeersNearbyState, self == to {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1357,17 +1357,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
guard let message = message else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (getBankCardInfo(account: strongSelf.context.account, cardNumber: number)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] info in
|
||||
if let strongSelf = self, let info = info {
|
||||
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData)
|
||||
var items: [ActionSheetItem] = []
|
||||
items.append(ActionSheetTextItem(title: info.title))
|
||||
if let url = info.url, let actionTitle = info.actionTitle {
|
||||
items.append(ActionSheetButtonItem(title: actionTitle, color: .accent, action: { [weak actionSheet] in
|
||||
for url in info.urls {
|
||||
items.append(ActionSheetButtonItem(title: url.title, color: .accent, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
if let strongSelf = self {
|
||||
strongSelf.controllerInteraction?.openUrl(url, false, false, message)
|
||||
strongSelf.controllerInteraction?.openUrl(url.url, false, false, message)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user